]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/main/main.js
73983c3c0308d4e896deca517d863e188e25dfb9
[working/Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / main / main.js
1 dump('entering main/main.js\n');
2 // vim:noet:sw=4:ts=4:
3
4 var xulG;
5 var offlineStrings;
6 var authStrings;
7 var openTabs = new Array();
8 var tempWindow = null;
9 var tempFocusWindow = null;
10
11 function grant_perms(url) {
12     var perms = "UniversalXPConnect UniversalPreferencesWrite UniversalBrowserWrite UniversalPreferencesRead UniversalBrowserRead UniversalFileRead";
13     dump('Granting ' + perms + ' to ' + url + '\n');
14     if (G.pref) {
15         G.pref.setCharPref("capability.principal.codebase.p0.granted", perms);
16         G.pref.setCharPref("capability.principal.codebase.p0.id", url);
17         G.pref.setCharPref("capability.principal.codebase.p1.granted", perms);
18         G.pref.setCharPref("capability.principal.codebase.p1.id", url.replace('http:','https:'));
19         G.pref.setBoolPref("dom.disable_open_during_load",false);
20         G.pref.setBoolPref("browser.popups.showPopupBlocker",false);
21     }
22
23 }
24
25 function clear_the_cache() {
26     try {
27         var cacheClass         = Components.classes["@mozilla.org/network/cache-service;1"];
28         var cacheService    = cacheClass.getService(Components.interfaces.nsICacheService);
29         cacheService.evictEntries(Components.interfaces.nsICache.STORE_ON_DISK);
30         cacheService.evictEntries(Components.interfaces.nsICache.STORE_IN_MEMORY);
31     } catch(E) {
32         dump(E+'\n');alert(E);
33     }
34 }
35
36 function toOpenWindowByType(inType, uri) { /* for Venkman */
37     try {
38         var winopts = "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar";
39         window.open(uri, "_blank", winopts);
40     } catch(E) {
41         alert(E); throw(E);
42     }
43 }
44
45 function start_debugger() {
46     setTimeout(
47         function() {
48             try { start_venkman(); } catch(E) { alert(E); }
49         }, 0
50     );
51 };
52
53 function start_inspector() {
54     setTimeout(
55         function() {
56             try { inspectDOMDocument(); } catch(E) { alert(E); }
57         }, 0
58     );
59 };
60
61 function start_chrome_list() {
62     setTimeout(
63         function() {
64             try { startChromeList(); } catch(E) { alert(E); }
65         }, 0
66     );
67 };
68
69 function start_js_shell() {
70     setTimeout(
71         function() {
72             try { window.open('chrome://open_ils_staff_client/content/util/shell.html','shell','chrome,resizable,scrollbars'); } catch(E) { alert(E); }
73         }, 0
74     );
75 };
76
77 function new_tabs(aTabList, aContinue) {
78     if(aTabList != null) {
79         openTabs = openTabs.concat(aTabList);
80     }
81     if(G.data.session) { // Just add to the list of stuff to open unless we are logged in
82         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
83         var targetwindow = null;
84         var focuswindow = null;
85         var focustab = {'focus' : true};
86         if(aContinue == true && tempWindow.closed == false) {
87             if(tempWindow.g == undefined || tempWindow.g.menu == undefined) {
88                 setTimeout(
89                     function() {
90                         new_tabs(null, true);
91                     }, 300);
92                 return null;
93             }
94             targetwindow = tempWindow;
95             tempWindow = null;
96             focuswindow = tempFocusWindow;
97             tempFocusWindow = null;
98             focustab = {'nofocus' : true};
99         }
100         else if(tempWindow != null) { // In theory, we are waiting on a setTimeout
101             if(tempWindow.closed == true) // But someone closed our window?
102             {
103                 tempWindow = null;
104                 tempFocusWindow = null;
105             }
106             else
107             {
108                 return null;
109             }
110         }
111         var newTab;
112         var firstURL;
113         var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
114             getService(Components.interfaces.nsIWindowMediator);
115             // This may look out of place, but this is so we can continue this loop from down below
116 opentabs:
117             while(openTabs.length > 0) {
118             newTab = openTabs.shift();
119             if(newTab == 'new' || newTab == 'init') {
120                 if(newTab != 'init' && openTabs.length > 0 && openTabs[0] != 'new') {
121                     firstURL = openTabs.shift();
122                     if(firstURL != 'tab') { // 'new' followed by 'tab' should be equal to 'init' in functionality, this should do that
123                         if(urls[firstURL]) {
124                             firstURL = urls[firstURL];
125                         }
126                         firstURL = '&firstURL=' + window.escape(firstURL);
127                     }
128                     else {
129                         firstURL = '';
130                     }
131                 }
132                 else {
133                     firstURL = '';
134                 }
135                 targetwindow = xulG.window.open(urls.XUL_MENU_FRAME
136                     + '?server='+window.escape(G.data.server) + firstURL,
137                     '_blank','chrome,resizable'
138                 );
139                 targetwindow.xulG = xulG;
140                 if (focuswindow == null) {
141                     focuswindow = targetwindow;
142                 }
143                 tempWindow = targetwindow;
144                 tempFocusWindow = focuswindow;
145                 setTimeout(
146                     function() {
147                         new_tabs(null, true);
148                     }, 300);
149                 return null;
150             }
151             else {
152                 if(newTab == 'tab') {
153                     newTab = null;
154                 }
155                 else if(urls[newTab]) {
156                     newTab = urls[newTab];
157                 }
158                 if(targetwindow != null) { // Already have a previous target window? Use it first.
159                     if(targetwindow.g.menu.new_tab(newTab,focustab,null)) {
160                         focustab = {'nofocus' : true};
161                         continue;
162                     }
163                 }
164                 var enumerator = wm.getEnumerator('eg_menu');
165                 while(enumerator.hasMoreElements()) {
166                     targetwindow = enumerator.getNext();
167                     if(targetwindow.g.menu.new_tab(newTab,focustab,null)) {
168                         focustab = {'nofocus' : true};
169                         if (focuswindow == null) {
170                             focuswindow = targetwindow;
171                         }
172                         continue opentabs;
173                     }
174                 }
175                 // No windows found to add the tab to? Make a new one.
176                 if(newTab == null) { // Were we making a "default" tab?
177                     openTabs.unshift('init'); // 'init' does that for us!
178                 }
179                 else {
180                     openTabs.unshift('new',newTab);
181                 }
182             }
183         }
184         if(focuswindow != null) {
185             focuswindow.focus();
186         }
187     }
188 }
189
190 // Returns false if we can't get an actual perm list
191 // Returns an array of perms with boolean has/hasn't flag
192 function get_menu_perms(indocument) {
193     // If we don't have our static perm list, and we have a remote window, go looking.
194     // We never need to look twice unless a dev is manually editing their files.
195     // Shame on them, they can restart the entire client ;)
196     if(typeof(get_menu_perms.perm_list) == 'undefined' && indocument != null)
197     {
198         get_menu_perms.perm_list = [ ];
199         var commands = indocument.getElementById('universal_cmds').getElementsByTagName('command');
200         for (var i = 0; i < commands.length; i++) { 
201             if (commands[i].hasAttribute('perm')) {
202                 get_menu_perms.perm_list = get_menu_perms.perm_list.concat(commands[i].getAttribute('perm').split(' '));
203             }           
204         }
205     }
206     // 
207     if(typeof(get_menu_perms.perm_list) == 'object') {
208         G.data.stash_retrieve();
209         if(!G.data.menu_perms) {
210             JSAN.use('util.network');
211             var network = new util.network();
212             var r = network.simple_request('BATCH_PERM_RETRIEVE_WORK_OU', [ G.data.session.key, get_menu_perms.perm_list ]);
213             for(p in r)
214                 r[p] = (typeof(r[p][0]) == 'number');
215             // Developer-enabled clients override permissions and always allow debugging
216             if(G.data.debug_build) {
217                 r['DEBUG_CLIENT'] = true;
218             }
219             // If we have DEBUG_CLIENT (by force or otherwise) we can use debugging interfaces
220             // Doing this here because this function gets called at least once per login
221             // Including operator change
222             G.data.enable_debug = (r['DEBUG_CLIENT'] == true);
223             G.data.stash('enable_debug');
224             G.data.menu_perms = r;
225             G.data.stash('menu_perms');
226         }
227         return G.data.menu_perms;
228     }
229     return false;
230 }
231
232 // Returns a list (cached or from filesystem) of hotkey sets
233 function load_hotkey_sets() {
234     if(typeof(load_hotkey_sets.set_list) == 'undefined') {
235         load_hotkey_sets.set_list = [];
236         JSAN.use('util.file');
237         var file = new util.file();
238         var dirEntries = file.get('hotkeys','skin').directoryEntries;
239         while(dirEntries.hasMoreElements()) {
240             var entry = dirEntries.getNext();
241             entry.QueryInterface(Components.interfaces.nsIFile);
242             if(!entry.isFile()) continue;
243             if(!entry.leafName.match(/.+\.keyset$/)) continue;
244             var keysetname = entry.leafName.replace(/\.keyset$/,'');
245             load_hotkey_sets.set_list.push(keysetname);
246         }
247         file.close();
248     }
249     return load_hotkey_sets.set_list;
250 }
251
252 // Returns an array (cached or from filesystem) for a given hotkey set
253 function get_hotkey_array(keyset_name) {
254     if(typeof(get_hotkey_array.keyset_cache) == 'undefined') {
255         get_hotkey_array.keyset_cache = {};
256     }
257     if(get_hotkey_array.keyset_cache[keyset_name])
258         return get_hotkey_array.keyset_cache[keyset_name];
259     JSAN.use('util.file');
260     var file = new util.file();
261     var keyset_raw;
262     try {
263         var keyset_file = file.get('hotkeys','skin');
264         keyset_file.append(keyset_name + ".keyset");
265         keyset_raw = file.get_content();
266         file.close();
267         var tempArray = [];
268
269         var keyset_lines = keyset_raw.trim().split("\n");
270         for(var line = 0; line < keyset_lines.length; line++) {
271             // Grab line, strip comments, strip leading/trailing whitespace
272             var curline = keyset_lines[line].replace(/\s*#.*$/,'').trim();
273             if(curline == "") continue; // Skip empty lines
274             // Split into pieces
275             var split_line = curline.split(',');
276             // We need at least 3 elements. Command, modifiers, keycode.
277             if(split_line.length < 3) continue;
278             // Trim each segment
279             split_line[0] = split_line[0].trim();
280             split_line[1] = split_line[1].trim();
281             split_line[2] = split_line[2].trim();
282             if(split_line.length > 3)
283                 split_line[3] = split_line[3].trim();
284             // Skip empty commands
285             if(split_line[0] == "") continue;
286             // Push to array
287             tempArray.push(split_line);
288         }
289         get_hotkey_array.keyset_cache[keyset_name] = tempArray;
290         return tempArray;
291     } catch(E) { // Something went wrong.
292         return false;
293     }
294 }
295
296 function main_init() {
297     dump('entering main_init()\n');
298     try {
299         clear_the_cache();
300         if("arguments" in window && window.arguments.length > 0 && window.arguments[0].wrappedJSObject != undefined && window.arguments[0].wrappedJSObject.openTabs != undefined) {
301             openTabs = openTabs.concat(window.arguments[0].wrappedJSObject.openTabs);
302         }
303
304         // Now we can safely load the strings without the cache getting wiped
305         offlineStrings = document.getElementById('offlineStrings');
306         authStrings = document.getElementById('authStrings');
307
308         if (typeof JSAN == 'undefined') {
309             throw(
310                 offlineStrings.getString('common.jsan.missing')
311             );
312         }
313         /////////////////////////////////////////////////////////////////////////////
314
315         JSAN.errorLevel = "die"; // none, warn, or die
316         JSAN.addRepository('..');
317
318         //JSAN.use('test.test'); test.test.hello_world();
319
320         var mw = self;
321         G =  {};
322         
323         G.pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
324         G.pref.QueryInterface(Components.interfaces.nsIPrefBranch2);
325         if (! G.pref.prefHasUserValue('general.useragent.override')) {
326             G.pref.setCharPref('general.useragent.override',navigator.userAgent + ' oils_xulrunner /xul/server/');
327         }
328
329         JSAN.use('util.error');
330         G.error = new util.error();
331         G.error.sdump('D_ERROR', offlineStrings.getString('main.testing'));
332
333         JSAN.use('util.window');
334         G.window = new util.window();
335
336         JSAN.use('auth.controller');
337         G.auth = new auth.controller( { 'window' : mw } );
338
339         JSAN.use('OpenILS.data');
340         G.data = new OpenILS.data();
341         G.data.on_error = G.auth.logoff;
342
343         JSAN.use('util.file');
344         G.file = new util.file();
345         try {
346             G.file.get('ws_info');
347             G.ws_info = G.file.get_object(); G.file.close();
348         } catch(E) {
349             G.ws_info = {};
350         }
351         G.data.ws_info = G.ws_info; G.data.stash('ws_info');
352
353         G.auth.on_login = function() {
354
355             var url = G.auth.controller.view.server_prompt.value.match(/^[^\/]*/).toString() || urls.remote;
356
357             G.data.server_unadorned = url; G.data.stash('server_unadorned'); G.data.stash_retrieve();
358
359             if (! url.match( '^http://' ) ) { url = 'http://' + url; }
360
361             G.data.server = url; G.data.stash('server'); 
362             G.data.session = { 'key' : G.auth.session.key, 'auth' : G.auth.session.authtime }; G.data.stash('session');
363             G.data.stash_retrieve();
364             try {
365                 var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
366                 var cookieUri = ios.newURI("http://" + G.data.server_unadorned, null, null);
367                 var cookieUriSSL = ios.newURI("https://" + G.data.server_unadorned, null, null);
368                 var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
369
370                 cookieSvc.setCookieString(cookieUri, null, "ses="+G.data.session.key, null);
371                 cookieSvc.setCookieString(cookieUriSSL, null, "ses="+G.data.session.key, null);
372                 cookieSvc.setCookieString(cookieUri, null, "xul=1", null);
373                 cookieSvc.setCookieString(cookieUriSSL, null, "xul=1", null);
374
375             } catch(E) {
376                 alert(offlineStrings.getFormattedString(main.session_cookie.error, [E]));
377             }
378
379             grant_perms(url);
380
381             xulG = {
382                 'auth' : G.auth,
383                 'url' : url,
384                 'window' : G.window,
385                 'data' : G.data,
386                 'pref' : G.pref
387             };
388
389             if (G.data.ws_info && G.data.ws_info[G.auth.controller.view.server_prompt.value]) {
390                 JSAN.use('util.widgets');
391                 var deck = document.getElementById('progress_space');
392                 util.widgets.remove_children( deck );
393                 var iframe = document.createElement('iframe'); deck.appendChild(iframe);
394                 iframe.setAttribute( 'src', url + urls.XUL_LOGIN_DATA );
395                 iframe.contentWindow.xulG = xulG;
396                 G.data_xul = iframe.contentWindow;
397             } else {
398                 xulG.file = G.file;
399                 var deck = G.auth.controller.view.ws_deck;
400                 JSAN.use('util.widgets'); util.widgets.remove_children('ws_deck');
401                 var iframe = document.createElement('iframe'); deck.appendChild(iframe);
402                 iframe.setAttribute( 'src', url + urls.XUL_WORKSTATION_INFO );
403                 iframe.contentWindow.xulG = xulG;
404                 deck.selectedIndex = deck.childNodes.length - 1;
405             }
406         };
407
408         G.auth.on_standalone = function() {
409             try {
410                 G.window.open(urls.XUL_STANDALONE,'Offline','chrome,resizable');
411             } catch(E) {
412                 alert(E);
413             }
414         };
415
416         G.auth.on_standalone_export = function() {
417             try {
418                 JSAN.use('util.file'); var file = new util.file('pending_xacts');
419                 if (file._file.exists()) {
420                     var file2 = new util.file('');
421                     var f = file2.pick_file( { 'mode' : 'save', 'title' : offlineStrings.getString('main.transaction_export.title') } );
422                     if (f) {
423                         if (f.exists()) {
424                             var r = G.error.yns_alert(
425                                 offlineStrings.getFormattedString('main.transaction_export.prompt', [f.leafName]),
426                                 offlineStrings.getString('main.transaction_export.prompt.title'),
427                                 offlineStrings.getString('common.yes'),
428                                 offlineStrings.getString('common.no'),
429                                 null,
430                                 offlineStrings.getString('common.confirm')
431                             );
432                             if (r != 0) { file.close(); return; }
433                         }
434                         var e_file = new util.file(''); e_file._file = f;
435                         e_file.write_content( 'truncate', file.get_content() );
436                         e_file.close();
437                         var r = G.error.yns_alert(
438                             offlineStrings.getFormattedString('main.transaction_export.success.prompt', [f.leafName]),
439                             offlineStrings.getString('main.transaction_export.success.title'),
440                             offlineStrings.getString('common.yes'),
441                             offlineStrings.getString('common.no'),
442                             null,
443                             offlineStrings.getString('common.confirm')
444                         );
445                         if (r == 0) {
446                             var count = 0;
447                             var filename = 'pending_xacts_exported_' + new Date().getTime();
448                             var t_file = new util.file(filename);
449                             while (t_file._file.exists()) {
450                                 filename = 'pending_xacts_' + new Date().getTime() + '.exported';
451                                 t_file = new util.file(filename);
452                                 if (count++ > 100) {
453                                     throw(offlineStrings.getString('main.transaction_export.filename.error'));
454                                 }
455                             }
456                             file.close(); file = new util.file('pending_xacts'); // prevents a bug with .moveTo below
457                             file._file.moveTo(null,filename);
458                         } else {
459                             alert(offlineStrings.getString('main.transaction_export.duplicate.warning'));
460                         }
461                     } else {
462                         alert(offlineStrings.getString('main.transaction_export.no_filename.error'));
463                     }
464                 } else {
465                     alert(offlineStrings.getString('main.transaction_export.no_transactions.error'));
466                 }
467                 file.close();
468             } catch(E) {
469                 alert(E);
470             }
471         };
472
473         G.auth.on_standalone_import = function() {
474             try {
475                 JSAN.use('util.file'); var file = new util.file('pending_xacts');
476                 if (file._file.exists()) {
477                     alert(offlineStrings.getString('main.transaction_import.outstanding.error'));
478                 } else {
479                     var file2 = new util.file('');
480                     var f = file2.pick_file( { 'mode' : 'open', 'title' : offlineStrings.getString('main.transaction_import.title')} );
481                     if (f && f.exists()) {
482                         var i_file = new util.file(''); i_file._file = f;
483                         file.write_content( 'truncate', i_file.get_content() );
484                         i_file.close();
485                         var r = G.error.yns_alert(
486                             offlineStrings.getFormattedString('main.transaction_import.delete.prompt', [f.leafName]),
487                             offlineStrings.getString('main.transaction_import.success'),
488                             offlineStrings.getString('common.yes'),
489                             offlineStrings.getString('common.no'),
490                             null,
491                             offlineStrings.getString('common.confirm')
492                         );
493                         if (r == 0) {
494                             f.remove(false);
495                         }
496                     }
497                 }
498                 file.close();
499             } catch(E) {
500                 alert(E);
501             }
502         };
503
504         G.auth.on_debug = function(action) {
505             switch(action) {
506                 case 'js_console' :
507                     G.window.open(urls.XUL_DEBUG_CONSOLE,'testconsole','chrome,resizable');
508                 break;
509                 case 'clear_cache' :
510                     clear_the_cache();
511                     alert(offlineStrings.getString('main.on_debug.clear_cache'));
512                 break;
513                 default:
514                     alert(offlineStrings.getString('main.on_debug.debug'));
515                 break;
516             }
517         };
518
519         G.auth.init();
520         // XML_HTTP_SERVER will get reset to G.auth.controller.view.server_prompt.value
521
522         /////////////////////////////////////////////////////////////////////////////
523
524         var version = CLIENT_VERSION;
525         if (CLIENT_STAMP.length == 0) {
526             version = 'versionless debug build';
527             document.getElementById('debug_gb').hidden = false;
528         }
529
530         try {
531             if (G.pref && G.pref.getBoolPref('open-ils.debug_options')) {
532                 document.getElementById('debug_gb').hidden = false;
533             }
534         } catch(E) {
535         }
536
537         // If we are showing the debugging frame then we consider this a debug build
538         // This could be a versionless build, a developer-pref enabled build, or otherwise
539         // If set this will enable all debugging commands, even if you normally don't have permission to use them
540         G.data.debug_build = !document.getElementById('debug_gb').hidden;
541         G.data.stash('debug_build');
542
543         var appInfo = Components.classes["@mozilla.org/xre/app-info;1"] 
544             .getService(Components.interfaces.nsIXULAppInfo); 
545
546         if (appInfo.ID == "staff-client@open-ils.org")
547         {
548             try {
549                 if (G.pref && G.pref.getBoolPref('app.update.enabled')) {
550                     document.getElementById('check_upgrade_sep').hidden = false;
551                     var upgrademenu = document.getElementById('check_upgrade');
552                     upgrademenu.hidden = false;
553                     G.upgradeCheck = function () {
554                         var um = Components.classes["@mozilla.org/updates/update-manager;1"]
555                             .getService(Components.interfaces.nsIUpdateManager);
556                         var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
557                             .createInstance(Components.interfaces.nsIUpdatePrompt);
558
559                         if (um.activeUpdate && um.activeUpdate.state == "pending")
560                             prompter.showUpdateDownloaded(um.activeUpdate);
561                         else
562                             prompter.checkForUpdates();
563                     }
564                     upgrademenu.addEventListener(
565                         'command',
566                         G.upgradeCheck,
567                         false
568                     );
569                 }
570             } catch(E) {
571             }
572         }
573
574         window.title = authStrings.getFormattedString('staff.auth.titlebar.label', version);
575         var x = document.getElementById('about_btn');
576         x.addEventListener(
577             'command',
578             function() {
579                 try { 
580                     G.window.open('about.html','about','chrome,resizable,width=800,height=600');
581                 } catch(E) { alert(E); }
582             }, 
583             false
584         );
585
586         var y = document.getElementById('new_window_btn');
587         y.addEventListener(
588             'command',
589             function() {
590                 if (G.data.session) {
591                     new_tabs(Array('new'), null, null);
592                 } else {
593                     alert ( offlineStrings.getString('main.new_window_btn.login_first_warning') );
594                 }
595             },
596             false
597         );
598
599         JSAN.use('util.mozilla');
600         var z = document.getElementById('locale_menupopup');
601         if (z) {
602             while (z.lastChild) z.removeChild(z.lastChild);
603             var locales = util.mozilla.chromeRegistry().getLocalesForPackage( String( location.href ).split(/\//)[2] );
604             var current_locale = util.mozilla.prefs().getCharPref('general.useragent.locale');
605             while (locales.hasMore()) {
606                 var locale = locales.getNext();
607                 var parts = locale.split(/-/);
608                 var label;
609                 try {
610                     label = locale + ' : ' + util.mozilla.languages().GetStringFromName(parts[0]);
611                     if (parts.length > 1) {
612                         try {
613                             label += ' (' + util.mozilla.regions().GetStringFromName(parts[1].toLowerCase()) + ')';
614                         } catch(E) {
615                             label += ' (' + parts[1] + ')';
616                         }
617                     }
618                 } catch(E) {
619                     label = locale;
620                 }
621                 var mi = document.createElement('menuitem');
622                 mi.setAttribute('label',label);
623                 mi.setAttribute('value',locale);
624                 if (locale == current_locale) {
625                     if (z.parentNode.tagName == 'menulist') {
626                         mi.setAttribute('selected','true');
627                         z.parentNode.setAttribute('label',label);
628                         z.parentNode.setAttribute('value',locale);
629                     }
630                 }
631                 z.appendChild( mi );
632             }
633         }
634         var xx = document.getElementById('apply_locale_btn');
635         xx.addEventListener(
636             'command',
637             function() {
638                 util.mozilla.change_locale(z.parentNode.value);
639             },
640             false
641         );
642
643         if ( found_ws_info_in_Achrome() && G.pref && G.pref.getBoolPref("open-ils.write_in_user_chrome_directory") ) {
644             //var hbox = x.parentNode; var b = document.createElement('button'); 
645             //b.setAttribute('label','Migrate legacy settings'); hbox.appendChild(b);
646             //b.addEventListener(
647             //    'command',
648             //    function() {
649             //        try {
650             //            handle_migration();
651             //        } catch(E) { alert(E); }
652             //    },
653             //    false
654             //);
655             if (window.confirm(offlineStrings.getString('main.settings.migrate'))) {
656                 setTimeout( function() { handle_migration(); }, 0 );
657             }
658         }
659
660         window.addEventListener(
661             'close',
662             function(ev) {
663
664                 G.data.stash_retrieve();
665                 if (typeof G.data.unsaved_data != 'undefined') {
666                     if (G.data.unsaved_data > 0) {
667                         var confirmation = window.confirm(offlineStrings.getString('menu.shutdown.unsaved_data_warning'));
668                         if (!confirmation) {
669                             ev.preventDefault();
670                             return false;
671                         }
672                     }
673                 }
674                 G.data.unsaved_data = 0;
675                 G.data.stash('unsaved_data');
676
677                 return true;
678
679             },
680             false
681         );
682
683         /**
684             @brief Stats for Offline Files / Transactions
685             @launchpad #797408
686         */
687         var px = new util.file('pending_xacts');
688         document.getElementById('offline_message').setAttribute('style','display:none;');
689         if (px._file.exists()) {
690             document.getElementById('offline_message').setAttribute('style','background-color:red;display:block;font-weight:bold;padding:2px;');
691             document.getElementById('offline_import_btn').disabled = true;
692         }
693
694         // Attempt auto-login, if provided
695         if("arguments" in window && window.arguments.length > 0 && window.arguments[0].wrappedJSObject != undefined && window.arguments[0].wrappedJSObject.loginInfo != undefined) {
696             auto_login(window.arguments[0].wrappedJSObject.loginInfo);
697             // Regardless of success, clear that variable now, so we don't possibly have passwords hanging around.
698             window.arguments[0].wrappedJSObject.loginInfo = null;
699         }
700
701     } catch(E) {
702         var error = offlineStrings.getFormattedString('common.exception', [E, '']);
703         try { G.error.sdump('D_ERROR',error); } catch(E) { dump(error); }
704         alert(error);
705     }
706     dump('exiting main_init()\n');
707 }
708
709 function found_ws_info_in_Achrome() {
710     JSAN.use('util.file');
711     var f = new util.file();
712     var f_in_chrome = f.get('ws_info','chrome');
713     var path = f_in_chrome.exists() ? f_in_chrome.path : false;
714     f.close();
715     return path;
716 }
717
718 function found_ws_info_in_Uchrome() {
719     JSAN.use('util.file');
720     var f = new util.file();
721     var f_in_uchrome = f.get('ws_info','uchrome');
722     var path = f_in_uchrome.exists() ? f_in_uchrome.path : false;
723     f.close();
724     return path;
725 }
726
727 function handle_migration() {
728     if ( found_ws_info_in_Uchrome() ) {
729         alert(offlineStrings.getFormattedString('main.settings.migrate.failed', [found_ws_info_in_Uchrome(), found_ws_info_in_Achrome()])
730         );
731     } else {
732         var dirService = Components.classes["@mozilla.org/file/directory_service;1"].getService( Components.interfaces.nsIProperties );
733         var f_new = dirService.get( "UChrm", Components.interfaces.nsIFile );
734         var f_old = dirService.get( "AChrom", Components.interfaces.nsIFile );
735         f_old.append(myPackageDir); f_old.append("content"); f_old.append("conf"); 
736         if (window.confirm(offlineStrings.getFormattedString("main.settings.migrate.confirm", [f_old.path, f_new.path]))) {
737             var files = f_old.directoryEntries;
738             while (files.hasMoreElements()) {
739                 var file = files.getNext();
740                 var file2 = file.QueryInterface( Components.interfaces.nsILocalFile );
741                 try {
742                     file2.moveTo( f_new, '' );
743                 } catch(E) {
744                     alert(offlineStrings.getFormattedString('main.settings.migrate.error', [file2.path, f_new.path]) + '\n');
745                 }
746             }
747             location.href = location.href; // huh?
748         }
749     }
750 }
751
752 function auto_login(loginInfo) {
753     if(G.data.session) return; // We are logged in. No auto-logoff supported.
754     if(loginInfo.host) G.auth.controller.view.server_prompt.value = loginInfo.host;
755     if(loginInfo.user) G.auth.controller.view.name_prompt.value = loginInfo.user;
756     if(loginInfo.passwd) G.auth.controller.view.password_prompt.value = loginInfo.passwd;
757     if(loginInfo.host && loginInfo.user && loginInfo.passwd && G.data.ws_info && G.data.ws_info[loginInfo.host]) {
758         G.auth.login();
759     }
760 }
761
762 dump('exiting main/main.js\n');