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