From 074847dd09967d5de27edc282c0ec3c7a640c4e5 Mon Sep 17 00:00:00 2001 From: "Mr. M" Date: Thu, 2 Oct 2025 22:22:35 +0200 Subject: [PATCH] feat: Finished implementation of the panel, b=no-bug, c=common, compact-mode, workspaces --- locales/en-US/browser/browser/zen-general.ftl | 3 + prefs/zen-urlbar.yaml | 3 + .../base/content/browser-pageActions-js.patch | 12 +++ .../base/content/zen-commands.inc.xhtml | 1 + .../base/content/zen-panels/site-data.inc | 12 ++- src/browser/themes/shared/zen-icons/icons.css | 28 ++++--- src/zen/common/ZenCustomizableUI.sys.mjs | 4 + src/zen/common/styles/zen-omnibox.css | 33 ++++---- .../common/styles/zen-single-components.css | 77 +++++++++++++++++++ src/zen/common/zen-sets.js | 3 + src/zen/compact-mode/ZenCompactMode.mjs | 35 ++++++--- src/zen/urlbar/ZenSiteDataPanel.sys.mjs | 70 ++++++++++++++--- src/zen/workspaces/zen-workspaces.css | 1 + 13 files changed, 232 insertions(+), 50 deletions(-) create mode 100644 src/browser/base/content/browser-pageActions-js.patch diff --git a/locales/en-US/browser/browser/zen-general.ftl b/locales/en-US/browser/browser/zen-general.ftl index f21b87b76..77f8a014b 100644 --- a/locales/en-US/browser/browser/zen-general.ftl +++ b/locales/en-US/browser/browser/zen-general.ftl @@ -49,6 +49,9 @@ zen-library-sidebar-workspaces = zen-library-sidebar-mods = .label = Mods +zen-toggle-compact-mode-button = + .tooltiptext = Toggle Compact Mode + # note: Do not translate the "
" tags in the following string zen-learn-more-text = Learn More diff --git a/prefs/zen-urlbar.yaml b/prefs/zen-urlbar.yaml index b9b0533d4..97be59be9 100644 --- a/prefs/zen-urlbar.yaml +++ b/prefs/zen-urlbar.yaml @@ -8,6 +8,9 @@ - name: zen.urlbar.show-protections-icon value: false +- name: zen.urlbar.show-contextual-id + value: false + - name: zen.urlbar.behavior value: floating-on-type diff --git a/src/browser/base/content/browser-pageActions-js.patch b/src/browser/base/content/browser-pageActions-js.patch new file mode 100644 index 000000000..197789f45 --- /dev/null +++ b/src/browser/base/content/browser-pageActions-js.patch @@ -0,0 +1,12 @@ +diff --git a/browser/base/content/browser-pageActions.js b/browser/base/content/browser-pageActions.js +index 00da33bc11189db17b6a2e656acb3a778531197c..9571155baccad9a886cbe9c7bf0bd76a135331c4 100644 +--- a/browser/base/content/browser-pageActions.js ++++ b/browser/base/content/browser-pageActions.js +@@ -451,6 +451,7 @@ var BrowserPageActions = { + ), + document.getElementById(this.mainButtonNode.id), + document.getElementById("identity-icon"), ++ document.getElementById("zen-site-data-icon-button"), + ]; + for (let node of potentialAnchorNodes) { + if (node && !node.hidden) { diff --git a/src/browser/base/content/zen-commands.inc.xhtml b/src/browser/base/content/zen-commands.inc.xhtml index aad8b0c74..48a39f105 100644 --- a/src/browser/base/content/zen-commands.inc.xhtml +++ b/src/browser/base/content/zen-commands.inc.xhtml @@ -9,6 +9,7 @@ + diff --git a/src/browser/base/content/zen-panels/site-data.inc b/src/browser/base/content/zen-panels/site-data.inc index 54737bdf6..dab190c80 100644 --- a/src/browser/base/content/zen-panels/site-data.inc +++ b/src/browser/base/content/zen-panels/site-data.inc @@ -16,11 +16,17 @@ mainview-with-header="true"> + data-l10n-id="zen-site-data-share" + flex="1" /> + command="View:ReaderView" + flex="1" /> + command="Browser:Screenshot" + flex="1" /> + diff --git a/src/browser/themes/shared/zen-icons/icons.css b/src/browser/themes/shared/zen-icons/icons.css index 016e8b19a..8dff5e399 100644 --- a/src/browser/themes/shared/zen-icons/icons.css +++ b/src/browser/themes/shared/zen-icons/icons.css @@ -54,7 +54,8 @@ } #sidebar-button:-moz-locale-dir(ltr):not([positionend]), -#sidebar-button:-moz-locale-dir(rtl)[positionend] { +#sidebar-button:-moz-locale-dir(rtl)[positionend], +#zen-toggle-compact-mode { list-style-image: url('chrome://browser/skin/sidebars.svg') !important; } @@ -265,6 +266,7 @@ } #bookmarks-menu-button, +#zen-site-data-header-bookmark, #appMenu-bookmarks-button, #sidebar-switcher-bookmarks, #appMenu-library-bookmarks-button, @@ -409,7 +411,8 @@ list-style-image: url('customize.svg') !important; } -#zen-copy-current-url-button { +#zen-copy-current-url-button, +#zen-site-data-header-share { list-style-image: url('share.svg'); } @@ -469,14 +472,19 @@ /* permissions */ #identity-permission-box, -#identity-icon-box { +#identity-box:not([pageproxystate='invalid']) #identity-icon-box, +#identity-box[pageproxystate='invalid'] #zen-site-data-icon-button { display: none !important; } -#zen-site-data-icon-button image { - list-style-image: url('permissions.svg'); - -moz-context-properties: fill, fill-opacity; - pointer-events: none; +#zen-site-data-icon-button { + padding: 0 6px; + + & image { + list-style-image: url('permissions.svg'); + -moz-context-properties: fill, fill-opacity; + pointer-events: none; + } } .geo-icon { @@ -504,7 +512,8 @@ list-style-image: url('desktop-notification-blocked.svg') !important; } -.camera-icon { +.camera-icon, +#zen-site-data-header-screenshot { list-style-image: url('camera.svg') !important; } @@ -608,7 +617,8 @@ background-image: url('stop-to-reload.svg') !important; } -#reader-mode-button > .urlbar-icon { +#reader-mode-button > .urlbar-icon, +#zen-site-data-header-reader-mode { list-style-image: url('reader-mode.svg') !important; } diff --git a/src/zen/common/ZenCustomizableUI.sys.mjs b/src/zen/common/ZenCustomizableUI.sys.mjs index 0ce977d6d..329eb2e8f 100644 --- a/src/zen/common/ZenCustomizableUI.sys.mjs +++ b/src/zen/common/ZenCustomizableUI.sys.mjs @@ -67,6 +67,10 @@ export var ZenCustomizableUI = new (class { addon-webext-overflowtarget="overflowed-extensions-list" mode="icons"> + diff --git a/src/zen/common/styles/zen-omnibox.css b/src/zen/common/styles/zen-omnibox.css index a216a1482..5b245f5f9 100644 --- a/src/zen/common/styles/zen-omnibox.css +++ b/src/zen/common/styles/zen-omnibox.css @@ -129,7 +129,8 @@ visibility: collapse; #navigator-toolbox:hover &, - &[open] { + &[open], + #identity-box[pageproxystate='invalid'] & { opacity: 1; visibility: visible; } @@ -234,7 +235,7 @@ } :root[zen-single-toolbar='true'] { - --urlbar-icon-border-radius: 10px !important; + --urlbar-icon-border-radius: 8px !important; .urlbar-page-action:not([open]):not([showing]):not(#identity-permission-box), #tracking-protection-icon-container { @@ -249,10 +250,6 @@ display: none; } - #urlbar:not([open]) #userContext-icons { - margin-inline: 0; - } - #urlbar:not([breakout-extend='true']) { #identity-box:not([pageproxystate='invalid']) { order: 2; @@ -325,10 +322,6 @@ } @container urlbar-container (width < 350px) { - #userContext-icons { - transition: all 0.1s ease; - } - #userContext-label { display: none; } @@ -336,12 +329,6 @@ #userContext-indicator { margin-inline-end: 4px; } - - #urlbar:hover:not([breakout-extend='true']) #userContext-icons { - margin-inline-end: calc(-16px - 2 * var(--urlbar-icon-padding)) !important; - opacity: 0; - pointer-events: none; - } } #notification-popup-box { @@ -674,5 +661,17 @@ padding: 0px; } -#reader-mode-button { +/* These are buttons that we dont need to be + * displayed anymore, since now zen displays + * them into a single, unified button */ +#reader-mode-button, +#urlbar-go-button, +#star-button-box { + display: none !important; +} + +@media not -moz-pref('zen.urlbar.show-contextual-id') { + #userContext-icons { + display: none !important; + } } diff --git a/src/zen/common/styles/zen-single-components.css b/src/zen/common/styles/zen-single-components.css index f77bf2ef4..375631311 100644 --- a/src/zen/common/styles/zen-single-components.css +++ b/src/zen/common/styles/zen-single-components.css @@ -460,3 +460,80 @@ body > #confetti { #unified-extensions-button:not([showing]) { display: none !important; } + +#zen-site-data-header { + gap: 6px; + align-items: center; + padding: 8px; + padding-bottom: 0; + + & toolbarbutton { + margin: 0; + appearance: none; + -moz-context-properties: fill; + fill: currentColor; + color: light-dark(rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.8)); + padding: 8px 0px; + position: relative; + + &[disabled] { + opacity: 0.5; + pointer-events: none; + } + + & .toolbarbutton-text { + display: none; + } + + & image { + width: 18px; + pointer-events: none; + z-index: 1; + } + + &::before { + content: ''; + position: absolute; + inset: 1px; + background: linear-gradient( + to bottom, + color-mix( + in srgb, + light-dark(rgba(255, 255, 255, 1), rgba(0, 0, 0, 0.3)) 15%, + transparent 100% + ), + color-mix( + in srgb, + light-dark(rgba(255, 255, 255, 0.8), rgba(0, 0, 0, 0.8)) 100%, + transparent 100% + ) + ); + transition: transform 0.12s ease-in-out; + box-shadow: 0px 2px 3px 1px rgba(0, 0, 0, 0.1); + border-radius: 6px; + --base-border-color: light-dark(rgba(0, 0, 0, 0.3), rgba(255, 255, 255, 0.1)); + border: 1px solid; + border-top-color: light-dark(var(--base-border-color), rgba(255, 255, 255, 0.12)); + border-left-color: light-dark(var(--base-border-color), transparent); + border-right-color: light-dark(var(--base-border-color), transparent); + border-bottom-color: light-dark(var(--base-border-color), rgba(0, 0, 0, 0.12)); + will-change: transform; + } + + &.active { + color: var(--button-primary-color); + + &::before { + background: var(--button-primary-bgcolor); + } + } + + &:hover::before { + transform: scale(1.03); + } + + &:active:hover::before { + transform: scale(0.97); + } + } +} diff --git a/src/zen/common/zen-sets.js b/src/zen/common/zen-sets.js index 5d8316589..9cb289a35 100644 --- a/src/zen/common/zen-sets.js +++ b/src/zen/common/zen-sets.js @@ -29,6 +29,9 @@ document.addEventListener( case 'cmd_zenCompactModeShowToolbar': gZenCompactModeManager.toggleToolbar(); break; + case 'cmd_toggleCompactModeIgnoreHover': + gZenCompactModeManager.toggle(true); + break; case 'cmd_zenWorkspaceForward': gZenWorkspaces.changeWorkspaceShortcut(); break; diff --git a/src/zen/compact-mode/ZenCompactMode.mjs b/src/zen/compact-mode/ZenCompactMode.mjs index 0606498ff..28a9e1a16 100644 --- a/src/zen/compact-mode/ZenCompactMode.mjs +++ b/src/zen/compact-mode/ZenCompactMode.mjs @@ -115,6 +115,7 @@ var gZenCompactModeManager = { // We wont do anything with it anyway, so we remove it delete this._wasInCompactMode; } + delete this._ignoreNextHover; // We dont want the user to be able to spam the button return; } @@ -308,6 +309,9 @@ var gZenCompactModeManager = { if (canAnimate) { this.sidebar.setAttribute('animate', 'true'); } + if (this._ignoreNextHover) { + this.sidebar.removeAttribute('zen-has-hover'); + } this.sidebar.style.removeProperty('margin-right'); this.sidebar.style.removeProperty('margin-left'); this.sidebar.style.removeProperty('transform'); @@ -335,20 +339,19 @@ var gZenCompactModeManager = { } else { sidebarWidth -= elementSeparation; } - this.sidebar.style.marginRight = '0px'; - this.sidebar.style.marginLeft = '0px'; + this.sidebar.removeAttribute('zen-has-hover'); gZenUIManager.motion .animate( this.sidebar, { - marginRight: this.sidebarIsOnRight ? `-${sidebarWidth}px` : 0, - marginLeft: this.sidebarIsOnRight ? 0 : `-${sidebarWidth}px`, + marginRight: [0, this.sidebarIsOnRight ? `-${sidebarWidth}px` : 0], + marginLeft: [0, this.sidebarIsOnRight ? 0 : `-${sidebarWidth}px`], }, { ease: 'easeIn', type: 'spring', bounce: 0, - duration: 0.15, + duration: 0.12, } ) .then(() => { @@ -365,6 +368,12 @@ var gZenCompactModeManager = { this._ignoreNextResize = true; setTimeout(() => { + if (this._ignoreNextHover) { + setTimeout(() => { + delete this._ignoreNextHover; + }); + } + this.sidebar.style.removeProperty('margin-right'); this.sidebar.style.removeProperty('margin-left'); this.sidebar.style.removeProperty('transition'); @@ -375,6 +384,7 @@ var gZenCompactModeManager = { titlebar.style.removeProperty('transition'); gURLBar.textbox.style.removeProperty('visibility'); + resolve(); }); }); @@ -399,7 +409,7 @@ var gZenCompactModeManager = { ease: 'easeOut', type: 'spring', bounce: 0, - duration: 0.15, + duration: 0.12, } ) .then(() => { @@ -448,7 +458,9 @@ var gZenCompactModeManager = { } }, - toggle() { + toggle(ignoreHover = false) { + // Only ignore the next hover when we are enabling compact mode + this._ignoreNextHover = ignoreHover && !this.preference; return (this.preference = !this.preference); }, @@ -551,7 +563,8 @@ var gZenCompactModeManager = { window.requestAnimationFrame(() => { if ( document.documentElement.getAttribute('supress-primary-adjustment') === 'true' || - this._hasHoveredUrlbar + this._hasHoveredUrlbar || + this._ignoreNextHover ) { return; } @@ -596,7 +609,8 @@ var gZenCompactModeManager = { event.explicitOriginalTarget.closest('#urlbar[zen-floating-urlbar]') || (document.documentElement.getAttribute('supress-primary-adjustment') === 'true' && gZenVerticalTabsManager._hasSetSingleToolbar) || - this._hasHoveredUrlbar + this._hasHoveredUrlbar || + this._ignoreNextHover ) { return; } @@ -699,6 +713,9 @@ var gZenCompactModeManager = { }, isSidebarPotentiallyOpen() { + if (this._ignoreNextHover) { + this.sidebar.removeAttribute('zen-has-hover'); + } return ( this.sidebar.hasAttribute('zen-user-show') || this.sidebar.hasAttribute('zen-has-hover') || diff --git a/src/zen/urlbar/ZenSiteDataPanel.sys.mjs b/src/zen/urlbar/ZenSiteDataPanel.sys.mjs index e917b33c3..b948cafd0 100644 --- a/src/zen/urlbar/ZenSiteDataPanel.sys.mjs +++ b/src/zen/urlbar/ZenSiteDataPanel.sys.mjs @@ -38,13 +38,19 @@ export class nsZenSiteDataPanel { #initEventListeners() { this.panel.addEventListener('popupshowing', this); - this.document - .getElementById('zen-site-data-new-addon-button') - .addEventListener('command', this); this.document.getElementById('zen-site-data-manage-addons').addEventListener('click', this); this.document.getElementById('zen-site-data-settings-more').addEventListener('click', this); - this.document.getElementById('zen-site-data-security-info').addEventListener('command', this); - this.document.getElementById('zen-site-data-actions').addEventListener('command', this); + const kCommandIDs = [ + 'zen-site-data-header-share', + 'zen-site-data-header-bookmark', + 'zen-site-data-security-info', + 'zen-site-data-actions', + 'zen-site-data-new-addon-button', + ]; + + for (let id of kCommandIDs) { + this.document.getElementById(id).addEventListener('command', this); + } this.#initContextMenuEventListener(); } @@ -71,6 +77,47 @@ export class nsZenSiteDataPanel { #preparePanel() { this.#setSitePermissions(); this.#setSiteSecurityInfo(); + this.#setSiteHeader(); + } + + #setSiteHeader() { + const { gReaderMode } = this.window; + + { + const button = this.document.getElementById('zen-site-data-header-reader-mode'); + const urlbarButton = this.window.document.getElementById('reader-mode-button'); + const isActive = gReaderMode?.isActive; + const isVisible = (urlbarButton && !urlbarButton.hidden) || isActive; + + button.disabled = !isVisible; + if (isActive) { + button.classList.add('active'); + } else { + button.classList.remove('active'); + } + this.document.l10n.setAttributes(button, urlbarButton?.getAttribute('data-l10n-id')); + } + { + const button = this.document.getElementById('zen-site-data-header-bookmark'); + const isPageBookmarked = this.window.BookmarkingUI.star?.hasAttribute('starred'); + + if (isPageBookmarked) { + button.classList.add('active'); + } else { + button.classList.remove('active'); + } + } + { + const button = this.document.getElementById('zen-site-data-header-share'); + if ( + this.window.gBrowser.currentURI.schemeIs('http') || + this.window.gBrowser.currentURI.schemeIs('https') + ) { + button.removeAttribute('disabled'); + } else { + button.setAttribute('disabled', 'true'); + } + } } #setSiteSecurityInfo() { @@ -139,9 +186,7 @@ export class nsZenSiteDataPanel { if (this._sharingState?.geo) { let geoPermission = permissions.find((perm) => perm.id === 'geo'); - if (geoPermission) { - geoPermission.sharingState = true; - } else { + if (!geoPermission) { permissions.push({ id: 'geo', state: SitePermissions.ALLOW, @@ -153,9 +198,7 @@ export class nsZenSiteDataPanel { if (this._sharingState?.xr) { let xrPermission = permissions.find((perm) => perm.id === 'xr'); - if (xrPermission) { - xrPermission.sharingState = true; - } else { + if (!xrPermission) { permissions.push({ id: 'xr', state: SitePermissions.ALLOW, @@ -178,7 +221,6 @@ export class nsZenSiteDataPanel { continue; } found = true; - permission.sharingState = webrtcState[id]; } if (!found) { // If the ALLOW permission item we were looking for doesn't exist, @@ -313,6 +355,10 @@ export class nsZenSiteDataPanel { ); break; } + case 'zen-site-data-header-bookmark': { + this.window.BookmarkingUI.onStarCommand(event); + break; + } } } diff --git a/src/zen/workspaces/zen-workspaces.css b/src/zen/workspaces/zen-workspaces.css index 5ac09c7c2..0946b6dd5 100644 --- a/src/zen/workspaces/zen-workspaces.css +++ b/src/zen/workspaces/zen-workspaces.css @@ -152,6 +152,7 @@ /* Mark workspaces indicator */ .zen-current-workspace-indicator { + margin-top: 1px; padding: calc(2px + var(--tab-inline-padding) + var(--zen-toolbox-padding)); font-weight: 500; position: relative;