Bug 1921060 - Implement full mute button spec r=desktop-theme-reviewers,tabbrowser-reviewers,dao,sessionstore-reviewers,sclements,sidebar-reviewers,fluent-reviewers,bolsson

Differential Revision: https://phabricator.services.mozilla.com/D231182
This commit is contained in:
Kelly Cochrane
2025-01-16 01:40:47 +00:00
parent 793467f360
commit f9046ef713
19 changed files with 290 additions and 220 deletions

View File

@@ -23,17 +23,14 @@
<image class="tab-sharing-icon-overlay" role="presentation"/>
<image class="tab-icon-overlay" role="presentation"/>
</stack>
<html:moz-button type="icon ghost" size="small" class="tab-audio-button" tabindex="-1"></html:moz-button>
<vbox class="tab-label-container"
align="start"
pack="center"
flex="1">
<label class="tab-text tab-label" role="presentation"/>
<hbox class="tab-secondary-label">
<label class="tab-icon-sound-label tab-icon-sound-playing-label" data-l10n-id="browser-tab-audio-playing2" role="presentation"/>
<label class="tab-icon-sound-label tab-icon-sound-muted-label" data-l10n-id="browser-tab-audio-muted2" role="presentation"/>
<label class="tab-icon-sound-label tab-icon-sound-blocked-label" data-l10n-id="browser-tab-audio-blocked" role="presentation"/>
<label class="tab-icon-sound-label tab-icon-sound-pip-label" data-l10n-id="browser-tab-audio-pip" role="presentation"/>
<label class="tab-icon-sound-label tab-icon-sound-tooltip-label" role="presentation"/>
</hbox>
</vbox>
<image class="tab-close-button close-icon" role="button" data-l10n-id="tabbrowser-close-tabs-button" data-l10n-args='{"tabCount": 1}' keyNav="false"/>
@@ -85,7 +82,7 @@
".tab-content":
"pinned,selected=visuallyselected,multiselected,titlechanged,attention",
".tab-icon-stack":
"sharing,pictureinpicture,crashed,busy,soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected,activemedia-blocked,indicator-replaces-favicon",
"sharing,pictureinpicture,crashed,busy,soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected,activemedia-blocked",
".tab-throbber":
"fadein,pinned,busy,progress,selected=visuallyselected",
".tab-icon-pending":
@@ -94,13 +91,15 @@
"src=image,triggeringprincipal=iconloadingprincipal,requestcontextid,fadein,pinned,selected=visuallyselected,busy,crashed,sharing,pictureinpicture",
".tab-sharing-icon-overlay": "sharing,selected=visuallyselected,pinned",
".tab-icon-overlay":
"sharing,pictureinpicture,crashed,busy,soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected,activemedia-blocked,indicator-replaces-favicon",
"sharing,pictureinpicture,crashed,busy,soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected,activemedia-blocked",
".tab-audio-button":
"crashed,soundplaying,soundplaying-scheduledremoval,pinned,muted,activemedia-blocked",
".tab-label-container":
"pinned,selected=visuallyselected,labeldirection",
".tab-label":
"text=label,accesskey,fadein,pinned,selected=visuallyselected,attention",
".tab-label-container .tab-secondary-label":
"soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected,activemedia-blocked,pictureinpicture",
"pinned,blocked,selected=visuallyselected,pictureinpicture",
".tab-close-button": "fadein,pinned,selected=visuallyselected",
};
}
@@ -310,10 +309,18 @@
return this.overlayIcon?.matches(":hover");
}
get _overAudioButton() {
return this.audioButton?.matches(":hover");
}
get overlayIcon() {
return this.querySelector(".tab-icon-overlay");
}
get audioButton() {
return this.querySelector(".tab-audio-button");
}
get throbber() {
return this.querySelector(".tab-throbber");
}
@@ -371,24 +378,6 @@
if (event.target.classList.contains("tab-close-button")) {
this.mOverCloseButton = true;
}
if (this._overPlayingIcon) {
const selectedTabs = gBrowser.selectedTabs;
const contextTabInSelection = selectedTabs.includes(this);
const affectedTabsLength = contextTabInSelection
? selectedTabs.length
: 1;
let stringID;
if (this.hasAttribute("activemedia-blocked")) {
stringID = "browser-tab-unblock";
} else {
stringID = this.linkedBrowser.audioMuted
? "browser-tab-unmute"
: "browser-tab-mute";
}
this.setSecondaryTabTooltipLabel(stringID, {
count: affectedTabsLength,
});
}
if (!this.visible) {
return;
@@ -409,9 +398,6 @@
if (event.target.classList.contains("tab-close-button")) {
this.mOverCloseButton = false;
}
if (event.target == this.overlayIcon) {
this.setSecondaryTabTooltipLabel(null);
}
// If the new target is not part of this tab then this is a mouseleave event.
if (!this.contains(event.relatedTarget)) {
@@ -451,7 +437,8 @@
this.style.MozUserFocus = "ignore";
} else if (
event.target.classList.contains("tab-close-button") ||
event.target.classList.contains("tab-icon-overlay")
event.target.classList.contains("tab-icon-overlay") ||
event.target.classList.contains("tab-audio-button")
) {
eventMaySelectTab = false;
}
@@ -516,14 +503,18 @@
if (
gBrowser.multiSelectedTabsCount > 0 &&
!event.target.classList.contains("tab-close-button") &&
!event.target.classList.contains("tab-icon-overlay")
!event.target.classList.contains("tab-icon-overlay") &&
!event.target.classList.contains("tab-audio-button")
) {
// Tabs were previously multi-selected and user clicks on a tab
// without holding Ctrl/Cmd Key
gBrowser.clearMultiSelectedTabs();
}
if (event.target.classList.contains("tab-icon-overlay")) {
if (
event.target.classList.contains("tab-icon-overlay") ||
event.target.classList.contains("tab-audio-button")
) {
if (this.activeMediaBlocked) {
if (this.multiselected) {
gBrowser.resumeDelayedMediaOnMultiSelectedTabs(this);
@@ -611,27 +602,6 @@
this.dispatchEvent(new CustomEvent("TabHoverEnd", { bubbles: true }));
}
setSecondaryTabTooltipLabel(l10nID, l10nArgs) {
this.querySelector(".tab-secondary-label").toggleAttribute(
"showtooltip",
l10nID
);
const tooltipEl = this.querySelector(".tab-icon-sound-tooltip-label");
if (l10nArgs) {
tooltipEl.setAttribute("data-l10n-args", JSON.stringify(l10nArgs));
} else {
tooltipEl.removeAttribute("data-l10n-args");
}
if (l10nID) {
tooltipEl.setAttribute("data-l10n-id", l10nID);
} else {
tooltipEl.removeAttribute("data-l10n-id");
}
// TODO(Itiel): Maybe simplify this when bug 1830989 lands
}
resumeDelayedMedia() {
if (this.activeMediaBlocked) {
this.removeAttribute("activemedia-blocked");

View File

@@ -2093,9 +2093,6 @@
// process so the browser can no longer be considered to be
// crashed.
tab.removeAttribute("crashed");
// we call updatetabIndicatorAttr here, rather than _tabAttrModified, so as
// to be consistent with how "crashed" attribute changes are handled elsewhere
this.tabContainer.updateTabIndicatorAttr(tab);
}
// If the findbar has been initialised, reset its browser reference.
@@ -6488,8 +6485,13 @@
event.stopPropagation();
let tab = event.target.triggerNode?.closest("tab");
if (!tab) {
event.preventDefault();
return;
if (event.target.triggerNode?.getRootNode()?.host?.closest("tab")) {
// Check if triggerNode is within shadowRoot of moz-button
tab = event.target.triggerNode?.getRootNode().host.closest("tab");
} else {
event.preventDefault();
return;
}
}
const tooltip = event.target;
@@ -6498,7 +6500,7 @@
const tabCount = this.selectedTabs.includes(tab)
? this.selectedTabs.length
: 1;
if (tab._overPlayingIcon) {
if (tab._overPlayingIcon || tab._overAudioButton) {
let l10nId;
const l10nArgs = { tabCount };
if (tab.selected) {
@@ -7112,7 +7114,6 @@
// process so the browser can no longer be considered to be
// crashed.
tab.removeAttribute("crashed");
gBrowser.tabContainer.updateTabIndicatorAttr(tab);
}
if (this.isFindBarInitialized(tab)) {
@@ -7437,7 +7438,6 @@
delete this.mBrowser.initialPageLoadedFromUserAction;
// If the browser is loading it must not be crashed anymore
this.mTab.removeAttribute("crashed");
gBrowser.tabContainer.updateTabIndicatorAttr(this.mTab);
}
if (this._shouldShowProgress(aRequest)) {

View File

@@ -55,8 +55,6 @@
this.addEventListener("TabAttrModified", this);
this.addEventListener("TabHide", this);
this.addEventListener("TabShow", this);
this.addEventListener("TabPinned", this);
this.addEventListener("TabUnpinned", this);
this.addEventListener("TabHoverStart", this);
this.addEventListener("TabHoverEnd", this);
this.addEventListener("TabGroupExpand", this);
@@ -227,17 +225,6 @@
this.#updateTabMinWidth();
this.#updateTabMinHeight();
let indicatorTabs = gBrowser.visibleTabs.filter(tab => {
return (
tab.hasAttribute("soundplaying") ||
tab.hasAttribute("muted") ||
tab.hasAttribute("activemedia-blocked")
);
});
for (const indicatorTab of indicatorTabs) {
this.updateTabIndicatorAttr(indicatorTab);
}
super.attributeChangedCallback(name, oldValue, newValue);
}
@@ -250,20 +237,19 @@
}
on_TabAttrModified(event) {
if (
["soundplaying", "muted", "activemedia-blocked", "sharing"].some(attr =>
event.detail.changed.includes(attr)
)
) {
this.updateTabIndicatorAttr(event.target);
}
if (
event.detail.changed.includes("soundplaying") &&
!event.target.visible
) {
this._hiddenSoundPlayingStatusChanged(event.target);
}
if (
event.detail.changed.includes("soundplaying") ||
event.detail.changed.includes("muted") ||
event.detail.changed.includes("activemedia-blocked")
) {
this.updateTabSoundLabel(event.target);
}
}
on_TabHide(event) {
@@ -278,14 +264,6 @@
}
}
on_TabPinned(event) {
this.updateTabIndicatorAttr(event.target);
}
on_TabUnpinned(event) {
this.updateTabIndicatorAttr(event.target);
}
on_TabHoverStart(event) {
if (!this._showCardPreviews) {
return;
@@ -3126,22 +3104,28 @@
CustomizableUI.removeListener(this);
}
updateTabIndicatorAttr(tab) {
const theseAttributes = ["soundplaying", "muted", "activemedia-blocked"];
const notTheseAttributes = ["pinned", "sharing", "crashed"];
if (
this.verticalMode ||
notTheseAttributes.some(attr => tab.hasAttribute(attr))
) {
tab.removeAttribute("indicator-replaces-favicon");
return;
updateTabSoundLabel(tab) {
// Add aria-label for inline audio button
const [unmute, mute, unblock] =
gBrowser.tabLocalization.formatMessagesSync([
"tabbrowser-unmute-tab-audio-aria-label",
"tabbrowser-mute-tab-audio-aria-label",
"tabbrowser-unblock-tab-audio-aria-label",
]);
if (tab.audioButton) {
if (tab.hasAttribute("muted") || tab.hasAttribute("soundplaying")) {
let ariaLabel;
tab.linkedBrowser.audioMuted
? (ariaLabel = unmute.attributes[0].value)
: (ariaLabel = mute.attributes[0].value);
tab.audioButton.setAttribute("aria-label", ariaLabel);
} else if (tab.hasAttribute("activemedia-blocked")) {
tab.audioButton.setAttribute(
"aria-label",
unblock.attributes[0].value
);
}
}
tab.toggleAttribute(
"indicator-replaces-favicon",
theseAttributes.some(attr => tab.hasAttribute(attr))
);
}
}