Documentation: doc/html/search/search.js Source File

| Documentation For Arduino users

- Main Page
- Related Pages
- Modules
- Classes
- Files
- Examples

- File List
- File Members

search.js
1 // Search script generated by doxygen
2 // Copyright (C) 2009 by Dimitri van Heesch.
3
4 // The code in this file is loosly based on main.js, part of Natural Docs,
5 // which is Copyright (C) 2003-2008 Greg Valure
6 // Natural Docs is licensed under the GPL.
7
8 var indexSectionsWithContent =
9 {
10 };
11
12 var indexSectionNames =
13 {
14 };
15
16 function convertToId(search)
17 {
18 var result = '';
19 for (i=0;i<search.length;i++)
20 {
21 var c = search.charAt(i);
22 var cn = c.charCodeAt(0);
23 if (c.match(/[a-z0-9\u0080-\uFFFF]/))
24 {
25 result+=c;
26 }
27 else if (cn<16)
28 {
29 result+="_0"+cn.toString(16);
30 }
31 else
32 {
33 result+="_"+cn.toString(16);
34 }
35 }
36 return result;
37 }
38
39 function getXPos(item)
40 {
41 var x = 0;
42 if (item.offsetWidth)
43 {
44 while (item && item!=document.body)
45 {
46 x += item.offsetLeft;
47 item = item.offsetParent;
48 }
49 }
50 return x;
51 }
52
53 function getYPos(item)
54 {
55 var y = 0;
56 if (item.offsetWidth)
57 {
58 while (item && item!=document.body)
59 {
60 y += item.offsetTop;
61 item = item.offsetParent;
62 }
63 }
64 return y;
65 }
66
67 /* A class handling everything associated with the search panel.
68
69 Parameters:
70 name - The name of the global variable that will be
71 storing this instance. Is needed to be able to set timeouts.
72 resultPath - path to use for external files
73 */
74 function SearchBox(name, resultsPath, inFrame, label)
75 {
76 if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); }
77
78 // ---------- Instance variables
79 this.name = name;
80 this.resultsPath = resultsPath;
81 this.keyTimeout = 0;
82 this.keyTimeoutLength = 500;
83 this.closeSelectionTimeout = 300;
84 this.lastSearchValue = "";
85 this.lastResultsPage = "";
86 this.hideTimeout = 0;
87 this.searchIndex = 0;
88 this.searchActive = false;
89 this.insideFrame = inFrame;
90 this.searchLabel = label;
91
92 // ----------- DOM Elements
93
94 this.DOMSearchField = function()
95 { return document.getElementById("MSearchField"); }
96
97 this.DOMSearchSelect = function()
98 { return document.getElementById("MSearchSelect"); }
99
100 this.DOMSearchSelectWindow = function()
101 { return document.getElementById("MSearchSelectWindow"); }
102
103 this.DOMPopupSearchResults = function()
104 { return document.getElementById("MSearchResults"); }
105
106 this.DOMPopupSearchResultsWindow = function()
107 { return document.getElementById("MSearchResultsWindow"); }
108
109 this.DOMSearchClose = function()
110 { return document.getElementById("MSearchClose"); }
111
112 this.DOMSearchBox = function()
113 { return document.getElementById("MSearchBox"); }
114
115 // ------------ Event Handlers
116
117 // Called when focus is added or removed from the search field.
118 this.OnSearchFieldFocus = function(isActive)
119 {
120 this.Activate(isActive);
121 }
122
123 this.OnSearchSelectShow = function()
124 {
125 var searchSelectWindow = this.DOMSearchSelectWindow();
126 var searchField = this.DOMSearchSelect();
127
128 if (this.insideFrame)
129 {
130 var left = getXPos(searchField);
131 var top = getYPos(searchField);
132 left += searchField.offsetWidth + 6;
133 top += searchField.offsetHeight;
134
135 // show search selection popup
136 searchSelectWindow.style.display='block';
137 left -= searchSelectWindow.offsetWidth;
138 searchSelectWindow.style.left = left + 'px';
139 searchSelectWindow.style.top = top + 'px';
140 }
141 else
142 {
143 var left = getXPos(searchField);
144 var top = getYPos(searchField);
145 top += searchField.offsetHeight;
146
147 // show search selection popup
148 searchSelectWindow.style.display='block';
149 searchSelectWindow.style.left = left + 'px';
150 searchSelectWindow.style.top = top + 'px';
151 }
152
153 // stop selection hide timer
154 if (this.hideTimeout)
155 {
156 clearTimeout(this.hideTimeout);
157 this.hideTimeout=0;
158 }
159 return false; // to avoid "image drag" default event
160 }
161
162 this.OnSearchSelectHide = function()
163 {
164 this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
165 this.closeSelectionTimeout);
166 }
167
168 // Called when the content of the search field is changed.
169 this.OnSearchFieldChange = function(evt)
170 {
171 if (this.keyTimeout) // kill running timer
172 {
173 clearTimeout(this.keyTimeout);
174 this.keyTimeout = 0;
175 }
176
177 var e = (evt) ? evt : window.event; // for IE
178 if (e.keyCode==40 || e.keyCode==13)
179 {
180 if (e.shiftKey==1)
181 {
182 this.OnSearchSelectShow();
183 var win=this.DOMSearchSelectWindow();
184 for (i=0;i<win.childNodes.length;i++)
185 {
186 var child = win.childNodes[i]; // get span within a
187 if (child.className=='SelectItem')
188 {
189 child.focus();
190 return;
191 }
192 }
193 return;
194 }
195 else if (window.frames.MSearchResults.searchResults)
196 {
197 var elem = window.frames.MSearchResults.searchResults.NavNext(0);
198 if (elem) elem.focus();
199 }
200 }
201 else if (e.keyCode==27) // Escape out of the search field
202 {
203 this.DOMSearchField().blur();
204 this.DOMPopupSearchResultsWindow().style.display = 'none';
205 this.DOMSearchClose().style.display = 'none';
206 this.lastSearchValue = '';
207 this.Activate(false);
208 return;
209 }
210
211 // strip whitespaces
212 var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
213
214 if (searchValue != this.lastSearchValue) // search value has changed
215 {
216 if (searchValue != "") // non-empty search
217 {
218 // set timer for search update
219 this.keyTimeout = setTimeout(this.name + '.Search()',
220 this.keyTimeoutLength);
221 }
222 else // empty search field
223 {
224 this.DOMPopupSearchResultsWindow().style.display = 'none';
225 this.DOMSearchClose().style.display = 'none';
226 this.lastSearchValue = '';
227 }
228 }
229 }
230
231 this.SelectItemCount = function(id)
232 {
233 var count=0;
234 var win=this.DOMSearchSelectWindow();
235 for (i=0;i<win.childNodes.length;i++)
236 {
237 var child = win.childNodes[i]; // get span within a
238 if (child.className=='SelectItem')
239 {
240 count++;
241 }
242 }
243 return count;
244 }
245
246 this.SelectItemSet = function(id)
247 {
248 var i,j=0;
249 var win=this.DOMSearchSelectWindow();
250 for (i=0;i<win.childNodes.length;i++)
251 {
252 var child = win.childNodes[i]; // get span within a
253 if (child.className=='SelectItem')
254 {
255 var node = child.firstChild;
256 if (j==id)
257 {
258 node.innerHTML='&#8226;';
259 }
260 else
261 {
262 node.innerHTML='&#160;';
263 }
264 j++;
265 }
266 }
267 }
268
269 // Called when an search filter selection is made.
270 // set item with index id as the active item
271 this.OnSelectItem = function(id)
272 {
273 this.searchIndex = id;
274 this.SelectItemSet(id);
275 var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
276 if (searchValue!="" && this.searchActive) // something was found -> do a search
277 {
278 this.Search();
279 }
280 }
281
282 this.OnSearchSelectKey = function(evt)
283 {
284 var e = (evt) ? evt : window.event; // for IE
285 if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
286 {
287 this.searchIndex++;
288 this.OnSelectItem(this.searchIndex);
289 }
290 else if (e.keyCode==38 && this.searchIndex>0) // Up
291 {
292 this.searchIndex--;
293 this.OnSelectItem(this.searchIndex);
294 }
295 else if (e.keyCode==13 || e.keyCode==27)
296 {
297 this.OnSelectItem(this.searchIndex);
298 this.CloseSelectionWindow();
299 this.DOMSearchField().focus();
300 }
301 return false;
302 }
303
304 // --------- Actions
305
306 // Closes the results window.
307 this.CloseResultsWindow = function()
308 {
309 this.DOMPopupSearchResultsWindow().style.display = 'none';
310 this.DOMSearchClose().style.display = 'none';
311 this.Activate(false);
312 }
313
314 this.CloseSelectionWindow = function()
315 {
316 this.DOMSearchSelectWindow().style.display = 'none';
317 }
318
319 // Performs a search.
320 this.Search = function()
321 {
322 this.keyTimeout = 0;
323
324 // strip leading whitespace
325 var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
326
327 var code = searchValue.toLowerCase().charCodeAt(0);
328 var idxChar = searchValue.substr(0, 1).toLowerCase();
329 if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
330 {
331 idxChar = searchValue.substr(0, 2);
332 }
333
334 var resultsPage;
335 var resultsPageWithSearch;
336 var hasResultsPage;
337
338 var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
339 if (idx!=-1)
340 {
341 var hexCode=idx.toString(16);
342 resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
343 resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
344 hasResultsPage = true;
345 }
346 else // nothing available for this search term
347 {
348 resultsPage = this.resultsPath + '/nomatches.html';
349 resultsPageWithSearch = resultsPage;
350 hasResultsPage = false;
351 }
352
353 window.frames.MSearchResults.location = resultsPageWithSearch;
354 var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
355
356 if (domPopupSearchResultsWindow.style.display!='block')
357 {
358 var domSearchBox = this.DOMSearchBox();
359 this.DOMSearchClose().style.display = 'inline';
360 if (this.insideFrame)
361 {
362 var domPopupSearchResults = this.DOMPopupSearchResults();
363 domPopupSearchResultsWindow.style.position = 'relative';
364 domPopupSearchResultsWindow.style.display = 'block';
365 var width = document.body.clientWidth - 8; // the -8 is for IE :-(
366 domPopupSearchResultsWindow.style.width = width + 'px';
367 domPopupSearchResults.style.width = width + 'px';
368 }
369 else
370 {
371 var domPopupSearchResults = this.DOMPopupSearchResults();
372 var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
373 var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1;
374 domPopupSearchResultsWindow.style.display = 'block';
375 left -= domPopupSearchResults.offsetWidth;
376 domPopupSearchResultsWindow.style.top = top + 'px';
377 domPopupSearchResultsWindow.style.left = left + 'px';
378 }
379 }
380
381 this.lastSearchValue = searchValue;
382 this.lastResultsPage = resultsPage;
383 }
384
385 // -------- Activation Functions
386
387 // Activates or deactivates the search panel, resetting things to
388 // their default values if necessary.
389 this.Activate = function(isActive)
390 {
391 if (isActive || // open it
392 this.DOMPopupSearchResultsWindow().style.display == 'block'
393 )
394 {
395 this.DOMSearchBox().className = 'MSearchBoxActive';
396
397 var searchField = this.DOMSearchField();
398
399 if (searchField.value == this.searchLabel) // clear "Search" term upon entry
400 {
401 searchField.value = '';
402 this.searchActive = true;
403 }
404 }
405 else if (!isActive) // directly remove the panel
406 {
407 this.DOMSearchBox().className = 'MSearchBoxInactive';
408 this.DOMSearchField().value = this.searchLabel;
409 this.searchActive = false;
410 this.lastSearchValue = ''
411 this.lastResultsPage = '';
412 }
413 }
414 }
415
416 // -----------------------------------------------------------------------
417
418 // The class that handles everything on the search results page.
419 function SearchResults(name)
420 {
421 // The number of matches from the last run of <Search()>.
422 this.lastMatchCount = 0;
423 this.lastKey = 0;
424 this.repeatOn = false;
425
426 // Toggles the visibility of the passed element ID.
427 this.FindChildElement = function(id)
428 {
429 var parentElement = document.getElementById(id);
430 var element = parentElement.firstChild;
431
432 while (element && element!=parentElement)
433 {
434 if (element.nodeName == 'DIV' && element.className == 'SRChildren')
435 {
436 return element;
437 }
438
439 if (element.nodeName == 'DIV' && element.hasChildNodes())
440 {
441 element = element.firstChild;
442 }
443 else if (element.nextSibling)
444 {
445 element = element.nextSibling;
446 }
447 else
448 {
449 do
450 {
451 element = element.parentNode;
452 }
453 while (element && element!=parentElement && !element.nextSibling);
454
455 if (element && element!=parentElement)
456 {
457 element = element.nextSibling;
458 }
459 }
460 }
461 }
462
463 this.Toggle = function(id)
464 {
465 var element = this.FindChildElement(id);
466 if (element)
467 {
468 if (element.style.display == 'block')
469 {
470 element.style.display = 'none';
471 }
472 else
473 {
474 element.style.display = 'block';
475 }
476 }
477 }
478
479 // Searches for the passed string. If there is no parameter,
480 // it takes it from the URL query.
481 //
482 // Always returns true, since other documents may try to call it
483 // and that may or may not be possible.
484 this.Search = function(search)
485 {
486 if (!search) // get search word from URL
487 {
488 search = window.location.search;
489 search = search.substring(1); // Remove the leading '?'
490 search = unescape(search);
491 }
492
493 search = search.replace(/^ +/, ""); // strip leading spaces
494 search = search.replace(/ +$/, ""); // strip trailing spaces
495 search = search.toLowerCase();
496 search = convertToId(search);
497
498 var resultRows = document.getElementsByTagName("div");
499 var matches = 0;
500
501 var i = 0;
502 while (i < resultRows.length)
503 {
504 var row = resultRows.item(i);
505 if (row.className == "SRResult")
506 {
507 var rowMatchName = row.id.toLowerCase();
508 rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
509
510 if (search.length<=rowMatchName.length &&
511 rowMatchName.substr(0, search.length)==search)
512 {
513 row.style.display = 'block';
514 matches++;
515 }
516 else
517 {
518 row.style.display = 'none';
519 }
520 }
521 i++;
522 }
523 document.getElementById("Searching").style.display='none';
524 if (matches == 0) // no results
525 {
526 document.getElementById("NoMatches").style.display='block';
527 }
528 else // at least one result
529 {
530 document.getElementById("NoMatches").style.display='none';
531 }
532 this.lastMatchCount = matches;
533 return true;
534 }
535
536 // return the first item with index index or higher that is visible
537 this.NavNext = function(index)
538 {
539 var focusItem;
540 while (1)
541 {
542 var focusName = 'Item'+index;
543 focusItem = document.getElementById(focusName);
544 if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
545 {
546 break;
547 }
548 else if (!focusItem) // last element
549 {
550 break;
551 }
552 focusItem=null;
553 index++;
554 }
555 return focusItem;
556 }
557
558 this.NavPrev = function(index)
559 {
560 var focusItem;
561 while (1)
562 {
563 var focusName = 'Item'+index;
564 focusItem = document.getElementById(focusName);
565 if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
566 {
567 break;
568 }
569 else if (!focusItem) // last element
570 {
571 break;
572 }
573 focusItem=null;
574 index--;
575 }
576 return focusItem;
577 }
578
579 this.ProcessKeys = function(e)
580 {
581 if (e.type == "keydown")
582 {
583 this.repeatOn = false;
584 this.lastKey = e.keyCode;
585 }
586 else if (e.type == "keypress")
587 {
588 if (!this.repeatOn)
589 {
590 if (this.lastKey) this.repeatOn = true;
591 return false; // ignore first keypress after keydown
592 }
593 }
594 else if (e.type == "keyup")
595 {
596 this.lastKey = 0;
597 this.repeatOn = false;
598 }
599 return this.lastKey!=0;
600 }
601
602 this.Nav = function(evt,itemIndex)
603 {
604 var e = (evt) ? evt : window.event; // for IE
605 if (e.keyCode==13) return true;
606 if (!this.ProcessKeys(e)) return false;
607
608 if (this.lastKey==38) // Up
609 {
610 var newIndex = itemIndex-1;
611 var focusItem = this.NavPrev(newIndex);
612 if (focusItem)
613 {
614 var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
615 if (child && child.style.display == 'block') // children visible
616 {
617 var n=0;
618 var tmpElem;
619 while (1) // search for last child
620 {
621 tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
622 if (tmpElem)
623 {
624 focusItem = tmpElem;
625 }
626 else // found it!
627 {
628 break;
629 }
630 n++;
631 }
632 }
633 }
634 if (focusItem)
635 {
636 focusItem.focus();
637 }
638 else // return focus to search field
639 {
640 parent.document.getElementById("MSearchField").focus();
641 }
642 }
643 else if (this.lastKey==40) // Down
644 {
645 var newIndex = itemIndex+1;
646 var focusItem;
647 var item = document.getElementById('Item'+itemIndex);
648 var elem = this.FindChildElement(item.parentNode.parentNode.id);
649 if (elem && elem.style.display == 'block') // children visible
650 {
651 focusItem = document.getElementById('Item'+itemIndex+'_c0');
652 }
653 if (!focusItem) focusItem = this.NavNext(newIndex);
654 if (focusItem) focusItem.focus();
655 }
656 else if (this.lastKey==39) // Right
657 {
658 var item = document.getElementById('Item'+itemIndex);
659 var elem = this.FindChildElement(item.parentNode.parentNode.id);
660 if (elem) elem.style.display = 'block';
661 }
662 else if (this.lastKey==37) // Left
663 {
664 var item = document.getElementById('Item'+itemIndex);
665 var elem = this.FindChildElement(item.parentNode.parentNode.id);
666 if (elem) elem.style.display = 'none';
667 }
668 else if (this.lastKey==27) // Escape
669 {
670 parent.searchBox.CloseResultsWindow();
671 parent.document.getElementById("MSearchField").focus();
672 }
673 else if (this.lastKey==13) // Enter
674 {
675 return true;
676 }
677 return false;
678 }
679
680 this.NavChild = function(evt,itemIndex,childIndex)
681 {
682 var e = (evt) ? evt : window.event; // for IE
683 if (e.keyCode==13) return true;
684 if (!this.ProcessKeys(e)) return false;
685
686 if (this.lastKey==38) // Up
687 {
688 if (childIndex>0)
689 {
690 var newIndex = childIndex-1;
691 document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
692 }
693 else // already at first child, jump to parent
694 {
695 document.getElementById('Item'+itemIndex).focus();
696 }
697 }
698 else if (this.lastKey==40) // Down
699 {
700 var newIndex = childIndex+1;
701 var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
702 if (!elem) // last child, jump to parent next parent
703 {
704 elem = this.NavNext(itemIndex+1);
705 }
706 if (elem)
707 {
708 elem.focus();
709 }
710 }
711 else if (this.lastKey==27) // Escape
712 {
713 parent.searchBox.CloseResultsWindow();
714 parent.document.getElementById("MSearchField").focus();
715 }
716 else if (this.lastKey==13) // Enter
717 {
718 return true;
719 }
720 return false;
721 }
722 }
723
724 function setKeyActions(elem,action)
725 {
726 elem.setAttribute('onkeydown',action);
727 elem.setAttribute('onkeypress',action);
728 elem.setAttribute('onkeyup',action);
729 }
730
731 function setClassAttr(elem,attr)
732 {
733 elem.setAttribute('class',attr);
734 elem.setAttribute('className',attr);
735 }
736
737 function createResults()
738 {
739 var results = document.getElementById("SRResults");
740 for (var e=0; e<searchData.length; e++)
741 {
742 var id = searchData[e][0];
743 var srResult = document.createElement('div');
744 srResult.setAttribute('id','SR_'+id);
745 setClassAttr(srResult,'SRResult');
746 var srEntry = document.createElement('div');
747 setClassAttr(srEntry,'SREntry');
748 var srLink = document.createElement('a');
749 srLink.setAttribute('id','Item'+e);
750 setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
751 setClassAttr(srLink,'SRSymbol');
752 srLink.innerHTML = searchData[e][1][0];
753 srEntry.appendChild(srLink);
754 if (searchData[e][1].length==2) // single result
755 {
756 srLink.setAttribute('href',searchData[e][1][1][0]);
757 if (searchData[e][1][1][1])
758 {
759 srLink.setAttribute('target','_parent');
760 }
761 var srScope = document.createElement('span');
762 setClassAttr(srScope,'SRScope');
763 srScope.innerHTML = searchData[e][1][1][2];
764 srEntry.appendChild(srScope);
765 }
766 else // multiple results
767 {
768 srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
769 var srChildren = document.createElement('div');
770 setClassAttr(srChildren,'SRChildren');
771 for (var c=0; c<searchData[e][1].length-1; c++)
772 {
773 var srChild = document.createElement('a');
774 srChild.setAttribute('id','Item'+e+'_c'+c);
775 setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
776 setClassAttr(srChild,'SRScope');
777 srChild.setAttribute('href',searchData[e][1][c+1][0]);
778 if (searchData[e][1][c+1][1])
779 {
780 srChild.setAttribute('target','_parent');
781 }
782 srChild.innerHTML = searchData[e][1][c+1][2];
783 srChildren.appendChild(srChild);
784 }
785 srEntry.appendChild(srChildren);
786 }
787 srResult.appendChild(srEntry);
788 results.appendChild(srResult);
789 }
790 }
791