/[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

Annotation of /trunk2/out/js/search.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 450 - (hide annotations)
Wed Sep 15 21:15:23 2004 UTC (19 years, 7 months ago) by dpavlin
File MIME type: application/javascript
File size: 8143 byte(s)
jsFind: fix warning with strict JavaScript

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

  ViewVC Help
Powered by ViewVC 1.1.26