/[webpac]/trunk2/out/js/search.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk2/out/js/search.js

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 533 by dpavlin, Sun Oct 10 18:55:05 2004 UTC revision 534 by dpavlin, Sat Oct 23 18:18:11 2004 UTC
# Line 27  Line 27 
27    
28  // Constants  // Constants
29  var conversion = new String  var conversion = new String
30        ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY");          ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY");
31    
32  // State variables  // State variables
33  var query_left = "";  var query_left = "";
# Line 39  var watchdog_id = 0; Line 39  var watchdog_id = 0;
39  var watchdog_callback = null;  var watchdog_callback = null;
40    
41  // Object to hold search results  // Object to hold search results
42  function Result(title, link, freq)  function Result(title, link, freq) {
43  {          this.title=title;
44    this.title=title;          this.link=link;
45    this.link=link;          this.frequency=Number(freq);
   this.frequency=Number(freq);  
46  }  }
47    
48  // Function to merge (intersect) two result sets  // Function to merge (intersect) two result sets
49  function intersect_results(data)  function intersect_results(data) {
50  {          // If there are no stored results, then these are the results
51    // If there are no stored results, then these are the results          if (! results) {
52    if(!results)                  results = data;
53    {                  return;
54      results = data;          }
55      return;  
56    }          var output=new Array();
57    
58    var output=new Array();          // There are existing results, to do an intersect...
59            for (var i=0; i<results.length; i++) {
60    // There are existing results, to do an intersect...                  for (var j=0; j<data.length; j++) {
61    for(var i=0; i<results.length; i++)                          if (data[j].title == results[i].title) {
62    {                                  results[i].frequency += data[j].frequency;
63      for(var j=0; j<data.length; j++)                                  output.push(results[i]);  
64      {                                  break;
65        if(data[j].title == results[i].title)                          }
66        {                  }
67          results[i].frequency += data[j].frequency;          }
         output.push(results[i]);    
         break;  
       }  
     }  
   }  
