]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/extras/opensearchportal.html
automatically choosing "merged" or "column" view
[working/Evergreen.git] / Open-ILS / src / extras / opensearchportal.html
1 <html>
2         <head>
3                 <title>mikers experimental opensearch portal</title>
4                 <style>
5
6 * {
7         font-family: verdana,arial,helvetica,sans-serif;
8 }
9
10 #result_sources a {
11         font-size: 8px;
12         color: grey;
13         text-decoration: none;
14 }
15
16 td {
17         vertical-align: top;
18 }
19
20 .data_table {
21 }
22
23 caption {
24         border: solid lightblue 1px;
25 }
26
27 a {
28         color: blue;
29         text-decoration: none;
30 }
31
32 a:hover {
33         color: blue;
34         text-decoration: underline;
35 }
36
37 a:active {
38         color: red;
39         text-decoration: underline;
40 }
41
42 a:visited {
43         color: blue;
44         text-decoration: none;
45 }
46
47 .title_link {
48         font-size: medium;
49         font-weight: bold;
50 }
51
52 .desc_text {
53         font-size: small;
54 }
55
56 .hide {
57         color: lightgray;
58 }
59
60 .col_tab {
61         border-collapse: collapse;
62         border: solid gray 1px;
63 }
64
65 .res_table {
66         border-collapse: collapse;
67         /*width: 100%;*/
68         max-width: 400px;
69 }
70
71 .res_tr {
72         border-bottom: 1px dashed darkgrey;
73 }
74
75 .noshow {
76         display: none;
77         visibility: hidden;
78 }
79
80                 </style>
81                 <script>
82
83 var isIE = false;
84
85 function create_requestor () {
86         var req;
87         try { 
88                 req = new ActiveXObject("Msxml2.XMLHTTP");
89                 isIE = true;
90         } catch (e) {
91                 try { 
92                         req = new ActiveXObject("Microsoft.XMLHTTP");
93                         isIE = true;
94                 } catch (E) {
95                         req = false;
96                 }
97         }
98
99         if (!req && typeof XMLHttpRequest!='undefined') {
100                 req = new XMLHttpRequest();
101         }
102         
103         if(!req) {
104                 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
105                 return null;
106         }
107
108         return req;
109 }
110
111 var proxy = 'http://gapines.org/opensearch/?fetch=';
112
113 var images = [];
114 var search_templates = [];
115 var search_urls = {};
116 var rel_scales = {};
117
118 var current_startPage = 1;
119 var current_startIndex = 1;
120 var current_count = 5;
121
122 function opensearch ( term, reset ) {
123
124         if (reset) {
125                 current_startPage = 1;
126                 rel_scales = {};
127         }
128
129         document.getElementById('next_button').className = 'hide';
130
131         if (current_startPage == 1)
132                 document.getElementById('prev_button').className = 'hide';
133         else 
134                 document.getElementById('prev_button').className = '';
135
136         var tot = document.getElementById('total');
137         while (tot.lastChild)
138                         tot.removeChild(tot.lastChild);
139
140         var src = document.getElementById('result_sources');
141         while (src.lastChild)
142                         src.removeChild(src.lastChild);
143
144         document.getElementById('int_res_hide').className = 'noshow';
145         document.getElementById('col_res_hide').className = 'noshow';
146
147         var tab = document.getElementById('int_res');
148         while (tab.lastChild)
149                         tab.removeChild(tab.lastChild);
150
151         tab = document.getElementById('col_res');
152         while (tab.lastChild)
153                         tab.removeChild(tab.lastChild);
154
155         search_count = 0;
156
157         var sources = new Array();
158         var selector = document.getElementsByName('source');
159         for (var i = 0; i < selector.length; i++) {
160                 if (selector[i].checked) {
161                         sources.push(selector[i].value);
162                 }
163         }
164
165         search_templates = [];
166         for (var i in sources) {
167                 create_search( sources[i] );
168         }
169
170         current_startIndex = (current_count * (current_startPage - 1)) + 1; 
171
172         search_urls = [];
173         for (var i in search_templates) {
174                 if (!search_templates[i])
175                         continue;
176
177                 if (!rel_scales[i])
178                         rel_scales[i] = 0;
179
180                 var url = search_templates[i].replace(/\{searchTerms\}/,encodeURIComponent(term));
181                 url = url.replace(/\{startPage\}/,current_startPage);
182                 url = url.replace(/\{startIndex\}/,current_startIndex);
183                 url = url.replace(/\{count\}/,current_count);
184                 url = url.replace(/\{relevanceScale}/,rel_scales[i]);
185                 search_urls[i] = proxy + encodeURIComponent(url);
186
187                 src.innerHTML += '<a href="' + url + '">' + url + '</a><br>';
188         }
189
190         for (var i in search_urls) {
191                 if (!search_templates[i])
192                         continue;
193
194                 perform_search(i);
195         }
196
197         document.getElementById('page_label').innerHTML = current_startPage;
198 }
199
200 function perform_search ( source ) {
201         var req = create_requestor();
202
203         req.onreadystatechange = function () {
204                 if (req.readyState != 4)
205                         return;
206
207                 var xml = req.responseXML;
208
209                 var desc  = getElementTextNS('','description',xml,0);
210                 var xml_link  = getElementTextNS('','link',xml,0);
211
212                 var total  = getElementFloatNS('openSearch','totalResults',xml,0);
213                 var integratible = (getElementNS('openIll','relevance',xml,0) != null);
214                 var scale = getElementFloatNS('openIll','relevanceScale',xml,0);
215
216                 rel_scales[source]  = scale;
217                 
218                 var current_tot = getElementFloatNS('','span',document.getElementById('total').parentNode,0);
219                 var tot = document.getElementById('total');
220
221                 if (!current_tot)
222                         current_tot = 0;
223
224                 if (total > (current_startPage * current_count))
225                         document.getElementById('next_button').className = '';
226
227                 current_tot += total
228                 tot.innerHTML = current_tot;
229
230                 var list = xml.getElementsByTagName('item');
231                 for (var i = 0; i < list.length; i++) {
232
233                         if ( typeof list[i] != 'object')
234                                         continue;
235
236                         var tab;
237                         if (!integratible) {
238                                 tab = document.getElementById('col_res');
239                                 document.getElementById('col_res_hide').className = '';
240                                 var col = document.getElementById(source);
241                                 if (!col) {
242                                         var row = tab.rows[0];
243                                         if (!row)
244                                                 row = tab.insertRow(0);
245
246                                         col = document.createElement('td');
247                                         col.setAttribute('id',source);
248                                         row.appendChild(col);
249
250                                         tab = document.createElement('table');
251                                         tab.setAttribute('valign','top');
252                                         tab.setAttribute('class','col_tab');
253
254                                         var cap = document.createElement('caption');
255                                         tab.appendChild(cap);
256                                         cap.innerHTML = desc + ' -- <a href="' + xml_link + '">XML</a>';
257
258                                         col.appendChild(tab);
259
260                                         var per = parseInt(100 / search_urls.length);
261                                         col.setAttribute('valign','top');
262                                         col.setAttribute('width', + per + '%');
263
264                                 } else {
265                                         tab = col.firstChild;
266                                 }
267                         } else {
268                                 tab = document.getElementById('int_res');
269                                 document.getElementById('int_res_hide').className = '';
270                         }
271
272                         if (!tab.rows.length) {
273                                 add_result_row(tab, 0, list[i], source);
274                         } else {
275                                 for (var j = 0; j < tab.rows.length; j++) {
276                                         if ( typeof tab.rows[j] != 'object')
277                                                 continue;
278
279                                         var rank;
280                                         try {
281                                                 rank = getElementFloatNS('openIll','relevance',list[i],0);
282                                         } catch (e) {
283                                                 alert("error getting float relevance: " + e);
284                                                 rank = 0;
285                                         }
286
287                                         if ( rank < parseFloat(tab.rows[j].firstChild.firstChild.textContent) ) {
288                                                 if ( (j + 1) == tab.rows.length) {
289                                                         add_result_row(tab, tab.rows.length, list[i], source);
290                                                         break
291                                                 }
292                                                 continue;
293                                         }
294                                         add_result_row(tab, j, list[i], source);
295                                         break;
296                                 }
297                         }
298                 }
299         };
300
301         req.open('GET', proxy + encodeURIComponent(search_urls[source]), true);
302         req.send(null);
303 }
304
305
306 // retrieve float of an XML document element, including
307 // elements using namespaces
308 function getElementFloatNS(prefix, local, parentElem, index) {
309     var result = getElementNS(prefix, local, parentElem, index);
310     if (result) {
311         // get text, accounting for possible
312         // whitespace (carriage return) text nodes 
313         if (result.childNodes.length > 1) {
314             return parseFloat(result.childNodes[1].nodeValue);
315         } else {
316             return parseFloat(result.textContent);              
317         }
318     } else {
319         return 0;
320     }
321 }
322
323 function getElementNS(prefix, local, parentElem, index) {
324     var result = "";
325     if (prefix && isIE) {
326         // IE/Windows way of handling namespaces
327         return parentElem.getElementsByTagName(prefix + ":" + local)[index];
328     } else {
329         // the namespace versions of this method 
330         // (getElementsByTagNameNS()) operate
331         // differently in Safari and Mozilla, but both
332         // return value with just local name, provided 
333         // there aren't conflicts with non-namespace element
334         // names
335         return parentElem.getElementsByTagName(local)[index];
336     }
337 }
338
339 // retrieve text of an XML document element, including
340 // elements using namespaces
341 function getElementTextNS(prefix, local, parentElem, index) {
342     var result = getElementNS(prefix, local, parentElem, index);
343     if (result) {
344         // get text, accounting for possible
345         // whitespace (carriage return) text nodes 
346         if (result.childNodes.length > 1) {
347             return result.childNodes[1].nodeValue;
348         } else {
349             return result.textContent;                  
350         }
351     } else {
352         return '';
353     }
354 }
355
356 function add_result_row (tab, index, xml, source) {
357         var img = images[source];
358         var rank,title,tlink,desc;
359
360         try {
361                 rank = getElementFloatNS('openIll','relevance',xml,0);
362         } catch (e) {
363                 alert("error getting relevance: " + e);
364                 rank = '0';
365         }
366         
367         try {
368                 title = xml.getElementsByTagName('title')[0].textContent;
369         } catch (e) {
370                 title = '';
371         }
372         
373         try {
374                 tlink = xml.getElementsByTagName('link')[0].textContent;
375         } catch (e) {
376                 tlink = '';
377         }
378
379         try {
380                 description = xml.getElementsByTagName('description')[0].textContent;
381         } catch (e) {
382                 description = '';
383         }
384
385         var row = tab.insertRow(index);
386         row.className = 'res_tr';
387         row.innerHTML = '<td style="padding: 4px"><div style="display: none; visibility: hidden;">' + rank +
388                                                  '</div><span class="title_link"><a href="' + tlink + '">' + title +
389                                                  '</a></span><br/><span class="desc_text">' + description + '</span></td>' +
390                                                  '<td><img title="' + parseInt(rank) + '% Relevant" width="32" height="32" src="' + img + '"></td>';
391 }
392
393 function create_search ( s ) {
394         var req = create_requestor();
395
396         req.open('GET',proxy +  encodeURIComponent(s),false);
397         req.send(null);
398
399         try {
400                 var xml = req.responseXML;
401                 search_templates[s] = xml.getElementsByTagName('Url')[0].textContent;
402                 var i =  xml.getElementsByTagName('Image');
403                 if (i.length)
404                         images[s] = i[0].textContent;
405         } catch (e) {
406                 alert('BAD XML!\n\n' + e + '\n\n' + req.responseText);
407                 search_templates[s] = null;
408                 images[s] = null;
409         }
410
411 }
412
413                 </script>
414         </head>
415         <body>
416                 <br/>
417                 <form onsubmit="opensearch(document.getElementById('term').value, true); return false;">
418                 <table>
419                         <tr valign="top">
420                                 <td>Keyword Search: </td>
421                                 <td align="left">
422                                         <input type="text" id="term" value="javascript"/>
423                                         <input type="submit" value="Go!"/>
424                                 </td>
425                                 <td>Hits per Source: </td>
426                                 <td>
427                                         <select onchange="current_count=this.options[this.selectedIndex].value;">
428                                                 <option value="5" selected>5</option>
429                                                 <option value="10">10</option>
430                                                 <option value="25">25</option>
431                                         </select>
432                                 </td>
433                         </tr>
434                         <tr valign="top">
435                                 <td colspan=4>Sources:  
436                                         <input name="source" type="checkbox" value="http://gapines.org/opensearch.xml" checked>GPLS Pines
437                                         <input name="source" type="checkbox" value="http://rsinger.library.gatech.edu/opensearch/osdd-gil.xml" checked>GIL Universal Catalog
438                                         <input name="source" type="checkbox" value="http://search.athenscounty.lib.oh.us/cgi-bin/koha/opensearchdescription">NPL/Koha
439                                         <input name="source" type="checkbox" value="http://www.webdevref.com/blog/opensearchdescription.xml">WebDefRef
440                                 </td>
441                         </tr>
442                 </table>
443                 </form>
444
445                 <div>Total results: <span id="total"/></div>
446                 <div>Current page: <span id="page_label"></span> -- 
447                         <button class='hide' id='prev_button' onclick="if (this.className != 'hide') {current_startPage -= 1; opensearch(document.getElementById('term').value);}">Previous Page</button>
448                         ...
449                         <button class='hide' id='next_button' onclick="if (this.className != 'hide') {current_startPage += 1; opensearch(document.getElementById('term').value);}">Next Page</button>
450                 </div>
451                 <hr/>
452                 <br/>
453                 <table id="results">
454                         <tr>
455                                 <td id="int_res_hide" class="noshow">
456                                         <table>
457                                                 <caption>Merged search results</caption>
458                                                 <tr>
459                                                         <td>
460                                                                 <table id='int_res' class="res_table"></table>
461                                                         </td>
462                                                 </tr>
463                                         </table>
464                                 </td>
465                                 <td id='col_res_hide' class="noshow">
466                                         <table>
467                                                 <caption>Unranked search results</caption>
468                                                 <tr>
469                                                         <td>
470                                                                 <table id='col_res' class="res_table"></table>
471                                                         </td>
472                                                 </tr>
473                                         </table>
474                                 </td>
475                         </tr>
476                 </table>
477                 <div id="result_sources"></div>
478                 <br/>
479         </body>
480 </html>