/[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 464 by dpavlin, Thu Sep 23 17:14:33 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  */  */
 function debug(msg)  
 {  
 //  return; // Disable debugging  
76    
77    var debug_div = element_id('debug');  var debug_div = null;
78    
79    if (debug_div) debug_div.innerHTML += msg+"<br/>\n";  function debug(msg) {
80  }  
81    //      return; // Disable debugging
82    
83  //          if (! debug_div) debug_div = document.getElementById('debug');
84    
85            // this will create debug div if it doesn't exist.
86            if (! debug_div) {
87                    debug_div = document.createElement('div');
88                    if (document.body) document.body.appendChild(debug_div);
89                    else debug_div = null;
90            }
91            if (debug_div) {
92                    debug_div.appendChild(document.createTextNode(msg));
93                    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;
122    
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
126  function loadXML(url, handler, data, result_handler)  
127  {  function loadXML(url, handler, data, result_handler) {
128    debug("loadXML("+url+","+data+")");          debug("loadXML("+url+","+data+")");
129    
130    // Timeout operation in 10 seconds          // Timeout operation in 10 seconds
131    watchdog_callback = result_handler;          watchdog_callback = result_handler;
132    watchdog_id=setTimeout("watchdog()", 20000);          watchdog_id=setTimeout("watchdog()", 20000);
133    
134    debug("setTimeout = "+watchdog_id);          debug("setTimeout = "+watchdog_id);
135    
136    try          try {
137    {                  // Use the standard DOM Level 2 technique, if it is supported
138      var xmldoc;                  if (document.implementation && document.implementation.createDocument) {
139      // Use the standard DOM Level 2 technique, if it is supported                          // Create a new Document object
140      if (document.implementation && document.implementation.createDocument)                          xmldoc = document.implementation.createDocument("", "", null);
141      {  
142       // Create a new Document object                          // Specify what should happen when it finishes loading
143        xmldoc = document.implementation.createDocument("", "", null);                          xmldoc.onload = function() { handler(xmldoc, url, data, result_handler); }
144    
145        // Specify what should happen when it finishes loading                          //xmldoc.onerror = docError;
146        xmldoc.onload = function() { handler(xmldoc, url, data, result_handler); }                          //xmldoc.addEventListener("load",docError,false);
147    
148        //xmldoc.onerror = docError;                          // And tell it what URL to load
149        //xmldoc.addEventListener("load",docError,false);                          xmldoc.load(url);
150                            return true;
151        // And tell it what URL to load                  }
152        xmldoc.load(url);                  // Otherwise use Microsoft's proprietary API for Internet Explorer
153      }                  // Something about not following standards once again
154      // Otherwise use Microsoft's proprietary API for Internet Explorer                  else if (window.ActiveXObject) {  
155      // Something about not following standards once again                          xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // Create doc.
156      else if (window.ActiveXObject)                          if (! xmldoc) xmldoc = new ActiveXObject("MSXML2.DOMDocument"); // Create doc.
157      {                            // Specify onload
158        xmldoc = new ActiveXObject("Microsoft.XMLDOM");   // Create doc.                          xmldoc.onreadystatechange = function() {              
159        if (! xmldoc) xmldoc = new ActiveXObject("MSXML2.DOMDocument");   // Create doc.                                  if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler);
160        // Specify onload                          }
161        xmldoc.onreadystatechange = function()                          xmldoc.load(url);                                     // Start loading!
162        {                                        return true;
163          if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler);                  }
164        }                  // else fallback on usage of iframes to load xml (Opera 7.53 without Java and maybe old Mac browsers)
165        xmldoc.load(url);                                     // Start loading!                  else {
166      }                          debug("using iframe xml loader - experimental and slow");
167    }                          if (! window.xml_iframe) {
168    catch(ex)                                  debug("creating iframe");
169    {                                  window.xml_iframe = document.createElement('div');
170      clearTimeout(watchdog_id);                                  window.xml_iframe.innerHTML = '<iframe src="'+url+'" name="xml_iframe" height="0" width="0" style="display: none;"></iframe>';
171      debug("clearTimeout = "+watchdog_id);                                  document.body.appendChild(window.xml_iframe);
172      debug ("CAUGHT EXCEPTION!");                          } else {
173      result_handler(new Array());                                  debug("loading xml in existing iframe");
174      return false;                                  window.frames.xml_iframe.window.document.location.href = url;
175    }                          }
176    
177    return true;                          // set timeout to re-check if iframe is loaded
178  }                          window.iframe_timeout = window.setInterval('iframe_xml_loaded();',100);
179    
180  function loadData(xmldoc, url, pos, result_handler)                          // save some data for iframe_xml_loaded()
181  {                          window.xml_handler = handler;
182    clearTimeout(watchdog_id);                          window.xml_url = url;
183    debug("clearTimeout = "+watchdog_id);                          window.xml_data = data;
184                            window.xml_result_handler = result_handler;
185    debug ("loadData("+url+","+pos+")");                          return true;
186                    }
187    var data = new Array();  
188                    clearTimeout(watchdog_id);
189    // Get all entries                  debug("Browser incompatilibity: can't request XML document by one of supported methods");
190    var entries = xmldoc.getElementsByTagName("e");                  return false;
191            }
192    if(entries.length > pos)  
193    {          catch(ex) {
194      // Get the links associated with this query                  clearTimeout(watchdog_id);
195      var links = entries[pos].getElementsByTagName("l");                  debug("clearTimeout = "+watchdog_id);
196                    debug ("CAUGHT EXCEPTION!");
197      // Dynamically append results to output                  result_handler(new Array());
198      for(var i=0; i<links.length; i++)                  return false;
199      {          }
200        data.push(new Result(links[i].getAttribute("t"),  
201                             links[i].firstChild.data,          return true;
202                             links[i].getAttribute("f")));  }
203      }  
204    function iframe_xml_loaded() {
205      intersect_results(data);          debug("iframe_xmldoc_loaded");
206            if (! window.frames['xml_iframe']) return;
207      if(query_left.length > 0)          var xml = eval('window.frames.xml_iframe.window.document');
208      {          if (xml) {
209        doSearch(index_path, query_left, result_handler);            clearTimeout(window.iframe_timeout);
210      }                  debug("calling handler with ("+window.xml_url+","+window.xml_data+",...)");
211      else                  window.xml_handler(window.frames.xml_iframe.window.document, window.xml_url, window.xml_data, window.xml_result_handler);
212      {          } else {
213        results.sort(sortResults);                  debug("can't eval iframe with xml");
214        result_handler(results);          }
215      }  }
216    }  
217    else  var data = new Array();
218    {  
219      debug("INTERNAL ERROR, Inconsistent index");  function loadData_intersect(xmldoc, url, pos, result_handler) {
220      search_err="INTERNAL ERROR, Inconsistent index";          data = new Array();
221    }          if (loadData(xmldoc, url, pos, result_handler)) {
222  }                  intersect_results(data);
223                    search_query_left(result_handler);
224  function sortResults(a, b)          } else {
225  {                  debug("INTERNAL ERROR, Inconsistent index");
226    return a.frequency - b.frequency;                  search_err="INTERNAL ERROR, Inconsistent index";
227  }          }
228    }
229  function traverseTree(xmldoc, url, query, result_handler)  
230  {  function loadData(xmldoc, url, pos, result_handler) {
231    clearTimeout(watchdog_id);  
232    debug("clearTimeout = "+watchdog_id);          clearTimeout(watchdog_id);
233            debug("clearTimeout = "+watchdog_id);
234    
235            debug ("loadData("+url+","+pos+")");
236    
237            // Get all entries
238            var entries = xmldoc.getElementsByTagName("e");
239    
240            if (entries.length > pos) {
241                    // Get the links associated with this query
242                    var links = entries[pos].getElementsByTagName("l");
243    
244                    debug("loaded "+links.length+" links");
245    
246                    // Dynamically append results to output
247                    var ret = false;
248                    for(i=0; i<links.length; i++) {
249                            data.push(new Result(
250                                    links[i].getAttribute("t"),
251                                    links[i].firstChild.data,
252                                    links[i].getAttribute("f"))
253                            );
254                            ret = true;
255                    }
256                    return ret;
257            } else {
258                    debug("ERROR: seek to "+pos+" with only "+entries.length+" elements");
259            }
260    }
261    
262    
263    function search_query_left(result_handler) {
264            if (query_left.length > 0) {
265                    doSearch(index_path, query_left, result_handler);  
266            } else {
267                    results.sort(sortResults);
268                    result_handler(results);
269            }
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");
284            var i;
285    
286            // support for wildcard
287            var qlen = query.length;
288            var wildcard = false;
289            var query_full = query;
290            if (query.charAt(qlen-1) == '*') {
291                    wildcard = true;
292                    query = query.substr(0,--qlen);
293                    debug("using wildcard "+query+"*");
294            }
295    
296            for(i = 0; i < keys.length; i++) {
297                    var key = keys[i].firstChild.data;
298    
299                    if (wildcard) {
300                            key = key.substr(0,qlen);
301                            debug("wildcard key "+key+"*");
302                    }
303    
304                    debug("traverseTree: "+key+"=="+query);
305    
306                    if (key != '' && key != null) {
307                            // Case where current key is greater than query, descend
308                            if (key > query) {
309                                    if (key != '' && key != null) {
310                                            if (! loadXML(url.replace(".xml","/"+convert(i)+".xml"), traverseTree,query_full,result_handler)) {
311                                                    debug("Unable to locate key "+query);
312                                                    result_handler(new Array());
313                                            }
314                                            // make sure of garbage collection
315                                            xmldoc=null;
316                                            return;
317                                    }
318                            }
319                            // Found it!
320                            else if (key==query) {
321                                    if (wildcard) {
322                                            data = new Array();
323                                            while (xmldoc && keys[i].firstChild.data.substr(0,qlen) == query) {
324                                                    var url2 = url;
325                                                    if (loadXML(url2.replace(/(\w+\.xml)/, "_$1"), loadData, i, result_handler)) {
326                                                            // add loaded data to results
327                                                            if (! results) {
328                                                                    results = data;
329                                                                    debug("wildcard loop: "+i+" created "+data.length+" results");
330                                                            } else {
331                                                                    for (var j=0; j<data.length; j++) {
332                                                                            results.push(data[j]);
333                                                                    }
334                                                                    debug("wildcard loop: "+i+" added "+j+" results");
335                                                            }
336    
337                                                    } else {
338                                                            // this will break out of loop
339                                                            xmldoc = null;
340                                                            debug("wildcard loop stop at "+i);
341                                                    }
342                                                    i++;
343                                            }
344                                            debug("wildcard results: "+results.length);
345                                            search_query_left(result_handler);
346                                            return;
347                                    } else {
348                                            // exact match
349                                            if (! loadXML(url.replace(/(\w+\.xml)/, "_$1"), loadData_intersect, i, result_handler)) {
350                                                    debug("ERROR: Unable to locate data "+query);
351                                                    result_handler(new Array());
352                                            }
353                                            // make sure of garbage collection
354                                            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    var keys = xmldoc.getElementsByTagName("k");  function doSearch(index_name,query, result_func) {
   var i;  
375    
376    for(i = 0; i < keys.length; i++)          //alert("doSearch("+index_name+","+query+")");
377    {          var pos=query.search(/[\s\+]/);
378      var key = keys[i].firstChild.data;          if (index_name) index_path = index_name+'/';
379      debug("traverseTree: key="+key+" query="+query);  
380      if(key != '' && key != null)          if (pos < 0) {
381      {                  query_left = "";
382        // Case where current key is greater than query, descend          } else {
383        if(key > query)                  query_left = query.slice(pos+1);
384        {                  query = query.slice(0,pos);
385          if(key != '' && key != null)          }
386          {  
387            if(!loadXML(url.replace(".xml","/"+convert(i)+".xml"),          if (! loadXML(index_path+"0.xml", traverseTree, query.toLowerCase(), result_func)) {
388                        traverseTree,query,result_handler))                  debug("ERROR: Couldn't find main index 0.xml");
389            {                  search_err = "INTERNAL ERROR: Unable to load main index 0.xml";
390              debug("Unable to locate key "+query);          }
             result_handler(new Array());  
           }  
           // make sure of garbage collection  
           xmldoc=null;  
           return;  
         }  
       }  
       // Found it!  
       else if(key==query)  
       {  
         if(!loadXML(url.replace(/(\w+\.xml)/, "_$1"),  
                     loadData, i, result_handler))  
         {  
           debug("ERROR: Unable to locate data "+query);  
           result_handler(new Array());  
         }  
         // make sure of garbage collection  
         xmldoc=null;  
         return;  
       }  
     }  
   }  
   // Look past the end...  
   if(keys.length == 0 || !loadXML(url.replace(".xml","/"+convert(i)+".xml"),  
               traverseTree,query,result_handler))  
   {  
     debug("Unable to locate key "+query);  
     result_handler(new Array());  
   }  
   // make sure of garbage collection  
   xmldoc=null;  
   return;  
 }  
   
 function doSearch(index_name,query, result_func)  
 {  
   //alert("doSearch("+index_name+","+query+")");  
   var pos=query.search(/[\s\+]/);  
   if (index_name) index_path = index_name+'/';  
   
   if(pos < 0)  
   {  
     query_left = "";  
   }  
   else  
   {  
     query_left = query.slice(pos+1);  
     query = query.slice(0,pos);  
   }  
   
   if(!loadXML(index_path+"0.xml", traverseTree, query.toLowerCase(), result_func))  
   {  
     debug("ERROR: Couldn't find main index 0.xml");  
     search_err = "INTERNAL ERROR: Unable to load main index 0.xml";  
   }  
391  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26