зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1596897 - Moved permission list from site identity to separate permission panel. r=johannh
- Added a new permission panel managed by the gPermissionPanel object - Updated identity-box to separate identity and permission section Differential Revision: https://phabricator.services.mozilla.com/D99892
This commit is contained in:
Родитель
7ce5240dfe
Коммит
6445d181dc
|
@ -206,6 +206,12 @@ var gIdentityHandler = {
|
||||||
delete this._identityBox;
|
delete this._identityBox;
|
||||||
return (this._identityBox = document.getElementById("identity-box"));
|
return (this._identityBox = document.getElementById("identity-box"));
|
||||||
},
|
},
|
||||||
|
get _identityIconBox() {
|
||||||
|
delete this._identityIconBox;
|
||||||
|
return (this._identityIconBox = document.getElementById(
|
||||||
|
"identity-icon-box"
|
||||||
|
));
|
||||||
|
},
|
||||||
get _identityPopupMultiView() {
|
get _identityPopupMultiView() {
|
||||||
delete this._identityPopupMultiView;
|
delete this._identityPopupMultiView;
|
||||||
return (this._identityPopupMultiView = document.getElementById(
|
return (this._identityPopupMultiView = document.getElementById(
|
||||||
|
@ -295,30 +301,6 @@ var gIdentityHandler = {
|
||||||
delete this._identityIcon;
|
delete this._identityIcon;
|
||||||
return (this._identityIcon = document.getElementById("identity-icon"));
|
return (this._identityIcon = document.getElementById("identity-icon"));
|
||||||
},
|
},
|
||||||
get _permissionList() {
|
|
||||||
delete this._permissionList;
|
|
||||||
return (this._permissionList = document.getElementById(
|
|
||||||
"identity-popup-permission-list"
|
|
||||||
));
|
|
||||||
},
|
|
||||||
get _defaultPermissionAnchor() {
|
|
||||||
delete this._defaultPermissionAnchor;
|
|
||||||
return (this._defaultPermissionAnchor = document.getElementById(
|
|
||||||
"identity-popup-permission-list-default-anchor"
|
|
||||||
));
|
|
||||||
},
|
|
||||||
get _permissionEmptyHint() {
|
|
||||||
delete this._permissionEmptyHint;
|
|
||||||
return (this._permissionEmptyHint = document.getElementById(
|
|
||||||
"identity-popup-permission-empty-hint"
|
|
||||||
));
|
|
||||||
},
|
|
||||||
get _permissionReloadHint() {
|
|
||||||
delete this._permissionReloadHint;
|
|
||||||
return (this._permissionReloadHint = document.getElementById(
|
|
||||||
"identity-popup-permission-reload-hint"
|
|
||||||
));
|
|
||||||
},
|
|
||||||
get _popupExpander() {
|
get _popupExpander() {
|
||||||
delete this._popupExpander;
|
delete this._popupExpander;
|
||||||
return (this._popupExpander = document.getElementById(
|
return (this._popupExpander = document.getElementById(
|
||||||
|
@ -331,32 +313,6 @@ var gIdentityHandler = {
|
||||||
"identity-popup-clear-sitedata-footer"
|
"identity-popup-clear-sitedata-footer"
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
get _permissionAnchors() {
|
|
||||||
delete this._permissionAnchors;
|
|
||||||
let permissionAnchors = {};
|
|
||||||
for (let anchor of document.getElementById("blocked-permissions-container")
|
|
||||||
.children) {
|
|
||||||
permissionAnchors[anchor.getAttribute("data-permission-id")] = anchor;
|
|
||||||
}
|
|
||||||
return (this._permissionAnchors = permissionAnchors);
|
|
||||||
},
|
|
||||||
|
|
||||||
get _geoSharingIcon() {
|
|
||||||
delete this._geoSharingIcon;
|
|
||||||
return (this._geoSharingIcon = document.getElementById("geo-sharing-icon"));
|
|
||||||
},
|
|
||||||
|
|
||||||
get _xrSharingIcon() {
|
|
||||||
delete this._xrSharingIcon;
|
|
||||||
return (this._xrSharingIcon = document.getElementById("xr-sharing-icon"));
|
|
||||||
},
|
|
||||||
|
|
||||||
get _webRTCSharingIcon() {
|
|
||||||
delete this._webRTCSharingIcon;
|
|
||||||
return (this._webRTCSharingIcon = document.getElementById(
|
|
||||||
"webrtc-sharing-icon"
|
|
||||||
));
|
|
||||||
},
|
|
||||||
|
|
||||||
get _insecureConnectionIconEnabled() {
|
get _insecureConnectionIconEnabled() {
|
||||||
delete this._insecureConnectionIconEnabled;
|
delete this._insecureConnectionIconEnabled;
|
||||||
|
@ -465,10 +421,6 @@ var gIdentityHandler = {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
},
|
},
|
||||||
|
|
||||||
openPermissionPreferences() {
|
|
||||||
openPreferences("privacy-permissions");
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for mouseclicks on the "More Information" button in the
|
* Handler for mouseclicks on the "More Information" button in the
|
||||||
* "identity-popup" panel.
|
* "identity-popup" panel.
|
||||||
|
@ -699,8 +651,9 @@ var gIdentityHandler = {
|
||||||
this.refreshIdentityBlock();
|
this.refreshIdentityBlock();
|
||||||
// Handle a location change while the Control Center is focused
|
// Handle a location change while the Control Center is focused
|
||||||
// by closing the popup (bug 1207542)
|
// by closing the popup (bug 1207542)
|
||||||
if (shouldHidePopup && this._popupInitialized) {
|
if (shouldHidePopup) {
|
||||||
PanelMultiView.hidePopup(this._identityPopup);
|
this.hidePopup();
|
||||||
|
gPermissionPanel.hidePopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: We do NOT update the identity popup (the control center) when
|
// NOTE: We do NOT update the identity popup (the control center) when
|
||||||
|
@ -733,46 +686,6 @@ var gIdentityHandler = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateSharingIndicator() {
|
|
||||||
let tab = gBrowser.selectedTab;
|
|
||||||
this._sharingState = tab._sharingState;
|
|
||||||
|
|
||||||
this._webRTCSharingIcon.removeAttribute("paused");
|
|
||||||
this._webRTCSharingIcon.removeAttribute("sharing");
|
|
||||||
this._geoSharingIcon.removeAttribute("sharing");
|
|
||||||
this._xrSharingIcon.removeAttribute("sharing");
|
|
||||||
|
|
||||||
if (this._sharingState) {
|
|
||||||
if (
|
|
||||||
this._sharingState &&
|
|
||||||
this._sharingState.webRTC &&
|
|
||||||
this._sharingState.webRTC.sharing
|
|
||||||
) {
|
|
||||||
this._webRTCSharingIcon.setAttribute(
|
|
||||||
"sharing",
|
|
||||||
this._sharingState.webRTC.sharing
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this._sharingState.webRTC.paused) {
|
|
||||||
this._webRTCSharingIcon.setAttribute("paused", "true");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this._sharingState.geo) {
|
|
||||||
this._geoSharingIcon.setAttribute("sharing", this._sharingState.geo);
|
|
||||||
}
|
|
||||||
if (this._sharingState.xr) {
|
|
||||||
this._xrSharingIcon.setAttribute("sharing", this._sharingState.xr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._popupInitialized && this._identityPopup.state != "closed") {
|
|
||||||
this.updateSitePermissions();
|
|
||||||
PanelView.forNode(
|
|
||||||
this._identityPopupMainView
|
|
||||||
).descriptionHeightWorkaround();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to provide proper IDN treatment for host names
|
* Attempt to provide proper IDN treatment for host names
|
||||||
*/
|
*/
|
||||||
|
@ -986,50 +899,6 @@ var gIdentityHandler = {
|
||||||
this._identityIconLabel.collapsed = !icon_label;
|
this._identityIconLabel.collapsed = !icon_label;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the permissions block in the identity block.
|
|
||||||
*/
|
|
||||||
_refreshPermissionIcons() {
|
|
||||||
let permissionAnchors = this._permissionAnchors;
|
|
||||||
|
|
||||||
// hide all permission icons
|
|
||||||
for (let icon of Object.values(permissionAnchors)) {
|
|
||||||
icon.removeAttribute("showing");
|
|
||||||
}
|
|
||||||
|
|
||||||
// keeps track if we should show an indicator that there are active permissions
|
|
||||||
let hasGrantedPermissions = false;
|
|
||||||
|
|
||||||
// show permission icons
|
|
||||||
let permissions = SitePermissions.getAllForBrowser(
|
|
||||||
gBrowser.selectedBrowser
|
|
||||||
);
|
|
||||||
for (let permission of permissions) {
|
|
||||||
if (
|
|
||||||
permission.state == SitePermissions.BLOCK ||
|
|
||||||
permission.state == SitePermissions.AUTOPLAY_BLOCKED_ALL
|
|
||||||
) {
|
|
||||||
let icon = permissionAnchors[permission.id];
|
|
||||||
if (icon) {
|
|
||||||
icon.setAttribute("showing", "true");
|
|
||||||
}
|
|
||||||
} else if (permission.state != SitePermissions.UNKNOWN) {
|
|
||||||
hasGrantedPermissions = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasGrantedPermissions) {
|
|
||||||
this._identityBox.classList.add("grantedPermissions");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show blocked popup icon in the identity-box if popups are blocked
|
|
||||||
// irrespective of popup permission capability value.
|
|
||||||
if (gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount()) {
|
|
||||||
let icon = permissionAnchors.popup;
|
|
||||||
icon.setAttribute("showing", "true");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the identity block user interface with the data from this object.
|
* Updates the identity block user interface with the data from this object.
|
||||||
*/
|
*/
|
||||||
|
@ -1045,12 +914,13 @@ var gIdentityHandler = {
|
||||||
// This will also filter out intermediate about:blank loads to avoid
|
// This will also filter out intermediate about:blank loads to avoid
|
||||||
// flickering the identity block and doing unnecessary work.
|
// flickering the identity block and doing unnecessary work.
|
||||||
if (this._hasInvalidPageProxyState()) {
|
if (this._hasInvalidPageProxyState()) {
|
||||||
|
gPermissionPanel.hidePermissionIcons();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._refreshIdentityIcons();
|
this._refreshIdentityIcons();
|
||||||
|
|
||||||
this._refreshPermissionIcons();
|
gPermissionPanel.refreshPermissionIcons();
|
||||||
|
|
||||||
// Hide the shield icon if it is a chrome page.
|
// Hide the shield icon if it is a chrome page.
|
||||||
gProtectionsHandler._trackingProtectionIconContainer.classList.toggle(
|
gProtectionsHandler._trackingProtectionIconContainer.classList.toggle(
|
||||||
|
@ -1252,9 +1122,6 @@ var gIdentityHandler = {
|
||||||
this._identityPopupContentOwner.textContent = owner;
|
this._identityPopupContentOwner.textContent = owner;
|
||||||
this._identityPopupContentSupp.textContent = supplemental;
|
this._identityPopupContentSupp.textContent = supplemental;
|
||||||
this._identityPopupContentVerif.textContent = verifier;
|
this._identityPopupContentVerif.textContent = verifier;
|
||||||
|
|
||||||
// Update per-site permissions section.
|
|
||||||
this.updateSitePermissions();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setURI(uri) {
|
setURI(uri) {
|
||||||
|
@ -1309,39 +1176,11 @@ var gIdentityHandler = {
|
||||||
return; // Left click, space or enter only
|
return; // Left click, space or enter only
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow left click, space or enter if the location has been modified,
|
// Don't allow left click, space or enter if the location has been modified.
|
||||||
// so long as we're not sharing any devices.
|
if (gURLBar.getAttribute("pageproxystate") != "valid") {
|
||||||
// If we are sharing a device, the identity block is prevented by CSS from
|
|
||||||
// being focused (and therefore, interacted with) by the user. However, we
|
|
||||||
// want to allow opening the identity popup from the device control menu,
|
|
||||||
// which calls click() on the identity button, so we don't return early.
|
|
||||||
if (
|
|
||||||
!this._sharingState &&
|
|
||||||
gURLBar.getAttribute("pageproxystate") != "valid"
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are in DOM full-screen, exit it before showing the identity popup
|
|
||||||
// (see bug 1557041)
|
|
||||||
if (document.fullscreen) {
|
|
||||||
// Open the identity popup after DOM full-screen exit
|
|
||||||
// We need to wait for the exit event and after that wait for the fullscreen exit transition to complete
|
|
||||||
// If we call _openPopup before the full-screen transition ends it can get cancelled
|
|
||||||
// Only waiting for painted is not sufficient because we could still be in the full-screen enter transition.
|
|
||||||
this._exitedEventReceived = false;
|
|
||||||
this._event = event;
|
|
||||||
Services.obs.addObserver(this, "fullscreen-painted");
|
|
||||||
window.addEventListener(
|
|
||||||
"MozDOMFullscreen:Exited",
|
|
||||||
() => {
|
|
||||||
this._exitedEventReceived = true;
|
|
||||||
},
|
|
||||||
{ once: true }
|
|
||||||
);
|
|
||||||
document.exitFullscreen();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._openPopup(event);
|
this._openPopup(event);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1349,14 +1188,11 @@ var gIdentityHandler = {
|
||||||
// Make the popup available.
|
// Make the popup available.
|
||||||
this._initializePopup();
|
this._initializePopup();
|
||||||
|
|
||||||
// Remove the reload hint that we show after a user has cleared a permission.
|
|
||||||
this._permissionReloadHint.setAttribute("hidden", "true");
|
|
||||||
|
|
||||||
// Update the popup strings
|
// Update the popup strings
|
||||||
this.refreshIdentityPopup();
|
this.refreshIdentityPopup();
|
||||||
|
|
||||||
// Add the "open" attribute to the identity box for styling
|
// Add the "open" attribute to the identity box for styling
|
||||||
this._identityBox.setAttribute("open", "true");
|
this._identityIconBox.setAttribute("open", "true");
|
||||||
|
|
||||||
// Check the panel state of other panels. Hide them if needed.
|
// Check the panel state of other panels. Hide them if needed.
|
||||||
let openPanels = Array.from(document.querySelectorAll("panel[openpanel]"));
|
let openPanels = Array.from(document.querySelectorAll("panel[openpanel]"));
|
||||||
|
@ -1365,7 +1201,7 @@ var gIdentityHandler = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now open the popup, anchored off the primary chrome element
|
// Now open the popup, anchored off the primary chrome element
|
||||||
PanelMultiView.openPopup(this._identityPopup, this._identityIcon, {
|
PanelMultiView.openPopup(this._identityPopup, this._identityIconBox, {
|
||||||
position: "bottomcenter topleft",
|
position: "bottomcenter topleft",
|
||||||
triggerEvent: event,
|
triggerEvent: event,
|
||||||
}).catch(Cu.reportError);
|
}).catch(Cu.reportError);
|
||||||
|
@ -1380,7 +1216,7 @@ var gIdentityHandler = {
|
||||||
onPopupHidden(event) {
|
onPopupHidden(event) {
|
||||||
if (event.target == this._identityPopup) {
|
if (event.target == this._identityPopup) {
|
||||||
window.removeEventListener("focus", this, true);
|
window.removeEventListener("focus", this, true);
|
||||||
this._identityBox.removeAttribute("open");
|
this._identityIconBox.removeAttribute("open");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1416,15 +1252,6 @@ var gIdentityHandler = {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "fullscreen-painted": {
|
|
||||||
if (subject != window || !this._exitedEventReceived) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Services.obs.removeObserver(this, "fullscreen-painted");
|
|
||||||
this._openPopup(this._event);
|
|
||||||
delete this._event;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1500,16 +1327,6 @@ var gIdentityHandler = {
|
||||||
gURLBar.view.close();
|
gURLBar.view.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
onLocationChange() {
|
|
||||||
if (this._popupInitialized && this._identityPopup.state != "closed") {
|
|
||||||
this._permissionReloadHint.setAttribute("hidden", "true");
|
|
||||||
|
|
||||||
if (this._isPermissionListEmpty()) {
|
|
||||||
this._permissionEmptyHint.removeAttribute("hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateAttribute(elem, attr, value) {
|
_updateAttribute(elem, attr, value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
elem.setAttribute(attr, value);
|
elem.setAttribute(attr, value);
|
||||||
|
@ -1517,598 +1334,4 @@ var gIdentityHandler = {
|
||||||
elem.removeAttribute(attr);
|
elem.removeAttribute(attr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_isPermissionListEmpty() {
|
|
||||||
return !this._permissionList.querySelectorAll(
|
|
||||||
".identity-popup-permission-item"
|
|
||||||
).length;
|
|
||||||
},
|
|
||||||
|
|
||||||
updateSitePermissions() {
|
|
||||||
let permissionItemSelector = [
|
|
||||||
".identity-popup-permission-item, .identity-popup-permission-item-container",
|
|
||||||
];
|
|
||||||
this._permissionList
|
|
||||||
.querySelectorAll(permissionItemSelector)
|
|
||||||
.forEach(e => e.remove());
|
|
||||||
|
|
||||||
let permissions = SitePermissions.getAllPermissionDetailsForBrowser(
|
|
||||||
gBrowser.selectedBrowser
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this._sharingState && this._sharingState.geo) {
|
|
||||||
let geoPermission = permissions.find(perm => perm.id === "geo");
|
|
||||||
if (geoPermission) {
|
|
||||||
geoPermission.sharingState = true;
|
|
||||||
} else {
|
|
||||||
permissions.push({
|
|
||||||
id: "geo",
|
|
||||||
state: SitePermissions.ALLOW,
|
|
||||||
scope: SitePermissions.SCOPE_REQUEST,
|
|
||||||
sharingState: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._sharingState && this._sharingState.xr) {
|
|
||||||
let xrPermission = permissions.find(perm => perm.id === "xr");
|
|
||||||
if (xrPermission) {
|
|
||||||
xrPermission.sharingState = true;
|
|
||||||
} else {
|
|
||||||
permissions.push({
|
|
||||||
id: "xr",
|
|
||||||
state: SitePermissions.ALLOW,
|
|
||||||
scope: SitePermissions.SCOPE_REQUEST,
|
|
||||||
sharingState: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._sharingState && this._sharingState.webRTC) {
|
|
||||||
let webrtcState = this._sharingState.webRTC;
|
|
||||||
// If WebRTC device or screen permissions are in use, we need to find
|
|
||||||
// the associated permission item to set the sharingState field.
|
|
||||||
for (let id of ["camera", "microphone", "screen"]) {
|
|
||||||
if (webrtcState[id]) {
|
|
||||||
let found = false;
|
|
||||||
for (let permission of permissions) {
|
|
||||||
if (permission.id != id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
found = true;
|
|
||||||
permission.sharingState = webrtcState[id];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
// If the permission item we were looking for doesn't exist,
|
|
||||||
// the user has temporarily allowed sharing and we need to add
|
|
||||||
// an item in the permissions array to reflect this.
|
|
||||||
permissions.push({
|
|
||||||
id,
|
|
||||||
state: SitePermissions.ALLOW,
|
|
||||||
scope: SitePermissions.SCOPE_REQUEST,
|
|
||||||
sharingState: webrtcState[id],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let totalBlockedPopups = gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount();
|
|
||||||
let hasBlockedPopupIndicator = false;
|
|
||||||
for (let permission of permissions) {
|
|
||||||
let [id, key] = permission.id.split(SitePermissions.PERM_KEY_DELIMITER);
|
|
||||||
|
|
||||||
if (id == "storage-access") {
|
|
||||||
// Ignore storage access permissions here, they are made visible inside
|
|
||||||
// the Content Blocking UI.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let item;
|
|
||||||
let anchor =
|
|
||||||
this._permissionList.querySelector(`[anchorfor="${id}"]`) ||
|
|
||||||
this._defaultPermissionAnchor;
|
|
||||||
|
|
||||||
if (id == "open-protocol-handler") {
|
|
||||||
let permContainer = this._createProtocolHandlerPermissionItem(
|
|
||||||
permission,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
if (permContainer) {
|
|
||||||
anchor.appendChild(permContainer);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item = this._createPermissionItem({
|
|
||||||
permission,
|
|
||||||
isContainer: id == "geo" || id == "xr",
|
|
||||||
nowrapLabel: id == "3rdPartyStorage",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!item) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
anchor.appendChild(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id == "popup" && totalBlockedPopups) {
|
|
||||||
this._createBlockedPopupIndicator(totalBlockedPopups);
|
|
||||||
hasBlockedPopupIndicator = true;
|
|
||||||
} else if (id == "geo" && permission.state === SitePermissions.ALLOW) {
|
|
||||||
this._createGeoLocationLastAccessIndicator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalBlockedPopups && !hasBlockedPopupIndicator) {
|
|
||||||
let permission = {
|
|
||||||
id: "popup",
|
|
||||||
state: SitePermissions.getDefault("popup"),
|
|
||||||
scope: SitePermissions.SCOPE_PERSISTENT,
|
|
||||||
};
|
|
||||||
let item = this._createPermissionItem({ permission });
|
|
||||||
this._defaultPermissionAnchor.appendChild(item);
|
|
||||||
this._createBlockedPopupIndicator(totalBlockedPopups);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show a placeholder text if there's no permission and no reload hint.
|
|
||||||
if (
|
|
||||||
this._isPermissionListEmpty() &&
|
|
||||||
this._permissionReloadHint.hasAttribute("hidden")
|
|
||||||
) {
|
|
||||||
this._permissionEmptyHint.removeAttribute("hidden");
|
|
||||||
} else {
|
|
||||||
this._permissionEmptyHint.setAttribute("hidden", "true");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a permission item based on the supplied options and returns it.
|
|
||||||
* It is up to the caller to actually insert the element somewhere.
|
|
||||||
*
|
|
||||||
* @param permission - An object containing information representing the
|
|
||||||
* permission, typically obtained via SitePermissions.jsm
|
|
||||||
* @param isContainer - If true, the permission item will be added to a vbox
|
|
||||||
* and the vbox will be returned.
|
|
||||||
* @param permClearButton - Whether to show an "x" button to clear the permission
|
|
||||||
* @param showStateLabel - Whether to show a label indicating the current status
|
|
||||||
* of the permission e.g. "Temporary Allowed"
|
|
||||||
* @param idNoSuffix - Some permission types have additional information suffixed
|
|
||||||
* to the ID - callers can pass the unsuffixed ID via this
|
|
||||||
* parameter to indicate the permission type manually.
|
|
||||||
* @param nowrapLabel - Whether to prevent the permission item's label from
|
|
||||||
* wrapping its text content. This allows styling text-overflow
|
|
||||||
* and is useful for e.g. 3rdPartyStorage permissions whose
|
|
||||||
* labels are origins - which could be of any length.
|
|
||||||
*/
|
|
||||||
_createPermissionItem({
|
|
||||||
permission,
|
|
||||||
isContainer = false,
|
|
||||||
permClearButton = true,
|
|
||||||
showStateLabel = true,
|
|
||||||
idNoSuffix = permission.id,
|
|
||||||
nowrapLabel = false,
|
|
||||||
}) {
|
|
||||||
let container = document.createXULElement("hbox");
|
|
||||||
container.setAttribute("class", "identity-popup-permission-item");
|
|
||||||
container.setAttribute("align", "center");
|
|
||||||
container.setAttribute("role", "group");
|
|
||||||
|
|
||||||
let img = document.createXULElement("image");
|
|
||||||
img.classList.add("identity-popup-permission-icon", idNoSuffix + "-icon");
|
|
||||||
if (
|
|
||||||
permission.state == SitePermissions.BLOCK ||
|
|
||||||
permission.state == SitePermissions.AUTOPLAY_BLOCKED_ALL
|
|
||||||
) {
|
|
||||||
img.classList.add("blocked-permission-icon");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
permission.sharingState ==
|
|
||||||
Ci.nsIMediaManagerService.STATE_CAPTURE_ENABLED ||
|
|
||||||
(idNoSuffix == "screen" &&
|
|
||||||
permission.sharingState &&
|
|
||||||
!permission.sharingState.includes("Paused"))
|
|
||||||
) {
|
|
||||||
img.classList.add("in-use");
|
|
||||||
|
|
||||||
// Synchronize control center and identity block blinking animations.
|
|
||||||
window
|
|
||||||
.promiseDocumentFlushed(() => {
|
|
||||||
let sharingIconBlink = this._webRTCSharingIcon.getAnimations()[0];
|
|
||||||
let imgBlink = img.getAnimations()[0];
|
|
||||||
return [sharingIconBlink, imgBlink];
|
|
||||||
})
|
|
||||||
.then(([sharingIconBlink, imgBlink]) => {
|
|
||||||
if (sharingIconBlink && imgBlink) {
|
|
||||||
imgBlink.startTime = sharingIconBlink.startTime;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let nameLabel = document.createXULElement("label");
|
|
||||||
nameLabel.setAttribute("flex", "1");
|
|
||||||
nameLabel.setAttribute("class", "identity-popup-permission-label");
|
|
||||||
let label = SitePermissions.getPermissionLabel(idNoSuffix);
|
|
||||||
if (label === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (nowrapLabel) {
|
|
||||||
nameLabel.setAttribute("value", label);
|
|
||||||
nameLabel.setAttribute("tooltiptext", label);
|
|
||||||
nameLabel.setAttribute("crop", "end");
|
|
||||||
} else {
|
|
||||||
nameLabel.textContent = label;
|
|
||||||
}
|
|
||||||
let nameLabelId = "identity-popup-permission-label-" + idNoSuffix;
|
|
||||||
nameLabel.setAttribute("id", nameLabelId);
|
|
||||||
|
|
||||||
let isPolicyPermission = [
|
|
||||||
SitePermissions.SCOPE_POLICY,
|
|
||||||
SitePermissions.SCOPE_GLOBAL,
|
|
||||||
].includes(permission.scope);
|
|
||||||
|
|
||||||
if (
|
|
||||||
(idNoSuffix == "popup" && !isPolicyPermission) ||
|
|
||||||
idNoSuffix == "autoplay-media"
|
|
||||||
) {
|
|
||||||
let menulist = document.createXULElement("menulist");
|
|
||||||
let menupopup = document.createXULElement("menupopup");
|
|
||||||
let block = document.createXULElement("vbox");
|
|
||||||
block.setAttribute("id", "identity-popup-popup-container");
|
|
||||||
block.setAttribute("class", "identity-popup-permission-item-container");
|
|
||||||
menulist.setAttribute("sizetopopup", "none");
|
|
||||||
menulist.setAttribute("id", "identity-popup-popup-menulist");
|
|
||||||
|
|
||||||
for (let state of SitePermissions.getAvailableStates(idNoSuffix)) {
|
|
||||||
let menuitem = document.createXULElement("menuitem");
|
|
||||||
// We need to correctly display the default/unknown state, which has its
|
|
||||||
// own integer value (0) but represents one of the other states.
|
|
||||||
if (state == SitePermissions.getDefault(idNoSuffix)) {
|
|
||||||
menuitem.setAttribute("value", "0");
|
|
||||||
} else {
|
|
||||||
menuitem.setAttribute("value", state);
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem.setAttribute(
|
|
||||||
"label",
|
|
||||||
SitePermissions.getMultichoiceStateLabel(idNoSuffix, state)
|
|
||||||
);
|
|
||||||
menupopup.appendChild(menuitem);
|
|
||||||
}
|
|
||||||
|
|
||||||
menulist.appendChild(menupopup);
|
|
||||||
|
|
||||||
if (permission.state == SitePermissions.getDefault(idNoSuffix)) {
|
|
||||||
menulist.value = "0";
|
|
||||||
} else {
|
|
||||||
menulist.value = permission.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoiding listening to the "select" event on purpose. See Bug 1404262.
|
|
||||||
menulist.addEventListener("command", () => {
|
|
||||||
SitePermissions.setForPrincipal(
|
|
||||||
gBrowser.contentPrincipal,
|
|
||||||
idNoSuffix,
|
|
||||||
menulist.selectedItem.value
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
container.appendChild(img);
|
|
||||||
container.appendChild(nameLabel);
|
|
||||||
container.appendChild(menulist);
|
|
||||||
container.setAttribute("aria-labelledby", nameLabelId);
|
|
||||||
block.appendChild(container);
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
container.appendChild(img);
|
|
||||||
container.appendChild(nameLabel);
|
|
||||||
let labelledBy = nameLabelId;
|
|
||||||
|
|
||||||
if (showStateLabel) {
|
|
||||||
let stateLabel = this._createStateLabel(permission, idNoSuffix);
|
|
||||||
container.appendChild(stateLabel);
|
|
||||||
labelledBy += " " + stateLabel.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
container.setAttribute("aria-labelledby", labelledBy);
|
|
||||||
|
|
||||||
/* We return the permission item here without a remove button if the permission is a
|
|
||||||
SCOPE_POLICY or SCOPE_GLOBAL permission. Policy permissions cannot be
|
|
||||||
removed/changed for the duration of the browser session. */
|
|
||||||
if (isPolicyPermission) {
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isContainer) {
|
|
||||||
let block = document.createXULElement("vbox");
|
|
||||||
block.setAttribute("id", "identity-popup-" + idNoSuffix + "-container");
|
|
||||||
block.setAttribute("class", "identity-popup-permission-item-container");
|
|
||||||
|
|
||||||
if (permClearButton) {
|
|
||||||
let button = this._createPermissionClearButton(permission, block);
|
|
||||||
container.appendChild(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
block.appendChild(container);
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permClearButton) {
|
|
||||||
let button = this._createPermissionClearButton(permission, container);
|
|
||||||
container.appendChild(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
return container;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createStateLabel(aPermission, idNoSuffix) {
|
|
||||||
let label = document.createXULElement("label");
|
|
||||||
label.setAttribute("flex", "1");
|
|
||||||
label.setAttribute("class", "identity-popup-permission-state-label");
|
|
||||||
let labelId = "identity-popup-permission-state-label-" + idNoSuffix;
|
|
||||||
label.setAttribute("id", labelId);
|
|
||||||
let { state, scope } = aPermission;
|
|
||||||
// If the user did not permanently allow this device but it is currently
|
|
||||||
// used, set the variables to display a "temporarily allowed" info.
|
|
||||||
if (state != SitePermissions.ALLOW && aPermission.sharingState) {
|
|
||||||
state = SitePermissions.ALLOW;
|
|
||||||
scope = SitePermissions.SCOPE_REQUEST;
|
|
||||||
}
|
|
||||||
label.textContent = SitePermissions.getCurrentStateLabel(
|
|
||||||
state,
|
|
||||||
idNoSuffix,
|
|
||||||
scope
|
|
||||||
);
|
|
||||||
return label;
|
|
||||||
},
|
|
||||||
|
|
||||||
_removePermPersistentAllow(principal, id) {
|
|
||||||
let perm = SitePermissions.getForPrincipal(principal, id);
|
|
||||||
if (
|
|
||||||
perm.state == SitePermissions.ALLOW &&
|
|
||||||
perm.scope == SitePermissions.SCOPE_PERSISTENT
|
|
||||||
) {
|
|
||||||
SitePermissions.removeFromPrincipal(principal, id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_createPermissionClearButton(
|
|
||||||
aPermission,
|
|
||||||
container,
|
|
||||||
clearCallback = () => {}
|
|
||||||
) {
|
|
||||||
let button = document.createXULElement("button");
|
|
||||||
button.setAttribute("class", "identity-popup-permission-remove-button");
|
|
||||||
let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
|
|
||||||
button.setAttribute("tooltiptext", tooltiptext);
|
|
||||||
button.addEventListener("command", () => {
|
|
||||||
let browser = gBrowser.selectedBrowser;
|
|
||||||
container.remove();
|
|
||||||
if (aPermission.sharingState) {
|
|
||||||
if (aPermission.id === "geo" || aPermission.id === "xr") {
|
|
||||||
let origins = browser.getDevicePermissionOrigins(aPermission.id);
|
|
||||||
for (let origin of origins) {
|
|
||||||
let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
|
|
||||||
origin
|
|
||||||
);
|
|
||||||
this._removePermPersistentAllow(principal, aPermission.id);
|
|
||||||
}
|
|
||||||
origins.clear();
|
|
||||||
} else if (
|
|
||||||
["camera", "microphone", "screen"].includes(aPermission.id)
|
|
||||||
) {
|
|
||||||
let windowId = this._sharingState.webRTC.windowId;
|
|
||||||
if (aPermission.id == "screen") {
|
|
||||||
windowId = "screen:" + windowId;
|
|
||||||
} else {
|
|
||||||
// If we set persistent permissions or the sharing has
|
|
||||||
// started due to existing persistent permissions, we need
|
|
||||||
// to handle removing these even for frames with different hostnames.
|
|
||||||
let origins = browser.getDevicePermissionOrigins("webrtc");
|
|
||||||
for (let origin of origins) {
|
|
||||||
// It's not possible to stop sharing one of camera/microphone
|
|
||||||
// without the other.
|
|
||||||
let principal;
|
|
||||||
for (let id of ["camera", "microphone"]) {
|
|
||||||
if (this._sharingState.webRTC[id]) {
|
|
||||||
if (!principal) {
|
|
||||||
principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
|
|
||||||
origin
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this._removePermPersistentAllow(principal, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let bc = this._sharingState.webRTC.browsingContext;
|
|
||||||
bc.currentWindowGlobal
|
|
||||||
.getActor("WebRTC")
|
|
||||||
.sendAsyncMessage("webrtc:StopSharing", windowId);
|
|
||||||
webrtcUI.forgetActivePermissionsFromBrowser(gBrowser.selectedBrowser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SitePermissions.removeFromPrincipal(
|
|
||||||
gBrowser.contentPrincipal,
|
|
||||||
aPermission.id,
|
|
||||||
browser
|
|
||||||
);
|
|
||||||
|
|
||||||
this._permissionReloadHint.removeAttribute("hidden");
|
|
||||||
PanelView.forNode(
|
|
||||||
this._identityPopupMainView
|
|
||||||
).descriptionHeightWorkaround();
|
|
||||||
|
|
||||||
if (aPermission.id === "geo") {
|
|
||||||
gBrowser.updateBrowserSharing(browser, { geo: false });
|
|
||||||
} else if (aPermission.id === "xr") {
|
|
||||||
gBrowser.updateBrowserSharing(browser, { xr: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
clearCallback();
|
|
||||||
});
|
|
||||||
|
|
||||||
return button;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getGeoLocationLastAccess() {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
let lastAccess = null;
|
|
||||||
ContentPrefService2.getByDomainAndName(
|
|
||||||
gBrowser.currentURI.spec,
|
|
||||||
"permissions.geoLocation.lastAccess",
|
|
||||||
gBrowser.selectedBrowser.loadContext,
|
|
||||||
{
|
|
||||||
handleResult(pref) {
|
|
||||||
lastAccess = pref.value;
|
|
||||||
},
|
|
||||||
handleCompletion() {
|
|
||||||
resolve(lastAccess);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
async _createGeoLocationLastAccessIndicator() {
|
|
||||||
let lastAccessStr = await this._getGeoLocationLastAccess();
|
|
||||||
let geoContainer = document.getElementById("identity-popup-geo-container");
|
|
||||||
|
|
||||||
// Check whether geoContainer still exists.
|
|
||||||
// We are async, the identity popup could have been closed already.
|
|
||||||
// Also check if it is already populated with a time label.
|
|
||||||
// This can happen if we update the permission panel multiple times in a
|
|
||||||
// short timeframe.
|
|
||||||
if (
|
|
||||||
lastAccessStr == null ||
|
|
||||||
!geoContainer ||
|
|
||||||
document.getElementById("geo-access-indicator-item")
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let lastAccess = new Date(lastAccessStr);
|
|
||||||
if (isNaN(lastAccess)) {
|
|
||||||
Cu.reportError("Invalid timestamp for last geolocation access");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let icon = document.createXULElement("image");
|
|
||||||
icon.setAttribute("class", "popup-subitem");
|
|
||||||
|
|
||||||
let indicator = document.createXULElement("hbox");
|
|
||||||
indicator.setAttribute("class", "identity-popup-permission-item");
|
|
||||||
indicator.setAttribute("align", "center");
|
|
||||||
indicator.setAttribute("id", "geo-access-indicator-item");
|
|
||||||
|
|
||||||
let timeFormat = new Services.intl.RelativeTimeFormat(undefined, {});
|
|
||||||
|
|
||||||
let text = document.createXULElement("label");
|
|
||||||
text.setAttribute("flex", "1");
|
|
||||||
text.setAttribute("class", "identity-popup-permission-label");
|
|
||||||
|
|
||||||
text.textContent = gNavigatorBundle.getFormattedString(
|
|
||||||
"geolocationLastAccessIndicatorText",
|
|
||||||
[timeFormat.formatBestUnit(lastAccess)]
|
|
||||||
);
|
|
||||||
|
|
||||||
indicator.appendChild(icon);
|
|
||||||
indicator.appendChild(text);
|
|
||||||
|
|
||||||
geoContainer.appendChild(indicator);
|
|
||||||
},
|
|
||||||
|
|
||||||
_createProtocolHandlerPermissionItem(permission, key) {
|
|
||||||
let container = document.getElementById(
|
|
||||||
"identity-popup-open-protocol-handler-container"
|
|
||||||
);
|
|
||||||
let initialCall;
|
|
||||||
|
|
||||||
if (!container) {
|
|
||||||
// First open-protocol-handler permission, create container.
|
|
||||||
container = this._createPermissionItem({
|
|
||||||
permission,
|
|
||||||
isContainer: true,
|
|
||||||
permClearButton: false,
|
|
||||||
showStateLabel: false,
|
|
||||||
idNoSuffix: "open-protocol-handler",
|
|
||||||
});
|
|
||||||
initialCall = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let icon = document.createXULElement("image");
|
|
||||||
icon.setAttribute("class", "popup-subitem-no-arrow");
|
|
||||||
|
|
||||||
let item = document.createXULElement("hbox");
|
|
||||||
item.setAttribute("class", "identity-popup-permission-item");
|
|
||||||
item.setAttribute("align", "center");
|
|
||||||
|
|
||||||
let text = document.createXULElement("label");
|
|
||||||
text.setAttribute("flex", "1");
|
|
||||||
text.setAttribute("class", "identity-popup-permission-label-subitem");
|
|
||||||
|
|
||||||
text.textContent = gNavigatorBundle.getFormattedString(
|
|
||||||
"openProtocolHandlerPermissionEntryLabel",
|
|
||||||
[key]
|
|
||||||
);
|
|
||||||
|
|
||||||
let stateLabel = this._createStateLabel(
|
|
||||||
permission,
|
|
||||||
"open-protocol-handler"
|
|
||||||
);
|
|
||||||
|
|
||||||
item.appendChild(text);
|
|
||||||
item.appendChild(stateLabel);
|
|
||||||
|
|
||||||
let button = this._createPermissionClearButton(permission, item, () => {
|
|
||||||
// When we're clearing the last open-protocol-handler permission, clean up
|
|
||||||
// the empty container.
|
|
||||||
// (<= 1 because the heading item is also a child of the container)
|
|
||||||
if (container.childElementCount <= 1) {
|
|
||||||
container.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
item.appendChild(button);
|
|
||||||
|
|
||||||
container.appendChild(item);
|
|
||||||
|
|
||||||
// If container already exists in permission list, don't return it again.
|
|
||||||
return initialCall && container;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createBlockedPopupIndicator(aTotalBlockedPopups) {
|
|
||||||
let indicator = document.createXULElement("hbox");
|
|
||||||
indicator.setAttribute("class", "identity-popup-permission-item");
|
|
||||||
indicator.setAttribute("align", "center");
|
|
||||||
indicator.setAttribute("id", "blocked-popup-indicator-item");
|
|
||||||
|
|
||||||
let icon = document.createXULElement("image");
|
|
||||||
icon.setAttribute("class", "popup-subitem");
|
|
||||||
|
|
||||||
let text = document.createXULElement("label", { is: "text-link" });
|
|
||||||
text.setAttribute("flex", "1");
|
|
||||||
text.setAttribute("class", "identity-popup-permission-label");
|
|
||||||
|
|
||||||
let messageBase = gNavigatorBundle.getString(
|
|
||||||
"popupShowBlockedPopupsIndicatorText"
|
|
||||||
);
|
|
||||||
let message = PluralForm.get(aTotalBlockedPopups, messageBase).replace(
|
|
||||||
"#1",
|
|
||||||
aTotalBlockedPopups
|
|
||||||
);
|
|
||||||
text.textContent = message;
|
|
||||||
|
|
||||||
text.addEventListener("click", () => {
|
|
||||||
gBrowser.selectedBrowser.popupBlocker.unblockAllPopups();
|
|
||||||
});
|
|
||||||
|
|
||||||
indicator.appendChild(icon);
|
|
||||||
indicator.appendChild(text);
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById("identity-popup-popup-container")
|
|
||||||
.appendChild(indicator);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,958 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
/* eslint-env mozilla/browser-window */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility object to handle manipulations of the identity permission indicators
|
||||||
|
* in the UI.
|
||||||
|
*/
|
||||||
|
var gPermissionPanel = {
|
||||||
|
_popupInitialized: false,
|
||||||
|
_initializePopup() {
|
||||||
|
if (!this._popupInitialized) {
|
||||||
|
let wrapper = document.getElementById("template-permission-popup");
|
||||||
|
wrapper.replaceWith(wrapper.content);
|
||||||
|
this._popupInitialized = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hidePopup() {
|
||||||
|
if (this._popupInitialized) {
|
||||||
|
PanelMultiView.hidePopup(this._permissionPopup);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// smart getters
|
||||||
|
get _identityPermissionBox() {
|
||||||
|
delete this._identityPermissionBox;
|
||||||
|
return (this._identityPermissionBox = document.getElementById(
|
||||||
|
"identity-permission-box"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _permissionGrantedIcon() {
|
||||||
|
delete this._permissionGrantedIcon;
|
||||||
|
return (this._permissionGrantedIcon = document.getElementById(
|
||||||
|
"permissions-granted-icon"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _permissionPopup() {
|
||||||
|
if (!this._popupInitialized) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
delete this._permissionPopup;
|
||||||
|
return (this._permissionPopup = document.getElementById(
|
||||||
|
"permission-popup"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _permissionPopupMainView() {
|
||||||
|
delete this._permissionPopupPopupMainView;
|
||||||
|
return (this._permissionPopupPopupMainView = document.getElementById(
|
||||||
|
"permission-popup-mainView"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _permissionPopupMainViewHeaderLabel() {
|
||||||
|
delete this._permissionPopupMainViewHeaderLabel;
|
||||||
|
return (this._permissionPopupMainViewHeaderLabel = document.getElementById(
|
||||||
|
"permission-popup-mainView-panel-header-span"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _permissionList() {
|
||||||
|
delete this._permissionList;
|
||||||
|
return (this._permissionList = document.getElementById(
|
||||||
|
"permission-popup-permission-list"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _defaultPermissionAnchor() {
|
||||||
|
delete this._defaultPermissionAnchor;
|
||||||
|
return (this._defaultPermissionAnchor = document.getElementById(
|
||||||
|
"permission-popup-permission-list-default-anchor"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _permissionReloadHint() {
|
||||||
|
delete this._permissionReloadHint;
|
||||||
|
return (this._permissionReloadHint = document.getElementById(
|
||||||
|
"permission-popup-permission-reload-hint"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
get _permissionAnchors() {
|
||||||
|
delete this._permissionAnchors;
|
||||||
|
let permissionAnchors = {};
|
||||||
|
for (let anchor of document.getElementById("blocked-permissions-container")
|
||||||
|
.children) {
|
||||||
|
permissionAnchors[anchor.getAttribute("data-permission-id")] = anchor;
|
||||||
|
}
|
||||||
|
return (this._permissionAnchors = permissionAnchors);
|
||||||
|
},
|
||||||
|
|
||||||
|
get _geoSharingIcon() {
|
||||||
|
delete this._geoSharingIcon;
|
||||||
|
return (this._geoSharingIcon = document.getElementById("geo-sharing-icon"));
|
||||||
|
},
|
||||||
|
|
||||||
|
get _xrSharingIcon() {
|
||||||
|
delete this._xrSharingIcon;
|
||||||
|
return (this._xrSharingIcon = document.getElementById("xr-sharing-icon"));
|
||||||
|
},
|
||||||
|
|
||||||
|
get _webRTCSharingIcon() {
|
||||||
|
delete this._webRTCSharingIcon;
|
||||||
|
return (this._webRTCSharingIcon = document.getElementById(
|
||||||
|
"webrtc-sharing-icon"
|
||||||
|
));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the contents of the permission popup. This includes the headline
|
||||||
|
* and the list of permissions.
|
||||||
|
*/
|
||||||
|
_refreshPermissionPopup() {
|
||||||
|
let host = gIdentityHandler.getHostForDisplay();
|
||||||
|
|
||||||
|
// Update header label
|
||||||
|
this._permissionPopupMainViewHeaderLabel.textContent = gNavigatorBundle.getFormattedString(
|
||||||
|
"permissions.header",
|
||||||
|
[host]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Refresh the permission list
|
||||||
|
this.updateSitePermissions();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by gIdentityHandler to hide permission icons for invalid proxy
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
|
hidePermissionIcons() {
|
||||||
|
this._identityPermissionBox.removeAttribute("hasGrantedPermissions");
|
||||||
|
this._identityPermissionBox.removeAttribute("hasPermissionIcon");
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the permissions icons in the identity block.
|
||||||
|
* We show icons for blocked permissions / popups.
|
||||||
|
*/
|
||||||
|
refreshPermissionIcons() {
|
||||||
|
let permissionAnchors = this._permissionAnchors;
|
||||||
|
|
||||||
|
// hide all permission icons
|
||||||
|
for (let icon of Object.values(permissionAnchors)) {
|
||||||
|
icon.removeAttribute("showing");
|
||||||
|
}
|
||||||
|
|
||||||
|
// keeps track if we should show an indicator that there are active permissions
|
||||||
|
let hasGrantedPermissions = false;
|
||||||
|
let hasPermissionIcon = false;
|
||||||
|
|
||||||
|
// show permission icons
|
||||||
|
let permissions = SitePermissions.getAllForBrowser(
|
||||||
|
gBrowser.selectedBrowser
|
||||||
|
);
|
||||||
|
for (let permission of permissions) {
|
||||||
|
if (
|
||||||
|
permission.state == SitePermissions.BLOCK ||
|
||||||
|
permission.state == SitePermissions.AUTOPLAY_BLOCKED_ALL
|
||||||
|
) {
|
||||||
|
let icon = permissionAnchors[permission.id];
|
||||||
|
if (icon) {
|
||||||
|
icon.setAttribute("showing", "true");
|
||||||
|
hasPermissionIcon = true;
|
||||||
|
}
|
||||||
|
} else if (permission.state != SitePermissions.UNKNOWN) {
|
||||||
|
hasGrantedPermissions = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show blocked popup icon in the identity-box if popups are blocked
|
||||||
|
// irrespective of popup permission capability value.
|
||||||
|
if (gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount()) {
|
||||||
|
let icon = permissionAnchors.popup;
|
||||||
|
icon.setAttribute("showing", "true");
|
||||||
|
hasPermissionIcon = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._identityPermissionBox.toggleAttribute(
|
||||||
|
"hasGrantedPermissions",
|
||||||
|
hasGrantedPermissions
|
||||||
|
);
|
||||||
|
this._identityPermissionBox.toggleAttribute(
|
||||||
|
"hasPermissionIcon",
|
||||||
|
hasPermissionIcon
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the permission popup.
|
||||||
|
* @param {Event} event - Event which caused the popup to show.
|
||||||
|
*/
|
||||||
|
_openPopup(event) {
|
||||||
|
// Make the popup available.
|
||||||
|
this._initializePopup();
|
||||||
|
|
||||||
|
// Remove the reload hint that we show after a user has cleared a permission.
|
||||||
|
this._permissionReloadHint.setAttribute("hidden", "true");
|
||||||
|
|
||||||
|
// Update the popup strings
|
||||||
|
this._refreshPermissionPopup();
|
||||||
|
|
||||||
|
// Add the "open" attribute to the button in the identity box for styling
|
||||||
|
this._identityPermissionBox.setAttribute("open", "true");
|
||||||
|
|
||||||
|
// Check the panel state of other panels. Hide them if needed.
|
||||||
|
let openPanels = Array.from(document.querySelectorAll("panel[openpanel]"));
|
||||||
|
for (let panel of openPanels) {
|
||||||
|
PanelMultiView.hidePopup(panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now open the popup, anchored off the primary chrome element
|
||||||
|
PanelMultiView.openPopup(
|
||||||
|
this._permissionPopup,
|
||||||
|
this._identityPermissionBox,
|
||||||
|
{
|
||||||
|
position: "bottomcenter topleft",
|
||||||
|
triggerEvent: event,
|
||||||
|
}
|
||||||
|
).catch(Cu.reportError);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update identity permission indicators based on sharing state of the
|
||||||
|
* selected tab. This should be called externally whenever the sharing state
|
||||||
|
* of the selected tab changes.
|
||||||
|
*/
|
||||||
|
updateSharingIndicator() {
|
||||||
|
let tab = gBrowser.selectedTab;
|
||||||
|
this._sharingState = tab._sharingState;
|
||||||
|
|
||||||
|
this._webRTCSharingIcon.removeAttribute("paused");
|
||||||
|
this._webRTCSharingIcon.removeAttribute("sharing");
|
||||||
|
this._geoSharingIcon.removeAttribute("sharing");
|
||||||
|
this._xrSharingIcon.removeAttribute("sharing");
|
||||||
|
|
||||||
|
let hasSharingIcon = false;
|
||||||
|
|
||||||
|
if (this._sharingState) {
|
||||||
|
if (this._sharingState.webRTC?.sharing) {
|
||||||
|
this._webRTCSharingIcon.setAttribute(
|
||||||
|
"sharing",
|
||||||
|
this._sharingState.webRTC.sharing
|
||||||
|
);
|
||||||
|
hasSharingIcon = true;
|
||||||
|
|
||||||
|
if (this._sharingState.webRTC?.paused) {
|
||||||
|
this._webRTCSharingIcon.setAttribute("paused", "true");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this._sharingState.geo) {
|
||||||
|
this._geoSharingIcon.setAttribute("sharing", this._sharingState.geo);
|
||||||
|
hasSharingIcon = true;
|
||||||
|
}
|
||||||
|
if (this._sharingState.xr) {
|
||||||
|
this._xrSharingIcon.setAttribute("sharing", this._sharingState.xr);
|
||||||
|
hasSharingIcon = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._identityPermissionBox.toggleAttribute(
|
||||||
|
"hasSharingIcon",
|
||||||
|
hasSharingIcon
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this._popupInitialized && this._permissionPopup.state != "closed") {
|
||||||
|
this.updateSitePermissions();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Click handler for the permission-box element in primary chrome.
|
||||||
|
*/
|
||||||
|
handleIdentityButtonEvent(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
if (
|
||||||
|
(event.type == "click" && event.button != 0) ||
|
||||||
|
(event.type == "keypress" &&
|
||||||
|
event.charCode != KeyEvent.DOM_VK_SPACE &&
|
||||||
|
event.keyCode != KeyEvent.DOM_VK_RETURN)
|
||||||
|
) {
|
||||||
|
return; // Left click, space or enter only
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't allow left click, space or enter if the location has been modified,
|
||||||
|
// so long as we're not sharing any devices.
|
||||||
|
// If we are sharing a device, the identity block is prevented by CSS from
|
||||||
|
// being focused (and therefore, interacted with) by the user. However, we
|
||||||
|
// want to allow opening the identity popup from the device control menu,
|
||||||
|
// which calls click() on the identity button, so we don't return early.
|
||||||
|
if (
|
||||||
|
!this._sharingState &&
|
||||||
|
gURLBar.getAttribute("pageproxystate") != "valid"
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are in DOM fullscreen, exit it before showing the permission popup
|
||||||
|
// (see bug 1557041)
|
||||||
|
if (document.fullscreen) {
|
||||||
|
// Open the identity popup after DOM fullscreen exit
|
||||||
|
// We need to wait for the exit event and after that wait for the fullscreen exit transition to complete
|
||||||
|
// If we call _openPopup before the fullscreen transition ends it can get cancelled
|
||||||
|
// Only waiting for painted is not sufficient because we could still be in the fullscreen enter transition.
|
||||||
|
this._exitedEventReceived = false;
|
||||||
|
this._event = event;
|
||||||
|
Services.obs.addObserver(this, "fullscreen-painted");
|
||||||
|
window.addEventListener(
|
||||||
|
"MozDOMFullscreen:Exited",
|
||||||
|
() => {
|
||||||
|
this._exitedEventReceived = true;
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
|
document.exitFullscreen();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._openPopup(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
onPopupShown(event) {
|
||||||
|
if (event.target == this._permissionPopup) {
|
||||||
|
window.addEventListener("focus", this, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onPopupHidden(event) {
|
||||||
|
if (event.target == this._permissionPopup) {
|
||||||
|
window.removeEventListener("focus", this, true);
|
||||||
|
this._identityPermissionBox.removeAttribute("open");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEvent(event) {
|
||||||
|
let elem = document.activeElement;
|
||||||
|
let position = elem.compareDocumentPosition(this._permissionPopup);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
position &
|
||||||
|
(Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_CONTAINED_BY)
|
||||||
|
) &&
|
||||||
|
!this._permissionPopup.hasAttribute("noautohide")
|
||||||
|
) {
|
||||||
|
// Hide the panel when focusing an element that is
|
||||||
|
// neither an ancestor nor descendant unless the panel has
|
||||||
|
// @noautohide (e.g. for a tour).
|
||||||
|
PanelMultiView.hidePopup(this._permissionPopup);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
observe(subject, topic, data) {
|
||||||
|
switch (topic) {
|
||||||
|
case "fullscreen-painted": {
|
||||||
|
if (subject != window || !this._exitedEventReceived) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Services.obs.removeObserver(this, "fullscreen-painted");
|
||||||
|
this._openPopup(this._event);
|
||||||
|
delete this._event;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onLocationChange() {
|
||||||
|
if (this._popupInitialized && this._permissionPopup.state != "closed") {
|
||||||
|
this._permissionReloadHint.setAttribute("hidden", "true");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the permission list in the permissions popup.
|
||||||
|
*/
|
||||||
|
updateSitePermissions() {
|
||||||
|
let permissionItemSelector = [
|
||||||
|
".permission-popup-permission-item, .permission-popup-permission-item-container",
|
||||||
|
];
|
||||||
|
this._permissionList
|
||||||
|
.querySelectorAll(permissionItemSelector)
|
||||||
|
.forEach(e => e.remove());
|
||||||
|
|
||||||
|
let permissions = SitePermissions.getAllPermissionDetailsForBrowser(
|
||||||
|
gBrowser.selectedBrowser
|
||||||
|
);
|
||||||
|
|
||||||
|
this._sharingState = gBrowser.selectedTab._sharingState;
|
||||||
|
|
||||||
|
if (this._sharingState?.geo) {
|
||||||
|
let geoPermission = permissions.find(perm => perm.id === "geo");
|
||||||
|
if (geoPermission) {
|
||||||
|
geoPermission.sharingState = true;
|
||||||
|
} else {
|
||||||
|
permissions.push({
|
||||||
|
id: "geo",
|
||||||
|
state: SitePermissions.ALLOW,
|
||||||
|
scope: SitePermissions.SCOPE_REQUEST,
|
||||||
|
sharingState: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._sharingState?.xr) {
|
||||||
|
let xrPermission = permissions.find(perm => perm.id === "xr");
|
||||||
|
if (xrPermission) {
|
||||||
|
xrPermission.sharingState = true;
|
||||||
|
} else {
|
||||||
|
permissions.push({
|
||||||
|
id: "xr",
|
||||||
|
state: SitePermissions.ALLOW,
|
||||||
|
scope: SitePermissions.SCOPE_REQUEST,
|
||||||
|
sharingState: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._sharingState?.webRTC) {
|
||||||
|
let webrtcState = this._sharingState.webRTC;
|
||||||
|
// If WebRTC device or screen permissions are in use, we need to find
|
||||||
|
// the associated permission item to set the sharingState field.
|
||||||
|
for (let id of ["camera", "microphone", "screen"]) {
|
||||||
|
if (webrtcState[id]) {
|
||||||
|
let found = false;
|
||||||
|
for (let permission of permissions) {
|
||||||
|
if (permission.id != id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
permission.sharingState = webrtcState[id];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
// If the permission item we were looking for doesn't exist,
|
||||||
|
// the user has temporarily allowed sharing and we need to add
|
||||||
|
// an item in the permissions array to reflect this.
|
||||||
|
permissions.push({
|
||||||
|
id,
|
||||||
|
state: SitePermissions.ALLOW,
|
||||||
|
scope: SitePermissions.SCOPE_REQUEST,
|
||||||
|
sharingState: webrtcState[id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let totalBlockedPopups = gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount();
|
||||||
|
let hasBlockedPopupIndicator = false;
|
||||||
|
for (let permission of permissions) {
|
||||||
|
let [id, key] = permission.id.split(SitePermissions.PERM_KEY_DELIMITER);
|
||||||
|
|
||||||
|
if (id == "storage-access") {
|
||||||
|
// Ignore storage access permissions here, they are made visible inside
|
||||||
|
// the Content Blocking UI.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let item;
|
||||||
|
let anchor =
|
||||||
|
this._permissionList.querySelector(`[anchorfor="${id}"]`) ||
|
||||||
|
this._defaultPermissionAnchor;
|
||||||
|
|
||||||
|
if (id == "open-protocol-handler") {
|
||||||
|
let permContainer = this._createProtocolHandlerPermissionItem(
|
||||||
|
permission,
|
||||||
|
key
|
||||||
|
);
|
||||||
|
if (permContainer) {
|
||||||
|
anchor.appendChild(permContainer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item = this._createPermissionItem({
|
||||||
|
permission,
|
||||||
|
isContainer: id == "geo" || id == "xr",
|
||||||
|
nowrapLabel: id == "3rdPartyStorage",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
anchor.appendChild(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == "popup" && totalBlockedPopups) {
|
||||||
|
this._createBlockedPopupIndicator(totalBlockedPopups);
|
||||||
|
hasBlockedPopupIndicator = true;
|
||||||
|
} else if (id == "geo" && permission.state === SitePermissions.ALLOW) {
|
||||||
|
this._createGeoLocationLastAccessIndicator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalBlockedPopups && !hasBlockedPopupIndicator) {
|
||||||
|
let permission = {
|
||||||
|
id: "popup",
|
||||||
|
state: SitePermissions.getDefault("popup"),
|
||||||
|
scope: SitePermissions.SCOPE_PERSISTENT,
|
||||||
|
};
|
||||||
|
let item = this._createPermissionItem({ permission });
|
||||||
|
this._defaultPermissionAnchor.appendChild(item);
|
||||||
|
this._createBlockedPopupIndicator(totalBlockedPopups);
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelView.forNode(
|
||||||
|
this._permissionPopupMainView
|
||||||
|
).descriptionHeightWorkaround();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a permission item based on the supplied options and returns it.
|
||||||
|
* It is up to the caller to actually insert the element somewhere.
|
||||||
|
*
|
||||||
|
* @param permission - An object containing information representing the
|
||||||
|
* permission, typically obtained via SitePermissions.jsm
|
||||||
|
* @param isContainer - If true, the permission item will be added to a vbox
|
||||||
|
* and the vbox will be returned.
|
||||||
|
* @param permClearButton - Whether to show an "x" button to clear the permission
|
||||||
|
* @param showStateLabel - Whether to show a label indicating the current status
|
||||||
|
* of the permission e.g. "Temporary Allowed"
|
||||||
|
* @param idNoSuffix - Some permission types have additional information suffixed
|
||||||
|
* to the ID - callers can pass the unsuffixed ID via this
|
||||||
|
* parameter to indicate the permission type manually.
|
||||||
|
* @param nowrapLabel - Whether to prevent the permission item's label from
|
||||||
|
* wrapping its text content. This allows styling text-overflow
|
||||||
|
* and is useful for e.g. 3rdPartyStorage permissions whose
|
||||||
|
* labels are origins - which could be of any length.
|
||||||
|
*/
|
||||||
|
_createPermissionItem({
|
||||||
|
permission,
|
||||||
|
isContainer = false,
|
||||||
|
permClearButton = true,
|
||||||
|
showStateLabel = true,
|
||||||
|
idNoSuffix = permission.id,
|
||||||
|
nowrapLabel = false,
|
||||||
|
}) {
|
||||||
|
let container = document.createXULElement("hbox");
|
||||||
|
container.setAttribute("class", "permission-popup-permission-item");
|
||||||
|
container.setAttribute("align", "center");
|
||||||
|
container.setAttribute("role", "group");
|
||||||
|
|
||||||
|
let img = document.createXULElement("image");
|
||||||
|
img.classList.add("permission-popup-permission-icon", idNoSuffix + "-icon");
|
||||||
|
if (
|
||||||
|
permission.state == SitePermissions.BLOCK ||
|
||||||
|
permission.state == SitePermissions.AUTOPLAY_BLOCKED_ALL
|
||||||
|
) {
|
||||||
|
img.classList.add("blocked-permission-icon");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
permission.sharingState ==
|
||||||
|
Ci.nsIMediaManagerService.STATE_CAPTURE_ENABLED ||
|
||||||
|
(idNoSuffix == "screen" &&
|
||||||
|
permission.sharingState &&
|
||||||
|
!permission.sharingState.includes("Paused"))
|
||||||
|
) {
|
||||||
|
img.classList.add("in-use");
|
||||||
|
|
||||||
|
// Synchronize permission panel and identity block blinking animations.
|
||||||
|
window
|
||||||
|
.promiseDocumentFlushed(() => {
|
||||||
|
let sharingIconBlink = this._webRTCSharingIcon.getAnimations()[0];
|
||||||
|
let imgBlink = img.getAnimations()[0];
|
||||||
|
return [sharingIconBlink, imgBlink];
|
||||||
|
})
|
||||||
|
.then(([sharingIconBlink, imgBlink]) => {
|
||||||
|
if (sharingIconBlink && imgBlink) {
|
||||||
|
imgBlink.startTime = sharingIconBlink.startTime;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let nameLabel = document.createXULElement("label");
|
||||||
|
nameLabel.setAttribute("flex", "1");
|
||||||
|
nameLabel.setAttribute("class", "permission-popup-permission-label");
|
||||||
|
let label = SitePermissions.getPermissionLabel(idNoSuffix);
|
||||||
|
if (label === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (nowrapLabel) {
|
||||||
|
nameLabel.setAttribute("value", label);
|
||||||
|
nameLabel.setAttribute("tooltiptext", label);
|
||||||
|
nameLabel.setAttribute("crop", "end");
|
||||||
|
} else {
|
||||||
|
nameLabel.textContent = label;
|
||||||
|
}
|
||||||
|
let nameLabelId = "permission-popup-permission-label-" + idNoSuffix;
|
||||||
|
nameLabel.setAttribute("id", nameLabelId);
|
||||||
|
|
||||||
|
let isPolicyPermission = [
|
||||||
|
SitePermissions.SCOPE_POLICY,
|
||||||
|
SitePermissions.SCOPE_GLOBAL,
|
||||||
|
].includes(permission.scope);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(idNoSuffix == "popup" && !isPolicyPermission) ||
|
||||||
|
idNoSuffix == "autoplay-media"
|
||||||
|
) {
|
||||||
|
let menulist = document.createXULElement("menulist");
|
||||||
|
let menupopup = document.createXULElement("menupopup");
|
||||||
|
let block = document.createXULElement("vbox");
|
||||||
|
block.setAttribute("id", "permission-popup-container");
|
||||||
|
block.setAttribute("class", "permission-popup-permission-item-container");
|
||||||
|
menulist.setAttribute("sizetopopup", "none");
|
||||||
|
menulist.setAttribute("id", "permission-popup-menulist");
|
||||||
|
|
||||||
|
for (let state of SitePermissions.getAvailableStates(idNoSuffix)) {
|
||||||
|
let menuitem = document.createXULElement("menuitem");
|
||||||
|
// We need to correctly display the default/unknown state, which has its
|
||||||
|
// own integer value (0) but represents one of the other states.
|
||||||
|
if (state == SitePermissions.getDefault(idNoSuffix)) {
|
||||||
|
menuitem.setAttribute("value", "0");
|
||||||
|
} else {
|
||||||
|
menuitem.setAttribute("value", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
menuitem.setAttribute(
|
||||||
|
"label",
|
||||||
|
SitePermissions.getMultichoiceStateLabel(idNoSuffix, state)
|
||||||
|
);
|
||||||
|
menupopup.appendChild(menuitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
menulist.appendChild(menupopup);
|
||||||
|
|
||||||
|
if (permission.state == SitePermissions.getDefault(idNoSuffix)) {
|
||||||
|
menulist.value = "0";
|
||||||
|
} else {
|
||||||
|
menulist.value = permission.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoiding listening to the "select" event on purpose. See Bug 1404262.
|
||||||
|
menulist.addEventListener("command", () => {
|
||||||
|
SitePermissions.setForPrincipal(
|
||||||
|
gBrowser.contentPrincipal,
|
||||||
|
idNoSuffix,
|
||||||
|
menulist.selectedItem.value
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(img);
|
||||||
|
container.appendChild(nameLabel);
|
||||||
|
container.appendChild(menulist);
|
||||||
|
container.setAttribute("aria-labelledby", nameLabelId);
|
||||||
|
block.appendChild(container);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.appendChild(img);
|
||||||
|
container.appendChild(nameLabel);
|
||||||
|
let labelledBy = nameLabelId;
|
||||||
|
|
||||||
|
if (showStateLabel) {
|
||||||
|
let stateLabel = this._createStateLabel(permission, idNoSuffix);
|
||||||
|
container.appendChild(stateLabel);
|
||||||
|
labelledBy += " " + stateLabel.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.setAttribute("aria-labelledby", labelledBy);
|
||||||
|
|
||||||
|
/* We return the permission item here without a remove button if the permission is a
|
||||||
|
SCOPE_POLICY or SCOPE_GLOBAL permission. Policy permissions cannot be
|
||||||
|
removed/changed for the duration of the browser session. */
|
||||||
|
if (isPolicyPermission) {
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isContainer) {
|
||||||
|
let block = document.createXULElement("vbox");
|
||||||
|
block.setAttribute("id", "permission-popup-" + idNoSuffix + "-container");
|
||||||
|
block.setAttribute("class", "permission-popup-permission-item-container");
|
||||||
|
|
||||||
|
if (permClearButton) {
|
||||||
|
let button = this._createPermissionClearButton(permission, block);
|
||||||
|
container.appendChild(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
block.appendChild(container);
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permClearButton) {
|
||||||
|
let button = this._createPermissionClearButton(permission, container);
|
||||||
|
container.appendChild(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
|
||||||
|
_createStateLabel(aPermission, idNoSuffix) {
|
||||||
|
let label = document.createXULElement("label");
|
||||||
|
label.setAttribute("flex", "1");
|
||||||
|
label.setAttribute("class", "permission-popup-permission-state-label");
|
||||||
|
let labelId = "permission-popup-permission-state-label-" + idNoSuffix;
|
||||||
|
label.setAttribute("id", labelId);
|
||||||
|
let { state, scope } = aPermission;
|
||||||
|
// If the user did not permanently allow this device but it is currently
|
||||||
|
// used, set the variables to display a "temporarily allowed" info.
|
||||||
|
if (state != SitePermissions.ALLOW && aPermission.sharingState) {
|
||||||
|
state = SitePermissions.ALLOW;
|
||||||
|
scope = SitePermissions.SCOPE_REQUEST;
|
||||||
|
}
|
||||||
|
label.textContent = SitePermissions.getCurrentStateLabel(
|
||||||
|
state,
|
||||||
|
idNoSuffix,
|
||||||
|
scope
|
||||||
|
);
|
||||||
|
return label;
|
||||||
|
},
|
||||||
|
|
||||||
|
_removePermPersistentAllow(principal, id) {
|
||||||
|
let perm = SitePermissions.getForPrincipal(principal, id);
|
||||||
|
if (
|
||||||
|
perm.state == SitePermissions.ALLOW &&
|
||||||
|
perm.scope == SitePermissions.SCOPE_PERSISTENT
|
||||||
|
) {
|
||||||
|
SitePermissions.removeFromPrincipal(principal, id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_createPermissionClearButton(
|
||||||
|
aPermission,
|
||||||
|
container,
|
||||||
|
clearCallback = () => {}
|
||||||
|
) {
|
||||||
|
let button = document.createXULElement("button");
|
||||||
|
button.setAttribute("class", "permission-popup-permission-remove-button");
|
||||||
|
let tooltiptext = gNavigatorBundle.getString("permissions.remove.tooltip");
|
||||||
|
button.setAttribute("tooltiptext", tooltiptext);
|
||||||
|
button.addEventListener("command", () => {
|
||||||
|
let browser = gBrowser.selectedBrowser;
|
||||||
|
container.remove();
|
||||||
|
if (aPermission.sharingState) {
|
||||||
|
if (aPermission.id === "geo" || aPermission.id === "xr") {
|
||||||
|
let origins = browser.getDevicePermissionOrigins(aPermission.id);
|
||||||
|
for (let origin of origins) {
|
||||||
|
let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
|
||||||
|
origin
|
||||||
|
);
|
||||||
|
this._removePermPersistentAllow(principal, aPermission.id);
|
||||||
|
}
|
||||||
|
origins.clear();
|
||||||
|
} else if (
|
||||||
|
["camera", "microphone", "screen"].includes(aPermission.id)
|
||||||
|
) {
|
||||||
|
let windowId = this._sharingState.webRTC.windowId;
|
||||||
|
if (aPermission.id == "screen") {
|
||||||
|
windowId = "screen:" + windowId;
|
||||||
|
} else {
|
||||||
|
// If we set persistent permissions or the sharing has
|
||||||
|
// started due to existing persistent permissions, we need
|
||||||
|
// to handle removing these even for frames with different hostnames.
|
||||||
|
let origins = browser.getDevicePermissionOrigins("webrtc");
|
||||||
|
for (let origin of origins) {
|
||||||
|
// It's not possible to stop sharing one of camera/microphone
|
||||||
|
// without the other.
|
||||||
|
let principal;
|
||||||
|
for (let id of ["camera", "microphone"]) {
|
||||||
|
if (this._sharingState.webRTC[id]) {
|
||||||
|
if (!principal) {
|
||||||
|
principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin(
|
||||||
|
origin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this._removePermPersistentAllow(principal, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let bc = this._sharingState.webRTC.browsingContext;
|
||||||
|
bc.currentWindowGlobal
|
||||||
|
.getActor("WebRTC")
|
||||||
|
.sendAsyncMessage("webrtc:StopSharing", windowId);
|
||||||
|
webrtcUI.forgetActivePermissionsFromBrowser(gBrowser.selectedBrowser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SitePermissions.removeFromPrincipal(
|
||||||
|
gBrowser.contentPrincipal,
|
||||||
|
aPermission.id,
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
|
||||||
|
this._permissionReloadHint.removeAttribute("hidden");
|
||||||
|
PanelView.forNode(
|
||||||
|
this._permissionPopupMainView
|
||||||
|
).descriptionHeightWorkaround();
|
||||||
|
|
||||||
|
if (aPermission.id === "geo") {
|
||||||
|
gBrowser.updateBrowserSharing(browser, { geo: false });
|
||||||
|
} else if (aPermission.id === "xr") {
|
||||||
|
gBrowser.updateBrowserSharing(browser, { xr: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCallback();
|
||||||
|
});
|
||||||
|
|
||||||
|
return button;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getGeoLocationLastAccess() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
let lastAccess = null;
|
||||||
|
ContentPrefService2.getByDomainAndName(
|
||||||
|
gBrowser.currentURI.spec,
|
||||||
|
"permissions.geoLocation.lastAccess",
|
||||||
|
gBrowser.selectedBrowser.loadContext,
|
||||||
|
{
|
||||||
|
handleResult(pref) {
|
||||||
|
lastAccess = pref.value;
|
||||||
|
},
|
||||||
|
handleCompletion() {
|
||||||
|
resolve(lastAccess);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async _createGeoLocationLastAccessIndicator() {
|
||||||
|
let lastAccessStr = await this._getGeoLocationLastAccess();
|
||||||
|
let geoContainer = document.getElementById(
|
||||||
|
"permission-popup-geo-container"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check whether geoContainer still exists.
|
||||||
|
// We are async, the identity popup could have been closed already.
|
||||||
|
// Also check if it is already populated with a time label.
|
||||||
|
// This can happen if we update the permission panel multiple times in a
|
||||||
|
// short timeframe.
|
||||||
|
if (
|
||||||
|
lastAccessStr == null ||
|
||||||
|
!geoContainer ||
|
||||||
|
document.getElementById("geo-access-indicator-item")
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let lastAccess = new Date(lastAccessStr);
|
||||||
|
if (isNaN(lastAccess)) {
|
||||||
|
Cu.reportError("Invalid timestamp for last geolocation access");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon = document.createXULElement("image");
|
||||||
|
icon.setAttribute("class", "popup-subitem");
|
||||||
|
|
||||||
|
let indicator = document.createXULElement("hbox");
|
||||||
|
indicator.setAttribute("class", "permission-popup-permission-item");
|
||||||
|
indicator.setAttribute("align", "center");
|
||||||
|
indicator.setAttribute("id", "geo-access-indicator-item");
|
||||||
|
|
||||||
|
let timeFormat = new Services.intl.RelativeTimeFormat(undefined, {});
|
||||||
|
|
||||||
|
let text = document.createXULElement("label");
|
||||||
|
text.setAttribute("flex", "1");
|
||||||
|
text.setAttribute("class", "permission-popup-permission-label");
|
||||||
|
|
||||||
|
text.textContent = gNavigatorBundle.getFormattedString(
|
||||||
|
"geolocationLastAccessIndicatorText",
|
||||||
|
[timeFormat.formatBestUnit(lastAccess)]
|
||||||
|
);
|
||||||
|
|
||||||
|
indicator.appendChild(icon);
|
||||||
|
indicator.appendChild(text);
|
||||||
|
|
||||||
|
geoContainer.appendChild(indicator);
|
||||||
|
},
|
||||||
|
|
||||||
|
_createProtocolHandlerPermissionItem(permission, key) {
|
||||||
|
let container = document.getElementById(
|
||||||
|
"permission-popup-open-protocol-handler-container"
|
||||||
|
);
|
||||||
|
let initialCall;
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
// First open-protocol-handler permission, create container.
|
||||||
|
container = this._createPermissionItem({
|
||||||
|
permission,
|
||||||
|
isContainer: true,
|
||||||
|
permClearButton: false,
|
||||||
|
showStateLabel: false,
|
||||||
|
idNoSuffix: "open-protocol-handler",
|
||||||
|
});
|
||||||
|
initialCall = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon = document.createXULElement("image");
|
||||||
|
icon.setAttribute("class", "popup-subitem-no-arrow");
|
||||||
|
|
||||||
|
let item = document.createXULElement("hbox");
|
||||||
|
item.setAttribute("class", "permission-popup-permission-item");
|
||||||
|
item.setAttribute("align", "center");
|
||||||
|
|
||||||
|
let text = document.createXULElement("label");
|
||||||
|
text.setAttribute("flex", "1");
|
||||||
|
text.setAttribute("class", "permission-popup-permission-label-subitem");
|
||||||
|
|
||||||
|
text.textContent = gNavigatorBundle.getFormattedString(
|
||||||
|
"openProtocolHandlerPermissionEntryLabel",
|
||||||
|
[key]
|
||||||
|
);
|
||||||
|
|
||||||
|
let stateLabel = this._createStateLabel(
|
||||||
|
permission,
|
||||||
|
"open-protocol-handler"
|
||||||
|
);
|
||||||
|
|
||||||
|
item.appendChild(text);
|
||||||
|
item.appendChild(stateLabel);
|
||||||
|
|
||||||
|
let button = this._createPermissionClearButton(permission, item, () => {
|
||||||
|
// When we're clearing the last open-protocol-handler permission, clean up
|
||||||
|
// the empty container.
|
||||||
|
// (<= 1 because the heading item is also a child of the container)
|
||||||
|
if (container.childElementCount <= 1) {
|
||||||
|
container.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item.appendChild(button);
|
||||||
|
|
||||||
|
container.appendChild(item);
|
||||||
|
|
||||||
|
// If container already exists in permission list, don't return it again.
|
||||||
|
return initialCall && container;
|
||||||
|
},
|
||||||
|
|
||||||
|
_createBlockedPopupIndicator(aTotalBlockedPopups) {
|
||||||
|
let indicator = document.createXULElement("hbox");
|
||||||
|
indicator.setAttribute("class", "permission-popup-permission-item");
|
||||||
|
indicator.setAttribute("align", "center");
|
||||||
|
indicator.setAttribute("id", "blocked-popup-indicator-item");
|
||||||
|
|
||||||
|
let icon = document.createXULElement("image");
|
||||||
|
icon.setAttribute("class", "popup-subitem");
|
||||||
|
|
||||||
|
let text = document.createXULElement("label", { is: "text-link" });
|
||||||
|
text.setAttribute("flex", "1");
|
||||||
|
text.setAttribute("class", "permission-popup-permission-label");
|
||||||
|
|
||||||
|
let messageBase = gNavigatorBundle.getString(
|
||||||
|
"popupShowBlockedPopupsIndicatorText"
|
||||||
|
);
|
||||||
|
let message = PluralForm.get(aTotalBlockedPopups, messageBase).replace(
|
||||||
|
"#1",
|
||||||
|
aTotalBlockedPopups
|
||||||
|
);
|
||||||
|
text.textContent = message;
|
||||||
|
|
||||||
|
text.addEventListener("click", () => {
|
||||||
|
gBrowser.selectedBrowser.popupBlocker.unblockAllPopups();
|
||||||
|
});
|
||||||
|
|
||||||
|
indicator.appendChild(icon);
|
||||||
|
indicator.appendChild(text);
|
||||||
|
|
||||||
|
document
|
||||||
|
.getElementById("permission-popup-container")
|
||||||
|
.appendChild(indicator);
|
||||||
|
},
|
||||||
|
};
|
|
@ -999,7 +999,7 @@ var ThirdPartyCookies = {
|
||||||
}
|
}
|
||||||
|
|
||||||
let removeException = document.createXULElement("button");
|
let removeException = document.createXULElement("button");
|
||||||
removeException.className = "identity-popup-permission-remove-button";
|
removeException.className = "permission-popup-permission-remove-button";
|
||||||
removeException.tooltipText = gNavigatorBundle.getFormattedString(
|
removeException.tooltipText = gNavigatorBundle.getFormattedString(
|
||||||
"contentBlocking.cookiesView.removeButton.tooltip",
|
"contentBlocking.cookiesView.removeButton.tooltip",
|
||||||
[origin]
|
[origin]
|
||||||
|
|
|
@ -738,7 +738,7 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
||||||
min-width: 280px;
|
min-width: 280px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box {
|
#identity-icon-box {
|
||||||
max-width: calc(30px + 10em);
|
max-width: calc(30px + 10em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,7 +752,7 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
||||||
:root[customizing] #urlbar-container {
|
:root[customizing] #urlbar-container {
|
||||||
min-width: 245px;
|
min-width: 245px;
|
||||||
}
|
}
|
||||||
#identity-box {
|
#identity-icon-box {
|
||||||
max-width: 80px;
|
max-width: 80px;
|
||||||
}
|
}
|
||||||
/* Contenxtual identity labels are user-customizable and can be very long,
|
/* Contenxtual identity labels are user-customizable and can be very long,
|
||||||
|
@ -779,7 +779,7 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
||||||
#nav-bar[downloadsbuttonshown] #urlbar-container {
|
#nav-bar[downloadsbuttonshown] #urlbar-container {
|
||||||
min-width: 225px;
|
min-width: 225px;
|
||||||
}
|
}
|
||||||
#identity-box {
|
#identity-icon-box {
|
||||||
max-width: 70px;
|
max-width: 70px;
|
||||||
}
|
}
|
||||||
#urlbar-zoom-button {
|
#urlbar-zoom-button {
|
||||||
|
|
|
@ -165,6 +165,11 @@ XPCOMUtils.defineLazyScriptGetter(
|
||||||
"gIdentityHandler",
|
"gIdentityHandler",
|
||||||
"chrome://browser/content/browser-siteIdentity.js"
|
"chrome://browser/content/browser-siteIdentity.js"
|
||||||
);
|
);
|
||||||
|
XPCOMUtils.defineLazyScriptGetter(
|
||||||
|
this,
|
||||||
|
"gPermissionPanel",
|
||||||
|
"chrome://browser/content/browser-sitePermissionPanel.js"
|
||||||
|
);
|
||||||
XPCOMUtils.defineLazyScriptGetter(
|
XPCOMUtils.defineLazyScriptGetter(
|
||||||
this,
|
this,
|
||||||
"gProtectionsHandler",
|
"gProtectionsHandler",
|
||||||
|
@ -1036,7 +1041,7 @@ var gPopupBlockerObserver = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gIdentityHandler.refreshIdentityBlock();
|
gPermissionPanel.refreshPermissionIcons();
|
||||||
|
|
||||||
let popupCount = gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount();
|
let popupCount = gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount();
|
||||||
|
|
||||||
|
@ -3480,6 +3485,7 @@ function BrowserReloadWithFlags(reloadFlags) {
|
||||||
delete tab.linkedBrowser.authPromptAbuseCounter;
|
delete tab.linkedBrowser.authPromptAbuseCounter;
|
||||||
}
|
}
|
||||||
gIdentityHandler.hidePopup();
|
gIdentityHandler.hidePopup();
|
||||||
|
gPermissionPanel.hidePopup();
|
||||||
|
|
||||||
let handlingUserInput = window.windowUtils.isHandlingUserInput;
|
let handlingUserInput = window.windowUtils.isHandlingUserInput;
|
||||||
|
|
||||||
|
@ -5150,7 +5156,7 @@ var XULBrowserWindow = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
gIdentityHandler.onLocationChange();
|
gPermissionPanel.onLocationChange();
|
||||||
|
|
||||||
gProtectionsHandler.onLocationChange();
|
gProtectionsHandler.onLocationChange();
|
||||||
|
|
||||||
|
|
|
@ -632,6 +632,7 @@
|
||||||
|
|
||||||
#include ../../components/customizableui/content/panelUI.inc.xhtml
|
#include ../../components/customizableui/content/panelUI.inc.xhtml
|
||||||
#include ../../components/controlcenter/content/identityPanel.inc.xhtml
|
#include ../../components/controlcenter/content/identityPanel.inc.xhtml
|
||||||
|
#include ../../components/controlcenter/content/permissionPanel.inc.xhtml
|
||||||
#include ../../components/controlcenter/content/protectionsPanel.inc.xhtml
|
#include ../../components/controlcenter/content/protectionsPanel.inc.xhtml
|
||||||
#include ../../components/downloads/content/downloadsPanel.inc.xhtml
|
#include ../../components/downloads/content/downloadsPanel.inc.xhtml
|
||||||
#include ../../../devtools/startup/enableDevToolsPopup.inc.xhtml
|
#include ../../../devtools/startup/enableDevToolsPopup.inc.xhtml
|
||||||
|
@ -1864,18 +1865,29 @@
|
||||||
<description id="tracking-protection-icon-tooltip-label" class="tooltip-label"/>
|
<description id="tracking-protection-icon-tooltip-label" class="tooltip-label"/>
|
||||||
</tooltip>
|
</tooltip>
|
||||||
</box>
|
</box>
|
||||||
<box id="identity-box" role="button"
|
<box id="identity-box"
|
||||||
|
pageproxystate="invalid"
|
||||||
|
ondragstart="gIdentityHandler.onDragStart(event);">
|
||||||
|
<box id="identity-icon-box"
|
||||||
|
role="button"
|
||||||
align="center"
|
align="center"
|
||||||
data-l10n-id="urlbar-identity-button"
|
data-l10n-id="urlbar-identity-button"
|
||||||
pageproxystate="invalid"
|
class="identity-box-button"
|
||||||
onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
|
onclick="gIdentityHandler.handleIdentityButtonEvent(event); PageProxyClickHandler(event);"
|
||||||
onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
|
onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);">
|
||||||
ondragstart="gIdentityHandler.onDragStart(event);">
|
<image id="identity-icon"/>
|
||||||
<image id="identity-icon"
|
<image id="remote-control-icon"
|
||||||
consumeanchor="identity-box"
|
data-l10n-id="urlbar-remote-control-notification-anchor"/>
|
||||||
onclick="PageProxyClickHandler(event);"/>
|
<label id="identity-icon-label" class="plain" crop="center" flex="1"/>
|
||||||
<image id="permissions-granted-icon"
|
</box>
|
||||||
data-l10n-id="urlbar-permissions-granted"/>
|
<box id="identity-permission-box"
|
||||||
|
data-l10n-id="urlbar-permissions-granted"
|
||||||
|
role="button"
|
||||||
|
align="center"
|
||||||
|
class="identity-box-button"
|
||||||
|
onclick="gPermissionPanel.handleIdentityButtonEvent(event); PageProxyClickHandler(event);"
|
||||||
|
onkeypress="gPermissionPanel.handleIdentityButtonEvent(event);">
|
||||||
|
<image id="permissions-granted-icon"/>
|
||||||
<box style="pointer-events: none;">
|
<box style="pointer-events: none;">
|
||||||
<image class="sharing-icon" id="webrtc-sharing-icon"/>
|
<image class="sharing-icon" id="webrtc-sharing-icon"/>
|
||||||
<image class="sharing-icon geo-icon" id="geo-sharing-icon"/>
|
<image class="sharing-icon geo-icon" id="geo-sharing-icon"/>
|
||||||
|
@ -1907,10 +1919,9 @@
|
||||||
<image data-permission-id="install" class="blocked-permission-icon install-icon" role="button"
|
<image data-permission-id="install" class="blocked-permission-icon install-icon" role="button"
|
||||||
data-l10n-id="urlbar-install-blocked"/>
|
data-l10n-id="urlbar-install-blocked"/>
|
||||||
</box>
|
</box>
|
||||||
|
</box>
|
||||||
<box id="notification-popup-box"
|
<box id="notification-popup-box"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
onmouseover="document.getElementById('identity-box').classList.add('no-hover');"
|
|
||||||
onmouseout="document.getElementById('identity-box').classList.remove('no-hover');"
|
|
||||||
align="center">
|
align="center">
|
||||||
<image id="default-notification-icon" class="notification-anchor-icon" role="button"
|
<image id="default-notification-icon" class="notification-anchor-icon" role="button"
|
||||||
data-l10n-id="urlbar-default-notification-anchor"/>
|
data-l10n-id="urlbar-default-notification-anchor"/>
|
||||||
|
@ -1957,9 +1968,6 @@
|
||||||
<image id="storage-access-notification-icon" class="notification-anchor-icon storage-access-icon" role="button"
|
<image id="storage-access-notification-icon" class="notification-anchor-icon storage-access-icon" role="button"
|
||||||
data-l10n-id="urlbar-storage-access-anchor"/>
|
data-l10n-id="urlbar-storage-access-anchor"/>
|
||||||
</box>
|
</box>
|
||||||
<image id="remote-control-icon"
|
|
||||||
data-l10n-id="urlbar-remote-control-notification-anchor"/>
|
|
||||||
<label id="identity-icon-label" class="plain" crop="center" flex="1"/>
|
|
||||||
</box>
|
</box>
|
||||||
<box id="urlbar-label-box" align="center">
|
<box id="urlbar-label-box" align="center">
|
||||||
<label id="urlbar-label-switchtab" class="urlbar-label" data-l10n-id="urlbar-switch-to-tab"/>
|
<label id="urlbar-label-switchtab" class="urlbar-label" data-l10n-id="urlbar-switch-to-tab"/>
|
||||||
|
|
|
@ -1227,7 +1227,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUserContextUIIndicator();
|
updateUserContextUIIndicator();
|
||||||
gIdentityHandler.updateSharingIndicator();
|
gPermissionPanel.updateSharingIndicator();
|
||||||
|
|
||||||
// Enable touch events to start a native dragging
|
// Enable touch events to start a native dragging
|
||||||
// session to allow the user to easily drag the selected tab.
|
// session to allow the user to easily drag the selected tab.
|
||||||
|
@ -1402,7 +1402,7 @@
|
||||||
tab.removeAttribute("sharing");
|
tab.removeAttribute("sharing");
|
||||||
this._tabAttrModified(tab, ["sharing"]);
|
this._tabAttrModified(tab, ["sharing"]);
|
||||||
if (aBrowser == this.selectedBrowser) {
|
if (aBrowser == this.selectedBrowser) {
|
||||||
gIdentityHandler.updateSharingIndicator();
|
gPermissionPanel.updateSharingIndicator();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1431,7 +1431,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aBrowser == this.selectedBrowser) {
|
if (aBrowser == this.selectedBrowser) {
|
||||||
gIdentityHandler.updateSharingIndicator();
|
gPermissionPanel.updateSharingIndicator();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -4187,6 +4187,7 @@
|
||||||
// Also reset DOS mitigations for the basic auth prompt on reload.
|
// Also reset DOS mitigations for the basic auth prompt on reload.
|
||||||
delete browser.authPromptAbuseCounter;
|
delete browser.authPromptAbuseCounter;
|
||||||
gIdentityHandler.hidePopup();
|
gIdentityHandler.hidePopup();
|
||||||
|
gPermissionPanel.hidePopup();
|
||||||
browser.reload();
|
browser.reload();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ browser.jar:
|
||||||
content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js)
|
content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js)
|
||||||
content/browser/browser-sidebar.js (content/browser-sidebar.js)
|
content/browser/browser-sidebar.js (content/browser-sidebar.js)
|
||||||
content/browser/browser-siteIdentity.js (content/browser-siteIdentity.js)
|
content/browser/browser-siteIdentity.js (content/browser-siteIdentity.js)
|
||||||
|
content/browser/browser-sitePermissionPanel.js (content/browser-sitePermissionPanel.js)
|
||||||
content/browser/browser-siteProtections.js (content/browser-siteProtections.js)
|
content/browser/browser-siteProtections.js (content/browser-siteProtections.js)
|
||||||
content/browser/browser-sync.js (content/browser-sync.js)
|
content/browser/browser-sync.js (content/browser-sync.js)
|
||||||
content/browser/browser-tabsintitlebar.js (content/browser-tabsintitlebar.js)
|
content/browser/browser-tabsintitlebar.js (content/browser-tabsintitlebar.js)
|
||||||
|
|
|
@ -88,33 +88,6 @@
|
||||||
oncommand="gIdentityHandler.showSecuritySubView();"/>
|
oncommand="gIdentityHandler.showSecuritySubView();"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
<!-- Permissions Section -->
|
|
||||||
<hbox class="identity-popup-section"
|
|
||||||
when-connection="not-secure secure secure-ev secure-cert-user-overridden file extension cert-error-page https-only-error-page">
|
|
||||||
<vbox id="identity-popup-permissions-content" flex="1" role="group"
|
|
||||||
aria-labelledby="identity-popup-permissions-headline">
|
|
||||||
<hbox id="identity-popup-permissions-header" align="center">
|
|
||||||
<label id="identity-popup-permissions-headline"
|
|
||||||
role="heading" aria-level="2"
|
|
||||||
data-l10n-id="identity-permissions"/>
|
|
||||||
</hbox>
|
|
||||||
<vbox id="identity-popup-permission-list">
|
|
||||||
<vbox id="identity-popup-permission-list-default-anchor" class="identity-popup-permission-list-anchor"/>
|
|
||||||
<vbox class="identity-popup-permission-list-anchor" anchorfor="3rdPartyStorage">
|
|
||||||
<vbox id="identity-popup-storage-access-permission-list-header">
|
|
||||||
<hbox align="center" role="group">
|
|
||||||
<image class="identity-popup-permission-icon storage-access-icon"/>
|
|
||||||
<label data-l10n-id="identity-permissions-storage-access-header" class="identity-popup-permission-header-label"/>
|
|
||||||
</hbox>
|
|
||||||
<description id="identity-popup-storage-access-permission-list-hint" data-l10n-id="identity-permissions-storage-access-hint"></description>
|
|
||||||
</vbox>
|
|
||||||
</vbox>
|
|
||||||
</vbox>
|
|
||||||
<description id="identity-popup-permission-reload-hint" data-l10n-id="identity-permissions-reload-hint"></description>
|
|
||||||
<description id="identity-popup-permission-empty-hint" data-l10n-id="identity-permissions-empty"></description>
|
|
||||||
</vbox>
|
|
||||||
</hbox>
|
|
||||||
|
|
||||||
<!-- Clear Site Data Button -->
|
<!-- Clear Site Data Button -->
|
||||||
<vbox hidden="true"
|
<vbox hidden="true"
|
||||||
id="identity-popup-clear-sitedata-footer"
|
id="identity-popup-clear-sitedata-footer"
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<!-- 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/. -->
|
||||||
|
|
||||||
|
<html:template id="template-permission-popup">
|
||||||
|
<panel id="permission-popup"
|
||||||
|
class="panel-no-padding"
|
||||||
|
type="arrow"
|
||||||
|
role="alertdialog"
|
||||||
|
noautofocus="true"
|
||||||
|
aria-labelledby="permission-popup-mainView-panel-header-span"
|
||||||
|
onpopupshown="gPermissionPanel.onPopupShown(event);"
|
||||||
|
onpopuphidden="gPermissionPanel.onPopupHidden(event);"
|
||||||
|
orient="vertical">
|
||||||
|
<panelmultiview id="permission-popup-multiView"
|
||||||
|
mainViewId="permission-popup-mainView">
|
||||||
|
<panelview id="permission-popup-mainView"
|
||||||
|
role="document"
|
||||||
|
descriptionheightworkaround="true">
|
||||||
|
<vbox id="permission-popup-mainView-panel-header">
|
||||||
|
<label>
|
||||||
|
<html:span id="permission-popup-mainView-panel-header-span" role="heading" aria-level="1"/>
|
||||||
|
</label>
|
||||||
|
</vbox>
|
||||||
|
<hbox class="permission-popup-section">
|
||||||
|
<vbox id="permission-popup-permissions-content" flex="1" role="group">
|
||||||
|
<vbox id="permission-popup-permission-list">
|
||||||
|
<vbox id="permission-popup-permission-list-default-anchor" class="permission-popup-permission-list-anchor"/>
|
||||||
|
<vbox class="permission-popup-permission-list-anchor" anchorfor="3rdPartyStorage">
|
||||||
|
<vbox id="permission-popup-storage-access-permission-list-header">
|
||||||
|
<hbox align="center" role="group">
|
||||||
|
<image class="permission-popup-permission-icon storage-access-icon"/>
|
||||||
|
<label data-l10n-id="identity-permissions-storage-access-header" class="permission-popup-permission-header-label"/>
|
||||||
|
</hbox>
|
||||||
|
<description id="permission-popup-storage-access-permission-list-hint" data-l10n-id="identity-permissions-storage-access-hint"></description>
|
||||||
|
</vbox>
|
||||||
|
</vbox>
|
||||||
|
</vbox>
|
||||||
|
<description id="permission-popup-permission-reload-hint" data-l10n-id="identity-permissions-reload-hint"></description>
|
||||||
|
</vbox>
|
||||||
|
</hbox>
|
||||||
|
</panelview>
|
||||||
|
</panelmultiview>
|
||||||
|
</panel>
|
||||||
|
</html:template>
|
|
@ -414,7 +414,11 @@ async function isBrowserShowingNotification() {
|
||||||
|
|
||||||
// tracking protection and identity box doorhangers
|
// tracking protection and identity box doorhangers
|
||||||
if (
|
if (
|
||||||
["tracking-protection-icon-container", "identity-box"].some(
|
[
|
||||||
|
"tracking-protection-icon-container",
|
||||||
|
"identity-icon-box",
|
||||||
|
"identity-permission-box",
|
||||||
|
].some(
|
||||||
id => window.document.getElementById(id).getAttribute("open") == "true"
|
id => window.document.getElementById(id).getAttribute("open") == "true"
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -307,13 +307,10 @@ identity-https-only-info-turn-on2 = Turn on HTTPS-Only Mode for this site if you
|
||||||
identity-https-only-info-turn-off2 = If the page seems broken, you may want to turn off HTTPS-Only Mode for this site to reload using insecure HTTP.
|
identity-https-only-info-turn-off2 = If the page seems broken, you may want to turn off HTTPS-Only Mode for this site to reload using insecure HTTP.
|
||||||
identity-https-only-info-no-upgrade = Unable to upgrade connection from HTTP.
|
identity-https-only-info-no-upgrade = Unable to upgrade connection from HTTP.
|
||||||
|
|
||||||
identity-permissions =
|
|
||||||
.value = Permissions
|
|
||||||
identity-permissions-storage-access-header = Cross-site cookies
|
identity-permissions-storage-access-header = Cross-site cookies
|
||||||
identity-permissions-storage-access-hint = These parties can use cross-site cookies and site data while you are on this site.
|
identity-permissions-storage-access-hint = These parties can use cross-site cookies and site data while you are on this site.
|
||||||
|
|
||||||
identity-permissions-reload-hint = You may need to reload the page for changes to apply.
|
identity-permissions-reload-hint = You may need to reload the page for changes to apply.
|
||||||
identity-permissions-empty = You have not granted this site any special permissions.
|
|
||||||
identity-clear-site-data =
|
identity-clear-site-data =
|
||||||
.label = Clear Cookies and Site Data…
|
.label = Clear Cookies and Site Data…
|
||||||
identity-connection-not-secure-security-view = You are not securely connected to this site.
|
identity-connection-not-secure-security-view = You are not securely connected to this site.
|
||||||
|
|
|
@ -983,6 +983,9 @@ captivePortal.infoMessage3 = You must log in to this network before you can acce
|
||||||
# The button shows the portal login page tab when clicked.
|
# The button shows the portal login page tab when clicked.
|
||||||
captivePortal.showLoginPage2 = Open Network Login Page
|
captivePortal.showLoginPage2 = Open Network Login Page
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (permissions.header):
|
||||||
|
# %S is the hostname of the site that is being displayed.
|
||||||
|
permissions.header = Permissions for %S
|
||||||
permissions.remove.tooltip = Clear this permission and ask again
|
permissions.remove.tooltip = Clear this permission and ask again
|
||||||
|
|
||||||
permissions.fullscreen.promptCanceled = Canceled pending permission requests: permission requests should not be issued before entering DOM fullscreen.
|
permissions.fullscreen.promptCanceled = Canceled pending permission requests: permission requests should not be issued before entering DOM fullscreen.
|
||||||
|
|
|
@ -672,13 +672,15 @@ var webrtcUI = {
|
||||||
aActiveStream.browser.focus();
|
aActiveStream.browser.focus();
|
||||||
}
|
}
|
||||||
browserWindow.focus();
|
browserWindow.focus();
|
||||||
let identityBox = browserWindow.document.getElementById("identity-box");
|
let permissionBox = browserWindow.document.getElementById(
|
||||||
|
"identity-permission-box"
|
||||||
|
);
|
||||||
if (AppConstants.platform == "macosx" && !Services.focus.activeWindow) {
|
if (AppConstants.platform == "macosx" && !Services.focus.activeWindow) {
|
||||||
browserWindow.addEventListener(
|
browserWindow.addEventListener(
|
||||||
"activate",
|
"activate",
|
||||||
function() {
|
function() {
|
||||||
Services.tm.dispatchToMainThread(function() {
|
Services.tm.dispatchToMainThread(function() {
|
||||||
identityBox.click();
|
permissionBox.click();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{ once: true }
|
{ once: true }
|
||||||
|
@ -688,7 +690,7 @@ var webrtcUI = {
|
||||||
.activateApplication(true);
|
.activateApplication(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
identityBox.click();
|
permissionBox.click();
|
||||||
},
|
},
|
||||||
|
|
||||||
updateWarningLabel(aMenuList) {
|
updateWarningLabel(aMenuList) {
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
%include ../../shared/controlcenter/panel.inc.css
|
%include ../../shared/controlcenter/panel.inc.css
|
||||||
|
|
||||||
.identity-popup-expander > .button-box,
|
.identity-popup-expander > .button-box,
|
||||||
.identity-popup-permission-remove-button > .button-box {
|
.permission-popup-permission-remove-button > .button-box {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-expander:-moz-focusring,
|
.identity-popup-expander:-moz-focusring,
|
||||||
.identity-popup-permission-remove-button:-moz-focusring {
|
.permission-popup-permission-remove-button:-moz-focusring {
|
||||||
outline: 1px -moz-dialogtext dotted;
|
outline: 1px -moz-dialogtext dotted;
|
||||||
outline-offset: -1px;
|
outline-offset: -1px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
%include ../../shared/controlcenter/panel.inc.css
|
%include ../../shared/controlcenter/panel.inc.css
|
||||||
|
|
||||||
.identity-popup-expander:-moz-focusring,
|
.identity-popup-expander:-moz-focusring,
|
||||||
.identity-popup-permission-remove-button:-moz-focusring {
|
.permission-popup-permission-remove-button:-moz-focusring {
|
||||||
box-shadow: var(--focus-ring-box-shadow);
|
box-shadow: var(--focus-ring-box-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
%filter substitution
|
%filter substitution
|
||||||
%define identityBoxPaddingInline 6px
|
%define identityBoxPaddingInline 6px
|
||||||
%define identityBoxMarginInlineEnd 2px
|
%define identityBoxMarginInline 3px
|
||||||
%define lwtPopupBrighttextLinkColor #74c0ff
|
%define lwtPopupBrighttextLinkColor #74c0ff
|
||||||
%define themeTransition background-color 0.1s cubic-bezier(.17,.67,.83,.67)
|
%define themeTransition background-color 0.1s cubic-bezier(.17,.67,.83,.67)
|
||||||
%define urlbarBreakoutExtend 2px
|
%define urlbarBreakoutExtend 2px
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
|
|
||||||
#identity-popup,
|
#identity-popup,
|
||||||
|
#permission-popup,
|
||||||
#protections-popup {
|
#protections-popup {
|
||||||
%if defined(XP_MACOSX) || defined(XP_WIN)
|
%if defined(XP_MACOSX) || defined(XP_WIN)
|
||||||
font-size: 1.18em;
|
font-size: 1.18em;
|
||||||
|
@ -46,7 +47,8 @@
|
||||||
|
|
||||||
/* This is used by screenshots tests to hide intermittently different
|
/* This is used by screenshots tests to hide intermittently different
|
||||||
* identity popup shadows (see bug 1425253). */
|
* identity popup shadows (see bug 1425253). */
|
||||||
#identity-popup.no-shadow {
|
#identity-popup.no-shadow,
|
||||||
|
#permission-popup.no-shadow {
|
||||||
-moz-window-shadow: none;
|
-moz-window-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +95,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-mainView,
|
#identity-popup-mainView,
|
||||||
|
#permission-popup-mainView,
|
||||||
#protections-popup-mainView,
|
#protections-popup-mainView,
|
||||||
#identity-popup-mainView-panel-header,
|
#identity-popup-mainView-panel-header,
|
||||||
|
#permission-popup-mainView-panel-header,
|
||||||
#protections-popup-mainView-panel-header {
|
#protections-popup-mainView-panel-header {
|
||||||
min-width: var(--popup-width);
|
min-width: var(--popup-width);
|
||||||
max-width: var(--popup-width);
|
max-width: var(--popup-width);
|
||||||
|
@ -110,6 +114,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-section,
|
.identity-popup-section,
|
||||||
|
.permission-popup-section,
|
||||||
.protections-popup-section {
|
.protections-popup-section {
|
||||||
border-top: 1px solid var(--panel-separator-color);
|
border-top: 1px solid var(--panel-separator-color);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +138,6 @@
|
||||||
margin-block: 0;
|
margin-block: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-permissions-header,
|
|
||||||
.identity-popup-security-connection,
|
.identity-popup-security-connection,
|
||||||
#identity-popup-security-description,
|
#identity-popup-security-description,
|
||||||
#identity-popup-security-httpsonlymode {
|
#identity-popup-security-httpsonlymode {
|
||||||
|
@ -171,32 +175,15 @@
|
||||||
margin-inline: 0;
|
margin-inline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-permissions-content {
|
#permission-popup-permissions-content {
|
||||||
padding-inline: 2em 1em;
|
padding-inline: 2em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-security-content,
|
.identity-popup-security-content,
|
||||||
#identity-popup-permissions-content {
|
#permission-popup-permissions-content {
|
||||||
padding-block: 1em;
|
padding-block: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-permissions-header {
|
|
||||||
background-image: url(chrome://browser/skin/permissions.svg);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
-moz-context-properties: fill;
|
|
||||||
fill: currentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
#identity-popup-permissions-header:-moz-locale-dir(rtl) {
|
|
||||||
background-position-x: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
#identity-popup-permissions-header,
|
|
||||||
#identity-popup-permission-list {
|
|
||||||
/* 16px icon width + 12px margin */
|
|
||||||
padding-inline-start: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#protections-popup-content {
|
#protections-popup-content {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 1em 1em;
|
background-position: 1em 1em;
|
||||||
|
@ -247,7 +234,6 @@
|
||||||
|
|
||||||
/* CONTENT */
|
/* CONTENT */
|
||||||
|
|
||||||
#identity-popup-permissions-headline,
|
|
||||||
.protections-popup-empty-label,
|
.protections-popup-empty-label,
|
||||||
.tracking-protection-button,
|
.tracking-protection-button,
|
||||||
.protections-popup-cookiesView-list-header,
|
.protections-popup-cookiesView-list-header,
|
||||||
|
@ -265,6 +251,7 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#permission-popup-mainView-panel-header,
|
||||||
#identity-popup-mainView-panel-header,
|
#identity-popup-mainView-panel-header,
|
||||||
#protections-popup-mainView-panel-header {
|
#protections-popup-mainView-panel-header {
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
|
@ -272,6 +259,7 @@
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#permission-popup-mainView-panel-header,
|
||||||
#identity-popup-mainView-panel-header {
|
#identity-popup-mainView-panel-header {
|
||||||
padding: var(--vertical-section-padding) var(--horizontal-padding);
|
padding: var(--vertical-section-padding) var(--horizontal-padding);
|
||||||
}
|
}
|
||||||
|
@ -301,6 +289,7 @@
|
||||||
background: radial-gradient(circle farthest-side at top left, #9059FF, #0250BB);
|
background: radial-gradient(circle farthest-side at top left, #9059FF, #0250BB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#permission-popup-mainView-panel-header-span,
|
||||||
#identity-popup-mainView-panel-header-span,
|
#identity-popup-mainView-panel-header-span,
|
||||||
#protections-popup-mainView-panel-header-span {
|
#protections-popup-mainView-panel-header-span {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
@ -312,11 +301,13 @@
|
||||||
margin-inline-start: 35px;
|
margin-inline-start: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#permission-popup-mainView-panel-header-span,
|
||||||
#identity-popup-mainView-panel-header-span,
|
#identity-popup-mainView-panel-header-span,
|
||||||
#protections-popup-mainView-panel-header-span,
|
#protections-popup-mainView-panel-header-span,
|
||||||
#protections-popup-toast-panel-tp-on-desc,
|
#protections-popup-toast-panel-tp-on-desc,
|
||||||
#protections-popup-toast-panel-tp-off-desc,
|
#protections-popup-toast-panel-tp-off-desc,
|
||||||
#protections-popup .panel-header > label > span,
|
#protections-popup .panel-header > label > span,
|
||||||
|
#permission-popup .panel-header > label > span,
|
||||||
#identity-popup .panel-header > label > span {
|
#identity-popup .panel-header > label > span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -338,7 +329,7 @@
|
||||||
fill-opacity: 1;
|
fill-opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-permissions-content > description,
|
#permission-popup-permissions-content > description,
|
||||||
#protections-popup-content > description {
|
#protections-popup-content > description {
|
||||||
color: var(--panel-description-color);
|
color: var(--panel-description-color);
|
||||||
}
|
}
|
||||||
|
@ -740,13 +731,13 @@ description#identity-popup-content-verifier,
|
||||||
@supports -moz-bool-pref("layout.css.emulate-moz-box-with-flex") {
|
@supports -moz-bool-pref("layout.css.emulate-moz-box-with-flex") {
|
||||||
/* The extra padding-bottom is there to work around XUL flex (Bug 1368281).
|
/* The extra padding-bottom is there to work around XUL flex (Bug 1368281).
|
||||||
This rule and the 1.5em above can both be removed once we are only using CSS flex. */
|
This rule and the 1.5em above can both be removed once we are only using CSS flex. */
|
||||||
#identity-popup-permissions-content {
|
#permission-popup-permissions-content {
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.protections-popup-category,
|
.protections-popup-category,
|
||||||
.identity-popup-permission-item {
|
.permission-popup-permission-item {
|
||||||
min-height: 24px;
|
min-height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,24 +749,22 @@ description#identity-popup-content-verifier,
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-item,
|
.permission-popup-permission-item,
|
||||||
#identity-popup-storage-access-permission-list-header {
|
#permission-popup-storage-access-permission-list-header {
|
||||||
padding-inline-end: 8px;
|
padding-inline-end: 8px;
|
||||||
margin-top: 0.25em;
|
margin-top: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-permission-reload-hint,
|
#permission-popup-permission-reload-hint,
|
||||||
#identity-popup-permission-empty-hint,
|
#permission-popup-permission-empty-hint {
|
||||||
#identity-popup-permission-list:not(:empty),
|
|
||||||
#identity-popup-permission-list:empty + #identity-popup-storage-access-permission-list:not(:empty) {
|
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-list-anchor[anchorfor="3rdPartyStorage"] > vbox:only-child {
|
.permission-popup-permission-list-anchor[anchorfor="3rdPartyStorage"] > vbox:only-child {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-storage-access-permission-list-hint {
|
#permission-popup-storage-access-permission-list-hint {
|
||||||
margin-top: 0.25em;
|
margin-top: 0.25em;
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
/* Matches offset for items - 3px margin + 16px icon + 10px margin */
|
/* Matches offset for items - 3px margin + 16px icon + 10px margin */
|
||||||
|
@ -783,23 +772,23 @@ description#identity-popup-content-verifier,
|
||||||
color: var(--panel-description-color);
|
color: var(--panel-description-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-icon {
|
.permission-popup-permission-icon {
|
||||||
margin-inline-start: 3px;
|
margin-inline-start: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.protections-popup-category-icon,
|
.protections-popup-category-icon,
|
||||||
.identity-popup-permission-icon {
|
.permission-popup-permission-icon {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-icon.in-use {
|
.permission-popup-permission-icon.in-use {
|
||||||
-moz-context-properties: fill;
|
-moz-context-properties: fill;
|
||||||
fill: rgb(224, 41, 29);
|
fill: rgb(224, 41, 29);
|
||||||
animation: 1.5s ease identity-popup-permission-icon-in-use-blink infinite;
|
animation: 1.5s ease permission-popup-permission-icon-in-use-blink infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes identity-popup-permission-icon-in-use-blink {
|
@keyframes permission-popup-permission-icon-in-use-blink {
|
||||||
50% { opacity: 0; }
|
50% { opacity: 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,24 +797,24 @@ description#identity-popup-content-verifier,
|
||||||
margin-inline-start: 1em;
|
margin-inline-start: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-label,
|
.permission-popup-permission-label,
|
||||||
.identity-popup-permission-header-label {
|
.permission-popup-permission-header-label {
|
||||||
margin-inline-start: 10px;
|
margin-inline-start: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-label-subitem {
|
.permission-popup-permission-label-subitem {
|
||||||
/* Align label with other labels with icon. */
|
/* Align label with other labels with icon. */
|
||||||
/* icon width + icon inline margin + label inline margin */
|
/* icon width + icon inline margin + label inline margin */
|
||||||
margin-inline-start: calc(16px + 3px + 10px);
|
margin-inline-start: calc(16px + 3px + 10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.protections-popup-category-state-label,
|
.protections-popup-category-state-label,
|
||||||
.identity-popup-permission-state-label {
|
.permission-popup-permission-state-label {
|
||||||
margin-inline-end: 5px;
|
margin-inline-end: 5px;
|
||||||
text-align: end;
|
text-align: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-state-label {
|
.permission-popup-permission-state-label {
|
||||||
color: var(--panel-description-color);
|
color: var(--panel-description-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,7 +822,7 @@ description#identity-popup-content-verifier,
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-remove-button {
|
.permission-popup-permission-remove-button {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-inline-start: 2px;
|
margin-inline-start: 2px;
|
||||||
|
@ -847,11 +836,11 @@ description#identity-popup-content-verifier,
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-remove-button > .button-box {
|
.permission-popup-permission-remove-button > .button-box {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-remove-button > .button-box > .button-icon {
|
.permission-popup-permission-remove-button > .button-box > .button-icon {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
@ -860,20 +849,20 @@ description#identity-popup-content-verifier,
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-remove-button > .button-box > .button-text {
|
.permission-popup-permission-remove-button > .button-box > .button-text {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* swap foreground / background colors on hover */
|
/* swap foreground / background colors on hover */
|
||||||
.identity-popup-permission-remove-button:not(:-moz-focusring):hover {
|
.permission-popup-permission-remove-button:not(:-moz-focusring):hover {
|
||||||
background-color: currentColor;
|
background-color: currentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-remove-button:not(:-moz-focusring):hover > .button-box > .button-icon {
|
.permission-popup-permission-remove-button:not(:-moz-focusring):hover > .button-box > .button-icon {
|
||||||
fill: var(--arrowpanel-background);
|
fill: var(--arrowpanel-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.identity-popup-permission-remove-button:not(:-moz-focusring):hover:active {
|
.permission-popup-permission-remove-button:not(:-moz-focusring):hover:active {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,8 @@ panelmultiview[transitioning] > .panel-viewcontainer > .panel-viewstack > panelv
|
||||||
#widget-overflow,
|
#widget-overflow,
|
||||||
#appMenu-popup,
|
#appMenu-popup,
|
||||||
#customizationui-widget-panel,
|
#customizationui-widget-panel,
|
||||||
|
#identity-popup,
|
||||||
|
#permission-popup,
|
||||||
#protections-popup {
|
#protections-popup {
|
||||||
margin-top: -6px;
|
margin-top: -6px;
|
||||||
}
|
}
|
||||||
|
@ -197,12 +199,6 @@ panelmultiview[transitioning] > .panel-viewcontainer > .panel-viewstack > panelv
|
||||||
margin-top: calc(var(--toolbarbutton-inner-padding) - var(--urlbar-icon-padding) - 6px)
|
margin-top: calc(var(--toolbarbutton-inner-padding) - var(--urlbar-icon-padding) - 6px)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The identity popup does not have any padding of its own,
|
|
||||||
otherwise would use the same formula as above. */
|
|
||||||
#identity-popup {
|
|
||||||
margin-top: calc(var(--toolbarbutton-inner-padding) - 6px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The bookmarks toolbar is too thin to have the panels overlap 6px. */
|
/* The bookmarks toolbar is too thin to have the panels overlap 6px. */
|
||||||
#downloadsPanel.bookmarks-toolbar,
|
#downloadsPanel.bookmarks-toolbar,
|
||||||
#widget-overflow.bookmarks-toolbar,
|
#widget-overflow.bookmarks-toolbar,
|
||||||
|
|
|
@ -7,8 +7,14 @@
|
||||||
%filter substitution
|
%filter substitution
|
||||||
|
|
||||||
#identity-box {
|
#identity-box {
|
||||||
padding-inline: @identityBoxPaddingInline@;
|
margin-inline: @identityBoxMarginInline@;
|
||||||
margin-inline-end: @identityBoxMarginInlineEnd@;
|
}
|
||||||
|
|
||||||
|
/* The tracking protection icon will be hidden if it is a chrome page. There
|
||||||
|
will be only the brand icon in the url bar. We need to change the margin
|
||||||
|
in order for the identity box to cover the whole urlbar start section. */
|
||||||
|
#identity-box[pageproxystate="valid"].chromeUI {
|
||||||
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box,
|
#identity-box,
|
||||||
|
@ -19,19 +25,15 @@
|
||||||
fill-opacity: .6;
|
fill-opacity: .6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The tracking protection icon will be hidden if it is a chrome page. There
|
#identity-box[pageproxystate="invalid"] {
|
||||||
will be only the brand icon in the url bar. So, we need to change the padding
|
margin-inline-end: calc(@identityBoxMarginInline@ + 2px);
|
||||||
start for proper positing the icon. */
|
|
||||||
#identity-box[pageproxystate="valid"].chromeUI {
|
|
||||||
padding-inline-start: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#urlbar.searchButton > #urlbar-input-container > #identity-box[pageproxystate="invalid"],
|
#urlbar.searchButton > #urlbar-input-container > #identity-box[pageproxystate="invalid"],
|
||||||
#identity-box[pageproxystate="invalid"] > #permissions-granted-icon,
|
#identity-box[pageproxystate="invalid"] > #identity-permission-box,
|
||||||
#identity-box[pageproxystate="invalid"] > #blocked-permissions-container,
|
|
||||||
#identity-box[pageproxystate="invalid"] > #notification-popup-box,
|
#identity-box[pageproxystate="invalid"] > #notification-popup-box,
|
||||||
#identity-box[pageproxystate="invalid"] > #identity-icon-label,
|
#identity-box[pageproxystate="invalid"] #identity-icon-label,
|
||||||
#identity-box[pageproxystate="invalid"] > #remote-control-icon {
|
#identity-box[pageproxystate="invalid"] #remote-control-icon {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,28 +42,32 @@
|
||||||
-moz-user-focus: ignore;
|
-moz-user-focus: ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box:hover:not(.no-hover, [open=true]),
|
.identity-box-button:hover:not([open=true]),
|
||||||
#tracking-protection-icon-container:hover:not([open=true]) {
|
#tracking-protection-icon-container:hover:not([open=true]) {
|
||||||
background-color: hsla(0,0%,70%,.2);
|
background-color: hsla(0,0%,70%,.2);
|
||||||
fill-opacity: .8;
|
fill-opacity: .8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box:hover:active:not(.no-hover),
|
.identity-box-button:hover:active,
|
||||||
#identity-box[open=true],
|
.identity-box-button[open=true],
|
||||||
#tracking-protection-icon-container:hover:active,
|
#tracking-protection-icon-container:hover:active,
|
||||||
#tracking-protection-icon-container[open=true] {
|
#tracking-protection-icon-container[open=true] {
|
||||||
background-color: hsla(0,0%,70%,.3);
|
background-color: hsla(0,0%,70%,.3);
|
||||||
fill-opacity: .8;
|
fill-opacity: .8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box:not(:active):-moz-focusring,
|
.identity-box-button:not(:active):-moz-focusring,
|
||||||
#tracking-protection-icon-container:not(:active):-moz-focusring {
|
#tracking-protection-icon-container:not(:active):-moz-focusring {
|
||||||
outline: var(--toolbarbutton-focus-outline);
|
outline: var(--toolbarbutton-focus-outline);
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
-moz-outline-radius: var(--toolbarbutton-border-radius);
|
-moz-outline-radius: var(--toolbarbutton-border-radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].chromeUI > #identity-icon-label,
|
.identity-box-button {
|
||||||
|
padding-inline: calc(@identityBoxPaddingInline@ / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#identity-box[pageproxystate="valid"].chromeUI #identity-icon-label,
|
||||||
.urlbar-label {
|
.urlbar-label {
|
||||||
opacity: .6;
|
opacity: .6;
|
||||||
}
|
}
|
||||||
|
@ -83,10 +89,10 @@
|
||||||
border-image-slice: 1;
|
border-image-slice: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].notSecureText,
|
#identity-box[pageproxystate="valid"].notSecureText > #identity-icon-box,
|
||||||
#identity-box[pageproxystate="valid"].chromeUI,
|
#identity-box[pageproxystate="valid"].chromeUI > #identity-icon-box,
|
||||||
#identity-box[pageproxystate="valid"].extensionPage {
|
#identity-box[pageproxystate="valid"].extensionPage > #identity-icon-box {
|
||||||
padding-inline-end: 8px;
|
padding-inline: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#urlbar-label-box {
|
#urlbar-label-box {
|
||||||
|
@ -116,10 +122,17 @@
|
||||||
#blocked-permissions-container > .blocked-permission-icon {
|
#blocked-permissions-container > .blocked-permission-icon {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
margin-inline-start: 4px;
|
|
||||||
-moz-context-properties: fill, fill-opacity;
|
-moz-context-properties: fill, fill-opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sharing-icon,
|
||||||
|
#identity-icon,
|
||||||
|
#tracking-protection-icon,
|
||||||
|
.notification-anchor-icon,
|
||||||
|
#blocked-permissions-container > .blocked-permission-icon {
|
||||||
|
margin-inline-start: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
#tracking-protection-icon {
|
#tracking-protection-icon {
|
||||||
margin-inline-start: 0;
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
@ -130,50 +143,51 @@
|
||||||
list-style-image: url(chrome://global/skin/icons/identity-icon.svg);
|
list-style-image: url(chrome://global/skin/icons/identity-icon.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].chromeUI > #identity-icon {
|
#identity-box[pageproxystate="valid"].chromeUI #identity-icon {
|
||||||
list-style-image: url(chrome://branding/content/identity-icons-brand.svg);
|
list-style-image: url(chrome://branding/content/identity-icons-brand.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].localResource > #identity-icon {
|
#identity-box[pageproxystate="valid"].localResource #identity-icon {
|
||||||
list-style-image: url(chrome://global/skin/icons/document.svg);
|
list-style-image: url(chrome://global/skin/icons/document.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] > #identity-icon {
|
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon {
|
||||||
list-style-image: url(chrome://global/skin/icons/search-glass.svg);
|
list-style-image: url(chrome://global/skin/icons/search-glass.svg);
|
||||||
fill-opacity: .4;
|
fill-opacity: .4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#urlbar[actiontype="extension"] > #urlbar-input-container > #identity-box > #identity-icon {
|
#urlbar[actiontype="extension"] > #urlbar-input-container > #identity-box #identity-icon {
|
||||||
list-style-image: url(chrome://mozapps/skin/extensions/extension.svg);
|
list-style-image: url(chrome://mozapps/skin/extensions/extension.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].extensionPage > #identity-icon {
|
#identity-box[pageproxystate="valid"].extensionPage #identity-icon {
|
||||||
list-style-image: url(chrome://mozapps/skin/extensions/extension.svg);
|
list-style-image: url(chrome://mozapps/skin/extensions/extension.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].verifiedDomain > #identity-icon,
|
#identity-box[pageproxystate="valid"].verifiedDomain #identity-icon,
|
||||||
#identity-box[pageproxystate="valid"].mixedActiveBlocked > #identity-icon {
|
#identity-box[pageproxystate="valid"].mixedActiveBlocked #identity-icon {
|
||||||
list-style-image: url(chrome://browser/skin/connection-secure.svg);
|
list-style-image: url(chrome://browser/skin/connection-secure.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].verifiedDomain > #identity-icon:not([lock-icon-gray]),
|
#identity-box[pageproxystate="valid"].verifiedDomain #identity-icon:not([lock-icon-gray]),
|
||||||
#identity-box[pageproxystate="valid"].mixedActiveBlocked > #identity-icon:not([lock-icon-gray]) {
|
#identity-box[pageproxystate="valid"].mixedActiveBlocked #identity-icon:not([lock-icon-gray]) {
|
||||||
fill-opacity: 1;
|
fill-opacity: 1;
|
||||||
fill: #12BC00;
|
fill: #12BC00;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].weakCipher > #identity-icon,
|
#identity-box[pageproxystate="valid"].weakCipher #identity-icon,
|
||||||
#identity-box[pageproxystate="valid"].mixedDisplayContent > #identity-icon,
|
#identity-box[pageproxystate="valid"].mixedDisplayContent #identity-icon,
|
||||||
#identity-box[pageproxystate="valid"].mixedDisplayContentLoadedActiveBlocked > #identity-icon,
|
#identity-box[pageproxystate="valid"].mixedDisplayContentLoadedActiveBlocked #identity-icon,
|
||||||
#identity-box[pageproxystate="valid"].certUserOverridden > #identity-icon,
|
#identity-box[pageproxystate="valid"].certUserOverridden #identity-icon,
|
||||||
#identity-box[pageproxystate="valid"].certErrorPage > #identity-icon {
|
#identity-box[pageproxystate="valid"].certErrorPage #identity-icon {
|
||||||
list-style-image: url(chrome://global/skin/icons/connection-mixed-passive-loaded.svg);
|
list-style-image: url(chrome://global/skin/icons/connection-mixed-passive-loaded.svg);
|
||||||
fill: unset;
|
fill: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box[pageproxystate="valid"].notSecure > #identity-icon,
|
|
||||||
#identity-box[pageproxystate="valid"].mixedActiveContent > #identity-icon,
|
#identity-box[pageproxystate="valid"].notSecure #identity-icon,
|
||||||
#identity-box[pageproxystate="valid"].httpsOnlyErrorPage > #identity-icon {
|
#identity-box[pageproxystate="valid"].mixedActiveContent #identity-icon,
|
||||||
|
#identity-box[pageproxystate="valid"].httpsOnlyErrorPage #identity-icon {
|
||||||
list-style-image: url(chrome://global/skin/icons/connection-mixed-active-loaded.svg);
|
list-style-image: url(chrome://global/skin/icons/connection-mixed-active-loaded.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,10 +195,17 @@
|
||||||
list-style-image: url(chrome://browser/skin/permissions.svg);
|
list-style-image: url(chrome://browser/skin/permissions.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-box:not(.grantedPermissions) > #permissions-granted-icon {
|
#identity-permission-box {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#identity-permission-box[open=true],
|
||||||
|
#identity-permission-box[hasGrantedPermissions],
|
||||||
|
#identity-permission-box[hasPermissionIcon],
|
||||||
|
#identity-permission-box[hasSharingIcon] {
|
||||||
|
display: -moz-box;
|
||||||
|
}
|
||||||
|
|
||||||
/* SHARING ICON */
|
/* SHARING ICON */
|
||||||
|
|
||||||
#webrtc-sharing-icon[sharing="camera"] {
|
#webrtc-sharing-icon[sharing="camera"] {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
.popup-notification-icon,
|
.popup-notification-icon,
|
||||||
.identity-popup-permission-icon {
|
.permission-popup-permission-icon {
|
||||||
-moz-context-properties: fill, fill-opacity;
|
-moz-context-properties: fill, fill-opacity;
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
fill-opacity: 0.6;
|
fill-opacity: 0.6;
|
||||||
|
@ -14,7 +14,6 @@
|
||||||
#notification-popup-box {
|
#notification-popup-box {
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
margin: -5px 0;
|
margin: -5px 0;
|
||||||
margin-inline-end: -5px;
|
|
||||||
padding-inline-end: 5px;
|
padding-inline-end: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,8 +258,8 @@ html|*#webRTC-previewVideo {
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#identity-popup-popup-menulist,
|
#permission-popup-menulist,
|
||||||
#identity-popup-popup-menulist > menupopup {
|
#permission-popup-menulist > menupopup {
|
||||||
min-width: 6.5em;
|
min-width: 6.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
%filter substitution
|
%filter substitution
|
||||||
%define urlbarViewPadding 4px
|
%define urlbarViewPadding 4px
|
||||||
%define urlbarViewIconMarginEnd (@identityBoxPaddingInline@ + @identityBoxMarginInlineEnd@)
|
%define urlbarViewIconMarginEnd (@identityBoxPaddingInline@ + @identityBoxMarginInline@)
|
||||||
%define urlbarViewMarginInline 7px
|
%define urlbarViewMarginInline 7px
|
||||||
%define urlbarViewItemInlinePadding 6px
|
%define urlbarViewItemInlinePadding 6px
|
||||||
%define urlbarViewFaviconWidth 16px
|
%define urlbarViewFaviconWidth 16px
|
||||||
|
@ -143,10 +143,10 @@
|
||||||
}
|
}
|
||||||
/* urlbarView-url is forced to be LTR for RTL locales, so set the padding based on the browser's directionality. */
|
/* urlbarView-url is forced to be LTR for RTL locales, so set the padding based on the browser's directionality. */
|
||||||
.urlbarView-results[wrap] > .urlbarView-row[has-url] > .urlbarView-row-inner > .urlbarView-url:-moz-locale-dir(ltr) {
|
.urlbarView-results[wrap] > .urlbarView-row[has-url] > .urlbarView-row-inner > .urlbarView-url:-moz-locale-dir(ltr) {
|
||||||
padding-left: calc(@urlbarViewItemInlinePadding@ + @identityBoxMarginInlineEnd@ + @urlbarViewFaviconWidth@);
|
padding-left: calc(@urlbarViewItemInlinePadding@ + @identityBoxMarginInline@ + @urlbarViewFaviconWidth@);
|
||||||
}
|
}
|
||||||
.urlbarView-results[wrap] > .urlbarView-row[has-url] > .urlbarView-row-inner > .urlbarView-url:-moz-locale-dir(rtl) {
|
.urlbarView-results[wrap] > .urlbarView-row[has-url] > .urlbarView-row-inner > .urlbarView-url:-moz-locale-dir(rtl) {
|
||||||
padding-right: calc(@urlbarViewItemInlinePadding@ + @identityBoxMarginInlineEnd@ + @urlbarViewFaviconWidth@);
|
padding-right: calc(@urlbarViewItemInlinePadding@ + @identityBoxMarginInline@ + @urlbarViewFaviconWidth@);
|
||||||
}
|
}
|
||||||
/* Note: switchtab entries show the url only in override mode,
|
/* Note: switchtab entries show the url only in override mode,
|
||||||
remotetab and sponsored ones only when selected or :hover. */
|
remotetab and sponsored ones only when selected or :hover. */
|
||||||
|
@ -161,7 +161,7 @@
|
||||||
}
|
}
|
||||||
.urlbarView-results[wrap] > .urlbarView-row[type=tabtosearch] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-action {
|
.urlbarView-results[wrap] > .urlbarView-row[type=tabtosearch] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-action {
|
||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
margin-inline-start: calc(@urlbarViewItemInlinePadding@ + @identityBoxMarginInlineEnd@ + @urlbarViewFaviconWidth@);
|
margin-inline-start: calc(@urlbarViewItemInlinePadding@ + @identityBoxMarginInline@ + @urlbarViewFaviconWidth@);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче