Bug 552731: Update FUEL to use the new EM APIs. r=mfinkle

This commit is contained in:
Dave Townsend 2010-04-20 15:14:15 -07:00
parent c63394efea
commit e9f8fcd5cb
7 changed files with 258 additions and 214 deletions

View File

@ -657,7 +657,6 @@ var ApplicationFactory = {
}; };
//================================================= //=================================================
// Application constructor // Application constructor
function Application() { function Application() {

View File

@ -50,7 +50,6 @@ _BROWSER_FILES =browser_Application.js \
browser_ApplicationQuitting.js \ browser_ApplicationQuitting.js \
browser_Bookmarks.js \ browser_Bookmarks.js \
browser_Browser.js \ browser_Browser.js \
browser_Extensions.js \
ContentA.html \ ContentA.html \
ContentB.html \ ContentB.html \
ContentWithFrames.html \ ContentWithFrames.html \

View File

@ -1,126 +0,0 @@
// The various pieces that we'll be testing
var testdata = {
dummyid: "fuel-dummy-extension@mozilla.org",
dummyname: "Dummy Extension",
inspectorid: "inspector@mozilla.org",
inspectorname: "DOM Inspector",
missing: "fuel.fuel-test-missing",
dummy: "fuel.fuel-test"
};
var gLastEvent = "";
function test() {
// test to see if the extensions object is available
ok(Application.extensions, "Check for the 'Extensions' object");
// test to see if a non-existant extension exists
ok(!Application.extensions.has(testdata.dummyid), "Check non-existant extension for existence");
// BUG 420028: Must find a way to add a dummy extension for test suite
return;
// test to see if an extension exists
ok(Application.extensions.has(testdata.inspectorid), "Check extension for existence");
var inspector = Application.extensions.get(testdata.inspectorid);
is(inspector.id, testdata.inspectorid, "Check 'Extension.id' for known extension");
is(inspector.name, testdata.inspectorname, "Check 'Extension.name' for known extension");
// The known version number changes too frequently to hardcode in
ok(inspector.version, "Check 'Extension.version' for known extension");
ok(inspector.firstRun, "Check 'Extension.firstRun' for known extension");
ok(inspector.enabled, "Check 'Extension.enabled' for known extension");
// test to see if extension find works
is(Application.extensions.all.length, 1, "Check a find for all extensions");
// STORAGE TESTING
// Make sure the we are given the same extension (cached) so things like .storage work right
inspector.storage.set("test", "simple check");
ok(inspector.storage.has("test"), "Checking that extension storage worked");
var inspector2 = Application.extensions.get(testdata.inspectorid);
is(inspector2.id, testdata.inspectorid, "Check 'Extension.id' for known extension - from cache");
ok(inspector.storage.has("test"), "Checking that extension storage worked - from cache");
is(inspector2.storage.get("test", "cache"), inspector.storage.get("test", "original"), "Checking that the storage of same extension is correct - from cache");
inspector.events.addListener("disable", onGenericEvent);
inspector.events.addListener("enable", onGenericEvent);
inspector.events.addListener("uninstall", onGenericEvent);
inspector.events.addListener("cancel", onGenericEvent);
var extmgr = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
extmgr.disableItem(testdata.inspectorid);
is(gLastEvent, "disable", "Checking that disable event is fired");
// enabling after a disable will only fire a 'cancel' event
// see - http://mxr.mozilla.org/seamonkey/source/toolkit/mozapps/extensions/src/nsExtensionManager.js.in#5216
extmgr.enableItem(testdata.inspectorid);
is(gLastEvent, "cancel", "Checking that enable (cancel) event is fired");
extmgr.uninstallItem(testdata.inspectorid);
is(gLastEvent, "uninstall", "Checking that uninstall event is fired");
extmgr.cancelUninstallItem(testdata.inspectorid);
is(gLastEvent, "cancel", "Checking that cancel event is fired");
// PREF TESTING
// Reset the install event preference, so that we can test it again later
inspector.prefs.get("install-event-fired").reset();
// test the value of the preference root
is(Application.extensions.all[0].prefs.root, "extensions.inspector@mozilla.org.", "Check an extension preference root");
// test getting non-existing values
var itemValue = inspector.prefs.getValue(testdata.missing, "default");
is(itemValue, "default", "Check 'Extension.prefs.getValue' for non-existing item");
is(inspector.prefs.get(testdata.missing), null, "Check 'Extension.prefs.get' for non-existing item");
// test setting and getting a value
inspector.prefs.setValue(testdata.dummy, "dummy");
itemValue = inspector.prefs.getValue(testdata.dummy, "default");
is(itemValue, "dummy", "Check 'Extension.prefs.getValue' for existing item");
// test for overwriting an existing value
inspector.prefs.setValue(testdata.dummy, "smarty");
itemValue = inspector.prefs.getValue(testdata.dummy, "default");
is(itemValue, "smarty", "Check 'Extension.prefs.getValue' for overwritten item");
// test setting and getting a value
inspector.prefs.get(testdata.dummy).value = "dummy2";
itemValue = inspector.prefs.get(testdata.dummy).value;
is(itemValue, "dummy2", "Check 'Extension.prefs.get().value' for existing item");
// test resetting a pref [since there is no default value, the pref should disappear]
inspector.prefs.get(testdata.dummy).reset();
var itemValue = inspector.prefs.getValue(testdata.dummy, "default");
is(itemValue, "default", "Check 'Extension.prefs.getValue' for reset pref");
// test to see if a non-existant property exists
ok(!inspector.prefs.has(testdata.dummy), "Check non-existant property for existence");
waitForExplicitFinish();
inspector.prefs.events.addListener("change", onPrefChange);
inspector.prefs.setValue("fuel.fuel-test", "change event");
}
function onGenericEvent(event) {
gLastEvent = event.type;
}
function onPrefChange(evt) {
var inspector3 = Application.extensions.get(testdata.inspectorid);
is(evt.data, testdata.dummy, "Check 'Extension.prefs.set' fired a change event");
inspector3.prefs.events.removeListener("change", onPrefChange);
inspector3.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2);
inspector3.prefs.setValue("fuel.fuel-test", "change event2");
}
function onPrefChange2(evt) {
is(evt.data, testdata.dummy, "Check 'Extension.prefs.set' fired a change event for a single preference");
finish();
}

View File

@ -36,6 +36,7 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/AddonManager.jsm");
//================================================= //=================================================
// Shutdown - used to store cleanup functions which will // Shutdown - used to store cleanup functions which will
@ -395,7 +396,7 @@ SessionStorage.prototype = {
function Extension(aItem) { function Extension(aItem) {
this._item = aItem; this._item = aItem;
this._firstRun = false; this._firstRun = false;
this._prefs = new PreferenceBranch("extensions." + this._item.id + "."); this._prefs = new PreferenceBranch("extensions." + this.id + ".");
this._storage = new SessionStorage(); this._storage = new SessionStorage();
this._events = new Events(); this._events = new Events();
@ -405,22 +406,8 @@ function Extension(aItem) {
this._firstRun = true; this._firstRun = true;
} }
this._enabled = false; AddonManager.addAddonListener(this);
const PREFIX_ITEM_URI = "urn:mozilla:item:"; AddonManager.addInstallListener(this);
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; var self = this;
gShutdown.push(function(){ self._shutdown(); }); gShutdown.push(function(){ self._shutdown(); });
@ -431,31 +418,38 @@ function Extension(aItem) {
Extension.prototype = { Extension.prototype = {
// cleanup observer so we don't leak // cleanup observer so we don't leak
_shutdown: function ext_shutdown() { _shutdown: function ext_shutdown() {
var os = Components.classes["@mozilla.org/observer-service;1"] AddonManager.removeAddonListener(this);
.getService(Ci.nsIObserverService); AddonManager.removeInstallListener(this);
os.removeObserver(this, "em-action-requested");
this._prefs = null; this._prefs = null;
this._storage = null; this._storage = null;
this._events = null; this._events = null;
}, },
// for nsIObserver // for AddonListener
observe: function ext_observe(aSubject, aTopic, aData) onDisabling: function(addon, needsRestart) {
{ if (addon.id == this.id)
if ((aSubject instanceof Ci.nsIUpdateItem) && (aSubject.id == this._item.id)) this._events.dispatch("disable", this.id);
{ },
if (aData == "item-uninstalled")
this._events.dispatch("uninstall", this._item.id); onEnabling: function(addon, needsRestart) {
else if (aData == "item-disabled") if (addon.id == this.id)
this._events.dispatch("disable", this._item.id); this._events.dispatch("enable", this.id);
else if (aData == "item-enabled") },
this._events.dispatch("enable", this._item.id);
else if (aData == "item-cancel-action") onUninstalling: function(addon, needsRestart) {
this._events.dispatch("cancel", this._item.id); if (addon.id == this.id)
else if (aData == "item-upgraded") this._events.dispatch("uninstall", this.id);
this._events.dispatch("upgrade", this._item.id); },
}
onOperationCancelled: function(addon) {
if (addon.id == this.id)
this._events.dispatch("cancel", this.id);
},
onInstallEnded: function(install, addon) {
if (addon.id == this.id)
this._events.dispatch("upgrade", this.id);
}, },
get id() { get id() {
@ -467,7 +461,7 @@ Extension.prototype = {
}, },
get enabled() { get enabled() {
return this._enabled; return this._item.isActive;
}, },
get version() { get version() {
@ -496,13 +490,13 @@ Extension.prototype = {
//================================================= //=================================================
// Extensions constructor // Extensions constructor
function Extensions() { function Extensions(addons) {
XPCOMUtils.defineLazyServiceGetter(this, "_extmgr",
"@mozilla.org/extensions/manager;1",
"nsIExtensionManager");
this._cache = {}; this._cache = {};
addons.forEach(function(addon) {
this._cache[addon.id] = new Extension(addon);
}, this);
var self = this; var self = this;
gShutdown.push(function() { self._shutdown(); }); gShutdown.push(function() { self._shutdown(); });
} }
@ -511,22 +505,9 @@ function Extensions() {
// Extensions implementation // Extensions implementation
Extensions.prototype = { Extensions.prototype = {
_shutdown : function exts_shutdown() { _shutdown : function exts_shutdown() {
this._extmgr = null;
this._cache = 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() { get all() {
return this.find({}); return this.find({});
}, },
@ -538,22 +519,15 @@ Extensions.prototype = {
// minVersion: "1.0" // minVersion: "1.0"
// maxVersion: "2.0" // maxVersion: "2.0"
find : function exts_find(aOptions) { find : function exts_find(aOptions) {
var retVal = []; return [e for each (e in this._cache)];
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) { has : function exts_has(aId) {
return this._extmgr.getItemForID(aId) != null; return aId in this._cache;
}, },
get : function exts_get(aId) { get : function exts_get(aId) {
return this.has(aId) ? this._get(aId) : null; return this.has(aId) ? this._cache[aId] : null;
}, },
QueryInterface : XPCOMUtils.generateQI([Ci.extIExtensions]) QueryInterface : XPCOMUtils.generateQI([Ci.extIExtensions])
@ -663,10 +637,10 @@ extApplication.prototype = {
return this.prefs; return this.prefs;
}, },
get extensions() { getExtensions: function(callback) {
let extensions = new Extensions(); AddonManager.getAddonsByTypes(["extension"], function(addons) {
this.__defineGetter__("extensions", function() extensions); callback.callback(new Extensions(addons));
return this.extensions; });
}, },
get events() { get events() {

View File

@ -308,7 +308,6 @@ interface extIExtension : nsISupports
readonly attribute extIEvents events; readonly attribute extIEvents events;
}; };
/** /**
* Interface representing a list of all installed extensions * Interface representing a list of all installed extensions
*/ */
@ -339,6 +338,15 @@ interface extIExtensions : nsISupports
extIExtension get(in AString aId); extIExtension get(in AString aId);
}; };
/**
* Interface representing a callback that receives an array of extIExtensions
*/
[scriptable, function, uuid(2571cbb5-550d-4400-8038-75df9b553f98)]
interface extIExtensionsCallback : nsISupports
{
void callback(in nsIVariant extensions);
};
/** /**
* Interface representing a simple storage system * Interface representing a simple storage system
*/ */
@ -382,7 +390,7 @@ interface extISessionStorage : nsISupports
nsIVariant get(in AString aName, in nsIVariant aDefaultValue); nsIVariant get(in AString aName, in nsIVariant aDefaultValue);
}; };
[scriptable, uuid(e53d6610-7468-11dd-ad8b-0800200c9a66)] [scriptable, uuid(2be87909-0817-4292-acfa-fc39be53be3f)]
interface extIApplication : nsISupports interface extIApplication : nsISupports
{ {
/** /**
@ -409,7 +417,7 @@ interface extIApplication : nsISupports
* The extensions object for the application. Contains a list * The extensions object for the application. Contains a list
* of all installed extensions. * of all installed extensions.
*/ */
readonly attribute extIExtensions extensions; void getExtensions(in extIExtensionsCallback aCallback);
/** /**
* The preferences object for the application. Defaults to an empty * The preferences object for the application. Defaults to an empty

View File

@ -93,24 +93,26 @@ window.onload = function () {
document.getElementById("supportLink").href = supportUrl; document.getElementById("supportLink").href = supportUrl;
// Update the other sections. // Update the other sections.
populateExtensionsSection();
populatePreferencesSection(); populatePreferencesSection();
populateExtensionsSection();
} }
function populateExtensionsSection() { function populateExtensionsSection() {
let extensions = Application.extensions.all; Application.getExtensions(function (extensions) {
let trExtensions = []; let all = extensions.all;
for (let i = 0; i < extensions.length; i++) { let trExtensions = [];
let extension = extensions[i]; for (let i = 0; i < all.length; i++) {
let tr = createParentElement("tr", [ let extension = all[i];
createElement("td", extension.name), let tr = createParentElement("tr", [
createElement("td", extension.version), createElement("td", extension.name),
createElement("td", extension.enabled), createElement("td", extension.version),
createElement("td", extension.id), createElement("td", extension.enabled),
]); createElement("td", extension.id),
trExtensions.push(tr); ]);
} trExtensions.push(tr);
appendChildren(document.getElementById("extensions-tbody"), trExtensions); }
appendChildren(document.getElementById("extensions-tbody"), trExtensions);
});
} }
function populatePreferencesSection() { function populatePreferencesSection() {

View File

@ -0,0 +1,188 @@
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
*
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dave Townsend <dtownsend@oxymoronical.com>
*
* 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 *****
*/
// This just verifies that FUEL integrates to the add-ons manager
var testdata = {
dummyid: "fuel-dummy-extension@mozilla.org",
dummyname: "Dummy Extension",
inspectorid: "addon1@tests.mozilla.org",
inspectorname: "Test Addon",
missing: "fuel.fuel-test-missing",
dummy: "fuel.fuel-test"
};
var Application = AM_Cc["@mozilla.org/fuel/application;1"].
getService(AM_Ci.nsISupports);
function run_test() {
do_test_pending();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
const profileDir = gProfD.clone();
profileDir.append("extensions");
var dest = profileDir.clone();
dest.append("addon1@tests.mozilla.org");
writeInstallRDFToDir({
id: "addon1@tests.mozilla.org",
version: "1.0",
name: "Test Addon",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}],
}, dest);
startupManager(1);
Application.getExtensions(function(extensions) {
// test to see if the extensions object is available
do_check_neq(extensions, null);
// test to see if a non-existant extension exists
do_check_true(!extensions.has(testdata.dummyid));
// test to see if an extension exists
do_check_true(extensions.has(testdata.inspectorid));
var inspector = extensions.get(testdata.inspectorid);
do_check_eq(inspector.id, testdata.inspectorid);
do_check_eq(inspector.name, testdata.inspectorname);
do_check_eq(inspector.version, "1.0");
do_check_true(inspector.firstRun, true);
do_check_true(inspector.enabled);
// test to see if extension find works
do_check_eq(extensions.all.length, 1);
// STORAGE TESTING
// Make sure the we are given the same extension (cached) so things like .storage work right
inspector.storage.set("test", "simple check");
do_check_true(inspector.storage.has("test"));
var inspector2 = extensions.get(testdata.inspectorid);
do_check_eq(inspector2.id, testdata.inspectorid);
do_check_true(inspector.storage.has("test"));
do_check_eq(inspector2.storage.get("test", "cache"), inspector.storage.get("test", "original"));
inspector.events.addListener("disable", onGenericEvent);
inspector.events.addListener("enable", onGenericEvent);
inspector.events.addListener("uninstall", onGenericEvent);
inspector.events.addListener("cancel", onGenericEvent);
AddonManager.getAddon(testdata.inspectorid, function(a) {
a.userDisabled = true;
do_check_eq(gLastEvent, "disable");
// enabling after a disable will only fire a 'cancel' event
// see - http://mxr.mozilla.org/seamonkey/source/toolkit/mozapps/extensions/src/nsExtensionManager.js.in#5216
a.userDisabled = false;
do_check_eq(gLastEvent, "cancel");
a.uninstall();
do_check_eq(gLastEvent, "uninstall");
a.cancelUninstall();
do_check_eq(gLastEvent, "cancel");
// PREF TESTING
// Reset the install event preference, so that we can test it again later
//inspector.prefs.get("install-event-fired").reset();
// test the value of the preference root
do_check_eq(extensions.all[0].prefs.root, "extensions.addon1@tests.mozilla.org.");
// test getting non-existing values
var itemValue = inspector.prefs.getValue(testdata.missing, "default");
do_check_eq(itemValue, "default");
do_check_eq(inspector.prefs.get(testdata.missing), null);
// test setting and getting a value
inspector.prefs.setValue(testdata.dummy, "dummy");
itemValue = inspector.prefs.getValue(testdata.dummy, "default");
do_check_eq(itemValue, "dummy");
// test for overwriting an existing value
inspector.prefs.setValue(testdata.dummy, "smarty");
itemValue = inspector.prefs.getValue(testdata.dummy, "default");
do_check_eq(itemValue, "smarty");
// test setting and getting a value
inspector.prefs.get(testdata.dummy).value = "dummy2";
itemValue = inspector.prefs.get(testdata.dummy).value;
do_check_eq(itemValue, "dummy2");
// test resetting a pref [since there is no default value, the pref should disappear]
inspector.prefs.get(testdata.dummy).reset();
var itemValue = inspector.prefs.getValue(testdata.dummy, "default");
do_check_eq(itemValue, "default");
// test to see if a non-existant property exists
do_check_true(!inspector.prefs.has(testdata.dummy));
inspector.prefs.events.addListener("change", onPrefChange);
inspector.prefs.setValue("fuel.fuel-test", "change event");
});
});
}
function onGenericEvent(event) {
gLastEvent = event.type;
}
function onPrefChange(evt) {
Application.getExtensions(function(extensions) {
var inspector3 = extensions.get(testdata.inspectorid);
do_check_eq(evt.data, testdata.dummy);
inspector3.prefs.events.removeListener("change", onPrefChange);
inspector3.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2);
inspector3.prefs.setValue("fuel.fuel-test", "change event2");
});
}
function onPrefChange2(evt) {
do_check_eq(evt.data, testdata.dummy);
do_test_finished();
}