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

Contents of /trunk/html/js/search.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Sun Jul 11 20:18:25 2004 UTC (19 years, 9 months ago) by dpavlin
File MIME type: application/javascript
File size: 7881 byte(s)
initial import into subversion of version 0.1

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 }
266 // make sure of garbage collection
267 xmldoc=null;
268 return;
269 }
270 }
271 // Found it!
272 else if(key==query)
273 {
274 if(!loadXML(url.replace(/(\w+\.xml)/, "_$1"),
275 loadData, i, result_handler))
276 {
277 debug("ERROR: Unable to locate data "+query);
278 }
279 // make sure of garbage collection
280 xmldoc=null;
281 return;
282 }
283 }
284 }
285 // Look past the end...
286 if(!loadXML(url.replace(".xml","/"+convert(i)+".xml"),
287 traverseTree,query,result_handler))
288 {
289 debug("Unable to locate key "+query);
290 }
291 // make sure of garbage collection
292 xmldoc=null;
293 return;
294 }
295
296 function doSearch(query, result_func)
297 {
298 //alert("doSearch("+query+")");
299 var pos=query.search(/[\s\+]/);
300
301 if(pos < 0)
302 {
303 query_left = "";
304 }
305 else
306 {
307 query_left = query.slice(pos+1);
308 query = query.slice(0,pos);
309 }
310
311 if(!loadXML("0.xml", traverseTree, query.toLowerCase(), result_func))
312 {
313 debug("ERROR: Couldn't find main index 0.xml");
314 search_err = "INTERNAL ERROR: Unable to load main index 0.xml";
315 }
316 }

  ViewVC Help
Powered by ViewVC 1.1.26