mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-09 21:33:43 +00:00
Bug 1080406 - "Add an optional badge to the hamburger menu when updates are available". r=gijskruitbosch+bugs c=jwalker
This commit is contained in:
parent
daabef29fa
commit
c6387f65a5
@ -182,6 +182,9 @@ pref("app.update.metro.enabled", true);
|
||||
// If set to true, the Update Service will present no UI for any event.
|
||||
pref("app.update.silent", false);
|
||||
|
||||
// If set to true, the hamburger button will show badges for update events.
|
||||
pref("app.update.badge", false);
|
||||
|
||||
// If set to true, the Update Service will apply updates in the background
|
||||
// when it finishes downloading them.
|
||||
pref("app.update.staging.enabled", true);
|
||||
|
@ -1324,6 +1324,8 @@ var gBrowserInit = {
|
||||
// Add Devtools menuitems and listeners
|
||||
gDevToolsBrowser.registerBrowserWindow(window);
|
||||
|
||||
gMenuButtonUpdateBadge.init();
|
||||
|
||||
window.addEventListener("mousemove", MousePosTracker, false);
|
||||
window.addEventListener("dragover", MousePosTracker, false);
|
||||
|
||||
@ -1470,6 +1472,8 @@ var gBrowserInit = {
|
||||
|
||||
DevEdition.uninit();
|
||||
|
||||
gMenuButtonUpdateBadge.uninit();
|
||||
|
||||
var enumerator = Services.wm.getEnumerator(null);
|
||||
enumerator.getNext();
|
||||
if (!enumerator.hasMoreElements()) {
|
||||
@ -2439,6 +2443,118 @@ function PageProxyClickHandler(aEvent)
|
||||
middleMousePaste(aEvent);
|
||||
}
|
||||
|
||||
// Setup the hamburger button badges for updates, if enabled.
|
||||
let gMenuButtonUpdateBadge = {
|
||||
enabled: false,
|
||||
|
||||
init: function () {
|
||||
try {
|
||||
this.enabled = Services.prefs.getBoolPref("app.update.badge");
|
||||
} catch (e) {}
|
||||
if (this.enabled) {
|
||||
PanelUI.menuButton.classList.add("badged-button");
|
||||
Services.obs.addObserver(this, "update-staged", false);
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
if (this.enabled) {
|
||||
Services.obs.removeObserver(this, "update-staged");
|
||||
PanelUI.panel.removeEventListener("popupshowing", this, true);
|
||||
this.enabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
onMenuPanelCommand: function(event) {
|
||||
if (event.originalTarget.getAttribute("update-status") === "succeeded") {
|
||||
// restart the app
|
||||
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
|
||||
.createInstance(Ci.nsISupportsPRBool);
|
||||
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
|
||||
|
||||
if (!cancelQuit.data) {
|
||||
Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);
|
||||
}
|
||||
} else {
|
||||
// open the page for manual update
|
||||
let url = Services.urlFormatter.formatURLPref("app.update.url.manual");
|
||||
openUILinkIn(url, "tab");
|
||||
}
|
||||
},
|
||||
|
||||
observe: function (subject, topic, status) {
|
||||
const STATE_DOWNLOADING = "downloading";
|
||||
const STATE_PENDING = "pending";
|
||||
const STATE_PENDING_SVC = "pending-service";
|
||||
const STATE_APPLIED = "applied";
|
||||
const STATE_APPLIED_SVC = "applied-service";
|
||||
const STATE_FAILED = "failed";
|
||||
|
||||
let updateButton = document.getElementById("PanelUI-update-status");
|
||||
|
||||
let updateButtonText;
|
||||
let stringId;
|
||||
|
||||
// Update the UI when the background updater is finished.
|
||||
switch (status) {
|
||||
case STATE_APPLIED:
|
||||
case STATE_APPLIED_SVC:
|
||||
case STATE_PENDING:
|
||||
case STATE_PENDING_SVC:
|
||||
// If the update is successfully applied, or if the updater has fallen back
|
||||
// to non-staged updates, add a badge to the hamburger menu to indicate an
|
||||
// update will be applied once the browser restarts.
|
||||
let badge = document.getAnonymousElementByAttribute(PanelUI.menuButton,
|
||||
"class",
|
||||
"toolbarbutton-badge");
|
||||
badge.style.backgroundColor = 'green';
|
||||
PanelUI.menuButton.setAttribute("badge", "\u2605");
|
||||
|
||||
let brandBundle = document.getElementById("bundle_brand");
|
||||
let brandShortName = brandBundle.getString("brandShortName");
|
||||
stringId = "appmenu.restartNeeded.description";
|
||||
updateButtonText = gNavigatorBundle.getFormattedString(stringId,
|
||||
[brandShortName]);
|
||||
|
||||
updateButton.label = updateButtonText;
|
||||
updateButton.hidden = false;
|
||||
updateButton.setAttribute("update-status", "succeeded");
|
||||
|
||||
PanelUI.panel.addEventListener("popupshowing", this, true);
|
||||
|
||||
break;
|
||||
case STATE_FAILED:
|
||||
// Background update has failed, let's show the UI responsible for
|
||||
// prompting the user to update manually.
|
||||
PanelUI.menuButton.setAttribute("badge", "!");
|
||||
|
||||
stringId = "appmenu.updateFailed.description";
|
||||
updateButtonText = gNavigatorBundle.getString(stringId);
|
||||
|
||||
updateButton.label = updateButtonText;
|
||||
updateButton.hidden = false;
|
||||
updateButton.setAttribute("update-status", "failed");
|
||||
|
||||
PanelUI.panel.addEventListener("popupshowing", this, true);
|
||||
|
||||
break;
|
||||
case STATE_DOWNLOADING:
|
||||
// We've fallen back to downloading the full update because the partial
|
||||
// update failed to get staged in the background. Therefore we need to keep
|
||||
// our observer.
|
||||
return;
|
||||
}
|
||||
this.uninit();
|
||||
},
|
||||
|
||||
handleEvent: function(e) {
|
||||
if (e.type === "popupshowing") {
|
||||
PanelUI.menuButton.removeAttribute("badge");
|
||||
PanelUI.panel.removeEventListener("popupshowing", this, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle command events bubbling up from error page content
|
||||
* or from about:newtab or from remote error pages that invoke
|
||||
|
@ -16,6 +16,10 @@
|
||||
</vbox>
|
||||
|
||||
<footer id="PanelUI-footer">
|
||||
<toolbarbutton id="PanelUI-update-status"
|
||||
oncommand="gMenuButtonUpdateBadge.onMenuPanelCommand(event);"
|
||||
wrap="true"
|
||||
hidden="true"/>
|
||||
<toolbarbutton id="PanelUI-fxa-status"
|
||||
defaultlabel="&fxaSignIn.label;"
|
||||
errorlabel="&fxaSignInError.label;"
|
||||
|
@ -1413,6 +1413,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
|
||||
-moz-image-region: rect(0px, 192px, 32px, 160px);
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-status > .toolbarbutton-icon,
|
||||
#PanelUI-quit > .toolbarbutton-icon,
|
||||
#PanelUI-customize > .toolbarbutton-icon,
|
||||
|
@ -22,6 +22,10 @@
|
||||
linear-gradient(rgba(255,255,255,0.3), transparent);
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
list-style-image: url(chrome://branding/content/icon32.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status {
|
||||
list-style-image: url(chrome://browser/skin/sync-horizontalbar@2x.png);
|
||||
}
|
||||
|
@ -381,6 +381,7 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"] > iframe {
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .panel-wide-item,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .toolbarbutton-1:not([panel-multiview-anchor="true"]),
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-fxa-status,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-update-status,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > toolbarseparator,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-customize,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-help:not([panel-multiview-anchor="true"]) {
|
||||
@ -493,6 +494,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#PanelUI-update-status,
|
||||
#PanelUI-help,
|
||||
#PanelUI-fxa-status,
|
||||
#PanelUI-customize,
|
||||
@ -509,12 +511,14 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
-moz-box-orient: horizontal;
|
||||
}
|
||||
|
||||
#PanelUI-update-status,
|
||||
#PanelUI-fxa-status {
|
||||
border-top: 1px solid hsla(210,4%,10%,.14);
|
||||
border-bottom: 1px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-text,
|
||||
#PanelUI-fxa-status > .toolbarbutton-text {
|
||||
width: 0; /* Fancy cropping solution for flexbox. */
|
||||
}
|
||||
@ -524,6 +528,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
min-width: 46px;
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-text,
|
||||
#PanelUI-fxa-status > .toolbarbutton-text,
|
||||
#PanelUI-customize > .toolbarbutton-text {
|
||||
margin: 0;
|
||||
@ -536,6 +541,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-status > .toolbarbutton-icon,
|
||||
#PanelUI-customize > .toolbarbutton-icon,
|
||||
#PanelUI-help > .toolbarbutton-icon,
|
||||
@ -550,6 +556,16 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
-moz-border-start-style: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
width: calc(@menuPanelWidth@ + 30px);
|
||||
-moz-padding-start: 15px;
|
||||
-moz-border-start-style: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
list-style-image: url(chrome://branding/content/icon16.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status {
|
||||
list-style-image: url(chrome://browser/skin/sync-horizontalbar.png);
|
||||
}
|
||||
@ -625,6 +641,32 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="succeeded"] {
|
||||
background-color: hsla(96, 65%, 75%, 0.1);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="succeeded"]:not([disabled]):hover {
|
||||
background-color: hsla(96, 65%, 75%, 0.4);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="succeeded"]:not([disabled]):hover:active {
|
||||
background-color: hsla(96, 65%, 75%, 0.6);
|
||||
box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="failed"] {
|
||||
background-color: hsla(359, 69%, 84%, 0.1);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="failed"]:not([disabled]):hover {
|
||||
background-color: hsla(359, 69%, 84%, 0.4);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="failed"]:not([disabled]):hover:active {
|
||||
background-color: hsla(359, 69%, 84%, 0.6);
|
||||
box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
|
||||
}
|
||||
|
||||
#PanelUI-quit:not([disabled]):hover {
|
||||
background-color: #d94141;
|
||||
outline-color: #c23a3a;
|
||||
|
Loading…
Reference in New Issue
Block a user