From 4ecdd55717bb4868dd0d0f6de366355722977e2e Mon Sep 17 00:00:00 2001 From: Aurimas Vinckevicius Date: Tue, 20 Jan 2015 21:54:05 -0600 Subject: [PATCH 1/3] Continue with default if declining Zotero to handle RIS/BibTex/etc. --- .../content/zotero/xpcom/mimeTypeHandler.js | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/chrome/content/zotero/xpcom/mimeTypeHandler.js b/chrome/content/zotero/xpcom/mimeTypeHandler.js index 84f444767e..eeda22a23b 100644 --- a/chrome/content/zotero/xpcom/mimeTypeHandler.js +++ b/chrome/content/zotero/xpcom/mimeTypeHandler.js @@ -107,7 +107,10 @@ Zotero.MIMETypeHandler = new function () { */ function _importHandler(string, uri, contentType, channel) { var win = channel.notificationCallbacks.getInterface(Components.interfaces.nsIDOMWindow).top; - if(!win) throw "Attempt to import from a channel without an attached document refused"; + if(!win) { + Zotero.debug("Attempt to import from a channel without an attached document refused"); + return false; + } var hostPort = channel.URI.hostPort.replace(";", "_", "g"); @@ -129,7 +132,7 @@ Zotero.MIMETypeHandler = new function () { bag.setPropertyAsBool("allowTabModal", true); var continueDownload = prompt.confirmCheck(title, text, checkMsg, checkValue); - if(!continueDownload) return; + if(!continueDownload) return false; if(checkValue.value) { // add to allowed sites if desired Zotero.Prefs.set("ingester.allowedSites", allowedSitesString+";"+hostPort); @@ -148,12 +151,14 @@ Zotero.MIMETypeHandler = new function () { var translators = translation.getTranslators(); if(!translators.length) { // we lied. we can't really translate this file. - throw "No translator found for handled RIS, Refer or ISI file" + Zotero.debug("No translator found to handle this file"); + return false; } // translate using first available translation.setTranslator(translators[0]); frontWindow.Zotero_Browser.performTranslation(translation); + return true; } /** @@ -300,11 +305,16 @@ Zotero.MIMETypeHandler = new function () { convStream.close(); inputStream.close(); + var handled = false; try { - _typeHandlers[this._contentType](readString, (this._request.name ? this._request.name : null), + handled = _typeHandlers[this._contentType](readString, (this._request.name ? this._request.name : null), this._contentType, channel); } catch(e) { - // if there was an error, handle using nsIExternalHelperAppService + Zotero.debug(e); + } + + if (!handled) { + // handle using nsIExternalHelperAppService var externalHelperAppService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]. getService(Components.interfaces.nsIExternalHelperAppService); var frontWindow = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]. @@ -317,10 +327,6 @@ Zotero.MIMETypeHandler = new function () { streamListener.onDataAvailable(this._request, context, inputStream, 0, this._storageStream.length); streamListener.onStopRequest(channel, context, status); } - this._storageStream.close(); - - // then throw our error - throw e; } this._storageStream.close(); From 3f3666c972d35ec5a3321b9e94358d5af7a13a17 Mon Sep 17 00:00:00 2001 From: Aurimas Vinckevicius Date: Tue, 20 Jan 2015 22:45:28 -0600 Subject: [PATCH 2/3] Add Zotero.Prefs.registerObserver * Easier monitoring of preference changes * Takes a preference name and a handler function that will be passed the new value of the preference * Unregister observer via Zotero.Prefs.unregisterObserver with the same parameters --- chrome/content/zotero/xpcom/zotero.js | 301 ++++++++++++++------------ 1 file changed, 167 insertions(+), 134 deletions(-) diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 903b4ff799..73a893563d 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -2291,6 +2291,133 @@ Zotero.Prefs = new function(){ // TODO: parse settings XML } + // Handlers for some Zotero preferences + var _handlers = [ + [ "statusBarIcon", function(val) { + var doc = Components.classes["@mozilla.org/appshell/window-mediator;1"] + .getService(Components.interfaces.nsIWindowMediator) + .getMostRecentWindow("navigator:browser").document; + + var addonBar = doc.getElementById("addon-bar"); + var icon = doc.getElementById("zotero-toolbar-button"); + // When the customize window is open, toolbar buttons seem to + // become wrapped in toolbarpaletteitems, which we need to remove + // manually if we change the pref to hidden or else the customize + // window doesn't close. + var wrapper = doc.getElementById("wrapper-zotero-toolbar-button"); + var palette = doc.getElementById("navigator-toolbox").palette; + var inAddonBar = false; + if (icon) { + // Because of the potential wrapper, don't just use .parentNode + var toolbar = Zotero.getAncestorByTagName(icon, "toolbar"); + inAddonBar = toolbar == addonBar; + } + + if (val == 0) { + // If showing in add-on bar, hide + if (!icon || !inAddonBar) { + return; + } + palette.appendChild(icon); + if (wrapper) { + addonBar.removeChild(wrapper); + } + addonBar.setAttribute("currentset", addonBar.currentSet); + doc.persist(addonBar.id, "currentset"); + } + else { + // If showing somewhere else, remove it from there + if (icon && !inAddonBar) { + palette.appendChild(icon); + if (wrapper) { + toolbar.removeChild(wrapper); + } + toolbar.setAttribute("currentset", toolbar.currentSet); + doc.persist(toolbar.id, "currentset"); + } + + // If not showing in add-on bar, add + if (!inAddonBar) { + var icon = addonBar.insertItem("zotero-toolbar-button"); + addonBar.setAttribute("currentset", addonBar.currentSet); + doc.persist(addonBar.id, "currentset"); + addonBar.setAttribute("collapsed", false); + doc.persist(addonBar.id, "collapsed"); + } + // And make small + if (val == 1) { + icon.setAttribute("compact", true); + } + // Or large + else if (val == 2) { + icon.removeAttribute("compact"); + } + } + }], + [ "automaticScraperUpdates", function(val) { + if (val){ + Zotero.Schema.updateFromRepository(); + } + else { + Zotero.Schema.stopRepositoryTimer(); + } + }], + [ "note.fontSize", function(val) { + if (val < 6) { + Zotero.Prefs.set('note.fontSize', 11); + } + }], + [ "zoteroDotOrgVersionHeader", function(val) { + if (val) { + Zotero.VersionHeader.register(); + } + else { + Zotero.VersionHeader.unregister(); + } + }], + [ "zoteroDotOrgVersionHeader", function(val) { + if (val) { + Zotero.VersionHeader.register(); + } + else { + Zotero.VersionHeader.unregister(); + } + }], + [ "sync.autoSync", function(val) { + if (val) { + Zotero.Sync.Runner.IdleListener.register(); + } + else { + Zotero.Sync.Runner.IdleListener.unregister(); + } + }], + [ "sync.fulltext.enabled", function(val) { + if (val) { + // Disable downgrades if full-text sync is enabled, since otherwise + // we could miss full-text content updates + if (Zotero.DB.valueQuery("SELECT version FROM version WHERE schema='userdata'") < 77) { + Zotero.DB.query("UPDATE version SET version=77 WHERE schema='userdata'"); + } + } + }], + [ "search.quicksearch-mode", function(val) { + var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] + .getService(Components.interfaces.nsIWindowMediator); + var enumerator = wm.getEnumerator("navigator:browser"); + while (enumerator.hasMoreElements()) { + var win = enumerator.getNext(); + if (!win.ZoteroPane) continue; + Zotero.updateQuickSearchBox(win.ZoteroPane.document); + } + + var enumerator = wm.getEnumerator("zotero:item-selector"); + while (enumerator.hasMoreElements()) { + var win = enumerator.getNext(); + if (!win.Zotero) continue; + Zotero.updateQuickSearchBox(win.document); + } + }] + ]; // // Methods to register a preferences observer @@ -2298,6 +2425,11 @@ Zotero.Prefs = new function(){ function register(){ this.prefBranch.QueryInterface(Components.interfaces.nsIPrefBranch2); this.prefBranch.addObserver("", this, false); + + // Register pre-set handlers + for (var i=0; i<_handlers.length; i++) { + this.registerObserver(_handlers[i][0], _handlers[i][1]); + } } function unregister(){ @@ -2307,147 +2439,48 @@ Zotero.Prefs = new function(){ this.prefBranch.removeObserver("", this); } + /** + * @param {nsIPrefBranch} subject The nsIPrefBranch we're observing (after appropriate QI) + * @param {String} topic The string defined by NS_PREFBRANCH_PREFCHANGE_TOPIC_ID + * @param {String} data The name of the pref that's been changed (relative to subject) + */ function observe(subject, topic, data){ - if(topic!="nsPref:changed"){ + if (topic != "nsPref:changed" || !_observers[data] || !_observers[data].length) { return; } - try { - - // subject is the nsIPrefBranch we're observing (after appropriate QI) - // data is the name of the pref that's been changed (relative to subject) - switch (data) { - case "statusBarIcon": - var doc = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Components.interfaces.nsIWindowMediator) - .getMostRecentWindow("navigator:browser").document; - - var addonBar = doc.getElementById("addon-bar"); - var icon = doc.getElementById("zotero-toolbar-button"); - // When the customize window is open, toolbar buttons seem to - // become wrapped in toolbarpaletteitems, which we need to remove - // manually if we change the pref to hidden or else the customize - // window doesn't close. - var wrapper = doc.getElementById("wrapper-zotero-toolbar-button"); - var palette = doc.getElementById("navigator-toolbox").palette; - var inAddonBar = false; - if (icon) { - // Because of the potential wrapper, don't just use .parentNode - var toolbar = Zotero.getAncestorByTagName(icon, "toolbar"); - inAddonBar = toolbar == addonBar; - } - var val = this.get("statusBarIcon"); - if (val == 0) { - // If showing in add-on bar, hide - if (!icon || !inAddonBar) { - return; - } - palette.appendChild(icon); - if (wrapper) { - addonBar.removeChild(wrapper); - } - addonBar.setAttribute("currentset", addonBar.currentSet); - doc.persist(addonBar.id, "currentset"); - } - else { - // If showing somewhere else, remove it from there - if (icon && !inAddonBar) { - palette.appendChild(icon); - if (wrapper) { - toolbar.removeChild(wrapper); - } - toolbar.setAttribute("currentset", toolbar.currentSet); - doc.persist(toolbar.id, "currentset"); - } - - // If not showing in add-on bar, add - if (!inAddonBar) { - var icon = addonBar.insertItem("zotero-toolbar-button"); - addonBar.setAttribute("currentset", addonBar.currentSet); - doc.persist(addonBar.id, "currentset"); - addonBar.setAttribute("collapsed", false); - doc.persist(addonBar.id, "collapsed"); - } - // And make small - if (val == 1) { - icon.setAttribute("compact", true); - } - // Or large - else if (val == 2) { - icon.removeAttribute("compact"); - } - } - break; - - case "automaticScraperUpdates": - if (this.get('automaticScraperUpdates')){ - Zotero.Schema.updateFromRepository(); - } - else { - Zotero.Schema.stopRepositoryTimer(); - } - break; - - case "note.fontSize": - var val = this.get('note.fontSize'); - if (val < 6) { - this.set('note.fontSize', 11); - } - break; - - case "zoteroDotOrgVersionHeader": - if (this.get("zoteroDotOrgVersionHeader")) { - Zotero.VersionHeader.register(); - } - else { - Zotero.VersionHeader.unregister(); - } - break; - - case "sync.autoSync": - if (this.get("sync.autoSync")) { - Zotero.Sync.Runner.IdleListener.register(); - } - else { - Zotero.Sync.Runner.IdleListener.unregister(); - } - break; - - // TEMP - case "sync.fulltext.enabled": - if (this.get("sync.fulltext.enabled")) { - // Disable downgrades if full-text sync is enabled, since otherwise - // we could miss full-text content updates - if (Zotero.DB.valueQuery("SELECT version FROM version WHERE schema='userdata'") < 77) { - Zotero.DB.query("UPDATE version SET version=77 WHERE schema='userdata'"); - } - } - break; - - case "search.quicksearch-mode": - var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Components.interfaces.nsIWindowMediator); - var enumerator = wm.getEnumerator("navigator:browser"); - while (enumerator.hasMoreElements()) { - var win = enumerator.getNext(); - if (!win.ZoteroPane) continue; - Zotero.updateQuickSearchBox(win.ZoteroPane.document); - } - - var enumerator = wm.getEnumerator("zotero:item-selector"); - while (enumerator.hasMoreElements()) { - var win = enumerator.getNext(); - if (!win.Zotero) continue; - Zotero.updateQuickSearchBox(win.document); - } - break; + var obs = _observers[data]; + for (var i=0; i Date: Tue, 20 Jan 2015 22:46:30 -0600 Subject: [PATCH 3/3] Don't require Zotero restart to change RIS/BibTeX handling preference --- .../content/zotero/xpcom/mimeTypeHandler.js | 66 ++++++++++++++----- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/chrome/content/zotero/xpcom/mimeTypeHandler.js b/chrome/content/zotero/xpcom/mimeTypeHandler.js index eeda22a23b..4d3b3f44b2 100644 --- a/chrome/content/zotero/xpcom/mimeTypeHandler.js +++ b/chrome/content/zotero/xpcom/mimeTypeHandler.js @@ -55,30 +55,50 @@ Zotero.MIMETypeHandler = new function () { _observers = []; if(Zotero.Prefs.get("parseEndNoteMIMETypes")) { - this.addHandler("application/x-endnote-refer", _importHandler, true); - this.addHandler("application/x-research-info-systems", _importHandler, true); - this.addHandler("application/x-inst-for-scientific-info", _importHandler, true); - - this.addHandler("text/x-bibtex", _importHandler, true); - this.addHandler("application/x-bibtex", _importHandler, true); - - // - // And some non-standard ones - // - this.addHandler("text/x-research-info-systems", _importHandler, true); - // Nature uses this one - this.addHandler("text/application/x-research-info-systems", _importHandler, true); - // Cell uses this one - this.addHandler("text/ris", _importHandler, true); - // Not even trying - this.addHandler("ris", _importHandler, true); + this.registerMetadataHandlers(); } + Zotero.Prefs.registerObserver("parseEndNoteMIMETypes", function(val) { + if (val) this.registerMetadataHandlers(); + else this.unregisterMetadataHandlers(); + }.bind(this)); + this.addHandler("application/vnd.citationstyles.style+xml", function(a1, a2) { Zotero.Styles.install(a1, a2) }); this.addHandler("text/x-csl", function(a1, a2) { Zotero.Styles.install(a1, a2) }); // deprecated this.addHandler("application/x-zotero-schema", Zotero.Schema.importSchema); this.addHandler("application/x-zotero-settings", Zotero.Prefs.importSettings); } + // MIME types that Zotero should handle when parseEndNoteMIMETypes preference + // is enabled + var metadataMIMETypes = [ + "application/x-endnote-refer", "application/x-research-info-systems", + "application/x-inst-for-scientific-info", + "text/x-bibtex", "application/x-bibtex", + // Non-standard + "text/x-research-info-systems", + "text/application/x-research-info-systems", // Nature serves this + "text/ris", // Cell serves this + "ris" // Not even trying + ]; + + /** + * Registers MIME types for parseEndNoteMIMETypes preference + */ + this.registerMetadataHandlers = function() { + for (var i=0; i