/* ***** BEGIN LICENSE BLOCK ***** Copyright © 2009 Center for History and New Media George Mason University, Fairfax, Virginia, USA http://zotero.org This file is part of Zotero. Zotero is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Zotero is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Zotero. If not, see . ***** END LICENSE BLOCK ***** */ Components.utils.import("resource://gre/modules/Services.jsm"); /** * This object contains the various functions for the interface */ const ZoteroStandalone = new function() { const FONT_SIZES = ["1.0", "1.15", "1.3", "1.5", "1.7", "1.9", "2.1"]; //const NOTE_FONT_SIZES = ["11", "12", "13", "14", "18", "24", "36", "48", "64", "72", "96"]; const NOTE_FONT_SIZE_DEFAULT = "12"; /** * Run when standalone window first opens */ this.onLoad = function() { // Fix window without menubar/titlebar when Zotero is closed in full-screen mode in OS X 10.11+ if (Zotero.isMac && window.document.documentElement.getAttribute('sizemode') == 'fullscreen') { window.document.documentElement.setAttribute('sizemode', 'normal'); } if (Zotero.isMac) { // Create tab bar by default document.documentElement.setAttribute('drawintitlebar', true); document.documentElement.setAttribute('tabsintitlebar', true); document.documentElement.setAttribute('chromemargin', '0,-1,-1,-1'); } this.switchMenuType('library'); this._notifierID = Zotero.Notifier.registerObserver( { notify: async (action, type, ids, extraData) => { if (action == 'select') { // Reader doesn't have tabID yet setTimeout(async () => { // Item and other things might not be loaded yet when reopening tabs await Zotero.Schema.schemaUpdatePromise; this.updateQuickCopyOptions(); }, 0); // "library" or "reader" this.switchMenuType(extraData[ids[0]].type); setTimeout(() => ZoteroPane.updateToolbarPosition(), 0); } } }, ['tab'], 'tab' ); Zotero.Promise.try(function () { if(!Zotero) { throw true; } if(Zotero.initializationPromise.isPending()) { Zotero.showZoteroPaneProgressMeter(); } return Zotero.initializationPromise; }) .then(async function () { document.getElementById('key_copyCitation') .setAttribute('key', Zotero.Keys.getKeyForCommand('copySelectedItemCitationsToClipboard')); document.getElementById('key_copyBibliography') .setAttribute('key', Zotero.Keys.getKeyForCommand('copySelectedItemsToClipboard')); ZoteroStandalone.DebugOutput.init(); Zotero.hideZoteroPaneOverlays(); ZoteroPane.init(); ZoteroPane.makeVisible(); // Don't ask before handing http and https URIs var eps = Components.classes['@mozilla.org/uriloader/external-protocol-service;1'] .getService(Components.interfaces.nsIExternalProtocolService); var hs = Components.classes["@mozilla.org/uriloader/handler-service;1"] .getService(Components.interfaces.nsIHandlerService); for (let scheme of ["http", "https"]) { var handlerInfo = eps.getProtocolHandlerInfo(scheme); handlerInfo.preferredAction = Components.interfaces.nsIHandlerInfo.useSystemDefault; handlerInfo.alwaysAskBeforeHandling = false; hs.store(handlerInfo); } // Add add-on listeners (not yet hooked up) Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false); Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false); Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false); Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false); Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false); }) .catch(function (e) { try { Zotero.debug(e, 1); } catch (e) {} Components.utils.reportError(e); ZoteroPane.displayStartupError(); window.close(); return; }); // Switch to library tab if dragging over one or more PDF files window.addEventListener('dragover', function (event) { // TODO: Consider allowing more (or all) file types, although shouldn't interfere with image dragging to note editor if (Zotero_Tabs.selectedID != 'zotero-pane' && event.dataTransfer.items && event.dataTransfer.items.length && !Array.from(event.dataTransfer.items).find(x => x.type != 'application/pdf')) { Zotero_Tabs.select('zotero-pane'); } }, true); } this.switchMenuType = function (type) { document.querySelectorAll('.menu-type-library, .menu-type-reader').forEach(el => el.hidden = true); document.querySelectorAll('.menu-type-' + type).forEach(el => el.hidden = false); }; this.onReaderCmd = function (cmd) { let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID); reader.menuCmd(cmd); }; this.onFileMenuOpen = function () { var active = false; try { let zp = Zotero.getActiveZoteroPane(); if (zp) { active = !!zp.getSelectedItems().filter((item) => { return item.isAttachment() || (item.isRegularItem() && item.getAttachments().length); }).length; } } catch (e) {} this.updateMenuItemEnabled('manage-attachments-menu', active); // PDF annotation transfer ("Import Annotation"/"Store Annotations in File") let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID); if (reader) { let item = Zotero.Items.get(reader.itemID); let library = Zotero.Libraries.get(item.libraryID); if (item // Don't allow annotation transfer in group libraries && library.libraryType == 'user' && library.editable && !(item.deleted || item.parentItem && item.parentItem.deleted)) { let annotations = item.getAnnotations(); let canTransferFromPDF = annotations.find(x => x.annotationIsExternal); this.updateMenuItemEnabled('menu_transferFromPDF', canTransferFromPDF); } else { this.updateMenuItemEnabled('menu_transferFromPDF', false); } } // TEMP: Quick implementation try { let menuitem = document.getElementById('menu_export_files'); let sep = menuitem.nextSibling; let zp = Zotero.getActiveZoteroPane(); if (zp && !reader) { let numFiles = zp.getSelectedItems().reduce((num, item) => { if (item.isPDFAttachment()) { return num + 1; } if (item.isRegularItem()) { return num + item.numPDFAttachments(); } return num; }, 0); if (numFiles) { menuitem.hidden = false; sep.hidden = false; if (numFiles == 1) { menuitem.label = 'Export PDF…'; } else { menuitem.label = 'Export PDFs…'; } } else { menuitem.hidden = true; sep.hidden = true; } } else { menuitem.hidden = true; sep.hidden = true; } } catch (e) { Zotero.logError(e); } }; /** * Builds new item menu */ this.buildNewItemMenu = function() { var addMenu = document.getElementById('menu_NewItemPopup'); // Remove all nodes so we can regenerate while(addMenu.hasChildNodes()) addMenu.removeChild(addMenu.firstChild); var typeSets = [Zotero.ItemTypes.getPrimaryTypes(), Zotero.ItemTypes.getSecondaryTypes()]; for(var j=0; j { return item.isLinkedFileAttachment() || (item.isRegularItem() && item.getAttachments() .map(id => Zotero.Items.get(id)) .some(att => att.isLinkedFileAttachment())); }).length; } } catch (e) {} this.updateMenuItemEnabled('file-menuitem-convert-to-stored', active); }; this.onManageAttachmentsMenuItemClick = function (event) { var menuitem = event.originalTarget; var id = menuitem.id; var prefix = 'file-menuitem-'; if (menuitem.disabled || !id.startsWith(prefix)) { return; } id = id.substr(prefix.length); switch (id) { case 'convert-to-stored': ZoteroPane.convertLinkedFilesToStoredFiles(); break; } }; this.updateQuickCopyOptions = function () { var selected = []; let win = Zotero.getMainWindow(); if (win) { if (win.Zotero_Tabs.selectedID == 'zotero-pane') { try { selected = win.ZoteroPane.getSelectedItems(); } catch (e) { } win.ZoteroPane.updateQuickCopyCommands(selected); } else { let reader = Zotero.Reader.getByTabID(win.Zotero_Tabs.selectedID); if (reader) { let item = Zotero.Items.get(reader.itemID); selected = item.parentItem && [item.parentItem] || []; item = item.parentItem || item; win.ZoteroPane.updateQuickCopyCommands([item]); } } } var format = Zotero.QuickCopy.getFormatFromURL(Zotero.QuickCopy.lastActiveURL); var exportingNotes = selected.every(item => item.isNote() || item.isAttachment()); if (exportingNotes) { format = Zotero.QuickCopy.getNoteFormat(); } format = Zotero.QuickCopy.unserializeSetting(format); var copyCitation = document.getElementById('menu_copyCitation'); var copyBibliography = document.getElementById('menu_copyBibliography'); var copyExport = document.getElementById('menu_copyExport'); var copyNote = document.getElementById('menu_copyNote'); copyCitation.hidden = !selected.length || format.mode != 'bibliography'; copyBibliography.hidden = !selected.length || format.mode != 'bibliography'; copyExport.hidden = !selected.length || format.mode != 'export' || exportingNotes; copyNote.hidden = !selected.length || format.mode != 'export' || !exportingNotes; if (format.mode == 'export') { try { let obj = Zotero.Translators.get(format.id); if (obj) { copyExport.label = Zotero.getString('quickCopy.copyAs', obj.label); } else { copyExport.hidden = true; } } catch (e) { if (!(e instanceof Zotero.Exception.UnloadedDataException && e.dataType == 'translators')) { Zotero.logError(e); } copyExport.hidden = true; } } }; this.onGoMenuOpen = function () { var keyBack = document.getElementById('key_back'); var keyForward = document.getElementById('key_forward'); if (Zotero.isMac) { keyBack.setAttribute('key', '['); keyBack.setAttribute('modifiers', 'meta'); keyForward.setAttribute('key', ']'); keyForward.setAttribute('modifiers', 'meta'); } else { keyBack.setAttribute('keycode', 'VK_LEFT'); keyBack.setAttribute('modifiers', 'alt'); keyForward.setAttribute('keycode', 'VK_RIGHT'); keyForward.setAttribute('modifiers', 'alt'); } // `key` attribute needs to be dynamically set for `menuitem` when // the key changes after DOM initialization var menuItemBack = document.getElementById('go-menuitem-back'); var menuItemForward = document.getElementById('go-menuitem-forward'); menuItemBack.setAttribute('key', 'key_back'); menuItemForward.setAttribute('key', 'key_forward'); var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID); if (reader) { this.updateMenuItemEnabled('go-menuitem-first-page', reader.allowNavigateFirstPage()); this.updateMenuItemEnabled('go-menuitem-last-page', reader.allowNavigateLastPage()); this.updateMenuItemEnabled('go-menuitem-back', reader.allowNavigateBack()); this.updateMenuItemEnabled('go-menuitem-forward', reader.allowNavigateForward()); } }; this.onViewMenuOpen = function () { // PDF Reader var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID); if (reader) { var { state } = reader; this.updateMenuItemCheckmark('view-menuitem-vertical-scrolling', state.scrollMode == 0); this.updateMenuItemCheckmark('view-menuitem-horizontal-scrolling', state.scrollMode == 1); this.updateMenuItemCheckmark('view-menuitem-wrapped-scrolling', state.scrollMode == 2); this.updateMenuItemCheckmark('view-menuitem-no-spreads', state.spreadMode == 0); this.updateMenuItemCheckmark('view-menuitem-odd-spreads', state.spreadMode == 1); this.updateMenuItemCheckmark('view-menuitem-even-spreads', state.spreadMode == 2); this.updateMenuItemCheckmark('view-menuitem-hand-tool', reader.isHandToolActive()); this.updateMenuItemCheckmark('view-menuitem-zoom-auto', reader.isZoomAutoActive()); this.updateMenuItemCheckmark('view-menuitem-zoom-page-width', reader.isZoomPageWidthActive()); this.updateMenuItemCheckmark('view-menuitem-zoom-page-height', reader.isZoomPageHeightActive()); } // Layout mode var mode = Zotero.Prefs.get('layout'); this.updateMenuItemCheckmark('view-menuitem-standard', mode != 'stacked'); this.updateMenuItemCheckmark('view-menuitem-stacked', mode == 'stacked'); // Panes this.updateMenuItemCheckmark( 'view-menuitem-collections-pane', document.getElementById('zotero-collections-pane').getAttribute('collapsed') != 'true' ); this.updateMenuItemCheckmark( 'view-menuitem-item-pane', document.getElementById('zotero-item-pane').getAttribute('collapsed') != 'true' ); this.updateMenuItemCheckmark( 'view-menuitem-tag-selector', document.getElementById('zotero-tag-selector-container').getAttribute('collapsed') != 'true' ); // Font size var fontSize = Zotero.Prefs.get('fontSize'); this.updateMenuItemEnabled('view-menuitem-font-size-bigger', fontSize < FONT_SIZES[FONT_SIZES.length - 1]); this.updateMenuItemEnabled('view-menuitem-font-size-smaller', fontSize > FONT_SIZES[0]); this.updateMenuItemEnabled('view-menuitem-font-size-reset', fontSize != FONT_SIZES[0]); var noteFontSize = Zotero.Prefs.get('note.fontSize'); for (let menuitem of document.querySelectorAll(`#note-font-size-menu menuitem`)) { if (parseInt(menuitem.getAttribute('label')) == noteFontSize) { menuitem.setAttribute('checked', true); } else { menuitem.removeAttribute('checked'); } } this.updateMenuItemEnabled( 'view-menuitem-note-font-size-reset', noteFontSize != NOTE_FONT_SIZE_DEFAULT ); // Recursive collections this.updateMenuItemCheckmark( 'view-menuitem-recursive-collections', Zotero.Prefs.get('recursiveCollections') ); }; this.onViewMenuItemClick = function (event) { var menuitem = event.originalTarget; var id = menuitem.id; var prefix = 'view-menuitem-'; if (menuitem.disabled || !id.startsWith(prefix)) { return; } id = id.substr(prefix.length); switch (id) { case 'standard': Zotero.Prefs.set('layout', 'standard'); break; case 'stacked': Zotero.Prefs.set('layout', 'stacked'); break; case 'collections-pane': var collectionsPane = document.getElementById('zotero-collections-pane'); // Show if (collectionsPane.getAttribute('collapsed') == 'true') { document.getElementById('zotero-collections-splitter').setAttribute('state', 'open'); collectionsPane.setAttribute('collapsed', false); } // Hide else { document.getElementById('zotero-collections-splitter').setAttribute('state', 'collapsed'); collectionsPane.setAttribute('collapsed', true); } ZoteroPane.updateToolbarPosition(); break; case 'item-pane': var itemPane = document.getElementById('zotero-item-pane'); // Show if (itemPane.getAttribute('collapsed') == 'true') { document.getElementById('zotero-items-splitter').setAttribute('state', 'open'); itemPane.setAttribute('collapsed', false); } // Hide else { document.getElementById('zotero-items-splitter').setAttribute('state', 'collapsed'); itemPane.setAttribute('collapsed', true); } ZoteroPane.updateToolbarPosition(); break; case 'tag-selector': ZoteroPane.toggleTagSelector(); break; case 'font-size-bigger': increaseFontSize('fontSize', FONT_SIZES); break; case 'font-size-smaller': decreaseFontSize('fontSize', FONT_SIZES); break; case 'font-size-reset': Zotero.Prefs.clear('fontSize'); break; /*case 'note-font-size-bigger': increaseFontSize('note.fontSize', NOTE_FONT_SIZES); break; case 'note-font-size-smaller': decreaseFontSize('note.fontSize', NOTE_FONT_SIZES); break; */ case 'note-font-size-reset': Zotero.Prefs.clear('note.fontSize'); break; case 'recursive-collections': this.toggleBooleanPref('recursiveCollections'); break; } }; this.updateMenuItemCheckmark = function (id, checked) { var menuitem = document.getElementById(id); if (checked) { menuitem.setAttribute('checked', true); } else { menuitem.removeAttribute('checked'); } }; this.updateMenuItemEnabled = function (id, enabled) { var menuitem = document.getElementById(id); if (enabled) { menuitem.removeAttribute('disabled'); } else { menuitem.setAttribute('disabled', true); } }; this.toggleBooleanPref = function (pref) { Zotero.Prefs.set(pref, !Zotero.Prefs.get(pref)); }; function decreaseFontSize(pref, sizes) { var fontSize = Zotero.Prefs.get(pref); var lastSize = fontSize; // Get the highest font size below the current one for (let i = sizes.length - 1; i >= 0; i--) { if (fontSize > sizes[i]) { lastSize = sizes[i]; break; } } Zotero.Prefs.set(pref, lastSize); } function increaseFontSize(pref, sizes) { var fontSize = Zotero.Prefs.get(pref); var lastSize = fontSize; // Get the font size above the current one for (let i = 0; i < sizes.length; i++) { if (sizes[i] > fontSize) { lastSize = sizes[i]; break; } } Zotero.Prefs.set(pref, lastSize); } this.updateNoteFontSize = function (event) { var size = event.originalTarget.getAttribute('label'); Zotero.Prefs.set('note.fontSize', size); }; this.promptForRestart = function () { // Prompt to restart var ps = Services.prompt; var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING + ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING; var index = ps.confirmEx( null, Zotero.getString('general.restartRequired'), Zotero.getString('general.restartRequiredForChange', [ZOTERO_CONFIG.CLIENT_NAME]), buttonFlags, Zotero.getString('general.restartNow'), Zotero.getString('general.restartLater'), null, null, {} ); if (index == 0) { Zotero.Utilities.Internal.quitZotero(true); } }; this.updateAddonsPane = function (doc) { // Unsigned add-on warnings are hidden by default in extensions.css (via style rules added // by fetch_xulrunner.sh), but allow other warnings function updateExtensions () { var addonList = doc.getElementById('addon-list'); for (let i = 0; i < addonList.itemCount; i++) { let richListItem = addonList.getItemAtIndex(i); let container = doc.getAnonymousElementByAttribute( richListItem, 'anonid', 'warning-container' ); if (container) { let link = doc.getAnonymousElementByAttribute( richListItem, 'anonid', 'warning-link' ); if (link) { if (!link.href.includes('unsigned-addons')) { container.classList.add('allowed-warning'); } } } } } doc.getElementById('category-extension').onclick = updateExtensions; setTimeout(updateExtensions); } /** * Handles help menu requests */ this.openHelp = function(type) { Components.utils.import("resource://zotero/config.js"); switch (type) { case "troubleshooting": ZoteroPane.loadURI(ZOTERO_CONFIG.TROUBLESHOOTING_URL); break; case "feedback": ZoteroPane.loadURI(ZOTERO_CONFIG.FEEDBACK_URL); break; case "connectors": ZoteroPane.loadURI(ZOTERO_CONFIG.CONNECTORS_URL); break; default: ZoteroPane.loadURI(ZOTERO_CONFIG.SUPPORT_URL); } } /** * Checks for updates */ this.checkForUpdates = function() { window.open('chrome://mozapps/content/update/updates.xul', 'updateChecker', 'chrome,centerscreen'); } /** * Called before standalone window is closed */ this.onUnload = function() { Zotero.Notifier.unregisterObserver(this._notifierID); ZoteroPane.destroy(); } } ZoteroStandalone.DebugOutput = { _timer: null, init: function () { var storing = Zotero.Debug.storing; this._showMenu(); this.update(); }, toggleStore: function () { Zotero.Debug.setStore(!Zotero.Debug.storing); }, update: function () { var enabled = Zotero.Debug.storing; var lines = Zotero.Debug.count(); var empty = lines == 0; // Show "Submit" when enabled, but leave disabled until there's output var menuitem = document.getElementById('debug-output-submit'); menuitem.hidden = !enabled && empty; menuitem.disabled = empty; // Toggle between "Enable" and "Disable" menuitem = document.getElementById('debug-output-enable-disable'); menuitem.label = Zotero.getString('general.' + (enabled ? 'disable' : 'enable')); // Update line count var str = Zotero.getString('zotero.debugOutputLogging.linesLogged', lines, lines); document.getElementById('debug-output-status').label = str; // Enable "Clear" when there's output document.getElementById('debug-output-clear').disabled = empty; }, submit: function () { // 'Zotero' isn't defined yet when this function is created, so do it inline return Zotero.Promise.coroutine(function* () { Zotero.debug("Submitting debug output"); Components.utils.import("resource://zotero/config.js"); var url = ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1"; var output = yield Zotero.Debug.get( Zotero.Prefs.get('debug.store.submitSize'), Zotero.Prefs.get('debug.store.submitLineLength') ); Zotero.Debug.setStore(false); var ps = Services.prompt; try { var xmlhttp = yield Zotero.HTTP.request( "POST", url, { compressBody: true, body: output, logBodyLength: 30, timeout: 15000, requestObserver: function (req) { // Don't fail during tests, with fake XHR if (!req.channel) { return; } req.channel.notificationCallbacks = { onProgress: function (request, progress, progressMax) {}, // nsIInterfaceRequestor getInterface: function (iid) { try { return this.QueryInterface(iid); } catch (e) { throw Components.results.NS_NOINTERFACE; } }, QueryInterface: function(iid) { if (iid.equals(Components.interfaces.nsISupports) || iid.equals(Components.interfaces.nsIInterfaceRequestor) || iid.equals(Components.interfaces.nsIProgressEventSink)) { return this; } throw Components.results.NS_NOINTERFACE; }, } } } ); } catch (e) { Zotero.logError(e); let title = Zotero.getString('general.error'); let msg; if (e instanceof Zotero.HTTP.UnexpectedStatusException) { msg = Zotero.getString('general.invalidResponseServer'); } else if (e instanceof Zotero.HTTP.BrowserOfflineException) { msg = Zotero.getString('general.browserIsOffline', Zotero.appName); } else { msg = Zotero.getString('zotero.debugOutputLogging.dialog.error'); } ps.alert(null, title, msg); return false; } Zotero.debug(xmlhttp.responseText); var reported = xmlhttp.responseXML.getElementsByTagName('reported'); if (reported.length != 1) { ps.alert( null, Zotero.getString('general.error'), Zotero.getString('general.serverError') ); return false; } var reportID = reported[0].getAttribute('reportID'); var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING + ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL; var index = ps.confirmEx( null, Zotero.getString('zotero.debugOutputLogging.dialog.title'), Zotero.getString('zotero.debugOutputLogging.dialog.sent', [ZOTERO_CONFIG.DOMAIN_NAME, reportID]), buttonFlags, Zotero.getString('general.copyToClipboard'), null, null, null, {} ); if (index == 0) { const helper = Components.classes["@mozilla.org/widget/clipboardhelper;1"] .getService(Components.interfaces.nsIClipboardHelper); helper.copyString("D" + reportID); } Zotero.Debug.clear(); return true; }.bind(this))(); }, view: function () { Zotero.openInViewer("chrome://zotero/content/debugViewer.html", function (doc) { var submitted = false; doc.querySelector('#submit-button').addEventListener('click', function (event) { submitted = true; }); doc.querySelector('#clear-button').addEventListener('click', function (event) { Zotero.Debug.clear(); }); // If output has been submitted, disable logging when window is closed doc.defaultView.addEventListener('unload', function (event) { if (submitted) { Zotero.Debug.setStore(false); Zotero.Debug.clear(); } }); }); }, clear: function () { Zotero.Debug.clear(); }, restartEnabled: function () { var ps = Services.prompt; var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING + ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL + ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING; var index = ps.confirmEx( null, Zotero.getString('zotero.debugOutputLogging'), Zotero.getString('zotero.debugOutputLogging.enabledAfterRestart', [Zotero.clientName]), buttonFlags, Zotero.getString('general.restartNow'), null, Zotero.getString('general.restartLater'), null, {} ); if (index != 1) { Zotero.Prefs.set('debug.store', true); } if (index == 0) { Zotero.Utilities.Internal.quit(true); } }, _showMenu: function () { document.getElementById('debug-output-menu').hidden = false; } }; function toJavaScriptConsole() { openWindowByType('chrome://global/content/console.xul', 'global:console'); } function openRunJSWindow() { openWindowByType( 'chrome://zotero/content/runJS.html', 'zotero:run-js', 'chrome,width=900,height=700,resizable,centerscreen' ); } function openStyleEditor() { openWindowByType( 'chrome://zotero/content/tools/csledit.xhtml', 'zotero:style-editor', 'chrome,width=950,height=700,resizable' ); } function openScaffold() { openWindowByType( 'chrome://scaffold/content/scaffold.xhtml', 'zotero:scaffold', 'chrome,resizable' ); } function openWindowByType(uri, type, features) { var win = Services.wm.getMostRecentWindow(type); if (win) { win.focus(); } else if (features) { window.open(uri, "_blank", features); } else { window.open(uri, "_blank", "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar"); } } const gXPInstallObserver = { observe: function (subject, topic, data) { const { installs } = subject.wrappedJSObject; switch (topic) { case "addon-install-disabled": case "addon-install-blocked": case "addon-install-failed": Zotero.alert( null, Zotero.getString("standalone.addonInstallationFailed.title"), Zotero.getString("standalone.addonInstallationFailed.body", installs[0].name)); break; /*case "addon-install-started": case "addon-install-complete":*/ } } }; // Used by update prompt function openUILinkIn(url) { ZoteroPane.loadURI(url); } window.addEventListener("load", function(e) { ZoteroStandalone.onLoad(e); }, false); window.addEventListener("unload", function(e) { ZoteroStandalone.onUnload(e); }, false);