Bug 1697295 - Replace camera and microphone labels with icons in WebRTC permission panel when Proton is enabled. r=pbz,Jamie,fluent-reviewers,desktop-theme-reviewers,harry,Gijs

This is not an exhaustive redress of the WebRTC panel. It just replaces the labels
preceding the camera/microphone selectors with icons if Proton is enabled. There's
still a bunch of styling work to do in this panel for Proton, but that will occur
in a follow-up patch.

Differential Revision: https://phabricator.services.mozilla.com/D107718
This commit is contained in:
Mike Conley 2021-03-12 17:42:54 +00:00
Родитель 67cce94aa4
Коммит 3fad3847c2
7 изменённых файлов: 113 добавлений и 50 удалений

Просмотреть файл

@ -700,7 +700,7 @@ function prompt(aActor, aBrowser, aRequest) {
return true;
}
function listDevices(menupopup, devices, label, deck) {
function listDevices(menupopup, devices, labelID) {
while (menupopup.lastChild) {
menupopup.removeChild(menupopup.lastChild);
}
@ -716,20 +716,24 @@ function prompt(aActor, aBrowser, aRequest) {
addDeviceToList(menupopup, device.name, device.deviceIndex);
}
let label = doc.getElementById(labelID);
if (devices.length == 1) {
label.value = devices[0].name;
deck.selectedIndex = 1;
label.hidden = false;
menulist.hidden = true;
} else {
deck.selectedIndex = 0;
label.hidden = true;
menulist.hidden = false;
}
}
let notificationElement = doc.getElementById(
"webRTC-shareDevices-notification"
);
function checkDisabledWindowMenuItem() {
let list = doc.getElementById("webRTC-selectWindow-menulist");
let item = list.selectedItem;
let notificationElement = doc.getElementById(
"webRTC-shareDevices-notification"
);
if (!item || item.hasAttribute("disabled")) {
notificationElement.setAttribute("invalidselection", "true");
} else {
@ -989,23 +993,37 @@ function prompt(aActor, aBrowser, aRequest) {
let micMenupopup = doc.getElementById(
"webRTC-selectMicrophone-menupopup"
);
let describedByIDs = ["webRTC-shareDevices-notification-description"];
let describedBySuffix = gProtonDoorhangersEnabled ? "icon" : "label";
if (sharingScreen) {
listScreenShareDevices(windowMenupopup, videoDevices);
checkDisabledWindowMenuItem();
} else {
let label = doc.getElementById("webRTC-selectCamera-label");
let deck = doc.getElementById("webRTC-selectCamera-deck");
listDevices(camMenupopup, videoDevices, label, deck);
doc
.getElementById("webRTC-shareDevices-notification")
.removeAttribute("invalidselection");
let labelID = "webRTC-selectCamera-single-device-label";
listDevices(camMenupopup, videoDevices, labelID);
notificationElement.removeAttribute("invalidselection");
if (videoDevices.length == 1) {
describedByIDs.push("webRTC-selectCamera-" + describedBySuffix);
describedByIDs.push(labelID);
}
}
if (!sharingAudio) {
let label = doc.getElementById("webRTC-selectMicrophone-label");
let deck = doc.getElementById("webRTC-selectMicrophone-deck");
listDevices(micMenupopup, audioDevices, label, deck);
let labelID = "webRTC-selectMicrophone-single-device-label";
listDevices(micMenupopup, audioDevices, labelID);
if (audioDevices.length == 1) {
describedByIDs.push("webRTC-selectMicrophone-" + describedBySuffix);
describedByIDs.push(labelID);
}
}
// PopupNotifications knows to clear the aria-describedby attribute
// when hiding, so we don't have to worry about cleaning it up ourselves.
chromeDoc.defaultView.PopupNotifications.panel.setAttribute(
"aria-describedby",
describedByIDs.join(" ")
);
this.mainAction.callback = async function(aState) {
let remember = false;

Просмотреть файл

@ -8,16 +8,19 @@
noautofocus="true"
role="alert"/>
<popupnotification id="webRTC-shareDevices-notification" hidden="true">
<popupnotification id="webRTC-shareDevices-notification" hidden="true"
descriptionid="webRTC-shareDevices-notification-description">
<popupnotificationcontent id="webRTC-selectCamera" orient="vertical">
<label data-l10n-id="popup-select-camera-device"
<label id="webRTC-selectCamera-label"
data-l10n-id="popup-select-camera-device"
control="webRTC-selectCamera-menulist"/>
<deck id="webRTC-selectCamera-deck">
<menulist id="webRTC-selectCamera-menulist">
<html:div class="webRTC-selectDevice-selector-container">
<xul:image id="webRTC-selectCamera-icon" class="webRTC-selectDevice-icon" data-l10n-id="popup-select-camera-icon"/>
<menulist id="webRTC-selectCamera-menulist" aria-labelledby="webRTC-selectCamera-icon">
<menupopup id="webRTC-selectCamera-menupopup"/>
</menulist>
<label id="webRTC-selectCamera-label" class="webRTC-selectDevice-label"></label>
</deck>
<label id="webRTC-selectCamera-single-device-label" class="webRTC-selectDevice-label"></label>
</html:div>
</popupnotificationcontent>
<popupnotificationcontent id="webRTC-selectWindowOrScreen" orient="vertical">
@ -39,14 +42,16 @@
</popupnotificationcontent>
<popupnotificationcontent id="webRTC-selectMicrophone" orient="vertical">
<label data-l10n-id="popup-select-microphone-device"
<label id="webRTC-selectMicrophone-label"
data-l10n-id="popup-select-microphone-device"
control="webRTC-selectMicrophone-menulist"/>
<deck id="webRTC-selectMicrophone-deck">
<menulist id="webRTC-selectMicrophone-menulist">
<html:div class="webRTC-selectDevice-selector-container">
<xul:image id="webRTC-selectMicrophone-icon" data-l10n-id="popup-select-microphone-icon" class="webRTC-selectDevice-icon"/>
<menulist id="webRTC-selectMicrophone-menulist" aria-labelledby="webRTC-selectMicrophone-icon">
<menupopup id="webRTC-selectMicrophone-menupopup"/>
</menulist>
<label id="webRTC-selectMicrophone-label" class="webRTC-selectDevice-label"></label>
</deck>
<label id="webRTC-selectMicrophone-single-device-label" class="webRTC-selectDevice-label"></label>
</html:div>
</popupnotificationcontent>
</popupnotification>

Просмотреть файл

@ -766,54 +766,49 @@ async function reloadAndAssertClosedStreams() {
function checkDeviceSelectors(aAudio, aVideo, aScreen, aWindow = window) {
let document = aWindow.document;
let micSelector = document.getElementById("webRTC-selectMicrophone");
let micDeck = document.getElementById("webRTC-selectMicrophone-deck");
let micLabel = document.getElementById("webRTC-selectMicrophone-label");
if (aAudio) {
ok(!micSelector.hidden, "microphone selector visible");
let micSelectorList = document.getElementById(
"webRTC-selectMicrophone-menulist"
);
// If there's only 1 device listed, the deck should show the label instead.
let micLabel = document.getElementById(
"webRTC-selectMicrophone-single-device-label"
);
// If there's only 1 device listed, then we should show the label instead of
// the menulist.
if (micSelectorList.itemCount == 1) {
is(micDeck.selectedIndex, "1", "Should be showing the microphone label.");
ok(micSelectorList.hidden, "Selector list should be hidden.");
ok(!micLabel.hidden, "Selector label should not be hidden.");
is(
micLabel.value,
micSelectorList.selectedItem.getAttribute("label"),
"Label should be showing the lone device label."
);
} else {
is(
micDeck.selectedIndex,
"0",
"Should be showing the microphone menulist."
);
ok(!micSelectorList.hidden, "Selector list should not be hidden.");
ok(micLabel.hidden, "Selector label should be hidden.");
}
} else {
ok(micSelector.hidden, "microphone selector hidden");
}
let cameraSelector = document.getElementById("webRTC-selectCamera");
let cameraDeck = document.getElementById("webRTC-selectCamera-deck");
let cameraLabel = document.getElementById("webRTC-selectCamera-label");
if (aVideo) {
ok(!cameraSelector.hidden, "camera selector visible");
let cameraSelectorList = document.getElementById(
"webRTC-selectCamera-menulist"
);
// If there's only 1 device listed, the deck should show the label instead.
let cameraLabel = document.getElementById(
"webRTC-selectCamera-single-device-label"
);
// If there's only 1 device listed, then we should show the label instead of
// the menulist.
if (cameraSelectorList.itemCount == 1) {
is(cameraDeck.selectedIndex, "1", "Should be showing the camera label.");
is(
cameraLabel.value,
cameraSelectorList.selectedItem.getAttribute("label"),
"Label should be showing the lone device label."
);
ok(cameraSelectorList.hidden, "Selector list should be hidden.");
ok(!cameraLabel.hidden, "Selector label should not be hidden.");
} else {
is(
cameraDeck.selectedIndex,
"0",
"Should be showing the camera menulist."
);
ok(!cameraSelectorList.hidden, "Selector list should not be hidden.");
ok(cameraLabel.hidden, "Selector label should be hidden.");
}
} else {
ok(cameraSelector.hidden, "camera selector hidden");

Просмотреть файл

@ -377,9 +377,13 @@ bookmarks-toolbar-empty-message = For quick access, place your bookmarks here on
popup-select-camera-device =
.value = Camera:
.accesskey = C
popup-select-camera-icon =
.tooltiptext = Camera
popup-select-microphone-device =
.value = Microphone:
.accesskey = M
popup-select-microphone-icon =
.tooltiptext = Microphone
popup-all-windows-shared = All visible windows on your screen will be shared.
popup-screen-sharing-block =

Просмотреть файл

@ -822,6 +822,42 @@ menupopup::part(drop-indicator) {
font-weight: 600;
}
.webRTC-selectDevice-selector-container {
display: flex;
align-items: center;
}
.webRTC-selectDevice-selector-container > menulist {
flex: 1;
}
@supports not -moz-bool-pref("browser.proton.doorhangers.enabled") {
#webRTC-selectCamera-icon,
#webRTC-selectMicrophone-icon {
display: none;
}
} /** END not Proton **/
@supports -moz-bool-pref("browser.proton.doorhangers.enabled") {
#webRTC-selectCamera-label,
#webRTC-selectMicrophone-label {
display: none;
}
.webRTC-selectDevice-icon {
-moz-context-properties: fill;
fill: currentColor;
}
#webRTC-selectCamera-icon {
list-style-image: url("chrome://browser/skin/notification-icons/camera.svg");
}
#webRTC-selectMicrophone-icon {
list-style-image: url("chrome://browser/skin/notification-icons/microphone.svg");
}
} /** END Proton **/
#tab-notification-deck {
display: flex;
}

Просмотреть файл

@ -12,7 +12,7 @@
return {
".popup-notification-icon": "popupid,src=icon,class=iconclass,hasicon",
".popup-notification-origin": "value=origin,tooltiptext=origin",
".popup-notification-description": "popupid",
".popup-notification-description": "popupid,id=descriptionid",
".popup-notification-description > span:first-of-type":
"text=label,popupid",
".popup-notification-description > b:first-of-type":

Просмотреть файл

@ -1694,6 +1694,11 @@ PopupNotifications.prototype = {
return;
}
// It's possible that a popupnotification set `aria-describedby` on the
// panel element in its eventCallback function. If so, we'll clear that out
// before showing the next notification.
this.panel.removeAttribute("aria-describedby");
// We may have removed the "noautofocus" attribute before showing the panel
// if the notification specified it wants to autofocus on first show.
// When the panel is closed, we have to restore the attribute to its default