From 94e43dbfd56f942514c83f41edcf07264d129b9e Mon Sep 17 00:00:00 2001 From: EnderDev Date: Wed, 22 Nov 2023 21:30:18 +0000 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20browser-status?= =?UTF-8?q?=20element=20to=20work=20with=20new=20context=20system?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BrowserCustomizableComponents.sys.mjs | 2 + .../tabs/content/browser-internal-tab.js | 29 +++++ components/tabs/content/browser-status.css | 122 +++++++++++------- components/tabs/content/browser-status.js | 45 ++++--- 4 files changed, 136 insertions(+), 62 deletions(-) diff --git a/components/customizableui/BrowserCustomizableComponents.sys.mjs b/components/customizableui/BrowserCustomizableComponents.sys.mjs index b0cbbf147e..15f1ca9a51 100644 --- a/components/customizableui/BrowserCustomizableComponents.sys.mjs +++ b/components/customizableui/BrowserCustomizableComponents.sys.mjs @@ -43,6 +43,8 @@ export const BrowserCustomizableComponents = { return html("button", { is: args.is }); case "web-contents": return html("browser-web-contents"); + case "tab-status": + return html("browser-status"); case "": return doc.createDocumentFragment(); default: diff --git a/components/tabs/content/browser-internal-tab.js b/components/tabs/content/browser-internal-tab.js index e05ae7f7c6..6bbfd0a3af 100644 --- a/components/tabs/content/browser-internal-tab.js +++ b/components/tabs/content/browser-internal-tab.js @@ -272,6 +272,10 @@ class BrowserTab extends MozElements.MozTab { console.log("initted event listeners for", this.id); this.webContents.addEventListener("pagetitlechanged", this); + this.webContents.addEventListener( + "BrowserTabs::BrowserStatusChange", + this + ); // Ensure site identity is initialised this._siteIdentity = new TabIdentityHandler(this); @@ -303,6 +307,10 @@ class BrowserTab extends MozElements.MozTab { window.removeEventListener("BrowserTabs::BrowserLocationChange", this); this.webContents.removeEventListener("pagetitlechanged", this); + this.webContents.removeEventListener( + "BrowserTabs::BrowserStatusChange", + this + ); } /** @@ -314,6 +322,9 @@ class BrowserTab extends MozElements.MozTab { case "BrowserTabs::TabSelect": this._onTabSelected(event); break; + case "BrowserTabs::BrowserStatusChange": + this._onBrowserStatusChange(event); + break; case "pagetitlechanged": if (gDot.tabs._isWebContentsBrowserElement(this.webContents)) { this.updateLabel( @@ -495,6 +506,24 @@ class BrowserTab extends MozElements.MozTab { this.toggleAttribute("selected", tab.id === this.id); } + /** + * Fired when the status for the linkedBrowser changes + * @param {CustomEvent} event + */ + _onBrowserStatusChange(event) { + // Clone the event and replay it back to the + // window with the linked browser attached + const evt = new CustomEvent(event.type, { + ...event, + detail: { + ...event.detail, + browser: this.linkedBrowser + } + }); + + window.dispatchEvent(evt); + } + attributeChangedCallback(name, oldValue, newValue) { if (!this.isConnectedAndReady) return; diff --git a/components/tabs/content/browser-status.css b/components/tabs/content/browser-status.css index b41577b1c8..e237affde2 100644 --- a/components/tabs/content/browser-status.css +++ b/components/tabs/content/browser-status.css @@ -3,76 +3,104 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ browser-status { - position: absolute; - bottom: 0; + display: flex; + align-items: center; + height: 100%; pointer-events: none; min-height: 0; max-width: calc(100% - 4rem); + overflow: hidden; + flex: 1; + padding: 0px 4px; + + &:-moz-locale-dir(ltr) { + mask-image: linear-gradient(to right, black 90%, #fff0); + } + + &:-moz-locale-dir(rtl) { + mask-image: linear-gradient(to left, black 90%, #fff0); + } } browser-status .browser-status-label { - display: block; - padding: 0.3rem 0.4rem; + white-space: nowrap; + overflow: hidden; +} - background-color: var(--toolbar-bgcolor); +browser-status[inactive] { + & .browser-status-label { + visibility: hidden; + opacity: 0; + } - border-top: 1px solid var(--border-override, var(--chrome-content-separator-color)); + &[statustype="overLink"] .browser-status-label { + transition: 0.1s opacity ease-out 0.4s, 0.1s visibility 0.4s; + } - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + &[statustype="busy"] .browser-status-label { + transition: 0.25s opacity ease-out 0.5s, 0.25s visibility 0.5s; + } +} - pointer-events: none; +browser-status:not([inactive]) { + & .browser-status-label { + opacity: 1; + visibility: visible; + } - user-select: none; + &[statustype="overLink"] .browser-status-label { + transition: 0.2s opacity ease-out, 0.2s visibility; + } } -browser-status[inactive] .browser-status-label { - visibility: hidden; - opacity: 0; -} +browser-frame browser-status { + position: absolute; + bottom: 0; + height: max-content; + flex: auto; + padding: 0; + mask-image: none !important; + /* todo: find a better way of doing this, without needing important flags */ -browser-status:not([inactive]) .browser-status-label { - opacity: 1; - visibility: visible; -} + & .browser-status-label { + display: block; + padding: 0.3rem 0.4rem; -browser-status[statustype="busy"] .browser-status-label { - min-width: 400px; -} + background-color: var(--toolbar-bgcolor); -browser-status[statustype="overLink"] .browser-status-label { - transition: 0.2s opacity ease-out, 0.2s visibility; -} + border-top: 1px solid var(--border-override, var(--chrome-content-separator-color)); + text-overflow: ellipsis; -browser-status[inactive][statustype="overLink"] .browser-status-label { - transition: 0.1s opacity ease-out 0.4s, 0.1s visibility 0.4s; -} + pointer-events: none; -browser-status[inactive][statustype="busy"] .browser-status-label { - transition: 0.25s opacity ease-out 0.5s, 0.25s visibility 0.5s; -} + user-select: none; + } -browser-status[side="left"] { - left: 0; - padding-right: 4rem; -} + &[statustype="busy"] .browser-status-label { + min-width: 400px; + } -browser-status[side="left"] .browser-status-label { - border-right: 1px solid var(--border-override, var(--chrome-content-separator-color)); - border-top-right-radius: 0.4rem; -} + &[side="left"] { + left: 0; + padding-right: 4rem; + } -browser-status[side="right"] { - right: 0; - padding-left: 4rem; - max-width: 50%; -} + &[side="left"] .browser-status-label { + border-right: 1px solid var(--border-override, var(--chrome-content-separator-color)); + border-top-right-radius: 0.4rem; + } + + &[side="right"] { + right: 0; + padding-left: 4rem; + max-width: 50%; + } -browser-status[side="right"] .browser-status-label { - border-left: 1px solid var(--border-override, var(--chrome-content-separator-color)); - border-top-left-radius: 0.4rem; + &[side="right"] .browser-status-label { + border-left: 1px solid var(--border-override, var(--chrome-content-separator-color)); + border-top-left-radius: 0.4rem; + } } @media (prefers-contrast) { diff --git a/components/tabs/content/browser-status.js b/components/tabs/content/browser-status.js index dd978eb822..c33abe2956 100644 --- a/components/tabs/content/browser-status.js +++ b/components/tabs/content/browser-status.js @@ -2,7 +2,7 @@ * 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/. */ -class BrowserStatus extends MozHTMLElement { +class BrowserStatus extends BrowserContextualMixin(MozHTMLElement) { constructor() { super(); } @@ -11,14 +11,32 @@ class BrowserStatus extends MozHTMLElement { return ["side"]; } + /** + * Get the closest browser webContents + * We only want browser elements as other webContents won't be firing status changes + * + * @returns {ChromeBrowser} + */ get webContents() { - // Get the closest browser webContents - // We only want browser elements as other webContents won't be firing status changes - return this.closest("browser-panel").querySelector( - "browser.browser-web-contents" - ); + const nearestPanel = this.closest("browser-panel"); + + if (!nearestPanel) { + // If we don't have a host, and we're just apart of , + // we can safely return the browser from the host's context. + if (this.host instanceof BrowserApplication) { + return this.hostContext.browser; + } + + // Otherwise, we may be inside a toolbar, where we can use hoveredBrowser instead. + return gDot.tabs.hoveredBrowser; + } + + return nearestPanel.querySelector("browser.browser-web-contents"); } + /** + * The label element for the browser status + */ get label() { return this.querySelector(".browser-status-label"); } @@ -32,30 +50,27 @@ class BrowserStatus extends MozHTMLElement { this.appendChild(html("span", { class: "browser-status-label" })); - this.webContents.addEventListener( - "BrowserTabs::BrowserStatusChange", - this - ); + window.addEventListener("BrowserTabs::BrowserStatusChange", this); window.addEventListener("BrowserTabs::TabSelect", this); } disconnectedCallback() { if (this.delayConnectedCallback()) return; - this.webContents.removeEventListener( - "BrowserTabs::BrowserStatusChange", - this - ); + window.removeEventListener("BrowserTabs::BrowserStatusChange", this); window.removeEventListener("BrowserTabs::TabSelect", this); } /** * Fired when the status changes for this browser * @param {object} status + * @param {ChromeBrowser} status.browser * @param {string} status.message * @param {"busy" | "overLink"} status.type */ onStatusChanged(status) { + if (status.browser != this.webContents) return; + if (status.message.length) this.label.textContent = status.message; let inactive = true; @@ -79,7 +94,7 @@ class BrowserStatus extends MozHTMLElement { */ onActiveTabChanged(tab) { // The tab change wasn't for our linked browser, so we can safely ignore this - if (tab.webContents !== this.webContents) return; + if (tab.linkedBrowser !== this.webContents) return; this.toggleAttribute("inactive", true); }