68    
69    results = output;          results = output;
70  }  }
71    
72  /*  /*
73   From David Flanagan's, _Javascript:_The Definitive_Guide_, pg. 294-5,   From David Flanagan's, _Javascript:_The Definitive_Guide_, pg. 294-5,
74    published by O'Reilly, 4th edition, 2002          published by O'Reilly, 4th edition, 2002
75  */  */
76    
77  var debug_div = null;  var debug_div = null;
78    
79  function debug(msg)  function debug(msg) {
80  {  
81  //  return; // Disable debugging  //      return; // Disable debugging
82    
83    if (! debug_div) debug_div = document.getElementById('debug');          if (! debug_div) debug_div = document.getElementById('debug');
84    
85    // this will create debug div if it doesn't exist.          // this will create debug div if it doesn't exist.
86    if (! debug_div) {          if (! debug_div) {
87          debug_div = document.createElement('div');                  debug_div = document.createElement('div');
88          if (document.body) document.body.appendChild(debug_div);                  if (document.body) document.body.appendChild(debug_div);
89          else debug_div = null;                  else debug_div = null;
90    }          }
91    if (debug_div) {          if (debug_div) {
92          debug_div.appendChild(document.createTextNode(msg));                  debug_div.appendChild(document.createTextNode(msg));
93          debug_div.appendChild(document.createElement("br"));                  debug_div.appendChild(document.createElement("br"));
94    }          }
95  }  }
96    
97  // Convert a number into a base 62 alphanumeric number string  // Convert a number into a base 62 alphanumeric number string
98  function convert(num)  function convert(num) {
99  {          var base = conversion.length;
100    var base = conversion.length;          var pow = 1;
101    var pow = 1;          var pos = 0;
102    var pos = 0;          var out = "";  
103    var out = "";    
104            if (num == 0) return "0";
105    if(num == 0)  
106    {          while (num > 0) {
107      return "0";                  pos = num % base;
108    }                  out = conversion.charAt(pos) + out;
109                    num = Math.floor(num/base);
110    while (num > 0)                  pow *= base;
111    {          }
112      pos = num % base;  
113      out = conversion.charAt(pos) + out;          return out;
114      num = Math.floor(num/base);  }
115      pow *= base;  
116    }  function watchdog() {
117            debug ("TIMEOUT!");
118    return out;          watchdog_callback(new Array());
 }  
   
 function watchdog()  
 {  
   debug ("TIMEOUT!");  
   watchdog_callback(new Array());  
119  }  }
120    
121  var xmldoc;  var xmldoc;
# Line 135  var xmldoc; Line 123  var xmldoc;
123  // This function loads the XML document from the specified URL, and when  // This function loads the XML document from the specified URL, and when
124  // it is fully loaded, passes that document and the url to the specified  // it is fully loaded, passes that document and the url to the specified
125  // handler function.  This function works with any XML document  // handler function.  This function works with any XML document
 function loadXML(url, handler, data, result_handler)  
 {  
   debug("loadXML("+url+","+data+")");  
   
   // Timeout operation in 10 seconds  
   watchdog_callback = result_handler;  
   watchdog_id=setTimeout("watchdog()", 20000);  
   
   debug("setTimeout = "+watchdog_id);  
   
   try  
   {  
     // Use the standard DOM Level 2 technique, if it is supported  
     if (document.implementation && document.implementation.createDocument)  
     {  
      // Create a new Document object  
       xmldoc = document.implementation.createDocument("", "", null);  
   
       // Specify what should happen when it finishes loading  
       xmldoc.onload = function() { handler(xmldoc, url, data, result_handler); }  
   
       //xmldoc.onerror = docError;  
       //xmldoc.addEventListener("load",docError,false);  
   
       // And tell it what URL to load  
       xmldoc.load(url);  
       return true;  
     }  
     // Otherwise use Microsoft's proprietary API for Internet Explorer  
     // Something about not following standards once again  
     else if (window.ActiveXObject)  
     {    
       xmldoc = new ActiveXObject("Microsoft.XMLDOM");   // Create doc.  
       if (! xmldoc) xmldoc = new ActiveXObject("MSXML2.DOMDocument");   // Create doc.  
       // Specify onload  
       xmldoc.onreadystatechange = function()  
       {                
         if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler);  
       }  
       xmldoc.load(url);                                     // Start loading!  
       return true;  
     }  
     // else fallback on usage of iframes to load xml (Opera 7.53 without Java and maybe old Mac browsers)  
     else {  
       debug("using iframe xml loader - experimental and slow");  
       if (! window.xml_iframe) {  
         debug("creating iframe");  
         window.xml_iframe = document.createElement('div');  
         window.xml_iframe.innerHTML = '<iframe src="'+url+'" name="xml_iframe" height="0" width="0" style="display: none;"></iframe>';  
         document.body.appendChild(window.xml_iframe);  
       } else {  
         debug("loading xml in existing iframe");  
         window.frames.xml_iframe.window.document.location.href = url;  
       }  
   
       // set timeout to re-check if iframe is loaded  
       window.iframe_timeout = window.setInterval('iframe_xml_loaded();',100);  
   
       // save some data for iframe_xml_loaded()  
       window.xml_handler = handler;  
       window.xml_url = url;  
       window.xml_data = data;  
       window.xml_result_handler = result_handler;  
       return true;  
     }  
     clearTimeout(watchdog_id);  
     debug("Browser incompatilibity: can't request XML document by one of supported methods");  
     return false;  
   }  
   catch(ex)  
   {  
     clearTimeout(watchdog_id);  
     debug("clearTimeout = "+watchdog_id);  
     debug ("CAUGHT EXCEPTION!");  
     result_handler(new Array());  
     return false;  
   }  
