This commit is contained in:
Tim Taubert 2012-09-18 11:27:53 +02:00
Родитель ce8d806929 896f520d2f
Коммит 591b7d6b5c
34 изменённых файлов: 215 добавлений и 1223 удалений

Просмотреть файл

@ -171,10 +171,10 @@ let gUpdater = {
// Set the site's initial opacity to zero.
site.node.style.opacity = 0;
// Without the setTimeout() the node would just appear instead of fade in.
setTimeout(function () {
gTransformation.showSite(site, function () batch.pop());
}, 0);
// Flush all style changes for the dynamically inserted site to make
// the fade-in transition work.
window.getComputedStyle(site.node).opacity;
gTransformation.showSite(site, function () batch.pop());
});
batch.close();

Просмотреть файл

@ -224,7 +224,7 @@ let PageThumbs = {
let sh = aWindow.innerHeight;
let {width: thumbnailWidth, height: thumbnailHeight} = aCanvas;
let scale = Math.max(thumbnailWidth / sw, thumbnailHeight / sh);
let scale = Math.min(Math.max(thumbnailWidth / sw, thumbnailHeight / sh), 1);
let scaledWidth = sw * scale;
let scaledHeight = sh * scale;

Просмотреть файл

@ -411,6 +411,34 @@ var Scratchpad = {
}
},
/**
* Reload the current page and execute the entire editor content when
* the page finishes loading. Note that this operation should be available
* only in the content context.
*/
reloadAndRun: function SP_reloadAndRun()
{
if (this.executionContext !== SCRATCHPAD_CONTEXT_CONTENT) {
Cu.reportError(this.strings.
GetStringFromName("scratchpadContext.invalid"));
return;
}
let browser = this.gBrowser.selectedBrowser;
this._reloadAndRunEvent = function onLoad(evt) {
if (evt.target !== browser.contentDocument) {
return;
}
browser.removeEventListener("load", this._reloadAndRunEvent, true);
this.run();
}.bind(this);
browser.addEventListener("load", this._reloadAndRunEvent, true);
browser.contentWindow.location.reload();
},
/**
* Execute the selected text (if any) or the entire editor content in the
* current context. The evaluation result is inserted into the editor after
@ -979,6 +1007,7 @@ var Scratchpad = {
let content = document.getElementById("sp-menu-content");
document.getElementById("sp-menu-browser").removeAttribute("checked");
document.getElementById("sp-cmd-reloadAndRun").removeAttribute("disabled");
content.setAttribute("checked", true);
this.executionContext = SCRATCHPAD_CONTEXT_CONTENT;
this.notificationBox.removeAllNotifications(false);
@ -995,8 +1024,12 @@ var Scratchpad = {
}
let browser = document.getElementById("sp-menu-browser");
let reloadAndRun = document.getElementById("sp-cmd-reloadAndRun");
document.getElementById("sp-menu-content").removeAttribute("checked");
reloadAndRun.setAttribute("disabled", true);
browser.setAttribute("checked", true);
this.executionContext = SCRATCHPAD_CONTEXT_BROWSER;
this.notificationBox.appendNotification(
this.strings.GetStringFromName("browserContext.notification"),
@ -1173,6 +1206,8 @@ var Scratchpad = {
}
this.resetContext();
this.gBrowser.selectedBrowser.removeEventListener("load",
this._reloadAndRunEvent, true);
this.editor.removeEventListener(SourceEditor.EVENTS.DIRTY_CHANGED,
this._onDirtyChanged);
PreferenceObserver.uninit();

Просмотреть файл

@ -45,6 +45,7 @@
<command id="sp-cmd-display" oncommand="Scratchpad.display();"/>
<command id="sp-cmd-contentContext" oncommand="Scratchpad.setContentContext();"/>
<command id="sp-cmd-browserContext" oncommand="Scratchpad.setBrowserContext();" disabled="true"/>
<command id="sp-cmd-reloadAndRun" oncommand="Scratchpad.reloadAndRun();"/>
<command id="sp-cmd-resetContext" oncommand="Scratchpad.resetContext();"/>
<command id="sp-cmd-errorConsole" oncommand="Scratchpad.openErrorConsole();" disabled="true"/>
<command id="sp-cmd-webConsole" oncommand="Scratchpad.openWebConsole();"/>
@ -90,6 +91,10 @@
key="&display.key;"
command="sp-cmd-display"
modifiers="accel"/>
<key id="sp-key-reloadAndRun"
key="&reloadAndRun.key;"
command="sp-cmd-reloadAndRun"
modifiers="accel,shift"/>
<key id="sp-key-errorConsole"
key="&errorConsoleCmd.commandkey;"
command="sp-cmd-errorConsole"
@ -194,6 +199,11 @@
key="sp-key-display"
command="sp-cmd-display"/>
<menuseparator/>
<menuitem id="sp-text-reloadAndRun"
label="&reloadAndRun.label;"
key="sp-key-reloadAndRun"
accesskey="&reloadAndRun.accesskey;"
command="sp-cmd-reloadAndRun"/>
<menuitem id="sp-text-resetContext"
label="&resetContext2.label;"
accesskey="&resetContext2.accesskey;"

Просмотреть файл

@ -34,6 +34,7 @@ MOCHITEST_BROWSER_FILES = \
browser_scratchpad_bug_651942_recent_files.js \
browser_scratchpad_bug756681_display_non_error_exceptions.js \
browser_scratchpad_bug_751744_revert_to_saved.js \
browser_scratchpad_bug740948_reload_and_run.js \
head.js \
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,73 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
let EDITOR_TEXT = [
"var evt = new CustomEvent('foo', { bubbles: true });",
"document.body.innerHTML = 'Modified text';",
"window.dispatchEvent(evt);"
].join("\n");
function test()
{
waitForExplicitFinish();
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,Scratchpad test for bug 740948";
}
function runTests()
{
let sp = gScratchpadWindow.Scratchpad;
ok(sp, "Scratchpad object exists in new window");
// Test that Reload And Run command is enabled in the content
// context and disabled in the browser context.
let reloadAndRun = gScratchpadWindow.document.
getElementById("sp-cmd-reloadAndRun");
ok(reloadAndRun, "Reload And Run command exists");
ok(!reloadAndRun.hasAttribute("disabled"),
"Reload And Run command is enabled");
sp.setBrowserContext();
ok(reloadAndRun.hasAttribute("disabled"),
"Reload And Run command is disabled in the browser context.");
// Switch back to the content context and run our predefined
// code. This code modifies the body of our document and dispatches
// a custom event 'foo'. We listen to that event and check the
// body to make sure that the page has been reloaded and Scratchpad
// code has been executed.
sp.setContentContext();
sp.setText(EDITOR_TEXT);
let browser = gBrowser.selectedBrowser;
browser.addEventListener("DOMWindowCreated", function onWindowCreated() {
browser.removeEventListener("DOMWindowCreated", onWindowCreated, true);
browser.contentWindow.addEventListener("foo", function onFoo() {
browser.contentWindow.removeEventListener("foo", onFoo, true);
is(browser.contentWindow.document.body.innerHTML, "Modified text",
"After reloading, HTML is different.");
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
finish();
}, true);
}, true);
ok(browser.contentWindow.document.body.innerHTML !== "Modified text",
"Before reloading, HTML is intact.");
sp.reloadAndRun();
}

Просмотреть файл

@ -105,6 +105,10 @@
<!ENTITY resetContext2.label "Reset Variables">
<!ENTITY resetContext2.accesskey "T">
<!ENTITY reloadAndRun.label "Reload And Run">
<!ENTITY reloadAndRun.accesskey "E">
<!ENTITY reloadAndRun.key "r">
<!ENTITY executeMenu.label "Execute">
<!ENTITY executeMenu.accesskey "X">

Просмотреть файл

@ -26,6 +26,10 @@ export.fileOverwriteConfirmation=File exists. Overwrite?
# type.
browserWindow.unavailable=Scratchpad cannot find any browser window to execute the code in.
# LOCALIZATION NOTE (scratchpadContext.invalid): This error message is shown
# when user tries to run an operation in Scratchpad in an unsupported context.
scratchpadContext.invalid=Scratchpad cannot run this operation in the current mode.
# LOCALIZATION NOTE (openFile.title): This is the file picker title, when you
# open a file from Scratchpad.
openFile.title=Open File

Просмотреть файл

@ -55,15 +55,17 @@ li.container {
.expander {
position: absolute;
-moz-appearance: treetwisty;
top: 0;
top: 5px;
left: 0;
width: 14px;
height: 14px;
background-repeat: no-repeat;
background-position: center;
background-image: url("chrome://global/skin/tree/twisty-clsd.png");
}
.expander[expanded] {
-moz-appearance: treetwistyopen;
background-image: url("chrome://global/skin/tree/twisty-open.png");
}
.styleinspector-propertyeditor {

Просмотреть файл

@ -2694,9 +2694,9 @@ Tab.prototype = {
// require error page UI to do privileged things, without letting error
// pages have any privilege themselves.
if (/^about:/.test(target.documentURI)) {
this.browser.addEventListener("click", ErrorPageEventHandler, false);
this.browser.addEventListener("click", ErrorPageEventHandler, true);
let listener = function() {
this.browser.removeEventListener("click", ErrorPageEventHandler, false);
this.browser.removeEventListener("click", ErrorPageEventHandler, true);
this.browser.removeEventListener("pagehide", listener, true);
}.bind(this);
@ -4068,6 +4068,10 @@ var ErrorPageEventHandler = {
} else if (target == errorDoc.getElementById("getMeOutOfHereButton")) {
errorDoc.location = "about:home";
}
} else if (/^about:neterror\?e=netOffline/.test(ownerDoc.documentURI)) {
let tryAgain = errorDoc.getElementById("errorTryAgain");
if (target == tryAgain)
Services.io.offline = false;
}
break;
}

Просмотреть файл

@ -76,12 +76,8 @@
function retryThis(buttonEl)
{
// If this is the "Offline mode" page, go online!
if (getErrorCode() == "netOffline") {
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.goOnline();
}
// Note: The application may wish to handle switching off "offline mode"
// before this event handler runs, but using a capturing event handler.
// Session history has the URL of the page that failed
// to load, not the one of the error page. So, just call

Просмотреть файл

@ -385,6 +385,7 @@ var Browser = {
messageManager.addMessageListener("Browser:CertException", this);
messageManager.addMessageListener("Browser:BlockedSite", this);
messageManager.addMessageListener("Browser:ErrorPage", this);
messageManager.addMessageListener("Browser:GoOnline", this);
messageManager.addMessageListener("Browser:PluginClickToPlayClicked", this);
// Broadcast a UIReady message so add-ons know we are finished with startup
@ -484,6 +485,7 @@ var Browser = {
messageManager.removeMessageListener("Browser:CertException", this);
messageManager.removeMessageListener("Browser:BlockedSite", this);
messageManager.removeMessageListener("Browser:ErrorPage", this);
messageManager.removeMessageListener("Browser:GoOnline", this);
messageManager.removeMessageListener("Browser:PluginClickToPlayClicked", this);
var os = Services.obs;
@ -1265,6 +1267,9 @@ var Browser = {
case "Browser:ErrorPage":
this._handleErrorPage(aMessage);
break;
case "Browser:GoOnline":
Services.io.offline = false;
break;
case "Browser:PluginClickToPlayClicked": {
// Save off session history
let parent = browser.parentNode;

Просмотреть файл

@ -292,7 +292,7 @@ let Content = {
// pages and other similar page. This lets us fix bugs like 401575 which
// require error page UI to do privileged things, without letting error
// pages have any privilege themselves.
addEventListener("click", this, false);
addEventListener("click", this, true);
docShell.QueryInterface(Ci.nsIDocShellHistory).useGlobalHistory = true;
},
@ -384,6 +384,10 @@ let Content = {
// http://hg.mozilla.org/mozilla-central/file/855e5cd3c884/browser/base/content/browser.js#l2672
// http://hg.mozilla.org/mozilla-central/file/855e5cd3c884/browser/components/safebrowsing/content/globalstore.js
}
} else if (/^about:neterror\?e=netOffline/.test(ownerDoc.documentURI)) {
let tryAgain = errorDoc.getElementById("errorTryAgain");
if (target == tryAgain)
sendSyncMessage("Browser:GoOnline", { });
}
break;
}

Просмотреть файл

@ -76,12 +76,8 @@
function retryThis(buttonEl)
{
// If this is the "Offline mode" page, go online!
if (getErrorCode() == "netOffline") {
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.goOnline();
}
// Note: The application may wish to handle switching off "offline mode"
// before this event handler runs, but using a capturing event handler.
// Session history has the URL of the page that failed
// to load, not the one of the error page. So, just call

Просмотреть файл

@ -82,6 +82,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
XPCOMUtils.defineLazyServiceGetter(this, "idleService",
"@mozilla.org/widget/idleservice;1",
"nsIIdleService");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
function generateUUID() {
let str = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
@ -143,42 +145,6 @@ function getSimpleMeasurements() {
return ret;
}
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other installations of the application that may use the same profile.
*/
function getUpdateChannel() {
var channel = "default";
var prefName;
var prefValue;
var defaults = Services.prefs.getDefaultBranch(null);
try {
channel = defaults.getCharPref("app.update.channel");
} catch (e) {
// use default when pref not found
}
try {
var partners = Services.prefs.getChildList("app.partner.");
if (partners.length) {
channel += "-cck";
partners.sort();
for each (prefName in partners) {
prefValue = Services.prefs.getCharPref(prefName);
channel += "-" + prefValue;
}
}
}
catch (e) {
Cu.reportError(e);
}
return channel;
}
/**
* Read current process I/O counters.
*/
@ -359,7 +325,7 @@ TelemetryPing.prototype = {
appVersion: ai.version,
appName: ai.name,
appBuildID: ai.appBuildID,
appUpdateChannel: getUpdateChannel(),
appUpdateChannel: UpdateChannel.get(),
platformBuildID: ai.platformBuildID,
locale: getLocale()
};

