commit f04b641f3ceb837501c2995d442db32d3960f675
parent d8f2d4b26801ee23713b65f16ba87750fc7f6b14
Author: Dan Stillman <dstillman@zotero.org>
Date: Fri, 30 Jan 2015 04:09:03 -0500
Merge pull request #617 from aurimasv/content-handler
Content handlers
Diffstat:
2 files changed, 231 insertions(+), 160 deletions(-)
diff --git 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<metadataMIMETypes.length; i++) {
+ this.addHandler(metadataMIMETypes[i], _importHandler, true);
+ }
+ }
+
+ /**
+ * Unregisters MIME types for parseEndNoteMIMETypes preference
+ */
+ this.unregisterMetadataHandlers = function() {
+ for (var i=0; i<metadataMIMETypes.length; i++) {
+ this.removeHandler(metadataMIMETypes[i]);
+ }
+ }
+
/**
* Adds a handler to handle a specific MIME type
* @param {String} type MIME type to handle
@@ -93,6 +113,18 @@ Zotero.MIMETypeHandler = new function () {
}
/**
+ * Removes a handler for a specific MIME type
+ * @param {String} type MIME type to handle
+ */
+ this.removeHandler = function(type) {
+ delete _typeHandlers[type];
+ var i = _ignoreContentDispositionTypes.indexOf(type);
+ if (i != -1) {
+ _ignoreContentDispositionTypes.splice(i, 1);
+ }
+ }
+
+ /**
* Adds an observer to inspect and possibly modify page headers
*/
this.addObserver = function(fn) {
@@ -107,7 +139,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 +164,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 +183,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 +337,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 +359,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();
diff --git 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<obs.length; i++) {
+ try {
+ obs[i](this.get(data));
+ }
+ catch (e) {
+ Zotero.debug("Error while executing preference observer handler for " + data);
+ Zotero.debug(e);
+ }
}
-
+ }
+
+ var _observers = {};
+ this.registerObserver = function(name, handler) {
+ _observers[name] = _observers[name] || [];
+ _observers[name].push(handler);
+ }
+
+ this.unregisterObserver = function(name, handler) {
+ var obs = _observers[name];
+ if (!obs) {
+ Zotero.debug("No preferences observer registered for " + name);
+ return;
}
- catch (e) {
- Zotero.debug(e);
- throw (e);
+
+ var i = obs.indexOf(handler);
+ if (i == -1) {
+ Zotero.debug("Handler was not registered for preference " + name);
+ return;
}
+
+ obs.splice(i, 1);
}
}