From 2556e5364804247bfd07dc95401b22fa5df9972b Mon Sep 17 00:00:00 2001 From: "reed%reedloden.com" Date: Sun, 13 Jan 2008 07:48:33 +0000 Subject: [PATCH] Bug 407963 - "[FUEL] Factor out generic toolkit aspects of FUEL into a reusable form" [p=jminta@gmail.com (Joey Minta) r=mfinkle r=gavin sr=bsmedberg a1.9=beltzner] git-svn-id: svn://10.0.0.236/trunk@242992 18797224-902f-48f8-a5cc-f745e15eee43 --- .../browser/fuel/public/fuelIApplication.idl | 434 ++--------- mozilla/browser/fuel/src/fuelApplication.js | 654 +---------------- mozilla/toolkit/components/Makefile.in | 1 + .../toolkit/components/exthelper/Makefile.in | 50 ++ .../components/exthelper/extApplication.js | 692 ++++++++++++++++++ .../components/exthelper/extIApplication.idl | 429 +++++++++++ 6 files changed, 1232 insertions(+), 1028 deletions(-) create mode 100644 mozilla/toolkit/components/exthelper/Makefile.in create mode 100644 mozilla/toolkit/components/exthelper/extApplication.js create mode 100644 mozilla/toolkit/components/exthelper/extIApplication.idl diff --git a/mozilla/browser/fuel/public/fuelIApplication.idl b/mozilla/browser/fuel/public/fuelIApplication.idl index 852eb990f44..d1300cfe8d4 100644 --- a/mozilla/browser/fuel/public/fuelIApplication.idl +++ b/mozilla/browser/fuel/public/fuelIApplication.idl @@ -1,354 +1,50 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FUEL. + * + * The Initial Developer of the Original Code is Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mark Finkle (Original Author) + * John Resig (Original Author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + #include "nsISupports.idl" +#include "extIApplication.idl" interface nsIVariant; interface nsIURI; interface nsIDOMHTMLDocument; -interface fuelIPreference; interface fuelIBookmarkFolder; interface fuelIBrowserTab; -/** - * Interface that gives simplified access to the console - */ -[scriptable, uuid(ae8482e0-aa5a-11db-abbd-0800200c9a66)] -interface fuelIConsole : nsISupports -{ - /** - * Sends a given string to the console. - * @param aMsg - * The text to send to the console - */ - void log(in AString aMsg); - - /** - * Opens the error console window. The console window - * is focused if already open. - */ - void open(); -}; - - -/** - * Interface holds information about an event. - */ -[scriptable, function, uuid(05281820-ab62-11db-abbd-0800200c9a66)] -interface fuelIEventItem : nsISupports -{ - /** - * The name of the event - */ - readonly attribute AString type; - - /** - * Can hold extra details and data associated with the event. This - * is optional and event specific. If the event does not send extra - * details, this is null. - */ - readonly attribute AString data; - - /** - * Cancels the event if it is cancelable. - */ - void preventDefault(); -}; - - -/** - * Interface used as a callback for listening to events. - */ -[scriptable, function, uuid(2dfe3a50-ab2f-11db-abbd-0800200c9a66)] -interface fuelIEventListener : nsISupports -{ - /** - * This method is called whenever an event occurs of the type for which - * the fuelIEventListener interface was registered. - * - * @param aEvent - * The fuelIEventItem associated with the event. - */ - void handleEvent(in fuelIEventItem aEvent); -}; - - -/** - * Interface for supporting custom events. - */ -[scriptable, uuid(3a8ec9d0-ab19-11db-abbd-0800200c9a66)] -interface fuelIEvents : nsISupports -{ - /** - * Adds an event listener to the list. If multiple identical event listeners - * are registered on the same event target with the same parameters the - * duplicate instances are discarded. They do not cause the EventListener - * to be called twice and since they are discarded they do not need to be - * removed with the removeListener method. - * - * @param aEvent - * The name of an event - * @param aListener - * The reference to a listener - */ - void addListener(in AString aEvent, in fuelIEventListener aListener); - - /** - * Removes an event listener from the list. Calling remove - * with arguments which do not identify any currently registered - * event listener has no effect. - * @param aEvent - * The name of an event - * @param aListener - * The reference to a listener - */ - void removeListener(in AString aEvent, in fuelIEventListener aListener); -}; - - -/** - * Interface for simplified access to preferences. The interface has a - * predefined root preference branch. The root branch is set based on the - * context of the owner. For example, an extension's preferences have a root - * of "extensions..", while the application level preferences - * have an empty root. All preference "aName" parameters used in this interface - * are relative to the root branch. - */ -[scriptable, uuid(ce697d40-aa5a-11db-abbd-0800200c9a66)] -interface fuelIPreferenceBranch : nsISupports -{ - /** - * The name of the branch root. - */ - readonly attribute AString root; - - /** - * Array of fuelIPreference listing all preferences in this branch. - */ - readonly attribute nsIVariant all; - - /** - * The events object for the preferences - * supports: "change" - */ - readonly attribute fuelIEvents events; - - /** - * Check to see if a preference exists. - * @param aName - * The name of preference - * @returns true if the preference exists, false if not - */ - boolean has(in AString aName); - - /** - * Gets an object representing a preference - * @param aName - * The name of preference - * @returns a preference object, or null if the preference does not exist - */ - fuelIPreference get(in AString aName); - - /** - * Gets the value of a preference. Returns a default value if - * the preference does not exist. - * @param aName - * The name of preference - * @param aDefaultValue - * The value to return if preference does not exist - * @returns value of the preference or the given default value if preference - * does not exists. - */ - nsIVariant getValue(in AString aName, in nsIVariant aDefaultValue); - - /** - * Sets the value of a storage item with the given name. - * @param aName - * The name of an item - * @param aValue - * The value to assign to the item - */ - void setValue(in AString aName, in nsIVariant aValue); - - /** - * Resets all preferences in a branch back to their default values. - */ - void reset(); -}; - -/** - * Interface for accessing a single preference. The data is not cached. - * All reads access the current state of the preference. - */ -[scriptable, uuid(2C7462E2-72C2-4473-9007-0E6AE71E23CA)] -interface fuelIPreference : nsISupports -{ - /** - * The name of the preference. - */ - readonly attribute AString name; - - /** - * A string representing the type of preference (String, Boolean, or Number). - */ - readonly attribute AString type; - - /** - * Get/Set the value of the preference. - */ - attribute nsIVariant value; - - /** - * Get the locked state of the preference. Set to a boolean value to (un)lock it. - */ - attribute boolean locked; - - /** - * Check if a preference has been modified by the user, or not. - */ - readonly attribute boolean modified; - - /** - * The preference branch that contains this preference. - */ - readonly attribute fuelIPreferenceBranch branch; - - /** - * The events object for this preference. - * supports: "change" - */ - readonly attribute fuelIEvents events; - - /** - * Resets a preference back to its default values. - */ - void reset(); -}; - - -/** - * Interface representing a simple storage system - */ -[scriptable, uuid(0787ac44-29b9-4889-b97f-13573aec6971)] -interface fuelISessionStorage : nsISupports -{ - /** - * The events object for the storage - * supports: "change" - */ - readonly attribute fuelIEvents events; - - /** - * Determines if a storage item exists with the given name. - * @param aName - * The name of an item - * @returns true if an item exists with the given name, - * false otherwise. - */ - boolean has(in AString aName); - - /** - * Sets the value of a storage item with the given name. - * @param aName - * The name of an item - * @param aValue - * The value to assign to the item - */ - void set(in AString aName, in nsIVariant aValue); - - /** - * Gets the value of a storage item with the given name. Returns a - * default value if the item does not exist. - * @param aName - * The name of an item - * @param aDefaultValue - * The value to return if no item exists with the given name - * @returns value of the item or the given default value if no item - * exists with the given name. - */ - nsIVariant get(in AString aName, in nsIVariant aDefaultValue); -}; - - -/** - * Interface representing an extension - */ -[scriptable, uuid(10cee02c-f6e0-4d61-ab27-c16572b18c46)] -interface fuelIExtension : nsISupports -{ - /** - * The id of the extension. - */ - readonly attribute AString id; - - /** - * The name of the extension. - */ - readonly attribute AString name; - - /** - * Check if the extension is currently enabled, or not. - */ - readonly attribute boolean enabled; - - /** - * The version number of the extension. - */ - readonly attribute AString version; - - /** - * Indicates whether this is the extension's first run after install - */ - readonly attribute boolean firstRun; - - /** - * The preferences object for the extension. Defaults to the - * "extensions.." branch. - */ - readonly attribute fuelIPreferenceBranch prefs; - - /** - * The storage object for the extension. - */ - readonly attribute fuelISessionStorage storage; - - /** - * The events object for the extension. - * supports: "uninstall" - */ - readonly attribute fuelIEvents events; -}; - - -/** - * Interface representing a list of all installed extensions - */ -[scriptable, uuid(de281930-aa5a-11db-abbd-0800200c9a66)] -interface fuelIExtensions : nsISupports -{ - /** - * Array of fuelIExtension listing all extensions in the application. - */ - readonly attribute nsIVariant all; - - /** - * Determines if an extension exists with the given id. - * @param aId - * The id of an extension - * @returns true if an extension exists with the given id, - * false otherwise. - */ - boolean has(in AString aId); - - /** - * Gets a fuelIExtension object for an extension. - * @param aId - * The id of an extension - * @returns An extension object or null if no extension exists - * with the given id. - */ - fuelIExtension get(in AString aId); -}; - - /** * Interface representing a collection of annotations associated * with a bookmark or bookmark folder. @@ -452,7 +148,7 @@ interface fuelIBookmark : nsISupports * The events object for the bookmark. * supports: "remove", "change", "visit", "move" */ - readonly attribute fuelIEvents events; + readonly attribute extIEvents events; /** * Removes the item from the parent folder. Used to @@ -504,7 +200,7 @@ interface fuelIBookmarkFolder : nsISupports * The events object for the folder. * supports: "add", "addchild", "remove", "removechild", "change", "move" */ - readonly attribute fuelIEvents events; + readonly attribute extIEvents events; /** * Array of all bookmarks, separators and folders contained @@ -567,7 +263,7 @@ interface fuelIWindow : nsISupports * The events object for the browser window. * supports: "TabOpen", "TabClose", "TabMove", "TabSelect" */ - readonly attribute fuelIEvents events; + readonly attribute extIEvents events; }; /** @@ -600,7 +296,7 @@ interface fuelIBrowserTab : nsISupports * The events object for the browser tab. * supports: "load" */ - readonly attribute fuelIEvents events; + readonly attribute extIEvents events; /** * Load a new URI into this browser tab. @@ -633,56 +329,12 @@ interface fuelIBrowserTab : nsISupports void moveToEnd(); }; - /** * Interface for managing and accessing the applications systems */ [scriptable, uuid(fe74cf80-aa2d-11db-abbd-0800200c9a66)] -interface fuelIApplication : nsISupports +interface fuelIApplication : extIApplication { - /** - * The id of the application. - */ - readonly attribute AString id; - - /** - * The name of the application. - */ - readonly attribute AString name; - - /** - * The version number of the application. - */ - readonly attribute AString version; - - /** - * The console object for the application. - */ - readonly attribute fuelIConsole console; - - /** - * The extensions object for the application. Contains a list - * of all installed extensions. - */ - readonly attribute fuelIExtensions extensions; - - /** - * The preferences object for the application. Defaults to an empty - * root branch. - */ - readonly attribute fuelIPreferenceBranch prefs; - - /** - * The storage object for the application. - */ - readonly attribute fuelISessionStorage storage; - - /** - * The events object for the application. - * supports: "load", "ready", "quit", "unload" - */ - readonly attribute fuelIEvents events; - /** * The root bookmarks object for the application. */ diff --git a/mozilla/browser/fuel/src/fuelApplication.js b/mozilla/browser/fuel/src/fuelApplication.js index 890f651a123..284dc78e9b9 100644 --- a/mozilla/browser/fuel/src/fuelApplication.js +++ b/mozilla/browser/fuel/src/fuelApplication.js @@ -40,520 +40,6 @@ const Cc = Components.classes; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -//================================================= -// Shutdown - used to store cleanup functions which will -// be called on Application shutdown -var gShutdown = []; - -//================================================= -// Console constructor -function Console() { - this._console = Components.classes["@mozilla.org/consoleservice;1"] - .getService(Ci.nsIConsoleService); -} - -//================================================= -// Console implementation -Console.prototype = { - log : function cs_log(aMsg) { - this._console.logStringMessage(aMsg); - }, - - open : function cs_open() { - var wMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Ci.nsIWindowMediator); - var console = wMediator.getMostRecentWindow("global:console"); - if (!console) { - var wWatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] - .getService(Ci.nsIWindowWatcher); - wWatch.openWindow(null, "chrome://global/content/console.xul", "_blank", - "chrome,dialog=no,all", null); - } else { - // console was already open - console.focus(); - } - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIConsole]) -}; - - -//================================================= -// EventItem constructor -function EventItem(aType, aData) { - this._type = aType; - this._data = aData; -} - -//================================================= -// EventItem implementation -EventItem.prototype = { - _cancel : false, - - get type() { - return this._type; - }, - - get data() { - return this._data; - }, - - preventDefault : function ei_pd() { - this._cancel = true; - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIEventItem]) -}; - - -//================================================= -// Events constructor -function Events() { - this._listeners = []; -} - -//================================================= -// Events implementation -Events.prototype = { - addListener : function evts_al(aEvent, aListener) { - if (this._listeners.some(hasFilter)) - return; - - this._listeners.push({ - event: aEvent, - listener: aListener - }); - - function hasFilter(element) { - return element.event == aEvent && element.listener == aListener; - } - }, - - removeListener : function evts_rl(aEvent, aListener) { - this._listeners = this._listeners.filter(function(element){ - return element.event != aEvent && element.listener != aListener; - }); - }, - - dispatch : function evts_dispatch(aEvent, aEventItem) { - eventItem = new EventItem(aEvent, aEventItem); - - this._listeners.forEach(function(key){ - if (key.event == aEvent) { - key.listener.handleEvent ? - key.listener.handleEvent(eventItem) : - key.listener(eventItem); - } - }); - - return !eventItem._cancel; - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIEvents]) -}; - - -//================================================= -// PreferenceBranch constructor -function PreferenceBranch(aBranch) { - if (!aBranch) - aBranch = ""; - - this._root = aBranch; - this._prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService); - - if (aBranch) - this._prefs = this._prefs.getBranch(aBranch); - - this._prefs.QueryInterface(Ci.nsIPrefBranch); - this._prefs.QueryInterface(Ci.nsIPrefBranch2); - - // we want to listen to "all" changes for this branch, so pass in a blank domain - this._prefs.addObserver("", this, true); - this._events = new Events(); - - var self = this; - gShutdown.push(function() { self._shutdown(); }); -} - -//================================================= -// PreferenceBranch implementation -PreferenceBranch.prototype = { - // cleanup observer so we don't leak - _shutdown: function prefs_shutdown() { - this._prefs.removeObserver(this._root, this); - - this._prefs = null; - this._events = null; - }, - - // for nsIObserver - observe: function prefs_observe(aSubject, aTopic, aData) { - if (aTopic == "nsPref:changed") - this._events.dispatch("change", aData); - }, - - get root() { - return this._root; - }, - - get all() { - return this.find({}); - }, - - get events() { - return this._events; - }, - - // XXX: Disabled until we can figure out the wrapped object issues - // name: "name" or /name/ - // path: "foo.bar." or "" or /fo+\.bar/ - // type: Boolean, Number, String (getPrefType) - // locked: true, false (prefIsLocked) - // modified: true, false (prefHasUserValue) - find : function prefs_find(aOptions) { - var retVal = []; - var items = this._prefs.getChildList("", []); - - for (var i = 0; i < items.length; i++) { - retVal.push(new Preference(items[i], this)); - } - - return retVal; - }, - - has : function prefs_has(aName) { - return (this._prefs.getPrefType(aName) != Ci.nsIPrefBranch.PREF_INVALID); - }, - - get : function prefs_get(aName) { - return this.has(aName) ? new Preference(aName, this) : null; - }, - - getValue : function prefs_gv(aName, aValue) { - var type = this._prefs.getPrefType(aName); - - switch (type) { - case Ci.nsIPrefBranch2.PREF_STRING: - aValue = this._prefs.getComplexValue(aName, Ci.nsISupportsString).data; - break; - case Ci.nsIPrefBranch2.PREF_BOOL: - aValue = this._prefs.getBoolPref(aName); - break; - case Ci.nsIPrefBranch2.PREF_INT: - aValue = this._prefs.getIntPref(aName); - break; - } - - return aValue; - }, - - setValue : function prefs_sv(aName, aValue) { - var type = aValue != null ? aValue.constructor.name : ""; - - switch (type) { - case "String": - var str = Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Ci.nsISupportsString); - str.data = aValue; - this._prefs.setComplexValue(aName, Ci.nsISupportsString, str); - break; - case "Boolean": - this._prefs.setBoolPref(aName, aValue); - break; - case "Number": - this._prefs.setIntPref(aName, aValue); - break; - default: - throw("Unknown preference value specified."); - } - }, - - reset : function prefs_reset() { - this._prefs.resetBranch(""); - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIPreferenceBranch, Ci.nsISupportsWeakReference]) -}; - - -//================================================= -// Preference constructor -function Preference(aName, aBranch) { - this._name = aName; - this._branch = aBranch; - this._events = new Events(); - - var self = this; - - this.branch.events.addListener("change", function(aEvent){ - if (aEvent.data == self.name) - self.events.dispatch(aEvent.type, aEvent.data); - }); -} - -//================================================= -// Preference implementation -Preference.prototype = { - get name() { - return this._name; - }, - - get type() { - var value = ""; - var type = this._prefs.getPrefType(name); - - switch (type) { - case Ci.nsIPrefBranch2.PREF_STRING: - value = "String"; - break; - case Ci.nsIPrefBranch2.PREF_BOOL: - value = "Boolean"; - break; - case Ci.nsIPrefBranch2.PREF_INT: - value = "Number"; - break; - } - - return value; - }, - - get value() { - return this.branch.getValue(this._name, null); - }, - - set value(aValue) { - return this.branch.setValue(this._name, aValue); - }, - - get locked() { - return this.branch._prefs.prefIsLocked(this.name); - }, - - set locked(aValue) { - this.branch._prefs[ aValue ? "lockPref" : "unlockPref" ](this.name); - }, - - get modified() { - return this.branch._prefs.prefHasUserValue(this.name); - }, - - get branch() { - return this._branch; - }, - - get events() { - return this._events; - }, - - reset : function pref_reset() { - this.branch._prefs.clearUserPref(this.name); - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIPreference]) -}; - - -//================================================= -// SessionStorage constructor -function SessionStorage() { - this._storage = {}; - this._events = new Events(); -} - -//================================================= -// SessionStorage implementation -SessionStorage.prototype = { - get events() { - return this._events; - }, - - has : function ss_has(aName) { - return this._storage.hasOwnProperty(aName); - }, - - set : function ss_set(aName, aValue) { - this._storage[aName] = aValue; - this._events.dispatch("change", aName); - }, - - get : function ss_get(aName, aDefaultValue) { - return this.has(aName) ? this._storage[aName] : aDefaultValue; - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelISessionStorage]) -}; - - -//================================================= -// Extension constructor -function Extension(aItem) { - this._item = aItem; - this._firstRun = false; - this._prefs = new PreferenceBranch("extensions." + this._item.id + "."); - this._storage = new SessionStorage(); - this._events = new Events(); - - var installPref = "install-event-fired"; - if (!this._prefs.has(installPref)) { - this._prefs.setValue(installPref, true); - this._firstRun = true; - } - - this._enabled = false; - const PREFIX_ITEM_URI = "urn:mozilla:item:"; - const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; - var rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService); - var itemResource = rdf.GetResource(PREFIX_ITEM_URI + this._item.id); - if (itemResource) { - var extmgr = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager); - var ds = extmgr.datasource; - var target = ds.GetTarget(itemResource, rdf.GetResource(PREFIX_NS_EM + "isDisabled"), true); - if (target && target instanceof Ci.nsIRDFLiteral) - this._enabled = (target.Value != "true"); - } - - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - os.addObserver(this, "em-action-requested", false); - - var self = this; - gShutdown.push(function(){ self._shutdown(); }); -} - -//================================================= -// Extension implementation -Extension.prototype = { - // cleanup observer so we don't leak - _shutdown: function ext_shutdown() { - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - os.removeObserver(this, "em-action-requested"); - - this._prefs = null; - this._storage = null; - this._events = null; - }, - - // for nsIObserver - observe: function ext_observe(aSubject, aTopic, aData) - { - if ((aSubject instanceof Ci.nsIUpdateItem) && (aSubject.id == this._item.id)) - { - if (aData == "item-uninstalled") - this._events.dispatch("uninstall", this._item.id); - else if (aData == "item-disabled") - this._events.dispatch("disable", this._item.id); - else if (aData == "item-enabled") - this._events.dispatch("enable", this._item.id); - else if (aData == "item-cancel-action") - this._events.dispatch("cancel", this._item.id); - else if (aData == "item-upgraded") - this._events.dispatch("upgrade", this._item.id); - } - }, - - get id() { - return this._item.id; - }, - - get name() { - return this._item.name; - }, - - get enabled() { - return this._enabled; - }, - - get version() { - return this._item.version; - }, - - get firstRun() { - return this._firstRun; - }, - - get storage() { - return this._storage; - }, - - get prefs() { - return this._prefs; - }, - - get events() { - return this._events; - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIExtension]) -}; - - -//================================================= -// Extensions constructor -function Extensions() { - this._extmgr = Components.classes["@mozilla.org/extensions/manager;1"] - .getService(Ci.nsIExtensionManager); - - this._cache = {}; - - var self = this; - gShutdown.push(function() { self._shutdown(); }); -} - -//================================================= -// Extensions implementation -Extensions.prototype = { - _shutdown : function exts_shutdown() { - this._extmgr = null; - this._cache = null; - }, - - /* - * Helper method to check cache before creating a new extension - */ - _get : function exts_get(aId) { - if (this._cache.hasOwnProperty(aId)) - return this._cache[aId]; - - var newExt = new Extension(this._extmgr.getItemForID(aId)); - this._cache[aId] = newExt; - return newExt; - }, - - get all() { - return this.find({}); - }, - - // XXX: Disabled until we can figure out the wrapped object issues - // id: "some@id" or /id/ - // name: "name" or /name/ - // version: "1.0.1" - // minVersion: "1.0" - // maxVersion: "2.0" - find : function exts_find(aOptions) { - var retVal = []; - var items = this._extmgr.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {}); - - for (var i = 0; i < items.length; i++) { - retVal.push(this._get(items[i].id)); - } - - return retVal; - }, - - has : function exts_has(aId) { - return this._extmgr.getItemForID(aId) != null; - }, - - get : function exts_get(aId) { - return this.has(aId) ? this._get(aId) : null; - }, - - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIExtensions]) -}; - //================================================= // Singleton that holds services and utilities var Utilities = { @@ -1140,26 +626,13 @@ var ApplicationFactory = { } }; + + //================================================= // Application constructor function Application() { - this._console = null; - this._prefs = null; - this._storage = null; - this._events = null; + this.initToolkitHelpers(); this._bookmarks = null; - - this._info = Components.classes["@mozilla.org/xre/app-info;1"] - .getService(Ci.nsIXULAppInfo); - - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - - os.addObserver(this, "final-ui-startup", false); - os.addObserver(this, "quit-application-requested", false); - os.addObserver(this, "quit-application-granted", false); - os.addObserver(this, "quit-application", false); - os.addObserver(this, "xpcom-shutdown", false); } //================================================= @@ -1173,76 +646,8 @@ Application.prototype = { // redefine the default factory for XPCOMUtils _xpcom_factory: ApplicationFactory, - // get this contractID registered for certain categories via XPCOMUtils - _xpcom_categories: [ - // make Application a startup observer - { category: "app-startup", service: true }, - - // add Application as a global property for easy access - { category: "JavaScript global privileged property" } - ], - - get id() { - return this._info.ID; - }, - - get name() { - return this._info.name; - }, - - get version() { - return this._info.version; - }, - - // for nsIObserver - observe: function app_observe(aSubject, aTopic, aData) { - if (aTopic == "app-startup") { - this._extensions = new Extensions(); - this.events.dispatch("load", "application"); - } - else if (aTopic == "final-ui-startup") { - this.events.dispatch("ready", "application"); - } - else if (aTopic == "quit-application-requested") { - // we can stop the quit by checking the return value - if (this.events.dispatch("quit", "application") == false) - aSubject.data = true; - } - else if (aTopic == "xpcom-shutdown") { - this.events.dispatch("unload", "application"); - - // call the cleanup functions and empty the array - while (gShutdown.length) { - gShutdown.shift()(); - } - - // release our observers - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - - os.removeObserver(this, "final-ui-startup"); - - os.removeObserver(this, "quit-application-requested"); - os.removeObserver(this, "quit-application-granted"); - os.removeObserver(this, "quit-application"); - - os.removeObserver(this, "xpcom-shutdown"); - - this._info = null; - this._console = null; - this._prefs = null; - this._storage = null; - this._events = null; - this._extensions = null; - this._bookmarks = null; - - Utilities.free(); - } - }, - - // for nsIClassInfo - flags : Ci.nsIClassInfo.SINGLETON, - implementationLanguage : Ci.nsIProgrammingLanguage.JAVASCRIPT, + // for nsISupports + QueryInterface : XPCOMUtils.generateQI([Ci.fuelIApplication, Ci.nsIObserver, Ci.nsIClassInfo]), getInterfaces : function app_gi(aCount) { var interfaces = [Ci.fuelIApplication, Ci.nsIObserver, Ci.nsIClassInfo]; @@ -1250,43 +655,14 @@ Application.prototype = { return interfaces; }, - getHelperForLanguage : function app_ghfl(aCount) { - return null; - }, - - // for nsISupports - QueryInterface : XPCOMUtils.generateQI([Ci.fuelIApplication, Ci.nsIObserver, Ci.nsIClassInfo]), - - get console() { - if (this._console == null) - this._console = new Console(); - - return this._console; - }, - - get storage() { - if (this._storage == null) - this._storage = new SessionStorage(); - - return this._storage; - }, - - get prefs() { - if (this._prefs == null) - this._prefs = new PreferenceBranch(""); - - return this._prefs; - }, - - get extensions() { - return this._extensions; - }, - - get events() { - if (this._events == null) - this._events = new Events(); - - return this._events; + // for nsIObserver + observe: function app_observe(aSubject, aTopic, aData) { + // Call the extApplication version of this function first + this.__proto__.__proto__.observe(aSubject, aTopic, aData); + if (aTopic == "xpcom-shutdown") { + this._bookmarks = null; + Utilities.free(); + } }, get bookmarks() { @@ -1313,5 +689,9 @@ Application.prototype = { //module initialization function NSGetModule(aCompMgr, aFileSpec) { + // set the proto, defined in extApplication.js + Application.prototype.__proto__ = extApplication.prototype; return XPCOMUtils.generateModule([Application]); } + +#include ../../../toolkit/components/exthelper/extApplication.js diff --git a/mozilla/toolkit/components/Makefile.in b/mozilla/toolkit/components/Makefile.in index 909eb695c5b..15b583bf7c5 100644 --- a/mozilla/toolkit/components/Makefile.in +++ b/mozilla/toolkit/components/Makefile.in @@ -61,6 +61,7 @@ DIRS += \ apppicker \ filepicker \ console \ + exthelper \ viewconfig \ typeaheadfind \ $(NULL) diff --git a/mozilla/toolkit/components/exthelper/Makefile.in b/mozilla/toolkit/components/exthelper/Makefile.in new file mode 100644 index 00000000000..f34b4f3349e --- /dev/null +++ b/mozilla/toolkit/components/exthelper/Makefile.in @@ -0,0 +1,50 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is FUEL. +# +# The Initial Developer of the Original Code is Mozilla Corporation. +# Portions created by the Initial Developer are Copyright (C) 2006 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Finkle +# John Resig +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = exthelper +XPIDL_MODULE = exthelper + +XPIDLSRCS = extIApplication.idl + +include $(topsrcdir)/config/rules.mk diff --git a/mozilla/toolkit/components/exthelper/extApplication.js b/mozilla/toolkit/components/exthelper/extApplication.js new file mode 100644 index 00000000000..07c7c0a92ca --- /dev/null +++ b/mozilla/toolkit/components/exthelper/extApplication.js @@ -0,0 +1,692 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FUEL. + * + * The Initial Developer of the Original Code is Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mark Finkle (Original Author) + * John Resig (Original Author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +//================================================= +// Shutdown - used to store cleanup functions which will +// be called on Application shutdown +var gShutdown = []; + +//================================================= +// Console constructor +function Console() { + this._console = Components.classes["@mozilla.org/consoleservice;1"] + .getService(Ci.nsIConsoleService); +} + +//================================================= +// Console implementation +Console.prototype = { + log : function cs_log(aMsg) { + this._console.logStringMessage(aMsg); + }, + + open : function cs_open() { + var wMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"] + .getService(Ci.nsIWindowMediator); + var console = wMediator.getMostRecentWindow("global:console"); + if (!console) { + var wWatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] + .getService(Ci.nsIWindowWatcher); + wWatch.openWindow(null, "chrome://global/content/console.xul", "_blank", + "chrome,dialog=no,all", null); + } else { + // console was already open + console.focus(); + } + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extIConsole]) +}; + + +//================================================= +// EventItem constructor +function EventItem(aType, aData) { + this._type = aType; + this._data = aData; +} + +//================================================= +// EventItem implementation +EventItem.prototype = { + _cancel : false, + + get type() { + return this._type; + }, + + get data() { + return this._data; + }, + + preventDefault : function ei_pd() { + this._cancel = true; + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extIEventItem]) +}; + + +//================================================= +// Events constructor +function Events() { + this._listeners = []; +} + +//================================================= +// Events implementation +Events.prototype = { + addListener : function evts_al(aEvent, aListener) { + if (this._listeners.some(hasFilter)) + return; + + this._listeners.push({ + event: aEvent, + listener: aListener + }); + + function hasFilter(element) { + return element.event == aEvent && element.listener == aListener; + } + }, + + removeListener : function evts_rl(aEvent, aListener) { + this._listeners = this._listeners.filter(function(element){ + return element.event != aEvent && element.listener != aListener; + }); + }, + + dispatch : function evts_dispatch(aEvent, aEventItem) { + eventItem = new EventItem(aEvent, aEventItem); + + this._listeners.forEach(function(key){ + if (key.event == aEvent) { + key.listener.handleEvent ? + key.listener.handleEvent(eventItem) : + key.listener(eventItem); + } + }); + + return !eventItem._cancel; + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extIEvents]) +}; + + +//================================================= +// PreferenceBranch constructor +function PreferenceBranch(aBranch) { + if (!aBranch) + aBranch = ""; + + this._root = aBranch; + this._prefs = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Ci.nsIPrefService); + + if (aBranch) + this._prefs = this._prefs.getBranch(aBranch); + + this._prefs.QueryInterface(Ci.nsIPrefBranch); + this._prefs.QueryInterface(Ci.nsIPrefBranch2); + + // we want to listen to "all" changes for this branch, so pass in a blank domain + this._prefs.addObserver("", this, true); + this._events = new Events(); + + var self = this; + gShutdown.push(function() { self._shutdown(); }); +} + +//================================================= +// PreferenceBranch implementation +PreferenceBranch.prototype = { + // cleanup observer so we don't leak + _shutdown: function prefs_shutdown() { + this._prefs.removeObserver(this._root, this); + + this._prefs = null; + this._events = null; + }, + + // for nsIObserver + observe: function prefs_observe(aSubject, aTopic, aData) { + if (aTopic == "nsPref:changed") + this._events.dispatch("change", aData); + }, + + get root() { + return this._root; + }, + + get all() { + return this.find({}); + }, + + get events() { + return this._events; + }, + + // XXX: Disabled until we can figure out the wrapped object issues + // name: "name" or /name/ + // path: "foo.bar." or "" or /fo+\.bar/ + // type: Boolean, Number, String (getPrefType) + // locked: true, false (prefIsLocked) + // modified: true, false (prefHasUserValue) + find : function prefs_find(aOptions) { + var retVal = []; + var items = this._prefs.getChildList("", []); + + for (var i = 0; i < items.length; i++) { + retVal.push(new Preference(items[i], this)); + } + + return retVal; + }, + + has : function prefs_has(aName) { + return (this._prefs.getPrefType(aName) != Ci.nsIPrefBranch.PREF_INVALID); + }, + + get : function prefs_get(aName) { + return this.has(aName) ? new Preference(aName, this) : null; + }, + + getValue : function prefs_gv(aName, aValue) { + var type = this._prefs.getPrefType(aName); + + switch (type) { + case Ci.nsIPrefBranch2.PREF_STRING: + aValue = this._prefs.getComplexValue(aName, Ci.nsISupportsString).data; + break; + case Ci.nsIPrefBranch2.PREF_BOOL: + aValue = this._prefs.getBoolPref(aName); + break; + case Ci.nsIPrefBranch2.PREF_INT: + aValue = this._prefs.getIntPref(aName); + break; + } + + return aValue; + }, + + setValue : function prefs_sv(aName, aValue) { + var type = aValue != null ? aValue.constructor.name : ""; + + switch (type) { + case "String": + var str = Components.classes["@mozilla.org/supports-string;1"] + .createInstance(Ci.nsISupportsString); + str.data = aValue; + this._prefs.setComplexValue(aName, Ci.nsISupportsString, str); + break; + case "Boolean": + this._prefs.setBoolPref(aName, aValue); + break; + case "Number": + this._prefs.setIntPref(aName, aValue); + break; + default: + throw("Unknown preference value specified."); + } + }, + + reset : function prefs_reset() { + this._prefs.resetBranch(""); + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extIPreferenceBranch, Ci.nsISupportsWeakReference]) +}; + + +//================================================= +// Preference constructor +function Preference(aName, aBranch) { + this._name = aName; + this._branch = aBranch; + this._events = new Events(); + + var self = this; + + this.branch.events.addListener("change", function(aEvent){ + if (aEvent.data == self.name) + self.events.dispatch(aEvent.type, aEvent.data); + }); +} + +//================================================= +// Preference implementation +Preference.prototype = { + get name() { + return this._name; + }, + + get type() { + var value = ""; + var type = this._prefs.getPrefType(name); + + switch (type) { + case Ci.nsIPrefBranch2.PREF_STRING: + value = "String"; + break; + case Ci.nsIPrefBranch2.PREF_BOOL: + value = "Boolean"; + break; + case Ci.nsIPrefBranch2.PREF_INT: + value = "Number"; + break; + } + + return value; + }, + + get value() { + return this.branch.getValue(this._name, null); + }, + + set value(aValue) { + return this.branch.setValue(this._name, aValue); + }, + + get locked() { + return this.branch._prefs.prefIsLocked(this.name); + }, + + set locked(aValue) { + this.branch._prefs[ aValue ? "lockPref" : "unlockPref" ](this.name); + }, + + get modified() { + return this.branch._prefs.prefHasUserValue(this.name); + }, + + get branch() { + return this._branch; + }, + + get events() { + return this._events; + }, + + reset : function pref_reset() { + this.branch._prefs.clearUserPref(this.name); + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extIPreference]) +}; + + +//================================================= +// SessionStorage constructor +function SessionStorage() { + this._storage = {}; + this._events = new Events(); +} + +//================================================= +// SessionStorage implementation +SessionStorage.prototype = { + get events() { + return this._events; + }, + + has : function ss_has(aName) { + return this._storage.hasOwnProperty(aName); + }, + + set : function ss_set(aName, aValue) { + this._storage[aName] = aValue; + this._events.dispatch("change", aName); + }, + + get : function ss_get(aName, aDefaultValue) { + return this.has(aName) ? this._storage[aName] : aDefaultValue; + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extISessionStorage]) +}; + + +//================================================= +// Extension constructor +function Extension(aItem) { + this._item = aItem; + this._firstRun = false; + this._prefs = new PreferenceBranch("extensions." + this._item.id + "."); + this._storage = new SessionStorage(); + this._events = new Events(); + + var installPref = "install-event-fired"; + if (!this._prefs.has(installPref)) { + this._prefs.setValue(installPref, true); + this._firstRun = true; + } + + this._enabled = false; + const PREFIX_ITEM_URI = "urn:mozilla:item:"; + const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; + var rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService); + var itemResource = rdf.GetResource(PREFIX_ITEM_URI + this._item.id); + if (itemResource) { + var extmgr = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager); + var ds = extmgr.datasource; + var target = ds.GetTarget(itemResource, rdf.GetResource(PREFIX_NS_EM + "isDisabled"), true); + if (target && target instanceof Ci.nsIRDFLiteral) + this._enabled = (target.Value != "true"); + } + + var os = Components.classes["@mozilla.org/observer-service;1"] + .getService(Ci.nsIObserverService); + os.addObserver(this, "em-action-requested", false); + + var self = this; + gShutdown.push(function(){ self._shutdown(); }); +} + +//================================================= +// Extension implementation +Extension.prototype = { + // cleanup observer so we don't leak + _shutdown: function ext_shutdown() { + var os = Components.classes["@mozilla.org/observer-service;1"] + .getService(Ci.nsIObserverService); + os.removeObserver(this, "em-action-requested"); + + this._prefs = null; + this._storage = null; + this._events = null; + }, + + // for nsIObserver + observe: function ext_observe(aSubject, aTopic, aData) + { + if ((aSubject instanceof Ci.nsIUpdateItem) && (aSubject.id == this._item.id)) + { + if (aData == "item-uninstalled") + this._events.dispatch("uninstall", this._item.id); + else if (aData == "item-disabled") + this._events.dispatch("disable", this._item.id); + else if (aData == "item-enabled") + this._events.dispatch("enable", this._item.id); + else if (aData == "item-cancel-action") + this._events.dispatch("cancel", this._item.id); + else if (aData == "item-upgraded") + this._events.dispatch("upgrade", this._item.id); + } + }, + + get id() { + return this._item.id; + }, + + get name() { + return this._item.name; + }, + + get enabled() { + return this._enabled; + }, + + get version() { + return this._item.version; + }, + + get firstRun() { + return this._firstRun; + }, + + get storage() { + return this._storage; + }, + + get prefs() { + return this._prefs; + }, + + get events() { + return this._events; + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extIExtension]) +}; + + +//================================================= +// Extensions constructor +function Extensions() { + this._extmgr = Components.classes["@mozilla.org/extensions/manager;1"] + .getService(Ci.nsIExtensionManager); + + this._cache = {}; + + var self = this; + gShutdown.push(function() { self._shutdown(); }); +} + +//================================================= +// Extensions implementation +Extensions.prototype = { + _shutdown : function exts_shutdown() { + this._extmgr = null; + this._cache = null; + }, + + /* + * Helper method to check cache before creating a new extension + */ + _get : function exts_get(aId) { + if (this._cache.hasOwnProperty(aId)) + return this._cache[aId]; + + var newExt = new Extension(this._extmgr.getItemForID(aId)); + this._cache[aId] = newExt; + return newExt; + }, + + get all() { + return this.find({}); + }, + + // XXX: Disabled until we can figure out the wrapped object issues + // id: "some@id" or /id/ + // name: "name" or /name/ + // version: "1.0.1" + // minVersion: "1.0" + // maxVersion: "2.0" + find : function exts_find(aOptions) { + var retVal = []; + var items = this._extmgr.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {}); + + for (var i = 0; i < items.length; i++) { + retVal.push(this._get(items[i].id)); + } + + return retVal; + }, + + has : function exts_has(aId) { + return this._extmgr.getItemForID(aId) != null; + }, + + get : function exts_get(aId) { + return this.has(aId) ? this._get(aId) : null; + }, + + QueryInterface : XPCOMUtils.generateQI([Ci.extIExtensions]) +}; + +//================================================= +// extApplication constructor +function extApplication() { +} + +//================================================= +// extApplication implementation +extApplication.prototype = { + initToolkitHelpers: function extApp_initToolkitHelpers() { + this._console = null; + this._storage = null; + this._prefs = null; + this._extensions = null; + this._events = null; + + this._info = Components.classes["@mozilla.org/xre/app-info;1"] + .getService(Ci.nsIXULAppInfo); + + var os = Components.classes["@mozilla.org/observer-service;1"] + .getService(Ci.nsIObserverService); + + os.addObserver(this, "final-ui-startup", false); + os.addObserver(this, "quit-application-requested", false); + os.addObserver(this, "quit-application-granted", false); + os.addObserver(this, "quit-application", false); + os.addObserver(this, "xpcom-shutdown", false); + }, + + // get this contractID registered for certain categories via XPCOMUtils + _xpcom_categories: [ + // make Application a startup observer + { category: "app-startup", service: true }, + + // add Application as a global property for easy access + { category: "JavaScript global privileged property" } + ], + + // for nsIClassInfo + flags : Ci.nsIClassInfo.SINGLETON, + implementationLanguage : Ci.nsIProgrammingLanguage.JAVASCRIPT, + + getInterfaces : function app_gi(aCount) { + var interfaces = [Ci.extIApplication, Ci.nsIObserver, Ci.nsIClassInfo]; + aCount.value = interfaces.length; + return interfaces; + }, + + getHelperForLanguage : function app_ghfl(aCount) { + return null; + }, + + // extIApplication + get id() { + return this._info.ID; + }, + + get name() { + return this._info.name; + }, + + get version() { + return this._info.version; + }, + + // for nsIObserver + observe: function app_observe(aSubject, aTopic, aData) { + if (aTopic == "app-startup") { + this.events.dispatch("load", "application"); + } + else if (aTopic == "final-ui-startup") { + this.events.dispatch("ready", "application"); + } + else if (aTopic == "quit-application-requested") { + // we can stop the quit by checking the return value + if (this.events.dispatch("quit", "application") == false) + aSubject.data = true; + } + else if (aTopic == "xpcom-shutdown") { + this.events.dispatch("unload", "application"); + + // call the cleanup functions and empty the array + while (gShutdown.length) { + gShutdown.shift()(); + } + + // release our observers + var os = Components.classes["@mozilla.org/observer-service;1"] + .getService(Ci.nsIObserverService); + + os.removeObserver(this, "final-ui-startup"); + + os.removeObserver(this, "quit-application-requested"); + os.removeObserver(this, "quit-application-granted"); + os.removeObserver(this, "quit-application"); + + os.removeObserver(this, "xpcom-shutdown"); + + this._info = null; + this._console = null; + this._prefs = null; + this._storage = null; + this._events = null; + this._extensions = null; + } + }, + + get console() { + if (this._console == null) + this._console = new Console(); + + return this._console; + }, + + get storage() { + if (this._storage == null) + this._storage = new SessionStorage(); + + return this._storage; + }, + + get prefs() { + if (this._prefs == null) + this._prefs = new PreferenceBranch(""); + + return this._prefs; + }, + + get extensions() { + if (this._extensions == null) + this._extensions = new Extensions(); + + return this._extensions; + }, + + get events() { + if (this._events == null) + this._events = new Events(); + + return this._events; + } +}; diff --git a/mozilla/toolkit/components/exthelper/extIApplication.idl b/mozilla/toolkit/components/exthelper/extIApplication.idl new file mode 100644 index 00000000000..53b9fe6d7f0 --- /dev/null +++ b/mozilla/toolkit/components/exthelper/extIApplication.idl @@ -0,0 +1,429 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FUEL. + * + * The Initial Developer of the Original Code is Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mark Finkle (Original Author) + * John Resig (Original Author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIVariant; +interface extIPreference; +interface extISessionStorage; + + +/** + * Interface that gives simplified access to the console + */ +[scriptable, uuid(ae8482e0-aa5a-11db-abbd-0800200c9a66)] +interface extIConsole : nsISupports +{ + /** + * Sends a given string to the console. + * @param aMsg + * The text to send to the console + */ + void log(in AString aMsg); + + /** + * Opens the error console window. The console window + * is focused if already open. + */ + void open(); +}; + + +/** + * Interface holds information about an event. + */ +[scriptable, function, uuid(05281820-ab62-11db-abbd-0800200c9a66)] +interface extIEventItem : nsISupports +{ + /** + * The name of the event + */ + readonly attribute AString type; + + /** + * Can hold extra details and data associated with the event. This + * is optional and event specific. If the event does not send extra + * details, this is null. + */ + readonly attribute AString data; + + /** + * Cancels the event if it is cancelable. + */ + void preventDefault(); +}; + + +/** + * Interface used as a callback for listening to events. + */ +[scriptable, function, uuid(2dfe3a50-ab2f-11db-abbd-0800200c9a66)] +interface extIEventListener : nsISupports +{ + /** + * This method is called whenever an event occurs of the type for which + * the extIEventListener interface was registered. + * + * @param aEvent + * The extIEventItem associated with the event. + */ + void handleEvent(in extIEventItem aEvent); +}; + + +/** + * Interface for supporting custom events. + */ +[scriptable, uuid(3a8ec9d0-ab19-11db-abbd-0800200c9a66)] +interface extIEvents : nsISupports +{ + /** + * Adds an event listener to the list. If multiple identical event listeners + * are registered on the same event target with the same parameters the + * duplicate instances are discarded. They do not cause the EventListener + * to be called twice and since they are discarded they do not need to be + * removed with the removeListener method. + * + * @param aEvent + * The name of an event + * @param aListener + * The reference to a listener + */ + void addListener(in AString aEvent, in extIEventListener aListener); + + /** + * Removes an event listener from the list. Calling remove + * with arguments which do not identify any currently registered + * event listener has no effect. + * @param aEvent + * The name of an event + * @param aListener + * The reference to a listener + */ + void removeListener(in AString aEvent, in extIEventListener aListener); +}; + + +/** + * Interface for simplified access to preferences. The interface has a + * predefined root preference branch. The root branch is set based on the + * context of the owner. For example, an extension's preferences have a root + * of "extensions..", while the application level preferences + * have an empty root. All preference "aName" parameters used in this interface + * are relative to the root branch. + */ +[scriptable, uuid(ce697d40-aa5a-11db-abbd-0800200c9a66)] +interface extIPreferenceBranch : nsISupports +{ + /** + * The name of the branch root. + */ + readonly attribute AString root; + + /** + * Array of extIPreference listing all preferences in this branch. + */ + readonly attribute nsIVariant all; + + /** + * The events object for the preferences + * supports: "change" + */ + readonly attribute extIEvents events; + + /** + * Check to see if a preference exists. + * @param aName + * The name of preference + * @returns true if the preference exists, false if not + */ + boolean has(in AString aName); + + /** + * Gets an object representing a preference + * @param aName + * The name of preference + * @returns a preference object, or null if the preference does not exist + */ + extIPreference get(in AString aName); + + /** + * Gets the value of a preference. Returns a default value if + * the preference does not exist. + * @param aName + * The name of preference + * @param aDefaultValue + * The value to return if preference does not exist + * @returns value of the preference or the given default value if preference + * does not exists. + */ + nsIVariant getValue(in AString aName, in nsIVariant aDefaultValue); + + /** + * Sets the value of a storage item with the given name. + * @param aName + * The name of an item + * @param aValue + * The value to assign to the item + */ + void setValue(in AString aName, in nsIVariant aValue); + + /** + * Resets all preferences in a branch back to their default values. + */ + void reset(); +}; + +/** + * Interface for accessing a single preference. The data is not cached. + * All reads access the current state of the preference. + */ +[scriptable, uuid(2C7462E2-72C2-4473-9007-0E6AE71E23CA)] +interface extIPreference : nsISupports +{ + /** + * The name of the preference. + */ + readonly attribute AString name; + + /** + * A string representing the type of preference (String, Boolean, or Number). + */ + readonly attribute AString type; + + /** + * Get/Set the value of the preference. + */ + attribute nsIVariant value; + + /** + * Get the locked state of the preference. Set to a boolean value to (un)lock it. + */ + attribute boolean locked; + + /** + * Check if a preference has been modified by the user, or not. + */ + readonly attribute boolean modified; + + /** + * The preference branch that contains this preference. + */ + readonly attribute extIPreferenceBranch branch; + + /** + * The events object for this preference. + * supports: "change" + */ + readonly attribute extIEvents events; + + /** + * Resets a preference back to its default values. + */ + void reset(); +}; + + +/** + * Interface representing an extension + */ +[scriptable, uuid(10cee02c-f6e0-4d61-ab27-c16572b18c46)] +interface extIExtension : nsISupports +{ + /** + * The id of the extension. + */ + readonly attribute AString id; + + /** + * The name of the extension. + */ + readonly attribute AString name; + + /** + * Check if the extension is currently enabled, or not. + */ + readonly attribute boolean enabled; + + /** + * The version number of the extension. + */ + readonly attribute AString version; + + /** + * Indicates whether this is the extension's first run after install + */ + readonly attribute boolean firstRun; + + /** + * The preferences object for the extension. Defaults to the + * "extensions.." branch. + */ + readonly attribute extIPreferenceBranch prefs; + + /** + * The storage object for the extension. + */ + readonly attribute extISessionStorage storage; + + /** + * The events object for the extension. + * supports: "uninstall" + */ + readonly attribute extIEvents events; +}; + + +/** + * Interface representing a list of all installed extensions + */ +[scriptable, uuid(de281930-aa5a-11db-abbd-0800200c9a66)] +interface extIExtensions : nsISupports +{ + /** + * Array of extIExtension listing all extensions in the application. + */ + readonly attribute nsIVariant all; + + /** + * Determines if an extension exists with the given id. + * @param aId + * The id of an extension + * @returns true if an extension exists with the given id, + * false otherwise. + */ + boolean has(in AString aId); + + /** + * Gets a extIExtension object for an extension. + * @param aId + * The id of an extension + * @returns An extension object or null if no extension exists + * with the given id. + */ + extIExtension get(in AString aId); +}; + +/** + * Interface representing a simple storage system + */ +[scriptable, uuid(0787ac44-29b9-4889-b97f-13573aec6971)] +interface extISessionStorage : nsISupports +{ + /** + * The events object for the storage + * supports: "change" + */ + readonly attribute extIEvents events; + + /** + * Determines if a storage item exists with the given name. + * @param aName + * The name of an item + * @returns true if an item exists with the given name, + * false otherwise. + */ + boolean has(in AString aName); + + /** + * Sets the value of a storage item with the given name. + * @param aName + * The name of an item + * @param aValue + * The value to assign to the item + */ + void set(in AString aName, in nsIVariant aValue); + + /** + * Gets the value of a storage item with the given name. Returns a + * default value if the item does not exist. + * @param aName + * The name of an item + * @param aDefaultValue + * The value to return if no item exists with the given name + * @returns value of the item or the given default value if no item + * exists with the given name. + */ + nsIVariant get(in AString aName, in nsIVariant aDefaultValue); +}; + +[scriptable, uuid(ba9442ee-7070-44fb-8157-c111e1fa70b6)] +interface extIApplication : nsISupports +{ + /** + * The id of the application. + */ + readonly attribute AString id; + + /** + * The name of the application. + */ + readonly attribute AString name; + + /** + * The version number of the application. + */ + readonly attribute AString version; + + /** + * The console object for the application. + */ + readonly attribute extIConsole console; + + /** + * The extensions object for the application. Contains a list + * of all installed extensions. + */ + readonly attribute extIExtensions extensions; + + /** + * The preferences object for the application. Defaults to an empty + * root branch. + */ + readonly attribute extIPreferenceBranch prefs; + + /** + * The storage object for the application. + */ + readonly attribute extISessionStorage storage; + + /** + * The events object for the application. + * supports: "load", "ready", "quit", "unload" + */ + readonly attribute extIEvents events; +};