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

Contents of /trunk2/out/js/search.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 505 - (show annotations)
Sun Oct 10 18:55:05 2004 UTC (19 years, 5 months ago) by dpavlin
File MIME type: application/javascript
File size: 9659 byte(s)
jsFind: fix warning in FireFox

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 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
83 var debug_div = null;
84
85 function debug(msg)
86 {
87 // return; // Disable debugging
88
89 if (! debug_div) debug_div = document.getElementById('debug');
90
91 // this will create debug div if it doesn't exist.
92 if (! debug_div) {
93 debug_div = document.createElement('div');
94 if (document.body) document.body.appendChild(debug_div);
95 else debug_div = null;
96 }
97 if (debug_div) {
98 debug_div.appendChild(document.createTextNode(msg));
99 debug_div.appendChild(document.createElement("br"));
100 }
101 }
102
103 // Convert a number into a base 62 alphanumeric number string
104 function convert(num)
105 {
106 var base = conversion.length;
107 var pow = 1;
108 var pos = 0;
109 var out = "";
110
111 if(num == 0)
112 {
113 return "0";
114 }
115
116 while (num > 0)
117 {
118 pos = num % base;
119 out = conversion.charAt(pos) + out;
120 num = Math.floor(num/base);
121 pow *= base;
122 }
123
124 return out;
125 }
126
127 function watchdog()
128 {
129 debug ("TIMEOUT!");
130 watchdog_callback(new Array());
131 }
132
133 var xmldoc;
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 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 return true;
165 }
166 // Otherwise use Microsoft's proprietary API for Internet Explorer
167 // Something about not following standards once again
168 else if (window.ActiveXObject)
169 {
170 xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // Create doc.
171 if (! xmldoc) xmldoc = new ActiveXObject("MSXML2.DOMDocument"); // Create doc.
172 // Specify onload
173 xmldoc.onreadystatechange = function()
174 {
175 if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler);
176 }
177 xmldoc.load(url); // Start loading!
178 return true;
179 }
180 // else fallback on usage of iframes to load xml (Opera 7.53 without Java and maybe old Mac browsers)
181 else {
182 debug("using iframe xml loader - experimental and slow");
183 if (! window.xml_iframe) {
184 debug("creating iframe");
185 window.xml_iframe = document.createElement('div');
186 window.xml_iframe.innerHTML = '<iframe src="'+url+'" name="xml_iframe" height="0" width="0" style="display: none;"></iframe>';
187 document.body.appendChild(window.xml_iframe);
188 } else {
189 debug("loading xml in existing iframe");
190 window.frames.xml_iframe.window.document.location.href = url;
191 }
192
193 // set timeout to re-check if iframe is loaded
194 window.iframe_timeout = window.setInterval('iframe_xml_loaded();',100);
195
196 // save some data for iframe_xml_loaded()
197 window.xml_handler = handler;
198 window.xml_url = url;
199 window.xml_data = data;
200 window.xml_result_handler = result_handler;
201 return true;
202 }
203 clearTimeout(watchdog_id);
204 debug("Browser incompatilibity: can't request XML document by one of supported methods");
205 return false;
206 }
207 catch(ex)
208 {
209 clearTimeout(watchdog_id);
210 debug("clearTimeout = "+watchdog_id);
211 debug ("CAUGHT EXCEPTION!");
212 result_handler(new Array());
213 return false;
214 }
215
216 return true;
217 }
218
219 function iframe_xml_loaded() {
220 debug("iframe_xmldoc_loaded");
221 if (! window.frames['xml_iframe']) return;
222 var xml = eval('window.frames.xml_iframe.window.document');
223 if (xml) {
224 clearTimeout(window.iframe_timeout);
225 debug("calling handler with ("+window.xml_url+","+window.xml_data+",...)");
226 window.xml_handler(window.frames.xml_iframe.window.document, window.xml_url, window.xml_data, window.xml_result_handler);
227 } else {
228 debug("can't eval iframe with xml");
229 }
230 }
231
232 function loadData(xmldoc, url, pos, result_handler)
233 {
234 clearTimeout(watchdog_id);
235 debug("clearTimeout = "+watchdog_id);
236
237 debug ("loadData("+url+","+pos+")");
238
239 var data = new Array();
240
241 // Get all entries
242 var entries = xmldoc.getElementsByTagName("e");
243
244 if(entries.length > pos)
245 {
246 // Get the links associated with this query
247 var links = entries[pos].getElementsByTagName("l");
248
249 // Dynamically append results to output
250 for(var i=0; i<links.length; i++)
251 {
252 data.push(new Result(links[i].getAttribute("t"),
253 links[i].firstChild.data,
254 links[i].getAttribute("f")));
255 }
256
257 intersect_results(data);
258
259 if(query_left.length > 0)
260 {
261 doSearch(index_path, query_left, result_handler);
262 }
263 else
264 {
265 results.sort(sortResults);
266 result_handler(results);
267 }
268 }
269 else
270 {
271 debug("INTERNAL ERROR, Inconsistent index");
272 search_err="INTERNAL ERROR, Inconsistent index";
273 }
274 }
275
276 function sortResults(a, b)
277 {
278 return a.frequency - b.frequency;
279 }
280
281 function traverseTree(xmldoc, url, query, result_handler)
282 {
283 clearTimeout(watchdog_id);
284 debug("clearTimeout = "+watchdog_id);
285
286 debug("traverseTree("+xmldoc+","+url+","+query+")");
287
288 var keys = xmldoc.getElementsByTagName("k");
289 var i;
290
291 for(i = 0; i < keys.length; i++)
292 {
293 var key = keys[i].firstChild.data;
294 debug("traverseTree: key="+key+" query="+query);
295 if(key != '' && key != null)
296 {
297 // Case where current key is greater than query, descend
298 if(key > query)
299 {
300 if(key != '' && key != null)
301 {
302 if(!loadXML(url.replace(".xml","/"+convert(i)+".xml"),
303 traverseTree,query,result_handler))
304 {
305 debug("Unable to locate key "+query);
306 result_handler(new Array());
307 }
308 // make sure of garbage collection
309 xmldoc=null;
310 return;
311 }
312 }
313 // Found it!
314 else if(key==query)
315 {
316 if(!loadXML(url.replace(/(\w+\.xml)/, "_$1"),
317 loadData, i, result_handler))
318 {
319 debug("ERROR: Unable to locate data "+query);
320 result_handler(new Array());
321 }
322 // make sure of garbage collection
323 xmldoc=null;
324 return;
325 }
326 }
327 }
328 // Look past the end...
329 if(keys.length == 0 || !loadXML(url.replace(".xml","/"+convert(i)+".xml"),
330 traverseTree,query,result_handler))
331 {
332 debug("Unable to locate key "+query);
333 result_handler(new Array());
334 }
335 // make sure of garbage collection
336 xmldoc=null;
337 return;
338 }
339
340 function doSearch(index_name,query, result_func)
341 {
342 //alert("doSearch("+index_name+","+query+")");
343 var pos=query.search(/[\s\+]/);
344 if (index_name) index_path = index_name+'/';
345
346 if(pos < 0)
347 {
348 query_left = "";
349 }
350 else
351 {
352 query_left = query.slice(pos+1);
353 query = query.slice(0,pos);
354 }
355
356 if(!loadXML(index_path+"0.xml", traverseTree, query.toLowerCase(), result_func))
357 {
358 debug("ERROR: Couldn't find main index 0.xml");
359 search_err = "INTERNAL ERROR: Unable to load main index 0.xml";
360 }
361 }

  ViewVC Help
Powered by ViewVC 1.1.26