From 564d27f51c3521e948856f1bdbeb79b7543fa12c Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Wed, 8 Feb 2012 23:05:34 -0500 Subject: [PATCH] Allow add-ons to be updated via addons.mozilla.org in Zotero Standalone, part 1 --- chrome/content/zotero/xpcom/standalone.js | 87 +++++++++++++++++++++++ chrome/content/zotero/xpcom/zotero.js | 1 + components/zotero-service.js | 7 ++ 3 files changed, 95 insertions(+) create mode 100644 chrome/content/zotero/xpcom/standalone.js diff --git a/chrome/content/zotero/xpcom/standalone.js b/chrome/content/zotero/xpcom/standalone.js new file mode 100644 index 000000000..c47bee904 --- /dev/null +++ b/chrome/content/zotero/xpcom/standalone.js @@ -0,0 +1,87 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2012 Center for History and New Media + George Mason University, Fairfax, Virginia, USA + http://zotero.org + + This file is part of Zotero. + + Zotero is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Zotero is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Zotero. If not, see . + + ***** END LICENSE BLOCK ***** +*/ + +Zotero.Standalone = new function() { + /** + * Stream listener proxy for AMO requests to replace Firefox's app ID with toolkit@mozilla.org. + * This means add-ons hosted at AMO will update properly for us. + */ + var AMOStreamListener = function() {}; + AMOStreamListener.prototype = { + "QueryInterface": function(arg) { + if (!iid.equals(Components.interfaces.nsIStreamListener) + && !iid.equals(Components.interfaces.nsIRequestObserver) + && !iid.equals(Components.interfaces.nsISupports)) { + throw Components.results.NS_ERROR_NO_INTERFACE; + } + return this; + }, + + "onStartRequest": function(aRequest, aContext) { + this._stream = Cc["@mozilla.org/binaryinputstream;1"]. + createInstance(Ci.nsIBinaryInputStream); + this._bytes = ""; + this.oldListener.onStartRequest(aRequest, aContext); + }, + + "onStopRequest": function(aRequest, aContext, aStatusCode) { + var requestFailed = !Components.isSuccessCode(aStatusCode); + if(!requestFailed && (aRequest instanceof Ci.nsIHttpChannel)) + requestFailed = !aRequest.requestSucceeded; + + if(!requestFailed) { + var data = this._bytes.replace("{ec8030f7-c20a-464f-9b0e-13a3a9e97384}", + "toolkit@mozilla.org", "g") + var nBytes = data.length; + var inputStream = Cc["@mozilla.org/io/string-input-stream;1"]. + createInstance(Ci.nsIStringInputStream); + inputStream.setData(data, nBytes); + this.oldListener.onDataAvailable(aRequest, aContext, inputStream, 0, nBytes); + } + this.oldListener.onStopRequest(aRequest, aContext, aStatusCode); + }, + + "onDataAvailable": function(aRequest, aContext, aInputStream, aOffset, aCount) { + this._stream.setInputStream(aInputStream); + this._bytes += this._stream.readBytes(aCount); + } + }; + + this.init = function() { + // Add an observer to handle AMO requests + Components.classes["@mozilla.org/observer-service;1"]. + getService(Components.interfaces.nsIObserverService). + addObserver({ + "observe":function(ch) { + if(ch.QueryInterface(Components.interfaces.nsIRequest).URI.host + !== "versioncheck.addons.mozilla.org") return; + var newListener = new AMOStreamListener; + newListener.oldListener = ch. + QueryInterface(Components.interfaces.nsITraceableChannel). + setNewListener(newListener); + } + }, "http-on-examine-response", false); + } +} diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index fd1fc6e6e..19f29ce1e 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -444,6 +444,7 @@ const ZOTERO_CONFIG = { } else { Zotero.debug("Loading in full mode"); if(!_initFull()) return false; + if(Zotero.isStandalone) Zotero.Standalone.init(); Zotero.initComplete(); } diff --git a/components/zotero-service.js b/components/zotero-service.js index 070c06273..4bf06bf98 100644 --- a/components/zotero-service.js +++ b/components/zotero-service.js @@ -250,6 +250,13 @@ function makeZoteroContext(isConnector) { .loadSubScript("chrome://zotero/content/xpcom/" + rdfXpcomFiles[i] + ".js", zContext.Zotero.RDF.AJAW); } + if(isStandalone()) { + // If isStandalone, load standalone.js + Cc["@mozilla.org/moz/jssubscript-loader;1"] + .getService(Ci.mozIJSSubScriptLoader) + .loadSubScript("chrome://zotero/content/xpcom/standalone.js", zContext); + } + // load nsTransferable (query: do we still use this?) Cc["@mozilla.org/moz/jssubscript-loader;1"] .getService(Ci.mozIJSSubScriptLoader)