mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central and fx-team
This commit is contained in:
commit
f823f7f1ee
@ -858,15 +858,6 @@
|
||||
<richlistbox id="menupopup-commands" onclick="if (event.target != this) AutofillMenuUI.selectByIndex(this.selectedIndex);" flex="1"/>
|
||||
</vbox>
|
||||
</box>
|
||||
|
||||
<!-- alerts for content -->
|
||||
<hbox id="alerts-container" hidden="true" align="start" bottom="0" onclick="AlertsHelper.click(event);">
|
||||
<image id="alerts-image"/>
|
||||
<vbox flex="1">
|
||||
<label id="alerts-title" value=""/>
|
||||
<description id="alerts-text" flex="1"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</stack>
|
||||
|
||||
</window>
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const URI_GENERIC_ICON_DOWNLOAD = "chrome://browser/skin/images/alert-downloads-30.png";
|
||||
const TOAST_URI_GENERIC_ICON_DOWNLOAD = "ms-appx:///metro/chrome/chrome/skin/images/alert-downloads-30.png"
|
||||
|
||||
var Downloads = {
|
||||
/**
|
||||
@ -154,26 +155,17 @@ var Downloads = {
|
||||
BrowserUI.newTab(uri, Browser.selectedTab);
|
||||
},
|
||||
|
||||
showAlert: function dh_showAlert(aName, aMessage, aTitle, aIcon) {
|
||||
showAlert: function dh_showAlert(aName, aMessage, aTitle, aIcon, aObserver) {
|
||||
var notifier = Cc["@mozilla.org/alerts-service;1"]
|
||||
.getService(Ci.nsIAlertsService);
|
||||
|
||||
// Callback for tapping on the alert popup
|
||||
let observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
if (aTopic == "alertclickcallback") {
|
||||
// TODO: Bug 783232 turns this alert into a native toast.
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!aTitle)
|
||||
aTitle = Strings.browser.GetStringFromName("alertDownloads");
|
||||
|
||||
if (!aIcon)
|
||||
aIcon = URI_GENERIC_ICON_DOWNLOAD;
|
||||
aIcon = TOAST_URI_GENERIC_ICON_DOWNLOAD;
|
||||
|
||||
notifier.showAlertNotification(aIcon, aTitle, aMessage, true, "", observer, aName);
|
||||
notifier.showAlertNotification(aIcon, aTitle, aMessage, true, "", aObserver, aName);
|
||||
},
|
||||
|
||||
showNotification: function dh_showNotification(title, msg, buttons, priority) {
|
||||
@ -257,6 +249,53 @@ var Downloads = {
|
||||
this._notificationBox.PRIORITY_WARNING_MEDIUM);
|
||||
},
|
||||
|
||||
_showDownloadCompleteToast: function (aDownload) {
|
||||
let name = "DownloadComplete";
|
||||
let msg = "";
|
||||
let title = "";
|
||||
let observer = null;
|
||||
if (this._downloadCount > 1) {
|
||||
title = PluralForm.get(this._downloadCount,
|
||||
Strings.browser.GetStringFromName("alertMultipleDownloadsComplete"))
|
||||
.replace("#1", this._downloadCount)
|
||||
msg = PluralForm.get(2, Strings.browser.GetStringFromName("downloadShowInFiles"));
|
||||
|
||||
observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "alertclickcallback":
|
||||
let fileURI = aDownload.target;
|
||||
let file = Downloads._getLocalFile(fileURI);
|
||||
file.reveal();
|
||||
|
||||
let downloadCompleteNotification =
|
||||
Downloads._notificationBox.getNotificationWithValue("download-complete");
|
||||
Downloads._notificationBox.removeNotification(downloadCompleteNotification);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
title = Strings.browser.formatStringFromName("alertDownloadsDone",
|
||||
[aDownload.displayName], 1);
|
||||
msg = Strings.browser.GetStringFromName("downloadRunNow");
|
||||
observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "alertclickcallback":
|
||||
Downloads.openDownload(aDownload);
|
||||
|
||||
let downloadCompleteNotification =
|
||||
Downloads._notificationBox.getNotificationWithValue("download-complete");
|
||||
Downloads._notificationBox.removeNotification(downloadCompleteNotification);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.showAlert(name, msg, title, null, observer);
|
||||
},
|
||||
|
||||
_updateCircularProgressMeter: function dv_updateCircularProgressMeter() {
|
||||
if (!this._progressNotificationInfo) {
|
||||
return;
|
||||
@ -391,6 +430,7 @@ var Downloads = {
|
||||
this._runDownloadBooleanMap.delete(download.targetFile.path);
|
||||
if (this._downloadsInProgress == 0) {
|
||||
if (this._downloadCount > 1 || !runAfterDownload) {
|
||||
this._showDownloadCompleteToast(download);
|
||||
this._showDownloadCompleteNotification(download);
|
||||
}
|
||||
this._progressNotificationInfo.clear();
|
||||
|
@ -3,80 +3,23 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var AlertsHelper = {
|
||||
_timeoutID: -1,
|
||||
_listener: null,
|
||||
_cookie: "",
|
||||
_clickable: false,
|
||||
get container() {
|
||||
delete this.container;
|
||||
let container = document.getElementById("alerts-container");
|
||||
|
||||
let self = this;
|
||||
container.addEventListener("transitionend", function() {
|
||||
self.alertTransitionOver();
|
||||
}, true);
|
||||
|
||||
return this.container = container;
|
||||
},
|
||||
|
||||
showAlertNotification: function ah_show(aImageURL, aTitle, aText, aTextClickable, aCookie, aListener) {
|
||||
this._clickable = aTextClickable || false;
|
||||
this._listener = aListener || null;
|
||||
this._cookie = aCookie || "";
|
||||
Services.obs.addObserver(this, "metro_native_toast_clicked", false);
|
||||
this._listener = aListener;
|
||||
this._cookie = aCookie;
|
||||
|
||||
// Reset the container settings from the last time so layout can happen naturally
|
||||
let container = this.container;
|
||||
container.removeAttribute("width");
|
||||
let alertText = document.getElementById("alerts-text");
|
||||
alertText.style.whiteSpace = "";
|
||||
|
||||
document.getElementById("alerts-image").setAttribute("src", aImageURL);
|
||||
document.getElementById("alerts-title").value = aTitle;
|
||||
alertText.textContent = aText;
|
||||
|
||||
container.hidden = false;
|
||||
let bcr = container.getBoundingClientRect();
|
||||
if (bcr.width > window.innerWidth - 50) {
|
||||
// If the window isn't wide enough, we need to re-layout
|
||||
container.setAttribute("width", window.innerWidth - 50); // force a max width
|
||||
alertText.style.whiteSpace = "pre-wrap"; // wrap text as needed
|
||||
bcr = container.getBoundingClientRect(); // recalculate the bcr
|
||||
}
|
||||
container.setAttribute("width", bcr.width); // redundant but cheap
|
||||
container.setAttribute("height", bcr.height);
|
||||
|
||||
container.classList.add("showing");
|
||||
|
||||
let timeout = Services.prefs.getIntPref("alerts.totalOpenTime");
|
||||
let self = this;
|
||||
if (this._timeoutID)
|
||||
clearTimeout(this._timeoutID);
|
||||
this._timeoutID = setTimeout(function() { self._timeoutAlert(); }, timeout);
|
||||
MetroUtils.showNativeToast(aTitle, aText, aImageURL);
|
||||
},
|
||||
|
||||
_timeoutAlert: function ah__timeoutAlert() {
|
||||
this._timeoutID = -1;
|
||||
|
||||
this.container.classList.remove("showing");
|
||||
if (this._listener)
|
||||
this._listener.observe(null, "alertfinished", this._cookie);
|
||||
},
|
||||
|
||||
alertTransitionOver: function ah_alertTransitionOver() {
|
||||
let container = this.container;
|
||||
if (!container.classList.contains("showing")) {
|
||||
container.height = 0;
|
||||
container.hidden = true;
|
||||
}
|
||||
},
|
||||
|
||||
click: function ah_click(aEvent) {
|
||||
if (this._clickable && this._listener)
|
||||
this._listener.observe(null, "alertclickcallback", this._cookie);
|
||||
|
||||
if (this._timeoutID != -1) {
|
||||
clearTimeout(this._timeoutID);
|
||||
this._timeoutAlert();
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "metro_native_toast_clicked":
|
||||
Services.obs.removeObserver(this, "metro_native_toast_clicked");
|
||||
this._listener.observe(null, "alertclickcallback", this._cookie);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -20,7 +20,28 @@ AlertsService.prototype = {
|
||||
|
||||
showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener, aName) {
|
||||
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
browser.AlertsHelper.showAlertNotification(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener);
|
||||
try {
|
||||
browser.AlertsHelper.showAlertNotification(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener);
|
||||
} catch (ex) {
|
||||
let chromeWin = this._getChromeWindow(browser).wrappedJSObject;
|
||||
let notificationBox = chromeWin.Browser.getNotificationBox();
|
||||
notificationBox.appendNotification(aTitle,
|
||||
aText,
|
||||
aImageUrl,
|
||||
notificationBox.PRIORITY_WARNING_MEDIUM,
|
||||
null);
|
||||
}
|
||||
},
|
||||
|
||||
_getChromeWindow: function (aWindow) {
|
||||
let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow)
|
||||
.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
return chromeWin;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -61,6 +61,7 @@ downloadRun=Run
|
||||
downloadSave=Save
|
||||
downloadCancel=Cancel
|
||||
downloadTryAgain=Try Again
|
||||
downloadRunNow=Run it now
|
||||
# LOCALIZATION NOTE (downloadShowInFiles): 'Files' refers to the Windows 8 file explorer
|
||||
downloadShowInFiles=Show in Files
|
||||
|
||||
|
@ -1245,37 +1245,4 @@ setting[type="radio"] > vbox {
|
||||
|
||||
#clear-notification-done {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Alert Popup ============================================================= */
|
||||
|
||||
#alerts-container {
|
||||
color: white;
|
||||
background-color: #5e6166;
|
||||
border: @border_width_small@ solid #767973;
|
||||
border-radius: @border_radius_normal@;
|
||||
box-shadow: black 0 @border_radius_tiny@ @border_radius_tiny@;
|
||||
padding: @padding_normal@; /* core spacing on top/bottom */
|
||||
margin-bottom: @margin_large@;
|
||||
transition-property: opacity;
|
||||
transition-duration: 0.5s;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#alerts-container.showing {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#alerts-title {
|
||||
font-size: @font_small@ !important;
|
||||
}
|
||||
|
||||
#alerts-text {
|
||||
font-size: @font_xsmall@ !important;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#alerts-container {
|
||||
-moz-margin-end: @margin_large@;
|
||||
}
|
||||
|
||||
}
|
@ -12,6 +12,6 @@
|
||||
android:title="@string/pref_developer_remotedebugging" />
|
||||
|
||||
<org.mozilla.gecko.AlignRightLinkPreference android:title="@string/pref_developer_remotedebugging_docs"
|
||||
url="https://developer.mozilla.org/docs/Tools/Debugger#Remote_debugging?" />
|
||||
url="https://developer.mozilla.org/docs/Tools/Remote_Debugging" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@ -4879,7 +4879,7 @@ var ErrorPageEventHandler = {
|
||||
let isMalware = errorDoc.documentURI.contains("e=malwareBlocked");
|
||||
let bucketName = isMalware ? "WARNING_MALWARE_PAGE_" : "WARNING_PHISHING_PAGE_";
|
||||
let nsISecTel = Ci.nsISecurityUITelemetry;
|
||||
let isIframe = (aOwnerDoc.defaultView.parent === aOwnerDoc.defaultView);
|
||||
let isIframe = (errorDoc.defaultView.parent === errorDoc.defaultView);
|
||||
bucketName += isIframe ? "TOP_" : "FRAME_";
|
||||
|
||||
let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
|
||||
|
@ -424,8 +424,10 @@ interface nsIApplicationUpdateService : nsISupports
|
||||
|
||||
/**
|
||||
* Whether or not the Update Service can download and install updates.
|
||||
* This is a function of whether or not the current user has access
|
||||
* privileges to the install directory.
|
||||
* On Windows, this is a function of whether or not the maintenance service
|
||||
* is installed and enabled. On other systems, and as a fallback on Windows,
|
||||
* this depends on whether the current user has write access to the install
|
||||
* directory.
|
||||
*/
|
||||
readonly attribute boolean canApplyUpdates;
|
||||
|
||||
|
@ -572,52 +572,61 @@ XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpda
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var updateTestFile = getUpdateFile([FILE_PERMS_TEST]);
|
||||
LOG("gCanApplyUpdates - testing write access " + updateTestFile.path);
|
||||
testWriteAccess(updateTestFile, false);
|
||||
let useService = false;
|
||||
if (shouldUseService() && isServiceInstalled()) {
|
||||
// No need to perform directory write checks, the maintenance service will
|
||||
// be able to write to all directories.
|
||||
LOG("gCanApplyUpdates - bypass the write checks because we'll use the service");
|
||||
useService = true;
|
||||
}
|
||||
|
||||
if (!useService) {
|
||||
try {
|
||||
var updateTestFile = getUpdateFile([FILE_PERMS_TEST]);
|
||||
LOG("gCanApplyUpdates - testing write access " + updateTestFile.path);
|
||||
testWriteAccess(updateTestFile, false);
|
||||
#ifdef XP_WIN
|
||||
var sysInfo = Cc["@mozilla.org/system-info;1"].
|
||||
getService(Ci.nsIPropertyBag2);
|
||||
var sysInfo = Cc["@mozilla.org/system-info;1"].
|
||||
getService(Ci.nsIPropertyBag2);
|
||||
|
||||
// Example windowsVersion: Windows XP == 5.1
|
||||
var windowsVersion = sysInfo.getProperty("version");
|
||||
LOG("gCanApplyUpdates - windowsVersion = " + windowsVersion);
|
||||
|
||||
/**
|
||||
# For Vista, updates can be performed to a location requiring admin
|
||||
# privileges by requesting elevation via the UAC prompt when launching
|
||||
# updater.exe if the appDir is under the Program Files directory
|
||||
# (e.g. C:\Program Files\) and UAC is turned on and we can elevate
|
||||
# (e.g. user has a split token).
|
||||
#
|
||||
# Note: this does note attempt to handle the case where UAC is turned on
|
||||
# and the installation directory is in a restricted location that
|
||||
# requires admin privileges to update other than Program Files.
|
||||
*/
|
||||
var userCanElevate = false;
|
||||
|
||||
if (parseFloat(windowsVersion) >= 6) {
|
||||
try {
|
||||
var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
// KEY_UPDROOT will fail and throw an exception if
|
||||
// appDir is not under the Program Files, so we rely on that
|
||||
var dir = fileLocator.get(KEY_UPDROOT, Ci.nsIFile);
|
||||
// appDir is under Program Files, so check if the user can elevate
|
||||
userCanElevate = Services.appinfo.QueryInterface(Ci.nsIWinAppHelper).
|
||||
userCanElevate;
|
||||
LOG("gCanApplyUpdates - on Vista, userCanElevate: " + userCanElevate);
|
||||
}
|
||||
catch (ex) {
|
||||
// When the installation directory is not under Program Files,
|
||||
// fall through to checking if write access to the
|
||||
// installation directory is available.
|
||||
LOG("gCanApplyUpdates - on Vista, appDir is not under Program Files");
|
||||
}
|
||||
}
|
||||
// Example windowsVersion: Windows XP == 5.1
|
||||
var windowsVersion = sysInfo.getProperty("version");
|
||||
LOG("gCanApplyUpdates - windowsVersion = " + windowsVersion);
|
||||
|
||||
/**
|
||||
# For Vista, updates can be performed to a location requiring admin
|
||||
# privileges by requesting elevation via the UAC prompt when launching
|
||||
# updater.exe if the appDir is under the Program Files directory
|
||||
# (e.g. C:\Program Files\) and UAC is turned on and we can elevate
|
||||
# (e.g. user has a split token).
|
||||
#
|
||||
# Note: this does note attempt to handle the case where UAC is turned on
|
||||
# and the installation directory is in a restricted location that
|
||||
# requires admin privileges to update other than Program Files.
|
||||
*/
|
||||
var userCanElevate = false;
|
||||
|
||||
if (parseFloat(windowsVersion) >= 6) {
|
||||
try {
|
||||
var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
// KEY_UPDROOT will fail and throw an exception if
|
||||
// appDir is not under the Program Files, so we rely on that
|
||||
var dir = fileLocator.get(KEY_UPDROOT, Ci.nsIFile);
|
||||
// appDir is under Program Files, so check if the user can elevate
|
||||
userCanElevate = Services.appinfo.QueryInterface(Ci.nsIWinAppHelper).
|
||||
userCanElevate;
|
||||
LOG("gCanApplyUpdates - on Vista, userCanElevate: " + userCanElevate);
|
||||
}
|
||||
catch (ex) {
|
||||
// When the installation directory is not under Program Files,
|
||||
// fall through to checking if write access to the
|
||||
// installation directory is available.
|
||||
LOG("gCanApplyUpdates - on Vista, appDir is not under Program Files");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
# On Windows, we no longer store the update under the app dir.
|
||||
#
|
||||
# If we are on Windows (including Vista, if we can't elevate) we need to
|
||||
@ -636,25 +645,26 @@ XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpda
|
||||
# (e.g. the user does not have a split token)
|
||||
# 4) UAC is turned on and the user is already elevated, so they can't be
|
||||
# elevated again
|
||||
*/
|
||||
if (!userCanElevate) {
|
||||
// if we're unable to create the test file this will throw an exception.
|
||||
var appDirTestFile = getAppBaseDir();
|
||||
appDirTestFile.append(FILE_PERMS_TEST);
|
||||
LOG("gCanApplyUpdates - testing write access " + appDirTestFile.path);
|
||||
if (appDirTestFile.exists())
|
||||
appDirTestFile.remove(false)
|
||||
appDirTestFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
|
||||
appDirTestFile.remove(false);
|
||||
}
|
||||
*/
|
||||
if (!userCanElevate) {
|
||||
// if we're unable to create the test file this will throw an exception.
|
||||
var appDirTestFile = getAppBaseDir();
|
||||
appDirTestFile.append(FILE_PERMS_TEST);
|
||||
LOG("gCanApplyUpdates - testing write access " + appDirTestFile.path);
|
||||
if (appDirTestFile.exists())
|
||||
appDirTestFile.remove(false)
|
||||
appDirTestFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
|
||||
appDirTestFile.remove(false);
|
||||
}
|
||||
#endif //XP_WIN
|
||||
}
|
||||
catch (e) {
|
||||
LOG("gCanApplyUpdates - unable to apply updates. Exception: " + e);
|
||||
// No write privileges to install directory
|
||||
submitHasPermissionsTelemetryPing(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
LOG("gCanApplyUpdates - unable to apply updates. Exception: " + e);
|
||||
// No write privileges to install directory
|
||||
submitHasPermissionsTelemetryPing(false);
|
||||
return false;
|
||||
}
|
||||
} // if (!useService)
|
||||
|
||||
if (!hasUpdateMutex()) {
|
||||
LOG("gCanApplyUpdates - unable to apply updates because another instance" +
|
||||
@ -1116,6 +1126,33 @@ function shouldUseService() {
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the service is is installed and enabled or not.
|
||||
*
|
||||
* @return true if the service should be used for updates,
|
||||
* is installed and enabled.
|
||||
*/
|
||||
function isServiceInstalled() {
|
||||
#ifdef XP_WIN
|
||||
let installed = 0;
|
||||
try {
|
||||
let wrk = Cc["@mozilla.org/windows-registry-key;1"].
|
||||
createInstance(Ci.nsIWindowsRegKey);
|
||||
wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\Mozilla\\MaintenanceService",
|
||||
wrk.ACCESS_READ | wrk.WOW64_64);
|
||||
installed = wrk.readIntValue("Installed");
|
||||
wrk.close();
|
||||
} catch(e) {
|
||||
}
|
||||
installed = installed == 1; // convert to bool
|
||||
LOG("isServiceInstalled = " + installed);
|
||||
return installed;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
# Writes the update's application version to a file in the patch directory. If
|
||||
# the update doesn't provide application version information via the
|
||||
@ -2243,7 +2280,7 @@ UpdateService.prototype = {
|
||||
* service was at some point installed, but is now uninstalled.
|
||||
*/
|
||||
_sendServiceInstalledTelemetryPing: function AUS__svcInstallTelemetryPing() {
|
||||
let installed = 0;
|
||||
let installed = isServiceInstalled(); // Is the service installed?
|
||||
let attempted = 0;
|
||||
try {
|
||||
let wrk = Cc["@mozilla.org/windows-registry-key;1"].
|
||||
@ -2251,14 +2288,14 @@ UpdateService.prototype = {
|
||||
wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\Mozilla\\MaintenanceService",
|
||||
wrk.ACCESS_READ | wrk.WOW64_64);
|
||||
// Was the service at some point installed, but is now uninstalled?
|
||||
attempted = wrk.readIntValue("Attempted");
|
||||
installed = wrk.readIntValue("Installed");
|
||||
wrk.close();
|
||||
} catch(e) {
|
||||
}
|
||||
try {
|
||||
let h = Services.telemetry.getHistogramById("UPDATER_SERVICE_INSTALLED");
|
||||
h.add(installed);
|
||||
h.add(Number(installed));
|
||||
} catch(e) {
|
||||
// Don't allow any exception to be propagated.
|
||||
Cu.reportError(e);
|
||||
@ -4270,7 +4307,7 @@ Downloader.prototype = {
|
||||
"max fail: " + maxFail + ", " + "retryTimeout: " + retryTimeout);
|
||||
if (Components.isSuccessCode(status)) {
|
||||
if (this._verifyDownload()) {
|
||||
state = shouldUseService() ? STATE_PENDING_SVC : STATE_PENDING
|
||||
state = shouldUseService() ? STATE_PENDING_SVC : STATE_PENDING;
|
||||
if (this.background) {
|
||||
shouldShowPrompt = !getCanStageUpdates();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
* implementation of this interface for non-Windows systems, for testing and
|
||||
* development purposes only.
|
||||
*/
|
||||
[scriptable, uuid(ac813696-3b0a-4259-bce1-1d078021ebbe)]
|
||||
[scriptable, uuid(c5a654c8-2443-47ce-9322-d150af3ca526)]
|
||||
interface nsIWinMetroUtils : nsISupports
|
||||
{
|
||||
/* Fullscreen landscape orientation */
|
||||
@ -66,6 +66,11 @@ interface nsIWinMetroUtils : nsISupports
|
||||
*/
|
||||
void launchInDesktop(in AString aPath, in AString aArguments);
|
||||
|
||||
/**
|
||||
* Displays a native Windows 8 toast.
|
||||
*/
|
||||
void showNativeToast(in AString aTitle, in AString aMessage, in AString anImage);
|
||||
|
||||
/**
|
||||
* Secondary tiles are a Windows 8 specific feature for pinning new tiles
|
||||
* to the start screen. Tiles can later be activated whether the browser is
|
||||
|
78
widget/windows/winrt/ToastNotificationHandler.cpp
Normal file
78
widget/windows/winrt/ToastNotificationHandler.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "ToastNotificationHandler.h"
|
||||
#include "MetroUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "FrameworkView.h"
|
||||
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::Data::Xml::Dom;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
using namespace mozilla;
|
||||
using namespace ABI::Windows::UI::Notifications;
|
||||
|
||||
typedef __FITypedEventHandler_2_Windows__CUI__CNotifications__CToastNotification_IInspectable_t ToastActivationHandler;
|
||||
|
||||
void ToastNotificationHandler::DisplayNotification(HSTRING title, HSTRING msg, HSTRING imagePath) {
|
||||
ComPtr<IToastNotificationManagerStatics> toastNotificationManagerStatics;
|
||||
AssertHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(),
|
||||
toastNotificationManagerStatics.GetAddressOf()));
|
||||
|
||||
ComPtr<IXmlDocument> toastXml;
|
||||
toastNotificationManagerStatics->GetTemplateContent(ToastTemplateType::ToastTemplateType_ToastImageAndText03, &toastXml);
|
||||
|
||||
ComPtr<IXmlNodeList> toastTextElements, toastImageElements;
|
||||
ComPtr<IXmlNode> titleTextNodeRoot, msgTextNodeRoot, imageNodeRoot, srcAttribute;
|
||||
|
||||
HSTRING textNodeStr, imageNodeStr, srcNodeStr;
|
||||
HSTRING_HEADER textHeader, imageHeader, srcHeader;
|
||||
WindowsCreateStringReference(L"text", 4, &textHeader, &textNodeStr);
|
||||
WindowsCreateStringReference(L"image", 5, &imageHeader, &imageNodeStr);
|
||||
WindowsCreateStringReference(L"src", 3, &srcHeader, &srcNodeStr);
|
||||
toastXml->GetElementsByTagName(textNodeStr, &toastTextElements);
|
||||
toastXml->GetElementsByTagName(imageNodeStr, &toastImageElements);
|
||||
|
||||
AssertHRESULT(toastTextElements->Item(0, &titleTextNodeRoot));
|
||||
AssertHRESULT(toastTextElements->Item(1, &msgTextNodeRoot));
|
||||
AssertHRESULT(toastImageElements->Item(0, &imageNodeRoot));
|
||||
|
||||
ComPtr<IXmlNamedNodeMap> attributes;
|
||||
AssertHRESULT(imageNodeRoot->get_Attributes(&attributes));
|
||||
AssertHRESULT(attributes->GetNamedItem(srcNodeStr, &srcAttribute));
|
||||
|
||||
SetNodeValueString(title, titleTextNodeRoot.Get(), toastXml.Get());
|
||||
SetNodeValueString(msg, msgTextNodeRoot.Get(), toastXml.Get());
|
||||
SetNodeValueString(imagePath, srcAttribute.Get(), toastXml.Get());
|
||||
|
||||
ComPtr<IToastNotification> notification;
|
||||
ComPtr<IToastNotificationFactory> factory;
|
||||
AssertHRESULT(GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(),
|
||||
factory.GetAddressOf()));
|
||||
AssertHRESULT(factory->CreateToastNotification(toastXml.Get(), ¬ification));
|
||||
|
||||
EventRegistrationToken activatedToken;
|
||||
AssertHRESULT(notification->add_Activated(Callback<ToastActivationHandler>(this,
|
||||
&ToastNotificationHandler::OnActivate).Get(), &activatedToken));
|
||||
|
||||
ComPtr<IToastNotifier> notifier;
|
||||
toastNotificationManagerStatics->CreateToastNotifier(¬ifier);
|
||||
notifier->Show(notification.Get());
|
||||
}
|
||||
|
||||
void ToastNotificationHandler::SetNodeValueString(HSTRING inputString, ComPtr<IXmlNode> node, ComPtr<IXmlDocument> xml) {
|
||||
ComPtr<IXmlText> inputText;
|
||||
ComPtr<IXmlNode> inputTextNode, pAppendedChild;
|
||||
|
||||
AssertHRESULT(xml->CreateTextNode(inputString, &inputText));
|
||||
AssertHRESULT(inputText.As(&inputTextNode));
|
||||
AssertHRESULT(node->AppendChild(inputTextNode.Get(), &pAppendedChild));
|
||||
}
|
||||
|
||||
HRESULT ToastNotificationHandler::OnActivate(IToastNotification *notification, IInspectable *inspectable) {
|
||||
MetroUtils::FireObserver("metro_native_toast_clicked");
|
||||
return S_OK;
|
||||
}
|
26
widget/windows/winrt/ToastNotificationHandler.h
Normal file
26
widget/windows/winrt/ToastNotificationHandler.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.ui.notifications.h>
|
||||
#include <windows.data.xml.dom.h>
|
||||
#include "mozwrlbase.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
class ToastNotificationHandler {
|
||||
typedef ABI::Windows::UI::Notifications::IToastNotification IToastNotification;
|
||||
typedef ABI::Windows::Data::Xml::Dom::IXmlNode IXmlNode;
|
||||
typedef ABI::Windows::Data::Xml::Dom::IXmlDocument IXmlDocument;
|
||||
|
||||
void SetNodeValueString(HSTRING inputString, ComPtr<IXmlNode> node, ComPtr<IXmlDocument> xml);
|
||||
public:
|
||||
ToastNotificationHandler() {};
|
||||
~ToastNotificationHandler() {};
|
||||
|
||||
void DisplayNotification(HSTRING title, HSTRING msg, HSTRING imagePath);
|
||||
HRESULT OnActivate(IToastNotification *notification, IInspectable *inspectable);
|
||||
};
|
@ -15,6 +15,7 @@ CPP_SOURCES += [
|
||||
'MetroInput.cpp',
|
||||
'MetroUtils.cpp',
|
||||
'MetroWidget.cpp',
|
||||
'ToastNotificationHandler.cpp',
|
||||
'UIAAccessibilityBridge.cpp',
|
||||
'UIABridge.cpp',
|
||||
'nsMetroFilePicker.cpp',
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "FrameworkView.h"
|
||||
#include "MetroApp.h"
|
||||
#include "nsIWindowsRegKey.h"
|
||||
#include "ToastNotificationHandler.h"
|
||||
|
||||
#include <shldisp.h>
|
||||
#include <shellapi.h>
|
||||
@ -339,6 +340,24 @@ nsWinMetroUtils::LaunchInDesktop(const nsAString &aPath, const nsAString &aArgum
|
||||
if (!ShellExecuteEx(&sinfo)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWinMetroUtils::ShowNativeToast(const nsAString &aTitle,
|
||||
const nsAString &aMessage, const nsAString &anImage)
|
||||
{
|
||||
// Firefox is in the foreground, no need for a notification.
|
||||
if (::GetActiveWindow() == ::GetForegroundWindow()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ToastNotificationHandler* notification_handler =
|
||||
new ToastNotificationHandler;
|
||||
|
||||
HSTRING title = HStringReference(aTitle.BeginReading()).Get();
|
||||
HSTRING msg = HStringReference(aMessage.BeginReading()).Get();
|
||||
HSTRING imagePath = HStringReference(anImage.BeginReading()).Get();
|
||||
notification_handler->DisplayNotification(title, msg, imagePath);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user