diff --git a/chrome.manifest b/chrome.manifest index 3deb0281b..92e453a5c 100644 --- a/chrome.manifest +++ b/chrome.manifest @@ -50,3 +50,16 @@ overlay chrome://browser/content/browser.xul chrome://zotero/content/itemPane.xu style chrome://browser/content/browser.xul chrome://zotero/skin/zotero.css style chrome://global/content/customizeToolbar.xul chrome://zotero/skin/zotero.css + +component {e4c61080-ec2d-11da-8ad9-0800200c9a66} components/zotero-service.js +contract @zotero.org/Zotero;1 {e4c61080-ec2d-11da-8ad9-0800200c9a66} + +component {06a2ed11-d0a4-4ff0-a56f-a44545eee6ea} components/zotero-autocomplete.js +contract @mozilla.org/autocomplete/search;1?name=zotero {06a2ed11-d0a4-4ff0-a56f-a44545eee6ea} + +component {9BC3D762-9038-486A-9D70-C997AF848A7C} components/zotero-protocol-handler.js +contract @mozilla.org/network/protocol;1?name=Zotero {9BC3D762-9038-486A-9D70-C997AF848A7C} + +component {531828f8-a16c-46be-b9aa-14845c3b010f} components/zotero-integration-service.js +contract @mozilla.org/commandlinehandler/general-startup;1?type=zotero-integration {531828f8-a16c-46be-b9aa-14845c3b010f} +category command-line-handler m-zotero-integration @mozilla.org/commandlinehandler/general-startup;1?type=zotero-integration diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 24c14586d..229937226 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -188,30 +188,33 @@ var Zotero = new function(){ var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]. - getService(Components.interfaces.nsIXULAppInfo) + getService(Components.interfaces.nsIXULAppInfo); + this.appName = appInfo.name; + this.isFx2 = appInfo.platformVersion.indexOf('1.8') === 0; // TODO: remove + this.isFx3 = appInfo.platformVersion.indexOf('1.9') === 0; + this.isFx30 = appInfo.platformVersion == '1.9' + || appInfo.platformVersion.indexOf('1.9.0') === 0; + this.isFx35 = appInfo.platformVersion.indexOf('1.9.1') === 0; + this.isFx31 = this.isFx35; + this.isFx36 = appInfo.platformVersion.indexOf('1.9.2') === 0; + this.isFx4 = appInfo.platformVersion[0] == 2; + this.isStandalone = appInfo.ID == ZOTERO_CONFIG['GUID']; - Zotero.debug(this.isStandalone); if(this.isStandalone) { - this.isFx35 = true; this.version = appInfo.version; } else { - this.appName = appInfo.name; - this.isFx2 = appInfo.platformVersion.indexOf('1.8') === 0; // TODO: remove - this.isFx3 = appInfo.platformVersion.indexOf('1.9') === 0; - this.isFx30 = appInfo.platformVersion == '1.9' - || appInfo.platformVersion.indexOf('1.9.0') === 0; - this.isFx35 = appInfo.platformVersion.indexOf('1.9.1') === 0; - this.isFx31 = this.isFx35; - // Load in the extension version from the extension manager - var nsIUpdateItem = Components.interfaces.nsIUpdateItem; - var gExtensionManager = - Components.classes["@mozilla.org/extensions/manager;1"] - .getService(Components.interfaces.nsIExtensionManager); - this.version - = gExtensionManager.getItemForID(ZOTERO_CONFIG['GUID']).version; + if(this.isFx4) { + AddonManager.getAddonByID(ZOTERO_CONFIG['GUID'], + function(addon) { Zotero.version = addon.version }); + } else { + var gExtensionManager = + Components.classes["@mozilla.org/extensions/manager;1"] + .getService(Components.interfaces.nsIExtensionManager); + this.version + = gExtensionManager.getItemForID(ZOTERO_CONFIG['GUID']).version; + } } - this.isFx36 = appInfo.platformVersion.indexOf('1.9.2') === 0; // OS platform var win = Components.classes["@mozilla.org/appshell/appShellService;1"] @@ -223,6 +226,13 @@ var Zotero = new function(){ this.isLinux = (this.platform.substr(0, 5) == "Linux"); this.oscpu = win.navigator.oscpu; + // Installed extensions (Fx4 only) + if(this.isFx4) { + AddonManager.getAllAddons(function(addonList) { + Zotero.addons = addonList; + }); + } + // Locale var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"]. getService(Components.interfaces.nsIHttpProtocolHandler); @@ -398,11 +408,10 @@ var Zotero = new function(){ Zotero.Schema.updateCustomTables(); } - // Initialize integration web server + // Initialize various services Zotero.Integration.init(); + Zotero.Connector.init(); - // Initialize data web server - Zotero.DataServer.init(); Zotero.Zeroconf.init(); Zotero.Sync.init(); @@ -457,10 +466,25 @@ var Zotero = new function(){ Zotero.debug(dir.path); return dir; } else { - var id = ZOTERO_CONFIG.GUID; - var em = Components.classes["@mozilla.org/extensions/manager;1"]. - getService(Components.interfaces.nsIExtensionManager); - return em.getInstallLocation(id).getItemLocation(id); + if(this.isFx4) { + /* TODO: + From https://developer.mozilla.org/en/Firefox_4_for_developers: + nsIExtensionManager has been replaced by AddonManager. Since there is + apparently no way at present to obtain the install location from a given + extension ID, the closest workaround is to use the directory service to + find the profile directory and append "extensions" to it (though this + approach will not catch extensions outside of the profile directory or + those which are aliased to another location). */ + var profDir = getProfileDirectory(); + profDir.append("extensions"); + profDir.append(ZOTERO_CONFIG.GUID); + return profDir; + } else { + var id = ZOTERO_CONFIG.GUID; + var em = Components.classes["@mozilla.org/extensions/manager;1"]. + getService(Components.interfaces.nsIExtensionManager); + return em.getInstallLocation(id).getItemLocation(id); + } } } @@ -782,11 +806,15 @@ var Zotero = new function(){ * @return {String[]} Array of extension names and versions */ this.getInstalledExtensions = function () { - var em = Components.classes["@mozilla.org/extensions/manager;1"]. - getService(Components.interfaces.nsIExtensionManager); - var installed = em.getItemList( - Components.interfaces.nsIUpdateItem.TYPE_ANY, {} - ); + if(this.isFx4) { + var installed = Zotero.addons; + } else { + var em = Components.classes["@mozilla.org/extensions/manager;1"]. + getService(Components.interfaces.nsIExtensionManager); + var installed = em.getItemList( + Components.interfaces.nsIUpdateItem.TYPE_ANY, {} + ); + } var addons = []; for each(var addon in installed) { diff --git a/components/zotero-autocomplete.js b/components/zotero-autocomplete.js index 73dbf287d..c5df89f7f 100644 --- a/components/zotero-autocomplete.js +++ b/components/zotero-autocomplete.js @@ -31,6 +31,7 @@ const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); /* * Implements nsIAutoCompleteSearch @@ -335,68 +336,24 @@ ZoteroAutoComplete.prototype.stopSearch = function(){ } } - -ZoteroAutoComplete.prototype.QueryInterface = function(iid){ - if (!iid.equals(Ci.nsIAutoCompleteSearch) && - !iid.equals(Ci.nsIAutoCompleteObserver) && - !iid.equals(Ci.nsISupports)){ - throw Cr.NS_ERROR_NO_INTERFACE; - } - return this; -} - - - // // XPCOM goop // -var ZoteroAutoCompleteFactory = { - createInstance: function(outer, iid){ - if (outer != null){ - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return new ZoteroAutoComplete().QueryInterface(iid); - } -}; +ZoteroAutoComplete.prototype.classDescription = ZOTERO_AC_CLASSNAME; +ZoteroAutoComplete.prototype.classID = ZOTERO_AC_CID; +ZoteroAutoComplete.prototype.contractID = ZOTERO_AC_CONTRACTID; +ZoteroAutoComplete.prototype.QueryInterface = XPCOMUtils.generateQI([ + Components.interfaces.nsIAutoCompleteSearch, + Components.interfaces.nsIAutoCompleteObserver, + Components.interfaces.nsISupports]); -var ZoteroAutoCompleteModule = { - _firstTime: true, - - registerSelf: function(compMgr, fileSpec, location, type){ - if (!this._firstTime){ - throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN; - } - this._firstTime = false; - - compMgr = - compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); - - compMgr.registerFactoryLocation(ZOTERO_AC_CID, - ZOTERO_AC_CLASSNAME, - ZOTERO_AC_CONTRACTID, - fileSpec, - location, - type); - }, - - unregisterSelf: function(compMgr, location, type){ - compMgr = - compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); - compMgr.unregisterFactoryLocation(ZOTERO_AC_CID, location); - }, - - getClassObject: function(compMgr, cid, iid){ - if (!cid.equals(ZOTERO_AC_CID)){ - throw Components.results.NS_ERROR_NO_INTERFACE; - } - if (!iid.equals(Components.interfaces.nsIFactory)){ - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - return ZoteroAutoCompleteFactory; - }, - - canUnload: function(compMgr){ return true; } -}; - -function NSGetModule(comMgr, fileSpec){ return ZoteroAutoCompleteModule; } +/** +* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4). +* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6). +*/ +if (XPCOMUtils.generateNSGetFactory) { + var NSGetFactory = XPCOMUtils.generateNSGetFactory([ZoteroAutoComplete]); +} else { + var NSGetModule = XPCOMUtils.generateNSGetModule([ZoteroAutoComplete]); +} \ No newline at end of file diff --git a/components/zotero-integration-service.js b/components/zotero-integration-service.js index 04058da2c..05f4d0f7a 100644 --- a/components/zotero-integration-service.js +++ b/components/zotero-integration-service.js @@ -1,3 +1,32 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2009 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 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Zotero. If not, see . + + + Based on nsChromeExtensionHandler example code by Ed Anuff at + http://kb.mozillazine.org/Dev_:_Extending_the_Chrome_Protocol + + ***** END LICENSE BLOCK ***** +*/ + /* Based on nsICommandLineHandler example code at https://developer.mozilla.org/en/Chrome/Command_Line @@ -15,12 +44,15 @@ const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher; const clh_contractID = "@mozilla.org/commandlinehandler/general-startup;1?type=zotero-integration"; const clh_CID = Components.ID("{531828f8-a16c-46be-b9aa-14845c3b010f}"); const clh_category = "m-zotero-integration"; +const clh_description = "Zotero Integration Command Line Handler"; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); /** * The XPCOM component that implements nsICommandLineHandler. - * It also implements nsIFactory to serve as its own singleton factory. */ -const ZoteroIntegrationCommandLineHandler = { +function ZoteroIntegrationCommandLineHandler() {} +ZoteroIntegrationCommandLineHandler.prototype = { Zotero : null, /* nsISupports */ @@ -47,65 +79,21 @@ const ZoteroIntegrationCommandLineHandler = { } }, - /* nsIFactory */ - createInstance : function(outer, iid) { - if (outer != null) throw Components.results.NS_ERROR_NO_AGGREGATION; - return this.QueryInterface(iid); - }, - - lockFactory : function(lock) { - /* no-op */ - } + classDescription: clh_description, + classID: clh_CID, + contractID: clh_contractID, + service: true, + _xpcom_categories: [{category:"command-line-handler", entry:clh_category}], + QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler, + Components.interfaces.nsISupports]) }; /** - * The XPCOM glue that implements nsIModule - */ -const ZoteroIntegrationModule = { - /* nsISupports */ - QueryInterface : function(iid) { - if(iid.equals(nsIModule) || iid.equals(nsISupports)) return this; - throw Components.results.NS_ERROR_NO_INTERFACE; - }, - - /* nsIModule */ - getClassObject : function(compMgr, cid, iid) { - if(cid.equals(clh_CID)) return ZoteroIntegrationCommandLineHandler.QueryInterface(iid); - throw Components.results.NS_ERROR_NOT_REGISTERED; - }, - - registerSelf : function(compMgr, fileSpec, location, type) { - compMgr.QueryInterface(nsIComponentRegistrar); - - compMgr.registerFactoryLocation(clh_CID, - "myAppHandler", - clh_contractID, - fileSpec, - location, - type); - - var catMan = Components.classes["@mozilla.org/categorymanager;1"]. - getService(nsICategoryManager); - catMan.addCategoryEntry("command-line-handler", - clh_category, - clh_contractID, true, true); - }, - - unregisterSelf : function(compMgr, location, type) { - compMgr.QueryInterface(nsIComponentRegistrar); - compMgr.unregisterFactoryLocation(clh_CID, location); - - var catMan = Components.classes["@mozilla.org/categorymanager;1"]. - getService(nsICategoryManager); - catMan.deleteCategoryEntry("command-line-handler", clh_category); - }, - - canUnload : function (compMgr) { - return true; - } -}; - -/* The NSGetModule function is the magic entry point that XPCOM uses to find what XPCOM objects - * this component provides - */ -function NSGetModule(comMgr, fileSpec){ return ZoteroIntegrationModule; } +* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4). +* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6). +*/ +if (XPCOMUtils.generateNSGetFactory) { + var NSGetFactory = XPCOMUtils.generateNSGetFactory([ZoteroIntegrationCommandLineHandler]); +} else { + var NSGetModule = XPCOMUtils.generateNSGetModule([ZoteroIntegrationCommandLineHandler]); +} \ No newline at end of file diff --git a/components/zotero-protocol-handler.js b/components/zotero-protocol-handler.js index 72c7f11ee..e6161a4ac 100644 --- a/components/zotero-protocol-handler.js +++ b/components/zotero-protocol-handler.js @@ -27,12 +27,13 @@ ***** END LICENSE BLOCK ***** */ - const ZOTERO_SCHEME = "zotero"; const ZOTERO_PROTOCOL_CID = Components.ID("{9BC3D762-9038-486A-9D70-C997AF848A7C}"); const ZOTERO_PROTOCOL_CONTRACTID = "@mozilla.org/network/protocol;1?name=" + ZOTERO_SCHEME; const ZOTERO_PROTOCOL_NAME = "Zotero Chrome Extension Protocol"; +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + // Dummy chrome URL used to obtain a valid chrome channel // This one was chosen at random and should be able to be substituted // for any other well known chrome URL in the browser installation @@ -943,7 +944,6 @@ function ChromeExtensionHandler() { } }; - var ReportExtensionSpec = ZOTERO_SCHEME + "://report" this._extensions[ReportExtensionSpec] = ReportExtension; @@ -1035,7 +1035,7 @@ ChromeExtensionHandler.prototype = { extChannel.owner = this._systemPrincipal; } - extChannel.originalURI = uri; + if(!extChannel.originalURI) extChannel.originalURI = uri; return extChannel; } @@ -1057,62 +1057,23 @@ ChromeExtensionHandler.prototype = { return newChannel; }, - QueryInterface : function(iid) { - if (!iid.equals(Components.interfaces.nsIProtocolHandler) && - !iid.equals(Components.interfaces.nsISupports)) { - throw Components.results.NS_ERROR_NO_INTERFACE; - } - return this; - } + contractID: ZOTERO_PROTOCOL_CONTRACTID, + classDescription: ZOTERO_PROTOCOL_NAME, + classID: ZOTERO_PROTOCOL_CID, + QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports, + Components.interfaces.nsIProtocolHandler]) }; - // // XPCOM goop // -var ChromeExtensionModule = { - cid: ZOTERO_PROTOCOL_CID, - - contractId: ZOTERO_PROTOCOL_CONTRACTID, - - registerSelf : function(compMgr, fileSpec, location, type) { - compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); - compMgr.registerFactoryLocation( - ZOTERO_PROTOCOL_CID, - ZOTERO_PROTOCOL_NAME, - ZOTERO_PROTOCOL_CONTRACTID, - fileSpec, - location, - type - ); - }, - - getClassObject : function(compMgr, cid, iid) { - if (!cid.equals(ZOTERO_PROTOCOL_CID)) { - throw Components.results.NS_ERROR_NO_INTERFACE; - } - if (!iid.equals(Components.interfaces.nsIFactory)) { - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - return this.myFactory; - }, - - canUnload : function(compMgr) { - return true; - }, - - myFactory : { - createInstance : function(outer, iid) { - if (outer != null) { - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - - return new ChromeExtensionHandler().QueryInterface(iid); - } - } -}; - -function NSGetModule(compMgr, fileSpec) { - return ChromeExtensionModule; -} +/** +* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4). +* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6). +*/ +if (XPCOMUtils.generateNSGetFactory) { + var NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeExtensionHandler]); +} else { + var NSGetModule = XPCOMUtils.generateNSGetModule([ChromeExtensionHandler]); +} \ No newline at end of file diff --git a/components/zotero-service.js b/components/zotero-service.js index 4d9138b16..f4b031be7 100644 --- a/components/zotero-service.js +++ b/components/zotero-service.js @@ -1,3 +1,32 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2009 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 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Zotero. If not, see . + + + Based on nsChromeExtensionHandler example code by Ed Anuff at + http://kb.mozillazine.org/Dev_:_Extending_the_Chrome_Protocol + + ***** END LICENSE BLOCK ***** +*/ + const ZOTERO_CONTRACTID = '@zotero.org/Zotero;1'; const ZOTERO_CLASSNAME = 'Zotero'; const ZOTERO_CID = Components.ID('{e4c61080-ec2d-11da-8ad9-0800200c9a66}'); @@ -6,10 +35,17 @@ const ZOTERO_IID = Components.interfaces.chnmIZoteroService; //unused const Cc = Components.classes; const Ci = Components.interfaces; +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]. + getService(Components.interfaces.nsIXULAppInfo); +if(appInfo.platformVersion[0] == 2) { + Components.utils.import("resource://gre/modules/AddonManager.jsm"); +} + // Assign the global scope to a variable to passed via wrappedJSObject var ZoteroWrapped = this; - /******************************************************************** * Include the core objects to be stored within XPCOM *********************************************************************/ @@ -154,6 +190,7 @@ function ZoteroService(){ /** * Convenience method to replicate window.alert() **/ +// TODO: is this still used? if so, move to zotero.js function alert(msg){ Cc["@mozilla.org/embedcomp/prompt-service;1"] .getService(Ci.nsIPromptService) @@ -163,6 +200,7 @@ function alert(msg){ /** * Convenience method to replicate window.confirm() **/ +// TODO: is this still used? if so, move to zotero.js function confirm(msg){ return Cc["@mozilla.org/embedcomp/prompt-service;1"] .getService(Ci.nsIPromptService) @@ -173,6 +211,7 @@ function confirm(msg){ /** * Convenience method to replicate window.setTimeout() **/ +// TODO: is this still used? if so, move to zotero.js function setTimeout(func, ms){ var timer = Components.classes["@mozilla.org/timer;1"]. createInstance(Components.interfaces.nsITimer); @@ -186,64 +225,21 @@ function setTimeout(func, ms){ // // XPCOM goop // + ZoteroService.prototype = { - QueryInterface: function(iid){ - if (!iid.equals(Components.interfaces.nsISupports) && - !iid.equals(ZOTERO_IID)){ // interface unused - throw Components.results.NS_ERROR_NO_INTERFACE; - } - return this; - } -}; + contractID: ZOTERO_CONTRACTID, + classDescription: ZOTERO_CLASSNAME, + classID: ZOTERO_CID, + service: true, + QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports, ZOTERO_IID]) +} - -var ZoteroFactory = { - createInstance: function(outer, iid){ - if (outer != null){ - throw Components.results.NS_ERROR_NO_AGGREGATION; - } - return new ZoteroService().QueryInterface(iid); - } -}; - - -var ZoteroModule = { - _firstTime: true, - - registerSelf: function(compMgr, fileSpec, location, type){ - if (!this._firstTime){ - throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN; - } - this._firstTime = false; - - compMgr = - compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); - - compMgr.registerFactoryLocation(ZOTERO_CID, - ZOTERO_CLASSNAME, - ZOTERO_CONTRACTID, - fileSpec, - location, - type); - }, - - unregisterSelf: function(compMgr, location, type){ - compMgr = - compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); - compMgr.unregisterFactoryLocation(ZOTERO_CID, location); - }, - - getClassObject: function(compMgr, cid, iid){ - if (!cid.equals(ZOTERO_CID)){ - throw Components.results.NS_ERROR_NO_INTERFACE; - } - if (!iid.equals(Components.interfaces.nsIFactory)){ - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - return ZoteroFactory; - }, - - canUnload: function(compMgr){ return true; } -}; - -function NSGetModule(comMgr, fileSpec){ return ZoteroModule; } +/** +* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4). +* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6). +*/ +if (XPCOMUtils.generateNSGetFactory) { + var NSGetFactory = XPCOMUtils.generateNSGetFactory([ZoteroService]); +} else { + var NSGetModule = XPCOMUtils.generateNSGetModule([ZoteroService]); +} \ No newline at end of file