1// Common functionality for PLT documentation pages 2 3// Page Parameters ------------------------------------------------------------ 4 5function GetURL() { 6 return new URL(location); 7} 8 9function GetPageArgs() { 10 return GetURL().searchParams; 11} 12 13function GetPageQueryString() { 14 return GetPageArgs().toString(); 15} 16 17function GetPageArg(key, def) { 18 return GetPageArgs().get(key) || def; 19} 20 21function MergePageArgsIntoLink(a) { 22 if (GetPageArgs().size === 0 || !a.dataset.pltdoc) return; 23 a.href = MergePageArgsIntoUrl(a.href); 24} 25 26function MergePageArgsIntoUrl(href) { 27 const url = new URL(href, window.location.href); 28 for (const [key, val] of GetPageArgs()) { 29 if (url.searchParams.has(key)) continue; 30 url.searchParams.append(key, val) 31 } 32 return url.href; 33} 34 35// Cookies -------------------------------------------------------------------- 36 37// Actually, try localStorage (a la HTML 5), first. 38 39function GetCookie(key, def) { 40 try { 41 var v = localStorage[key]; 42 if (!v) v = def; 43 return v; 44 } catch (e) { 45 var i, cookiestrs; 46 try { 47 if (document.cookie.length <= 0) return def; 48 cookiestrs = document.cookie.split(/; */); 49 } catch (e) { return def; } 50 for (i = 0; i < cookiestrs.length; i++) { 51 var cur = cookiestrs[i]; 52 var eql = cur.indexOf('='); 53 if (eql >= 0 && cur.substring(0,eql) == key) 54 return unescape(cur.substring(eql+1)); 55 } 56 return def; 57 } 58} 59 60function SetCookie(key, val) { 61 try { 62 localStorage[key] = val; 63 } catch(e) { 64 var d = new Date(); 65 d.setTime(d.getTime()+(365*24*60*60*1000)); 66 try { 67 document.cookie = 68 key + "=" + escape(val) + "; expires="+ d.toGMTString() + "; path=/"; 69 } catch (e) {} 70 } 71} 72 73// note that this always stores a directory name, ending with a "/" 74function SetPLTRoot(ver, relative) { 75 var root = location.protocol + "//" + location.host 76 + NormalizePath(location.pathname.replace(/[^\/]*$/, relative)); 77 SetCookie("PLT_Root."+ver, root); 78} 79 80// adding index.html works because of the above 81function GotoPLTRoot(ver, relative) { 82 var u = GetRootPath(ver); 83 if (u == null) return true; // no cookie: use plain up link 84 // the relative path is optional, default goes to the toplevel start page 85 if (!relative) relative = "index.html"; 86 location = u + relative; 87 return false; 88} 89 90function GetRootPath(ver) { 91 var u = GetCookie("PLT_Root."+ver, null); 92 if (u != null) 93 return u; 94 // use root specified by local-redirect wrapper, if present 95 if (typeof user_doc_root != "undefined") 96 return user_doc_root; 97 return null; 98} 99 100// Utilities ------------------------------------------------------------------ 101 102var normalize_rxs = [/\/\/+/g, /\/\.(\/|$)/, /\/[^\/]*\/\.\.(\/|$)/]; 103function NormalizePath(path) { 104 var tmp, i; 105 for (i = 0; i < normalize_rxs.length; i++) 106 while ((tmp = path.replace(normalize_rxs[i], "/")) != path) path = tmp; 107 return path; 108} 109 110// `noscript' is problematic in some browsers (always renders as a 111// block), use this hack instead (does not always work!) 112// document.write("<style>mynoscript { display:none; }</style>"); 113 114// Interactions --------------------------------------------------------------- 115 116function DoSearchKey(event, field, ver, top_path) { 117 var val = field.value; 118 if (event && event.key === 'Enter') { 119 var u = GetRootPath(ver); 120 if (u == null) u = top_path; // default: go to the top path 121 u += "search/index.html?q=" + encodeURIComponent(val); 122 u = MergePageArgsIntoUrl(u); 123 location = u; 124 return false; 125 } 126 return true; 127} 128 129function TocviewToggle(glyph, id) { 130 var s = document.getElementById(id).style; 131 var expand = s.display == "none"; 132 s.display = expand ? "block" : "none"; 133 glyph.innerHTML = expand ? "▼" : "►"; 134} 135 136function TocsetToggle() { 137 document.body.classList.toggle("tocsetoverlay"); 138} 139 140// Page Init ------------------------------------------------------------------ 141 142// Note: could make a function that inspects and uses window.onload to chain to 143// a previous one, but this file needs to be required first anyway, since it 144// contains utilities for all other files.
145var on_load_funcs = []; 146function AddOnLoad(fun) { on_load_funcs.push(fun); } 147window.onload = function() { 148 for (var i=0; i<on_load_funcs.length; i++) on_load_funcs[i](); 149}; 150 151AddOnLoad(function(){ 152 var links = document.getElementsByTagName("a"); 153 for (var i=0; i<links.length; i++) MergePageArgsIntoLink(links[i]); 154 var label = GetPageArg("ctxtname",false); 155 if (!label) return; 156 var indicator = document.getElementById("contextindicator"); 157 if (!indicator) return; 158 indicator.innerHTML = label; 159 indicator.style.display = "block"; 160 }); 161 162// Pressing "S" or "s" focuses on the "...search manuals..." text field 163AddOnLoad(function(){ 164 window.addEventListener("keyup", function(e) { 165 if ((e.key === 's' || e.key === 'S') && e.target === document.body) { 166 var searchBox = document.getElementById('searchbox'); 167 if (searchBox) { 168 searchBox.focus(); 169 } 170 } 171 }, false); 172});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.