diff --git a/chrome/content/zotero/icon.js b/chrome/content/zotero/icon.js index ccfcbee109..1f3ce8ce9e 100644 --- a/chrome/content/zotero/icon.js +++ b/chrome/content/zotero/icon.js @@ -25,6 +25,7 @@ "use strict"; +Components.utils.import("resource://zotero/config.js"); Components.utils.import("resource:///modules/CustomizableUI.jsm"); var comboButtonsID = 'zotero-toolbar-buttons'; @@ -119,8 +120,8 @@ CustomizableUI.addListener({ CustomizableUI.createWidget({ id: comboButtonsID, type: 'custom', - label: 'Zotero', - tooltiptext: "Zotero", + label: ZOTERO_CONFIG.CLIENT_NAME, + tooltiptext: ZOTERO_CONFIG.CLIENT_NAME, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function (document) { const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index 91fe971f6d..631d921562 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -40,10 +40,14 @@ var ZoteroOverlay = new function() zoteroSplitter = document.getElementById('zotero-splitter'); var self = this; + var iconLoaded = false; Zotero.Promise.try(function () { - if (!Zotero || Zotero.skipLoading) { - throw true; + if (!Zotero) { + throw new Error("No Zotero object"); + } + if (Zotero.skipLoading) { + throw new Error("Skipping loading"); } return Zotero.Promise.all([Zotero.initializationPromise, Zotero.unlockPromise]); }) @@ -51,7 +55,7 @@ var ZoteroOverlay = new function() Zotero.debug("Initializing overlay"); if (Zotero.skipLoading) { - throw true; + throw new Error("Skipping loading"); } ZoteroPane_Overlay = ZoteroPane; @@ -94,6 +98,7 @@ var ZoteroOverlay = new function() // Add toolbar icon try { + iconLoaded = true; Services.scriptloader.loadSubScript("chrome://zotero/content/icon.js", {}, "UTF-8"); } catch (e) { @@ -134,6 +139,17 @@ var ZoteroOverlay = new function() }) .catch(function (e) { Zotero.debug(e, 1); + + // Add toolbar icon if still necessary + if (!iconLoaded) { + try { + Services.scriptloader.loadSubScript("chrome://zotero/content/icon.js", {}, "UTF-8"); + } + catch (e) { + Zotero.logError(e); + } + } + throw e; }); } diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js index 4e6b5451b6..9629caf95c 100644 --- a/chrome/content/zotero/xpcom/db.js +++ b/chrome/content/zotero/xpcom/db.js @@ -1317,3 +1317,9 @@ Zotero.DBConnection.prototype._getTypedValue = function (statement, i) { // Initialize main database connection Zotero.DB = new Zotero.DBConnection('zotero'); + +Zotero.DB.IncompatibleVersionException = function (msg, dbClientVersion) { + this.message = msg; + this.dbClientVersion = dbClientVersion; +} +Zotero.DB.IncompatibleVersionException.prototype = Object.create(Error.prototype); diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js index 056ca4b79e..c4c4ed0a2a 100644 --- a/chrome/content/zotero/xpcom/schema.js +++ b/chrome/content/zotero/xpcom/schema.js @@ -106,8 +106,13 @@ Zotero.Schema = new function(){ } if (compatibility > _maxCompatibility) { - throw new Error("Database is incompatible this Zotero version " - + "(" + compatibility + " > " + _maxCompatibility + ")"); + let dbClientVersion = yield Zotero.DB.valueQueryAsync( + "SELECT value FROM settings " + + "WHERE setting='client' AND key='lastCompatibleVersion'" + ); + let msg = "Database is incompatible with this Zotero version " + + `(${compatibility} > ${_maxCompatibility})` + throw new Zotero.DB.IncompatibleVersionException(msg, dbClientVersion); } var schemaVersion = yield _getSchemaSQLVersion('userdata'); @@ -1554,6 +1559,19 @@ Zotero.Schema = new function(){ } + var _updateCompatibility = Zotero.Promise.coroutine(function* (version) { + if (version > _maxCompatibility) { + throw new Error("Can't set compatibility greater than _maxCompatibility"); + } + + yield Zotero.DB.queryAsync( + "REPLACE INTO settings VALUES (?, ?, ?)", + ['client', 'lastCompatibleVersion', Zotero.version] + ); + yield _updateDBVersion('compatibility', version); + }); + + /** * Process the response from the repository * @@ -1944,7 +1962,7 @@ Zotero.Schema = new function(){ // previous revision to that one. for (let i = fromVersion + 1; i <= toVersion; i++) { if (i == 80) { - yield _updateDBVersion('compatibility', 1); + yield _updateCompatibility(1); yield Zotero.DB.queryAsync("ALTER TABLE libraries RENAME TO librariesOld"); yield Zotero.DB.queryAsync("CREATE TABLE libraries (\n libraryID INTEGER PRIMARY KEY,\n type TEXT NOT NULL,\n editable INT NOT NULL,\n filesEditable INT NOT NULL,\n version INT NOT NULL DEFAULT 0,\n lastSync INT NOT NULL DEFAULT 0,\n lastStorageSync INT NOT NULL DEFAULT 0\n)"); @@ -2282,7 +2300,7 @@ Zotero.Schema = new function(){ } if (i == 81) { - yield _updateDBVersion('compatibility', 2); + yield _updateCompatibility(2); yield Zotero.DB.queryAsync("ALTER TABLE libraries RENAME TO librariesOld"); yield Zotero.DB.queryAsync("CREATE TABLE libraries (\n libraryID INTEGER PRIMARY KEY,\n type TEXT NOT NULL,\n editable INT NOT NULL,\n filesEditable INT NOT NULL,\n version INT NOT NULL DEFAULT 0,\n storageVersion INT NOT NULL DEFAULT 0,\n lastSync INT NOT NULL DEFAULT 0\n)"); diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index a6efd8c8f9..eb95c60e5e 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -630,23 +630,23 @@ Components.utils.import("resource://gre/modules/osfile.jsm"); Zotero.Items.startEmptyTrashTimer(); } catch (e) { - Zotero.debug(e, 1); - Components.utils.reportError(e); // DEBUG: doesn't always work + Zotero.logError(e); - if (e.toString().match('newer than SQL file')) { - let versions = e.toString().match(/\((\d+) < (\d+)\)/); + if (e instanceof Zotero.DB.IncompatibleVersionException) { let kbURL = "https://www.zotero.org/support/kb/newer_db_version"; - let msg = Zotero.getString('startupError.zoteroVersionIsOlder') + " " - + Zotero.getString('startupError.zoteroVersionIsOlder.upgrade') + "\n\n" + let msg = Zotero.getString('startupError.incompatibleDBVersion', + [Zotero.clientName, e.dbClientVersion]) + "\n\n" + Zotero.getString('startupError.zoteroVersionIsOlder.current', Zotero.version) - + (versions ? " (" + versions[1] + " < " + versions[2] + ")" : "") + "\n\n" - + Zotero.getString('general.seeForMoreInformation', kbURL); + + "\n\n" + + Zotero.getString('startupError.zoteroVersionIsOlder.upgrade', + ZOTERO_CONFIG.DOMAIN_NAME); Zotero.startupError = msg; _startupErrorHandler = function() { var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService); 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) + ps.BUTTON_POS_0_DEFAULT; var index = ps.confirmEx( @@ -655,10 +655,13 @@ Components.utils.import("resource://gre/modules/osfile.jsm"); Zotero.startupError, buttonFlags, Zotero.getString('general.checkForUpdate'), - null, null, null, {} + null, + Zotero.getString('general.moreInformation'), + null, + {} ); - // "Check for updates" button + // "Check for Update" button if(index === 0) { if(Zotero.isStandalone) { Components.classes["@mozilla.org/embedcomp/window-watcher;1"] @@ -703,11 +706,23 @@ Components.utils.import("resource://gre/modules/osfile.jsm"); ); } } + // Load More Info page + else if (index == 2) { + let io = Components.classes['@mozilla.org/network/io-service;1'] + .getService(Components.interfaces.nsIIOService); + let uri = io.newURI(kbURL, null, null); + let handler = Components.classes['@mozilla.org/uriloader/external-protocol-service;1'] + .getService(Components.interfaces.nsIExternalProtocolService) + .getProtocolHandlerInfo('http'); + handler.preferredAction = Components.interfaces.nsIHandlerInfo.useSystemDefault; + handler.launchWithURI(uri, null); + } }; + throw e; } Zotero.startupError = Zotero.getString('startupError.databaseUpgradeError') + "\n\n" + e; - throw true; + throw e; }; return true; diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties index a7feffd0c1..fcf6f6c974 100644 --- a/chrome/locale/en-US/zotero/zotero.properties +++ b/chrome/locale/en-US/zotero/zotero.properties @@ -138,9 +138,9 @@ startupError.closeStandalone = If Zotero Standalone is open, please close it startupError.closeFirefox = If Firefox with the Zotero extension is open, please close it and restart Zotero Standalone. startupError.databaseCannotBeOpened = The Zotero database cannot be opened. startupError.checkPermissions = Make sure you have read and write permissions for all files in the Zotero data directory. -startupError.zoteroVersionIsOlder = This version of Zotero is older than the version last used with your database. -startupError.zoteroVersionIsOlder.upgrade = Please upgrade to the latest version from zotero.org. +startupError.incompatibleDBVersion = This %1$S database requires %1$S %2$S or later. startupError.zoteroVersionIsOlder.current = Current version: %S +startupError.zoteroVersionIsOlder.upgrade = Please upgrade to the latest version from %S. startupError.databaseUpgradeError = Database upgrade error date.relative.secondsAgo.one = 1 second ago diff --git a/resource/config.js b/resource/config.js index 5cd95fe591..b5aaf5734c 100644 --- a/resource/config.js +++ b/resource/config.js @@ -1,6 +1,7 @@ var ZOTERO_CONFIG = { GUID: 'zotero@chnm.gmu.edu', CLIENT_NAME: 'Zotero', + DOMAIN_NAME: 'zotero.org', REPOSITORY_URL: 'https://repo.zotero.org/repo/', REPOSITORY_CHECK_INTERVAL: 86400, // 24 hours REPOSITORY_RETRY_INTERVAL: 3600, // 1 hour