diff --git a/locales/en-US/browser/browser/zen-general.ftl b/locales/en-US/browser/browser/zen-general.ftl
index 708bc05d9..bea40c496 100644
--- a/locales/en-US/browser/browser/zen-general.ftl
+++ b/locales/en-US/browser/browser/zen-general.ftl
@@ -64,3 +64,6 @@ zen-icons-picker-svg =
.label = Icons
urlbar-search-mode-zen_actions = Actions
+zen-site-data-settings = Settings
+
+zen-generic-manage = Manage
diff --git a/src/browser/base/content/browser-addons-js.patch b/src/browser/base/content/browser-addons-js.patch
index 318539af9..968b5f924 100644
--- a/src/browser/base/content/browser-addons-js.patch
+++ b/src/browser/base/content/browser-addons-js.patch
@@ -1,5 +1,5 @@
diff --git a/browser/base/content/browser-addons.js b/browser/base/content/browser-addons.js
-index d7542a38a0242dd9c9c6390171d59992d75a0c19..d20e5a9fa42c88c7ba28fac1ef13dd693f1f1135 100644
+index d7542a38a0242dd9c9c6390171d59992d75a0c19..e3bda9bc28aeca7258fcd91fa1a4719b4950e28b 100644
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -1064,7 +1064,7 @@ var gXPInstallObserver = {
@@ -20,7 +20,20 @@ index d7542a38a0242dd9c9c6390171d59992d75a0c19..d20e5a9fa42c88c7ba28fac1ef13dd69
},
};
-@@ -2608,7 +2608,7 @@ var gUnifiedExtensions = {
+@@ -2509,11 +2509,7 @@ var gUnifiedExtensions = {
+ // Lazy load the unified-extensions-panel panel the first time we need to
+ // display it.
+ if (!this._panel) {
+- let template = document.getElementById(
+- "unified-extensions-panel-template"
+- );
+- template.replaceWith(template.content);
+- this._panel = document.getElementById("unified-extensions-panel");
++ this._panel = document.getElementById("zen-unified-site-data-panel");
+ let customizationArea = this._panel.querySelector(
+ "#unified-extensions-area"
+ );
+@@ -2608,7 +2604,7 @@ var gUnifiedExtensions = {
this.recordButtonTelemetry(reason || "extensions_panel_showing");
this.ensureButtonShownBeforeAttachingPanel(panel);
PanelMultiView.openPopup(panel, this._button, {
@@ -29,7 +42,7 @@ index d7542a38a0242dd9c9c6390171d59992d75a0c19..d20e5a9fa42c88c7ba28fac1ef13dd69
triggerEvent: aEvent,
});
}
-@@ -2795,18 +2795,20 @@ var gUnifiedExtensions = {
+@@ -2795,18 +2791,20 @@ var gUnifiedExtensions = {
this._maybeMoveWidgetNodeBack(widgetId);
}
diff --git a/src/browser/base/content/zen-panels/site-data.inc b/src/browser/base/content/zen-panels/site-data.inc
new file mode 100644
index 000000000..88ed567d3
--- /dev/null
+++ b/src/browser/base/content/zen-panels/site-data.inc
@@ -0,0 +1,65 @@
+# 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/.
+
+
+
+# We'll keep the view with this name/id in order to prevent
+# any sort of future issues we may have if firefox decides
+# to change the functionality of this view
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Keep this button on the DOM even though we hide it for ever,
+# again, to keep firefox happy if they decide to change functionality
+# for this specific button / id
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/browser/base/content/zen-popupset.inc.xhtml b/src/browser/base/content/zen-popupset.inc.xhtml
index 3a812435a..e58a85c4c 100644
--- a/src/browser/base/content/zen-popupset.inc.xhtml
+++ b/src/browser/base/content/zen-popupset.inc.xhtml
@@ -5,5 +5,6 @@
#include zen-panels/gradient-generator.inc
#include zen-panels/emojis-picker.inc
#include zen-panels/folders-search.inc
+#include zen-panels/site-data.inc
#include zen-panels/popups.inc
diff --git a/src/browser/themes/shared/zen-icons/icons.css b/src/browser/themes/shared/zen-icons/icons.css
index fec5a4d24..a7f516d8e 100644
--- a/src/browser/themes/shared/zen-icons/icons.css
+++ b/src/browser/themes/shared/zen-icons/icons.css
@@ -74,7 +74,8 @@
}
#appMenu-zoom-controls,
-#PanelUI-zen-gradient-generator-color-add {
+#PanelUI-zen-gradient-generator-color-add,
+#zen-site-data-new-addon-button {
list-style-image: url('plus.svg') !important;
}
@@ -466,8 +467,14 @@
}
/* permissions */
-#permissions-granted-icon {
- list-style-image: url('permissions.svg') !important;
+#identity-permission-box,
+#identity-icon-box {
+ display: none !important;
+}
+
+#zen-site-data-icon {
+ list-style-image: url('permissions.svg');
+ -moz-context-properties: fill, fill-opacity;
}
.geo-icon {
diff --git a/src/zen/common/ZenUIManager.mjs b/src/zen/common/ZenUIManager.mjs
index c98f8fdca..78f17b3a2 100644
--- a/src/zen/common/ZenUIManager.mjs
+++ b/src/zen/common/ZenUIManager.mjs
@@ -1,6 +1,11 @@
// 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/.
+
+ChromeUtils.defineESModuleGetters(this, {
+ nsZenSiteDataPanel: 'resource:///modules/ZenSiteDataPanel.sys.mjs',
+});
+
var gZenUIManager = {
_popupTrackingElements: [],
_hoverPausedForExpand: false,
@@ -14,19 +19,6 @@ var gZenUIManager = {
init() {
document.addEventListener('popupshowing', this.onPopupShowing.bind(this));
document.addEventListener('popuphidden', this.onPopupHidden.bind(this));
- XPCOMUtils.defineLazyPreferenceGetter(
- this,
- 'contentElementSeparation',
- 'zen.theme.content-element-separation',
- 0
- );
- XPCOMUtils.defineLazyPreferenceGetter(this, 'urlbarWaitToClear', 'zen.urlbar.wait-to-clear', 0);
- XPCOMUtils.defineLazyPreferenceGetter(
- this,
- 'urlbarShowDomainOnly',
- 'zen.urlbar.show-domain-only-in-sidebar',
- true
- );
document.addEventListener('mousedown', this.handleMouseDown.bind(this), true);
@@ -44,6 +36,8 @@ var gZenUIManager = {
return document.getElementById('zen-toast-container');
});
+ window.gZenSiteDataPanel = new nsZenSiteDataPanel(window);
+
gURLBar._zenTrimURL = this.urlbarTrim.bind(this);
new ResizeObserver(
@@ -596,6 +590,26 @@ var gZenUIManager = {
},
};
+XPCOMUtils.defineLazyPreferenceGetter(
+ gZenUIManager,
+ 'contentElementSeparation',
+ 'zen.theme.content-element-separation',
+ 0
+);
+
+XPCOMUtils.defineLazyPreferenceGetter(
+ gZenUIManager,
+ 'urlbarWaitToClear',
+ 'zen.urlbar.wait-to-clear',
+ 0
+);
+XPCOMUtils.defineLazyPreferenceGetter(
+ gZenUIManager,
+ 'urlbarShowDomainOnly',
+ 'zen.urlbar.show-domain-only-in-sidebar',
+ true
+);
+
var gZenVerticalTabsManager = {
init() {
this._multiWindowFeature = new nsZenMultiWindowFeature();
diff --git a/src/zen/common/styles/zen-omnibox.css b/src/zen/common/styles/zen-omnibox.css
index 421641b4f..3be04ae0d 100644
--- a/src/zen/common/styles/zen-omnibox.css
+++ b/src/zen/common/styles/zen-omnibox.css
@@ -224,17 +224,7 @@
display: none;
}
- #identity-box:not([pageproxystate='invalid']):not(.notSecure) #identity-icon-box:not([open]) {
- margin-inline-start: calc(-8px - 2 * var(--urlbar-icon-padding));
- transform: translateX(100%);
- opacity: 0;
-
- :root:not([supress-primary-adjustment]) & {
- transition: all 0.1s ease;
- }
- }
-
- #identity-permission-box > *:not(#permissions-granted-icon) {
+ #identity-permission-box > *:not(#zen-site-data-icon) {
visibility: collapse;
}
@@ -242,25 +232,11 @@
display: none;
}
- #urlbar[open]
- :is(#tracking-protection-icon-container, .urlbar-page-action, .identity-box-button):not(
- [hidden]
- ):not(#identity-permission-box),
- #urlbar:hover #identity-icon-box {
- opacity: 1 !important;
- margin-inline-start: 0 !important;
- transform: none !important;
- display: flex;
- #urlbar:not(:hover) & {
- transition: none;
- }
- }
-
#urlbar:not([open]) #userContext-icons {
margin-inline: 0;
}
- #urlbar:not([open]) {
+ #urlbar:not([breakout-extend='true']) {
#identity-box:not([pageproxystate='invalid']) {
order: 2;
}
diff --git a/src/zen/common/styles/zen-popup.css b/src/zen/common/styles/zen-popup.css
index 5eceee4eb..ecc8b78f7 100644
--- a/src/zen/common/styles/zen-popup.css
+++ b/src/zen/common/styles/zen-popup.css
@@ -241,12 +241,6 @@ panel {
margin-inline: 0;
}
-#identity-popup-mainView > toolbarseparator:first-child,
-#unified-extensions-view > toolbarseparator:first-child {
- display: none;
- opacity: 0;
-}
-
menupopup,
panel {
box-shadow: none;
diff --git a/src/zen/common/styles/zen-single-components.css b/src/zen/common/styles/zen-single-components.css
index 8bdaa80c0..1cc267dd5 100644
--- a/src/zen/common/styles/zen-single-components.css
+++ b/src/zen/common/styles/zen-single-components.css
@@ -261,3 +261,82 @@ body > #confetti {
#customization-container {
--toolbar-bgcolor: var(--zen-dialog-background);
}
+
+/* Site Data popup */
+
+#zen-unified-site-data-panel {
+ --panel-padding: 14px;
+ --panel-width: 250px;
+ --menu-panel-width-wide: calc(var(--panel-width) - var(--panel-padding) * 2);
+ --uei-icon-size: 16px;
+ --arrowpanel-menuitem-border-radius: 10px;
+}
+
+#unified-extensions-messages-container {
+ display: none;
+}
+
+#zen-site-data-addons {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+
+ .unified-extensions-item-name,
+ .unified-extensions-item-message,
+ .unified-extensions-item-message-hover,
+ .unified-extensions-item-message-hover-menu-button,
+ .unified-extensions-item-menu-button {
+ display: none;
+ }
+
+ #overflowed-extensions-list,
+ #unified-extensions-area,
+ .unified-extensions-list,
+ #zen-site-data-new-addon-button-container {
+ display: contents;
+
+ &:empty {
+ display: none;
+ }
+
+ & > * {
+ background-color: color-mix(in srgb, currentcolor 6%, transparent) !important;
+ width: 48px;
+ height: 32px;
+ margin: 0;
+ justify-content: center;
+ align-items: center;
+ border-radius: 6px;
+
+ & .toolbarbutton-badge-stack {
+ margin: 0;
+ }
+ }
+ }
+}
+
+.zen-site-data-section {
+ gap: 8px;
+ padding-bottom: 20px;
+}
+
+.zen-site-data-section-header {
+ font-weight: 600;
+
+ & label {
+ margin: 0;
+ }
+
+ & > label:nth-child(2) {
+ transition: opacity 0.15s ease-in-out;
+ opacity: 0;
+
+ .zen-site-data-section:hover & {
+ opacity: 0.8;
+ }
+ }
+}
+
+#zen-site-data-new-addon-button .toolbarbutton-text {
+ display: none;
+}
diff --git a/src/zen/urlbar/ZenSiteDataPanel.sys.mjs b/src/zen/urlbar/ZenSiteDataPanel.sys.mjs
new file mode 100644
index 000000000..d379c8f73
--- /dev/null
+++ b/src/zen/urlbar/ZenSiteDataPanel.sys.mjs
@@ -0,0 +1,163 @@
+/* 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/. */
+
+export class nsZenSiteDataPanel {
+ constructor(window) {
+ this.window = window;
+ this.document = window.document;
+
+ this.panel = this.document.getElementById('zen-unified-site-data-panel');
+ this.#init();
+ }
+
+ #init() {
+ // Add a new button to the urlbar popup
+ const button = this.window.MozXULElement.parseXULToFragment(`
+
+
+
+ `);
+ this.document.getElementById('identity-icon-box').after(button);
+ button.addEventListener('command', this);
+
+ // Remove the old permissions dialog
+ this.document.getElementById('unified-extensions-panel-template').remove();
+ }
+
+ show() {
+ this.#preparePanel();
+ }
+
+ #preparePanel() {
+ this.#setSitePermissions();
+ }
+
+ #setSitePermissions() {
+ const { gBrowser, SitePermissions } = this.window;
+ const list = this.document.getElementById('zen-site-data-settings-list');
+ const section = list.closest('.zen-site-data-section');
+
+ // show permission icons
+ let permissions = SitePermissions.getAllPermissionDetailsForBrowser(gBrowser.selectedBrowser);
+
+ // Don't display origin-keyed 3rdPartyStorage permissions that are covered by
+ // site-keyed 3rdPartyFrameStorage permissions.
+ let thirdPartyStorageSites = new Set(
+ permissions
+ .map(function (permission) {
+ let [id, key] = permission.id.split(SitePermissions.PERM_KEY_DELIMITER);
+ if (id == '3rdPartyFrameStorage') {
+ return key;
+ }
+ return null;
+ })
+ .filter(function (key) {
+ return key != null;
+ })
+ );
+ permissions = permissions.filter(function (permission) {
+ let [id, key] = permission.id.split(SitePermissions.PERM_KEY_DELIMITER);
+ if (id != '3rdPartyStorage') {
+ return true;
+ }
+ try {
+ let origin = Services.io.newURI(key);
+ let site = Services.eTLD.getSite(origin);
+ return !thirdPartyStorageSites.has(site);
+ } catch {
+ return false;
+ }
+ });
+
+ 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 are in use, we need to find
+ // the associated ALLOW 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) {
+ let [permId] = permission.id.split(SitePermissions.PERM_KEY_DELIMITER);
+ if (permId != id || permission.state != SitePermissions.ALLOW) {
+ continue;
+ }
+ found = true;
+ permission.sharingState = webrtcState[id];
+ }
+ if (!found) {
+ // If the ALLOW 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],
+ });
+ }
+ }
+ }
+ }
+
+ list.innerHTML = '';
+ let totalBlockedPopups = gBrowser.selectedBrowser.popupBlocker.getBlockedPopupCount();
+ 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 = this.#createPermissionItem(id, key, permission);
+ if (item) {
+ list.appendChild(item);
+ }
+ }
+
+ section.hidden = list.childElementCount == 0;
+ }
+
+ #createPermissionItem(id, key, permission) {}
+
+ handleEvent(event) {
+ const type = event.type;
+ switch (type) {
+ case 'command':
+ this.show();
+ break;
+ }
+ }
+}
diff --git a/src/zen/urlbar/moz.build b/src/zen/urlbar/moz.build
index 1e331db90..f321a86bb 100644
--- a/src/zen/urlbar/moz.build
+++ b/src/zen/urlbar/moz.build
@@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [
+ "ZenSiteDataPanel.sys.mjs",
"ZenUBActionsProvider.sys.mjs",
"ZenUBGlobalActions.sys.mjs",
"ZenUBProvider.sys.mjs",