1 dump('entering addon/pv_supa.js\n');
7 JSAN.use('addon.pv_supa_goodstuff');
8 var goodstuff = new addon.pv_supa_goodstuff();
11 alert('Received: ' + data);
15 goodstuff.request_items();
18 if (typeof addon == 'undefined') addon = {};
19 addon.pv_supa_goodstuff = function (params) {
22 dump('addon: pv_supa_goodstuff() constructor\n');
24 const Cc = Components.classes;
25 const Ci = Components.interfaces;
26 const prefs_Cc = '@mozilla.org/preferences-service;1';
27 this.prefs = Cc[prefs_Cc].getService(Ci['nsIPrefBranch']);
29 JSAN.use('OpenILS.data');
30 this.data = new OpenILS.data();
31 this.data.stash_retrieve();
33 JSAN.use('util.error');
34 this.error = new util.error();
37 if (this.prefs.prefHasUserValue('oils.addon.pvsupa.goodstuff.enabled')){
38 this.active = this.prefs.getBoolPref(
39 'oils.addon.pvsupa.goodstuff.enabled'
43 dump('addon: pv_supa goodstuff enabled by preference\n');
45 dump('addon: pv_supa goodstuff not enabled by preference\n');
49 if (g.checkin && this.active) {
50 this.common_ui_init();
58 if (g.checkout && this.active) {
59 this.common_ui_init();
67 if (String(location.href).match('/patron/barcode_entry.xul') && this.active) {
68 this.common_ui_init();
72 obj.patron_for_checkout_init();
77 this.common_ui_init();
84 dump('addon: Error in pv_supa_goodstuff(): ' + E + '\n');
88 addon.pv_supa_goodstuff.prototype = {
89 'common_ui_init' : function() {
90 dump('addon: pv_supa common_ui_init\n');
93 var mc = document.createElement('messagecatalog');
94 mc.setAttribute('id','addon_pvsupa_goodstuff_strings');
97 '/xul/server/locale/'+LOCALE+'/addon/pv_supa_goodstuff.properties'
99 var mc_parent = $('offlineStrings')
100 ? $('offlineStrings').parentNode
101 : document.getElementsByTagName('window').item(0)
102 || document.getElementsByTagName('html').item(0);
103 mc_parent.appendChild(mc);
105 // We don't really need CSS here, but as an example:
106 var sss = Cc['@mozilla.org/content/style-sheet-service;1']
107 .getService(Ci.nsIStyleSheetService);
108 var ios = Cc['@mozilla.org/network/io-service;1']
109 .getService(Ci.nsIIOService);
110 var uri = ios.newURI(
111 'oils://remote/xul/server/skin/addon/pv_supa_goodstuff.css',
115 if(!sss.sheetRegistered(uri, sss.USER_SHEET)) {
116 sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
119 dump('addon: pv_supa Error in common_ui_init(): ' + E + '\n');
123 'socket_init' : function() {
124 dump('addon: pv_supa socket_init on page ' + location.href + '\n');
127 if (! this.data.addon) {
128 this.data.addon = {};
130 if (! this.data.addon.pv_supa) {
131 this.data.addon.pv_supa = {};
133 if (! this.data.addon.pv_supa.goodstuff) {
134 this.data.addon.pv_supa.goodstuff = {};
136 if (! this.data.addon.pv_supa.goodstuff.message_log) {
137 this.data.addon.pv_supa.goodstuff.message_log = [];
139 if (this.data.addon.pv_supa.goodstuff.socket) {
140 // don't know if we want to keep and re-use sockets
141 // Previously I was test .socket.isAlive() and only
142 // recreating if false
143 dump('addon: pv_supa goodstuff destroying old socket\n');
144 this.data.addon.pv_supa.goodstuff.socket.close();
145 this.data.addon.pv_supa.goodstuff.socket = null;
147 if (! this.data.addon.pv_supa.goodstuff.socket) {
148 JSAN.use('util.socket');
149 this.data.addon.pv_supa.goodstuff.socket = new util.socket(
151 this.prefs.prefHasUserValue('oils.addon.pvsupa.goodstuff.host')
152 ? this.prefs.getCharPref('oils.addon.pvsupa.goodstuff.host')
155 this.prefs.prefHasUserValue('oils.addon.pvsupa.goodstuff.port')
156 ? this.prefs.getIntPref('oils.addon.pvsupa.goodstuff.port')
157 : 5000 /* FIXME find out actual default port */
159 this.data.addon.pv_supa.goodstuff.socket.onStopRequest(
160 function(request,context,result) {
161 dump('addon: pv_supa goodstuff lost connection on page ' + location.href + '\n');
162 obj.updateStatusBar('!lost connection\n');
163 obj.data.addon.pv_supa.goodstuff.last_start_end_msg = null;
166 dump('addon: pv_supa goodstuff socket opened\n');
167 this.updateStatusBar('!new connection\n');
168 obj.data.addon.pv_supa.goodstuff.last_start_end_msg = null;
170 dump('addon: pv_supa goodstuff socket already opened\n');
172 this.socket = this.data.addon.pv_supa.goodstuff.socket;
173 this.token = location.href + ' : ' + new Date();
174 this.data.addon.pv_supa.goodstuff.token = this.token;
179 'addon: pv_supa goodstuff socket\n\t' +
180 'host: ' + obj.socket.host + '\n\t' +
181 'port: ' + obj.socket.port + '\n\t' +
189 dump('addon: pv_supa Error in socket_init(): ' + E + '\n');
192 'updateStatusBar' : function(d) {
195 if (xulG && xulG.set_statusbar) {
196 if (obj.data.addon.pv_supa.goodstuff.message_log.length > 16) {
197 obj.data.addon.pv_supa.goodstuff.message_log.shift();
199 obj.data.addon.pv_supa.goodstuff.message_log.push(d);
203 obj.data.addon.pv_supa.goodstuff.message_log.join(""),
206 obj.data.addon.pv_supa.goodstuff.message_log.join("")
212 dump('addon: pv_supa Error in updateStatusBar('+d+'): ' + E + '\n');
215 'onData' : function(f,security) {
216 dump('addon: setting pv_supa goodstuff onData callback, on page '
217 + location.href + ' with token ' + this.token + '\n');
219 this.socket.dataCallback(
222 dump('addon: dataCallback func at page '
223 + location.href + ' with token ' + obj.token + '\n');
224 obj.updateStatusBar('>' + d);
225 if (obj.token != obj.data.addon.pv_supa.goodstuff.token) {
226 var e = 'addon error: pv supa: reading data out of turn\n';
228 obj.updateStatusBar('!' + e);
230 d= d.replace("\n","","g").replace("\r","","g").replace(" ","","g");
231 var p = d.split("|");
234 f(p[0]); // hopefully a patron barcode
236 } else if (p[0] == 'START') {
237 obj.data.addon.pv_supa.goodstuff.last_start_end_msg = p[0];
238 } else if (p[0] == 'END') {
239 obj.data.addon.pv_supa.goodstuff.last_start_end_msg = p[0];
240 } else if (p[1] == 'NOK') {
242 var msg = $('addon_pvsupa_goodstuff_strings').getFormattedString(
243 security == 'ACTIVATE'
244 ? 'rfid.set_security_failure.prompt.message.activate_failure'
245 : 'rfid.set_security_failure.prompt.message.deactivate_failure',
248 var choice = obj.error.yns_alert(
250 $('addon_pvsupa_goodstuff_strings').getString(
251 'rfid.set_security_failure.prompt.title'
253 $('addon_pvsupa_goodstuff_strings').getString(
254 'rfid.set_security_failure.prompt.button.activate_security'
256 $('addon_pvsupa_goodstuff_strings').getString(
257 'rfid.set_security_failure.prompt.button.deactivate_security'
259 $('addon_pvsupa_goodstuff_strings').getString(
260 'rfid.set_security_failure.prompt.button.do_nothing_with_security'
265 obj.write(p[0]+'|ACTIVATE\n');
266 } else if (choice == 1) {
267 obj.write(p[0]+'|DEACTIVATE\n');
269 obj.write(p[0]+'\n');
272 dump('addon: unknown error\n');
274 } else if (p[1] == 'OK') {
276 } else if (p[1].match('/')) {
277 var counts = p[1].split('/');
278 var read = counts[0];
281 var msg = $('addon_pvsupa_goodstuff_strings').getFormattedString(
282 'rfid.partial_scan.prompt.message',
285 var choice = obj.error.yns_alert(
287 $('addon_pvsupa_goodstuff_strings').getString(
288 'rfid.partial_scan.prompt.title'
290 $('addon_pvsupa_goodstuff_strings').getString(
291 'rfid.partial_scan.prompt.button.rescan'
293 $('addon_pvsupa_goodstuff_strings').getString(
294 'rfid.partial_scan.prompt.button.skip'
296 $('addon_pvsupa_goodstuff_strings').getString(
297 'rfid.partial_scan.prompt.button.proceed'
301 if (!choice || choice == 0) {
302 obj.write(p[0]+'|REREAD\n');
303 } else if (choice == 1) {
304 obj.write(p[0]+'\n'); // do nothing, skip
305 } else if (choice == 2) {
307 f(p[0]); // hopefully an item barcode
312 f(p[0]); // hopefully an item barcode
317 f(p[0]); // no idea; shouldn't get here
321 dump('addon: error in onData callback: ' + E + '\n');
326 'write' : function(s,ignore_token) {
327 dump('addon: write "' + s + '", on page ' + location.href + ' with token ' + this.token + '\n');
328 if ((this.token != this.data.addon.pv_supa.goodstuff.token) && !ignore_token) {
329 var e = 'addon error: pv supa: sending data out of turn\n';
331 this.updateStatusBar('!' + e);
333 if (!this.socket.socket.isAlive()) {
334 dump('addon error: pv supa: writing to not alive socket\n');
336 this.updateStatusBar('<' + s);
337 this.socket.write(s);
339 'request_items' : function() {
340 dump('addon: request_items on page ' + location.href + '\n');
341 if (this.data.addon.pv_supa.goodstuff.last_start_end_msg == 'START') {
344 this.write('START|ITEM\n'); // we expect START|OK
346 'request_patrons' : function() {
347 dump('addon: request_patrons on page ' + location.href + '\n');
348 if (this.data.addon.pv_supa.goodstuff.last_start_end_msg == 'START') {
351 this.write('START|PATRON\n'); // we expect START|OK
353 'end_session' : function() {
354 dump('addon: end_session on page ' + location.href + '\n');
355 if (this.token == this.data.addon.pv_supa.goodstuff.token) {
356 if (this.data.addon.pv_supa.goodstuff.last_start_end_msg == 'START') {
359 this.data.addon.pv_supa.goodstuff.socket.close();
360 this.data.addon.pv_supa.goodstuff.socket = null;
364 'prefs_init' : function() {
365 dump('addon: pv_supa prefs_init\n');
369 if (! (g && g.addons_ui)) { return; }
371 const Cc = Components.classes;
372 const Ci = Components.interfaces;
374 function post_overlay() {
375 var tab = $('pv_supa_goodstuff_tab');
378 $('addon_pvsupa_goodstuff_strings').getString('prefs.tab.label')
382 $('addon_pvsupa_goodstuff_strings').getString('prefs.tab.accesskey')
385 var enabled_label = $('pv_supa_goodstuff_enabled_label');
386 enabled_label.setAttribute(
388 $('addon_pvsupa_goodstuff_strings').getString('prefs.checkbox.label')
390 enabled_label.setAttribute(
392 $('addon_pvsupa_goodstuff_strings').getString('prefs.checkbox.accesskey')
395 var host_label = $('pv_supa_goodstuff_hostname_label');
396 host_label.setAttribute(
398 $('addon_pvsupa_goodstuff_strings').getString('prefs.host.label')
400 host_label.setAttribute(
402 $('addon_pvsupa_goodstuff_strings').getString('prefs.host.accesskey')
405 var port_label = $('pv_supa_goodstuff_port_label');
406 port_label.setAttribute(
408 $('addon_pvsupa_goodstuff_strings').getString('prefs.port.label')
410 port_label.setAttribute(
412 $('addon_pvsupa_goodstuff_strings').getString('prefs.port.accesskey')
415 var save_btn = $('pv_supa_goodstuff_save_btn');
416 save_btn.setAttribute(
418 $('addon_pvsupa_goodstuff_strings').getString('prefs.update.label')
420 save_btn.setAttribute(
422 $('addon_pvsupa_goodstuff_strings').getString('prefs.update.accesskey')
424 save_btn.addEventListener(
434 function myObserver() { this.register(); }
435 myObserver.prototype = {
436 register: function() {
437 var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
438 observerService.addObserver(this, "xul-overlay-merged", false);
440 unregister: function() {
441 var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
442 observerService.removeObserver(this, "xul-overlay-merged");
444 observe: function(subject,topic,data) {
445 dump('observe: <'+subject+','+topic+','+data+'>\n');
446 // setTimeout is needed here for xulrunner 1.8
447 setTimeout( function() { try { post_overlay(); } catch(E) { alert(E); } }, 0 );
451 var observer = new myObserver();
452 var url = '/xul/server/addon/pv_supa_goodstuff_config_overlay.xul';
453 document.loadOverlay(location.protocol + '//' + location.hostname + url,observer)
456 dump('addon: pv_supa Error in prefs_init(): ' + E + '\n');
460 'display_prefs' : function() {
463 $('pv_supa_goodstuff_enabled_cb').checked = obj.active;
464 $('pv_supa_goodstuff_hostname_tb').value =
465 obj.prefs.prefHasUserValue('oils.addon.pvsupa.goodstuff.host')
466 ? obj.prefs.getCharPref('oils.addon.pvsupa.goodstuff.host')
469 $('pv_supa_goodstuff_port_tb').value =
470 obj.prefs.prefHasUserValue('oils.addon.pvsupa.goodstuff.port')
471 ? obj.prefs.getIntPref('oils.addon.pvsupa.goodstuff.port')
472 : 5000; /* FIXME find out actual default port */
475 dump('addon: pv_supa Error in display_prefs(): ' + E + '\n');
479 'save_prefs' : function() {
482 obj.prefs.setBoolPref(
483 'oils.addon.pvsupa.goodstuff.enabled',
484 $('pv_supa_goodstuff_enabled_cb').checked
486 obj.prefs.setCharPref(
487 'oils.addon.pvsupa.goodstuff.host',
488 $('pv_supa_goodstuff_hostname_tb').value
490 obj.prefs.setIntPref(
491 'oils.addon.pvsupa.goodstuff.port',
492 $('pv_supa_goodstuff_port_tb').value
494 location.href = location.href;
496 dump('addon: pv_supa Error in save_prefs(): ' + E + '\n');
500 'checkin_init' : function() {
501 dump('addon: pv_supa checkin_init\n');
506 if (! (g && g.checkin)) { return; }
508 function setOnData() {
511 g.checkin.controller.view.checkin_barcode_entry_textbox.value = barcode;
513 // unlike checkout, I don't really care whether the checkin
514 // succeeds or not; I think we should activate security on
515 // the item and move on. Errored items are still listed in
516 // the interface and can be handled separately.
517 obj.write(barcode+'|ACTIVATE\n');
524 var spacer = $('pcii3s');
525 var rfid_cb = document.createElement('checkbox');
526 rfid_cb.setAttribute('id','addon_rfid_cb');
527 rfid_cb.setAttribute(
529 $('addon_pvsupa_goodstuff_strings').getString(
530 'rfid.checkbox.label'
533 rfid_cb.setAttribute(
535 $('addon_pvsupa_goodstuff_strings').getString(
536 'rfid.checkbox.accesskey'
539 spacer.parentNode.insertBefore(rfid_cb,spacer);
540 if (obj.prefs.prefHasUserValue(
541 'oils.addon.pvsupa.goodstuff.checkin.rfid_checkbox.checked'
543 rfid_cb.checked = obj.prefs.getBoolPref(
544 'oils.addon.pvsupa.goodstuff.checkin.rfid_checkbox.checked'
548 if (rfid_cb.checked) {
552 rfid_cb.addEventListener(
555 if (ev.target.checked) {
566 obj.prefs.setBoolPref(
567 'oils.addon.pvsupa.goodstuff.checkin.rfid_checkbox.checked',
573 window.addEventListener(
580 window.addEventListener(
584 if (rfid_cb.checked) {
597 dump('addon: pv_supa Error in checkin_init(): ' + E + '\n');
600 'checkout_init' : function() {
601 dump('addon: pv_supa checkout_init\n');
606 if (! (g && g.checkout)) { return; }
608 function setOnData() {
611 g.checkout.controller.view.checkout_barcode_entry_textbox.value = barcode;
612 var pre_list_count = g.checkout.list.row_count.total;
613 g.checkout.checkout({'barcode':barcode});
614 var post_list_count = g.checkout.list.row_count.total;
615 if (pre_list_count != post_list_count) {
616 obj.write(barcode+'|DEACTIVATE\n'); // checkout success
618 obj.write(barcode+'|ACTIVATE\n'); // checkout failure
626 var spacer = $('pcii3s');
627 var rfid_cb = document.createElement('checkbox');
628 rfid_cb.setAttribute('id','addon_rfid_cb');
629 rfid_cb.setAttribute(
631 $('addon_pvsupa_goodstuff_strings').getString(
632 'rfid.checkbox.label'
635 rfid_cb.setAttribute(
637 $('addon_pvsupa_goodstuff_strings').getString(
638 'rfid.checkbox.accesskey'
641 spacer.parentNode.insertBefore(rfid_cb,spacer);
642 if (obj.prefs.prefHasUserValue(
643 'oils.addon.pvsupa.goodstuff.checkout.rfid_checkbox.checked'
645 rfid_cb.checked = obj.prefs.getBoolPref(
646 'oils.addon.pvsupa.goodstuff.checkout.rfid_checkbox.checked'
650 if (rfid_cb.checked) {
654 rfid_cb.addEventListener(
657 if (ev.target.checked) {
668 obj.prefs.setBoolPref(
669 'oils.addon.pvsupa.goodstuff.checkout.rfid_checkbox.checked',
675 window.addEventListener(
682 window.addEventListener(
686 if (rfid_cb.checked) {
699 dump('addon: pv_supa Error in checkout_init(): ' + E + '\n');
702 'patron_for_checkout_init' : function() {
703 dump('addon: pv_supa patron_for_checkout_init\n');
708 if (! String(location.href).match('/patron/barcode_entry.xul')) { return; }
710 function setOnData() {
713 obj.write(barcode+'\n');
714 $('barcode_tb').value = barcode;
722 var hbox = $('barcode_tb').parentNode;
723 var rfid_cb = document.createElement('checkbox');
724 rfid_cb.setAttribute('id','addon_rfid_cb');
725 rfid_cb.setAttribute(
727 $('addon_pvsupa_goodstuff_strings').getString(
728 'rfid.checkbox.label'
731 rfid_cb.setAttribute(
733 $('addon_pvsupa_goodstuff_strings').getString(
734 'rfid.checkbox.accesskey'
737 hbox.appendChild(rfid_cb);
738 if (obj.prefs.prefHasUserValue(
739 'oils.addon.pvsupa.goodstuff.patron_for_checkout.rfid_checkbox.checked'
741 rfid_cb.checked = obj.prefs.getBoolPref(
742 'oils.addon.pvsupa.goodstuff.patron_for_checkout.rfid_checkbox.checked'
746 if (rfid_cb.checked) {
747 obj.request_patrons();
750 rfid_cb.addEventListener(
753 if (ev.target.checked) {
758 obj.request_patrons();
764 obj.prefs.setBoolPref(
765 'oils.addon.pvsupa.goodstuff.patron_for_checkout.rfid_checkbox.checked',
771 window.addEventListener(
778 window.addEventListener(
782 if (rfid_cb.checked) {
786 obj.request_patrons();
795 dump('addon: pv_supa Error in patron_for_checkout_init(): ' + E + '\n');