126    
127    return true;  function loadXML(url, handler, data, result_handler) {
128            debug("loadXML("+url+","+data+")");
129    
130            // Timeout operation in 10 seconds
131            watchdog_callback = result_handler;
132            watchdog_id=setTimeout("watchdog()", 20000);
133    
134            debug("setTimeout = "+watchdog_id);
135    
136            try {
137                    // Use the standard DOM Level 2 technique, if it is supported
138                    if (document.implementation && document.implementation.createDocument) {
139                            // Create a new Document object
140                            xmldoc = document.implementation.createDocument("", "", null);
141    
142                            // Specify what should happen when it finishes loading
143                            xmldoc.onload = function() { handler(xmldoc, url, data, result_handler); }
144    
145                            //xmldoc.onerror = docError;
146                            //xmldoc.addEventListener("load",docError,false);
147    
148                            // And tell it what URL to load
149                            xmldoc.load(url);
150                            return true;
151                    }
152                    // Otherwise use Microsoft's proprietary API for Internet Explorer
153                    // Something about not following standards once again
154                    else if (window.ActiveXObject) {  
155                            xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // Create doc.
156                            if (! xmldoc) xmldoc = new ActiveXObject("MSXML2.DOMDocument"); // Create doc.
157                            // Specify onload
158                            xmldoc.onreadystatechange = function() {              
159                                    if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler);
160                            }
161                            xmldoc.load(url);                                     // Start loading!
162                            return true;
163                    }
164                    // else fallback on usage of iframes to load xml (Opera 7.53 without Java and maybe old Mac browsers)
165                    else {
166                            debug("using iframe xml loader - experimental and slow");
167                            if (! window.xml_iframe) {
168                                    debug("creating iframe");
169                                    window.xml_iframe = document.createElement('div');
170                                    window.xml_iframe.innerHTML = '<iframe src="'+url+'" name="xml_iframe" height="0" width="0" style="display: none;"></iframe>';
171                                    document.body.appendChild(window.xml_iframe);
172                            } else {
173                                    debug("loading xml in existing iframe");
174                                    window.frames.xml_iframe.window.document.location.href = url;
175                            }
176    
177                            // set timeout to re-check if iframe is loaded
178                            window.iframe_timeout = window.setInterval('iframe_xml_loaded();',100);
179    
180                            // save some data for iframe_xml_loaded()
181                            window.xml_handler = handler;
182                            window.xml_url = url;
183                            window.xml_data = data;
184                            window.xml_result_handler = result_handler;
185                            return true;
186                    }
187    
188                    clearTimeout(watchdog_id);
189                    debug("Browser incompatilibity: can't request XML document by one of supported methods");
190                    return false;
191            }
192    
193            catch(ex) {
194                    clearTimeout(watchdog_id);
195                    debug("clearTimeout = "+watchdog_id);
196                    debug ("CAUGHT EXCEPTION!");
197                    result_handler(new Array());
198                    return false;
199            }
200    
201            return true;
202  }  }
203    
204  function iframe_xml_loaded() {  function iframe_xml_loaded() {
205    debug("iframe_xmldoc_loaded");          debug("iframe_xmldoc_loaded");
206    if (! window.frames['xml_iframe']) return;          if (! window.frames['xml_iframe']) return;
207    var xml = eval('window.frames.xml_iframe.window.document');          var xml = eval('window.frames.xml_iframe.window.document');
208    if (xml) {          if (xml) {
209          clearTimeout(window.iframe_timeout);          clearTimeout(window.iframe_timeout);
210          debug("calling handler with ("+window.xml_url+","+window.xml_data+",...)");                  debug("calling handler with ("+window.xml_url+","+window.xml_data+",...)");
211          window.xml_handler(window.frames.xml_iframe.window.document, window.xml_url, window.xml_data, window.xml_result_handler);                  window.xml_handler(window.frames.xml_iframe.window.document, window.xml_url, window.xml_data, window.xml_result_handler);
212    } else {          } else {
213          debug("can't eval iframe with xml");                  debug("can't eval iframe with xml");
214    }          }
215  }  }
216    
217  function loadData(xmldoc, url, pos, result_handler)  var data = new Array();
218  {  
219    clearTimeout(watchdog_id);  function loadData_intersect(xmldoc, url, pos, result_handler) {
220    debug("clearTimeout = "+watchdog_id);          data = new Array();
221            if (loadData(xmldoc, url, pos, result_handler)) {
222    debug ("loadData("+url+","+pos+")");                  intersect_results(data);
223                    search_query_left(result_handler);
224    var data = new Array();          } else {
225                    debug("INTERNAL ERROR, Inconsistent index");
226    // Get all entries                  search_err="INTERNAL ERROR, Inconsistent index";
227    var entries = xmldoc.getElementsByTagName("e");          }
228    }
229    if(entries.length > pos)  
230    {  function loadData(xmldoc, url, pos, result_handler) {
231      // Get the links associated with this query  
232      var links = entries[pos].getElementsByTagName("l");          clearTimeout(watchdog_id);
233            debug("clearTimeout = "+watchdog_id);
234      // Dynamically append results to output  
235      for(var i=0; i<links.length; i++)          debug ("loadData("+url+","+pos+")");
236      {  
237        data.push(new Result(links[i].getAttribute("t"),          // Get all entries
238                             links[i].firstChild.data,          var entries = xmldoc.getElementsByTagName("e");
239                             links[i].getAttribute("f")));  
240      }          if (entries.length > pos) {
241                    // Get the links associated with this query
242      intersect_results(data);                  var links = entries[pos].getElementsByTagName("l");
243    
244      if(query_left.length > 0)                  debug("loaded "+links.length+" links");
245      {  
246        doSearch(index_path, query_left, result_handler);                    // Dynamically append results to output
247      }                  var ret = false;
248      else                  for(i=0; i<links.length; i++) {
249      {                          data.push(new Result(
250        results.sort(sortResults);                                  links[i].getAttribute("t"),
251        result_handler(results);                                  links[i].firstChild.data,
252      }                                  links[i].getAttribute("f"))
253    }                          );
254    else                          ret = true;
255    {                  }
256      debug("INTERNAL ERROR, Inconsistent index");                  return ret;
257      search_err="INTERNAL ERROR, Inconsistent index";          } else {
258    }                  debug("ERROR: seek to "+pos+" with only "+entries.length+" elements");
259  }          }
260    }
261  function sortResults(a, b)  
262  {  
263    return a.frequency - b.frequency;  function search_query_left(result_handler) {
264  }          if (query_left.length > 0) {
265                    doSearch(index_path, query_left, result_handler);  
266  function traverseTree(xmldoc, url, query, result_handler)          } else {
267  {                  results.sort(sortResults);
268    clearTimeout(watchdog_id);                  result_handler(results);
269    debug("clearTimeout = "+watchdog_id);          }
270    }
271    
272    // you may override this function to sort by something else
273    function sortResults(a, b) {
274            return a.frequency - b.frequency;
275    }
276    
277    function traverseTree(xmldoc, url, query, result_handler) {
278            clearTimeout(watchdog_id);
279            debug("clearTimeout = "+watchdog_id);
280    
281    debug("traverseTree("+xmldoc+","+url+","+query+")");          debug("traverseTree("+xmldoc+","+url+","+query+")");
282    
283    var keys = xmldoc.getElementsByTagName("k");          var keys = xmldoc.getElementsByTagName("k");
284    var i;          var i;
285    
286    for(i = 0; i < keys.length; i++)          // support for wildcard
287    {          var qlen = query.length;
288      var key = keys[i].firstChild.data;          var wildcard = false;
289      debug("traverseTree: key="+key+" query="+query);          var query_full = query;
290      if(key != '' && key != null)          if (query.charAt(qlen-1) == '*') {
291      {                  wildcard = true;
292        // Case where current key is greater than query, descend                  query = query.substr(0,--qlen);
293        if(key > query)                  debug("using wildcard "+query+"*");
294        {          }
295          if(key != '' && key != null)  
296          {          for(i = 0; i < keys.length; i++) {
297            if(!loadXML(url.replace(".xml","/"+convert(i)+".xml"),                  var key = keys[i].firstChild.data;
298                        traverseTree,query,result_handler))  
299            {                  if (wildcard) {
300              debug("Unable to locate key "+query);                          key = key.substr(0,qlen);
301              result_handler(new Array());                          debug("wildcard key "+key+"*");
302            }                  }
303            // make sure of garbage collection  
304            xmldoc=null;                  debug("traverseTree: "+key+"=="+query);
305            return;  
306          }                  if (key != '' && key != null) {
307        }                          // Case where current key is greater than query, descend
308        // Found it!                          if (key > query) {
309        else if(key==query)                                  if (key != '' && key != null) {
310        {                                          if (! loadXML(url.replace(".xml","/"+convert(i)+".xml"), traverseTree,query_full,result_handler)) {
311          if(!loadXML(url.replace(/(\w+\.xml)/, "_$1"),                                                  debug("Unable to locate key "+query);
312                      loadData, i, result_handler))                                                  result_handler(new Array());
313          {                                          }
314            debug("ERROR: Unable to locate data "+query);                                          // make sure of garbage collection
315            result_handler(new Array());                                          xmldoc=null;
316          }                                          return;
317          // make sure of garbage collection                                  }
318          xmldoc=null;                          }
319          return;                          // Found it!
320        }                          else if (key==query) {
321      }                                  if (wildcard) {
322    }                                          data = new Array();
323    // Look past the end...                                          while (xmldoc && keys[i].firstChild.data.substr(0,qlen) == query) {
324    if(keys.length == 0 || !loadXML(url.replace(".xml","/"+convert(i)+".xml"),                                                  var url2 = url;
325                traverseTree,query,result_handler))                                                  if (loadXML(url2.replace(/(\w+\.xml)/, "_$1"), loadData, i, result_handler)) {
326    {                                                          // add loaded data to results
327      debug("Unable to locate key "+query);                                                          if (! results) {
328      result_handler(new Array());                                                                  results = data;
329    }                                                                  debug("wildcard loop: "+i+" created "+data.length+" results");
330    // make sure of garbage collection                                                          } else {
331    xmldoc=null;                                                                  for (var j=0; j<data.length; j++) {
332    return;                                                                          results.push(data[j]);
333  }                                                                  }
334                                                                    debug("wildcard loop: "+i+" added "+j+" results");
335  function doSearch(index_name,query, result_func)                                                          }
336  {  
337    //alert("doSearch("+index_name+","+query+")");                                                  } else {
338    var pos=query.search(/[\s\+]/);                                                          // this will break out of loop
339    if (index_name) index_path = index_name+'/';                                                          xmldoc = null;
340                                                            debug("wildcard loop stop at "+i);
341    if(pos < 0)                                                  }
342    {                                                  i++;
343      query_left = "";                                          }
344    }                                          debug("wildcard results: "+results.length);
345    else                                          search_query_left(result_handler);
346    {                                          return;
347      query_left = query.slice(pos+1);                                  } else {
348      query = query.slice(0,pos);                                          // exact match
349    }                                          if (! loadXML(url.replace(/(\w+\.xml)/, "_$1"), loadData_intersect, i, result_handler)) {
350                                                    debug("ERROR: Unable to locate data "+query);
351    if(!loadXML(index_path+"0.xml", traverseTree, query.toLowerCase(), result_func))                                                  result_handler(new Array());
352    {                                          }
353      debug("ERROR: Couldn't find main index 0.xml");                                          // make sure of garbage collection
354      search_err = "INTERNAL ERROR: Unable to load main index 0.xml";                                          xmldoc=null;
355    }                                          return;
356                                    }
357                            } // key < query
358                    } // if key
359            } // for
360    
361            // Look past the end...
362            if (wildcard) query += '*';
363    
364            if (keys.length == 0 || !loadXML(url.replace(".xml","/"+convert(i)+".xml"), traverseTree,query,result_handler)) {
365                            debug("Unable to locate key "+query);
366                            result_handler(new Array());
367            }
368    
369            // make sure of garbage collection
370            xmldoc=null;
371            return;
372    }
373    
374    function doSearch(index_name,query, result_func) {
375    
376            //alert("doSearch("+index_name+","+query+")");
377            var pos=query.search(/[\s\+]/);
378            if (index_name) index_path = index_name+'/';
379    
380            if (pos < 0) {
381                    query_left = "";
382            } else {
383                    query_left = query.slice(pos+1);
384                    query = query.slice(0,pos);
385            }
386    
387            if (! loadXML(index_path+"0.xml", traverseTree, query.toLowerCase(), result_func)) {
388                    debug("ERROR: Couldn't find main index 0.xml");
389                    search_err = "INTERNAL ERROR: Unable to load main index 0.xml";
390            }
391  }  }

Legend:
Removed from v.533  
changed lines
  Added in v.534

  ViewVC Help
Powered by ViewVC 1.1.26