source: tspsg-svn/trunk/docs/html/search/search.js @ 69

Last change on this file since 69 was 68, checked in by laleppa, 15 years ago

Adding documentation generated by doxygen.

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