зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1291642 - Part 1 - Add an optional checkbox to PopupNotifications. r=paolo
MozReview-Commit-ID: 9wzV6kNt5pV --HG-- extra : rebase_source : b0fa1dea0c23197a795076e1cb3c1be091c18872
This commit is contained in:
Родитель
2963c2ebb3
Коммит
aa0121a4fe
|
@ -347,8 +347,8 @@ function prompt(aBrowser, aRequest) {
|
|||
secondaryActions.unshift({
|
||||
label: stringBundle.getString("getUserMedia.always.label"),
|
||||
accessKey: stringBundle.getString("getUserMedia.always.accesskey"),
|
||||
callback: function () {
|
||||
mainAction.callback(true);
|
||||
callback: function (aState) {
|
||||
mainAction.callback(aState, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ function prompt(aBrowser, aRequest) {
|
|||
if (!sharingAudio)
|
||||
listDevices(micMenupopup, audioDevices);
|
||||
|
||||
this.mainAction.callback = function(aRemember) {
|
||||
this.mainAction.callback = function(aState, aRemember) {
|
||||
let allowedDevices = [];
|
||||
let perms = Services.perms;
|
||||
if (videoDevices.length) {
|
||||
|
|
|
@ -493,6 +493,9 @@
|
|||
<children includes="popupnotificationcontent"/>
|
||||
<xul:label class="text-link popup-notification-learnmore-link"
|
||||
xbl:inherits="onclick=learnmoreclick,href=learnmoreurl">&learnMore;</xul:label>
|
||||
<xul:checkbox anonid="checkbox"
|
||||
xbl:inherits="hidden=checkboxhidden,checked=checkboxchecked,label=checkboxlabel,oncommand=checkboxcommand" />
|
||||
<xul:description class="popup-notification-warning" xbl:inherits="hidden=warninghidden,xbl:text=warninglabel"/>
|
||||
<xul:spacer flex="1"/>
|
||||
<xul:hbox class="popup-notification-button-container"
|
||||
pack="end" align="center">
|
||||
|
@ -500,7 +503,7 @@
|
|||
<xul:button anonid="button"
|
||||
class="popup-notification-menubutton"
|
||||
type="menu-button"
|
||||
xbl:inherits="oncommand=buttoncommand,onpopupshown=buttonpopupshown,label=buttonlabel,accesskey=buttonaccesskey">
|
||||
xbl:inherits="oncommand=buttoncommand,onpopupshown=buttonpopupshown,label=buttonlabel,accesskey=buttonaccesskey,disabled=mainactiondisabled">
|
||||
<xul:menupopup anonid="menupopup"
|
||||
xbl:inherits="oncommand=menucommand">
|
||||
<children/>
|
||||
|
@ -516,6 +519,9 @@
|
|||
<stylesheet src="chrome://global/skin/notification.css"/>
|
||||
</resources>
|
||||
<implementation>
|
||||
<field name="checkbox" readonly="true">
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "checkbox");
|
||||
</field>
|
||||
<field name="closebutton" readonly="true">
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "closebutton");
|
||||
</field>
|
||||
|
|
|
@ -55,6 +55,18 @@ function getAnchorFromBrowser(aBrowser, aAnchorID) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function getNotificationFromElement(aElement) {
|
||||
// Need to find the associated notification object, which is a bit tricky
|
||||
// since it isn't associated with the element directly - this is kind of
|
||||
// gross and very dependent on the structure of the popupnotification
|
||||
// binding's content.
|
||||
let notificationEl;
|
||||
let parent = aElement;
|
||||
while (parent && (parent = aElement.ownerDocument.getBindingParent(parent)))
|
||||
notificationEl = parent;
|
||||
return notificationEl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification object describes a single popup notification.
|
||||
*
|
||||
|
@ -72,6 +84,8 @@ function Notification(id, message, anchorID, mainAction, secondaryActions,
|
|||
this.options = options || {};
|
||||
|
||||
this._dismissed = false;
|
||||
// Will become a boolean when manually toggled by the user.
|
||||
this._checkboxChecked = null;
|
||||
this.wasDismissed = false;
|
||||
this.recordedTelemetryStats = new Set();
|
||||
this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(
|
||||
|
@ -274,7 +288,8 @@ PopupNotifications.prototype = {
|
|||
* - label (string): the button's label.
|
||||
* - accessKey (string): the button's accessKey.
|
||||
* - callback (function): a callback to be invoked when the button is
|
||||
* pressed.
|
||||
* pressed, is passed an object that contains the following fields:
|
||||
* - checkboxChecked: (boolean) If the optional checkbox is checked.
|
||||
* - [optional] dismiss (boolean): If this is true, the notification
|
||||
* will be dismissed instead of removed after running the callback.
|
||||
* If null, the notification will not have a button, and
|
||||
|
@ -332,6 +347,26 @@ PopupNotifications.prototype = {
|
|||
* removed when they would have otherwise been dismissed
|
||||
* (i.e. any time the popup is closed due to user
|
||||
* interaction).
|
||||
* checkbox: An object that allows you to add a checkbox and
|
||||
* control its behavior with these fields:
|
||||
* label:
|
||||
* (required) Label to be shown next to the checkbox.
|
||||
* checked:
|
||||
* (optional) Whether the checkbox should be checked
|
||||
* by default. Defaults to false.
|
||||
* checkedState:
|
||||
* (optional) An object that allows you to customize
|
||||
* the notification state when the checkbox is checked.
|
||||
* disableMainAction:
|
||||
* (optional) Whether the mainAction is disabled.
|
||||
* Defaults to false.
|
||||
* warningLabel:
|
||||
* (optional) A (warning) text that is shown below the
|
||||
* checkbox. Pass null to hide.
|
||||
* uncheckedState:
|
||||
* (optional) An object that allows you to customize
|
||||
* the notification state when the checkbox is not checked.
|
||||
* Has the same attributes as checkedState.
|
||||
* hideNotNow: If true, indicates that the 'Not Now' menuitem should
|
||||
* not be shown. If 'Not Now' is hidden, it needs to be
|
||||
* replaced by another 'do nothing' item, so providing at
|
||||
|
@ -705,6 +740,25 @@ PopupNotifications.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
let checkbox = n.options.checkbox;
|
||||
if (checkbox && checkbox.label) {
|
||||
let checked = n._checkboxChecked != null ? n._checkboxChecked : !!checkbox.checked;
|
||||
|
||||
popupnotification.setAttribute("checkboxhidden", "false");
|
||||
popupnotification.setAttribute("checkboxchecked", checked);
|
||||
popupnotification.setAttribute("checkboxlabel", checkbox.label);
|
||||
|
||||
popupnotification.setAttribute("checkboxcommand", "PopupNotifications._onCheckboxCommand(event);");
|
||||
|
||||
if (checked) {
|
||||
this._setNotificationUIState(popupnotification, checkbox.checkedState);
|
||||
} else {
|
||||
this._setNotificationUIState(popupnotification, checkbox.uncheckedState);
|
||||
}
|
||||
} else {
|
||||
popupnotification.setAttribute("checkboxhidden", "true");
|
||||
}
|
||||
|
||||
this.panel.appendChild(popupnotification);
|
||||
|
||||
// The popupnotification may be hidden if we got it from the chrome
|
||||
|
@ -713,6 +767,32 @@ PopupNotifications.prototype = {
|
|||
}, this);
|
||||
},
|
||||
|
||||
_setNotificationUIState(notification, state={}) {
|
||||
notification.setAttribute("mainactiondisabled", state.disableMainAction || "false");
|
||||
|
||||
if (state.warningLabel) {
|
||||
notification.setAttribute("warninglabel", state.warningLabel);
|
||||
notification.setAttribute("warninghidden", "false");
|
||||
} else {
|
||||
notification.setAttribute("warninghidden", "true");
|
||||
}
|
||||
},
|
||||
|
||||
_onCheckboxCommand(event) {
|
||||
let notificationEl = getNotificationFromElement(event.originalTarget);
|
||||
let checked = notificationEl.checkbox.checked;
|
||||
let notification = notificationEl.notification;
|
||||
|
||||
// Save checkbox state to be able to persist it when re-opening the doorhanger.
|
||||
notification._checkboxChecked = checked;
|
||||
|
||||
if (checked) {
|
||||
this._setNotificationUIState(notificationEl, notification.options.checkbox.checkedState);
|
||||
} else {
|
||||
this._setNotificationUIState(notificationEl, notification.options.checkbox.uncheckedState);
|
||||
}
|
||||
},
|
||||
|
||||
_showPanel: function PopupNotifications_showPanel(notificationsToShow, anchorElement) {
|
||||
this.panel.hidden = false;
|
||||
|
||||
|
@ -1102,15 +1182,7 @@ PopupNotifications.prototype = {
|
|||
},
|
||||
|
||||
_onButtonEvent(event, type) {
|
||||
// Need to find the associated notification object, which is a bit tricky
|
||||
// since it isn't associated with the button directly - this is kind of
|
||||
// gross and very dependent on the structure of the popupnotification
|
||||
// binding's content.
|
||||
let target = event.originalTarget;
|
||||
let notificationEl;
|
||||
let parent = target;
|
||||
while (parent && (parent = target.ownerDocument.getBindingParent(parent)))
|
||||
notificationEl = parent;
|
||||
let notificationEl = getNotificationFromElement(event.originalTarget);
|
||||
|
||||
if (!notificationEl)
|
||||
throw "PopupNotifications._onButtonEvent: couldn't find notification element";
|
||||
|
@ -1150,7 +1222,9 @@ PopupNotifications.prototype = {
|
|||
notification._recordTelemetryStat(TELEMETRY_STAT_ACTION_1);
|
||||
|
||||
try {
|
||||
notification.mainAction.callback.call();
|
||||
notification.mainAction.callback.call(undefined, {
|
||||
checkboxChecked: notificationEl.checkbox.checked
|
||||
});
|
||||
} catch (error) {
|
||||
Cu.reportError(error);
|
||||
}
|
||||
|
@ -1169,12 +1243,15 @@ PopupNotifications.prototype = {
|
|||
if (!target.action || !target.notification)
|
||||
throw "menucommand target has no associated action/notification";
|
||||
|
||||
let notificationEl = target.parentElement;
|
||||
event.stopPropagation();
|
||||
|
||||
target.notification._recordTelemetryStat(target.action.telemetryStatId);
|
||||
|
||||
try {
|
||||
target.action.callback.call();
|
||||
target.action.callback.call(undefined, {
|
||||
checkboxChecked: notificationEl.checkbox.checked
|
||||
});
|
||||
} catch (error) {
|
||||
Cu.reportError(error);
|
||||
}
|
||||
|
|
|
@ -200,3 +200,7 @@ notification[type="info"]:not([value="translation"]) .close-icon:not(:hover) {
|
|||
.popup-notification-menubutton > .button-menubutton-button[disabled] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.popup-notification-warning {
|
||||
color: #aa1b08;
|
||||
}
|
||||
|
|
|
@ -207,3 +207,7 @@ XXX: apply styles to all themes until bug 509642 is fixed
|
|||
.popup-notification-menubutton > .button-menubutton-button[disabled] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (-moz-windows-default-theme) {
|
||||
color: #aa1b08;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче