Merge pull request #617 from aurimasv/content-handler

Content handlers
This commit is contained in:
Dan Stillman 2015-01-30 04:09:03 -05:00
commit f04b641f3c
2 changed files with 231 additions and 160 deletions

View File

@ -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
@ -92,6 +112,18 @@ Zotero.MIMETypeHandler = new function () {
_ignoreContentDispositionTypes.push(type);
}
/**
* 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
*/
@ -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();

View File

@ -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;
}
var i = obs.indexOf(handler);
if (i == -1) {
Zotero.debug("Handler was not registered for preference " + name);
return;
}
catch (e) {
Zotero.debug(e);
throw (e);
}
obs.splice(i, 1);
}
}