Corrected some typos and errors in the help docs
[supercollider.git] / HelpSource / scdoc.js
blob89731e611f62a48337c16f4fc59632dcd92c7cb8
1 function toggle_visibility(e) {
2 if(e.style.display == 'none') {
3 e.style.display = 'block';
4 return e;
5 } else {
6 e.style.display = 'none';
7 return undefined;
12 function createCookie(name,value,days) {
13 if (days) {
14 var date = new Date();
15 date.setTime(date.getTime()+(days*24*60*60*1000));
16 var expires = "; expires="+date.toGMTString();
18 else var expires = "";
19 document.cookie = name+"="+value+expires+"; path=/";
22 function readCookie(name) {
23 var nameEQ = name + "=";
24 var ca = document.cookie.split(';');
25 for(var i=0;i < ca.length;i++) {
26 var c = ca[i];
27 while (c.charAt(0)==' ') c = c.substring(1,c.length);
28 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
30 return null;
34 var storage;
35 var sidetoc;
36 var toc;
37 var menubar;
38 var allItems;
39 function popOutTOC(original_toc, p0) {
40 var t = original_toc.cloneNode(true);
41 t.id = "sidetoc";
42 var c = document.getElementsByClassName("contents")[0];
43 var left = c.style.marginLeft;
44 c.style.marginLeft = "20.5em";
45 document.body.insertBefore(t,c);
47 t.getElementsByClassName("toc_search")[0].getElementsByTagName("input")[0].onkeyup = toc_search;
49 t.style.top = menubar.clientHeight;
50 t.style.maxHeight = "none";
51 t.style.display = "block";
53 var p = t.getElementsByClassName("popoutlink")[0];
54 p.innerHTML = "close";
55 p.onclick = function() {
56 t.parentNode.removeChild(t);
57 c.style.marginLeft = left;
58 p0.style.display = "";
59 sidetoc = null;
60 allItems = toc.getElementsByTagName("ul")[0].getElementsByTagName("li");
61 storage.popToc = "no";
62 return false;
64 var x = document.createElement("div");
65 x.id = "toctitle";
66 x.innerHTML = "Table of contents";
67 t.insertBefore(x,p.nextSibling);
68 p0.style.display = "none";
70 sidetoc = t;
71 allItems = t.getElementsByTagName("ul")[0].getElementsByTagName("li");
72 resize_handler();
73 storage.popToc = "yes";
76 function resize_handler() {
77 var height = window.innerHeight - menubar.clientHeight - 20;
78 if(sidetoc)
79 sidetoc.style.height = height;
80 if(toc)
81 toc.style.maxHeight = height * 0.75;
84 function addInheritedMethods() {
85 if(! /\/Classes\/[^\/]+/.test(window.location.pathname)) return; // skip this if not a class doc
86 var doc = docmap["Classes/"+document.title];
87 if(!doc) return;
88 if(doc.implementor) {
89 var sups = docmap["Classes/"+doc.implementor].superclasses;
90 } else {
91 var sups = doc.superclasses;
93 if(!sups) return;
94 var divs = [document.getElementById("inheritedclassmets"), document.getElementById("inheritedinstmets")];
95 for(var i=0;i<sups.length;i++) {
96 var s = docmap["Classes/"+sups[i]];
97 var d = [];
98 for(var j=0;j<2;j++) {
99 d[j] = document.createElement("ul");
100 d[j].className = "inheritedmets";
101 d[j].style.display = "none";
103 var mets = s.methods.sort();
104 for(var j=0;j<mets.length;j++) {
105 var m = mets[j];
106 if(doc.methods.indexOf("_"+m.slice(1))<0) { // ignore methods already documented in this helpfile
107 var li = document.createElement("li");
108 li.innerHTML = "<a href='"+helpRoot+"/"+s.path+".html#"+m.slice(1)+"'>"+m.slice(2)+"</a>";
109 if(m[1]=="*") {
110 d[0].appendChild(li);
111 } else
112 if(m[1]=="-") {
113 d[1].appendChild(li);
117 for(var j=0;j<2;j++) {
118 var count = d[j].childElementCount;
119 if(count) {
120 var x = document.createElement("div");
121 var show = "&#9658; show";
122 var hide = "&#9660; hide";
123 x.className = "inheritedmets_class";
124 x.innerHTML = count+" methods from <a href='"+helpRoot+"/"+s.path+".html'>"+s.title+"</a> ";
125 divs[j].appendChild(x);
126 (function(z) {
127 var a = document.createElement("a");
128 a.className = "inheritedmets_toggle";
129 a.setAttribute("href","#");
130 a.innerHTML = show;
131 a.onclick = function() {
132 if(z.style.display == "none") {
133 z.style.display = "block";
134 a.innerHTML = hide;
135 } else {
136 z.style.display = "none";
137 a.innerHTML = show;
139 return false;
141 x.appendChild(a);
142 })(d[j]);
143 divs[j].appendChild(d[j]);
149 function showAllSubclasses(a) {
150 var e = document.getElementById("hiddensubclasses");
151 e.style.display = "";
152 a.style.display = "none";
156 This key event handler selects the whole line when pressing shift/ctrl-enter with no selection.
157 But the problem is that it does not update the selection sent to the client.
158 This is probably because the WebView catches the key event before javascript does!
159 A fix might be to expose a function to JS that evaluates selection, and call it here.
160 Or can the WebView make sure that JS has responded to all key events before getting the selection?
162 function selectLine() {
163 var s = window.getSelection();
164 var r = s.getRangeAt();
166 function findleft(p) {
167 var y, j;
168 while(p) {
169 if(p.nodeName == "BR")
170 return [p,j];
171 if(p.childNodes.length>0) {
172 for(var i=p.childNodes.length-1;i>=0;i--) {
173 y = findleft(p.childNodes[i]);
174 if(y) return y;
177 p = p.previousSibling;
179 return null;
182 function findright(p) {
183 var y, j;
184 while(p) {
185 if(p.nodeName == "BR")
186 return [p,j];
187 for(var i=0;i<p.childNodes.length;i++) {
188 y = findright(p.childNodes[i]);
189 if(y) return y;
191 p = p.nextSibling;
193 return null;
197 if(r.collapsed) {
198 var r2 = document.createRange();
199 var top = r.startContainer;
200 while(top && top.nodeName != "PRE")
201 top = top.parentNode;
203 var p = r.startContainer;
204 while(!p.previousSibling && p != top) {
205 p = p.parentNode;
207 if(p==top) {
208 r2.setStartBefore(top.firstChild);
209 } else {
210 var found = findleft(p.previousSibling);
211 if(found) {
212 r2.setStartAfter(found[0]);
213 } else {
214 r2.setStartBefore(top.firstChild);
217 var p = r.startContainer;
218 while(!p.nextSibling && p != top) {
219 p = p.parentNode;
221 if(p==top) {
222 r2.setEndAfter(top.lastChild);
223 } else {
224 var found = findright(p.nextSibling);
225 if(found) {
226 r2.setEndBefore(found[0]);
227 } else {
228 r2.setEndAfter(top.lastChild);
231 s.removeAllRanges();
232 s.addRange(r2);
236 function countChar(str,chr) {
237 var x = 0, a, b;
238 for(var i=0;i<str.length;i++) {
239 if(str[i]==chr) {
240 if(a==undefined) a = i;
241 b = i;
242 x++;
245 // return count, first occurence and last occurence
246 return [x,a,b];
249 var code_click_node;
250 var code_click_pos;
252 function selectParens(ev) {
253 var s = window.getSelection();
254 var r = s.getRangeAt();
255 var r2 = document.createRange();
256 var j;
258 function countChars(char, counterChar, text, count, back)
260 var len = text.length;
261 var i;
262 if(back) {
263 for(i=len-1; i>=0; i--) {
264 var c = text.charAt(i);
265 if(c == char) count--;
266 else if(c == counterChar) count++;
267 if( count < 1 ) break;
270 else {
271 for(i=0; i<len; i++) {
272 var c = text.charAt(i);
273 if(c == char) count--;
274 else if(c == counterChar) count++;
275 if( count < 1 ) break;
278 return [count, i];
281 function advance(node, top, back) {
282 var childs = node.childNodes;
283 if(childs && childs.length) {
284 var child = back ? childs[childs.length-1] : childs[0];
285 return child;
287 else {
288 var next;
289 if(back) {
290 while( node != top && !(next = node.previousSibling) )
291 node = node.parentNode;
293 else {
294 while( node != top && !(next = node.nextSibling) )
295 node = node.parentNode;
297 return next;
301 function findChar(char, counterChar, top, node, back, count) {
302 do {
303 var text = node.nodeValue;
304 if(text) {
305 var res = countChars(char, counterChar, text, count, back);
306 count = res[0];
307 if(count < 1) return [node, res[1]];
309 node = advance(node, top, back);
310 } while(node);
312 return null;
315 function findAdjacentChar(top, node, pos, chars) {
316 var ok = false;
317 var text, len;
318 var i;
320 // try right:
321 text = node.nodeValue;
322 len = text.length;
323 if(text && pos < len) {
324 if( (i = chars.indexOf(text[pos])) != -1 )
325 return [chars[i], node, pos];
327 else {
328 var n = node;
329 do {
330 n = advance(n, top, false);
331 } while (n && !(text = n.nodeValue));
332 if(n && (len=text.length)) {
333 if( (i = chars.indexOf(text[0])) != -1 )
334 return [chars[i], n, 0];
338 // try left:
339 text = node.nodeValue;
340 len = text.length;
341 if(text && pos > 0) {
342 if( (i = chars.indexOf(text[pos-1])) != -1 )
343 return [chars[i], node, pos-1];
345 else {
346 n = node;
347 do {
348 n = advance(n, top, true);
349 } while (n && !(text = n.nodeValue));
350 if(n && (len=text.length)) {
351 if( (i = chars.indexOf(text[len-1])) != -1 )
352 return [chars[i], n, len-1];
356 return null;
359 if(!code_click_node) return;
361 var top = ev.target;
362 while( top && top.className.indexOf("lang-sc") == -1 )
363 top = top.parentNode;
364 if(!top) return;
366 var pos = code_click_pos;
367 var node = code_click_node; code_click_node = null;
368 var char;
370 var startRes = findAdjacentChar(top, node, pos, "()");
371 if(startRes) {
372 char = startRes[0];
373 node = startRes[1];
374 pos = startRes[2];
376 else {
377 return;
380 back = char == ")";
381 counterChar = back ? "(" : ")";
382 var count = 1, countRes;
383 var rnode, rpos;
385 // try same node
386 var text = node.nodeValue;
387 if( back) text = text.substring(0, pos);
388 else text = text.substring(pos+1);
389 countRes = countChars(counterChar, char, text, count, back);
390 count = countRes[0];
391 if( count < 1 ) {
392 rpos = countRes[1];
393 if(!back) rpos += pos + 1;
394 rnode = node;
396 else {
397 // try other nodes
398 var n = advance(node, top, back);
399 res = findChar(counterChar, char, top, n, back, count);
400 if(res) {
401 rnode = res[0];
402 rpos = res[1];
406 if(rnode) {
407 if(back) {
408 r2.setStart(rnode, rpos);
409 r2.setEnd(node, pos+1);
411 else {
412 r2.setStart(node, pos);
413 r2.setEnd(rnode, rpos+1);
415 s.removeAllRanges();
416 s.addRange(r2);
420 escape_regexp = function(str) {
421 var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
422 return str.replace(specials, "\\$&");
425 function toc_search(ev) {
426 //TODO: on enter, go to first match
427 var re = RegExp("^"+escape_regexp(ev.target.value),"i");
428 for(var i=0;i<allItems.length;i++) {
429 var li = allItems[i];
430 var a = li.firstChild;
431 if(re.test(a.innerHTML)) {
432 li.style.display = "";
433 var lev = li.className[3];
434 for(var i2 = i-1;i2>=0;i2--) {
435 var e = allItems[i2];
436 if(e.className[3]<lev) {
437 e.style.display = "";
438 lev -= 1;
440 if(e.className[3]==1) break;
442 } else {
443 li.style.display = "none";
448 function fixTOC() {
449 var x = document.getElementsByClassName("lang-sc");
450 for(var i=0;i<x.length;i++) {
451 var e = x[i];
453 // make all code examples editable!
454 e.setAttribute("contentEditable",true);
456 // select parenthesis on double-click
457 e.onclick = function(ev) {
458 var r = window.getSelection().getRangeAt(0);
459 if(r.collapsed) {
460 code_click_node = r.startContainer;
461 code_click_pos = r.startOffset;
464 e.ondblclick = selectParens;
467 addInheritedMethods();
469 if('localStorage' in window) {
470 storage = window.localStorage;
471 } else {
472 storage = {};
475 var openMenu;
476 var inMenu = false;
478 var toggleMenu = function(e) {
479 if(openMenu) {
480 openMenu.style.display = 'none';
482 if(e != openMenu) {
483 e.style.display = 'block';
484 openMenu = e;
485 } else {
486 openMenu = undefined;
488 inMenu = true;
491 document.onclick = function(e) {
492 if(openMenu && !inMenu && e.target.id!="toc_search") {
493 openMenu.style.display = 'none';
494 openMenu = undefined;
496 inMenu = false;
497 return true;
500 // make header menu
501 var bar = document.getElementById("menubar");
502 menubar = bar;
503 var nav = ["Home","Browse","Search"];
504 var url = ["Help.html","Browse.html","Search.html"];
505 for(var i=0;i<nav.length;i++) {
506 var li = document.createElement("li");
507 li.className = "menuitem";
508 var a = document.createElement("a");
509 a.innerHTML = nav[i];
510 a.setAttribute("href",helpRoot+"/"+url[i]);
511 a.className = "navLink";
512 li.appendChild(a);
513 bar.appendChild(li);
516 var li = document.createElement("li");
517 li.className = "menuitem";
518 var a = document.createElement("a");
519 a.innerHTML = "Indexes &#9660;";
520 a.setAttribute("href","#");
521 var m1 = document.createElement("div");
522 m1.className = "submenu";
523 m1.style.display = "none";
524 a.onclick = function() {
525 toggleMenu(m1);
526 return false;
528 var nav = ["Documents","Classes","Methods"];
529 for(var i=0;i<nav.length;i++) {
530 var b = document.createElement("a");
531 b.setAttribute("href",helpRoot+"/Overviews/"+nav[i]+".html");
532 b.innerHTML = nav[i];
533 m1.appendChild(b);
535 li.appendChild(a);
536 li.appendChild(m1);
537 bar.appendChild(li);
539 var li = document.createElement("li");
540 li.className = "menuitem";
541 var x = document.createElement("span");
542 x.id = "topdoctitle";
543 x.appendChild(document.createTextNode(document.title));
544 x.onclick = function() {
545 scroll(0,0);
546 return false;
548 li.appendChild(x)
549 bar.appendChild(li);
551 var t = document.getElementById("toc");
552 toc = t;
553 if(t) {
554 var div = document.createElement("span");
555 div.className = "toc_search";
556 var ts = document.createElement("input");
557 ts.type = "text";
558 ts.id = "toc_search";
559 ts.value = "";
560 ts.style.border = "1px solid #ddd";
561 allItems = toc.getElementsByTagName("ul")[0].getElementsByTagName("li");
562 ts.onkeyup = toc_search;
563 div.appendChild(document.createTextNode("Filter:"));
564 div.appendChild(ts);
565 t.insertBefore(div,t.firstChild);
567 x.appendChild(document.createTextNode(" - "));
568 t.style.display = 'none';
570 var a = document.createElement("a");
571 a.setAttribute("href","#");
572 a.innerHTML = "Table of contents &#9660;";
573 li.appendChild(a);
574 a.onclick = function() {
575 ts.focus();
576 toggleMenu(t);
577 return false;
579 li.appendChild(t.parentNode.removeChild(t));
580 var p = document.createElement("a");
581 p.setAttribute("href","#");
582 p.className = "popoutlink";
583 p.innerHTML = "pop out";
584 p.onclick = function() {
585 if(!sidetoc)
586 popOutTOC(t,a);
587 return false;
589 t.insertBefore(p,t.firstChild);
590 resize_handler();
591 if(storage.popToc == "yes") {
592 popOutTOC(t,a);
595 window.onresize = resize_handler;