scribble-common.js (5466B)
1 // Common functionality for PLT documentation pages 2 3 // Page Parameters ------------------------------------------------------------ 4 5 var page_query_string = location.search.substring(1); 6 7 var page_args = 8 ((function(){ 9 if (!page_query_string) return []; 10 var args = page_query_string.split(/[&;]/); 11 for (var i=0; i<args.length; i++) { 12 var a = args[i]; 13 var p = a.indexOf('='); 14 if (p >= 0) args[i] = [a.substring(0,p), a.substring(p+1)]; 15 else args[i] = [a, false]; 16 } 17 return args; 18 })()); 19 20 function GetPageArg(key, def) { 21 for (var i=0; i<page_args.length; i++) 22 if (page_args[i][0] == key) return decodeURIComponent(page_args[i][1]); 23 return def; 24 } 25 26 function MergePageArgsIntoLink(a) { 27 if (page_args.length == 0 || 28 (!a.attributes["data-pltdoc"]) || (a.attributes["data-pltdoc"].value == "")) 29 return; 30 a.href = MergePageArgsIntoUrl(a.href); 31 } 32 33 function MergePageArgsIntoUrl(href) { 34 var mtch = href.match(/^([^?#]*)(?:\?([^#]*))?(#.*)?$/); 35 if (mtch == undefined) { // I think this never happens 36 return "?" + page_query_string; 37 } 38 if (!mtch[2]) { 39 return mtch[1] + "?" + page_query_string + (mtch[3] || ""); 40 } 41 // need to merge here, precedence to arguments that exist in `a' 42 var i, j; 43 var prefix = mtch[1], str = mtch[2] || "", suffix = mtch[3] || ""; 44 var args = str.split(/[&;]/); 45 for (i=0; i<args.length; i++) { 46 j = args[i].indexOf('='); 47 if (j) args[i] = args[i].substring(0,j); 48 } 49 var additions = ""; 50 for (i=0; i<page_args.length; i++) { 51 var exists = false; 52 for (j=0; j<args.length; j++) 53 if (args[j] == page_args[i][0]) { exists = true; break; } 54 if (!exists) str += "&" + page_args[i][0] + "=" + page_args[i][1]; 55 } 56 return prefix + "?" + str + suffix; 57 } 58 59 // Cookies -------------------------------------------------------------------- 60 61 // Actually, try localStorage (a la HTML 5), first. 62 63 function GetCookie(key, def) { 64 try { 65 var v = localStorage[key]; 66 if (!v) v = def; 67 return v; 68 } catch (e) { 69 var i, cookiestrs; 70 try { 71 if (document.cookie.length <= 0) return def; 72 cookiestrs = document.cookie.split(/; */); 73 } catch (e) { return def; } 74 for (i = 0; i < cookiestrs.length; i++) { 75 var cur = cookiestrs[i]; 76 var eql = cur.indexOf('='); 77 if (eql >= 0 && cur.substring(0,eql) == key) 78 return unescape(cur.substring(eql+1)); 79 } 80 return def; 81 } 82 } 83 84 function SetCookie(key, val) { 85 try { 86 localStorage[key] = val; 87 } catch(e) { 88 var d = new Date(); 89 d.setTime(d.getTime()+(365*24*60*60*1000)); 90 try { 91 document.cookie = 92 key + "=" + escape(val) + "; expires="+ d.toGMTString() + "; path=/"; 93 } catch (e) {} 94 } 95 } 96 97 // note that this always stores a directory name, ending with a "/" 98 function SetPLTRoot(ver, relative) { 99 var root = location.protocol + "//" + location.host 100 + NormalizePath(location.pathname.replace(/[^\/]*$/, relative)); 101 SetCookie("PLT_Root."+ver, root); 102 } 103 104 // adding index.html works because of the above 105 function GotoPLTRoot(ver, relative) { 106 var u = GetCookie("PLT_Root."+ver, null); 107 if (u == null) return true; // no cookie: use plain up link 108 // the relative path is optional, default goes to the toplevel start page 109 if (!relative) relative = "index.html"; 110 location = u + relative; 111 return false; 112 } 113 114 // Utilities ------------------------------------------------------------------ 115 116 var normalize_rxs = [/\/\/+/g, /\/\.(\/|$)/, /\/[^\/]*\/\.\.(\/|$)/]; 117 function NormalizePath(path) { 118 var tmp, i; 119 for (i = 0; i < normalize_rxs.length; i++) 120 while ((tmp = path.replace(normalize_rxs[i], "/")) != path) path = tmp; 121 return path; 122 } 123 124 // `noscript' is problematic in some browsers (always renders as a 125 // block), use this hack instead (does not always work!) 126 // document.write("<style>mynoscript { display:none; }</style>"); 127 128 // Interactions --------------------------------------------------------------- 129 130 function DoSearchKey(event, field, ver, top_path) { 131 var val = field.value; 132 if (event && event.keyCode == 13) { 133 var u = GetCookie("PLT_Root."+ver, null); 134 if (u == null) u = top_path; // default: go to the top path 135 u += "search/index.html?q=" + encodeURIComponent(val); 136 u = MergePageArgsIntoUrl(u); 137 location = u; 138 return false; 139 } 140 return true; 141 } 142 143 function TocviewToggle(glyph, id) { 144 var s = document.getElementById(id).style; 145 var expand = s.display == "none"; 146 s.display = expand ? "block" : "none"; 147 glyph.innerHTML = expand ? "▼" : "►"; 148 } 149 150 // Page Init ------------------------------------------------------------------ 151 152 // Note: could make a function that inspects and uses window.onload to chain to 153 // a previous one, but this file needs to be required first anyway, since it 154 // contains utilities for all other files. 155 var on_load_funcs = []; 156 function AddOnLoad(fun) { on_load_funcs.push(fun); } 157 window.onload = function() { 158 for (var i=0; i<on_load_funcs.length; i++) on_load_funcs[i](); 159 }; 160 161 AddOnLoad(function(){ 162 var links = document.getElementsByTagName("a"); 163 for (var i=0; i<links.length; i++) MergePageArgsIntoLink(links[i]); 164 var label = GetPageArg("ctxtname",false); 165 if (!label) return; 166 var indicator = document.getElementById("contextindicator"); 167 if (!indicator) return; 168 indicator.innerHTML = label; 169 indicator.style.display = "block"; 170 });