]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/util/browser.js
Improve Firefox/XULRunner Support
[Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / util / browser.js
1 dump('entering util.browser.js\n');
2
3 if (typeof util == 'undefined') util = {};
4 util.browser = function (params) {
5     try {
6         JSAN.use('util.error'); this.error = new util.error();
7     } catch(E) {
8         dump('util.browser: ' + E + '\n');
9     }
10 }
11
12 util.browser.prototype = {
13
14     'lock_reload' : false, // as opposed to lock 'n load :)
15
16     'back_button_clicked' : false,
17     'from_back' : false,
18
19     'init' : function( params ) {
20
21         try {
22             var obj = this;
23
24             obj.url = params['url'];
25             obj.push_xulG = params['push_xulG'];
26             obj.html_source = params['html_source'];
27             obj.browser_id = params['browser_id'];
28             obj.debug_label = params['debug_label'];
29             obj.passthru_content_params = params['passthru_content_params'];
30             obj.on_url_load = params['on_url_load'];
31             obj.printer_context = params['printer_context'] || 'default';
32
33             JSAN.use('util.controller'); obj.controller = new util.controller();
34             obj.controller.init(
35                 {
36                     control_map : {
37                         'cmd_broken' : [
38                             ['command'],
39                             function() { alert('Not Yet Implemented'); }
40                         ],
41                         'cmd_debug' : [
42                             ['command'],
43                             function() {
44                                 var curr_url = obj.get_content().location.href;
45                                 var url = window.prompt('Original URL: ' + obj.url + '\nCurrent URL: ' + curr_url + '\nEnter new URL:',curr_url);
46                                 if (url) { obj.get_content().location.href = url; }
47                             }
48                         ],
49                         'cmd_view_source' : [
50                             ['command'],
51                             function() {
52                                 var curr_url = obj.get_content().location.href;
53                                 //obj.get_content().location.href = 'view-source:' + curr_url; // This works too, but the openDialog below is more feature-rich
54                                 window.openDialog("chrome://global/content/viewSource.xul", "", "all,dialog=no", curr_url);
55                             }
56                         ],
57                         'cmd_print' : [
58                             ['command'],
59                             function() {
60                                 try {
61                                     var content = obj.get_content();
62                                     JSAN.use('util.print'); var p = new util.print(obj.printer_context);
63                                     var print_params = {};
64                                     if (obj.html_source) {
65                                         print_params.msg = obj.html_source;
66                                         print_params.content_type = 'text/html';
67                                     }
68                                     if (typeof content.printable_output == 'function') {
69                                         print_params.msg = content.printable_output();
70                                         print_params.content_type = 'text/plain';
71                                         content = print_params.msg;
72                                     }
73                                     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
74                                     // Override the print strategy temporarily if it's not set or is equal to webBrowserPrint (which is buggy here)
75                                     if (data.print_strategy) {
76                                         if (data.print_strategy[obj.printer_context] || data.print_strategy['default']) {
77                                             if (data.print_strategy[obj.printer_context]) {
78                                                 if (data.print_strategy[obj.printer_context] == 'webBrowserPrint') {
79                                                     print_params.print_strategy = 'window.print';
80                                                 }
81                                             } else {
82                                                 if (data.print_strategy['default'] == 'webBrowserPrint') {
83                                                     print_params.print_strategy = 'window.print';
84                                                 }
85                                             }
86                                         } else {
87                                             print_params.print_strategy = 'window.print';
88                                         }
89                                     } else {
90                                         print_params.print_strategy = 'window.print';
91                                     }
92                                     p.NSPrint(content,false,print_params);
93                                 } catch(E) {
94                                     alert('browser.js, cmd_print exception: ' + E);
95                                 }
96                             }
97                         ],
98                         'cmd_forward' : [
99                             ['command'],
100                             function() {
101                                 try {
102                                     var n = obj.getWebNavigation();
103                                     if (n.canGoForward) n.goForward();
104                                 } catch(E) {
105                                     var err = 'cmd_forward: ' + E;
106                                     obj.error.sdump('D_ERROR',err);
107                                 }
108                             }
109                         ],
110                         'cmd_back' : [
111                             ['command'],
112                             function() {
113                                 try {
114                                     var n = obj.getWebNavigation();
115                                     if (n.canGoBack) {
116                                         obj.back_button_clicked = true;
117                                         n.goBack();
118                                     }
119                                 } catch(E) {
120                                     var err = 'cmd_back: ' + E;
121                                     obj.error.sdump('D_ERROR',err);
122                                 }
123                             }
124                         ],
125                         'cmd_reload' : [
126                             ['command'],
127                             function() {
128                                 try {
129                                     obj.reload();
130                                 } catch(E) {
131                                     var err = 'cmd_reload: ' + E;
132                                     obj.error.sdump('D_ERROR',err);
133                                 }
134                             }
135                         ],
136                         'cmd_find' : [
137                             ['command'],
138                             function() {
139                                 var text = window.prompt('Enter text to find:');
140                                 obj.find(text);
141                             }
142                         ]
143                     }
144                 }
145             );
146             obj.controller.render();
147
148             var browser_id = 'browser_browser'; if (obj.browser_id) browser_id = obj.browser_id;
149             obj.controller.view.browser_browser = document.getElementById(browser_id);
150
151             obj.buildProgressListener();
152             /*
153             dump('obj.controller.view.browser_browser.addProgressListener = ' 
154                 + obj.controller.view.browser_browser.addProgressListener + '\n');
155             */
156             obj.controller.view.browser_browser.addProgressListener(obj.progressListener,
157                             Components.interfaces.nsIWebProgress.NOTIFY_ALL );
158
159             obj.controller.view.browser_browser.setAttribute('src',obj.url);
160             //dump('browser url = ' + obj.url + '\n');
161
162             window.help_context_set_locally = true;
163
164         } catch(E) {
165             this.error.sdump('D_ERROR','util.browser.init: ' + E + '\n');
166         }
167     },
168
169     'reload' : function() {
170         var obj = this;
171         if (obj.lock_reload) {
172             if (window.confirm( $('offlineStrings').getString('browser.reload.unsaved_data_warning') )) {
173                 obj.lock_reload = false;
174                 window.xulG.unlock_tab();
175             } else {
176                 return;
177             }
178         }
179         var n = obj.getWebNavigation();
180         n.reload( Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE );
181     },
182
183     'find' : function(text) {
184         var obj = this;
185         try {
186             function getBrowser() {
187                 return obj.controller.view.browser_browser;
188             }
189
190             function getFocusedSelCtrl() {
191                 var ds = getBrowser().docShell;
192                 var dsEnum = ds.getDocShellEnumerator(Components.interfaces.nsIDocShellTreeItem.typeContent,
193                                                     Components.interfaces.nsIDocShell.ENUMERATE_FORWARDS);
194                 while (dsEnum.hasMoreElements()) {
195                     ds = dsEnum.getNext().QueryInterface(Components.interfaces.nsIDocShell);
196                     if (ds.hasFocus) {
197                         var display = ds.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsISelectionDisplay);
198                         if (!display) return null;
199                         return display.QueryInterface(Components.interfaces.nsISelectionController);
200                     }
201                 }
202
203                 // One last try
204                 return getBrowser().docShell
205                     .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
206                     .getInterface(Components.interfaces.nsISelectionDisplay)
207                     .QueryInterface(Components.interfaces.nsISelectionController);
208             }
209
210             function setSelection(range) {
211                 try {
212                     var selctrlcomp = Components.interfaces.nsISelectionController;
213                     var selctrl = getFocusedSelCtrl();
214                     var sel = selctrl.getSelection(selctrlcomp.SELECTION_NORMAL);
215                     sel.removeAllRanges();
216                     sel.addRange(range.cloneRange());
217
218                     selctrl.scrollSelectionIntoView(selctrlcomp.SELECTION_NORMAL,
219                         selctrlcomp.SELECTION_FOCUS_REGION,
220                         true);
221                 } catch(e) {alert("setSelection: " + e);}
222             }
223
224             var doc = obj.get_content().document;
225             var body = doc.body;
226             var count = body.childNodes.length;
227             var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance()
228                 .QueryInterface(Components.interfaces.nsIFind);
229             var searchRange = doc.createRange();
230             var startPt = doc.createRange();
231             var endPt = doc.createRange();
232                 searchRange.setStart(body,0);
233                 searchRange.setEnd(body, count);
234                 startPt.setStart(body, 0);
235                 startPt.setEnd(body, 0);
236                 endPt.setStart(body, count);
237                 endPt.setEnd(body, count);
238             var retRange = finder.Find(text, searchRange, startPt, endPt);
239             dump('retRange = ' + retRange + '\n');
240             setSelection(retRange);
241         } catch(E) {
242             alert('Error in browser.js, find(): ' + E);
243         }
244     },
245
246     'get_content' : function() {
247         try {
248             if (this.controller.view.browser_browser.contentWindow.wrappedJSObject) {
249                 return this.controller.view.browser_browser.contentWindow.wrappedJSObject;
250             } else {
251                 return this.controller.view.browser_browser.contentWindow;
252             }
253         } catch(E) {
254             this.error.sdump('D_ERROR','util.browser.get_content(): ' + E);
255         }
256     },
257
258     'push_variables' : function() {
259         try {
260             var obj = this;
261             var s = '';
262             try { s += obj.url + '\n' + obj.get_content().location.href + '\n'; } catch(E) { s+=E + '\n'; }
263             if (!obj.push_xulG) return;
264             var cw = this.get_content();
265             cw.IAMXUL = true;
266             cw.XUL_BUILD_ID = '/xul/server/'.split(/\//)[2];
267             cw.xulG = obj.passthru_content_params || {};
268             cw.xulG.fromBack = obj.from_back;
269             if (!cw.xulG.set_tab) { cw.xulG.set_tab = function(a,b,c) { return window.xulG.set_tab(a,b,c); }; }
270             if (!cw.xulG.new_tab) { cw.xulG.new_tab = function(a,b,c) { return window.xulG.new_tab(a,b,c); }; }
271             if (!cw.xulG.close_tab) { cw.xulG.close_tab = function(a) { return window.xulG.close_tab(a); }; }
272             if (!cw.xulG.lock_tab) {
273                 cw.xulG.lock_tab = function() {
274                     obj.lock_reload = true;
275                     return window.xulG.lock_tab();
276                 };
277             }
278             if (!cw.xulG.unlock_tab) {
279                 cw.xulG.unlock_tab = function() {
280                     obj.lock_reload = false;
281                     return window.xulG.unlock_tab();
282                 };
283             }
284             if (!cw.xulG.inspect_tab) { cw.xulG.inspect_tab = function() { return window.xulG.inspect_tab(); }; }
285             if (!cw.xulG.is_tab_locked) { cw.xulG.is_tab_locked = function() { return window.xulG.is_tab_locked(); }; }
286             if (!cw.xulG.new_patron_tab) { cw.xulG.new_patron_tab = function(a,b) { return window.xulG.new_patron_tab(a,b); }; }
287             if (!cw.xulG.set_patron_tab) { cw.xulG.set_patron_tab = function(a,b) { return window.xulG.set_patron_tab(a,b); }; }
288             if (!cw.xulG.volume_item_creator) { cw.xulG.volume_item_creator = function(a) { return window.xulG.volume_item_creator(a); }; }
289             if (!cw.xulG.get_new_session) { cw.xulG.get_new_session = function(a) { return window.xulG.get_new_session(a); }; }
290             if (!cw.xulG.holdings_maintenance_tab) { cw.xulG.holdings_maintenance_tab = function(a,b,c) { return window.xulG.holdings_maintenance_tab(a,b,c); }; }
291             if (!cw.xulG.url_prefix) { cw.xulG.url_prefix = function(url,secure) { return window.xulG.url_prefix(url,secure); }; }
292             if (!cw.xulG.urls) { cw.xulG.urls = window.urls; }
293             try { s += ('******** cw = ' + cw + ' cw.xulG = ' + (cw.xulG) + '\n'); } catch(E) { s+=E + '\n'; }
294             obj.error.sdump('D_BROWSER',s);
295         } catch(E) {
296             this.error.sdump('D_ERROR','util.browser.push_variables: ' + E + '\n');
297         }
298     },
299
300     'getWebNavigation' : function() {
301         try {
302             var wn = this.controller.view.browser_browser.webNavigation;
303             var s = this.url + '\n' + this.get_content().location.href + '\n';
304             s += ('getWebNavigation() = ' + wn + '\n');
305             //this.error.sdump('D_BROWSER',s);
306             return wn;
307         } catch(E) {
308             this.error.sdump('D_ERROR','util.browser.getWebNavigation(): ' + E );
309         }
310     },
311
312     'updateNavButtons' : function() {
313         var obj = this; 
314         var s = obj.url + '\n' + obj.get_content().location.href + '\n';
315         try {
316             var n = obj.getWebNavigation();
317             s += ('webNavigation = ' + n + '\n');
318             s += ('webNavigation.canGoForward = ' + n.canGoForward + '\n');
319             if (n.canGoForward) {
320                 if (typeof obj.controller.view.cmd_forward != 'undefined') {
321                     obj.controller.view.cmd_forward.disabled = false;
322                     obj.controller.view.cmd_forward.setAttribute('disabled','false');
323                 }
324             } else {
325                 if (typeof obj.controller.view.cmd_forward != 'undefined') {
326                     obj.controller.view.cmd_forward.disabled = true;
327                     obj.controller.view.cmd_forward.setAttribute('disabled','true');
328                 }
329             }
330         } catch(E) {
331             s += E + '\n';
332         }
333         try {
334             var n = obj.getWebNavigation();
335             s += ('webNavigation = ' + n + '\n');
336             s += ('webNavigation.canGoBack = ' + n.canGoBack + '\n');
337             if (n.canGoBack) {
338                 if (typeof obj.controller.view.cmd_back != 'undefined') {
339                     obj.controller.view.cmd_back.disabled = false;
340                     obj.controller.view.cmd_back.setAttribute('disabled','false');
341                 }
342             } else {
343                 if (typeof obj.controller.view.cmd_back != 'undefined') {
344                     obj.controller.view.cmd_back.disabled = true;
345                     obj.controller.view.cmd_back.setAttribute('disabled','true');
346                 }
347             }
348         } catch(E) {
349             s += E + '\n';
350         }
351         //this.error.sdump('D_BROWSER',s);
352
353         // Let's also update @protocol, @hostname, @port, and @pathname on the <help> widget
354         if (xulG.set_help_context) {
355             try {
356                 var help_params = {
357                     'protocol' : obj.get_content().location.protocol,
358                     'hostname' : obj.get_content().location.hostname,
359                     'port' : obj.get_content().location.port,
360                     'pathname' : obj.get_content().location.pathname,
361                     'src' : ''
362                 };
363                 xulG.set_help_context(help_params);
364             } catch(E) {
365                 dump('Error in browser.js, setting location on help widget: ' + E);
366             }
367         } else {
368             dump(location.href + ': browser.js, updateNavButtons, xulG = ' + xulG + ' xulG.set_help_context = ' + xulG.set_help_context + '\n');
369         }
370     },
371
372     'buildProgressListener' : function() {
373
374         try {
375             var obj = this;
376             obj.progressListener = {
377                 onProgressChange    : function(webProgress,request,curSelfProgress,maxSelfProgress,curTotalProgress,maxTotalProgress){
378                     try {
379                         /*dump('browser.js onProgressChange('
380                             +webProgress
381                             +','+request
382                             +','+curSelfProgress
383                             +','+maxSelfProgress
384                             +','+curTotalProgress
385                             +','+maxTotalProgress+')\n');*/
386                     } catch(E) {
387                         dump('error in util.browser.progresslistener.onProgressChange: ' + E + '\n');
388                     }
389                 },
390                 onLocationChange    : function(webProgress,request,uri){
391                     try {
392                         /*dump('browser.js onLocationChange('
393                             +webProgress
394                             +','+request
395                             +','+uri+')\n');*/
396                     } catch(E) {
397                         dump('error in util.browser.progresslistener.onLocationChange: ' + E + '\n');
398                     }
399                 },
400                 onStatusChange        : function(webProgress,request,status,message){
401                     try {
402                         /*dump('browser.js onStatusChange('
403                             +webProgress+','
404                             +request
405                             +','+status
406                             +','+message+')\n');*/
407                     } catch(E) {
408                         dump('error in util.browser.progresslistener.onStatusChange: ' + E + '\n');
409                     }
410                 },
411                 onSecurityChange    : function(webProgress,request,state){
412                     try {
413                         /*dump('browser.js onSecurityChange('
414                             +webProgress
415                             +','+request
416                             +','+state+')\n');*/
417                     } catch(E) {
418                         dump('error in util.browser.progresslistener.onSecurityChange: ' + E + '\n');
419                     }
420                 },
421                 onStateChange         : function ( webProgress, request, stateFlags, status) {
422                     try {
423                         /*dump('browser.js onStateChange('
424                             +webProgress
425                             +','+request
426                             +','+stateFlags
427                             +','+status+')\n');*/
428                         var s = obj.url + '\n' + obj.get_content().location.href + '\n';
429                         const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
430                         const nsIChannel = Components.interfaces.nsIChannel;
431                         ////// handle the throbber
432                         var throbber = xulG.page_meter;
433                         if (throbber) {
434                             var busy = false;
435                             if (!(stateFlags & nsIWebProgressListener.STATE_RESTORING)) {
436                                 busy = true;
437                                 throbber.on();
438                             }
439                             if (stateFlags & nsIWebProgressListener.STATE_STOP) {
440                                 busy = false;
441                                 setTimeout(
442                                     function() {
443                                         if (!busy) { throbber.off(); }
444                                     }, 2000
445                                 );
446                             }
447                         }
448                         //////
449                         if ( (stateFlags & nsIWebProgressListener.STATE_IS_REQUEST
450                                 && stateFlags & nsIWebProgressListener.STATE_TRANSFERRING)
451                             || (stateFlags & nsIWebProgressListener.STATE_IS_REQUEST
452                                 && stateFlags & nsIWebProgressListener.STATE_START)
453                             || (stateFlags & nsIWebProgressListener.STATE_IS_REQUEST
454                                 && stateFlags & nsIWebProgressListener.STATE_STOP)
455                             ) {
456                             return;
457                         }
458                         s += ('onStateChange: stateFlags = ' + stateFlags + ' status = ' + status + '\n');
459                         if (stateFlags & nsIWebProgressListener.STATE_IS_REQUEST) {
460                             s += ('\tSTATE_IS_REQUEST\n');
461                         }
462                         if (stateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) {
463                             s += ('\tSTATE_IS_DOCUMENT\n');
464                             if( stateFlags & nsIWebProgressListener.STATE_STOP ) {
465                                 var alert_string = 'document has stopped: ' + new Date() + '\n'; dump(alert_string);
466                                 try {
467                                     obj.push_variables(); obj.updateNavButtons();
468                                 } catch(E) {
469                                     var err_msg = 'browser.js STATE_IS_DOCUMENT STATE_STOP error with push_variables or updateNavButtons: ' + E + '\n';
470                                     dump(err_msg);
471                                     obj.error.sdump('D_ERROR',err_msg);
472                                 }
473                                 if (typeof obj.on_url_load == 'function') {
474                                     try {
475                                         obj.error.sdump('D_TRACE','calling on_url_load');
476                                         var helpers = {
477                                             'doc_write' : function(html) {
478                                                 obj.get_content().document.write(html);
479                                             },
480                                             'doc_close' : function() {
481                                                 obj.get_content().document.close();
482                                             }
483                                         }
484                                         obj.on_url_load( obj.controller.view.browser_browser, obj, helpers );
485                                     } catch(E) {
486                                         obj.error.sdump('D_ERROR','on_url_load: ' + E );
487                                     }
488                                 }
489                                 if (obj.debug_label) {
490                                     try {
491                                         document.getElementById(obj.debug_label).setAttribute('tooltiptext','url: ' + obj.get_content().location.href);
492                                     } catch(E) {
493                                         obj.error.sdump('D_ERROR','on_url_load, debug_label: ' + E );
494                                     }
495                                 }
496                             }
497                         }
498                         if (stateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
499                             s += ('\tSTATE_IS_NETWORK\n');
500                         }
501                         if (stateFlags & nsIWebProgressListener.STATE_IS_WINDOW) {
502                             s += ('\tSTATE_IS_WINDOW\n');
503                         }
504                         if (stateFlags & nsIWebProgressListener.STATE_START) {
505                             s += ('\tSTATE_START\n');
506                             obj.from_back = obj.back_button_clicked;
507                             obj.back_button_clicked = false;
508                         }
509                         if (stateFlags & nsIWebProgressListener.STATE_REDIRECTING) {
510                             s += ('\tSTATE_REDIRECTING\n');
511                         }
512                         if (stateFlags & nsIWebProgressListener.STATE_TRANSFERING) {
513                             s += ('\tSTATE_TRANSFERING\n');
514                         }
515                         if (stateFlags & nsIWebProgressListener.STATE_NEGOTIATING) {
516                             s += ('\tSTATE_NEGOTIATING\n');
517                         }
518                         if (stateFlags & nsIWebProgressListener.STATE_STOP) {
519                             s += ('\tSTATE_STOP\n');
520                         }
521                         //obj.error.sdump('D_BROWSER',s);    
522                         if (throbber) { throbber.tooltip(s); }
523                     } catch(E) {
524                         dump('error in util.browser.progresslistener.onStateChange: ' + E + '\n');
525                         obj.error.sdump('D_ERROR','util.browser.progresslistener.onstatechange: ' + (E));
526                     }
527                 }
528             }
529             obj.progressListener.QueryInterface = function(){return this;};
530         } catch(E) {
531             this.error.sdump('D_ERROR','util.browser.buildProgressListener: ' + E + '\n');
532         }
533     }
534 }
535
536 dump('exiting util.browser.js\n');