Просмотреть файл

@ -20,11 +20,12 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const PREF_PARTNER_BRANCH = "app.partner.";
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
function nsURLFormatterService() {
XPCOMUtils.defineLazyGetter(this, "appInfo", function UFS_appInfo() {
return Cc["@mozilla.org/xre/app-info;1"].
@ -62,29 +63,6 @@ function nsURLFormatterService() {
return encodeURIComponent(OSVersion);
});
XPCOMUtils.defineLazyGetter(this, "updateChannel", function UFS_updateChannel() {
// Read the update channel from defaults only. We do this to ensure that
// the channel is tightly coupled with the application and does not apply
// to other instances of the application that may use the same profile.
let channel = "default";
let defaults = Services.prefs.getDefaultBranch(null);
try {
channel = defaults.getCharPref(PREF_APP_UPDATE_CHANNEL);
} catch (e) {}
try {
let partners = Services.prefs.getChildList(PREF_PARTNER_BRANCH).sort();
if (partners.length) {
channel += "-cck";
partners.forEach(function (prefName) {
channel += "-" + Services.prefs.getCharPref(prefName);
});
}
} catch (e) {}
return channel;
});
XPCOMUtils.defineLazyGetter(this, "distribution", function UFS_distribution() {
let distribution = { id: "default", version: "default" };
@ -120,7 +98,7 @@ nsURLFormatterService.prototype = {
XPCOMABI: function() this.ABI,
BUILD_TARGET: function() this.appInfo.OS + "_" + this.ABI,
OS_VERSION: function() this.OSVersion,
CHANNEL: function() this.updateChannel,
CHANNEL: function() UpdateChannel.get(),
DISTRIBUTION: function() this.distribution.id,
DISTRIBUTION_VERSION: function() this.distribution.version
},

Просмотреть файл

@ -67,6 +67,7 @@ EXTRA_JS_MODULES = \
PrivateBrowsingUtils.jsm \
PropertyListUtils.jsm \
Task.jsm \
UpdateChannel.jsm \
$(NULL)
EXTRA_PP_JS_MODULES = \

Просмотреть файл

@ -0,0 +1,40 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const EXPORTED_SYMBOLS = ["UpdateChannel"];
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
let UpdateChannel = {
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other instances of the application that may use the same profile.
*/
get: function UpdateChannel_get() {
let channel = "default";
let defaults = Services.prefs.getDefaultBranch(null);
try {
channel = defaults.getCharPref("app.update.channel");
} catch (e) {
// use default when pref not found
}
try {
let partners = Services.prefs.getChildList("app.partner.").sort();
if (partners.length) {
channel += "-cck";
partners.forEach(function (prefName) {
channel += "-" + Services.prefs.getCharPref(prefName);
});
}
} catch (e) {
Cu.reportError(e);
}
return channel;
}
};

Просмотреть файл

@ -1826,7 +1826,7 @@ function getFunctionName(aFunction) {
let desc = aFunction.getOwnPropertyDescriptor("displayName");
if (desc && desc.value && typeof desc.value == "string") {
name = desc.value;
} else if ("displayName" in aFunction) {
} else {
// Otherwise use SpiderMonkey's inferred name.
name = aFunction.displayName;
}

Просмотреть файл

@ -16,6 +16,8 @@ Components.utils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
const TOOLKIT_ID = "toolkit@mozilla.org"
const KEY_PROFILEDIR = "ProfD";
@ -31,10 +33,8 @@ const PREF_BLOCKLIST_PINGCOUNTTOTAL = "extensions.blocklist.pingCountTotal";
const PREF_BLOCKLIST_PINGCOUNTVERSION = "extensions.blocklist.pingCountVersion";
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
const PREF_GENERAL_USERAGENT_LOCALE = "general.useragent.locale";
const PREF_PARTNER_BRANCH = "app.partner.";
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled";
const XMLURI_BLOCKLIST = "http://www.mozilla.org/2006/addons-blocklist";
const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
@ -225,42 +225,6 @@ function getLocale() {
return gPref.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
}
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other installations of the application that may use the same profile.
*/
function getUpdateChannel() {
var channel = "default";
var prefName;
var prefValue;
var defaults = gPref.getDefaultBranch(null);
try {
channel = defaults.getCharPref(PREF_APP_UPDATE_CHANNEL);
} catch (e) {
// use default when pref not found
}
try {
var partners = gPref.getChildList(PREF_PARTNER_BRANCH);
if (partners.length) {
channel += "-cck";
partners.sort();
for each (prefName in partners) {
prefValue = gPref.getCharPref(prefName);
channel += "-" + prefValue;
}
}
}
catch (e) {
Components.utils.reportError(e);
}
return channel;
}
/* Get the distribution pref values, from defaults only */
function getDistributionPrefValue(aPrefName) {
var prefValue = "default";
@ -461,7 +425,7 @@ Blocklist.prototype = {
dsURI = dsURI.replace(/%BUILD_TARGET%/g, gApp.OS + "_" + gABI);
dsURI = dsURI.replace(/%OS_VERSION%/g, gOSVersion);
dsURI = dsURI.replace(/%LOCALE%/g, getLocale());
dsURI = dsURI.replace(/%CHANNEL%/g, getUpdateChannel());
dsURI = dsURI.replace(/%CHANNEL%/g, UpdateChannel.get());
dsURI = dsURI.replace(/%PLATFORM_VERSION%/g, gApp.platformVersion);
dsURI = dsURI.replace(/%DISTRIBUTION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION));

Просмотреть файл

@ -1,64 +0,0 @@
<?xml version="1.0"?>
<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
xmlns:NC="http://home.netscape.com/NC-rdf#"
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<RDF:Description RDF:about="urn:mozilla:item:bug356370_1@tests.mozilla.org">
<em:installLocation>app-profile</em:installLocation>
<em:version>1</em:version>
<em:name>Bug 356370 test 1</em:name>
<em:type NC:parseType="Integer">2</em:type>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:bug356370_2@tests.mozilla.org">
<em:installLocation>invalid-hi</em:installLocation>
<em:version>1</em:version>
<em:name>Bug 356370 test 2</em:name>
<em:type NC:parseType="Integer">2</em:type>
<em:userDisabled>true</em:userDisabled>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:bug356370_3@tests.mozilla.org">
<em:installLocation>invalid</em:installLocation>
<em:version>1</em:version>
<em:name>Bug 356370 test 3</em:name>
<em:type NC:parseType="Integer">2</em:type>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:bug356370_4@tests.mozilla.org">
<em:installLocation>invalid</em:installLocation>
<em:version>1</em:version>
<em:name>Bug 356370 test 4</em:name>
<em:type NC:parseType="Integer">4</em:type>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
<RDF:Seq RDF:about="urn:mozilla:item:root">
<RDF:li RDF:resource="urn:mozilla:item:bug356370_1@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:bug356370_2@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:bug356370_3@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:bug356370_4@tests.mozilla.org"/>
</RDF:Seq>
</RDF:RDF>

Просмотреть файл

@ -1,20 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>bug356370_1@tests.mozilla.org</em:id>
<em:version>1</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<em:name>Bug 356370 test 1</em:name>
</Description>
</RDF>

Просмотреть файл

@ -1,20 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>bug356370_2@tests.mozilla.org</em:id>
<em:version>1</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<em:name>Bug 356370 test 2</em:name>
</Description>
</RDF>

Просмотреть файл

@ -1,21 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>bug356370_4@tests.mozilla.org</em:id>
<em:version>1</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<em:name>Bug 356370 test 4</em:name>
<em:type NC:parseType="Integer">4</em:type>
</Description>
</RDF>

Просмотреть файл

@ -1 +0,0 @@
# blank file to stop the EM attempting to create one anyway

Просмотреть файл

@ -1,22 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>bug421396@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>bug421396 test</em:name>
</Description>
</RDF>

Просмотреть файл

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<RDF:Description about="urn:mozilla:extension:test_bug463819_2@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>1.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>2</em:maxVersion>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug463819_5@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>1.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>2</em:maxVersion>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug463819_8@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>1.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>2</em:maxVersion>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
</RDF:Description>
</RDF:RDF>

Просмотреть файл

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
<emItems>
<emItem id="test_bug463819_4@tests.mozilla.org">
<versionRange severity="1"/>
</emItem>
<emItem id="test_bug463819_5@tests.mozilla.org">
<versionRange severity="1"/>
</emItem>
<emItem id="test_bug463819_6@tests.mozilla.org">
<versionRange severity="1"/>
</emItem>
<emItem id="test_bug463819_7@tests.mozilla.org">
<versionRange severity="3"/>
</emItem>
<emItem id="test_bug463819_8@tests.mozilla.org">
<versionRange severity="3"/>
</emItem>
<emItem id="test_bug463819_9@tests.mozilla.org">
<versionRange severity="3"/>
</emItem>
</emItems>
</blocklist>

Просмотреть файл

@ -1,234 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* These are intended to be a set of base functions enabling unit testing
* for the Extension Manager component.
*/
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
const PREFIX_NS_CHROME = "http://www.mozilla.org/rdf/chrome#";
const PREFIX_ITEM_URI = "urn:mozilla:item:";
const NS_INSTALL_LOCATION_APPPROFILE = "app-profile";
const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}");
var gXULAppInfo = null;
var gEM = null;
var gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]
.getService(Components.interfaces.nsIRDFService);
/**
* Utility functions
*/
function EM_NS(property) {
return PREFIX_NS_EM + property;
}
function CHROME_NS(property) {
return PREFIX_NS_CHROME + property;
}
function EM_R(property) {
return gRDF.GetResource(EM_NS(property));
}
function EM_L(literal) {
return gRDF.GetLiteral(literal);
}
function EM_I(integer) {
return gRDF.GetIntLiteral(integer);
}
function EM_D(integer) {
return gRDF.GetDateLiteral(integer);
}
/**
* Extract the string value from a RDF Literal or Resource
* @param literalOrResource
* RDF String Literal or Resource
* @returns String value of the literal or resource, or undefined if the object
* supplied is not a RDF string literal or resource.
*/
function stringData(literalOrResource) {
if (literalOrResource instanceof Components.interfaces.nsIRDFLiteral)
return literalOrResource.Value;
if (literalOrResource instanceof Components.interfaces.nsIRDFResource)
return literalOrResource.Value;
return undefined;
}
/**
* Extract the integer value of a RDF Literal
* @param literal
* nsIRDFInt literal
* @return integer value of the literal
*/
function intData(literal) {
if (literal instanceof Components.interfaces.nsIRDFInt)
return literal.Value;
return undefined;
}
/**
* Gets a RDF Resource for item with the given ID
* @param id
* The GUID of the item to construct a RDF resource to the
* active item for
* @returns The RDF Resource to the Active item.
*/
function getResourceForID(id) {
return gRDF.GetResource(PREFIX_ITEM_URI + id);
}
/**
* Extract a string property for an add-on
* @param id
* ID of the add-on to retrieve a property for
* @param property
* The localname of the property
* @returns String value of the property or undefined if the property
* does not exist
*/
function getManifestProperty(id, property) {
return stringData(gEM.datasource.GetTarget(getResourceForID(id), EM_R(property), true));
}
/**
* Returns a testcase xpi
* @param name
* The name of the testcase (without extension)
* @returns an nsIFile pointing to the testcase xpi
*/
function do_get_addon(name)
{
return do_get_file("addons/" + name + ".xpi");
}
/**
* Creates an nsIXULAppInfo
* @param id
* The ID of the test application
* @param name
* A name for the test application
* @param version
* The version of the application
* @param platformVersion
* The gecko version of the application
*/
function createAppInfo(id, name, version, platformVersion)
{
gXULAppInfo = {
vendor: "Mozilla",
name: name,
ID: id,
version: version,
appBuildID: "2007010101",
platformVersion: platformVersion,
platformBuildID: "2007010101",
inSafeMode: false,
logConsoleErrors: true,
OS: "XPCShell",
XPCOMABI: "noarch-spidermonkey",
invalidateCachesOnRestart: function invalidateCachesOnRestart() {},
QueryInterface: function QueryInterface(iid) {
if (iid.equals(Components.interfaces.nsIXULAppInfo)
|| iid.equals(Components.interfaces.nsIXULRuntime)
|| iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
var XULAppInfoFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return gXULAppInfo.QueryInterface(iid);
}
};
var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
XULAPPINFO_CONTRACTID, XULAppInfoFactory);
}
function startEM(upgraded) {
var needsRestart = false;
if (upgraded) {
try {
needsRestart = gEM.checkForMismatches();
}
catch (e) {
do_throw("checkForMismatches threw an exception: " + e + "\n");
needsRestart = false;
upgraded = false;
}
}
if (!upgraded || !needsRestart)
needsRestart = gEM.start();
if (needsRestart)
restartEM();
}
/**
* This simulates an application startup. Since we will be starting from an
* empty profile we follow that path.
*/
function startupEM()
{
gEM = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
gEM.QueryInterface(Components.interfaces.nsIObserver);
gEM.observe(null, "profile-after-change", "startup");
// First run is a new profile which nsAppRunner would consider as an update
// (no existing compatibility.ini)
startEM(true);
}
/**
* Simple function to simulate the termination of an app to the EM.
* This harness does not support creating a new EM after calling this.
*/
function shutdownEM()
{
// xpcshell calls xpcom-shutdown so we don't actually do anything here.
gEM = null;
}
/**
* Many operations require restarts to take effect. This function should
* perform all that is necessary for this to happen.
*/
function restartEM(newVersion)
{
if (newVersion) {
gXULAppInfo.version = newVersion;
startEM(true);
}
else {
startEM(false);
}
}
var gDirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
// Need to create and register a profile folder.
var gProfD = do_get_profile();
var gPrefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
// Enable more extensive EM logging
gPrefs.setBoolPref("extensions.logging.enabled", true);

Просмотреть файл

@ -1,8 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Close down any remaining EM
if (gEM)
shutdownEM();

Просмотреть файл

@ -1,128 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
// Don't need the full interface, attempts to call other methods will just
// throw which is just fine
var WindowWatcher = {
openWindow: function(parent, url, name, features, arguments) {
// It is expected that the update dialog is shown during this test.
do_check_eq(url, URI_EXTENSION_UPDATE_DIALOG);
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIWindowWatcher)
|| iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
}
var WindowWatcherFactory = {
createInstance: function createInstance(outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return WindowWatcher.QueryInterface(iid);
}
};
var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"),
"Fake Window Watcher",
"@mozilla.org/embedcomp/window-watcher;1",
WindowWatcherFactory);
function write_cache_line(stream, location, id, mtime) {
var line = location + "\t" + id + "\trel%" + id + "\t" + Math.floor(mtime / 1000) + "\t\r\n";
stream.write(line, line.length);
}
/**
* This copies two extensions, a default extensions datasource into the profile
* It also manufactures an extensions.cache file with invalid items.
* There are 4 test extensions:
* bug356370_1@tests.mozilla.org exists in app-profile and an unused version is in invalid-lo
* bug356370_2@tests.mozilla.org exists in invalid-hi and an unused version is in app-profile
* bug356370_3@tests.mozilla.org exists in invalid
* bug356370_4@tests.mozilla.org is a theme existing in invalid and a new install
* will be detected in app-profile
*
* After startup only the first two should exist in the correct install location
* and installing extensions should be successful.
*/
function setup_profile() {
// Set up the profile with some existing extensions
// Not nice to copy the extensions datasource in, but bringing up the EM to
// create it properly will invalidate the test
var source = do_get_file("data/test_bug356370.rdf");
source.copyTo(gProfD, "extensions.rdf");
// Must programmatically generate the cache since it depends on the mimetimes
// being accurate.
var cache = gProfD.clone();
cache.append("extensions.cache");
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(cache, 0x02 | 0x08 | 0x20, 0666, 0); // Write, create, truncate
var addon = gProfD.clone();
addon.append("extensions");
addon.append("bug356370_1@tests.mozilla.org");
source = do_get_file("data/test_bug356370_1.rdf");
addon.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
source.copyTo(addon, "install.rdf");
write_cache_line(foStream, "app-profile", "bug356370_1@tests.mozilla.org",
addon.lastModifiedTime);
addon = gProfD.clone();
addon.append("extensions");
addon.append("bug356370_2@tests.mozilla.org");
source = do_get_file("data/test_bug356370_2.rdf");
addon.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
source.copyTo(addon, "install.rdf");
write_cache_line(foStream, "app-profile", "bug356370_2@tests.mozilla.org",
addon.lastModifiedTime);
addon = gProfD.clone();
addon.append("extensions");
addon.append("bug356370_4@tests.mozilla.org");
source = do_get_file("data/test_bug356370_4.rdf");
addon.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
source.copyTo(addon, "install.rdf");
// Write out a set of invalid entries
write_cache_line(foStream, "invalid-lo", "bug356370_1@tests.mozilla.org", 0);
write_cache_line(foStream, "invalid-hi", "bug356370_2@tests.mozilla.org", 0);
write_cache_line(foStream, "invalid", "bug356370_3@tests.mozilla.org", 0);
write_cache_line(foStream, "invalid", "bug356370_4@tests.mozilla.org", 0);
foStream.close();
}
function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
gPrefs.setCharPref("extensions.lastAppVersion", "4");
setup_profile();
startupEM();
do_check_neq(gEM.getItemForID("bug356370_1@tests.mozilla.org"), null);
do_check_eq(getManifestProperty("bug356370_1@tests.mozilla.org", "installLocation"), "app-profile");
do_check_neq(gEM.getItemForID("bug356370_2@tests.mozilla.org"), null);
do_check_eq(getManifestProperty("bug356370_2@tests.mozilla.org", "installLocation"), "app-profile");
// This should still be disabled
do_check_eq(getManifestProperty("bug356370_2@tests.mozilla.org", "isDisabled"), "true");
do_check_eq(gEM.getItemForID("bug356370_3@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("bug356370_4@tests.mozilla.org"), null);
do_check_eq(getManifestProperty("bug356370_4@tests.mozilla.org", "installLocation"), "app-profile");
gEM.installItemFromFile(do_get_addon("test_bug257155"), NS_INSTALL_LOCATION_APPPROFILE);
do_check_neq(gEM.getItemForID("bug257155@tests.mozilla.org"), null);
restartEM();
do_check_neq(gEM.getItemForID("bug257155@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("bug356370_1@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("bug356370_2@tests.mozilla.org"), null);
do_check_eq(gEM.getItemForID("bug356370_3@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("bug356370_4@tests.mozilla.org"), null);
}

Просмотреть файл

@ -1,220 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
const TESTID = "bug421396@tests.mozilla.org";
var INSTALLED = true;
// This creates a fake directory that cannot be modified. Nothing exists inside
// the directory.
function RestrictedPath(source, isVisible) {
this.source = source;
this.isVisible = isVisible;
}
// This doesn't implement all of nsIFile, just enough to keep the EM happy.
RestrictedPath.prototype = {
// A real nsIFile that this shadows
source: null,
// If this file is visible or not. Only the main directory for the addon is visible.
isVisible: null,
append: function(node) {
this.source.append(node);
this.isVisible = false;
},
normalize: function() {
this.source.normalize();
},
create: function(type, permissions) {
if (this.isVisible)
throw Components.errors.NS_ERROR_FILE_ALREADY_EXISTS;
throw Components.errors.NS_ERROR_FILE_ACCESS_DENIED;
},
get leafName() {
return this.source.leafName;
},
copyTo: function(parentdir, name) {
throw Components.errors.NS_ERROR_FILE_ACCESS_DENIED;
},
copyToFollowingLinks: function(parentdir, name) {
throw Components.errors.NS_ERROR_FILE_ACCESS_DENIED;
},
moveTo: function(parentdir, name) {
throw Components.errors.NS_ERROR_FILE_ACCESS_DENIED;
},
remove: function(recursive) {
if (this.isVisible)
throw Components.errors.NS_ERROR_FILE_ACCESS_DENIED;
throw Components.errors.NS_ERROR_FILE_NOT_FOUND;
},
get lastModifiedTime() {
if (this.isVisible)
return Date.now();
throw Components.errors.NS_ERROR_FILE_NOT_FOUND;
},
get lastModifiedTimeOfLink() {
return this.lastModifiedTime;
},
get path() { return this.source.path; },
exists: function() { return this.isVisible; },
isDirectory: function() { return this.isVisible; },
isFile: function() { return !this.isVisible; },
clone: function() {
return new RestrictedPath(this.source.clone(), this.isVisible);
},
get parent() {
return new RestrictedPath(this.source.parent, false);
},
getRelativeDescriptor: function(basedir) {
return this.source.getRelativeDescriptor(basedir);
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIFile)
|| iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
function DirectoryEnumerator(files) {
this.files = files;
this.pos = 0;
}
DirectoryEnumerator.prototype = {
pos: null,
files: null,
get nextFile() {
if (this.pos < this.files.length)
return this.files[this.pos++];
return null;
},
close: function() {
}
};
var InstallLocation = {
name: "test-location",
location: null,
restricted: null,
canAccess: null,
priority: Components.interfaces.nsIInstallLocation.PRIORITY_APP_SYSTEM_GLOBAL,
get itemLocations() {
return new DirectoryEnumerator([ this.getItemLocation(TESTID) ]);
},
getItemLocation: function(id) {
if (id == TESTID) {
var file = do_get_file("data/test_bug421396");
if (INSTALLED)
return file;
// If we are simulating after the extension is "removed" then return the
// empty undeletable directory.
return new RestrictedPath(file, true);
}
var file = do_get_cwd();
file.append("INVALIDNAME");
file.append(id);
return file;
},
getIDForLocation: function(file) {
if (file.leafName == "test_bug421396")
return TESTID;
return file.leafName;
},
getItemFile: function(id, filePath) {
var itemLocation = this.getItemLocation(id).clone();
var parts = filePath.split("/");
for (let part of parts)
itemLocation.append(part);
return itemLocation;
},
itemIsManagedIndependently: function(id) {
return false;
},
stageFile: function(file, id) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
getStageFile: function(id) {
return null;
},
removeFile: function(file) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIInstallLocation)
|| iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
}
var InstallLocationFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return InstallLocation.QueryInterface(iid);
}
};
const IL_CID = Components.ID("{6bdd8320-57c7-4f19-81ad-c32fdfc2b423}");
const IL_CONTRACT = "@tests.mozilla.org/installlocation;1";
var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(IL_CID, "Test Install Location",
IL_CONTRACT, InstallLocationFactory);
var categoryManager = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
categoryManager.addCategoryEntry("extension-install-locations", "test-location",
IL_CONTRACT, false, true);
function run_test()
{
// EM needs to be running.
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
startupEM();
// Addon in the fake location should be installed now.
do_check_neq(gEM.getItemForID(TESTID), null);
// Mark the add-on as uninstalled and restart ot pickup the change.
INSTALLED = false;
restartEM();
do_check_eq(gEM.getItemForID(TESTID), null);
// Test install something.
gEM.installItemFromFile(do_get_addon("test_bug397778"), NS_INSTALL_LOCATION_APPPROFILE);
do_check_neq(gEM.getItemForID("bug397778@tests.mozilla.org"), null);
restartEM();
do_check_eq(gEM.getItemForID(TESTID), null);
do_check_neq(gEM.getItemForID("bug397778@tests.mozilla.org"), null);
}

Просмотреть файл

@ -1,229 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
const INSTALLERROR_SUCCESS = 0;
const INSTALLERROR_INCOMPATIBLE_VERSION = -3;
const INSTALLERROR_BLOCKLISTED = -6;
const INSTALLERROR_SOFTBLOCKED = -10;
// Disables security checking our updates which haven't been signed
gPrefs.setBoolPref("extensions.checkUpdateSecurity", false);
// Get the HTTP server.
const Cr = Components.results;
Components.utils.import("resource://testing-common/httpd.js");
var testserver;
// This allows the EM to attempt to display errors to the user without failing
var promptService = {
alert: function(aParent, aDialogTitle, aText) {
},
alertCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
},
confirm: function(aParent, aDialogTitle, aText) {
},
confirmCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
},
confirmEx: function(aParent, aDialogTitle, aText, aButtonFlags, aButton0Title, aButton1Title, aButton2Title, aCheckMsg, aCheckState) {
},
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
},
promptUsernameAndPassword: function(aParent, aDialogTitle, aText, aUsername, aPassword, aCheckMsg, aCheckState) {
},
promptPassword: function(aParent, aDialogTitle, aText, aPassword, aCheckMsg, aCheckState) {
},
select: function(aParent, aDialogTitle, aText, aCount, aSelectList, aOutSelection) {
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIPromptService)
|| iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
// This will be called to show the blocklist message, we just make it look like
// it was dismissed.
var WindowWatcher = {
openWindow: function(parent, url, name, features, arguments) {
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIWindowWatcher)
|| iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
}
}
var WindowWatcherFactory = {
createInstance: function createInstance(outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return WindowWatcher.QueryInterface(iid);
}
};
var PromptServiceFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return promptService.QueryInterface(iid);
}
};
var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(Components.ID("{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}"),
"PromptService",
"@mozilla.org/embedcomp/prompt-service;1", PromptServiceFactory);
registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"),
"Fake Window Watcher",
"@mozilla.org/embedcomp/window-watcher;1", WindowWatcherFactory);
var gNextTest, gLastStatus;
// nsIAddonInstallListener
var installListener = {
onDownloadStarted: function(aAddon) {
},
onDownloadEnded: function(aAddon) {
},
onInstallStarted: function(aAddon) {
},
onCompatibilityCheckStarted: function(aAddon) {
},
onCompatibilityCheckEnded: function(aAddon, aStatus) {
},
onInstallEnded: function(aAddon, aStatus) {
gLastStatus = aStatus;
},
onInstallsCompleted: function() {
gNextTest();
},
onDownloadProgress: function onProgress(aAddon, aValue, aMaxValue) {
}
}
function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "1.9");
// Install the blocklist
var blocklist = do_get_file("data/test_bug463819.xml");
blocklist.copyTo(gProfD, "blocklist.xml");
// Create and configure the HTTP server.
testserver = new HttpServer();
testserver.registerDirectory("/", do_get_file("data"));
testserver.start(4444);
startupEM();
gEM.addInstallListener(installListener);
// These add-ons require no update check so will complete installation immediately
dump("Installing add-on 1\n");
gNextTest = test_addon_1;
gEM.installItemFromFile(do_get_addon("test_bug463819_1"), NS_INSTALL_LOCATION_APPPROFILE);
dump("Installing add-on 4\n");
gNextTest = test_addon_4;
gEM.installItemFromFile(do_get_addon("test_bug463819_4"), NS_INSTALL_LOCATION_APPPROFILE);
dump("Installing add-on 7\n");
gNextTest = test_addon_7;
gEM.installItemFromFile(do_get_addon("test_bug463819_7"), NS_INSTALL_LOCATION_APPPROFILE);
do_test_pending();
// These add-ons will perform a compatibility check before responding.
dump("Installing add-on 2\n");
gNextTest = test_addon_2;
gEM.installItemFromFile(do_get_addon("test_bug463819_2"), NS_INSTALL_LOCATION_APPPROFILE);
}
// Compatible in install.rdf and not in blocklist
function test_addon_1() {
do_check_eq(gLastStatus, INSTALLERROR_SUCCESS);
}
// Compatible in install.rdf and low severity in blocklist
function test_addon_4() {
do_check_eq(gLastStatus, INSTALLERROR_SOFTBLOCKED);
}
// Compatible in install.rdf and high severity in blocklist
function test_addon_7() {
do_check_eq(gLastStatus, INSTALLERROR_BLOCKLISTED);
}
// Incompatible in install.rdf, compatible in update.rdf, not in blocklist
function test_addon_2() {
do_check_eq(gLastStatus, INSTALLERROR_SUCCESS);
dump("Installing add-on 3\n");
gNextTest = test_addon_3;
gEM.installItemFromFile(do_get_addon("test_bug463819_3"), NS_INSTALL_LOCATION_APPPROFILE);
}
// Incompatible in install.rdf, incompatible in update.rdf, not in blocklist
function test_addon_3() {
do_check_eq(gLastStatus, INSTALLERROR_INCOMPATIBLE_VERSION);
dump("Installing add-on 5\n");
gNextTest = test_addon_5;
gEM.installItemFromFile(do_get_addon("test_bug463819_5"), NS_INSTALL_LOCATION_APPPROFILE);
}
// Incompatible in install.rdf, compatible in update.rdf, low severity in blocklist
function test_addon_5() {
do_check_eq(gLastStatus, INSTALLERROR_SOFTBLOCKED);
dump("Installing add-on 6\n");
gNextTest = test_addon_6;
gEM.installItemFromFile(do_get_addon("test_bug463819_6"), NS_INSTALL_LOCATION_APPPROFILE);
}
// Incompatible in install.rdf, incompatible in update.rdf, low severity in blocklist
function test_addon_6() {
do_check_eq(gLastStatus, INSTALLERROR_INCOMPATIBLE_VERSION);
dump("Installing add-on 8\n");
gNextTest = test_addon_8;
gEM.installItemFromFile(do_get_addon("test_bug463819_8"), NS_INSTALL_LOCATION_APPPROFILE);
}
// Incompatible in install.rdf, compatible in update.rdf, high severity in blocklist
function test_addon_8() {
do_check_eq(gLastStatus, INSTALLERROR_BLOCKLISTED);
dump("Installing add-on 9\n");
gNextTest = test_addon_9;
gEM.installItemFromFile(do_get_addon("test_bug463819_9"), NS_INSTALL_LOCATION_APPPROFILE);
}
// Incompatible in install.rdf, incompatible in update.rdf, high severity in blocklist
function test_addon_9() {
do_check_eq(gLastStatus, INSTALLERROR_INCOMPATIBLE_VERSION);
finish_test();
}
function finish_test() {
testserver.stop(do_test_finished);
}

