/[jsFind]/trunk/html/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

Annotation of /trunk/html/js/search.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Sun Jul 11 21:15:44 2004 UTC (19 years, 10 months ago) by dpavlin
File MIME type: application/javascript
File size: 8014 byte(s)
print "Noting Found" in all cases (especially on W2K, don't know why)

1 dpavlin 1 /**
2     search.js searchs an XML index to HTML files.
3    
4     A part of the jsfind project (http://projects.elucidsoft.net/jsfind)
5     Copyright (C) 2003 Shawn Garbett
6    
7     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 2
10     of the License, or (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20    
21     Contact Info:
22     Shawn Garbett <Shawn@eLucidSoft.net>
23     http://www.elucidsoft.net
24     4037 General Bate Drive
25     Nashville, TN 37204
26     */
27    
28     // Constants
29     var conversion = new String
30     ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY");
31    
32     // State variables
33     var query_left = "";
34     var search_err = "";
35     var results = null;
36    
37     var watchdog_id = 0;
38     var watchdog_callback = null;
39    
40     // Object to hold search results
41     function Result(title, link, freq)
42     {
43     this.title=title;
44     this.link=link;
45     this.frequency=Number(freq);
46     }
47    
48     // Function to merge (intersect) two result sets
49     function intersect_results(data)
50     {
51     // If there are no stored results, then these are the results
52     if(!results)
53     {
54     results = data;
55     return;
56     }
57    
58     var output=new Array();
59    
60     // There are existing results, to do an intersect...
61     for(var i=0; i<results.length; i++)
62     {
63     for(var j=0; j<data.length; j++)
64     {
65     if(data[j].title == results[i].title)
66     {
67     results[i].frequency += data[j].frequency;
68     output.push(results[i]);
69     break;
70     }
71     }
72     }
73    
74     results = output;
75     }
76    
77     /*
78     From David Flanagan's, _Javascript:_The Definitive_Guide_, pg. 294-5,
79     published by O'Reilly, 4th edition, 2002
80     */
81     function debug(msg)
82     {
83     // return; // Disable debugging
84    
85     if(!debug.box)
86     {
87     debug.box = document.createElement("div");
88     debug.box.setAttribute("style",
89     "background-color:white" +
90     "font-family: monospace; " +
91     "border: solid black 3px; "+
92     "padding: 10px;");
93    
94     document.body.appendChild(debug.box);
95     debug.box.innerHTML = "<h1 style='test-align:cent'>Debugging Output</h1>";
96     }
97    
98     var p = document.createElement("p");
99     p.appendChild(document.createTextNode(msg));
100     debug.box.appendChild(p);
101     }
102    
103     //
104    
105     // Convert a number into a base 62 alphanumeric number string
106     function convert(num)
107     {
108     var base = conversion.length;
109     var pow = 1;
110     var pos = 0;
111     var out = "";
112    
113     if(num == 0)
114     {
115     return "0";
116     }
117    
118     while (num > 0)
119     {
120     pos = num % base;
121     out = conversion.charAt(pos) + out;
122     num = Math.floor(num/base);
123     pow *= base;
124     }
125    
126     return out;
127     }
128    
129     function watchdog()
130     {
131     debug ("TIMEOUT!");
132     watchdog_callback(new Array());
133     }
134    
135     // This function loads the XML document from the specified URL, and when
136     // it is fully loaded, passes that document and the url to the specified
137     // handler function. This function works with any XML document
138     function loadXML(url, handler, data, result_handler)
139     {
140     debug("loadXML("+url+","+data+")");
141    
142     // Timeout operation in 10 seconds
143     watchdog_callback = result_handler;
144     watchdog_id=setTimeout("watchdog()", 20000);
145    
146     debug("setTimeout = "+watchdog_id);
147    
148     try
149     {
150     // Use the standard DOM Level 2 technique, if it is supported
151     if (document.implementation && document.implementation.createDocument)
152     {
153     // Create a new Document object
154     var xmldoc = document.implementation.createDocument("", "", null);
155    
156     // Specify what should happen when it finishes loading
157     xmldoc.onload = function() { handler(xmldoc, url, data, result_handler); }
158    
159     //xmldoc.onerror = docError;
160     //xmldoc.addEventListener("load",docError,false);
161    
162     // And tell it what URL to load
163     xmldoc.load(url);
164     }
165     // Otherwise use Microsoft's proprietary API for Internet Explorer
166     // Something about not following standards once again
167     else if (window.ActiveXObject)
168     {
169     //var xmldoc = new ActiveXObject("MSXML2.DOMDocument"); // Create doc.
170     var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // Create doc.
171     // Specify onload
172     xmldoc.onreadystatechange = function()
173     {
174     if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler);
175     }
176     xmldoc.load(url); // Start loading!
177     }
178     }
179     catch(ex)
180     {
181     clearTimeout(watchdog_id);
182     debug("clearTimeout = "+watchdog_id);
183     debug ("CAUGHT EXCEPTION!");
184     result_handler(new Array());
185     return false;
186     }
187    
188     return true;
189     }
190    
191     function loadData(xmldoc, url, pos, result_handler)
192     {
193     clearTimeout(watchdog_id);
194     debug("clearTimeout = "+watchdog_id);
195    
196     debug ("loadData("+url+","+pos+")");
197    
198     var data = new Array();
199    
200     // Get all entries
201     var entries = xmldoc.getElementsByTagName("e");
202    
203     if(entries.length > pos)
204     {
205     // Get the links associated with this query
206     var links = entries[pos].getElementsByTagName("l");
207    
208     // Dynamically append results to output
209     for(var i=0; i<links.length; i++)
210     {
211     data.push(new Result(links[i].getAttribute("t"),
212     links[i].firstChild.data,
213     links[i].getAttribute("f")));
214     }
215    
216     intersect_results(data);
217    
218     if(query_left.length > 0)
219     {
220     doSearch(query_left, result_handler);
221     }
222     else
223     {
224     results.sort(sortResults);
225     result_handler(results);
226     }
227     }
228     else
229     {
230     debug("INTERNAL ERROR, Inconsistent index");
231     search_err="INTERNAL ERROR, Inconsistent index";
232     }
233     }
234    
235     function sortResults(a, b)
236     {
237     return a.frequency - b.frequency;
238     }
239    
240     function traverseTree(xmldoc, url, query, result_handler)
241     {
242     clearTimeout(watchdog_id);
243     debug("clearTimeout = "+watchdog_id);
244    
245     debug("traverseTree("+xmldoc+","+url+","+query+")");
246    
247     var keys = xmldoc.getElementsByTagName("k");
248     var i;
249    
250     for(i = 0; i < keys.length; i++)
251     {
252     var key = keys[i].firstChild.data;
253     debug("traverseTree: key="+key+" query="+query);
254     if(key != '' && key != null)
255     {
256     // Case where current key is greater than query, descend
257     if(key > query)
258     {
259     if(key != '' && key != null)
260     {
261     if(!loadXML(url.replace(".xml","/"+convert(i)+".xml"),
262     traverseTree,query,result_handler))
263     {
264     debug("Unable to locate key "+query);
265 dpavlin 2 result_handler(new Array());
266 dpavlin 1 }
267     // make sure of garbage collection
268     xmldoc=null;
269     return;
270     }
271     }
272     // Found it!
273     else if(key==query)
274     {
275     if(!loadXML(url.replace(/(\w+\.xml)/, "_$1"),
276     loadData, i, result_handler))
277     {
278     debug("ERROR: Unable to locate data "+query);
279 dpavlin 2 result_handler(new Array());
280 dpavlin 1 }
281     // make sure of garbage collection
282     xmldoc=null;
283     return;
284     }
285     }
286     }
287     // Look past the end...
288 dpavlin 2 if(keys.length == 0 || !loadXML(url.replace(".xml","/"+convert(i)+".xml"),
289 dpavlin 1 traverseTree,query,result_handler))
290     {
291     debug("Unable to locate key "+query);
292 dpavlin 2 result_handler(new Array());
293 dpavlin 1 }
294     // make sure of garbage collection
295     xmldoc=null;
296     return;
297     }
298    
299     function doSearch(query, result_func)
300     {
301     //alert("doSearch("+query+")");
302     var pos=query.search(/[\s\+]/);
303    
304     if(pos < 0)
305     {
306     query_left = "";
307     }
308     else
309     {
310     query_left = query.slice(pos+1);
311     query = query.slice(0,pos);
312     }
313    
314     if(!loadXML("0.xml", traverseTree, query.toLowerCase(), result_func))
315     {
316     debug("ERROR: Couldn't find main index 0.xml");
317     search_err = "INTERNAL ERROR: Unable to load main index 0.xml";
318     }
319     }

  ViewVC Help
Powered by ViewVC 1.1.26