diff options
author | Travis CI <julien.tanguy@jhome.fr> | 2016-01-16 10:32:55 +0000 |
---|---|---|
committer | Travis CI <julien.tanguy@jhome.fr> | 2016-01-16 10:32:55 +0000 |
commit | 19f6782ef4a09195abf9c45acde992e5b3147853 (patch) | |
tree | 61f2d2732db5746bce4a684a3a8ed61f4fe68cc4 /haddock-util.js | |
download | hmacaroons-19f6782ef4a09195abf9c45acde992e5b3147853.tar.gz hmacaroons-19f6782ef4a09195abf9c45acde992e5b3147853.tar.zst hmacaroons-19f6782ef4a09195abf9c45acde992e5b3147853.zip |
Deploy to GitHub Pagesgh-pages
Diffstat (limited to 'haddock-util.js')
-rw-r--r-- | haddock-util.js | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/haddock-util.js b/haddock-util.js new file mode 100644 index 0000000..9a6fccf --- /dev/null +++ b/haddock-util.js | |||
@@ -0,0 +1,344 @@ | |||
1 | // Haddock JavaScript utilities | ||
2 | |||
3 | var rspace = /\s\s+/g, | ||
4 | rtrim = /^\s+|\s+$/g; | ||
5 | |||
6 | function spaced(s) { return (" " + s + " ").replace(rspace, " "); } | ||
7 | function trim(s) { return s.replace(rtrim, ""); } | ||
8 | |||
9 | function hasClass(elem, value) { | ||
10 | var className = spaced(elem.className || ""); | ||
11 | return className.indexOf( " " + value + " " ) >= 0; | ||
12 | } | ||
13 | |||
14 | function addClass(elem, value) { | ||
15 | var className = spaced(elem.className || ""); | ||
16 | if ( className.indexOf( " " + value + " " ) < 0 ) { | ||
17 | elem.className = trim(className + " " + value); | ||
18 | } | ||
19 | } | ||
20 | |||
21 | function removeClass(elem, value) { | ||
22 | var className = spaced(elem.className || ""); | ||
23 | className = className.replace(" " + value + " ", " "); | ||
24 | elem.className = trim(className); | ||
25 | } | ||
26 | |||
27 | function toggleClass(elem, valueOn, valueOff, bool) { | ||
28 | if (bool == null) { bool = ! hasClass(elem, valueOn); } | ||
29 | if (bool) { | ||
30 | removeClass(elem, valueOff); | ||
31 | addClass(elem, valueOn); | ||
32 | } | ||
33 | else { | ||
34 | removeClass(elem, valueOn); | ||
35 | addClass(elem, valueOff); | ||
36 | } | ||
37 | return bool; | ||
38 | } | ||
39 | |||
40 | |||
41 | function makeClassToggle(valueOn, valueOff) | ||
42 | { | ||
43 | return function(elem, bool) { | ||
44 | return toggleClass(elem, valueOn, valueOff, bool); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | toggleShow = makeClassToggle("show", "hide"); | ||
49 | toggleCollapser = makeClassToggle("collapser", "expander"); | ||
50 | |||
51 | function toggleSection(id) | ||
52 | { | ||
53 | var b = toggleShow(document.getElementById("section." + id)); | ||
54 | toggleCollapser(document.getElementById("control." + id), b); | ||
55 | rememberCollapsed(id, b); | ||
56 | return b; | ||
57 | } | ||
58 | |||
59 | var collapsed = {}; | ||
60 | function rememberCollapsed(id, b) | ||
61 | { | ||
62 | if(b) | ||
63 | delete collapsed[id] | ||
64 | else | ||
65 | collapsed[id] = null; | ||
66 | |||
67 | var sections = []; | ||
68 | for(var i in collapsed) | ||
69 | { | ||
70 | if(collapsed.hasOwnProperty(i)) | ||
71 | sections.push(i); | ||
72 | } | ||
73 | // cookie specific to this page; don't use setCookie which sets path=/ | ||
74 | document.cookie = "collapsed=" + escape(sections.join('+')); | ||
75 | } | ||
76 | |||
77 | function restoreCollapsed() | ||
78 | { | ||
79 | var cookie = getCookie("collapsed"); | ||
80 | if(!cookie) | ||
81 | return; | ||
82 | |||
83 | var ids = cookie.split('+'); | ||
84 | for(var i in ids) | ||
85 | { | ||
86 | if(document.getElementById("section." + ids[i])) | ||
87 | toggleSection(ids[i]); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | function setCookie(name, value) { | ||
92 | document.cookie = name + "=" + escape(value) + ";path=/;"; | ||
93 | } | ||
94 | |||
95 | function clearCookie(name) { | ||
96 | document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;"; | ||
97 | } | ||
98 | |||
99 | function getCookie(name) { | ||
100 | var nameEQ = name + "="; | ||
101 | var ca = document.cookie.split(';'); | ||
102 | for(var i=0;i < ca.length;i++) { | ||
103 | var c = ca[i]; | ||
104 | while (c.charAt(0)==' ') c = c.substring(1,c.length); | ||
105 | if (c.indexOf(nameEQ) == 0) { | ||
106 | return unescape(c.substring(nameEQ.length,c.length)); | ||
107 | } | ||
108 | } | ||
109 | return null; | ||
110 | } | ||
111 | |||
112 | |||
113 | |||
114 | var max_results = 75; // 50 is not enough to search for map in the base libraries | ||
115 | var shown_range = null; | ||
116 | var last_search = null; | ||
117 | |||
118 | function quick_search() | ||
119 | { | ||
120 | perform_search(false); | ||
121 | } | ||
122 | |||
123 | function full_search() | ||
124 | { | ||
125 | perform_search(true); | ||
126 | } | ||
127 | |||
128 | |||
129 | function perform_search(full) | ||
130 | { | ||
131 | var text = document.getElementById("searchbox").value.toLowerCase(); | ||
132 | if (text == last_search && !full) return; | ||
133 | last_search = text; | ||
134 | |||
135 | var table = document.getElementById("indexlist"); | ||
136 | var status = document.getElementById("searchmsg"); | ||
137 | var children = table.firstChild.childNodes; | ||
138 | |||
139 | // first figure out the first node with the prefix | ||
140 | var first = bisect(-1); | ||
141 | var last = (first == -1 ? -1 : bisect(1)); | ||
142 | |||
143 | if (first == -1) | ||
144 | { | ||
145 | table.className = ""; | ||
146 | status.innerHTML = "No results found, displaying all"; | ||
147 | } | ||
148 | else if (first == 0 && last == children.length - 1) | ||
149 | { | ||
150 | table.className = ""; | ||
151 | status.innerHTML = ""; | ||
152 | } | ||
153 | else if (last - first >= max_results && !full) | ||
154 | { | ||
155 | table.className = ""; | ||
156 | status.innerHTML = "More than " + max_results + ", press Search to display"; | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | // decide what you need to clear/show | ||
161 | if (shown_range) | ||
162 | setclass(shown_range[0], shown_range[1], "indexrow"); | ||
163 | setclass(first, last, "indexshow"); | ||
164 | shown_range = [first, last]; | ||
165 | table.className = "indexsearch"; | ||
166 | status.innerHTML = ""; | ||
167 | } | ||
168 | |||
169 | |||
170 | function setclass(first, last, status) | ||
171 | { | ||
172 | for (var i = first; i <= last; i++) | ||
173 | { | ||
174 | children[i].className = status; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | |||
179 | // do a binary search, treating 0 as ... | ||
180 | // return either -1 (no 0's found) or location of most far match | ||
181 | function bisect(dir) | ||
182 | { | ||
183 | var first = 0, finish = children.length - 1; | ||
184 | var mid, success = false; | ||
185 | |||
186 | while (finish - first > 3) | ||
187 | { | ||
188 | mid = Math.floor((finish + first) / 2); | ||
189 | |||
190 | var i = checkitem(mid); | ||
191 | if (i == 0) i = dir; | ||
192 | if (i == -1) | ||
193 | finish = mid; | ||
194 | else | ||
195 | first = mid; | ||
196 | } | ||
197 | var a = (dir == 1 ? first : finish); | ||
198 | var b = (dir == 1 ? finish : first); | ||
199 | for (var i = b; i != a - dir; i -= dir) | ||
200 | { | ||
201 | if (checkitem(i) == 0) return i; | ||
202 | } | ||
203 | return -1; | ||
204 | } | ||
205 | |||
206 | |||
207 | // from an index, decide what the result is | ||
208 | // 0 = match, -1 is lower, 1 is higher | ||
209 | function checkitem(i) | ||
210 | { | ||
211 | var s = getitem(i).toLowerCase().substr(0, text.length); | ||
212 | if (s == text) return 0; | ||
213 | else return (s > text ? -1 : 1); | ||
214 | } | ||
215 | |||
216 | |||
217 | // from an index, get its string | ||
218 | // this abstracts over alternates | ||
219 | function getitem(i) | ||
220 | { | ||
221 | for ( ; i >= 0; i--) | ||
222 | { | ||
223 | var s = children[i].firstChild.firstChild.data; | ||
224 | if (s.indexOf(' ') == -1) | ||
225 | return s; | ||
226 | } | ||
227 | return ""; // should never be reached | ||
228 | } | ||
229 | } | ||
230 | |||
231 | function setSynopsis(filename) { | ||
232 | if (parent.window.synopsis) { | ||
233 | if (parent.window.synopsis.location.replace) { | ||
234 | // In Firefox this avoids adding the change to the history. | ||
235 | parent.window.synopsis.location.replace(filename); | ||
236 | } else { | ||
237 | parent.window.synopsis.location = filename; | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | |||
242 | function addMenuItem(html) { | ||
243 | var menu = document.getElementById("page-menu"); | ||
244 | if (menu) { | ||
245 | var btn = menu.firstChild.cloneNode(false); | ||
246 | btn.innerHTML = html; | ||
247 | menu.appendChild(btn); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | function adjustForFrames() { | ||
252 | var bodyCls; | ||
253 | |||
254 | if (parent.location.href == window.location.href) { | ||
255 | // not in frames, so add Frames button | ||
256 | addMenuItem("<a href='#' onclick='reframe();return true;'>Frames</a>"); | ||
257 | bodyCls = "no-frame"; | ||
258 | } | ||
259 | else { | ||
260 | bodyCls = "in-frame"; | ||
261 | } | ||
262 | addClass(document.body, bodyCls); | ||
263 | } | ||
264 | |||
265 | function reframe() { | ||
266 | setCookie("haddock-reframe", document.URL); | ||
267 | window.location = "frames.html"; | ||
268 | } | ||
269 | |||
270 | function postReframe() { | ||
271 | var s = getCookie("haddock-reframe"); | ||
272 | if (s) { | ||
273 | parent.window.main.location = s; | ||
274 | clearCookie("haddock-reframe"); | ||
275 | } | ||
276 | } | ||
277 | |||
278 | function styles() { | ||
279 | var i, a, es = document.getElementsByTagName("link"), rs = []; | ||
280 | for (i = 0; a = es[i]; i++) { | ||
281 | if(a.rel.indexOf("style") != -1 && a.title) { | ||
282 | rs.push(a); | ||
283 | } | ||
284 | } | ||
285 | return rs; | ||
286 | } | ||
287 | |||
288 | function addStyleMenu() { | ||
289 | var as = styles(); | ||
290 | var i, a, btns = ""; | ||
291 | for(i=0; a = as[i]; i++) { | ||
292 | btns += "<li><a href='#' onclick=\"setActiveStyleSheet('" | ||
293 | + a.title + "'); return false;\">" | ||
294 | + a.title + "</a></li>" | ||
295 | } | ||
296 | if (as.length > 1) { | ||
297 | var h = "<div id='style-menu-holder'>" | ||
298 | + "<a href='#' onclick='styleMenu(); return false;'>Style ▾</a>" | ||
299 | + "<ul id='style-menu' class='hide'>" + btns + "</ul>" | ||
300 | + "</div>"; | ||
301 | addMenuItem(h); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | function setActiveStyleSheet(title) { | ||
306 | var as = styles(); | ||
307 | var i, a, found; | ||
308 | for(i=0; a = as[i]; i++) { | ||
309 | a.disabled = true; | ||
310 | // need to do this always, some browsers are edge triggered | ||
311 | if(a.title == title) { | ||
312 | found = a; | ||
313 | } | ||
314 | } | ||
315 | if (found) { | ||
316 | found.disabled = false; | ||
317 | setCookie("haddock-style", title); | ||
318 | } | ||
319 | else { | ||
320 | as[0].disabled = false; | ||
321 | clearCookie("haddock-style"); | ||
322 | } | ||
323 | styleMenu(false); | ||
324 | } | ||
325 | |||
326 | function resetStyle() { | ||
327 | var s = getCookie("haddock-style"); | ||
328 | if (s) setActiveStyleSheet(s); | ||
329 | } | ||
330 | |||
331 | |||
332 | function styleMenu(show) { | ||
333 | var m = document.getElementById('style-menu'); | ||
334 | if (m) toggleShow(m, show); | ||
335 | } | ||
336 | |||
337 | |||
338 | function pageLoad() { | ||
339 | addStyleMenu(); | ||
340 | adjustForFrames(); | ||
341 | resetStyle(); | ||
342 | restoreCollapsed(); | ||
343 | } | ||
344 | |||