1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2020 The Android Open Source Project 2*6dbdd20aSAndroid Build Coastguard Worker// 3*6dbdd20aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*6dbdd20aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*6dbdd20aSAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*6dbdd20aSAndroid Build Coastguard Worker// 7*6dbdd20aSAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*6dbdd20aSAndroid Build Coastguard Worker// 9*6dbdd20aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*6dbdd20aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*6dbdd20aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*6dbdd20aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*6dbdd20aSAndroid Build Coastguard Worker// limitations under the License. 14*6dbdd20aSAndroid Build Coastguard Worker 15*6dbdd20aSAndroid Build Coastguard Worker'use strict'; 16*6dbdd20aSAndroid Build Coastguard Worker 17*6dbdd20aSAndroid Build Coastguard Workerlet tocAnchors = []; 18*6dbdd20aSAndroid Build Coastguard Workerlet lastMouseOffY = 0; 19*6dbdd20aSAndroid Build Coastguard Workerlet onloadFired = false; 20*6dbdd20aSAndroid Build Coastguard Workerconst postLoadActions = []; 21*6dbdd20aSAndroid Build Coastguard Workerlet tocEventHandlersInstalled = false; 22*6dbdd20aSAndroid Build Coastguard Workerlet resizeObserver = undefined; 23*6dbdd20aSAndroid Build Coastguard Worker 24*6dbdd20aSAndroid Build Coastguard Workerfunction doAfterLoadEvent(action) { 25*6dbdd20aSAndroid Build Coastguard Worker if (onloadFired) { 26*6dbdd20aSAndroid Build Coastguard Worker return action(); 27*6dbdd20aSAndroid Build Coastguard Worker } 28*6dbdd20aSAndroid Build Coastguard Worker postLoadActions.push(action); 29*6dbdd20aSAndroid Build Coastguard Worker} 30*6dbdd20aSAndroid Build Coastguard Worker 31*6dbdd20aSAndroid Build Coastguard Workerfunction setupSandwichMenu() { 32*6dbdd20aSAndroid Build Coastguard Worker const header = document.querySelector('.site-header'); 33*6dbdd20aSAndroid Build Coastguard Worker const docsNav = document.querySelector('.nav'); 34*6dbdd20aSAndroid Build Coastguard Worker const menu = header.querySelector('.menu'); 35*6dbdd20aSAndroid Build Coastguard Worker menu.addEventListener('click', (e) => { 36*6dbdd20aSAndroid Build Coastguard Worker e.preventDefault(); 37*6dbdd20aSAndroid Build Coastguard Worker 38*6dbdd20aSAndroid Build Coastguard Worker // If we are displaying any /docs, toggle the navbar instead (the TOC). 39*6dbdd20aSAndroid Build Coastguard Worker if (docsNav) { 40*6dbdd20aSAndroid Build Coastguard Worker // |after_first_click| is to avoid spurious transitions on page load. 41*6dbdd20aSAndroid Build Coastguard Worker docsNav.classList.add('after_first_click'); 42*6dbdd20aSAndroid Build Coastguard Worker updateNav(); 43*6dbdd20aSAndroid Build Coastguard Worker setTimeout(() => docsNav.classList.toggle('expanded'), 0); 44*6dbdd20aSAndroid Build Coastguard Worker } else { 45*6dbdd20aSAndroid Build Coastguard Worker header.classList.toggle('expanded'); 46*6dbdd20aSAndroid Build Coastguard Worker } 47*6dbdd20aSAndroid Build Coastguard Worker }); 48*6dbdd20aSAndroid Build Coastguard Worker} 49*6dbdd20aSAndroid Build Coastguard Worker 50*6dbdd20aSAndroid Build Coastguard Worker// (Re-)Generates the Table Of Contents for docs (the right-hand-side one). 51*6dbdd20aSAndroid Build Coastguard Workerfunction updateTOC() { 52*6dbdd20aSAndroid Build Coastguard Worker const tocContainer = document.querySelector('.docs .toc'); 53*6dbdd20aSAndroid Build Coastguard Worker if (!tocContainer) 54*6dbdd20aSAndroid Build Coastguard Worker return; 55*6dbdd20aSAndroid Build Coastguard Worker const toc = document.createElement('ul'); 56*6dbdd20aSAndroid Build Coastguard Worker const anchors = document.querySelectorAll('.doc a.anchor'); 57*6dbdd20aSAndroid Build Coastguard Worker tocAnchors = []; 58*6dbdd20aSAndroid Build Coastguard Worker for (const anchor of anchors) { 59*6dbdd20aSAndroid Build Coastguard Worker const li = document.createElement('li'); 60*6dbdd20aSAndroid Build Coastguard Worker const link = document.createElement('a'); 61*6dbdd20aSAndroid Build Coastguard Worker link.innerText = anchor.parentElement.innerText; 62*6dbdd20aSAndroid Build Coastguard Worker link.href = anchor.href; 63*6dbdd20aSAndroid Build Coastguard Worker link.onclick = () => { 64*6dbdd20aSAndroid Build Coastguard Worker onScroll(link) 65*6dbdd20aSAndroid Build Coastguard Worker }; 66*6dbdd20aSAndroid Build Coastguard Worker li.appendChild(link); 67*6dbdd20aSAndroid Build Coastguard Worker if (anchor.parentElement.tagName === 'H3') 68*6dbdd20aSAndroid Build Coastguard Worker li.style.paddingLeft = '10px'; 69*6dbdd20aSAndroid Build Coastguard Worker toc.appendChild(li); 70*6dbdd20aSAndroid Build Coastguard Worker doAfterLoadEvent(() => { 71*6dbdd20aSAndroid Build Coastguard Worker tocAnchors.push( 72*6dbdd20aSAndroid Build Coastguard Worker { top: anchor.offsetTop + anchor.offsetHeight / 2, obj: link }); 73*6dbdd20aSAndroid Build Coastguard Worker }); 74*6dbdd20aSAndroid Build Coastguard Worker } 75*6dbdd20aSAndroid Build Coastguard Worker tocContainer.innerHTML = ''; 76*6dbdd20aSAndroid Build Coastguard Worker tocContainer.appendChild(toc); 77*6dbdd20aSAndroid Build Coastguard Worker 78*6dbdd20aSAndroid Build Coastguard Worker // Add event handlers on the first call (can be called more than once to 79*6dbdd20aSAndroid Build Coastguard Worker // recompute anchors on resize). 80*6dbdd20aSAndroid Build Coastguard Worker if (tocEventHandlersInstalled) 81*6dbdd20aSAndroid Build Coastguard Worker return; 82*6dbdd20aSAndroid Build Coastguard Worker tocEventHandlersInstalled = true; 83*6dbdd20aSAndroid Build Coastguard Worker const doc = document.querySelector('.doc'); 84*6dbdd20aSAndroid Build Coastguard Worker const passive = { passive: true }; 85*6dbdd20aSAndroid Build Coastguard Worker if (doc) { 86*6dbdd20aSAndroid Build Coastguard Worker const offY = doc.offsetTop; 87*6dbdd20aSAndroid Build Coastguard Worker doc.addEventListener('mousemove', (e) => onMouseMove(offY, e), passive); 88*6dbdd20aSAndroid Build Coastguard Worker doc.addEventListener('mouseleave', () => { 89*6dbdd20aSAndroid Build Coastguard Worker lastMouseOffY = 0; 90*6dbdd20aSAndroid Build Coastguard Worker }, passive); 91*6dbdd20aSAndroid Build Coastguard Worker } 92*6dbdd20aSAndroid Build Coastguard Worker window.addEventListener('scroll', () => onScroll(), passive); 93*6dbdd20aSAndroid Build Coastguard Worker resizeObserver = new ResizeObserver(() => requestAnimationFrame(() => { 94*6dbdd20aSAndroid Build Coastguard Worker updateNav(); 95*6dbdd20aSAndroid Build Coastguard Worker updateTOC(); 96*6dbdd20aSAndroid Build Coastguard Worker })); 97*6dbdd20aSAndroid Build Coastguard Worker resizeObserver.observe(doc); 98*6dbdd20aSAndroid Build Coastguard Worker} 99*6dbdd20aSAndroid Build Coastguard Worker 100*6dbdd20aSAndroid Build Coastguard Worker// Highlights the current TOC anchor depending on the scroll offset. 101*6dbdd20aSAndroid Build Coastguard Workerfunction onMouseMove(offY, e) { 102*6dbdd20aSAndroid Build Coastguard Worker lastMouseOffY = e.clientY - offY; 103*6dbdd20aSAndroid Build Coastguard Worker onScroll(); 104*6dbdd20aSAndroid Build Coastguard Worker} 105*6dbdd20aSAndroid Build Coastguard Worker 106*6dbdd20aSAndroid Build Coastguard Workerfunction onScroll(forceHighlight) { 107*6dbdd20aSAndroid Build Coastguard Worker const y = document.documentElement.scrollTop + lastMouseOffY; 108*6dbdd20aSAndroid Build Coastguard Worker let highEl = undefined; 109*6dbdd20aSAndroid Build Coastguard Worker for (const x of tocAnchors) { 110*6dbdd20aSAndroid Build Coastguard Worker if (y < x.top) 111*6dbdd20aSAndroid Build Coastguard Worker continue; 112*6dbdd20aSAndroid Build Coastguard Worker highEl = x.obj; 113*6dbdd20aSAndroid Build Coastguard Worker } 114*6dbdd20aSAndroid Build Coastguard Worker for (const link of document.querySelectorAll('.docs .toc a')) { 115*6dbdd20aSAndroid Build Coastguard Worker if ((!forceHighlight && link === highEl) || (forceHighlight === link)) { 116*6dbdd20aSAndroid Build Coastguard Worker link.classList.add('highlighted'); 117*6dbdd20aSAndroid Build Coastguard Worker } else { 118*6dbdd20aSAndroid Build Coastguard Worker link.classList.remove('highlighted'); 119*6dbdd20aSAndroid Build Coastguard Worker } 120*6dbdd20aSAndroid Build Coastguard Worker } 121*6dbdd20aSAndroid Build Coastguard Worker} 122*6dbdd20aSAndroid Build Coastguard Worker 123*6dbdd20aSAndroid Build Coastguard Worker// This function needs to be idempotent as it is called more than once (on every 124*6dbdd20aSAndroid Build Coastguard Worker// resize). 125*6dbdd20aSAndroid Build Coastguard Workerfunction updateNav() { 126*6dbdd20aSAndroid Build Coastguard Worker const curDoc = document.querySelector('.doc'); 127*6dbdd20aSAndroid Build Coastguard Worker let curFileName = ''; 128*6dbdd20aSAndroid Build Coastguard Worker if (curDoc) 129*6dbdd20aSAndroid Build Coastguard Worker curFileName = curDoc.dataset['mdFile']; 130*6dbdd20aSAndroid Build Coastguard Worker 131*6dbdd20aSAndroid Build Coastguard Worker // First identify all the top-level nav entries (Quickstart, Data Sources, 132*6dbdd20aSAndroid Build Coastguard Worker // ...) and make them compressible. 133*6dbdd20aSAndroid Build Coastguard Worker const toplevelSections = document.querySelectorAll('.docs .nav > ul > li'); 134*6dbdd20aSAndroid Build Coastguard Worker const toplevelLinks = []; 135*6dbdd20aSAndroid Build Coastguard Worker for (const sec of toplevelSections) { 136*6dbdd20aSAndroid Build Coastguard Worker const childMenu = sec.querySelector('ul'); 137*6dbdd20aSAndroid Build Coastguard Worker if (!childMenu) { 138*6dbdd20aSAndroid Build Coastguard Worker // Don't make it compressible if it has no children (e.g. the very 139*6dbdd20aSAndroid Build Coastguard Worker // first 'Introduction' link). 140*6dbdd20aSAndroid Build Coastguard Worker continue; 141*6dbdd20aSAndroid Build Coastguard Worker } 142*6dbdd20aSAndroid Build Coastguard Worker 143*6dbdd20aSAndroid Build Coastguard Worker // Don't make it compressible if the entry has an actual link (e.g. the very 144*6dbdd20aSAndroid Build Coastguard Worker // first 'Introduction' link), because otherwise it become ambiguous whether 145*6dbdd20aSAndroid Build Coastguard Worker // the link should toggle or open the link. 146*6dbdd20aSAndroid Build Coastguard Worker const link = sec.querySelector('a'); 147*6dbdd20aSAndroid Build Coastguard Worker if (!link || !link.href.endsWith('#')) 148*6dbdd20aSAndroid Build Coastguard Worker continue; 149*6dbdd20aSAndroid Build Coastguard Worker 150*6dbdd20aSAndroid Build Coastguard Worker sec.classList.add('compressible'); 151*6dbdd20aSAndroid Build Coastguard Worker 152*6dbdd20aSAndroid Build Coastguard Worker // Remember the compressed status as long as the page is opened, so clicking 153*6dbdd20aSAndroid Build Coastguard Worker // through links keeps the sidebar in a consistent visual state. 154*6dbdd20aSAndroid Build Coastguard Worker const memoKey = `docs.nav.compressed[${link.innerHTML}]`; 155*6dbdd20aSAndroid Build Coastguard Worker 156*6dbdd20aSAndroid Build Coastguard Worker if (sessionStorage.getItem(memoKey) === '1') { 157*6dbdd20aSAndroid Build Coastguard Worker sec.classList.add('compressed'); 158*6dbdd20aSAndroid Build Coastguard Worker } 159*6dbdd20aSAndroid Build Coastguard Worker doAfterLoadEvent(() => { 160*6dbdd20aSAndroid Build Coastguard Worker childMenu.style.maxHeight = `${childMenu.scrollHeight + 40}px`; 161*6dbdd20aSAndroid Build Coastguard Worker }); 162*6dbdd20aSAndroid Build Coastguard Worker 163*6dbdd20aSAndroid Build Coastguard Worker toplevelLinks.push(link); 164*6dbdd20aSAndroid Build Coastguard Worker link.onclick = (evt) => { 165*6dbdd20aSAndroid Build Coastguard Worker evt.preventDefault(); 166*6dbdd20aSAndroid Build Coastguard Worker sec.classList.toggle('compressed'); 167*6dbdd20aSAndroid Build Coastguard Worker if (sec.classList.contains('compressed')) { 168*6dbdd20aSAndroid Build Coastguard Worker sessionStorage.setItem(memoKey, '1'); 169*6dbdd20aSAndroid Build Coastguard Worker } else { 170*6dbdd20aSAndroid Build Coastguard Worker sessionStorage.removeItem(memoKey); 171*6dbdd20aSAndroid Build Coastguard Worker } 172*6dbdd20aSAndroid Build Coastguard Worker }; 173*6dbdd20aSAndroid Build Coastguard Worker } 174*6dbdd20aSAndroid Build Coastguard Worker 175*6dbdd20aSAndroid Build Coastguard Worker const exps = document.querySelectorAll('.docs .nav ul a'); 176*6dbdd20aSAndroid Build Coastguard Worker let found = false; 177*6dbdd20aSAndroid Build Coastguard Worker for (const x of exps) { 178*6dbdd20aSAndroid Build Coastguard Worker // If the url of the entry matches the url of the page, mark the item as 179*6dbdd20aSAndroid Build Coastguard Worker // highlighted and expand all its parents. 180*6dbdd20aSAndroid Build Coastguard Worker if (!x.href) 181*6dbdd20aSAndroid Build Coastguard Worker continue; 182*6dbdd20aSAndroid Build Coastguard Worker const url = new URL(x.href); 183*6dbdd20aSAndroid Build Coastguard Worker if (x.href.endsWith('#')) { 184*6dbdd20aSAndroid Build Coastguard Worker // This is a non-leaf link to a menu. 185*6dbdd20aSAndroid Build Coastguard Worker if (toplevelLinks.indexOf(x) < 0) { 186*6dbdd20aSAndroid Build Coastguard Worker x.removeAttribute('href'); 187*6dbdd20aSAndroid Build Coastguard Worker } 188*6dbdd20aSAndroid Build Coastguard Worker } else if (url.pathname === curFileName && !found) { 189*6dbdd20aSAndroid Build Coastguard Worker x.classList.add('selected'); 190*6dbdd20aSAndroid Build Coastguard Worker doAfterLoadEvent(() => x.scrollIntoViewIfNeeded()); 191*6dbdd20aSAndroid Build Coastguard Worker found = true; // Highlight only the first occurrence. 192*6dbdd20aSAndroid Build Coastguard Worker } 193*6dbdd20aSAndroid Build Coastguard Worker } 194*6dbdd20aSAndroid Build Coastguard Worker} 195*6dbdd20aSAndroid Build Coastguard Worker 196*6dbdd20aSAndroid Build Coastguard Worker// If the page contains a ```mermaid ``` block, lazily loads the plugin and 197*6dbdd20aSAndroid Build Coastguard Worker// renders. 198*6dbdd20aSAndroid Build Coastguard Workerfunction initMermaid() { 199*6dbdd20aSAndroid Build Coastguard Worker const graphs = document.querySelectorAll('.mermaid'); 200*6dbdd20aSAndroid Build Coastguard Worker 201*6dbdd20aSAndroid Build Coastguard Worker // Skip if there are no mermaid graphs to render. 202*6dbdd20aSAndroid Build Coastguard Worker if (!graphs.length) 203*6dbdd20aSAndroid Build Coastguard Worker return; 204*6dbdd20aSAndroid Build Coastguard Worker 205*6dbdd20aSAndroid Build Coastguard Worker const script = document.createElement('script'); 206*6dbdd20aSAndroid Build Coastguard Worker script.type = 'text/javascript'; 207*6dbdd20aSAndroid Build Coastguard Worker script.src = '/assets/mermaid.min.js'; 208*6dbdd20aSAndroid Build Coastguard Worker const themeCSS = ` 209*6dbdd20aSAndroid Build Coastguard Worker .cluster rect { fill: #FCFCFC; stroke: #ddd } 210*6dbdd20aSAndroid Build Coastguard Worker .node rect { fill: #DCEDC8; stroke: #8BC34A} 211*6dbdd20aSAndroid Build Coastguard Worker .edgeLabel:not(:empty) { 212*6dbdd20aSAndroid Build Coastguard Worker border-radius: 6px; 213*6dbdd20aSAndroid Build Coastguard Worker font-size: 0.9em; 214*6dbdd20aSAndroid Build Coastguard Worker padding: 4px; 215*6dbdd20aSAndroid Build Coastguard Worker background: #F5F5F5; 216*6dbdd20aSAndroid Build Coastguard Worker border: 1px solid #DDDDDD; 217*6dbdd20aSAndroid Build Coastguard Worker color: #666; 218*6dbdd20aSAndroid Build Coastguard Worker } 219*6dbdd20aSAndroid Build Coastguard Worker `; 220*6dbdd20aSAndroid Build Coastguard Worker script.addEventListener('load', () => { 221*6dbdd20aSAndroid Build Coastguard Worker mermaid.initialize({ 222*6dbdd20aSAndroid Build Coastguard Worker startOnLoad: false, 223*6dbdd20aSAndroid Build Coastguard Worker themeCSS: themeCSS, 224*6dbdd20aSAndroid Build Coastguard Worker securityLevel: 'loose', // To allow #in-page-links 225*6dbdd20aSAndroid Build Coastguard Worker }); 226*6dbdd20aSAndroid Build Coastguard Worker for (const graph of graphs) { 227*6dbdd20aSAndroid Build Coastguard Worker requestAnimationFrame(() => { 228*6dbdd20aSAndroid Build Coastguard Worker mermaid.init(undefined, graph); 229*6dbdd20aSAndroid Build Coastguard Worker graph.classList.add('rendered'); 230*6dbdd20aSAndroid Build Coastguard Worker }); 231*6dbdd20aSAndroid Build Coastguard Worker } 232*6dbdd20aSAndroid Build Coastguard Worker }) 233*6dbdd20aSAndroid Build Coastguard Worker document.body.appendChild(script); 234*6dbdd20aSAndroid Build Coastguard Worker} 235*6dbdd20aSAndroid Build Coastguard Worker 236*6dbdd20aSAndroid Build Coastguard Workerfunction setupSearch() { 237*6dbdd20aSAndroid Build Coastguard Worker const URL = 238*6dbdd20aSAndroid Build Coastguard Worker 'https://www.googleapis.com/customsearch/v1?key=AIzaSyBTD2XJkQkkuvDn76LSftsgWOkdBz9Gfwo&cx=007128963598137843411:8suis14kcmy&q=' 239*6dbdd20aSAndroid Build Coastguard Worker const searchContainer = document.getElementById('search'); 240*6dbdd20aSAndroid Build Coastguard Worker const searchBox = document.getElementById('search-box'); 241*6dbdd20aSAndroid Build Coastguard Worker const searchRes = document.getElementById('search-res') 242*6dbdd20aSAndroid Build Coastguard Worker if (!searchBox || !searchRes) return; 243*6dbdd20aSAndroid Build Coastguard Worker 244*6dbdd20aSAndroid Build Coastguard Worker document.body.addEventListener('keydown', (e) => { 245*6dbdd20aSAndroid Build Coastguard Worker if (e.key === '/' && e.target.tagName.toLowerCase() === 'body') { 246*6dbdd20aSAndroid Build Coastguard Worker searchBox.setSelectionRange(0, -1); 247*6dbdd20aSAndroid Build Coastguard Worker searchBox.focus(); 248*6dbdd20aSAndroid Build Coastguard Worker e.preventDefault(); 249*6dbdd20aSAndroid Build Coastguard Worker } else if (e.key === 'Escape' && searchContainer.contains(e.target)) { 250*6dbdd20aSAndroid Build Coastguard Worker searchBox.blur(); 251*6dbdd20aSAndroid Build Coastguard Worker 252*6dbdd20aSAndroid Build Coastguard Worker // Handle the case of clicking Tab and moving down to results. 253*6dbdd20aSAndroid Build Coastguard Worker e.target.blur(); 254*6dbdd20aSAndroid Build Coastguard Worker } 255*6dbdd20aSAndroid Build Coastguard Worker }); 256*6dbdd20aSAndroid Build Coastguard Worker 257*6dbdd20aSAndroid Build Coastguard Worker let timerId = -1; 258*6dbdd20aSAndroid Build Coastguard Worker let lastSearchId = 0; 259*6dbdd20aSAndroid Build Coastguard Worker 260*6dbdd20aSAndroid Build Coastguard Worker const doSearch = async () => { 261*6dbdd20aSAndroid Build Coastguard Worker timerId = -1; 262*6dbdd20aSAndroid Build Coastguard Worker searchRes.style.width = `${searchBox.offsetWidth}px`; 263*6dbdd20aSAndroid Build Coastguard Worker 264*6dbdd20aSAndroid Build Coastguard Worker // `searchId` handles the case of two subsequent requests racing. This is to 265*6dbdd20aSAndroid Build Coastguard Worker // prevent older results, delivered in reverse order, to replace newer ones. 266*6dbdd20aSAndroid Build Coastguard Worker const searchId = ++lastSearchId; 267*6dbdd20aSAndroid Build Coastguard Worker const f = await fetch(URL + encodeURIComponent(searchBox.value)); 268*6dbdd20aSAndroid Build Coastguard Worker const jsonRes = await f.json(); 269*6dbdd20aSAndroid Build Coastguard Worker const results = jsonRes['items']; 270*6dbdd20aSAndroid Build Coastguard Worker searchRes.innerHTML = ''; 271*6dbdd20aSAndroid Build Coastguard Worker if (results === undefined || searchId != lastSearchId) { 272*6dbdd20aSAndroid Build Coastguard Worker return; 273*6dbdd20aSAndroid Build Coastguard Worker } 274*6dbdd20aSAndroid Build Coastguard Worker for (const res of results) { 275*6dbdd20aSAndroid Build Coastguard Worker const link = document.createElement('a'); 276*6dbdd20aSAndroid Build Coastguard Worker link.href = res.link; 277*6dbdd20aSAndroid Build Coastguard Worker const title = document.createElement('div'); 278*6dbdd20aSAndroid Build Coastguard Worker title.className = 'sr-title'; 279*6dbdd20aSAndroid Build Coastguard Worker title.innerText = res.title.replace(' - Perfetto Tracing Docs', ''); 280*6dbdd20aSAndroid Build Coastguard Worker link.appendChild(title); 281*6dbdd20aSAndroid Build Coastguard Worker 282*6dbdd20aSAndroid Build Coastguard Worker const snippet = document.createElement('div'); 283*6dbdd20aSAndroid Build Coastguard Worker snippet.className = 'sr-snippet'; 284*6dbdd20aSAndroid Build Coastguard Worker snippet.innerText = res.snippet; 285*6dbdd20aSAndroid Build Coastguard Worker link.appendChild(snippet); 286*6dbdd20aSAndroid Build Coastguard Worker 287*6dbdd20aSAndroid Build Coastguard Worker const div = document.createElement('div'); 288*6dbdd20aSAndroid Build Coastguard Worker div.appendChild(link); 289*6dbdd20aSAndroid Build Coastguard Worker searchRes.appendChild(div); 290*6dbdd20aSAndroid Build Coastguard Worker } 291*6dbdd20aSAndroid Build Coastguard Worker }; 292*6dbdd20aSAndroid Build Coastguard Worker 293*6dbdd20aSAndroid Build Coastguard Worker searchBox.addEventListener('keyup', () => { 294*6dbdd20aSAndroid Build Coastguard Worker if (timerId >= 0) return; 295*6dbdd20aSAndroid Build Coastguard Worker timerId = setTimeout(doSearch, 200); 296*6dbdd20aSAndroid Build Coastguard Worker }); 297*6dbdd20aSAndroid Build Coastguard Worker} 298*6dbdd20aSAndroid Build Coastguard Worker 299*6dbdd20aSAndroid Build Coastguard Workerwindow.addEventListener('DOMContentLoaded', () => { 300*6dbdd20aSAndroid Build Coastguard Worker updateNav(); 301*6dbdd20aSAndroid Build Coastguard Worker updateTOC(); 302*6dbdd20aSAndroid Build Coastguard Worker}); 303*6dbdd20aSAndroid Build Coastguard Worker 304*6dbdd20aSAndroid Build Coastguard Workerwindow.addEventListener('load', () => { 305*6dbdd20aSAndroid Build Coastguard Worker setupSandwichMenu(); 306*6dbdd20aSAndroid Build Coastguard Worker initMermaid(); 307*6dbdd20aSAndroid Build Coastguard Worker 308*6dbdd20aSAndroid Build Coastguard Worker // Don't smooth-scroll on pages that are too long (e.g. reference pages). 309*6dbdd20aSAndroid Build Coastguard Worker if (document.body.scrollHeight < 10000) { 310*6dbdd20aSAndroid Build Coastguard Worker document.documentElement.style.scrollBehavior = 'smooth'; 311*6dbdd20aSAndroid Build Coastguard Worker } else { 312*6dbdd20aSAndroid Build Coastguard Worker document.documentElement.style.scrollBehavior = 'initial'; 313*6dbdd20aSAndroid Build Coastguard Worker } 314*6dbdd20aSAndroid Build Coastguard Worker 315*6dbdd20aSAndroid Build Coastguard Worker onloadFired = true; 316*6dbdd20aSAndroid Build Coastguard Worker while (postLoadActions.length > 0) { 317*6dbdd20aSAndroid Build Coastguard Worker postLoadActions.shift()(); 318*6dbdd20aSAndroid Build Coastguard Worker } 319*6dbdd20aSAndroid Build Coastguard Worker 320*6dbdd20aSAndroid Build Coastguard Worker updateTOC(); 321*6dbdd20aSAndroid Build Coastguard Worker setupSearch(); 322*6dbdd20aSAndroid Build Coastguard Worker 323*6dbdd20aSAndroid Build Coastguard Worker // Enable animations only after the load event. This is to prevent glitches 324*6dbdd20aSAndroid Build Coastguard Worker // when switching pages. 325*6dbdd20aSAndroid Build Coastguard Worker document.documentElement.style.setProperty('--anim-enabled', '1') 326*6dbdd20aSAndroid Build Coastguard Worker}); 327*6dbdd20aSAndroid Build Coastguard Worker 328*6dbdd20aSAndroid Build Coastguard Worker// Handles redirects from the old docs.perfetto.dev. 329*6dbdd20aSAndroid Build Coastguard Workerconst legacyRedirectMap = { 330*6dbdd20aSAndroid Build Coastguard Worker '#/contributing': '/docs/contributing/getting-started#community', 331*6dbdd20aSAndroid Build Coastguard Worker '#/build-instructions': '/docs/contributing/build-instructions', 332*6dbdd20aSAndroid Build Coastguard Worker '#/testing': '/docs/contributing/testing', 333*6dbdd20aSAndroid Build Coastguard Worker '#/app-instrumentation': '/docs/instrumentation/tracing-sdk', 334*6dbdd20aSAndroid Build Coastguard Worker '#/recording-traces': '/docs/instrumentation/tracing-sdk#recording', 335*6dbdd20aSAndroid Build Coastguard Worker '#/running': '/docs/quickstart/android-tracing', 336*6dbdd20aSAndroid Build Coastguard Worker '#/long-traces': '/docs/concepts/config#long-traces', 337*6dbdd20aSAndroid Build Coastguard Worker '#/detached-mode': '/docs/concepts/detached-mode', 338*6dbdd20aSAndroid Build Coastguard Worker '#/heapprofd': '/docs/data-sources/native-heap-profiler', 339*6dbdd20aSAndroid Build Coastguard Worker '#/java-hprof': '/docs/data-sources/java-heap-profiler', 340*6dbdd20aSAndroid Build Coastguard Worker '#/trace-processor': '/docs/analysis/trace-processor', 341*6dbdd20aSAndroid Build Coastguard Worker '#/analysis': '/docs/analysis/trace-processor#annotations', 342*6dbdd20aSAndroid Build Coastguard Worker '#/metrics': '/docs/analysis/metrics', 343*6dbdd20aSAndroid Build Coastguard Worker '#/traceconv': '/docs/quickstart/traceconv', 344*6dbdd20aSAndroid Build Coastguard Worker '#/clock-sync': '/docs/concepts/clock-sync', 345*6dbdd20aSAndroid Build Coastguard Worker '#/architecture': '/docs/concepts/service-model', 346*6dbdd20aSAndroid Build Coastguard Worker}; 347*6dbdd20aSAndroid Build Coastguard Worker 348*6dbdd20aSAndroid Build Coastguard Workerconst fragment = location.hash.split('?')[0].replace('.md', ''); 349*6dbdd20aSAndroid Build Coastguard Workerif (fragment in legacyRedirectMap) { 350*6dbdd20aSAndroid Build Coastguard Worker location.replace(legacyRedirectMap[fragment]); 351*6dbdd20aSAndroid Build Coastguard Worker} 352*6dbdd20aSAndroid Build Coastguard Worker 353*6dbdd20aSAndroid Build Coastguard Worker// Pages which have been been removed/renamed/moved and need to be redirected 354*6dbdd20aSAndroid Build Coastguard Worker// to their new home. 355*6dbdd20aSAndroid Build Coastguard Workerconst redirectMap = { 356*6dbdd20aSAndroid Build Coastguard Worker // stdlib docs is not a perfect replacement but is good enough until we write 357*6dbdd20aSAndroid Build Coastguard Worker // a proper, Android specific query codelab page. 358*6dbdd20aSAndroid Build Coastguard Worker // TODO(lalitm): switch to that page when it's ready. 359*6dbdd20aSAndroid Build Coastguard Worker '/docs/analysis/common-queries': '/docs/analysis/stdlib-docs', 360*6dbdd20aSAndroid Build Coastguard Worker}; 361*6dbdd20aSAndroid Build Coastguard Worker 362*6dbdd20aSAndroid Build Coastguard Workerif (location.pathname in redirectMap) { 363*6dbdd20aSAndroid Build Coastguard Worker location.replace(redirectMap[location.pathname]); 364*6dbdd20aSAndroid Build Coastguard Worker} 365