1 dump('entering main/main.js\n');
7 var openTabs = new Array();
9 var tempFocusWindow = null;
11 function grant_perms(url) {
12 var perms = "UniversalXPConnect UniversalPreferencesWrite UniversalBrowserWrite UniversalPreferencesRead UniversalBrowserRead UniversalFileRead";
13 dump('Granting ' + perms + ' to ' + url + '\n');
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);
25 function clear_the_cache() {
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);
32 dump(E+'\n');alert(E);
36 function toOpenWindowByType(inType, uri) { /* for Venkman */
38 var winopts = "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar";
39 window.open(uri, "_blank", winopts);
45 function start_debugger() {
48 try { start_venkman(); } catch(E) { alert(E); }
53 function start_inspector() {
56 try { inspectDOMDocument(); } catch(E) { alert(E); }
61 function start_chrome_list() {
64 try { startChromeList(); } catch(E) { alert(E); }
69 function start_js_shell() {
72 try { window.open('chrome://open_ils_staff_client/content/util/shell.html','shell','chrome,resizable,scrollbars'); } catch(E) { alert(E); }
77 function new_tabs(aTabList, aContinue) {
78 if(aTabList != null) {
79 openTabs = openTabs.concat(aTabList);
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) {
94 targetwindow = tempWindow;
96 focuswindow = tempFocusWindow;
97 tempFocusWindow = null;
98 focustab = {'nofocus' : true};
100 else if(tempWindow != null) { // In theory, we are waiting on a setTimeout
101 if(tempWindow.closed == true) // But someone closed our window?
104 tempFocusWindow = null;
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
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
124 firstURL = urls[firstURL];
126 firstURL = '&firstURL=' + window.escape(firstURL);
135 targetwindow = xulG.window.open(urls.XUL_MENU_FRAME
136 + '?server='+window.escape(G.data.server) + firstURL,
137 '_blank','chrome,resizable'
139 targetwindow.xulG = xulG;
140 if (focuswindow == null) {
141 focuswindow = targetwindow;
143 tempWindow = targetwindow;
144 tempFocusWindow = focuswindow;
147 new_tabs(null, true);
152 if(newTab == 'tab') {
155 else if(urls[newTab]) {
156 newTab = urls[newTab];
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};
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;
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!
180 openTabs.unshift('new',newTab);
184 if(focuswindow != null) {
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)
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(' '));
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 ]);
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;
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');
227 return G.data.menu_perms;
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);
249 return load_hotkey_sets.set_list;
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 = {};
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();
263 var keyset_file = file.get('hotkeys','skin');
264 keyset_file.append(keyset_name + ".keyset");
265 keyset_raw = file.get_content();
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
275 var split_line = curline.split(',');
276 // We need at least 3 elements. Command, modifiers, keycode.
277 if(split_line.length < 3) continue;
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;
287 tempArray.push(split_line);
289 get_hotkey_array.keyset_cache[keyset_name] = tempArray;
291 } catch(E) { // Something went wrong.
296 function main_init() {
297 dump('entering main_init()\n');
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);
304 // Now we can safely load the strings without the cache getting wiped
305 offlineStrings = document.getElementById('offlineStrings');
306 authStrings = document.getElementById('authStrings');
308 if (typeof JSAN == 'undefined') {
310 offlineStrings.getString('common.jsan.missing')
313 /////////////////////////////////////////////////////////////////////////////
315 JSAN.errorLevel = "die"; // none, warn, or die
316 JSAN.addRepository('..');
318 //JSAN.use('test.test'); test.test.hello_world();
323 G.pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
324 if (! G.pref.prefHasUserValue('general.useragent.override')) {
325 G.pref.setCharPref('general.useragent.override',navigator.userAgent + ' oils_xulrunner /xul/server/');
328 JSAN.use('util.error');
329 G.error = new util.error();
330 G.error.sdump('D_ERROR', offlineStrings.getString('main.testing'));
332 JSAN.use('util.window');
333 G.window = new util.window();
335 JSAN.use('auth.controller');
336 G.auth = new auth.controller( { 'window' : mw } );
338 JSAN.use('OpenILS.data');
339 G.data = new OpenILS.data();
340 G.data.on_error = G.auth.logoff;
342 JSAN.use('util.file');
343 G.file = new util.file();
345 G.file.get('ws_info');
346 G.ws_info = G.file.get_object(); G.file.close();
350 G.data.ws_info = G.ws_info; G.data.stash('ws_info');
352 G.auth.on_login = function() {
354 var url = G.auth.controller.view.server_prompt.value.match(/^[^\/]*/).toString() || urls.remote;
356 G.data.server_unadorned = url; G.data.stash('server_unadorned'); G.data.stash_retrieve();
358 if (! url.match( '^http://' ) ) { url = 'http://' + url; }
360 G.data.server = url; G.data.stash('server');
361 G.data.session = { 'key' : G.auth.session.key, 'auth' : G.auth.session.authtime }; G.data.stash('session');
362 G.data.stash_retrieve();
364 var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
365 var cookieUri = ios.newURI("http://" + G.data.server_unadorned, null, null);
366 var cookieUriSSL = ios.newURI("https://" + G.data.server_unadorned, null, null);
367 var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
369 cookieSvc.setCookieString(cookieUri, null, "ses="+G.data.session.key, null);
370 cookieSvc.setCookieString(cookieUriSSL, null, "ses="+G.data.session.key, null);
371 cookieSvc.setCookieString(cookieUri, null, "xul=1", null);
372 cookieSvc.setCookieString(cookieUriSSL, null, "xul=1", null);
375 alert(offlineStrings.getFormattedString(main.session_cookie.error, [E]));
388 if (G.data.ws_info && G.data.ws_info[G.auth.controller.view.server_prompt.value]) {
389 JSAN.use('util.widgets');
390 var deck = document.getElementById('progress_space');
391 util.widgets.remove_children( deck );
392 var iframe = document.createElement('iframe'); deck.appendChild(iframe);
393 iframe.setAttribute( 'src', url + urls.XUL_LOGIN_DATA );
394 iframe.contentWindow.xulG = xulG;
395 G.data_xul = iframe.contentWindow;
398 var deck = G.auth.controller.view.ws_deck;
399 JSAN.use('util.widgets'); util.widgets.remove_children('ws_deck');
400 var iframe = document.createElement('iframe'); deck.appendChild(iframe);
401 iframe.setAttribute( 'src', url + urls.XUL_WORKSTATION_INFO );
402 iframe.contentWindow.xulG = xulG;
403 deck.selectedIndex = deck.childNodes.length - 1;
407 G.auth.on_standalone = function() {
409 G.window.open(urls.XUL_STANDALONE,'Offline','chrome,resizable');
415 G.auth.on_standalone_export = function() {
417 JSAN.use('util.file'); var file = new util.file('pending_xacts');
418 if (file._file.exists()) {
419 var file2 = new util.file('');
420 var f = file2.pick_file( { 'mode' : 'save', 'title' : offlineStrings.getString('main.transaction_export.title') } );
423 var r = G.error.yns_alert(
424 offlineStrings.getFormattedString('main.transaction_export.prompt', [f.leafName]),
425 offlineStrings.getString('main.transaction_export.prompt.title'),
426 offlineStrings.getString('common.yes'),
427 offlineStrings.getString('common.no'),
429 offlineStrings.getString('common.confirm')
431 if (r != 0) { file.close(); return; }
433 var e_file = new util.file(''); e_file._file = f;
434 e_file.write_content( 'truncate', file.get_content() );
436 var r = G.error.yns_alert(
437 offlineStrings.getFormattedString('main.transaction_export.success.prompt', [f.leafName]),
438 offlineStrings.getString('main.transaction_export.success.title'),
439 offlineStrings.getString('common.yes'),
440 offlineStrings.getString('common.no'),
442 offlineStrings.getString('common.confirm')
446 var filename = 'pending_xacts_exported_' + new Date().getTime();
447 var t_file = new util.file(filename);
448 while (t_file._file.exists()) {
449 filename = 'pending_xacts_' + new Date().getTime() + '.exported';
450 t_file = new util.file(filename);
452 throw(offlineStrings.getString('main.transaction_export.filename.error'));
455 file.close(); file = new util.file('pending_xacts'); // prevents a bug with .moveTo below
456 file._file.moveTo(null,filename);
458 alert(offlineStrings.getString('main.transaction_export.duplicate.warning'));
461 alert(offlineStrings.getString('main.transaction_export.no_filename.error'));
464 alert(offlineStrings.getString('main.transaction_export.no_transactions.error'));
472 G.auth.on_standalone_import = function() {
474 JSAN.use('util.file'); var file = new util.file('pending_xacts');
475 if (file._file.exists()) {
476 alert(offlineStrings.getString('main.transaction_import.outstanding.error'));
478 var file2 = new util.file('');
479 var f = file2.pick_file( { 'mode' : 'open', 'title' : offlineStrings.getString('main.transaction_import.title')} );
480 if (f && f.exists()) {
481 var i_file = new util.file(''); i_file._file = f;
482 file.write_content( 'truncate', i_file.get_content() );
484 var r = G.error.yns_alert(
485 offlineStrings.getFormattedString('main.transaction_import.delete.prompt', [f.leafName]),
486 offlineStrings.getString('main.transaction_import.success'),
487 offlineStrings.getString('common.yes'),
488 offlineStrings.getString('common.no'),
490 offlineStrings.getString('common.confirm')
503 G.auth.on_debug = function(action) {
506 G.window.open(urls.XUL_DEBUG_CONSOLE,'testconsole','chrome,resizable');
510 alert(offlineStrings.getString('main.on_debug.clear_cache'));
513 alert(offlineStrings.getString('main.on_debug.debug'));
519 // XML_HTTP_SERVER will get reset to G.auth.controller.view.server_prompt.value
521 /////////////////////////////////////////////////////////////////////////////
523 var version = CLIENT_VERSION;
524 if (CLIENT_STAMP.length == 0) {
525 version = 'versionless debug build';
526 document.getElementById('debug_gb').hidden = false;
530 if (G.pref && G.pref.getBoolPref('open-ils.debug_options')) {
531 document.getElementById('debug_gb').hidden = false;
536 // If we are showing the debugging frame then we consider this a debug build
537 // This could be a versionless build, a developer-pref enabled build, or otherwise
538 // If set this will enable all debugging commands, even if you normally don't have permission to use them
539 G.data.debug_build = !document.getElementById('debug_gb').hidden;
540 G.data.stash('debug_build');
542 var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
543 .getService(Components.interfaces.nsIXULAppInfo);
545 if (appInfo.ID == "staff-client@open-ils.org")
548 if (G.pref && G.pref.getBoolPref('app.update.enabled')) {
549 document.getElementById('check_upgrade_sep').hidden = false;
550 var upgrademenu = document.getElementById('check_upgrade');
551 upgrademenu.hidden = false;
552 G.upgradeCheck = function () {
553 var um = Components.classes["@mozilla.org/updates/update-manager;1"]
554 .getService(Components.interfaces.nsIUpdateManager);
555 var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
556 .createInstance(Components.interfaces.nsIUpdatePrompt);
558 if (um.activeUpdate && um.activeUpdate.state == "pending")
559 prompter.showUpdateDownloaded(um.activeUpdate);
561 prompter.checkForUpdates();
563 upgrademenu.addEventListener(
573 window.title = authStrings.getFormattedString('staff.auth.titlebar.label', version);
574 var x = document.getElementById('about_btn');
579 G.window.open('about.html','about','chrome,resizable,width=800,height=600');
580 } catch(E) { alert(E); }
585 var y = document.getElementById('new_window_btn');
589 if (G.data.session) {
590 new_tabs(Array('new'), null, null);
592 alert ( offlineStrings.getString('main.new_window_btn.login_first_warning') );
598 JSAN.use('util.mozilla');
599 var z = document.getElementById('locale_menupopup');
601 while (z.lastChild) z.removeChild(z.lastChild);
602 var locales = util.mozilla.chromeRegistry().getLocalesForPackage( String( location.href ).split(/\//)[2] );
603 var current_locale = util.mozilla.prefs().getCharPref('general.useragent.locale');
604 while (locales.hasMore()) {
605 var locale = locales.getNext();
606 var parts = locale.split(/-/);
609 label = locale + ' : ' + util.mozilla.languages().GetStringFromName(parts[0]);
610 if (parts.length > 1) {
612 label += ' (' + util.mozilla.regions().GetStringFromName(parts[1].toLowerCase()) + ')';
614 label += ' (' + parts[1] + ')';
620 var mi = document.createElement('menuitem');
621 mi.setAttribute('label',label);
622 mi.setAttribute('value',locale);
623 if (locale == current_locale) {
624 if (z.parentNode.tagName == 'menulist') {
625 mi.setAttribute('selected','true');
626 z.parentNode.setAttribute('label',label);
627 z.parentNode.setAttribute('value',locale);
633 var xx = document.getElementById('apply_locale_btn');
637 util.mozilla.change_locale(z.parentNode.value);
642 if ( found_ws_info_in_Achrome() && G.pref && G.pref.getBoolPref("open-ils.write_in_user_chrome_directory") ) {
643 //var hbox = x.parentNode; var b = document.createElement('button');
644 //b.setAttribute('label','Migrate legacy settings'); hbox.appendChild(b);
645 //b.addEventListener(
649 // handle_migration();
650 // } catch(E) { alert(E); }
654 if (window.confirm(offlineStrings.getString('main.settings.migrate'))) {
655 setTimeout( function() { handle_migration(); }, 0 );
659 window.addEventListener(
663 G.data.stash_retrieve();
664 if (typeof G.data.unsaved_data != 'undefined') {
665 if (G.data.unsaved_data > 0) {
666 var confirmation = window.confirm(offlineStrings.getString('menu.shutdown.unsaved_data_warning'));
673 G.data.unsaved_data = 0;
674 G.data.stash('unsaved_data');
683 @brief Stats for Offline Files / Transactions
686 var px = new util.file('pending_xacts');
687 document.getElementById('offline_message').setAttribute('style','display:none;');
688 if (px._file.exists()) {
689 document.getElementById('offline_message').setAttribute('style','background-color:red;display:block;font-weight:bold;padding:2px;');
690 document.getElementById('offline_import_btn').disabled = true;
694 var error = offlineStrings.getFormattedString('common.exception', [E, '']);
695 try { G.error.sdump('D_ERROR',error); } catch(E) { dump(error); }
698 dump('exiting main_init()\n');
701 function found_ws_info_in_Achrome() {
702 JSAN.use('util.file');
703 var f = new util.file();
704 var f_in_chrome = f.get('ws_info','chrome');
705 var path = f_in_chrome.exists() ? f_in_chrome.path : false;
710 function found_ws_info_in_Uchrome() {
711 JSAN.use('util.file');
712 var f = new util.file();
713 var f_in_uchrome = f.get('ws_info','uchrome');
714 var path = f_in_uchrome.exists() ? f_in_uchrome.path : false;
719 function handle_migration() {
720 if ( found_ws_info_in_Uchrome() ) {
721 alert(offlineStrings.getFormattedString('main.settings.migrate.failed', [found_ws_info_in_Uchrome(), found_ws_info_in_Achrome()])
724 var dirService = Components.classes["@mozilla.org/file/directory_service;1"].getService( Components.interfaces.nsIProperties );
725 var f_new = dirService.get( "UChrm", Components.interfaces.nsIFile );
726 var f_old = dirService.get( "AChrom", Components.interfaces.nsIFile );
727 f_old.append(myPackageDir); f_old.append("content"); f_old.append("conf");
728 if (window.confirm(offlineStrings.getFormattedString("main.settings.migrate.confirm", [f_old.path, f_new.path]))) {
729 var files = f_old.directoryEntries;
730 while (files.hasMoreElements()) {
731 var file = files.getNext();
732 var file2 = file.QueryInterface( Components.interfaces.nsILocalFile );
734 file2.moveTo( f_new, '' );
736 alert(offlineStrings.getFormattedString('main.settings.migrate.error', [file2.path, f_new.path]) + '\n');
739 location.href = location.href; // huh?
744 dump('exiting main/main.js\n');