Просмотреть файл

@ -30,7 +30,6 @@ const PREF_APP_UPDATE_CERT_CHECKATTRS = "app.update.cert.checkAttributes";
const PREF_APP_UPDATE_CERT_ERRORS = "app.update.cert.errors";
const PREF_APP_UPDATE_CERT_MAXERRORS = "app.update.cert.maxErrors";
const PREF_APP_UPDATE_CERT_REQUIREBUILTIN = "app.update.cert.requireBuiltIn";
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
const PREF_APP_UPDATE_IDLETIME = "app.update.idletime";
const PREF_APP_UPDATE_INCOMPATIBLE_MODE = "app.update.incompatible.mode";
@ -50,7 +49,6 @@ const PREF_APP_UPDATE_SERVICE_ENABLED = "app.update.service.enabled";
const PREF_APP_UPDATE_SERVICE_ERRORS = "app.update.service.errors";
const PREF_APP_UPDATE_SERVICE_MAX_ERRORS = "app.update.service.maxErrors";
const PREF_PARTNER_BRANCH = "app.partner.";
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
@ -160,6 +158,9 @@ const DEFAULT_SERVICE_MAX_ERRORS = 10;
var gLocale = null;
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyGetter(this, "gLogEnabled", function aus_gLogEnabled() {
return getPref("getBoolPref", PREF_APP_UPDATE_LOG, false);
});
@ -873,44 +874,6 @@ function getLocale() {
return gLocale;
}
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other instances of the application that may use the same profile.
*/
function getUpdateChannel() {
// Preprocess the channel name that is defined when building to allow updating
// even when the preference file that defines the channel name doesn't exist.
var channel = "@MOZ_UPDATE_CHANNEL@";
var prefName;
var prefValue;
try {
channel = Services.prefs.getDefaultBranch(null).
getCharPref(PREF_APP_UPDATE_CHANNEL);
} catch (e) {
// Use the channel name from above that was preprocessed when building.
}
try {
var partners = Services.prefs.getChildList(PREF_PARTNER_BRANCH);
if (partners.length) {
channel += "-cck";
partners.sort();
for each (prefName in partners) {
prefValue = Services.prefs.getCharPref(prefName);
channel += "-" + prefValue;
}
}
}
catch (e) {
Components.utils.reportError(e);
}
return channel;
}
/* Get the distribution pref values, from defaults only */
function getDistributionPrefValue(aPrefName) {
var prefValue = "default";
@ -2450,7 +2413,7 @@ UpdateManager.prototype = {
*/
get activeUpdate() {
if (this._activeUpdate &&
this._activeUpdate.channel != getUpdateChannel()) {
this._activeUpdate.channel != UpdateChannel.get()) {
// User switched channels, clear out any old active updates and remove
// partial downloads
this._activeUpdate = null;
@ -2661,7 +2624,7 @@ Checker.prototype = {
url = url.replace(/%OS_VERSION%/g, gOSVersion);
if (/%LOCALE%/.test(url))
url = url.replace(/%LOCALE%/g, getLocale());
url = url.replace(/%CHANNEL%/g, getUpdateChannel());
url = url.replace(/%CHANNEL%/g, UpdateChannel.get());
url = url.replace(/%PLATFORM_VERSION%/g, Services.appinfo.platformVersion);
url = url.replace(/%DISTRIBUTION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION));
@ -2754,7 +2717,7 @@ Checker.prototype = {
continue;
}
update.serviceURL = this.getUpdateURL(this._forced);
update.channel = getUpdateChannel();
update.channel = UpdateChannel.get();
updates.push(update);
}