1 dump('entering main/main.js\n');
7 var openTabs = new Array();
9 var tempFocusWindow = null;
11 function clear_the_cache() {
13 var cacheClass = Components.classes["@mozilla.org/network/cache-service;1"];
14 var cacheService = cacheClass.getService(Components.interfaces.nsICacheService);
15 cacheService.evictEntries(Components.interfaces.nsICache.STORE_ON_DISK);
16 cacheService.evictEntries(Components.interfaces.nsICache.STORE_IN_MEMORY);
18 dump(E+'\n');alert(E);
22 function toOpenWindowByType(inType, uri) { /* for Venkman */
24 var winopts = "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar";
25 window.open(uri, "_blank", winopts);
31 function start_debugger() {
34 try { start_venkman(); } catch(E) { alert(E); }
39 function start_inspector() {
42 try { inspectDOMDocument(); } catch(E) { alert(E); }
47 function start_chrome_list() {
50 try { startChromeList(); } catch(E) { alert(E); }
55 function start_js_shell() {
58 try { window.open('chrome://open_ils_staff_client/content/util/shell.html','shell','chrome,resizable,scrollbars'); } catch(E) { alert(E); }
63 function new_tabs(aTabList, aContinue) {
64 if(aTabList != null) {
65 openTabs = openTabs.concat(aTabList);
67 if(G.data.session) { // Just add to the list of stuff to open unless we are logged in
68 var targetwindow = null;
69 var focuswindow = null;
70 var focustab = {'focus' : true};
71 if(aContinue == true && tempWindow.closed == false) {
72 if(tempWindow.g == undefined || tempWindow.g.menu == undefined) {
79 targetwindow = tempWindow;
81 focuswindow = tempFocusWindow;
82 tempFocusWindow = null;
83 focustab = {'nofocus' : true};
85 else if(tempWindow != null) { // In theory, we are waiting on a setTimeout
86 if(tempWindow.closed == true) // But someone closed our window?
89 tempFocusWindow = null;
98 var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
99 getService(Components.interfaces.nsIWindowMediator);
100 // This may look out of place, but this is so we can continue this loop from down below
102 while(openTabs.length > 0) {
103 newTab = openTabs.shift();
104 if(newTab == 'new' || newTab == 'init') {
105 if(newTab != 'init' && openTabs.length > 0 && openTabs[0] != 'new') {
106 firstURL = openTabs.shift();
107 if(firstURL != 'tab') { // 'new' followed by 'tab' should be equal to 'init' in functionality, this should do that
109 firstURL = urls[firstURL];
111 firstURL = '&firstURL=' + window.escape(firstURL);
120 targetwindow = xulG.window.open(urls.XUL_MENU_FRAME
121 + '?server='+window.escape(G.data.server) + firstURL,
122 '_blank','chrome,resizable'
124 targetwindow.xulG = xulG;
125 if (focuswindow == null) {
126 focuswindow = targetwindow;
128 tempWindow = targetwindow;
129 tempFocusWindow = focuswindow;
132 new_tabs(null, true);
137 if(newTab == 'tab') {
140 else if(urls[newTab]) {
141 newTab = urls[newTab];
143 if(targetwindow != null) { // Already have a previous target window? Use it first.
144 if(targetwindow.g.menu.new_tab(newTab,focustab,null)) {
145 focustab = {'nofocus' : true};
149 var enumerator = wm.getEnumerator('eg_menu');
150 while(enumerator.hasMoreElements()) {
151 targetwindow = enumerator.getNext();
152 if(targetwindow.g.menu.new_tab(newTab,focustab,null)) {
153 focustab = {'nofocus' : true};
154 if (focuswindow == null) {
155 focuswindow = targetwindow;
160 // No windows found to add the tab to? Make a new one.
161 if(newTab == null) { // Were we making a "default" tab?
162 openTabs.unshift('init'); // 'init' does that for us!
165 openTabs.unshift('new',newTab);
169 if(focuswindow != null) {
175 // Returns false if we can't get an actual perm list
176 // Returns an array of perms with boolean has/hasn't flag
177 function get_menu_perms(indocument) {
178 // If we don't have our static perm list, and we have a remote window, go looking.
179 // We never need to look twice unless a dev is manually editing their files.
180 // Shame on them, they can restart the entire client ;)
181 if(typeof(get_menu_perms.perm_list) == 'undefined' && indocument != null)
183 get_menu_perms.perm_list = [ ];
184 var commands = indocument.getElementById('universal_cmds').getElementsByTagName('command');
185 for (var i = 0; i < commands.length; i++) {
186 if (commands[i].hasAttribute('perm')) {
187 get_menu_perms.perm_list = get_menu_perms.perm_list.concat(commands[i].getAttribute('perm').split(' '));
192 if(typeof(get_menu_perms.perm_list) == 'object') {
193 G.data.stash_retrieve();
194 if(!G.data.menu_perms) {
195 JSAN.use('util.network');
196 var network = new util.network();
197 var r = network.simple_request('BATCH_PERM_RETRIEVE_WORK_OU', [ G.data.session.key, get_menu_perms.perm_list ]);
199 r[p] = (typeof(r[p][0]) == 'number');
200 // Developer-enabled clients override permissions and always allow debugging
201 if(G.data.debug_build) {
202 r['DEBUG_CLIENT'] = true;
204 // If we have DEBUG_CLIENT (by force or otherwise) we can use debugging interfaces
205 // Doing this here because this function gets called at least once per login
206 // Including operator change
207 G.data.enable_debug = (r['DEBUG_CLIENT'] == true);
208 G.data.stash('enable_debug');
209 G.data.menu_perms = r;
210 G.data.stash('menu_perms');
212 return G.data.menu_perms;
217 // Returns a list (cached or from filesystem) of hotkey sets
218 function load_hotkey_sets() {
219 if(typeof(load_hotkey_sets.set_list) == 'undefined') {
220 load_hotkey_sets.set_list = [];
221 // We can't safely use util.file here because extensions aren't unpacked in Firefox 4+
222 // So instead we will use and parse information from a chrome:// URL
223 var hotkeysBase = 'chrome://open_ils_staff_client/skin/hotkeys/';
224 var ioService=Components.classes["@mozilla.org/network/io-service;1"]
225 .getService(Components.interfaces.nsIIOService);
226 var scriptableStream=Components
227 .classes["@mozilla.org/scriptableinputstream;1"]
228 .getService(Components.interfaces.nsIScriptableInputStream);
230 var channel=ioService.newChannel(hotkeysBase,null,null);
231 var input=channel.open();
233 scriptableStream.init(input);
235 while(input.available()) {
236 str+=scriptableStream.read(input.available());
239 scriptableStream.close();
241 // str now, in theory, has a list of files (and metadata) for our base chrome URL.
242 str = str.replace(/^(?!201: ).*$/gm,''); // Remove non-filename result lines
243 str = str.replace(/^(?!.*\.keyset).*$/gm,''); // Remove non-keyset file result lines
244 str = str.replace(/^201: (.*)\.keyset.*$/gm, "$1"); // Reduce keyset matches to just base names
245 // Split into an array
246 var files = str.trim().split(/[\r\n]+/g);
247 for (var i = 0; i < files.length; i++) {
248 if(files[i].length = 0) continue;
249 load_hotkey_sets.set_list.push(files[i]);
252 return load_hotkey_sets.set_list;
255 // Returns an array (cached or from filesystem) for a given hotkey set
256 function get_hotkey_array(keyset_name) {
257 if(typeof(get_hotkey_array.keyset_cache) == 'undefined') {
258 get_hotkey_array.keyset_cache = {};
260 if(get_hotkey_array.keyset_cache[keyset_name])
261 return get_hotkey_array.keyset_cache[keyset_name];
262 // We can't safely use util.file here because extensions aren't unpacked in Firefox 4+
263 // So instead we will use and parse information from a chrome:// URL
264 var hotkeysBase = 'chrome://open_ils_staff_client/skin/hotkeys/' + keyset_name + '.keyset';
265 var ioService=Components.classes["@mozilla.org/network/io-service;1"]
266 .getService(Components.interfaces.nsIIOService);
267 var scriptableStream=Components
268 .classes["@mozilla.org/scriptableinputstream;1"]
269 .getService(Components.interfaces.nsIScriptableInputStream);
271 var channel=ioService.newChannel(hotkeysBase,null,null);
272 var input=channel.open();
274 scriptableStream.init(input);
276 while(input.available()) {
277 keyset_raw+=scriptableStream.read(input.available());
280 scriptableStream.close();
285 var keyset_lines = keyset_raw.trim().split("\n");
286 for(var line = 0; line < keyset_lines.length; line++) {
287 // Grab line, strip comments, strip leading/trailing whitespace
288 var curline = keyset_lines[line].replace(/\s*#.*$/,'').trim();
289 if(curline == "") continue; // Skip empty lines
291 var split_line = curline.split(',');
292 // We need at least 3 elements. Command, modifiers, keycode.
293 if(split_line.length < 3) continue;
295 split_line[0] = split_line[0].trim();
296 split_line[1] = split_line[1].trim();
297 split_line[2] = split_line[2].trim();
298 if(split_line.length > 3)
299 split_line[3] = split_line[3].trim();
300 // Skip empty commands
301 if(split_line[0] == "") continue;
303 tempArray.push(split_line);
305 get_hotkey_array.keyset_cache[keyset_name] = tempArray;
309 function main_init() {
310 dump('entering main_init()\n');
313 if("arguments" in window && window.arguments.length > 0 && window.arguments[0].wrappedJSObject != undefined && window.arguments[0].wrappedJSObject.openTabs != undefined) {
314 openTabs = openTabs.concat(window.arguments[0].wrappedJSObject.openTabs);
317 // Disable commands that we can't do anything with right now
318 if(typeof start_venkman != 'function') {
319 document.getElementById('cmd_debugger').setAttribute('disabled','true');
321 if(typeof inspectDOMDocument != 'function') {
322 document.getElementById('cmd_inspector').setAttribute('disabled','true');
324 if(typeof startChromeList != 'function') {
325 document.getElementById('cmd_chrome_list').setAttribute('disabled','true');
328 // Now we can safely load the strings without the cache getting wiped
329 offlineStrings = document.getElementById('offlineStrings');
330 authStrings = document.getElementById('authStrings');
332 if (typeof JSAN == 'undefined') {
334 offlineStrings.getString('common.jsan.missing')
337 /////////////////////////////////////////////////////////////////////////////
339 JSAN.errorLevel = "die"; // none, warn, or die
340 JSAN.addRepository('..');
342 //JSAN.use('test.test'); test.test.hello_world();
347 G.pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
348 G.pref.QueryInterface(Components.interfaces.nsIPrefBranch2);
350 JSAN.use('util.error');
351 G.error = new util.error();
352 G.error.sdump('D_ERROR', offlineStrings.getString('main.testing'));
354 JSAN.use('util.window');
355 G.window = new util.window();
357 JSAN.use('auth.controller');
358 G.auth = new auth.controller( { 'window' : mw } );
360 JSAN.use('OpenILS.data');
361 G.data = new OpenILS.data();
362 G.data.on_error = G.auth.logoff;
364 JSAN.use('util.file');
365 G.file = new util.file();
367 G.file.get('ws_info');
368 G.ws_info = G.file.get_object(); G.file.close();
372 G.data.ws_info = G.ws_info; G.data.stash('ws_info');
374 G.auth.on_login = function() {
376 var url = G.auth.controller.view.server_prompt.value.match(/^[^\/]*/).toString() || urls.remote;
378 G.data.server_unadorned = url; G.data.stash('server_unadorned'); G.data.stash_retrieve();
380 if (! url.match( '^(http|https)://' ) ) { url = 'http://' + url; }
382 G.data.server = url; G.data.stash('server');
383 G.data.session = { 'key' : G.auth.session.key, 'auth' : G.auth.session.authtime }; G.data.stash('session');
384 G.data.stash_retrieve();
386 var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
387 var cookieUriSSL = ios.newURI("https://" + G.data.server_unadorned, null, null);
388 var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
390 cookieSvc.setCookieString(cookieUriSSL, null, "ses="+G.data.session.key + "; secure;", null);
393 alert(offlineStrings.getFormattedString(main.session_cookie.error, [E]));
404 if (G.data.ws_info && G.data.ws_info[G.auth.controller.view.server_prompt.value]) {
405 JSAN.use('util.widgets');
406 var deck = document.getElementById('progress_space');
407 util.widgets.remove_children( deck );
408 var iframe = document.createElement('iframe'); deck.appendChild(iframe);
409 iframe.setAttribute( 'src', urls.XUL_LOGIN_DATA );
410 iframe.contentWindow.xulG = xulG;
411 G.data_xul = iframe.contentWindow;
414 var deck = G.auth.controller.view.ws_deck;
415 JSAN.use('util.widgets'); util.widgets.remove_children('ws_deck');
416 var iframe = document.createElement('iframe'); deck.appendChild(iframe);
417 iframe.setAttribute( 'src', urls.XUL_WORKSTATION_INFO );
418 iframe.contentWindow.xulG = xulG;
419 deck.selectedIndex = deck.childNodes.length - 1;
423 G.auth.on_standalone = function() {
425 G.window.open(urls.XUL_STANDALONE,'Offline','chrome,resizable');
431 G.auth.on_standalone_export = function() {
433 JSAN.use('util.file'); var file = new util.file('pending_xacts');
434 if (file._file.exists()) {
435 var file2 = new util.file('');
436 var f = file2.pick_file( { 'mode' : 'save', 'title' : offlineStrings.getString('main.transaction_export.title') } );
439 var r = G.error.yns_alert(
440 offlineStrings.getFormattedString('main.transaction_export.prompt', [f.leafName]),
441 offlineStrings.getString('main.transaction_export.prompt.title'),
442 offlineStrings.getString('common.yes'),
443 offlineStrings.getString('common.no'),
445 offlineStrings.getString('common.confirm')
447 if (r != 0) { file.close(); return; }
449 var e_file = new util.file(''); e_file._file = f;
450 e_file.write_content( 'truncate', file.get_content() );
452 var r = G.error.yns_alert(
453 offlineStrings.getFormattedString('main.transaction_export.success.prompt', [f.leafName]),
454 offlineStrings.getString('main.transaction_export.success.title'),
455 offlineStrings.getString('common.yes'),
456 offlineStrings.getString('common.no'),
458 offlineStrings.getString('common.confirm')
462 var filename = 'pending_xacts_exported_' + new Date().getTime();
463 var t_file = new util.file(filename);
464 while (t_file._file.exists()) {
465 filename = 'pending_xacts_' + new Date().getTime() + '.exported';
466 t_file = new util.file(filename);
468 throw(offlineStrings.getString('main.transaction_export.filename.error'));
471 file.close(); file = new util.file('pending_xacts'); // prevents a bug with .moveTo below
472 file._file.moveTo(null,filename);
474 alert(offlineStrings.getString('main.transaction_export.duplicate.warning'));
477 alert(offlineStrings.getString('main.transaction_export.no_filename.error'));
480 alert(offlineStrings.getString('main.transaction_export.no_transactions.error'));
488 G.auth.on_standalone_import = function() {
490 JSAN.use('util.file'); var file = new util.file('pending_xacts');
491 if (file._file.exists()) {
492 alert(offlineStrings.getString('main.transaction_import.outstanding.error'));
494 var file2 = new util.file('');
495 var f = file2.pick_file( { 'mode' : 'open', 'title' : offlineStrings.getString('main.transaction_import.title')} );
496 if (f && f.exists()) {
497 var i_file = new util.file(''); i_file._file = f;
498 file.write_content( 'truncate', i_file.get_content() );
500 var r = G.error.yns_alert(
501 offlineStrings.getFormattedString('main.transaction_import.delete.prompt', [f.leafName]),
502 offlineStrings.getString('main.transaction_import.success'),
503 offlineStrings.getString('common.yes'),
504 offlineStrings.getString('common.no'),
506 offlineStrings.getString('common.confirm')
519 G.auth.on_debug = function(action) {
522 G.window.open(urls.XUL_DEBUG_CONSOLE,'testconsole','chrome,resizable');
526 alert(offlineStrings.getString('main.on_debug.clear_cache'));
529 alert(offlineStrings.getString('main.on_debug.debug'));
535 // XML_HTTP_SERVER will get reset to G.auth.controller.view.server_prompt.value
537 /////////////////////////////////////////////////////////////////////////////
539 var version = CLIENT_VERSION;
540 if (CLIENT_STAMP.length == 0) {
541 version = 'versionless debug build';
542 document.getElementById('debug_gb').hidden = false;
546 if (G.pref && G.pref.getBoolPref('open-ils.debug_options')) {
547 document.getElementById('debug_gb').hidden = false;
552 // If we are showing the debugging frame then we consider this a debug build
553 // This could be a versionless build, a developer-pref enabled build, or otherwise
554 // If set this will enable all debugging commands, even if you normally don't have permission to use them
555 G.data.debug_build = !document.getElementById('debug_gb').hidden;
556 G.data.stash('debug_build');
558 var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
559 .getService(Components.interfaces.nsIXULAppInfo);
561 if (appInfo.ID == "staff-client@open-ils.org")
564 if (G.pref && G.pref.getBoolPref('app.update.enabled')) {
565 document.getElementById('check_upgrade_sep').hidden = false;
566 var upgrademenu = document.getElementById('check_upgrade');
567 upgrademenu.hidden = false;
568 G.upgradeCheck = function () {
569 var um = Components.classes["@mozilla.org/updates/update-manager;1"]
570 .getService(Components.interfaces.nsIUpdateManager);
571 var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
572 .createInstance(Components.interfaces.nsIUpdatePrompt);
574 if (um.activeUpdate && um.activeUpdate.state == "pending")
575 prompter.showUpdateDownloaded(um.activeUpdate);
577 prompter.checkForUpdates();
579 upgrademenu.addEventListener(
589 window.title = authStrings.getFormattedString('staff.auth.titlebar.label', version);
590 var x = document.getElementById('about_btn');
595 G.window.open('about.html','about','chrome,resizable,width=800,height=600');
596 } catch(E) { alert(E); }
601 var y = document.getElementById('new_window_btn');
605 if (G.data.session) {
606 new_tabs(Array('new'), null, null);
608 alert ( offlineStrings.getString('main.new_window_btn.login_first_warning') );
614 JSAN.use('util.mozilla');
615 var z = document.getElementById('locale_menupopup');
617 while (z.lastChild) z.removeChild(z.lastChild);
618 var locales = util.mozilla.chromeRegistry().getLocalesForPackage( String( location.href ).split(/\//)[2] );
619 var current_locale = util.mozilla.prefs().getCharPref('general.useragent.locale');
620 while (locales.hasMore()) {
621 var locale = locales.getNext();
622 var parts = locale.split(/-/);
625 label = locale + ' : ' + util.mozilla.languages().GetStringFromName(parts[0]);
626 if (parts.length > 1) {
628 label += ' (' + util.mozilla.regions().GetStringFromName(parts[1].toLowerCase()) + ')';
630 label += ' (' + parts[1] + ')';
636 var mi = document.createElement('menuitem');
637 mi.setAttribute('label',label);
638 mi.setAttribute('value',locale);
639 if (locale == current_locale) {
640 if (z.parentNode.tagName == 'menulist') {
641 mi.setAttribute('selected','true');
642 z.parentNode.setAttribute('label',label);
643 z.parentNode.setAttribute('value',locale);
649 var xx = document.getElementById('apply_locale_btn');
653 util.mozilla.change_locale(z.parentNode.value);
658 if ( found_ws_info_in_Achrome() && G.pref && G.pref.getBoolPref("open-ils.write_in_user_chrome_directory") ) {
659 //var hbox = x.parentNode; var b = document.createElement('button');
660 //b.setAttribute('label','Migrate legacy settings'); hbox.appendChild(b);
661 //b.addEventListener(
665 // handle_migration();
666 // } catch(E) { alert(E); }
670 if (window.confirm(offlineStrings.getString('main.settings.migrate'))) {
671 setTimeout( function() { handle_migration(); }, 0 );
675 window.addEventListener(
679 G.data.stash_retrieve();
680 if (typeof G.data.unsaved_data != 'undefined') {
681 if (G.data.unsaved_data > 0) {
682 var confirmation = window.confirm(offlineStrings.getString('menu.shutdown.unsaved_data_warning'));
689 G.data.unsaved_data = 0;
690 G.data.stash('unsaved_data');
699 @brief Stats for Offline Files / Transactions
702 var px = new util.file('pending_xacts');
703 document.getElementById('offline_message').setAttribute('style','display:none;');
704 if (px._file.exists()) {
705 document.getElementById('offline_message').setAttribute('style','background-color:red;display:block;font-weight:bold;padding:2px;');
706 document.getElementById('offline_import_btn').disabled = true;
709 // Attempt auto-login, if provided
710 if("arguments" in window && window.arguments.length > 0 && window.arguments[0].wrappedJSObject != undefined && window.arguments[0].wrappedJSObject.loginInfo != undefined) {
711 auto_login(window.arguments[0].wrappedJSObject.loginInfo);
712 // Regardless of success, clear that variable now, so we don't possibly have passwords hanging around.
713 window.arguments[0].wrappedJSObject.loginInfo = null;
717 var error = offlineStrings.getFormattedString('common.exception', [E, '']);
718 try { G.error.sdump('D_ERROR',error); } catch(E) { dump(error); }
721 dump('exiting main_init()\n');
724 function found_ws_info_in_Achrome() {
725 JSAN.use('util.file');
726 var f = new util.file();
727 var f_in_chrome = f.get('ws_info','chrome');
728 var path = f_in_chrome.exists() ? f_in_chrome.path : false;
733 function found_ws_info_in_Uchrome() {
734 JSAN.use('util.file');
735 var f = new util.file();
736 var f_in_uchrome = f.get('ws_info','uchrome');
737 var path = f_in_uchrome.exists() ? f_in_uchrome.path : false;
742 function handle_migration() {
743 if ( found_ws_info_in_Uchrome() ) {
744 alert(offlineStrings.getFormattedString('main.settings.migrate.failed', [found_ws_info_in_Uchrome(), found_ws_info_in_Achrome()])
747 var dirService = Components.classes["@mozilla.org/file/directory_service;1"].getService( Components.interfaces.nsIProperties );
748 var f_new = dirService.get( "UChrm", Components.interfaces.nsIFile );
749 var f_old = dirService.get( "AChrom", Components.interfaces.nsIFile );
750 f_old.append(myPackageDir); f_old.append("content"); f_old.append("conf");
751 if (window.confirm(offlineStrings.getFormattedString("main.settings.migrate.confirm", [f_old.path, f_new.path]))) {
752 var files = f_old.directoryEntries;
753 while (files.hasMoreElements()) {
754 var file = files.getNext();
755 var file2 = file.QueryInterface( Components.interfaces.nsILocalFile );
757 file2.moveTo( f_new, '' );
759 alert(offlineStrings.getFormattedString('main.settings.migrate.error', [file2.path, f_new.path]) + '\n');
762 location.href = location.href; // huh?
767 function auto_login(loginInfo) {
768 G.data.stash_retrieve();
769 if(G.data.session) return; // We are logged in. No auto-logoff supported.
770 if(loginInfo.host) G.auth.controller.view.server_prompt.value = loginInfo.host;
771 if(loginInfo.user) G.auth.controller.view.name_prompt.value = loginInfo.user;
772 if(loginInfo.passwd) G.auth.controller.view.password_prompt.value = loginInfo.passwd;
773 if(loginInfo.host && loginInfo.user && loginInfo.passwd && G.data.ws_info && G.data.ws_info[loginInfo.host]) {
778 dump('exiting main/main.js\n');