+/*
+** $Id: pz2.js,v 1.13 2007-05-14 12:57:43 jakub Exp $
+** pz2.js - pazpar2's javascript client library.
+*/
+
+//since explorer is flawed
+if (!window['Node']) {
+ window.Node = new Object();
+ Node.ELEMENT_NODE = 1;
+ Node.ATTRIBUTE_NODE = 2;
+ Node.TEXT_NODE = 3;
+ Node.CDATA_SECTION_NODE = 4;
+ Node.ENTITY_REFERENCE_NODE = 5;
+ Node.ENTITY_NODE = 6;
+ Node.PROCESSING_INSTRUCTION_NODE = 7;
+ Node.COMMENT_NODE = 8;
+ Node.DOCUMENT_NODE = 9;
+ Node.DOCUMENT_TYPE_NODE = 10;
+ Node.DOCUMENT_FRAGMENT_NODE = 11;
+ Node.NOTATION_NODE = 12;
+}
// check for jQuery
-if(typeof window.jQuery == "undefined")
+if(typeof window.jQuery == "undefined"){
throw new Error("pz2.js requires jQuery library");
+}
// prevent execution of more than once
if(typeof window.pz2 == "undefined") {
window.undefined = window.undefined;
// at least one callback required
if ( !paramArray )
- throw new Error("An array with parameters has to be suplied when instantiating a class");
+ throw new Error("An array with parameters has to be suplied when instantiating a class");
+
+ //supported pazpar2's protocol version
+ __myself.suppProtoVer = '1';
+ __myself.errorHandler = paramArray.errorhandler || null;
// function callbacks
__myself.statCallback = paramArray.onstat || null;
__myself.termlistCallback = paramArray.onterm || null;
__myself.recordCallback = paramArray.onrecord || null;
__myself.bytargetCallback = paramArray.onbytarget || null;
+ __myself.resetCallback = paramArray.onreset || null;
// termlist keys
__myself.termKeys = paramArray.termlist || "subject";
//timers
__myself.statTime = paramArray.stattime || 2000;
__myself.statTimer = null;
- __myself.termTime = paramArray.termtime || 2000;
+ __myself.termTime = paramArray.termtime || 1000;
__myself.termTimer = null;
- __myself.showTime = paramArray.showtime || 2000;
+ __myself.showTime = paramArray.showtime || 1000;
__myself.showTimer = null;
+ __myself.showFastCount = 4;
__myself.bytargetTime = paramArray.bytargettime || 1000;
__myself.bytargetTimer = null;
+ //useful?
+ __myself.dumpFactor = 500;
+ __myself.showCounter = 0;
+ __myself.termCounter = 0;
+
// active clients, updated by stat and show
// might be an issue since bytarget will poll accordingly
__myself.activeClients = 1;
// error handling
$(document).ajaxError(
- function (request, settings, exception) {
- if ( settings.responseXML && settings.responseXML.getElementsByTagName("error") )
- throw new Error( settings.responseXML.getElementsByTagName("error")[0].childNodes[0].nodeValue);
+ function (ajaxError, xhr, reqSettings, prevException)
+ {
+ if ( xhr.responseXML && xhr.responseXML.getElementsByTagName("error").length )
+ {
+ var errMsg = xhr.responseXML.getElementsByTagName("error")[0].childNodes[0].nodeValue;
+ var errCode = xhr.responseXML.getElementsByTagName("error")[0].getAttribute("code");
+
+ var err = new Error(errMsg);
+ err.code = errCode;
+
+ if (__myself.errorHandler) {
+ __myself.errorHandler(err);
+ }
+ else {
+ throw err;
+ }
+ }
+ // ensure the errors are propagated
+ else if (prevException != undefined ) {
+ throw prevException;
+ }
+ else {
+ throw new Error("XMLHttpRequest error. STATUS: " + xhr.status + " STATUS TEXT: " + xhr.statusText);
+ }
});
// auto init session?
if (paramArray.autoInit !== false)
- __myself.init(__myself.keepAlive);
-}
+ __myself.init();
+};
pz2.prototype = {
- init: function(keepAlive)
+ reset: function ()
{
- if ( keepAlive < __myself.keepAlive )
- __myself.keepAlive = keepAlive;
-
- $.get( __myself.pz2String,
- { "command": "init" },
- function(data) {
- if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
- __myself.initStatusOK = true;
- __myself.sessionID = data.getElementsByTagName("session")[0].childNodes[0].nodeValue;
- setTimeout(__myself.ping, __myself.keepAlive);
+ __myself.sessionID = null;
+ __myself.initStatusOK = false;
+ __myself.pingStatusOK = false;
+ __myself.searchStatusOK = false;
+
+ clearTimeout(__myself.statTimer);
+ clearTimeout(__myself.showTimer);
+ clearTimeout(__myself.termTimer);
+ clearTimeout(__myself.bytargetTimer);
+
+ __myself.resetCallback();
+ },
+ init: function ( sessionId )
+ {
+ __myself.reset();
+ if ( sessionId != undefined ) {
+ __myself.initStatusOK = true;
+ __myself.sessionID = sessionId;
+ __myself.ping();
+
+ } else {
+ $.get( __myself.pz2String,
+ { "command": "init" },
+ function(data) {
+ if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
+ if ( data.getElementsByTagName("protocol")[0].childNodes[0].nodeValue != __myself.suppProtoVer )
+ throw new Error("Server's protocol not supported by the client");
+ __myself.initStatusOK = true;
+ __myself.sessionID = data.getElementsByTagName("session")[0].childNodes[0].nodeValue;
+ setTimeout("__myself.ping()", __myself.keepAlive);
+ }
+ else
+ // if it gets here the http return code was 200 (pz2 errors are 417)
+ // but the response was invalid, it should never occur
+ setTimeout("__myself.init()", 1000);
}
- else
- // if it gets here the http return code was 200 (pz2 errors are 417)
- // but the response was invalid, it should never occur
- setTimeout("__myself.init()", 1000)
- }
- );
+ );
+ }
},
// no need to ping explicitly
- ping: function()
+ ping: function ()
{
if( !__myself.initStatusOK )
return;
else
// if it gets here the http return code was 200 (pz2 errors are 417)
// but the response was invalid, it should never occur
- setTimeout("__myself.ping()", 1000)
+ setTimeout("__myself.ping()", 1000);
}
);
},
- search: function(query, num, sort, filter)
+ search: function (query, num, sort, filter)
{
clearTimeout(__myself.statTimer);
clearTimeout(__myself.showTimer);
clearTimeout(__myself.termTimer);
clearTimeout(__myself.bytargetTimer);
-
+
+ __myself.showCounter = 0;
+ __myself.termCounter = 0;
+
if( !__myself.initStatusOK )
return;
if ( data.getElementsByTagName("status")[0].childNodes[0].nodeValue == "OK" ) {
__myself.searchStatusOK = true;
//piggyback search
- __myself.show(0, num, sort)
+ __myself.show(0, num, sort);
if ( __myself.statCallback )
__myself.statTimer = setTimeout("__myself.stat()", __myself.statTime / 2);
if ( __myself.termlistCallback )
- __myself.termlist();
- //__myself.termTimer = setTimeout("__myself.termlist()", __myself.termTime / 2);
+ //__myself.termlist();
+ __myself.termTimer = setTimeout("__myself.termlist()", __myself.termTime / 2);
if ( __myself.bytargetCallback )
__myself.bytargetTimer = setTimeout("__myself.bytarget()", __myself.bytargetTime / 2);
}
"idle": Number( data.getElementsByTagName("idle")[0].childNodes[0].nodeValue ),
"failed": Number( data.getElementsByTagName("failed")[0].childNodes[0].nodeValue ),
"error": Number( data.getElementsByTagName("error")[0].childNodes[0].nodeValue )
- }
+ };
__myself.statCallback(stat);
if (activeClients > 0)
__myself.statTimer = setTimeout("__myself.stat()", __myself.statTime);
else
// if it gets here the http return code was 200 (pz2 errors are 417)
// but the response was invalid, it should never occur
- __myself.statTimer = setTimeout("__myself.stat()", __myself.statTime / 4)
+ __myself.statTimer = setTimeout("__myself.stat()", __myself.statTime / 4);
}
);
},
"start": Number( data.getElementsByTagName("start")[0].childNodes[0].nodeValue ),
"num": Number( data.getElementsByTagName("num")[0].childNodes[0].nodeValue ),
"hits": []
- }
+ };
// parse all the first-level nodes for all <hit> tags
var hits = data.getElementsByTagName("hit");
var hit = new Array();
for (i = 0; i < hits.length; i++) {
show.hits[i] = new Array();
+ show.hits[i]['location'] = new Array();
for ( j = 0; j < hits[i].childNodes.length; j++) {
+ var locCount = 0;
if ( hits[i].childNodes[j].nodeType == Node.ELEMENT_NODE ) {
- var nodeName = hits[i].childNodes[j].nodeName;
- var nodeText = hits[i].childNodes[j].firstChild.nodeValue;
- show.hits[i][nodeName] = nodeText;
+ if (hits[i].childNodes[j].nodeName == 'location') {
+ var locNode = hits[i].childNodes[j];
+ var id = locNode.getAttribute('id');
+ show.hits[i]['location'][id] = {
+ "id": locNode.getAttribute("id"),
+ "name": locNode.getAttribute("name")
+ };
+ }
+ else {
+ var nodeName = hits[i].childNodes[j].nodeName;
+ var nodeText = hits[i].childNodes[j].firstChild.nodeValue;
+ show.hits[i][nodeName] = nodeText;
+ }
}
}
}
__myself.showCallback(show);
+ __myself.showCounter++;
+ var delay = __myself.showTime;
+ if (__myself.showCounter > __myself.showFastCount)
+ delay *= 2;
if (activeClients > 0)
- __myself.showTimer = setTimeout("__myself.show()", __myself.showTime);
+ __myself.showTimer = setTimeout("__myself.show()", delay);
}
else
// if it gets here the http return code was 200 (pz2 errors are 417)
for ( j = 0; j < locationNodes[i].childNodes.length; j++) {
if ( locationNodes[i].childNodes[j].nodeType == Node.ELEMENT_NODE ) {
var nodeName = locationNodes[i].childNodes[j].nodeName;
- var nodeText = locationNodes[i].childNodes[j].firstChild.nodeValue;
+ var nodeText;
+ if (locationNodes[i].childNodes[j].firstChild)
+ nodeText = locationNodes[i].childNodes[j].firstChild.nodeValue;
+ else
+ nodeText = '';
record["location"][i][nodeName] = nodeText;
}
}
{ "command": "termlist", "session": __myself.sessionID, "name": __myself.termKeys },
function(data) {
if ( data.getElementsByTagName("termlist") ) {
- var termList = { "activeclients": Number( data.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue ) }
+ var termList = { "activeclients": Number( data.getElementsByTagName("activeclients")[0].childNodes[0].nodeValue ) };
var termLists = data.getElementsByTagName("list");
//for each termlist
for (i = 0; i < termLists.length; i++) {
for (j = 0; j < terms.length; j++) {
var term = {
"name": terms[j].getElementsByTagName("name")[0].childNodes[0].nodeValue,
- "freq": terms[j].getElementsByTagName("frequency")[0].childNodes[0].nodeValue,
- }
+ "freq": terms[j].getElementsByTagName("frequency")[0].childNodes[0].nodeValue
+ };
var termIdNode = terms[j].getElementsByTagName("id");
if(terms[j].getElementsByTagName("id").length)
termList[listName][j] = term;
}
}
+
__myself.termlistCallback(termList);
+ __myself.termCounter++;
if (termList["activeclients"] > 0)
- __myself.termTimer = setTimeout("__myself.termlist()", __myself.termTime);
+ __myself.termTimer = setTimeout("__myself.termlist()", (__myself.termTime + __myself.termCounter*__myself.dumpFactor));
}
else
// if it gets here the http return code was 200 (pz2 errors are 417)