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