--- trunk2/out/js/search.js 2004/09/15 21:15:23 450 +++ trunk2/out/js/search.js 2004/10/23 18:18:11 534 @@ -27,7 +27,7 @@ // Constants var conversion = new String - ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"); + ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"); // State variables var query_left = ""; @@ -39,284 +39,353 @@ var watchdog_callback = null; // Object to hold search results -function Result(title, link, freq) -{ - this.title=title; - this.link=link; - this.frequency=Number(freq); +function Result(title, link, freq) { + this.title=title; + this.link=link; + this.frequency=Number(freq); } // Function to merge (intersect) two result sets -function intersect_results(data) -{ - // If there are no stored results, then these are the results - if(!results) - { - results = data; - return; - } - - var output=new Array(); - - // There are existing results, to do an intersect... - for(var i=0; i 0) - { - pos = num % base; - out = conversion.charAt(pos) + out; - num = Math.floor(num/base); - pow *= base; - } - - return out; -} - -function watchdog() -{ - debug ("TIMEOUT!"); - watchdog_callback(new Array()); +function convert(num) { + var base = conversion.length; + var pow = 1; + var pos = 0; + var out = ""; + + if (num == 0) return "0"; + + while (num > 0) { + pos = num % base; + out = conversion.charAt(pos) + out; + num = Math.floor(num/base); + pow *= base; + } + + return out; +} + +function watchdog() { + debug ("TIMEOUT!"); + watchdog_callback(new Array()); } +var xmldoc; + // This function loads the XML document from the specified URL, and when // it is fully loaded, passes that document and the url to the specified // handler function. This function works with any XML document -function loadXML(url, handler, data, result_handler) -{ - debug("loadXML("+url+","+data+")"); - - // Timeout operation in 10 seconds - watchdog_callback = result_handler; - watchdog_id=setTimeout("watchdog()", 20000); - - debug("setTimeout = "+watchdog_id); - - try - { - var xmldoc; - // Use the standard DOM Level 2 technique, if it is supported - if (document.implementation && document.implementation.createDocument) - { - // Create a new Document object - xmldoc = document.implementation.createDocument("", "", null); - - // Specify what should happen when it finishes loading - xmldoc.onload = function() { handler(xmldoc, url, data, result_handler); } - - //xmldoc.onerror = docError; - //xmldoc.addEventListener("load",docError,false); - - // And tell it what URL to load - xmldoc.load(url); - } - // Otherwise use Microsoft's proprietary API for Internet Explorer - // Something about not following standards once again - else if (window.ActiveXObject) - { - xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // Create doc. - if (! xmldoc) xmldoc = new ActiveXObject("MSXML2.DOMDocument"); // Create doc. - // Specify onload - xmldoc.onreadystatechange = function() - { - if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler); - } - xmldoc.load(url); // Start loading! - } - } - catch(ex) - { - clearTimeout(watchdog_id); - debug("clearTimeout = "+watchdog_id); - debug ("CAUGHT EXCEPTION!"); - result_handler(new Array()); - return false; - } - - return true; -} - -function loadData(xmldoc, url, pos, result_handler) -{ - clearTimeout(watchdog_id); - debug("clearTimeout = "+watchdog_id); - - debug ("loadData("+url+","+pos+")"); - - var data = new Array(); - - // Get all entries - var entries = xmldoc.getElementsByTagName("e"); - - if(entries.length > pos) - { - // Get the links associated with this query - var links = entries[pos].getElementsByTagName("l"); - - // Dynamically append results to output - for(var i=0; i 0) - { - doSearch(index_path, query_left, result_handler); - } - else - { - results.sort(sortResults); - result_handler(results); - } - } - else - { - debug("INTERNAL ERROR, Inconsistent index"); - search_err="INTERNAL ERROR, Inconsistent index"; - } -} - -function sortResults(a, b) -{ - return a.frequency - b.frequency; -} - -function traverseTree(xmldoc, url, query, result_handler) -{ - clearTimeout(watchdog_id); - debug("clearTimeout = "+watchdog_id); + +function loadXML(url, handler, data, result_handler) { + debug("loadXML("+url+","+data+")"); + + // Timeout operation in 10 seconds + watchdog_callback = result_handler; + watchdog_id=setTimeout("watchdog()", 20000); + + debug("setTimeout = "+watchdog_id); + + try { + // Use the standard DOM Level 2 technique, if it is supported + if (document.implementation && document.implementation.createDocument) { + // Create a new Document object + xmldoc = document.implementation.createDocument("", "", null); + + // Specify what should happen when it finishes loading + xmldoc.onload = function() { handler(xmldoc, url, data, result_handler); } + + //xmldoc.onerror = docError; + //xmldoc.addEventListener("load",docError,false); + + // And tell it what URL to load + xmldoc.load(url); + return true; + } + // Otherwise use Microsoft's proprietary API for Internet Explorer + // Something about not following standards once again + else if (window.ActiveXObject) { + xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // Create doc. + if (! xmldoc) xmldoc = new ActiveXObject("MSXML2.DOMDocument"); // Create doc. + // Specify onload + xmldoc.onreadystatechange = function() { + if (xmldoc.readyState == 4) handler(xmldoc, url, data, result_handler); + } + xmldoc.load(url); // Start loading! + return true; + } + // else fallback on usage of iframes to load xml (Opera 7.53 without Java and maybe old Mac browsers) + else { + debug("using iframe xml loader - experimental and slow"); + if (! window.xml_iframe) { + debug("creating iframe"); + window.xml_iframe = document.createElement('div'); + window.xml_iframe.innerHTML = ''; + document.body.appendChild(window.xml_iframe); + } else { + debug("loading xml in existing iframe"); + window.frames.xml_iframe.window.document.location.href = url; + } + + // set timeout to re-check if iframe is loaded + window.iframe_timeout = window.setInterval('iframe_xml_loaded();',100); + + // save some data for iframe_xml_loaded() + window.xml_handler = handler; + window.xml_url = url; + window.xml_data = data; + window.xml_result_handler = result_handler; + return true; + } + + clearTimeout(watchdog_id); + debug("Browser incompatilibity: can't request XML document by one of supported methods"); + return false; + } + + catch(ex) { + clearTimeout(watchdog_id); + debug("clearTimeout = "+watchdog_id); + debug ("CAUGHT EXCEPTION!"); + result_handler(new Array()); + return false; + } + + return true; +} + +function iframe_xml_loaded() { + debug("iframe_xmldoc_loaded"); + if (! window.frames['xml_iframe']) return; + var xml = eval('window.frames.xml_iframe.window.document'); + if (xml) { + clearTimeout(window.iframe_timeout); + debug("calling handler with ("+window.xml_url+","+window.xml_data+",...)"); + window.xml_handler(window.frames.xml_iframe.window.document, window.xml_url, window.xml_data, window.xml_result_handler); + } else { + debug("can't eval iframe with xml"); + } +} + +var data = new Array(); + +function loadData_intersect(xmldoc, url, pos, result_handler) { + data = new Array(); + if (loadData(xmldoc, url, pos, result_handler)) { + intersect_results(data); + search_query_left(result_handler); + } else { + debug("INTERNAL ERROR, Inconsistent index"); + search_err="INTERNAL ERROR, Inconsistent index"; + } +} + +function loadData(xmldoc, url, pos, result_handler) { + + clearTimeout(watchdog_id); + debug("clearTimeout = "+watchdog_id); + + debug ("loadData("+url+","+pos+")"); + + // Get all entries + var entries = xmldoc.getElementsByTagName("e"); + + if (entries.length > pos) { + // Get the links associated with this query + var links = entries[pos].getElementsByTagName("l"); + + debug("loaded "+links.length+" links"); + + // Dynamically append results to output + var ret = false; + for(i=0; i 0) { + doSearch(index_path, query_left, result_handler); + } else { + results.sort(sortResults); + result_handler(results); + } +} + +// you may override this function to sort by something else +function sortResults(a, b) { + return a.frequency - b.frequency; +} + +function traverseTree(xmldoc, url, query, result_handler) { + clearTimeout(watchdog_id); + debug("clearTimeout = "+watchdog_id); - debug("traverseTree("+xmldoc+","+url+","+query+")"); + debug("traverseTree("+xmldoc+","+url+","+query+")"); + + var keys = xmldoc.getElementsByTagName("k"); + var i; + + // support for wildcard + var qlen = query.length; + var wildcard = false; + var query_full = query; + if (query.charAt(qlen-1) == '*') { + wildcard = true; + query = query.substr(0,--qlen); + debug("using wildcard "+query+"*"); + } + + for(i = 0; i < keys.length; i++) { + var key = keys[i].firstChild.data; + + if (wildcard) { + key = key.substr(0,qlen); + debug("wildcard key "+key+"*"); + } + + debug("traverseTree: "+key+"=="+query); + + if (key != '' && key != null) { + // Case where current key is greater than query, descend + if (key > query) { + if (key != '' && key != null) { + if (! loadXML(url.replace(".xml","/"+convert(i)+".xml"), traverseTree,query_full,result_handler)) { + 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 (wildcard) { + data = new Array(); + while (xmldoc && keys[i].firstChild.data.substr(0,qlen) == query) { + var url2 = url; + if (loadXML(url2.replace(/(\w+\.xml)/, "_$1"), loadData, i, result_handler)) { + // add loaded data to results + if (! results) { + results = data; + debug("wildcard loop: "+i+" created "+data.length+" results"); + } else { + for (var j=0; j