Git init
[external/libjpeg-turbo.git] / doc / 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: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000011001010011100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
11   1: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
12   2: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000011001000011100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
13 };
14
15 var indexSectionNames =
16 {
17   0: "all",
18   1: "classes",
19   2: "variables"
20 };
21
22 function convertToId(search)
23 {
24   var result = '';
25   for (i=0;i<search.length;i++)
26   {
27     var c = search.charAt(i);
28     var cn = c.charCodeAt(0);
29     if (c.match(/[a-z0-9]/))
30     {
31       result+=c;
32     }
33     else if (cn<16) 
34     {
35       result+="_0"+cn.toString(16);
36     }
37     else 
38     {
39       result+="_"+cn.toString(16);
40     }
41   }
42   return result;
43 }
44
45 function getXPos(item)
46 {
47   var x = 0;
48   if (item.offsetWidth)
49   {
50     while (item && item!=document.body)
51     {
52       x   += item.offsetLeft;
53       item = item.offsetParent;
54     }
55   }
56   return x;
57 }
58
59 function getYPos(item)
60 {
61   var y = 0;
62   if (item.offsetWidth)
63   {
64      while (item && item!=document.body)
65      {
66        y   += item.offsetTop;
67        item = item.offsetParent;
68      }
69   }
70   return y;
71 }
72
73 /* A class handling everything associated with the search panel.
74
75    Parameters:
76    name - The name of the global variable that will be 
77           storing this instance.  Is needed to be able to set timeouts.
78    resultPath - path to use for external files
79 */
80 function SearchBox(name, resultsPath, inFrame, label)
81 {
82   if (!name || !resultsPath) {  alert("Missing parameters to SearchBox."); }
83    
84   // ---------- Instance variables
85   this.name                  = name;
86   this.resultsPath           = resultsPath;
87   this.keyTimeout            = 0;
88   this.keyTimeoutLength      = 500;
89   this.closeSelectionTimeout = 300;
90   this.lastSearchValue       = "";
91   this.lastResultsPage       = "";
92   this.hideTimeout           = 0;
93   this.searchIndex           = 0;
94   this.searchActive          = false;
95   this.insideFrame           = inFrame;
96   this.searchLabel           = label;
97
98   // ----------- DOM Elements
99
100   this.DOMSearchField = function()
101   {  return document.getElementById("MSearchField");  }
102
103   this.DOMSearchSelect = function()
104   {  return document.getElementById("MSearchSelect");  }
105
106   this.DOMSearchSelectWindow = function()
107   {  return document.getElementById("MSearchSelectWindow");  }
108
109   this.DOMPopupSearchResults = function()
110   {  return document.getElementById("MSearchResults");  }
111
112   this.DOMPopupSearchResultsWindow = function()
113   {  return document.getElementById("MSearchResultsWindow");  }
114
115   this.DOMSearchClose = function()
116   {  return document.getElementById("MSearchClose"); }
117
118   this.DOMSearchBox = function()
119   {  return document.getElementById("MSearchBox");  }
120
121   // ------------ Event Handlers
122
123   // Called when focus is added or removed from the search field.
124   this.OnSearchFieldFocus = function(isActive)
125   {
126     this.Activate(isActive);
127   }
128
129   this.OnSearchSelectShow = function()
130   {
131     var searchSelectWindow = this.DOMSearchSelectWindow();
132     var searchField        = this.DOMSearchSelect();
133
134     if (this.insideFrame)
135     {
136       var left = getXPos(searchField);
137       var top  = getYPos(searchField);
138       left += searchField.offsetWidth + 6;
139       top += searchField.offsetHeight;
140
141       // show search selection popup
142       searchSelectWindow.style.display='block';
143       left -= searchSelectWindow.offsetWidth;
144       searchSelectWindow.style.left =  left + 'px';
145       searchSelectWindow.style.top  =  top  + 'px';
146     }
147     else
148     {
149       var left = getXPos(searchField);
150       var top  = getYPos(searchField);
151       top += searchField.offsetHeight;
152
153       // show search selection popup
154       searchSelectWindow.style.display='block';
155       searchSelectWindow.style.left =  left + 'px';
156       searchSelectWindow.style.top  =  top  + 'px';
157     }
158
159     // stop selection hide timer
160     if (this.hideTimeout) 
161     {
162       clearTimeout(this.hideTimeout);
163       this.hideTimeout=0;
164     }
165     return false; // to avoid "image drag" default event
166   }
167
168   this.OnSearchSelectHide = function()
169   {
170     this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
171                                   this.closeSelectionTimeout);
172   }
173
174   // Called when the content of the search field is changed.
175   this.OnSearchFieldChange = function(evt)
176   {
177     if (this.keyTimeout) // kill running timer
178     {
179       clearTimeout(this.keyTimeout);
180       this.keyTimeout = 0;
181     }
182
183     var e  = (evt) ? evt : window.event; // for IE
184     if (e.keyCode==40 || e.keyCode==13)
185     {
186       if (e.shiftKey==1)
187       {
188         this.OnSearchSelectShow();
189         var win=this.DOMSearchSelectWindow(); 
190         for (i=0;i<win.childNodes.length;i++)
191         {
192           var child = win.childNodes[i]; // get span within a
193           if (child.className=='SelectItem')
194           {
195             child.focus();
196             return;
197           }
198         }
199         return;
200       }
201       else if (window.frames.MSearchResults.searchResults)
202       {
203         var elem = window.frames.MSearchResults.searchResults.NavNext(0);
204         if (elem) elem.focus();
205       }
206     }
207     else if (e.keyCode==27) // Escape out of the search field
208     {
209       this.DOMSearchField().blur();
210       this.DOMPopupSearchResultsWindow().style.display = 'none';
211       this.DOMSearchClose().style.display = 'none';
212       this.lastSearchValue = '';
213       this.Activate(false);
214       return;
215     }
216
217     // strip whitespaces
218     var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
219
220     if (searchValue != this.lastSearchValue) // search value has changed
221     {
222       if (searchValue != "") // non-empty search
223       {
224         // set timer for search update
225         this.keyTimeout = setTimeout(this.name + '.Search()',
226                                      this.keyTimeoutLength);
227       }
228       else // empty search field
229       {
230         this.DOMPopupSearchResultsWindow().style.display = 'none';
231         this.DOMSearchClose().style.display = 'none';
232         this.lastSearchValue = '';
233       }
234     }
235   }
236
237   this.SelectItemCount = function(id)
238   {
239     var count=0;
240     var win=this.DOMSearchSelectWindow(); 
241     for (i=0;i<win.childNodes.length;i++)
242     {
243       var child = win.childNodes[i]; // get span within a
244       if (child.className=='SelectItem')
245       {
246         count++;
247       }
248     }
249     return count;
250   }
251
252   this.SelectItemSet = function(id)
253   {
254     var i,j=0;
255     var win=this.DOMSearchSelectWindow(); 
256     for (i=0;i<win.childNodes.length;i++)
257     {
258       var child = win.childNodes[i]; // get span within a
259       if (child.className=='SelectItem')
260       {
261         var node = child.firstChild;
262         if (j==id)
263         {
264           node.innerHTML='&bull;';
265         }
266         else
267         {
268           node.innerHTML='&#160;';
269         }
270         j++;
271       }
272     }
273   }
274
275   // Called when an search filter selection is made.
276   // set item with index id as the active item
277   this.OnSelectItem = function(id)
278   {
279     this.searchIndex = id;
280     this.SelectItemSet(id);
281     var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
282     if (searchValue!="" && this.searchActive) // something was found -> do a search
283     {
284       this.Search();
285     }
286   }
287
288   this.OnSearchSelectKey = function(evt)
289   {
290     var e = (evt) ? evt : window.event; // for IE
291     if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
292     {
293       this.searchIndex++;
294       this.OnSelectItem(this.searchIndex);
295     }
296     else if (e.keyCode==38 && this.searchIndex>0) // Up
297     {
298       this.searchIndex--;
299       this.OnSelectItem(this.searchIndex);
300     }
301     else if (e.keyCode==13 || e.keyCode==27)
302     {
303       this.OnSelectItem(this.searchIndex);
304       this.CloseSelectionWindow();
305       this.DOMSearchField().focus();
306     }
307     return false;
308   }
309
310   // --------- Actions
311
312   // Closes the results window.
313   this.CloseResultsWindow = function()
314   {
315     this.DOMPopupSearchResultsWindow().style.display = 'none';
316     this.DOMSearchClose().style.display = 'none';
317     this.Activate(false);
318   }
319
320   this.CloseSelectionWindow = function()
321   {
322     this.DOMSearchSelectWindow().style.display = 'none';
323   }
324
325   // Performs a search.
326   this.Search = function()
327   {
328     this.keyTimeout = 0;
329
330     // strip leading whitespace
331     var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
332
333     var code = searchValue.toLowerCase().charCodeAt(0);
334     var hexCode;
335     if (code<16) 
336     {
337       hexCode="0"+code.toString(16);
338     }
339     else 
340     {
341       hexCode=code.toString(16);
342     }
343
344     var resultsPage;
345     var resultsPageWithSearch;
346     var hasResultsPage;
347
348     if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1')
349     {
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.href = 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 }