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