From 90d8363b0f15cbdc77abece581608b77bb4bbf12 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Fri, 17 Feb 2012 21:40:19 -0500 Subject: [PATCH 01/60] Make sure updateDocument throws a visible error --- chrome/content/zotero/xpcom/integration.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js index 02eab1599..a3f291c39 100644 --- a/chrome/content/zotero/xpcom/integration.js +++ b/chrome/content/zotero/xpcom/integration.js @@ -1437,12 +1437,17 @@ Zotero.Integration.Fields.prototype._processFields = function(fields, callback, Zotero.Integration.Fields.prototype.updateDocument = function(forceCitations, forceBibliography, ignoreCitationChanges, callback) { // update citations - this._session.updateUpdateIndices(forceCitations); - var me = this; - var deleteCitations = Zotero.pumpGenerator(this._session.updateCitations(function(deleteCitations) { - Zotero.pumpGenerator(me._updateDocument(forceCitations, forceBibliography, - ignoreCitationChanges, deleteCitations, callback)); - })); + try { + this._session.updateUpdateIndices(forceCitations); + var me = this; + var deleteCitations = Zotero.pumpGenerator(this._session.updateCitations(function(deleteCitations) { + Zotero.pumpGenerator(me._updateDocument(forceCitations, forceBibliography, + ignoreCitationChanges, deleteCitations, callback)); + })); + } catch(e) { + Zotero.logError(e); + Zotero.Integration.handleError(e, this._doc); + } } /** @@ -1786,7 +1791,7 @@ Zotero.Integration.CitationEditInterface.prototype = { me._fields.updateSession(function() { me._errorOccurred = false; me.accept(progressCallback, true); - }) + }); }, 0); return; } From 7eac0e1820f9003010541af1e1c9ab9383dd5312 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Fri, 17 Feb 2012 21:54:05 -0500 Subject: [PATCH 02/60] More error handling improvements --- chrome/content/zotero/xpcom/integration.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js index a3f291c39..b7fd147d6 100644 --- a/chrome/content/zotero/xpcom/integration.js +++ b/chrome/content/zotero/xpcom/integration.js @@ -1305,8 +1305,7 @@ Zotero.Integration.Fields.prototype.updateSession = function(callback, errorCall try { me._session.loadBibliographyData(me._bibliographyData); } catch(e) { - if(errorCallback) { - errorCallback(e); + if(errorCallback && !errorCallback(e)) { } else if(e instanceof Zotero.Integration.CorruptFieldException) { var msg = Zotero.getString("integration.corruptBibliography")+'\n\n'+ Zotero.getString('integration.corruptBibliography.description'); @@ -1367,8 +1366,7 @@ Zotero.Integration.Fields.prototype._processFields = function(fields, callback, try { this._session.addCitation(i, noteIndex, content); } catch(e) { - if(errorCallback) { - errorCallback(e); + if(errorCallback && !errorCallback(e)) { } else if(e instanceof Zotero.Integration.MissingItemException) { // First, check if we've already decided to remove field codes from these var reselect = true; @@ -1741,7 +1739,18 @@ Zotero.Integration.CitationEditInterface.prototype = { }, function(e) { if(e instanceof Zotero.Integration.MissingItemException || e instanceof Zotero.Integration.CorruptFieldException) { - me._errorOccurred = true; + if(me._haveAccepted) { + // If accept button has been pressed, go ahead and show errors + return true; + } else { + // If not, suppress errors and we will show them later + me._errorOccurred = true; + return false; + } + } else { + // If not a MissingItemException or CorruptFieldException, go ahead and show + // the error now. This shouldn't happen! + return true; } }); } From 6021214b062c329a35cff3ac898f00668723fb4a Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Fri, 17 Feb 2012 23:10:18 -0500 Subject: [PATCH 03/60] Further restructuring of error handling --- chrome/content/zotero/xpcom/integration.js | 206 +++++++++++++-------- 1 file changed, 128 insertions(+), 78 deletions(-) diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js index b7fd147d6..87840ce8c 100644 --- a/chrome/content/zotero/xpcom/integration.js +++ b/chrome/content/zotero/xpcom/integration.js @@ -1246,7 +1246,10 @@ Zotero.Integration.Fields.prototype._retrieveFields = function() { * Shows an error if a field code is corrupted * @param {Exception} e The exception thrown * @param {Field} field The Zotero field object + * @param {Function} callback The callback passed to updateSession + * @param {Function} errorCallback The error callback passed to updateSession * @param {Integer} i The field index + * @return {Boolean} Whether to continue updating the session */ Zotero.Integration.Fields.prototype._showCorruptFieldError = function(e, field, callback, errorCallback, i) { Zotero.logError(e); @@ -1277,6 +1280,58 @@ Zotero.Integration.Fields.prototype._showCorruptFieldError = function(e, field, } } +/** + * Shows an error if a field code is missing + * @param {Exception} e The exception thrown + * @param {Exception} e The exception thrown + * @param {Field} field The Zotero field object + * @param {Function} callback The callback passed to updateSession + * @param {Function} errorCallback The error callback passed to updateSession + * @param {Integer} i The field index + * @return {Boolean} Whether to continue updating the session + */ +Zotero.Integration.Fields.prototype._showMissingItemError = function(e, field, callback, errorCallback, i) { + // First, check if we've already decided to remove field codes from these + var reselect = true; + for each(var reselectKey in e.reselectKeys) { + if(this._deleteKeys[reselectKey]) { + this._removeCodeFields.push(i); + return true; + } + } + + // Ask user what to do with this item + if(e.citationLength == 1) { + var msg = Zotero.getString("integration.missingItem.single"); + } else { + var msg = Zotero.getString("integration.missingItem.multiple", (e.citationIndex+1).toString()); + } + msg += '\n\n'+Zotero.getString('integration.missingItem.description'); + field.select(); + this._doc.activate(); + var result = this._doc.displayAlert(msg, 1, 3); + if(result == 0) { // Cancel + throw new Zotero.Integration.UserCancelledException(); + } else if(result == 1) { // No + for each(var reselectKey in e.reselectKeys) { + this._deleteKeys[reselectKey] = true; + } + this._removeCodeFields.push(i); + return true; + } else { // Yes + // Display reselect item dialog + var me = this; + var oldCurrentWindow = Zotero.Integration.currentWindow; + this._session.reselectItem(this._doc, e, function() { + // Now try again + Zotero.Integration.currentWindow = oldCurrentWindow; + me._doc.activate(); + me._processFields(me._fields, callback, errorCallback, i); + }); + return false; + } +} + /** * Updates Zotero.Integration.Session attached to Zotero.Integration.Fields in line with document */ @@ -1305,22 +1360,28 @@ Zotero.Integration.Fields.prototype.updateSession = function(callback, errorCall try { me._session.loadBibliographyData(me._bibliographyData); } catch(e) { - if(errorCallback && !errorCallback(e)) { - } else if(e instanceof Zotero.Integration.CorruptFieldException) { - var msg = Zotero.getString("integration.corruptBibliography")+'\n\n'+ - Zotero.getString('integration.corruptBibliography.description'); - var result = me._doc.displayAlert(msg, - Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_CAUTION, - Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK_CANCEL); - if(result == 0) { - throw e; + var defaultHandler = function() { + if(e instanceof Zotero.Integration.CorruptFieldException) { + var msg = Zotero.getString("integration.corruptBibliography")+'\n\n'+ + Zotero.getString('integration.corruptBibliography.description'); + var result = me._doc.displayAlert(msg, + Components.interfaces.zoteroIntegrationDocument.DIALOG_ICON_CAUTION, + Components.interfaces.zoteroIntegrationDocument.DIALOG_BUTTONS_OK_CANCEL); + if(result == 0) { + throw e; + } else { + me._bibliographyData = ""; + me._session.bibliographyHasChanged = true; + me._session.bibliographyDataHasChanged = true; + } } else { - me._bibliographyData = ""; - me._session.bibliographyHasChanged = true; - me._session.bibliographyDataHasChanged = true; + throw e; } - } else { - throw e; + }; + if(errorCallback) { + if(!errorCallback(e, defaultHandler)) return; + } else if(!defaultHandler()) { + return; } } } @@ -1351,13 +1412,26 @@ Zotero.Integration.Fields.prototype.updateSession = function(callback, errorCall Zotero.Integration.Fields.prototype._processFields = function(fields, callback, errorCallback, i) { if(!i) i = 0; + var me = this; for(var n = fields.length; i Date: Sat, 18 Feb 2012 01:38:28 -0500 Subject: [PATCH 04/60] Don't save undesired snapshots from connector --- chrome/content/zotero/xpcom/translation/translate.js | 1 + 1 file changed, 1 insertion(+) diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js index 72c1e2721..6653270e2 100644 --- a/chrome/content/zotero/xpcom/translation/translate.js +++ b/chrome/content/zotero/xpcom/translation/translate.js @@ -124,6 +124,7 @@ Zotero.Translate.Sandbox = { for(var j=0; j Date: Sun, 19 Feb 2012 23:13:49 -0500 Subject: [PATCH 05/60] Address Rintze's comments per http://forums.zotero.org/discussion/21934/ --- chrome/locale/en-US/zotero/zotero.dtd | 2 +- chrome/locale/en-US/zotero/zotero.properties | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/chrome/locale/en-US/zotero/zotero.dtd b/chrome/locale/en-US/zotero/zotero.dtd index ae7cf602d..c3df599c8 100644 --- a/chrome/locale/en-US/zotero/zotero.dtd +++ b/chrome/locale/en-US/zotero/zotero.dtd @@ -175,7 +175,7 @@ - + diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties index 4675a3388..3f2427950 100644 --- a/chrome/locale/en-US/zotero/zotero.properties +++ b/chrome/locale/en-US/zotero/zotero.properties @@ -581,7 +581,7 @@ integration.revertAll.button = Revert All integration.revert.title = Are you sure you want to revert this edit? integration.revert.body = If you choose to continue, the text of the bibliography entries corresponded to the selected item(s) will be replaced with the unmodified text specified by the selected style. integration.revert.button = Revert -integration.removeBibEntry.title = The selected references is cited within your document. +integration.removeBibEntry.title = The selected reference is cited within your document. integration.removeBibEntry.body = Are you sure you want to omit it from your bibliography? integration.cited = Cited @@ -601,7 +601,7 @@ integration.error.cannotInsertHere = Zotero fields cannot be inserted here. integration.error.notInCitation = You must place the cursor in a Zotero citation to edit it. integration.error.noBibliography = The current bibliographic style does not define a bibliography. If you wish to add a bibliography, please choose another style. integration.error.deletePipe = The pipe that Zotero uses to communicate with the word processor could not be initialized. Would you like Zotero to attempt to correct this error? You will be prompted for your password. -integration.error.invalidStyle = The style you have selected does not appear to be valid. If you have created this style yourself, please ensure that it passes validation as described at http://zotero.org/support/dev/citation_styles. Alternatively, try selecting another style. +integration.error.invalidStyle = The style you have selected does not appear to be valid. If you have created this style yourself, please ensure that it passes validation as described at https://github.com/citation-style-language/styles/wiki/Validation. Alternatively, try selecting another style. integration.error.fieldTypeMismatch = Zotero cannot update this document because it was created by a different word processing application with an incompatible field encoding. In order to make a document compatible with both Word and OpenOffice.org/LibreOffice/NeoOffice, open the document in the word processor with which it was originally created and switch the field type to Bookmarks in the Zotero Document Preferences. integration.replace = Replace this Zotero field? @@ -616,7 +616,7 @@ integration.corruptField.description = Clicking "No" will delete the field codes integration.corruptBibliography = The Zotero field code for your bibliography is corrupted. Should Zotero clear this field code and generate a new bibliography? integration.corruptBibliography.description = All items cited in the text will appear in the new bibliography, but modifications you made in the "Edit Bibliography" dialog will be lost. integration.citationChanged = You have modified this citation since Zotero generated it. Do you want to keep your modifications and prevent future updates? -integration.citationChanged.description = Clicking "Yes" will prevent Zotero from updating this citation if you add additional citations, switch styles, or modify the reference to which it refers. Clicking "No" will erase your changes. +integration.citationChanged.description = Clicking "Yes" will prevent Zotero from updating this citation if you add additional citations, switch styles, or modify the item to which it refers. Clicking "No" will erase your changes. integration.citationChanged.edit = You have modified this citation since Zotero generated it. Editing will clear your modifications. Do you want to continue? styles.installStyle = Install style "%1$S" from %2$S? @@ -757,7 +757,7 @@ standalone.addonInstallationFailed.body = The add-on "%S" could not be installe connector.error.title = Zotero Connector Error connector.standaloneOpen = Your database cannot be accessed because Zotero Standalone is currently open. Please view your items in Zotero Standalone. -firstRunGuidance.saveIcon = Zotero can recognize a reference on this page. Click this icon in the address bar to save the reference to your Zotero library. +firstRunGuidance.saveIcon = Zotero has found a reference on this page. Click this icon in the address bar to save the reference to your Zotero library. firstRunGuidance.authorMenu = Zotero lets you specify editors and translators, too. You can turn an author into an editor or translator by selecting from this menu. firstRunGuidance.quickFormat = Type a title or author to search for a reference.\n\nAfter you've made your selection, click the bubble or press Ctrl-\u2193 to add page numbers, prefixes, or suffixes. You can also include a page number along with your search terms to add it directly.\n\nYou can edit citations directly in the word processor document. firstRunGuidance.quickFormatMac = Type a title or author to search for a reference.\n\nAfter you've made your selection, click the bubble or press Cmd-\u2193 to add page numbers, prefixes, or suffixes. You can also include a page number along with your search terms to add it directly.\n\nYou can edit citations directly in the word processor document. \ No newline at end of file From 549fa4a508aed7aaae905703918f371da9c92943 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 02:06:33 -0500 Subject: [PATCH 06/60] Make translator tester time out after 10 minutes, add partial failure condition in tester pane, and rename "Unknown" to the more descriptive "Data Mismatch" --- .../tools/testTranslators/testTranslators.css | 8 ++++++-- .../tools/testTranslators/testTranslators.js | 17 ++++++++++------- .../tools/testTranslators/translatorTester.js | 12 +++++++++++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.css b/chrome/content/zotero/tools/testTranslators/testTranslators.css index 0613011f2..905103972 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.css +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.css @@ -26,7 +26,7 @@ td, th { width: 100px; } -.th-pending, .th-supported, .th-succeeded, .th-failed, .th-unknown { +.th-pending, .th-supported, .th-succeeded, .th-failed, .th-mismatch { width: 75px; } @@ -38,7 +38,7 @@ td, th { background-color: #ff9090; } -.status-unknown { +.status-mismatch { background-color: #FFB; } @@ -50,6 +50,10 @@ td, th { background-color: #9FF; } +.status-partial-failure { + background-color: rgb(249, 180, 98); +} + tr.output-displayed > td { background-color: #b4d5ff !important; } diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index 191b7cd52..611bc2a8f 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -25,7 +25,7 @@ const NUM_CONCURRENT_TESTS = 6; const TRANSLATOR_TYPES = ["Web", "Import", "Export", "Search"]; -const TABLE_COLUMNS = ["Translator", "Supported", "Status", "Pending", "Succeeded", "Failed", "Unknown"]; +const TABLE_COLUMNS = ["Translator", "Supported", "Status", "Pending", "Succeeded", "Failed", "Mismatch"]; var translatorTables = {}, translatorTestViews = {}, translatorTestViewsToRun = {}, @@ -89,7 +89,7 @@ var TranslatorTestView = function(translator, type) { this._status = document.createElement("td"); row.appendChild(this._status); - // Unknown + // Pending this._pending = document.createElement("td"); row.appendChild(this._pending); @@ -101,7 +101,7 @@ var TranslatorTestView = function(translator, type) { this._failed = document.createElement("td"); row.appendChild(this._failed); - // Unknown + // Mismatch this._unknown = document.createElement("td"); row.appendChild(this._unknown); @@ -212,15 +212,18 @@ TranslatorTestView.prototype.updateStatus = function(obj, status) { } else { this._status.textContent = "Not Run"; } + } else if((succeeded || unknown) && failed) { + this._status.className = "status-partial-failure"; + this._status.textContent = "Partial Failure"; } else if(failed) { this._status.className = "status-failed"; - this._status.textContent = "Failed"; + this._status.textContent = "Failure"; } else if(unknown) { - this._status.className = "status-unknown"; - this._status.textContent = "Unknown"; + this._status.className = "status-mismatch"; + this._status.textContent = "Data Mismatch"; } else { this._status.className = "status-succeeded"; - this._status.textContent = "Succeeded"; + this._status.textContent = "Success"; } } else { this._status.className = "status-untested"; diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index 5bb871fbd..de0d4f9cb 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -23,6 +23,9 @@ ***** END LICENSE BLOCK ***** */ +// Timeout for test to complete +const TEST_RUN_TIMEOUT = 600000; + var Zotero_TranslatorTester_IGNORE_FIELDS = ["complete", "accessDate", "checkFields"]; /** @@ -137,14 +140,17 @@ Zotero_TranslatorTester.prototype.runTests = function(testDoneCallback, recursiv * @param {Function} testDoneCallback A callback to be executed each time a test is complete */ Zotero_TranslatorTester.prototype._runTestsRecursively = function(testDoneCallback) { - var test = this.pending.shift(); var testNumber = this.tests.length-this.pending.length; var me = this; this._debug(this, "\nTranslatorTester: Running "+this.translator.label+" Test "+testNumber); + var executedCallback = false; var callback = function(obj, test, status, message) { + if(executedCallback) return; + executedCallback = true; + me._debug(this, "TranslatorTester: "+me.translator.label+" Test "+testNumber+": "+status+" ("+message+")"); me[status].push(test); if(testDoneCallback) testDoneCallback(me, test, status, message); @@ -156,6 +162,10 @@ Zotero_TranslatorTester.prototype._runTestsRecursively = function(testDoneCallba } else { this.runTest(test, null, callback); } + + window.setTimeout(function() { + callback(me, test, "failed", "Test timed out after "+TEST_RUN_TIMEOUT+" seconds"); + }, TEST_RUN_TIMEOUT); }; /** From 99d65926bf37687584027eed07a698c0bc08c921 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 02:26:41 -0500 Subject: [PATCH 07/60] Unregister mimeTypeHandler and version header on Zotero shutdown --- chrome/content/zotero/xpcom/mimeTypeHandler.js | 5 +++++ chrome/content/zotero/xpcom/zotero.js | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/mimeTypeHandler.js b/chrome/content/zotero/xpcom/mimeTypeHandler.js index d5467e6a6..b299e47da 100644 --- a/chrome/content/zotero/xpcom/mimeTypeHandler.js +++ b/chrome/content/zotero/xpcom/mimeTypeHandler.js @@ -39,6 +39,11 @@ Zotero.MIMETypeHandler = new function () { getService(Components.interfaces.nsIObserverService). addObserver(_Observer, "http-on-examine-response", false); this.initializeHandlers(); + Zotero.addShutdownListener(function() { + Components.classes["@mozilla.org/observer-service;1"]. + getService(Components.interfaces.nsIObserverService). + removeObserver(_Observer, "http-on-examine-response", false); + }); } /** diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 33272ed47..d74e54133 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -2234,6 +2234,7 @@ Zotero.VersionHeader = { if (Zotero.Prefs.get("zoteroDotOrgVersionHeader")) { this.register(); } + Zotero.addShutdownListener(this.unregister); }, // Called from this.init() and Zotero.Prefs.observe() @@ -2258,7 +2259,7 @@ Zotero.VersionHeader = { unregister: function () { var observerService = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); - observerService.removeObserver(this, "http-on-modify-request"); + observerService.removeObserver(Zotero.VersionHeader, "http-on-modify-request"); } } From 5dcade91c5e533b9bfa95fc76989dea6d9945bae Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 02:38:29 -0500 Subject: [PATCH 08/60] Serialize browser --- .../zotero/tools/testTranslators/testTranslators.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index 611bc2a8f..f78491b1c 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -376,9 +376,9 @@ function init() { if(req.responseText) { // success; unserialize var data = JSON.parse(req.responseText); - for(var i=0, n=data.length; i Date: Mon, 20 Feb 2012 03:03:32 -0500 Subject: [PATCH 09/60] Minor refactoring --- .../tools/testTranslators/testTranslators.js | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index f78491b1c..cb79dd6b4 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -324,13 +324,7 @@ function init() { var type = translatorType; return function(e) { e.preventDefault(); - for(var i in translatorTestViewsToRun[type]) { - var testView = translatorTestViewsToRun[type][i]; - testView.updateStatus(testView._translatorTester, "pending"); - } - for(var i=0; i Date: Mon, 20 Feb 2012 03:11:53 -0500 Subject: [PATCH 10/60] Refocus content when closing Zotero pane by any means besides opening Zotero Standalone --- chrome/content/zotero/overlay.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index 7ed07ca6a..152e2e6c1 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -156,10 +156,10 @@ var ZoteroOverlay = new function() // save current state _stateBeforeReload = !zoteroPane.hidden && !zoteroPane.collapsed; // ensure pane is closed - if(!zoteroPane.collapsed) ZoteroOverlay.toggleDisplay(false); + if(!zoteroPane.collapsed) ZoteroOverlay.toggleDisplay(false, true); } else { // reopen pane if it was open before - ZoteroOverlay.toggleDisplay(_stateBeforeReload); + ZoteroOverlay.toggleDisplay(_stateBeforeReload, true); } }); } @@ -176,8 +176,12 @@ var ZoteroOverlay = new function() /** * Hides/displays the Zotero interface + * @param {Boolean} makeVisible Whether or not Zotero interface should be visible + * @param {Boolean} dontRefocus If true, don't focus content when closing Zotero pane. Used + * when closing pane because Zotero Standalone is being opened, to avoid pulling Firefox to + * the foreground. */ - this.toggleDisplay = function(makeVisible) + this.toggleDisplay = function(makeVisible, dontRefocus) { if(!Zotero || !Zotero.initialized) { ZoteroPane.displayStartupError(); @@ -245,6 +249,11 @@ var ZoteroOverlay = new function() zoteroPane.height = 0; document.getElementById('content').setAttribute('collapsed', false); + + if(!dontRefocus) { + // Return focus to the browser content pane + window.content.window.focus(); + } } } From 0d34e34a3aa9e681ab33ec93db0714553c75f69e Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Mon, 20 Feb 2012 03:31:22 -0500 Subject: [PATCH 11/60] Don't add 'Web Page" to new item menu by accident And ignore it if it's there --- .../content/zotero/xpcom/data/cachedTypes.js | 2 +- chrome/content/zotero/zoteroPane.js | 32 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/chrome/content/zotero/xpcom/data/cachedTypes.js b/chrome/content/zotero/xpcom/data/cachedTypes.js index ff411b245..1b23b69de 100644 --- a/chrome/content/zotero/xpcom/data/cachedTypes.js +++ b/chrome/content/zotero/xpcom/data/cachedTypes.js @@ -273,7 +273,7 @@ Zotero.ItemTypes = new function() { mru = mru.split(',').slice(0, limit); for (var i=0, len=mru.length; i Date: Mon, 20 Feb 2012 04:18:06 -0500 Subject: [PATCH 12/60] Fire a DOM event when we have translators --- .../content/zotero/tools/testTranslators/testTranslators.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index cb79dd6b4..d4a4d01fe 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -425,6 +425,10 @@ function haveTranslators(translators, type) { translatorTestViewsToRun[type].push(translatorTestView); } } + + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('ZoteroHaveTranslators-'+type, true, true); + document.dispatchEvent(ev); } /** From a27f7259ec826f28e92bb8307ac32cc09fdd5845 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 04:46:34 -0500 Subject: [PATCH 13/60] Use Zotero.setTimeout when possible --- chrome/content/zotero/tools/testTranslators/translatorTester.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index de0d4f9cb..495427206 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -163,7 +163,7 @@ Zotero_TranslatorTester.prototype._runTestsRecursively = function(testDoneCallba this.runTest(test, null, callback); } - window.setTimeout(function() { + (Zotero.setTimeout ? Zotero : window).setTimeout(function() { callback(me, test, "failed", "Test timed out after "+TEST_RUN_TIMEOUT+" seconds"); }, TEST_RUN_TIMEOUT); }; From ed6a7b665a31ebcdffc46f23e1b6537bc6565bf6 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 05:14:47 -0500 Subject: [PATCH 14/60] Give seconds in seconds, not ms --- chrome/content/zotero/tools/testTranslators/translatorTester.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index 495427206..ebbb4ba14 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -164,7 +164,7 @@ Zotero_TranslatorTester.prototype._runTestsRecursively = function(testDoneCallba } (Zotero.setTimeout ? Zotero : window).setTimeout(function() { - callback(me, test, "failed", "Test timed out after "+TEST_RUN_TIMEOUT+" seconds"); + callback(me, test, "failed", "Test timed out after "+TEST_RUN_TIMEOUT/1000+" seconds"); }, TEST_RUN_TIMEOUT); }; From 2f61e417bc49f59e49938fe126a8aa165cb886a6 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 16:17:05 -0500 Subject: [PATCH 15/60] Include more information in translator tester output --- .../tools/testTranslators/testTranslators.js | 8 +++---- .../tools/testTranslators/translatorTester.js | 24 +++++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index d4a4d01fe..6375f7c25 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -170,10 +170,10 @@ TranslatorTestView.prototype.serialize = function(serializedData) { "output":this._outputView.getOutput(), "label":this._label.textContent, "isSupported":this.isSupported, - "pending":parseInt(this._pending.textContent), - "failed":parseInt(this._failed.textContent), - "succeeded":parseInt(this._succeeded.textContent), - "unknown":parseInt(this._unknown.textContent) + "pending":this._translatorTester.pending, + "failed":this._translatorTester.failed, + "succeeded":this._translatorTester.succeeded, + "unknown":this._translatorTester.unknown }; } diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index ebbb4ba14..4a6b4569e 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -153,6 +153,7 @@ Zotero_TranslatorTester.prototype._runTestsRecursively = function(testDoneCallba me._debug(this, "TranslatorTester: "+me.translator.label+" Test "+testNumber+": "+status+" ("+message+")"); me[status].push(test); + test.message = message; if(testDoneCallback) testDoneCallback(me, test, status, message); me.runTests(testDoneCallback, true); }; @@ -217,8 +218,12 @@ Zotero_TranslatorTester.prototype.runTest = function(test, doc, testDoneCallback me._runTestTranslate(translate, translators, test, testDoneCallback); }); translate.setHandler("debug", this._debug); + var errorReturned; + translate.setHandler("error", function(obj, err) { + errorReturned = err; + }); translate.setHandler("done", function(obj, returnValue) { - me._checkResult(test, obj, returnValue, testDoneCallback); + me._checkResult(test, obj, returnValue, errorReturned, testDoneCallback); }); translate.setHandler("select", function(obj, items, callback) { if(test.items !== "multiple" && test.items.length <= 1) { @@ -275,9 +280,23 @@ Zotero_TranslatorTester.prototype._runTestTranslate = function(translate, transl * @param {Object} test Test that was executed * @param {Zotero.Translate} translate The Zotero.Translate instance * @param {Boolean} returnValue Whether translation completed successfully + * @param {Error} error Error code, if one was specified * @param {Function} testDoneCallback A callback to be executed when test is complete */ -Zotero_TranslatorTester.prototype._checkResult = function(test, translate, returnValue, testDoneCallback) { +Zotero_TranslatorTester.prototype._checkResult = function(test, translate, returnValue, error, testDoneCallback) { + if(error) { + var errorString = "Translation failed: "+error.toString(); + if(typeof error === "object") { + for(var i in error) { + if(typeof(error[i]) != "object") { + errorString += "\n"+i+' => '+error[i]; + } + } + } + testDoneCallback(this, test, "failed", errorString); + return; + } + if(!returnValue) { testDoneCallback(this, test, "failed", "Translation failed; examine debug output for errors"); return; @@ -299,6 +318,7 @@ Zotero_TranslatorTester.prototype._checkResult = function(test, translate, retur var translatedItem = Zotero_TranslatorTester._sanitizeItem(translate.newItems[i]); if(!this._compare(testItem, translatedItem)) { + test.translatedItem = testItem; testDoneCallback(this, test, "unknown", "Item "+i+" does not match"); return; } From 833031dbdf4ae1c2ff06704ec649d1aacaf006fa Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 16:20:50 -0500 Subject: [PATCH 16/60] Remove unchecked data before serializing --- chrome/content/zotero/tools/testTranslators/translatorTester.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index 4a6b4569e..725c61e12 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -318,7 +318,7 @@ Zotero_TranslatorTester.prototype._checkResult = function(test, translate, retur var translatedItem = Zotero_TranslatorTester._sanitizeItem(translate.newItems[i]); if(!this._compare(testItem, translatedItem)) { - test.translatedItem = testItem; + test.itemReturned = Zotero_TranslatorTester._sanitizeItem(test.items[i], true); testDoneCallback(this, test, "unknown", "Item "+i+" does not match"); return; } From 705672d43191af988e60980f345a3c06deec4f7b Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 16:26:35 -0500 Subject: [PATCH 17/60] Serialize all items, in case there are multiple --- .../zotero/tools/testTranslators/translatorTester.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index 725c61e12..92b954a04 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -318,7 +318,12 @@ Zotero_TranslatorTester.prototype._checkResult = function(test, translate, retur var translatedItem = Zotero_TranslatorTester._sanitizeItem(translate.newItems[i]); if(!this._compare(testItem, translatedItem)) { - test.itemReturned = Zotero_TranslatorTester._sanitizeItem(test.items[i], true); + var m = translate.newItems.length; + test.itemsReturned = new Array(m); + for(var j=0; j Date: Mon, 20 Feb 2012 23:06:26 -0500 Subject: [PATCH 18/60] Accept browser, version, and date arguments --- .../tools/testTranslators/testTranslators.js | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index 6375f7c25..00c14cedd 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -363,7 +363,25 @@ function init() { if(viewerMode) { // if no Zotero object, try to unserialize data var req = new XMLHttpRequest(); - req.open("GET", "testResults.json", true); + var loc = "testResults.json"; + if(window.location.hash) { + var hashVars = {}; + var hashVarsSplit = window.location.hash.substr(1).split("&"); + for(var i=0; i Date: Mon, 20 Feb 2012 23:30:28 -0500 Subject: [PATCH 19/60] Don't show "Translating undefined" for non-web translators --- chrome/content/zotero/tools/testTranslators/translatorTester.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index 92b954a04..dc3c23e8a 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -201,7 +201,7 @@ Zotero_TranslatorTester.prototype.fetchPageAndRunTest = function(test, testDoneC * @param {Function} testDoneCallback A callback to be executed when test is complete */ Zotero_TranslatorTester.prototype.runTest = function(test, doc, testDoneCallback) { - this._debug(this, "TranslatorTester: Translating "+test.url); + this._debug(this, "TranslatorTester: Translating"+(test.url ? " "+test.url : "")); var me = this; var translate = Zotero.Translate.newInstance(this.type); From cb18dd6a3a8b1a68163b0e9fe157df3957ffd73f Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 20 Feb 2012 23:32:14 -0500 Subject: [PATCH 20/60] Show appropriate error on missing test data --- chrome/content/zotero/tools/testTranslators/testTranslators.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index 00c14cedd..55a85f65d 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -386,7 +386,7 @@ function init() { req.onreadystatechange = function(e) { if(req.readyState != 4) return; - if(req.responseText) { // success; unserialize + if(req.status === 200 && req.responseText) { // success; unserialize var data = JSON.parse(req.responseText); for(var i=0, n=data.results.length; i Date: Mon, 20 Feb 2012 14:04:38 +0800 Subject: [PATCH 21/60] Upgrade citeproc-js to version 1.0.286. --- chrome/content/zotero/xpcom/citeproc.js | 48 +++++++++++++------------ 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js index 3dee989b5..9bcaecf85 100644 --- a/chrome/content/zotero/xpcom/citeproc.js +++ b/chrome/content/zotero/xpcom/citeproc.js @@ -186,8 +186,8 @@ var CSL = { ALL_ROMANESQUE_REGEXP: /^[a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe]+$/, VIETNAMESE_SPECIALS: /[\u00c0-\u00c3\u00c8-\u00ca\u00cc\u00cd\u00d2-\u00d5\u00d9\u00da\u00dd\u00e0-\u00e3\u00e8-\u00ea\u00ec\u00ed\u00f2-\u00f5\u00f9\u00fa\u00fd\u0101\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01a0\u01a1\u01af\u01b0\u1ea0-\u1ef9]/, VIETNAMESE_NAMES: /^(?:(?:[.AaBbCcDdEeGgHhIiKkLlMmNnOoPpQqRrSsTtUuVvXxYy \u00c0-\u00c3\u00c8-\u00ca\u00cc\u00cd\u00d2-\u00d5\u00d9\u00da\u00dd\u00e0-\u00e3\u00e8-\u00ea\u00ec\u00ed\u00f2-\u00f5\u00f9\u00fa\u00fd\u0101\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01a0\u01a1\u01af\u01b0\u1ea0-\u1ef9]{2,6})(\s+|$))+$/, - NOTE_FIELDS_REGEXP: /\{:[\-a-z]+:[^\}]+\}/g, - NOTE_FIELD_REGEXP: /\{:([\-a-z]+):\s*([^\}]+)\}/, + NOTE_FIELDS_REGEXP: /\{:[\-_a-z]+:[^\}]+\}/g, + NOTE_FIELD_REGEXP: /\{:([\-_a-z]+):\s*([^\}]+)\}/, DISPLAY_CLASSES: ["block", "left-margin", "right-inline", "indent"], NAME_VARIABLES: [ "author", @@ -2148,7 +2148,7 @@ CSL.DateParser = function () { }; CSL.Engine = function (sys, style, lang, forceLang) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.285"; + this.processor_version = "1.0.286"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -2493,7 +2493,7 @@ CSL.Engine.prototype.retrieveItem = function (id) { if (this.opt.development_extensions.jurisdiction_subfield && Item.jurisdiction) { var subjurisdictions = Item.jurisdiction.split(";"); if (subjurisdictions.length > 1) { - Item.subjurisdiction = subjurisdictions.slice(0,2).join(";"); + Item.subjurisdiction = subjurisdictions.join(";"); } } for (var i = 1, ilen = CSL.DATE_VARIABLES.length; i < ilen; i += 1) { @@ -3387,11 +3387,12 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, if (this.opt.update_mode === CSL.POSITION) { textCitations = []; noteCitations = []; + var citationsInNote = {}; } var update_items = []; for (i = 0, ilen = citationByIndex.length; i < ilen; i += 1) { citationByIndex[i].properties.index = i; - for (j = 0, jlen = citationByIndex[i].sortedItems.length; j < jlen; j += 1) { + for (j = 0, jlen = citationByIndex[i].sortedItems.length; j < jlen; j += 1) { item = citationByIndex[i].sortedItems[j]; if (!this.registry.citationreg.citationsByItemId[item[1].id]) { this.registry.citationreg.citationsByItemId[item[1].id] = []; @@ -3405,6 +3406,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, if (citationByIndex[i].properties.noteIndex) { noteCitations.push(citationByIndex[i]); } else { + citationByIndex[i].properties.noteIndex = 0; textCitations.push(citationByIndex[i]); } } @@ -3446,20 +3448,20 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, } var citations; if (this.opt.update_mode === CSL.POSITION) { - var citationsInNote = {}; for (i = 0; i < 2; i += 1) { citations = [textCitations, noteCitations][i]; var first_ref = {}; var last_ref = {}; for (j = 0, jlen = citations.length; j < jlen; j += 1) { var onecitation = citations[j]; - if (!onecitation.properties.noteIndex) { - onecitation.properties.noteIndex = 0; - } - if (!citationsInNote[onecitation.properties.noteIndex]) { - citationsInNote[onecitation.properties.noteIndex] = 1; - } else { - citationsInNote[onecitation.properties.noteIndex] += 1; + for (var k = 0, klen = onecitation.sortedItems.length; k < klen; k += 1) { + if (!this.registry.registry[onecitation.sortedItems[k][1].id].parallel) { + if (!citationsInNote[onecitation.properties.noteIndex]) { + citationsInNote[onecitation.properties.noteIndex] = 1; + } else { + citationsInNote[onecitation.properties.noteIndex] += 1; + } + } } for (k = 0, klen = citations[j].sortedItems.length; k < klen; k += 1) { item = citations[j].sortedItems[k]; @@ -3491,7 +3493,7 @@ CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, var items = citations[(j - 1)].sortedItems; var useme = false; if ((citations[(j - 1)].sortedItems[0][1].id == item[1].id && citations[j - 1].properties.noteIndex >= (citations[j].properties.noteIndex - 1)) || citations[(j - 1)].sortedItems[0][1].id == this.registry.registry[item[1].id].parallel) { - if (citationsInNote[citations[j - 1].properties.noteIndex] === 1 || citations[j - 1].properties.noteIndex === 0) { + if (citationsInNote[citations[j - 1].properties.noteIndex] == 1 || citations[j - 1].properties.noteIndex == 0) { useme = true; } } @@ -5334,15 +5336,17 @@ CSL.NameOutput.prototype.outputNames = function () { var blob = this.state.output.pop(); this.state.output.append(blob, this.names); this.state.tmp.name_node.top = this.state.output.current.value(); - var oldSuppressDecorations = this.state.tmp.suppress_decorations; - this.state.tmp.suppress_decorations = true; - var lastBlob = this.state.tmp.name_node.top.blobs.pop(); - var name_node_string = this.state.output.string(this.state, lastBlob.blobs, false); - this.state.tmp.name_node.top.blobs.push(lastBlob); - if (name_node_string) { - this.state.tmp.name_node.string = name_node_string; + if (variables[0] !== "authority") { + var oldSuppressDecorations = this.state.tmp.suppress_decorations; + this.state.tmp.suppress_decorations = true; + var lastBlob = this.state.tmp.name_node.top.blobs.pop(); + var name_node_string = this.state.output.string(this.state, lastBlob.blobs, false); + this.state.tmp.name_node.top.blobs.push(lastBlob); + if (name_node_string) { + this.state.tmp.name_node.string = name_node_string; + } + this.state.tmp.suppress_decorations = oldSuppressDecorations; } - this.state.tmp.suppress_decorations = oldSuppressDecorations; if (this.state.tmp.name_node.string && !this.state.tmp.first_name_string) { this.state.tmp.first_name_string = this.state.tmp.name_node.string; } From f68eb7c6f5804de25dcc6cd3115bb33f8090dd22 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 21 Feb 2012 13:02:02 +0800 Subject: [PATCH 22/60] Upgrade citeproc-js to version 1.0.287 --- chrome/content/zotero/xpcom/citeproc.js | 78 ++++++++++++++++--------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/chrome/content/zotero/xpcom/citeproc.js b/chrome/content/zotero/xpcom/citeproc.js index 9bcaecf85..f18303030 100644 --- a/chrome/content/zotero/xpcom/citeproc.js +++ b/chrome/content/zotero/xpcom/citeproc.js @@ -178,12 +178,12 @@ var CSL = { PREFIX_PUNCTUATION: /[.;:]\s*$/, SUFFIX_PUNCTUATION: /^\s*[.;:,\(\)]/, NUMBER_REGEXP: /(?:^\d+|\d+$)/, - NAME_INITIAL_REGEXP: /^([A-Z\u0080-\u017f\u0400-\u042f])([a-zA-Z\u0080-\u017f\u0400-\u052f]*|)/, - ROMANESQUE_REGEXP: /[a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe]/, - ROMANESQUE_NOT_REGEXP: /[^a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe]/g, - STARTSWITH_ROMANESQUE_REGEXP: /^[&a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe]/, - ENDSWITH_ROMANESQUE_REGEXP: /[.;:&a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe]$/, - ALL_ROMANESQUE_REGEXP: /^[a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe]+$/, + NAME_INITIAL_REGEXP: /^([A-Z\u0080-\u017f\u0400-\u042f\u0600-\u06ff])([a-zA-Z\u0080-\u017f\u0400-\u052f\u0600-\u06ff]*|)/, + ROMANESQUE_REGEXP: /[a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe\u0600-\u06ff\u200c\u200d\u200e\u202a-\u202e]/, + ROMANESQUE_NOT_REGEXP: /[^a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe\u0600-\u06ff\u200c\u200d\u200e\u202a-\u202e]/g, + STARTSWITH_ROMANESQUE_REGEXP: /^[&a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe\u0600-\u06ff\u200c\u200d\u200e\u202a-\u202e]/, + ENDSWITH_ROMANESQUE_REGEXP: /[.;:&a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe\u0600-\u06ff\u200c\u200d\u200e\u202a-\u202e]$/, + ALL_ROMANESQUE_REGEXP: /^[a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe\u0600-\u06ff\u200c\u200d\u200e\u202a-\u202e]+$/, VIETNAMESE_SPECIALS: /[\u00c0-\u00c3\u00c8-\u00ca\u00cc\u00cd\u00d2-\u00d5\u00d9\u00da\u00dd\u00e0-\u00e3\u00e8-\u00ea\u00ec\u00ed\u00f2-\u00f5\u00f9\u00fa\u00fd\u0101\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01a0\u01a1\u01af\u01b0\u1ea0-\u1ef9]/, VIETNAMESE_NAMES: /^(?:(?:[.AaBbCcDdEeGgHhIiKkLlMmNnOoPpQqRrSsTtUuVvXxYy \u00c0-\u00c3\u00c8-\u00ca\u00cc\u00cd\u00d2-\u00d5\u00d9\u00da\u00dd\u00e0-\u00e3\u00e8-\u00ea\u00ec\u00ed\u00f2-\u00f5\u00f9\u00fa\u00fd\u0101\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01a0\u01a1\u01af\u01b0\u1ea0-\u1ef9]{2,6})(\s+|$))+$/, NOTE_FIELDS_REGEXP: /\{:[\-_a-z]+:[^\}]+\}/g, @@ -302,6 +302,7 @@ var CSL = { es: "es_ES", et: "et_EE", fa: "fa_FA", + fi: "fi_FI", fr: "fr_FR", he: "he_IL", hu: "hu_HU", @@ -2148,7 +2149,7 @@ CSL.DateParser = function () { }; CSL.Engine = function (sys, style, lang, forceLang) { var attrs, langspec, localexml, locale; - this.processor_version = "1.0.286"; + this.processor_version = "1.0.287"; this.csl_version = "1.0"; this.sys = sys; this.sys.xml = new CSL.System.Xml.Parsing(); @@ -2690,7 +2691,20 @@ CSL.Engine.prototype.setAbbreviations = function (arg) { if (this.sys.setAbbreviations) { this.sys.setAbbreviations(arg); } -} +}; +CSL.Engine.prototype.setEnglishLocaleEscapes = function (arg) { + if ("string" === typeof arg) { + arg = arg.split(/\s+,\s+/); + } + if (!arg || !arg.length) { + arg = []; + } + for (var i = 0, ilen = arg.length; i < ilen; i += 1) { + if (this.opt.english_locale_escapes.indexOf(arg[i]) === -1) { + this.opt.english_locale_escapes.push(arg[i]); + } + } +}; CSL.Engine.Opt = function () { this.has_disambiguate = false; this.mode = "html"; @@ -2713,6 +2727,7 @@ CSL.Engine.Opt = function () { this.citation_number_slug = false; this.max_number_of_names = 0; this.trigraph = "Aaaa00:AaAa00:AaAA00:AAAA00"; + this.english_locale_escapes = []; this.development_extensions = {}; this.development_extensions.field_hack = true; this.development_extensions.locator_date_and_revision = true; @@ -4228,17 +4243,22 @@ CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) { } for (termname in this.locale[lang_out].terms) { if (this.locale[lang_out].terms.hasOwnProperty(termname)) { - for (i = 0, ilen = 2; i < ilen; i += 1) { - genderform = CSL.GENDERS[i]; - if (this.locale[lang_out].terms[termname][genderform]) { - for (form in this.locale[lang_out].terms[termname]) { - if (!this.locale[lang_out].terms[termname][genderform][form]) { - this.locale[lang_out].terms[termname][genderform][form] = this.locale[lang_out].terms[termname][form]; + for (i = 0, ilen = 2; i < ilen; i += 1) { + genderform = CSL.GENDERS[i]; + if (this.locale[lang_out].terms[termname][genderform]) { + for (form in this.locale[lang_out].terms[termname]) { + if (!this.locale[lang_out].terms[termname][genderform][form]) { + this.locale[lang_out].terms[termname][genderform][form] = this.locale[lang_out].terms[termname][form]; + } } } } } - } + } + if (lang_out && lang_out.slice(0, 2) === "fr") { + this.locale[lang_out].terms["page-range-delimiter"] = "-"; + } else { + this.locale[lang_out].terms["page-range-delimiter"] = "\u2013"; } nodes = this.sys.xml.getNodesByName(locale, 'style-options'); for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) { @@ -7522,7 +7542,7 @@ CSL.Node.text = { func = function (state, Item, item) { if (item && item[this.variables[0]]) { var locator = "" + item[this.variables[0]]; - locator = locator.replace(/([^\\])--*/g,"$1\u2013"); + locator = locator.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter")); locator = locator.replace(/\\-/g,"-"); state.output.append(locator, this, false, false, true); } @@ -7544,7 +7564,7 @@ CSL.Node.text = { func = function (state, Item) { var value = state.getVariable(Item, "page", form); if (value) { - value = value.replace(/([^\\])--*/g,"$1\u2013"); + value = value.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter")); value = value.replace(/\\-/g,"-"); value = state.fun.page_mangler(value); state.output.append(value, this, false, false, true); @@ -8367,18 +8387,22 @@ CSL.Attributes["@text-case"] = function (state, arg) { this.strings["text-case"] = arg; if (arg === "title") { var m = false; + var default_locale = state.opt["default-locale"][0].slice(0, 2); if (Item.language) { - m = Item.language.match(/^\s*([a-z]{2})(?:$|-| )/); - } - if (state.opt["default-locale"][0].slice(0, 2) === "en") { - if (m && m[1] !== "en") { + m = Item.language.match(/^\s*([A-Za-z]{2})(?:$|-| )/); + if (!m) { this.strings["text-case"] = "passthrough"; + } else if (m[1].toLowerCase() !== "en") { + this.strings["text-case"] = "passthrough"; + for (var i = 0, ilen = state.opt.english_locale_escapes.length; i < ilen; i += 1) { + var escaper = state.opt.english_locale_escapes[i]; + if (m[1].slice(0, escaper.length).toLowerCase() === escaper) { + this.strings["text-case"] = arg; + } + } } - } else { + } else if (default_locale !== "en") { this.strings["text-case"] = "passthrough"; - if (m && m[1] === "en") { - this.strings["text-case"] = arg; - } } } }; @@ -10096,10 +10120,10 @@ CSL.Engine.prototype.processNumber = function (node, ItemObject, variable) { && elements[i].match(/^[0-9]+/) && parseInt(elements[i - 2]) < parseInt(elements[i].replace(/[^0-9].*/,""))) { var start = this.tmp.shadow_numbers[variable].values.slice(-2); - middle[0][1] = "\u2013"; + middle[0][1] = this.getTerm("page-range-delimiter"); if (this.opt["page-range-format"] ) { var newstr = this.fun.page_mangler(start[0][1] +"-"+elements[i]); - newstr = newstr.split(/\u2013/); + newstr = newstr.split(this.getTerm("page-range-delimiter")); elements[i] = newstr[1]; } count = count + 1; From 32ad75c680785dff4370ab960089c920480b0dcc Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Tue, 21 Feb 2012 12:42:11 -0500 Subject: [PATCH 23/60] Serialize translatorID --- chrome/content/zotero/tools/testTranslators/testTranslators.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index 55a85f65d..54d333a81 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -129,6 +129,7 @@ var TranslatorTestView = function(translator, type) { * Initializes TranslatorTestView given a translator and its type */ TranslatorTestView.prototype.initWithTranslatorAndType = function(translator, type) { + this._translatorID = translator.translatorID; this._label.appendChild(document.createTextNode(translator.label)); this.isSupported = translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER; @@ -166,6 +167,7 @@ TranslatorTestView.prototype.unserialize = function(serializedData) { */ TranslatorTestView.prototype.serialize = function(serializedData) { return { + "translatorID":this._translatorID, "type":this._type, "output":this._outputView.getOutput(), "label":this._label.textContent, From 74299b96b93f97bef1b4e891b9d1e2403e825a10 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Tue, 21 Feb 2012 17:44:26 -0500 Subject: [PATCH 24/60] Show issues on GitHub that start with the translator label --- .../tools/testTranslators/testTranslators.js | 78 ++++++++++++++++++- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.js b/chrome/content/zotero/tools/testTranslators/testTranslators.js index 54d333a81..1808c6943 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.js +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.js @@ -25,7 +25,7 @@ const NUM_CONCURRENT_TESTS = 6; const TRANSLATOR_TYPES = ["Web", "Import", "Export", "Search"]; -const TABLE_COLUMNS = ["Translator", "Supported", "Status", "Pending", "Succeeded", "Failed", "Mismatch"]; +const TABLE_COLUMNS = ["Translator", "Supported", "Status", "Pending", "Succeeded", "Failed", "Mismatch", "Issues"]; var translatorTables = {}, translatorTestViews = {}, translatorTestViewsToRun = {}, @@ -35,6 +35,53 @@ var translatorTables = {}, currentOutputView, viewerMode = true; +/** + * Fetches issue information from GitHub + */ +var Issues = new function() { + var _executeWhenRetrieved = []; + var githubInfo; + + /** + * Gets issues for a specific translator + * @param {String} translatorLabel Gets issues starting with translatorLabel + * @param {Function} callback Function to call when issue information is available + */ + this.getFor = function(translatorLabel, callback) { + translatorLabel = translatorLabel.toLowerCase(); + + var whenRetrieved = function() { + var issues = []; + for(var i=0; i Date: Tue, 21 Feb 2012 17:45:00 -0500 Subject: [PATCH 25/60] CSS changes --- .../zotero/tools/testTranslators/testTranslators.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/chrome/content/zotero/tools/testTranslators/testTranslators.css b/chrome/content/zotero/tools/testTranslators/testTranslators.css index 905103972..8d3309687 100644 --- a/chrome/content/zotero/tools/testTranslators/testTranslators.css +++ b/chrome/content/zotero/tools/testTranslators/testTranslators.css @@ -18,8 +18,8 @@ td, th { } .th-translator { - width: 500px; - max-width: 500px; + width: 250px; + max-width: 250px; } .th-status { @@ -30,6 +30,11 @@ td, th { width: 75px; } +.th-issues { + width: 250px; + max-width: 500px; +} + .status-succeeded, .supported-yes { background-color: #90ff90; } From 39fc50913c2df07b06595e8ab38a934b1dca1ae5 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Tue, 21 Feb 2012 14:03:07 -0500 Subject: [PATCH 26/60] Fix debug output of objects, which I broke in da09a8df --- chrome/content/zotero/xpcom/debug.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/debug.js b/chrome/content/zotero/xpcom/debug.js index d88d48e30..8da623f7d 100644 --- a/chrome/content/zotero/xpcom/debug.js +++ b/chrome/content/zotero/xpcom/debug.js @@ -62,7 +62,8 @@ Zotero.Debug = new function () { break; } } - else if (typeof message != 'string') { + + if (typeof message != 'string') { message = Zotero.Utilities.varDump(message); } From 4cf4e13a7b5f2bd5959d791ce611fbdf33a2264f Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Tue, 21 Feb 2012 18:10:09 -0500 Subject: [PATCH 27/60] Add more helpful error message for file import error --- chrome/content/zotero/xpcom/attachments.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chrome/content/zotero/xpcom/attachments.js b/chrome/content/zotero/xpcom/attachments.js index a7ae4ec87..e246a88bc 100644 --- a/chrome/content/zotero/xpcom/attachments.js +++ b/chrome/content/zotero/xpcom/attachments.js @@ -102,6 +102,10 @@ Zotero.Attachments = new function(){ // hmph Zotero.DB.rollbackTransaction(); + var msg = "Failed importing file " + file.path; + Components.utils.reportError(msg); + Zotero.debug(msg, 1); + try { // Clean up if (itemID) { From e45c48a66f4782ce0d4147d822336f8d1412a564 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Tue, 21 Feb 2012 18:12:19 -0500 Subject: [PATCH 28/60] Fix "Function complete defined in y, not in x, or definitions differ" --- .../tools/testTranslators/translatorTester.js | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index dc3c23e8a..49d9913bf 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -85,21 +85,24 @@ Zotero_TranslatorTester._sanitizeItem = function(item, forSave) { if(item.attachments && item.attachments.length) { // don't actually test URI equality for (var i=0; i Date: Tue, 21 Feb 2012 22:18:43 -0500 Subject: [PATCH 29/60] Attempt to escape wrapper hell by serializing and unserializing the item --- .../content/zotero/tools/testTranslators/translatorTester.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/chrome/content/zotero/tools/testTranslators/translatorTester.js b/chrome/content/zotero/tools/testTranslators/translatorTester.js index 49d9913bf..e84a87d82 100644 --- a/chrome/content/zotero/tools/testTranslators/translatorTester.js +++ b/chrome/content/zotero/tools/testTranslators/translatorTester.js @@ -100,6 +100,11 @@ Zotero_TranslatorTester._sanitizeItem = function(item, forSave) { } } + // try to convert to JSON and back to get rid of undesirable undeletable elements; this may fail + try { + item = JSON.parse(JSON.stringify(item)); + } catch(e) {}; + // remove fields to be ignored for(var j=0, n=Zotero_TranslatorTester_IGNORE_FIELDS.length; j Date: Wed, 22 Feb 2012 04:40:11 -0500 Subject: [PATCH 30/60] Don't show site-specific Quick Copy in Standalone --- .../content/zotero/preferences/preferences.js | 4 ++- .../zotero/preferences/preferences.xul | 23 ++------------- .../preferences/preferences_firefox.xul | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/chrome/content/zotero/preferences/preferences.js b/chrome/content/zotero/preferences/preferences.js index b796dcc4f..4cc95fe76 100644 --- a/chrome/content/zotero/preferences/preferences.js +++ b/chrome/content/zotero/preferences/preferences.js @@ -588,7 +588,9 @@ function populateQuickCopyList() { menulist.setAttribute('preference', "pref-quickCopy-setting"); updateQuickCopyHTMLCheckbox(); - refreshQuickCopySiteList(); + if (!Zotero.isStandalone) { + refreshQuickCopySiteList(); + } } diff --git a/chrome/content/zotero/preferences/preferences.xul b/chrome/content/zotero/preferences/preferences.xul index da995dd0e..d28b31ef4 100644 --- a/chrome/content/zotero/preferences/preferences.xul +++ b/chrome/content/zotero/preferences/preferences.xul @@ -503,7 +503,7 @@ To add a new preference: - +