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

Legend:
Removed from v.496  
changed lines
  Added in v.535

  ViewVC Help
Powered by ViewVC 1.1.26