зеркало из https://github.com/mozilla/gecko-dev.git
Bug 538331 - On update perform action based upon the update metadata. r=dietrich, r=dtownsend, r=gavin, ui-r=beltzner
This commit is contained in:
Родитель
ff4d34e035
Коммит
472ef22f32
|
@ -85,6 +85,10 @@ ifdef MOZ_SAFE_BROWSING
|
|||
PARALLEL_DIRS += safebrowsing
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
|
||||
DIRS += build
|
||||
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Strong <robert.bugzilla@gmail.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
|
||||
|
@ -149,6 +150,40 @@ function needHomepageOverride(prefb) {
|
|||
return OVERRIDE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the override page for the first run after the application has been
|
||||
* updated.
|
||||
* @param defaultOverridePage
|
||||
* The default override page.
|
||||
* @return The override page.
|
||||
*/
|
||||
function getPostUpdateOverridePage(defaultOverridePage) {
|
||||
var um = Components.classes["@mozilla.org/updates/update-manager;1"]
|
||||
.getService(Components.interfaces.nsIUpdateManager);
|
||||
try {
|
||||
// If the updates.xml file is deleted then getUpdateAt will throw.
|
||||
var update = um.getUpdateAt(0)
|
||||
.QueryInterface(Components.interfaces.nsIPropertyBag);
|
||||
} catch (e) {
|
||||
// This should never happen.
|
||||
Components.utils.reportError("Unable to find update: " + e);
|
||||
return defaultOverridePage;
|
||||
}
|
||||
|
||||
let actions = update.getProperty("actions");
|
||||
// When the update doesn't specify actions fallback to the original behavior
|
||||
// of displaying the default override page.
|
||||
if (!actions)
|
||||
return defaultOverridePage;
|
||||
|
||||
// The existence of silent or the non-existence of showURL in the actions both
|
||||
// mean that an override page should not be displayed.
|
||||
if (actions.indexOf("silent") != -1 || actions.indexOf("showURL") == -1)
|
||||
return "";
|
||||
|
||||
return update.getProperty("openURL") || defaultOverridePage;
|
||||
}
|
||||
|
||||
// Copies a pref override file into the user's profile pref-override folder,
|
||||
// and then tells the pref service to reload its default prefs.
|
||||
function copyPrefOverride() {
|
||||
|
@ -536,8 +571,10 @@ var nsBrowserContentHandler = {
|
|||
.getService(Components.interfaces.nsISessionStartup);
|
||||
haveUpdateSession = ss.doRestore();
|
||||
overridePage = formatter.formatURLPref("startup.homepage_override_url");
|
||||
if (prefb.prefHasUserValue("app.update.postupdate"))
|
||||
overridePage = getPostUpdateOverridePage(overridePage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (ex) {}
|
||||
|
||||
// formatURLPref might return "about:blank" if getting the pref fails
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
# Dietrich Ayala <dietrich@mozilla.com>
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Nils Maier <maierman@web.de>
|
||||
# Robert Strong <robert.bugzilla@gmail.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
|
||||
|
@ -217,6 +218,13 @@ BrowserGlue.prototype = {
|
|||
if (topic == "bookmarks-restore-success" && data == "html-initial")
|
||||
this.ensurePlacesDefaultQueriesInitialized();
|
||||
break;
|
||||
case "browser-glue-test": // used by tests
|
||||
if (data == "post-update-notification") {
|
||||
if (this._prefs.prefHasUserValue("app.update.postupdate"))
|
||||
this._showUpdateNotification();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -339,6 +347,10 @@ BrowserGlue.prototype = {
|
|||
if (this._shouldShowRights())
|
||||
this._showRightsNotification();
|
||||
|
||||
// Show update notification, if needed.
|
||||
if (this._prefs.prefHasUserValue("app.update.postupdate"))
|
||||
this._showUpdateNotification();
|
||||
|
||||
// If new add-ons were installed during startup open the add-ons manager.
|
||||
if (this._prefs.prefHasUserValue(PREF_EM_NEW_ADDONS_LIST)) {
|
||||
var args = Cc["@mozilla.org/supports-array;1"].
|
||||
|
@ -576,7 +588,123 @@ BrowserGlue.prototype = {
|
|||
var box = notifyBox.appendNotification(notifyRightsText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
|
||||
box.persistence = 3; // arbitrary number, just so bar sticks around for a bit
|
||||
},
|
||||
|
||||
|
||||
_showUpdateNotification: function BG__showUpdateNotification() {
|
||||
this._prefs.clearUserPref("app.update.postupdate");
|
||||
|
||||
var um = Cc["@mozilla.org/updates/update-manager;1"].
|
||||
getService(Ci.nsIUpdateManager);
|
||||
try {
|
||||
// If the updates.xml file is deleted then getUpdateAt will throw.
|
||||
var update = um.getUpdateAt(0).QueryInterface(Ci.nsIPropertyBag);
|
||||
}
|
||||
catch (e) {
|
||||
// This should never happen.
|
||||
Cu.reportError("Unable to find update: " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
var actions = update.getProperty("actions");
|
||||
if (!actions || actions.indexOf("silent") != -1)
|
||||
return;
|
||||
|
||||
var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
|
||||
getService(Ci.nsIURLFormatter);
|
||||
var browserBundle = this._bundleService.
|
||||
createBundle("chrome://browser/locale/browser.properties");
|
||||
var brandBundle = this._bundleService.
|
||||
createBundle("chrome://branding/locale/brand.properties");
|
||||
var appName = brandBundle.GetStringFromName("brandShortName");
|
||||
|
||||
function getNotifyString(aPropData) {
|
||||
var propValue = update.getProperty(aPropData.propName);
|
||||
if (!propValue) {
|
||||
if (aPropData.prefName)
|
||||
propValue = formatter.formatURLPref(aPropData.prefName);
|
||||
else if (aPropData.stringParams)
|
||||
propValue = browserBundle.formatStringFromName(aPropData.stringName,
|
||||
aPropData.stringParams,
|
||||
aPropData.stringParams.length);
|
||||
else
|
||||
propValue = browserBundle.GetStringFromName(aPropData.stringName);
|
||||
}
|
||||
return propValue;
|
||||
}
|
||||
|
||||
if (actions.indexOf("showNotification") != -1) {
|
||||
let text = getNotifyString({propName: "notificationText",
|
||||
stringName: "puNotifyText",
|
||||
stringParams: [appName]});
|
||||
let url = getNotifyString({propName: "notificationURL",
|
||||
prefName: "startup.homepage_override_url"});
|
||||
let label = getNotifyString({propName: "notificationButtonLabel",
|
||||
stringName: "pu.notifyButton.label"});
|
||||
let key = getNotifyString({propName: "notificationButtonAccessKey",
|
||||
stringName: "pu.notifyButton.accesskey"});
|
||||
|
||||
let win = this.getMostRecentBrowserWindow();
|
||||
let browser = win.gBrowser; // for closure in notification bar callback
|
||||
let notifyBox = browser.getNotificationBox();
|
||||
|
||||
let buttons = [
|
||||
{
|
||||
label: label,
|
||||
accessKey: key,
|
||||
popup: null,
|
||||
callback: function(aNotificationBar, aButton) {
|
||||
browser.selectedTab = browser.addTab(url);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
let box = notifyBox.appendNotification(text, "post-update-notification",
|
||||
null, notifyBox.PRIORITY_INFO_LOW,
|
||||
buttons);
|
||||
box.persistence = 3;
|
||||
}
|
||||
|
||||
if (actions.indexOf("showAlert") == -1)
|
||||
return;
|
||||
|
||||
let notifier;
|
||||
try {
|
||||
notifier = Cc["@mozilla.org/alerts-service;1"].
|
||||
getService(Ci.nsIAlertsService);
|
||||
}
|
||||
catch (e) {
|
||||
// nsIAlertsService is not available for this platform
|
||||
return;
|
||||
}
|
||||
|
||||
let title = getNotifyString({propName: "alertTitle",
|
||||
stringName: "puAlertTitle",
|
||||
stringParams: [appName]});
|
||||
let text = getNotifyString({propName: "alertText",
|
||||
stringName: "puAlertText",
|
||||
stringParams: [appName]});
|
||||
let url = getNotifyString({propName: "alertURL",
|
||||
prefName: "startup.homepage_override_url"});
|
||||
|
||||
var self = this;
|
||||
function clickCallback(subject, topic, data) {
|
||||
// This callback will be called twice but only once with this topic
|
||||
if (topic != "alertclickcallback")
|
||||
return;
|
||||
let win = self.getMostRecentBrowserWindow();
|
||||
let browser = win.gBrowser;
|
||||
browser.selectedTab = browser.addTab(data);
|
||||
}
|
||||
|
||||
try {
|
||||
// This will throw NS_ERROR_NOT_AVAILABLE if the notification cannot
|
||||
// be displayed per the idl.
|
||||
notifier.showAlertNotification("post-update-notification", title, text,
|
||||
true, url, clickCallback);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
},
|
||||
|
||||
_showPluginUpdatePage: function BG__showPluginUpdatePage() {
|
||||
this._prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false);
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# ***** 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):
|
||||
# Robert Strong <robert.bugzilla@gmail.com> (Original Author)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of 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
|
||||
|
||||
DIRS = browser
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,52 @@
|
|||
# ***** 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):
|
||||
# Robert Strong <robert.bugzilla@gmail.com> (Original Author)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of 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@
|
||||
relativesrcdir = browser/components/test/browser
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_BROWSER_TEST_FILES = \
|
||||
browser_bug538331.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
|
@ -0,0 +1,373 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const PREF_POSTUPDATE = "app.update.postupdate";
|
||||
const PREF_MSTONE = "browser.startup.homepage_override.mstone";
|
||||
const PREF_OVERRIDE_URL = "startup.homepage_override_url";
|
||||
|
||||
const DEFAULT_PREF_URL = "http://pref.example.com/";
|
||||
const DEFAULT_UPDATE_URL = "http://example.com/";
|
||||
|
||||
const XML_EMPTY = "<?xml version=\"1.0\"?><updates xmlns=" +
|
||||
"\"http://www.mozilla.org/2005/app-update\"></updates>";
|
||||
|
||||
const XML_PREFIX = "<updates xmlns=\"http://www.mozilla.org/2005/app-update\"" +
|
||||
"><update appVersion=\"1.0\" buildID=\"20080811053724\" " +
|
||||
"channel=\"nightly\" displayVersion=\"Version 1.0\" " +
|
||||
"extensionVersion=\"1.0\" installDate=\"1238441400314\" " +
|
||||
"isCompleteUpdate=\"true\" name=\"Update Test 1.0\" " +
|
||||
"serviceURL=\"https://example.com/\" showNeverForVersion=" +
|
||||
"\"false\" showPrompt=\"false\" showSurvey=\"false\" type=" +
|
||||
"\"minor\" version=\"version 1.0\" detailsURL=" +
|
||||
"\"http://example.com/\" previousAppVersion=\"1.0\" " +
|
||||
"statusText=\"The Update was successfully installed\" " +
|
||||
"foregroundDownload=\"true\"";
|
||||
|
||||
const XML_SUFFIX = "><patch type=\"complete\" URL=\"http://example.com/\" " +
|
||||
"hashFunction=\"MD5\" hashValue=" +
|
||||
"\"6232cd43a1c77e30191c53a329a3f99d\" size=\"775\" " +
|
||||
"selected=\"true\" state=\"succeeded\"/></update></updates>";
|
||||
|
||||
// nsBrowserContentHandler.js defaultArgs tests
|
||||
const BCH_TESTS = [
|
||||
{
|
||||
description: "no mstone change and no update",
|
||||
noPostUpdatePref: true,
|
||||
noMstoneChange: true
|
||||
}, {
|
||||
description: "mstone changed and no update",
|
||||
noPostUpdatePref: true,
|
||||
prefURL: DEFAULT_PREF_URL
|
||||
}, {
|
||||
description: "no mstone change and update with 'showURL' for actions",
|
||||
actions: "showURL",
|
||||
noMstoneChange: true
|
||||
}, {
|
||||
description: "update without actions",
|
||||
prefURL: DEFAULT_PREF_URL
|
||||
}, {
|
||||
description: "update with 'showURL' for actions",
|
||||
actions: "showURL",
|
||||
prefURL: DEFAULT_PREF_URL
|
||||
}, {
|
||||
description: "update with 'showURL' for actions and openURL",
|
||||
actions: "showURL",
|
||||
openURL: DEFAULT_UPDATE_URL
|
||||
}, {
|
||||
description: "update with 'showURL showAlert' for actions",
|
||||
actions: "showAlert showURL",
|
||||
prefURL: DEFAULT_PREF_URL
|
||||
}, {
|
||||
description: "update with 'showAlert showURL' for actions and openURL",
|
||||
actions: "showAlert showURL",
|
||||
openURL: DEFAULT_UPDATE_URL
|
||||
}, {
|
||||
description: "update with 'showURL showNotification' for actions",
|
||||
actions: "showURL showNotification",
|
||||
prefURL: DEFAULT_PREF_URL
|
||||
}, {
|
||||
description: "update with 'showNotification showURL' for actions and " +
|
||||
"openURL",
|
||||
actions: "showNotification showURL",
|
||||
openURL: DEFAULT_UPDATE_URL
|
||||
}, {
|
||||
description: "update with 'showAlert showURL showNotification' for actions",
|
||||
actions: "showAlert showURL showNotification",
|
||||
prefURL: DEFAULT_PREF_URL
|
||||
}, {
|
||||
description: "update with 'showNotification showURL showAlert' for " +
|
||||
"actions and openURL",
|
||||
actions: "showNotification showURL showAlert",
|
||||
openURL: DEFAULT_UPDATE_URL
|
||||
}, {
|
||||
description: "update with 'showAlert' for actions",
|
||||
actions: "showAlert"
|
||||
}, {
|
||||
description: "update with 'showAlert showNotification' for actions",
|
||||
actions: "showAlert showNotification"
|
||||
}, {
|
||||
description: "update with 'showNotification' for actions",
|
||||
actions: "showNotification"
|
||||
}, {
|
||||
description: "update with 'showNotification showAlert' for actions",
|
||||
actions: "showNotification showAlert"
|
||||
}, {
|
||||
description: "update with 'silent' for actions",
|
||||
actions: "silent"
|
||||
}, {
|
||||
description: "update with 'silent showURL showAlert showNotification' " +
|
||||
"for actions and openURL",
|
||||
actions: "silent showURL showAlert showNotification"
|
||||
}
|
||||
];
|
||||
|
||||
var gOriginalMStone;
|
||||
var gOriginalOverrideURL;
|
||||
|
||||
__defineGetter__("gBG", function() {
|
||||
delete this.gBG;
|
||||
return this.gBG = Cc["@mozilla.org/browser/browserglue;1"].
|
||||
getService(Ci.nsIBrowserGlue).
|
||||
QueryInterface(Ci.nsIObserver);
|
||||
});
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
|
||||
gOriginalMStone = gPrefService.getCharPref(PREF_MSTONE);
|
||||
}
|
||||
|
||||
if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
|
||||
gOriginalOverrideURL = gPrefService.getCharPref(PREF_OVERRIDE_URL);
|
||||
}
|
||||
|
||||
testDefaultArgs();
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
// Reset browser.startup.homepage_override.mstone to the original value or
|
||||
// clear it if it didn't exist.
|
||||
if (gOriginalMStone) {
|
||||
gPrefService.setCharPref(PREF_MSTONE, gOriginalMStone);
|
||||
} else if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
|
||||
gPrefService.clearUserPref(PREF_MSTONE);
|
||||
}
|
||||
|
||||
// Reset startup.homepage_override_url to the original value or clear it if
|
||||
// it didn't exist.
|
||||
if (gOriginalOverrideURL) {
|
||||
gPrefService.setCharPref(PREF_OVERRIDE_URL, gOriginalOverrideURL);
|
||||
} else if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
|
||||
gPrefService.clearUserPref(PREF_OVERRIDE_URL);
|
||||
}
|
||||
|
||||
writeUpdatesToXMLFile(XML_EMPTY);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
// Test the defaultArgs returned by nsBrowserContentHandler after an update
|
||||
function testDefaultArgs()
|
||||
{
|
||||
// Clear any pre-existing override in defaultArgs that are hanging around.
|
||||
// This will also set the browser.startup.homepage_override.mstone preference
|
||||
// if it isn't already set.
|
||||
Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
|
||||
|
||||
let originalMstone = gPrefService.getCharPref(PREF_MSTONE);
|
||||
|
||||
gPrefService.setCharPref(PREF_OVERRIDE_URL, DEFAULT_PREF_URL);
|
||||
|
||||
writeUpdatesToXMLFile(XML_EMPTY);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
for (let i = 0; i < BCH_TESTS.length; i++) {
|
||||
let test = BCH_TESTS[i];
|
||||
ok(true, "Test nsBrowserContentHandler " + (i + 1) + ": " + test.description);
|
||||
|
||||
if (test.actions) {
|
||||
let actionsXML = " actions=\"" + test.actions + "\"";
|
||||
if (test.openURL) {
|
||||
actionsXML += " openURL=\"" + test.openURL + "\"";
|
||||
}
|
||||
writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
|
||||
} else {
|
||||
writeUpdatesToXMLFile(XML_EMPTY);
|
||||
}
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
let noOverrideArgs = Cc["@mozilla.org/browser/clh;1"].
|
||||
getService(Ci.nsIBrowserHandler).defaultArgs;
|
||||
|
||||
let overrideArgs = "";
|
||||
if (test.prefURL) {
|
||||
overrideArgs = test.prefURL;
|
||||
} else if (test.openURL) {
|
||||
overrideArgs = test.openURL;
|
||||
}
|
||||
|
||||
if (overrideArgs == "" && noOverrideArgs) {
|
||||
overrideArgs = noOverrideArgs;
|
||||
} else if (noOverrideArgs) {
|
||||
overrideArgs += "|" + noOverrideArgs;
|
||||
}
|
||||
|
||||
if (test.noMstoneChange === undefined) {
|
||||
gPrefService.setCharPref(PREF_MSTONE, "PreviousMilestone");
|
||||
}
|
||||
|
||||
if (test.noPostUpdatePref == undefined) {
|
||||
gPrefService.setBoolPref(PREF_POSTUPDATE, true);
|
||||
}
|
||||
|
||||
let defaultArgs = Cc["@mozilla.org/browser/clh;1"].
|
||||
getService(Ci.nsIBrowserHandler).defaultArgs;
|
||||
is(defaultArgs, overrideArgs, "correct value returned by defaultArgs");
|
||||
|
||||
if (test.noMstoneChange === undefined || test.noMstoneChange != true) {
|
||||
let newMstone = gPrefService.getCharPref(PREF_MSTONE);
|
||||
is(originalMstone, newMstone, "preference " + PREF_MSTONE +
|
||||
" should have been updated");
|
||||
}
|
||||
|
||||
if (gPrefService.prefHasUserValue(PREF_POSTUPDATE)) {
|
||||
gPrefService.clearUserPref(PREF_POSTUPDATE);
|
||||
}
|
||||
}
|
||||
|
||||
testShowNotification();
|
||||
}
|
||||
|
||||
// nsBrowserGlue.js _showUpdateNotification notification tests
|
||||
const BG_NOTIFY_TESTS = [
|
||||
{
|
||||
description: "'silent showNotification' actions should not display a notification",
|
||||
actions: "silent showNotification"
|
||||
}, {
|
||||
description: "'showNotification' for actions should display a notification",
|
||||
actions: "showNotification"
|
||||
}, {
|
||||
description: "no actions and empty updates.xml",
|
||||
}, {
|
||||
description: "'showAlert' for actions should not display a notification",
|
||||
actions: "showAlert"
|
||||
}, {
|
||||
// This test MUST be the last test in the array to test opening the url
|
||||
// provided by the updates.xml.
|
||||
description: "'showNotification' for actions with custom notification " +
|
||||
"attributes should display a notification",
|
||||
actions: "showNotification",
|
||||
notificationText: "notification text",
|
||||
notificationURL: DEFAULT_UPDATE_URL,
|
||||
notificationButtonLabel: "button label",
|
||||
notificationButtonAccessKey: "b"
|
||||
}
|
||||
];
|
||||
|
||||
// Test showing a notification after an update
|
||||
// _showUpdateNotification in nsBrowserGlue.js
|
||||
function testShowNotification()
|
||||
{
|
||||
let gTestBrowser = gBrowser.selectedBrowser;
|
||||
let notifyBox = gBrowser.getNotificationBox(gTestBrowser);
|
||||
|
||||
for (let i = 0; i < BG_NOTIFY_TESTS.length; i++) {
|
||||
let test = BG_NOTIFY_TESTS[i];
|
||||
ok(true, "Test showNotification " + (i + 1) + ": " + test.description);
|
||||
|
||||
if (test.actions) {
|
||||
let actionsXML = " actions=\"" + test.actions + "\"";
|
||||
if (test.notificationText) {
|
||||
actionsXML += " notificationText=\"" + test.notificationText + "\"";
|
||||
}
|
||||
if (test.notificationURL) {
|
||||
actionsXML += " notificationURL=\"" + test.notificationURL + "\"";
|
||||
}
|
||||
if (test.notificationButtonLabel) {
|
||||
actionsXML += " notificationButtonLabel=\"" + test.notificationButtonLabel + "\"";
|
||||
}
|
||||
if (test.notificationButtonAccessKey) {
|
||||
actionsXML += " notificationButtonAccessKey=\"" + test.notificationButtonAccessKey + "\"";
|
||||
}
|
||||
writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
|
||||
} else {
|
||||
writeUpdatesToXMLFile(XML_EMPTY);
|
||||
}
|
||||
|
||||
reloadUpdateManagerData();
|
||||
gPrefService.setBoolPref(PREF_POSTUPDATE, true);
|
||||
|
||||
gBG.observe(null, "browser-glue-test", "post-update-notification");
|
||||
|
||||
let updateBox = notifyBox.getNotificationWithValue("post-update-notification");
|
||||
if (test.actions && test.actions.indexOf("showNotification") != -1 &&
|
||||
test.actions.indexOf("silent") == -1) {
|
||||
ok(updateBox, "Update notification box should have been displayed");
|
||||
if (updateBox) {
|
||||
if (test.notificationText) {
|
||||
is(updateBox.label, test.notificationText, "Update notification box " +
|
||||
"should have the label provided by the update");
|
||||
}
|
||||
if (test.notificationButtonLabel) {
|
||||
var button = updateBox.getElementsByTagName("button").item(0);
|
||||
is(button.label, test.notificationButtonLabel, "Update notification " +
|
||||
"box button should have the label provided by the update");
|
||||
if (test.notificationButtonAccessKey) {
|
||||
let accessKey = button.getAttribute("accesskey");
|
||||
is(accessKey, test.notificationButtonAccessKey, "Update " +
|
||||
"notification box button should have the accesskey " +
|
||||
"provided by the update");
|
||||
}
|
||||
}
|
||||
// The last test opens an url and verifies the url from the updates.xml
|
||||
// is correct.
|
||||
if (i == (BG_NOTIFY_TESTS.length - 1)) {
|
||||
button.click();
|
||||
gBrowser.selectedBrowser.addEventListener("load", testNotificationURL, true);
|
||||
}
|
||||
} else if (i == (BG_NOTIFY_TESTS.length - 1)) {
|
||||
// If updateBox is null the test has already reported errors so bail
|
||||
finish_test();
|
||||
}
|
||||
notifyBox.removeAllNotifications(true);
|
||||
} else {
|
||||
ok(!updateBox, "Update notification box should not have been displayed");
|
||||
}
|
||||
|
||||
let prefHasUserValue = gPrefService.prefHasUserValue(PREF_POSTUPDATE);
|
||||
is(prefHasUserValue, false, "preference " + PREF_POSTUPDATE +
|
||||
" shouldn't have a user value");
|
||||
}
|
||||
}
|
||||
|
||||
// Test opening the url provided by the updates.xml in the last test
|
||||
function testNotificationURL()
|
||||
{
|
||||
ok(true, "Test testNotificationURL: clicking the notification button " +
|
||||
"opened the url specified by the update");
|
||||
let href = gBrowser.selectedBrowser.contentWindow.location.href;
|
||||
let expectedURL = BG_NOTIFY_TESTS[BG_NOTIFY_TESTS.length - 1].notificationURL;
|
||||
is(href, expectedURL, "The url opened from the notification should be the " +
|
||||
"url provided by the update");
|
||||
gBrowser.removeCurrentTab();
|
||||
window.focus();
|
||||
finish_test();
|
||||
}
|
||||
|
||||
/* Reloads the update metadata from disk */
|
||||
function reloadUpdateManagerData()
|
||||
{
|
||||
Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager).
|
||||
QueryInterface(Ci.nsIObserver).observe(null, "um-reload-update-data", "");
|
||||
}
|
||||
|
||||
|
||||
function writeUpdatesToXMLFile(aText)
|
||||
{
|
||||
const PERMS_FILE = 0644;
|
||||
|
||||
const MODE_WRONLY = 0x02;
|
||||
const MODE_CREATE = 0x08;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("XCurProcD", Ci.nsIFile);
|
||||
file.append("updates.xml");
|
||||
let fos = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
if (!file.exists()) {
|
||||
file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
}
|
||||
fos.init(file, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, PERMS_FILE, 0);
|
||||
fos.write(aText, aText.length);
|
||||
fos.close();
|
||||
}
|
|
@ -191,6 +191,14 @@ editBookmarkPanel.editBookmarkTitle=Edit This Bookmark
|
|||
# instead of "Remove #1 Bookmarks".
|
||||
editBookmark.removeBookmarks.label=Remove Bookmark;Remove #1 Bookmarks
|
||||
|
||||
# Post Update Notifications
|
||||
pu.notifyButton.label=Details…
|
||||
pu.notifyButton.accesskey=D
|
||||
# LOCALIZATION NOTE %S will be replaced by the short name of the application.
|
||||
puNotifyText=%S has been updated
|
||||
puAlertTitle=%S Updated
|
||||
puAlertText=Click here for details
|
||||
|
||||
# Geolocation UI
|
||||
|
||||
# LOCALIZATION NOTE (geolocation.shareLocation geolocation.dontShareLocation):
|
||||
|
|
Загрузка…
Ссылка в новой задаче