]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/extras/opensearchportal.html
UI fix
[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         font-size: small;
9 }
10
11 #result_sources a {
12         font-size: 8px;
13         color: grey;
14         text-decoration: none;
15 }
16
17 td {
18         vertical-align: top;
19 }
20
21 caption {
22         border: solid black 1px;
23 }
24
25 .header {
26         border: solid lightblue 1px;
27         background-color: lightblue;
28 }
29
30 a {
31         color: blue;
32         text-decoration: none;
33 }
34
35 a:hover {
36         color: blue;
37         text-decoration: underline;
38 }
39
40 a:active {
41         color: red;
42         text-decoration: underline;
43 }
44
45 a:visited {
46         color: blue;
47         text-decoration: none;
48 }
49
50 .title_link {
51         font-size: medium;
52         font-weight: bold;
53 }
54
55 .desc_text {
56         font-size: small;
57 }
58
59 .hide {
60         color: lightgray;
61 }
62
63 .col_tab {
64         border-collapse: collapse;
65         border: solid gray 1px;
66 }
67
68 .res_table {
69         border-collapse: collapse;
70 }
71
72 #col_res {
73         max-width: 300px !important;
74         min-width: 200px !important;
75 }
76
77 #int_res {
78         max-width: 100% !important;
79 }
80
81 #int_res_hide {
82         max-width: 100% !important;
83         min-width: 400px !important;
84 }
85
86 .res_tr {
87         border-bottom: 1px dashed darkgrey;
88 }
89
90 .noshow {
91         display: none;
92         visibility: hidden;
93 }
94
95                 </style>
96                 <script>
97
98 var isIE = false;
99
100 function create_requestor () {
101         var req;
102         try { 
103                 req = new ActiveXObject("Msxml2.XMLHTTP");
104                 isIE = true;
105         } catch (e) {
106                 try { 
107                         req = new ActiveXObject("Microsoft.XMLHTTP");
108                         isIE = true;
109                 } catch (E) {
110                         req = false;
111                 }
112         }
113
114         if (!req && typeof XMLHttpRequest!='undefined') {
115                 req = new XMLHttpRequest();
116         }
117         
118         if(!req) {
119                 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
120                 return null;
121         }
122
123         return req;
124 }
125
126 var proxy = 'http://gapines.org/opensearch/?fetch=';
127
128 var insearch=false;
129
130 var images = [];
131 var search_templates = [];
132 var search_urls = {};
133 var rel_scales = {};
134
135 var current_startPage = 1;
136 var current_startIndex = 1;
137 var current_count = 5;
138
139 function opensearch ( term, reset, single_source ) {
140
141         if (reset) {
142                 current_startPage = 1;
143                 rel_scales = {};
144         }
145
146         if (single_source) {
147
148                 create_search(single_source);
149                 var turi = search_templates[single_source].replace(/\{searchTerms\}/,encodeURIComponent(term));
150                 turi = turi.replace(/\{startPage\}/,current_startPage);
151                 turi = turi.replace(/\{startIndex\}/,current_startIndex);
152                 turi = turi.replace(/\{count\}/,current_count);
153                 turi = turi.replace(/\{relevanceScale}/,'0');
154                 search_urls[single_source] = proxy + encodeURIComponent(turi);
155
156                 rel_scales
157                 var cur_src = document.getElementById('result_sources');
158                 for (var i = 1; i < cur_src.childNodes.length; i++) {
159                         if (cur_src.childNodes[i].textContent == turi)
160                                 return;
161                 }
162                 cur_src.innerHTML += '<a name="' + single_source + '" href="' + turi + '">' + turi + '</a><br>';
163                 perform_search(single_source);
164                 return;
165         }
166
167         document.getElementById('next_button').className = 'hide';
168
169         if (current_startPage == 1)
170                 document.getElementById('prev_button').className = 'hide';
171         else 
172                 document.getElementById('prev_button').className = '';
173
174         var tot = document.getElementById('total');
175         while (tot.lastChild)
176                         tot.removeChild(tot.lastChild);
177
178         var src = document.getElementById('result_sources');
179         while (src.lastChild)
180                         src.removeChild(src.lastChild);
181
182         document.getElementById('int_res_hide').className = 'noshow';
183         document.getElementById('col_res_hide').className = 'noshow';
184
185         var tab = document.getElementById('int_res');
186         while (tab.lastChild)
187                         tab.removeChild(tab.lastChild);
188
189         tab = document.getElementById('col_res');
190         while (tab.lastChild)
191                         tab.removeChild(tab.lastChild);
192
193         search_count = 0;
194
195         var sources = new Array();
196         var selector = document.getElementsByName('source');
197         for (var i = 0; i < selector.length; i++) {
198                 if (selector[i].checked) {
199                         sources.push(selector[i].value);
200                 }
201         }
202
203         search_templates = [];
204         for (var i in sources) {
205                 create_search( sources[i] );
206         }
207
208         current_startIndex = (current_count * (current_startPage - 1)) + 1; 
209
210         search_urls = [];
211         for (var i in search_templates) {
212                 if (!search_templates[i])
213                         continue;
214
215                 if (!rel_scales[i])
216                         rel_scales[i] = 0;
217
218                 var url = search_templates[i].replace(/\{searchTerms\}/,encodeURIComponent(term));
219                 url = url.replace(/\{startPage\}/,current_startPage);
220                 url = url.replace(/\{startIndex\}/,current_startIndex);
221                 url = url.replace(/\{count\}/,current_count);
222                 url = url.replace(/\{relevanceScale}/,rel_scales[i]);
223                 search_urls[i] = proxy + encodeURIComponent(url);
224
225                 src.innerHTML += '<a name="' + i + '" href="' + url + '">' + url + '</a><br>';
226         }
227
228         for (var i in search_urls) {
229                 if (!search_templates[i])
230                         continue;
231
232                 perform_search(i);
233         }
234
235         document.getElementById('page_label').innerHTML = current_startPage;
236 }
237
238 function perform_search ( source ) {
239         var req = create_requestor();
240
241         req.onreadystatechange = function () {
242                 if (req.readyState != 4)
243                         return;
244
245                 var xml = req.responseXML;
246
247                 var desc  = getElementTextNS('','description',xml,0);
248                 var xml_link  = getElementTextNS('','link',xml,0);
249
250                 var total  = getElementFloatNS('openSearch','totalResults',xml,0);
251                 var integratible = (getElementNS('openIll','relevance',xml,0) != null);
252                 var scale = getElementFloatNS('openIll','relevanceScale',xml,0);
253
254                 rel_scales[source]  = scale;
255                 
256                 var tot = document.getElementById('total');
257                 var current_tot = parseFloat(tot.textContent);
258                 var res_type = document.getElementById('res_type');
259
260                 if (res_type.options[res_type.selectedIndex].value == 'col')
261                         integratible = 0;
262
263                 if (!current_tot)
264                         current_tot = 0;
265
266                 if (total > (current_startPage * current_count))
267                         document.getElementById('next_button').className = '';
268
269                 current_tot += total
270                 tot.innerHTML = current_tot;
271
272                 var list = xml.getElementsByTagName('item');
273                 for (var i = 0; i < list.length; i++) {
274
275                         if ( typeof list[i] != 'object')
276                                         continue;
277
278                         var tab;
279                         if (!integratible) {
280                                 tab = document.getElementById('col_res');
281                                 document.getElementById('col_res_hide').className = '';
282                                 var col = document.getElementById(source);
283                                 if (!col) {
284                                         var row = tab.rows[0];
285                                         if (!row)
286                                                 row = tab.insertRow(0);
287
288                                         col = document.createElement('td');
289                                         col.setAttribute('id',source);
290                                         col.setAttribute('name',source);
291                                         row.appendChild(col);
292
293                                         tab = document.createElement('table');
294                                         tab.setAttribute('valign','top');
295                                         tab.setAttribute('class','col_tab');
296
297                                         var cap = document.createElement('caption');
298                                         tab.appendChild(cap);
299                                         cap.innerHTML = desc + ' -- <a href="' + xml_link + '">XML</a>';
300
301                                         col.appendChild(tab);
302
303                                         var per = parseInt(100 / (search_urls.length * 2)) - 1;
304                                         col.setAttribute('valign','top');
305                                         col.setAttribute('width', + per + '%');
306
307                                 } else {
308                                         tab = col.firstChild;
309                                 }
310                         } else {
311                                 tab = document.getElementById('int_res');
312                                 document.getElementById('int_res_hide').className = '';
313                         }
314
315                         if (!tab.rows.length) {
316                                 add_result_row(tab, 0, list[i], source);
317                         } else {
318                                 for (var j = 0; j < tab.rows.length; j++) {
319                                         if ( typeof tab.rows[j] != 'object')
320                                                 continue;
321
322                                         var rank;
323                                         try {
324                                                 rank = getElementFloatNS('openIll','relevance',list[i],0);
325                                         } catch (e) {
326                                                 alert("error getting float relevance: " + e);
327                                                 rank = 0;
328                                         }
329
330                                         if ( rank < parseFloat(tab.rows[j].firstChild.firstChild.textContent) ) {
331                                                 if ( (j + 1) == tab.rows.length) {
332                                                         add_result_row(tab, tab.rows.length, list[i], source);
333                                                         break
334                                                 }
335                                                 continue;
336                                         }
337                                         add_result_row(tab, j, list[i], source);
338                                         break;
339                                 }
340                         }
341                 }
342         };
343
344         req.open('GET', proxy + encodeURIComponent(search_urls[source]), true);
345         req.send(null);
346 }
347
348
349 // retrieve float of an XML document element, including
350 // elements using namespaces
351 function getElementFloatNS(prefix, local, parentElem, index) {
352     var result = getElementNS(prefix, local, parentElem, index);
353     if (result) {
354         // get text, accounting for possible
355         // whitespace (carriage return) text nodes 
356         if (result.childNodes.length > 1) {
357             return parseFloat(result.childNodes[1].nodeValue);
358         } else {
359             return parseFloat(result.textContent);              
360         }
361     } else {
362         return 0;
363     }
364 }
365
366 function getElementNS(prefix, local, parentElem, index) {
367     var result = "";
368     if (prefix && isIE) {
369         // IE/Windows way of handling namespaces
370         return parentElem.getElementsByTagName(prefix + ":" + local)[index];
371     } else {
372         // the namespace versions of this method 
373         // (getElementsByTagNameNS()) operate
374         // differently in Safari and Mozilla, but both
375         // return value with just local name, provided 
376         // there aren't conflicts with non-namespace element
377         // names
378         return parentElem.getElementsByTagName(local)[index];
379     }
380 }
381
382 // retrieve text of an XML document element, including
383 // elements using namespaces
384 function getElementTextNS(prefix, local, parentElem, index) {
385     var result = getElementNS(prefix, local, parentElem, index);
386     if (result) {
387         // get text, accounting for possible
388         // whitespace (carriage return) text nodes 
389         if (result.childNodes.length > 1) {
390             return result.childNodes[1].nodeValue;
391         } else {
392             return result.firstChild.nodeValue;                 
393         }
394     } else {
395         return '';
396     }
397 }
398
399 function add_result_row (tab, index, xml, source) {
400         var img = images[source];
401         var rank,title,tlink,desc;
402
403         try {
404                 rank = getElementFloatNS('openIll','relevance',xml,0);
405         } catch (e) {
406                 alert("error getting relevance: " + e);
407                 rank = '0';
408         }
409         
410         try {
411                 title = getElementTextNS('','title',xml,0);
412         } catch (e) {
413                 title = '';
414         }
415         
416         try {
417                 tlink = getElementTextNS('','link',xml,0);
418         } catch (e) {
419                 tlink = '';
420         }
421
422         try {
423                 description = getElementTextNS('','description',xml,0);
424         } catch (e) {
425                 description = '';
426         }
427
428         var row = tab.insertRow(index);
429         row.setAttribute('name',source);
430         row.className = 'res_tr';
431         row.innerHTML = '<td style="padding: 4px"><div style="display: none; visibility: hidden;">' + rank +
432                                                  '</div><span class="title_link"><a href="' + tlink + '">' + title +
433                                                  '</a></span><br/><span class="desc_text">' + description + '</span></td>' +
434                                                  '<td><img title="' + parseInt(rank) + '% Relevant" width="32" height="32" src="' + img + '"></td>';
435 }
436
437 function create_search ( s ) {
438         var req = create_requestor();
439
440         req.open('GET',proxy +  encodeURIComponent(s),false);
441         req.send(null);
442
443         try {
444                 var xml = req.responseXML;
445                 search_templates[s] = xml.getElementsByTagName('Url')[0].textContent;
446                 var i =  xml.getElementsByTagName('Image');
447                 if (i.length)
448                         images[s] = i[0].textContent;
449                 return search_templates[s];
450         } catch (e) {
451                 alert('BAD XML!\n\n' + e + '\n\n' + req.responseText);
452                 search_templates[s] = null;
453                 images[s] = null;
454         }
455
456 }
457
458 function remove_by_name( src ) {
459         var list = document.getElementsByName(src);
460
461         var len = list.length;
462
463         while (list.length)
464                 list[0].parentNode.removeChild(list[0]);
465 }
466
467                 </script>
468         </head>
469         <body>
470                 <br/>
471                 <form>
472                 <table style="border-collapse: collapse; margin: 5px;" width="100%">
473                         <tr style="border-bottom: dotted black 1px;" valign="top">
474                                 <td align="right">Keyword Search: </td>
475                                 <td align="left">
476                                         <input type="text" id="term" value="javascript"/>
477                                         <input type="submit" value="Go!" onclick="insearch=true; opensearch(document.getElementById('term').value, true); return false;"/>
478                                 </td>
479                                 <td align="left">Hits per Source for each page: 
480                                         <select onchange="current_count=this.options[this.selectedIndex].value;">
481                                                 <option value="5" selected>5</option>
482                                                 <option value="10">10</option>
483                                                 <option value="25">25</option>
484                                         </select>
485                                 </td>
486                                 <td align="left">Display style: 
487                                         <select id="res_type">
488                                                 <option value="int" selected>Merged Results</option>
489                                                 <option value="col">Separate Columns</option>
490                                         </select>
491                                 </td>
492                         </tr>
493                         <tr style="border-bottom: dotted black 1px;" valign="top">
494                                 <td align="right">Sources: </td>
495                                 <td colspan=3>
496                                         <table width="100%" style="border-collapse: collapse;">
497                                                 <tr>
498                                                         <td>
499                                                                 <label class="source_input">
500                                                                         <input
501                                                                                 onclick="
502                                                                                         if(insearch) {
503                                                                                                 if(this.checked) {
504                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
505                                                                                                 } else {
506                                                                                                         remove_by_name(this.value);
507                                                                                                 }
508                                                                                         }"
509                                                                                 name="source"
510                                                                                 type="checkbox"
511                                                                                 value="http://gapines.org/opensearch.xml"
512                                                                                 checked>GPLS Pines
513                                                                 </label>
514                                                         </td>
515                                                         <td>
516                                                                 <label class="source_input">
517                                                                         <input
518                                                                                 onclick="
519                                                                                         if(insearch) {
520                                                                                                 if(this.checked) {
521                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
522                                                                                                 } else {
523                                                                                                         remove_by_name(this.value);
524                                                                                                 }
525                                                                                         }"
526                                                                                 name="source"
527                                                                                 type="checkbox"
528                                                                                 value="http://rsinger.library.gatech.edu/opensearch/osdd-gil.xml"
529                                                                                 checked>GIL Universal Catalog
530                                                                 </label>
531                                                         </td>
532                                                         <td>
533                                                                 <label class="source_input">
534                                                                         <input
535                                                                                 onclick="
536                                                                                         if(insearch) {
537                                                                                                 if(this.checked) {
538                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
539                                                                                                 } else {
540                                                                                                         remove_by_name(this.value);
541                                                                                                 }
542                                                                                         }"
543                                                                                 name="source"
544                                                                                 type="checkbox"
545                                                                                 value="http://search.athenscounty.lib.oh.us/cgi-bin/koha/opensearchdescription">NPL/Koha
546                                                                 </label>
547                                                         </td>
548                                                         <td>
549                                                                 <label class="source_input">
550                                                                         <input
551                                                                                 onclick="
552                                                                                         if(insearch) {
553                                                                                                 if(this.checked) {
554                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
555                                                                                                 } else {
556                                                                                                         remove_by_name(this.value);
557                                                                                                 }
558                                                                                         }"
559                                                                                 name="source"
560                                                                                 type="checkbox"
561                                                                                 value="http://www.koders.com/search/KodersSourceCodeSearchDescription.xml">Koders Source Code
562                                                                 </label>
563                                                         </td>
564                                                         <td>
565                                                 </tr>
566                                                 <tr>
567                                                         <td>
568                                                                 <label class="source_input">
569                                                                         <input
570                                                                                 onclick="
571                                                                                         if(insearch) {
572                                                                                                 if(this.checked) {
573                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
574                                                                                                 } else {
575                                                                                                         remove_by_name(this.value);
576                                                                                                 }
577                                                                                         }"
578                                                                                 name="source"
579                                                                                 type="checkbox"
580                                                                                 value="http://cnx.rice.edu/content/opensearchdescription">rice.edu Connexions
581                                                                 </label>
582                                                         </td>
583                                                         <td>
584                                                                 <label class="source_input">
585                                                                         <input
586                                                                                 onclick="
587                                                                                         if(insearch) {
588                                                                                                 if(this.checked) {
589                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
590                                                                                                 } else {
591                                                                                                         remove_by_name(this.value);
592                                                                                                 }
593                                                                                         }"
594                                                                                 name="source"
595                                                                                 type="checkbox"
596                                                                                 value="http://redlightgreen.com/ucwprod/web/opensearchDescription.xml">RedLightGreen
597                                                                 </label>
598                                                         </td>
599                                                         <td>
600                                                                 <label class="source_input">
601                                                                         <input
602                                                                                 onclick="
603                                                                                         if(insearch) {
604                                                                                                 if(this.checked) {
605                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
606                                                                                                 } else {
607                                                                                                         remove_by_name(this.value);
608                                                                                                 }
609                                                                                         }"
610                                                                                 name="source"
611                                                                                 type="checkbox"
612                                                                                 value="http://www.itpapers.com/itpaperssearchdescription.xml">ITPapers
613                                                                 </label>
614                                                         </td>
615                                                         <td>
616                                                                 <label class="source_input">
617                                                                         <input
618                                                                                 onclick="
619                                                                                         if(insearch) {
620                                                                                                 if(this.checked) {
621                                                                                                         opensearch(document.getElementById('term').value, false, this.value);
622                                                                                                 } else {
623                                                                                                         remove_by_name(this.value);
624                                                                                                 }
625                                                                                         }"
626                                                                                 name="source"
627                                                                                 type="checkbox"
628                                                                                 value="http://lib-cufts.lib.sfu.ca/CUFTS/opensearchjournal.xml">SFU CUFTS
629                                                                 </label>
630                                                         </td>
631                                         <!-- <input name="source" type="checkbox" value="http://www.webdevref.com/blog/opensearchdescription.xml">WebDefRef -->
632                                                 </tr>
633                                         </table>
634                                 </td>
635                         </tr>
636                         <tr>
637                                 <td>Total results: </td>
638                                 <td colspan=2 id="total"></td>
639                         </tr>
640                         <tr>
641                                 <td>Current page: </td>
642                                 <td id="page_label"></td>
643                                 <td>
644                                         <button
645                                                 class='hide'
646                                                 id='prev_button'
647                                                 onclick="
648                                                         if (this.className != 'hide') {
649                                                                 current_startPage -= 1;
650                                                                 opensearch(document.getElementById('term').value);
651                                                         }
652                                                         return false;">Previous Page
653                                         </button> ...
654                                         <button
655                                                 class='hide'
656                                                 id='next_button'
657                                                 onclick="
658                                                         if (this.className != 'hide') {
659                                                                 current_startPage += 1;
660                                                                 opensearch(document.getElementById('term').value);
661                                                         }
662                                                         return false;">Next Page
663                                         </button>
664                                 </td>
665                         </tr>
666                 </table>
667                 </form>
668
669                 <hr/>
670                 <br/>
671                 <table id="results" width="100%">
672                         <tr>
673                                 <td id="int_res_hide" class="noshow" width="100%">
674                                         <table width="100%">
675                                                 <caption class="header">Merged search results</caption>
676                                                 <tr>
677                                                         <td width="100%">
678                                                                 <table id='int_res' class="res_table" width="100%"></table>
679                                                         </td>
680                                                 </tr>
681                                         </table>
682                                 </td>
683                                 <td id='col_res_hide' class="noshow">
684                                         <table>
685                                                 <caption class="header">Unranked search results</caption>
686                                                 <tr>
687                                                         <td>
688                                                                 <table id='col_res' class="res_table"></table>
689                                                         </td>
690                                                 </tr>
691                                         </table>
692                                 </td>
693                         </tr>
694                 </table>
695                 <div id="result_sources"></div>
696                 <br/>
697         </body>
698 </html>