henry pushed to branch mullvad-browser-140.4.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
-
81be023b
by Henry Wilkes at 2025-10-15T18:07:04+01:00
-
deed64ab
by Henry Wilkes at 2025-10-15T18:07:05+01:00
-
f18fc8f5
by Henry Wilkes at 2025-10-15T18:07:06+01:00
-
77ea2cff
by Henry Wilkes at 2025-10-15T18:07:06+01:00
-
725f9b44
by Henry Wilkes at 2025-10-15T18:07:07+01:00
-
c5acc4f7
by Henry Wilkes at 2025-10-15T18:07:08+01:00
-
d3f14e86
by Henry Wilkes at 2025-10-15T18:07:09+01:00
-
f622ced5
by Henry Wilkes at 2025-10-15T18:07:09+01:00
-
9bd8b0b8
by Henry Wilkes at 2025-10-15T18:07:10+01:00
-
f6b94a03
by Henry Wilkes at 2025-10-15T18:07:11+01:00
-
9f0d03ed
by Henry Wilkes at 2025-10-15T18:07:12+01:00
-
a11336fe
by Henry Wilkes at 2025-10-15T18:07:12+01:00
4 changed files:
- browser/base/content/browser-fullScreenAndPointerLock.js
- browser/themes/shared/tabbrowser/content-area.css
- toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
- toolkit/components/resistfingerprinting/content/letterboxing.css
Changes:
| ... | ... | @@ -879,7 +879,13 @@ var FullScreen = { |
| 879 | 879 | }
|
| 880 | 880 | |
| 881 | 881 | this._isChromeCollapsed = false;
|
| 882 | - Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "shown");
|
|
| 882 | + // Need a subject to know which window this applies to.
|
|
| 883 | + // Base browser patch can be dropped after bugzilla bug 1992036.
|
|
| 884 | + Services.obs.notifyObservers(
|
|
| 885 | + gNavToolbox,
|
|
| 886 | + "fullscreen-nav-toolbox",
|
|
| 887 | + "shown"
|
|
| 888 | + );
|
|
| 883 | 889 | },
|
| 884 | 890 | |
| 885 | 891 | hideNavToolbox(aAnimate = false) {
|
| ... | ... | @@ -943,7 +949,13 @@ var FullScreen = { |
| 943 | 949 | gNavToolbox.style.marginTop =
|
| 944 | 950 | -gNavToolbox.getBoundingClientRect().height + "px";
|
| 945 | 951 | this._isChromeCollapsed = true;
|
| 946 | - Services.obs.notifyObservers(null, "fullscreen-nav-toolbox", "hidden");
|
|
| 952 | + // Need a subject to know which window this applies to.
|
|
| 953 | + // Base browser patch can be dropped after bugzilla bug 1880918.
|
|
| 954 | + Services.obs.notifyObservers(
|
|
| 955 | + gNavToolbox,
|
|
| 956 | + "fullscreen-nav-toolbox",
|
|
| 957 | + "hidden"
|
|
| 958 | + );
|
|
| 947 | 959 | |
| 948 | 960 | MousePosTracker.removeListener(this);
|
| 949 | 961 | },
|
| ... | ... | @@ -242,13 +242,17 @@ |
| 242 | 242 | }
|
| 243 | 243 | }
|
| 244 | 244 | |
| 245 | -#statuspanel[type=letterboxingStatus] > #statuspanel-label,
|
|
| 246 | -#statuspanel[previoustype=letterboxingStatus][inactive] > #statuspanel-label {
|
|
| 245 | +#statuspanel:is([type=letterboxingStatus], [previoustype=letterboxingStatus][inactive]) > #statuspanel-label {
|
|
| 247 | 246 | background-image: url("chrome://browser/skin/window.svg");
|
| 248 | 247 | background-size: 1em;
|
| 249 | 248 | background-repeat: no-repeat;
|
| 250 | - background-position-x: .5em;
|
|
| 251 | 249 | background-position-y: center;
|
| 250 | + background-position-x: left .5em;
|
|
| 251 | + |
|
| 252 | + &:-moz-locale-dir(rtl) {
|
|
| 253 | + background-position-x: right .5em;
|
|
| 254 | + }
|
|
| 255 | + |
|
| 252 | 256 | padding-inline-start: 2em;
|
| 253 | 257 | -moz-context-properties: fill;
|
| 254 | 258 | fill: var(--color-accent-primary);
|
| ... | ... | @@ -18,8 +18,6 @@ const kPrefLetterboxingTesting = |
| 18 | 18 | "privacy.resistFingerprinting.letterboxing.testing";
|
| 19 | 19 | const kPrefLetterboxingVcenter =
|
| 20 | 20 | "privacy.resistFingerprinting.letterboxing.vcenter";
|
| 21 | -const kPrefLetterboxingGradient =
|
|
| 22 | - "privacy.resistFingerprinting.letterboxing.gradient";
|
|
| 23 | 21 | const kPrefLetterboxingDidForceSize =
|
| 24 | 22 | "privacy.resistFingerprinting.letterboxing.didForceSize";
|
| 25 | 23 | const kPrefLetterboxingRememberSize =
|
| ... | ... | @@ -28,10 +26,17 @@ const kPrefLetterboxingRememberSize = |
| 28 | 26 | const kTopicDOMWindowOpened = "domwindowopened";
|
| 29 | 27 | const kTopicDOMWindowClosed = "domwindowclosed";
|
| 30 | 28 | |
| 29 | +const kTopicFullscreenNavToolbox = "fullscreen-nav-toolbox";
|
|
| 30 | + |
|
| 31 | 31 | const kPrefResizeWarnings = "privacy.resistFingerprinting.resizeWarnings";
|
| 32 | 32 | |
| 33 | +const kPrefVerticalTabs = "sidebar.verticalTabs";
|
|
| 34 | + |
|
| 33 | 35 | const lazy = {};
|
| 34 | 36 | |
| 37 | +ChromeUtils.defineESModuleGetters(lazy, {
|
|
| 38 | + Color: "resource://gre/modules/Color.sys.mjs",
|
|
| 39 | +});
|
|
| 35 | 40 | ChromeUtils.defineLazyGetter(lazy, "logConsole", () =>
|
| 36 | 41 | console.createInstance({
|
| 37 | 42 | prefix: "RFPHelper",
|
| ... | ... | @@ -155,7 +160,8 @@ class _RFPHelper { |
| 155 | 160 | Services.prefs.addObserver(kPrefResistFingerprinting, this);
|
| 156 | 161 | Services.prefs.addObserver(kPrefLetterboxing, this);
|
| 157 | 162 | Services.prefs.addObserver(kPrefLetterboxingVcenter, this);
|
| 158 | - Services.prefs.addObserver(kPrefLetterboxingGradient, this);
|
|
| 163 | + Services.prefs.addObserver(kPrefVerticalTabs, this);
|
|
| 164 | + Services.obs.addObserver(this, kTopicFullscreenNavToolbox);
|
|
| 159 | 165 | |
| 160 | 166 | XPCOMUtils.defineLazyPreferenceGetter(
|
| 161 | 167 | this,
|
| ... | ... | @@ -188,9 +194,10 @@ class _RFPHelper { |
| 188 | 194 | |
| 189 | 195 | // Remove unconditional observers
|
| 190 | 196 | Services.prefs.removeObserver(kPrefResistFingerprinting, this);
|
| 191 | - Services.prefs.removeObserver(kPrefLetterboxingGradient, this);
|
|
| 192 | 197 | Services.prefs.removeObserver(kPrefLetterboxingVcenter, this);
|
| 193 | 198 | Services.prefs.removeObserver(kPrefLetterboxing, this);
|
| 199 | + Services.prefs.removeObserver(kPrefVerticalTabs, this);
|
|
| 200 | + Services.obs.removeObserver(this, kTopicFullscreenNavToolbox);
|
|
| 194 | 201 | // Remove the RFP observers, swallowing exceptions if they weren't present
|
| 195 | 202 | this._removeLanguagePrefObservers();
|
| 196 | 203 | }
|
| ... | ... | @@ -212,6 +219,15 @@ class _RFPHelper { |
| 212 | 219 | case kTopicDOMWindowClosed:
|
| 213 | 220 | this._handleDOMWindowClosed(subject);
|
| 214 | 221 | break;
|
| 222 | + case kTopicFullscreenNavToolbox:
|
|
| 223 | + // The `subject` is the gNavToolbox.
|
|
| 224 | + // Record whether the toobox has been hidden when the browser (not
|
|
| 225 | + // content) is in fullscreen.
|
|
| 226 | + subject.ownerGlobal.gBrowser.tabbox.classList.toggle(
|
|
| 227 | + "letterboxing-nav-toolbox-hidden",
|
|
| 228 | + data === "hidden"
|
|
| 229 | + );
|
|
| 230 | + break;
|
|
| 215 | 231 | default:
|
| 216 | 232 | break;
|
| 217 | 233 | }
|
| ... | ... | @@ -226,6 +242,13 @@ class _RFPHelper { |
| 226 | 242 | resizeObserver.observe(browser.parentElement);
|
| 227 | 243 | break;
|
| 228 | 244 | }
|
| 245 | + case "nativethemechange":
|
|
| 246 | + // NOTE: "nativethemechange" seems to always be sent after
|
|
| 247 | + // "windowlwthemeupdate". So all the lwtheme CSS properties should be
|
|
| 248 | + // set to the new theme's values already, so we don't need to wait for
|
|
| 249 | + // windowlwthemeupdate.
|
|
| 250 | + this._updateLetterboxingColors(aMessage.currentTarget, true);
|
|
| 251 | + break;
|
|
| 229 | 252 | default:
|
| 230 | 253 | break;
|
| 231 | 254 | }
|
| ... | ... | @@ -245,9 +268,13 @@ class _RFPHelper { |
| 245 | 268 | Services.prefs.clearUserPref(kPrefLetterboxingDidForceSize);
|
| 246 | 269 | // fall-through
|
| 247 | 270 | case kPrefLetterboxingVcenter:
|
| 248 | - case kPrefLetterboxingGradient:
|
|
| 249 | 271 | this._handleLetterboxingPrefChanged();
|
| 250 | 272 | break;
|
| 273 | + case kPrefVerticalTabs:
|
|
| 274 | + if (this.letterboxingEnabled) {
|
|
| 275 | + forEachWindow(win => this._updateLetterboxingColors(win));
|
|
| 276 | + }
|
|
| 277 | + break;
|
|
| 251 | 278 | default:
|
| 252 | 279 | break;
|
| 253 | 280 | }
|
| ... | ... | @@ -452,7 +479,7 @@ class _RFPHelper { |
| 452 | 479 | // If not already cached on the document object, traverse the CSSOM and
|
| 453 | 480 | // find the rule applying the default letterboxing styles to browsers
|
| 454 | 481 | // preemptively in order to beat race conditions on tab/window creation
|
| 455 | - return (document._letterboxingMarginsRule ||= (() => {
|
|
| 482 | + return (document._letterboxingDefaultRule ||= (() => {
|
|
| 456 | 483 | const LETTERBOX_CSS_SELECTOR = ".letterboxing";
|
| 457 | 484 | const LETTERBOX_CSS_URL =
|
| 458 | 485 | "chrome://global/content/resistfingerprinting/letterboxing.css";
|
| ... | ... | @@ -688,26 +715,22 @@ class _RFPHelper { |
| 688 | 715 | |
| 689 | 716 | if (lastRoundedSize) {
|
| 690 | 717 | // Check whether the letterboxing margin is less than the border radius,
|
| 691 | - // and if so flatten the borders.
|
|
| 692 | - let borderRadius = parseInt(
|
|
| 693 | - win
|
|
| 694 | - .getComputedStyle(browserContainer)
|
|
| 695 | - .getPropertyValue("--letterboxing-border-radius")
|
|
| 718 | + // and if so do not show an outline.
|
|
| 719 | + const gapVertical = parentHeight - lastRoundedSize.height;
|
|
| 720 | + const gapHorizontal = parentWidth - lastRoundedSize.width;
|
|
| 721 | + browserParent.classList.toggle(
|
|
| 722 | + "letterboxing-show-outline",
|
|
| 723 | + gapVertical >= this._letterboxingBorderRadius ||
|
|
| 724 | + gapHorizontal >= this._letterboxingBorderRadius
|
|
| 725 | + );
|
|
| 726 | + // When the Letterboxing area is top-aligned, only show the sidebar corner
|
|
| 727 | + // if there is enough horizontal space.
|
|
| 728 | + // The factor of 4 is from the horizontal centre-alignment and wanting
|
|
| 729 | + // enough space for twice the corner radius.
|
|
| 730 | + browserParent.classList.toggle(
|
|
| 731 | + "letterboxing-show-sidebar-corner",
|
|
| 732 | + gapHorizontal >= 4 * this._letterboxingBorderRadius
|
|
| 696 | 733 | );
|
| 697 | - if (
|
|
| 698 | - borderRadius &&
|
|
| 699 | - parentWidth - lastRoundedSize.width < borderRadius &&
|
|
| 700 | - parentHeight - lastRoundedSize.height < borderRadius
|
|
| 701 | - ) {
|
|
| 702 | - borderRadius = 0;
|
|
| 703 | - } else {
|
|
| 704 | - borderRadius = "";
|
|
| 705 | - }
|
|
| 706 | - styleChanges.queueIfNeeded(browserParent, {
|
|
| 707 | - "--letterboxing-decorator-visibility":
|
|
| 708 | - borderRadius === 0 ? "hidden" : "",
|
|
| 709 | - "--letterboxing-border-radius": borderRadius,
|
|
| 710 | - });
|
|
| 711 | 734 | if (win.gBrowser.selectedBrowser == aBrowser) {
|
| 712 | 735 | const updateStatus = async args => {
|
| 713 | 736 | win.XULBrowserWindow.letterboxingStatus = args
|
| ... | ... | @@ -769,20 +792,31 @@ class _RFPHelper { |
| 769 | 792 | |
| 770 | 793 | _resetContentSize(aBrowser) {
|
| 771 | 794 | aBrowser.parentElement.classList.add("exclude-letterboxing");
|
| 795 | + aBrowser.parentElement.classList.remove(
|
|
| 796 | + "letterboxing-show-outline",
|
|
| 797 | + "letterboxing-show-sidebar-corner"
|
|
| 798 | + );
|
|
| 772 | 799 | }
|
| 773 | 800 | |
| 774 | 801 | _updateSizeForTabsInWindow(aWindow) {
|
| 775 | 802 | let tabBrowser = aWindow.gBrowser;
|
| 776 | 803 | |
| 777 | - tabBrowser.tabpanels?.classList.add("letterboxing");
|
|
| 778 | - tabBrowser.tabpanels?.classList.toggle(
|
|
| 804 | + tabBrowser.tabbox.classList.add("letterboxing");
|
|
| 805 | + tabBrowser.tabbox.classList.toggle(
|
|
| 779 | 806 | "letterboxing-vcenter",
|
| 780 | 807 | Services.prefs.getBoolPref(kPrefLetterboxingVcenter, false)
|
| 781 | 808 | );
|
| 782 | - tabBrowser.tabpanels?.classList.toggle(
|
|
| 783 | - "letterboxing-gradient",
|
|
| 784 | - Services.prefs.getBoolPref(kPrefLetterboxingGradient, false)
|
|
| 785 | - );
|
|
| 809 | + if (this._letterboxingBorderRadius === undefined && tabBrowser.tabbox) {
|
|
| 810 | + // Cache the value since it is not expected to change in a session for any
|
|
| 811 | + // window.
|
|
| 812 | + this._letterboxingBorderRadius = Math.ceil(
|
|
| 813 | + parseFloat(
|
|
| 814 | + aWindow
|
|
| 815 | + .getComputedStyle(tabBrowser.tabbox)
|
|
| 816 | + .getPropertyValue("--letterboxing-border-radius")
|
|
| 817 | + )
|
|
| 818 | + );
|
|
| 819 | + }
|
|
| 786 | 820 | |
| 787 | 821 | for (let tab of tabBrowser.tabs) {
|
| 788 | 822 | let browser = tab.linkedBrowser;
|
| ... | ... | @@ -791,7 +825,7 @@ class _RFPHelper { |
| 791 | 825 | // We need to add this class late because otherwise new windows get
|
| 792 | 826 | // maximized.
|
| 793 | 827 | aWindow.setTimeout(() => {
|
| 794 | - tabBrowser.tabpanels?.classList.add("letterboxing-ready");
|
|
| 828 | + tabBrowser.tabbox.classList.add("letterboxing-ready");
|
|
| 795 | 829 | if (!aWindow._rfpOriginalSize) {
|
| 796 | 830 | this._recordWindowSize(aWindow);
|
| 797 | 831 | }
|
| ... | ... | @@ -869,6 +903,247 @@ class _RFPHelper { |
| 869 | 903 | this._resizeObservers.set(aWindow, resizeObserver);
|
| 870 | 904 | // Rounding the content viewport.
|
| 871 | 905 | this._updateSizeForTabsInWindow(aWindow);
|
| 906 | + |
|
| 907 | + this._updateLetterboxingColors(aWindow, true);
|
|
| 908 | + aWindow.addEventListener("nativethemechange", this);
|
|
| 909 | + }
|
|
| 910 | + |
|
| 911 | + /**
|
|
| 912 | + * Convert a CSS property to its RGBA value.
|
|
| 913 | + *
|
|
| 914 | + * @param {Window} win - The window for the element.
|
|
| 915 | + * @param {CSSStyleDeclaration} style - The computed style for the element we
|
|
| 916 | + * want to grab the color from.
|
|
| 917 | + * @param {string} property - The name of the property we want.
|
|
| 918 | + *
|
|
| 919 | + * @returns {InspectorRGBATuple} - The RGBA color. The "r", "g", "b" fields
|
|
| 920 | + * are relative to the 0-255 color range. The "a" field is in the 0-1 range.
|
|
| 921 | + */
|
|
| 922 | + _convertToRGBA(win, style, property) {
|
|
| 923 | + let cssColor = style.getPropertyValue(property);
|
|
| 924 | + if (!cssColor) {
|
|
| 925 | + lazy.logConsole.error(`Missing color "${property}"`);
|
|
| 926 | + return { r: 0, g: 0, b: 0, a: 0 };
|
|
| 927 | + }
|
|
| 928 | + const currentColorRegex =
|
|
| 929 | + /(^|[^a-zA-Z0-9_-])currentColor($|[^a-zA-Z0-9_-])/g;
|
|
| 930 | + if (currentColorRegex.test(cssColor)) {
|
|
| 931 | + const currentColor = style.color;
|
|
| 932 | + cssColor = cssColor.replace(currentColorRegex, (_, pre, post) => {
|
|
| 933 | + return pre + currentColor + post;
|
|
| 934 | + });
|
|
| 935 | + lazy.logConsole.debug(
|
|
| 936 | + "Replaced currentColor.",
|
|
| 937 | + property,
|
|
| 938 | + currentColor,
|
|
| 939 | + cssColor
|
|
| 940 | + );
|
|
| 941 | + }
|
|
| 942 | + /* Can drop the document argument after bugzilla bug 1973684 (142). */
|
|
| 943 | + const colorRGBA = win.InspectorUtils.colorToRGBA(cssColor, win.document);
|
|
| 944 | + if (!colorRGBA) {
|
|
| 945 | + lazy.logConsole.error(
|
|
| 946 | + `Failed to convert "${property}" color (${cssColor}) to RGBA`
|
|
| 947 | + );
|
|
| 948 | + return { r: 0, g: 0, b: 0, a: 0 };
|
|
| 949 | + }
|
|
| 950 | + return colorRGBA;
|
|
| 951 | + }
|
|
| 952 | + |
|
| 953 | + /**
|
|
| 954 | + * Compose two colors with alpha values on top of each other.
|
|
| 955 | + *
|
|
| 956 | + * @param {InspectorRGBATuple} topRGBA - The color to place on the top.
|
|
| 957 | + * @param {InspectorRGBATuple} bottomRGBA - The color to place on the bottom.
|
|
| 958 | + *
|
|
| 959 | + * @returns {InspectorRGBATuple} - The composed color.
|
|
| 960 | + */
|
|
| 961 | + _composeRGBA(topRGBA, bottomRGBA) {
|
|
| 962 | + const topA = Math.max(0, Math.min(1, topRGBA.a));
|
|
| 963 | + const bottomA = Math.max(0, Math.min(1, bottomRGBA.a));
|
|
| 964 | + const a = topA + bottomA - topA * bottomA; // Should be 1 if either is 1.
|
|
| 965 | + if (a === 0) {
|
|
| 966 | + return { r: 0, g: 0, b: 0, a };
|
|
| 967 | + }
|
|
| 968 | + const ret = { a };
|
|
| 969 | + for (const field of ["r", "g", "b"]) {
|
|
| 970 | + ret[field] =
|
|
| 971 | + (topRGBA[field] * topA + bottomRGBA[field] * bottomA * (1 - topA)) / a;
|
|
| 972 | + }
|
|
| 973 | + return ret;
|
|
| 974 | + }
|
|
| 975 | + |
|
| 976 | + /**
|
|
| 977 | + * Calculate the urlbar's container opaque background color, removing any
|
|
| 978 | + * transparency.
|
|
| 979 | + *
|
|
| 980 | + * @param {Window} win - The window to calculate the color for.
|
|
| 981 | + * @param {CSSStyleDeclaration} style - The computed style for the #nav-bar
|
|
| 982 | + * element.
|
|
| 983 | + *
|
|
| 984 | + * @returns {InspectorRGBATuple} - The calculated color, which will be opaque.
|
|
| 985 | + */
|
|
| 986 | + _calculateUrlbarContainerColor(win, style) {
|
|
| 987 | + let colorRGBA;
|
|
| 988 | + if (!Services.prefs.getBoolPref(kPrefVerticalTabs)) {
|
|
| 989 | + lazy.logConsole.debug("Toolbar background used.");
|
|
| 990 | + colorRGBA = this._convertToRGBA(win, style, "--toolbar-bgcolor");
|
|
| 991 | + if (colorRGBA.a === 1) {
|
|
| 992 | + return colorRGBA;
|
|
| 993 | + }
|
|
| 994 | + } else {
|
|
| 995 | + // The urlbar only has the toolbox colour.
|
|
| 996 | + colorRGBA = { r: 0, g: 0, b: 0, a: 0 };
|
|
| 997 | + }
|
|
| 998 | + let toolboxHasBackgroundImage = false;
|
|
| 999 | + const isLwTheme = win.document.documentElement.hasAttribute("lwtheme");
|
|
| 1000 | + if (isLwTheme) {
|
|
| 1001 | + for (const prop of ["--lwt-header-image", "--lwt-additional-images"]) {
|
|
| 1002 | + const headerImage = style.getPropertyValue(prop);
|
|
| 1003 | + if (headerImage && headerImage !== "none") {
|
|
| 1004 | + // The theme sets a background image behind the urlbar. No easy way to
|
|
| 1005 | + // derive a single colour from this.
|
|
| 1006 | + toolboxHasBackgroundImage = true;
|
|
| 1007 | + lazy.logConsole.debug(
|
|
| 1008 | + "Toolbox has background image.",
|
|
| 1009 | + prop,
|
|
| 1010 | + headerImage
|
|
| 1011 | + );
|
|
| 1012 | + break;
|
|
| 1013 | + }
|
|
| 1014 | + }
|
|
| 1015 | + }
|
|
| 1016 | + if (!toolboxHasBackgroundImage) {
|
|
| 1017 | + lazy.logConsole.debug("Toolbox background used.");
|
|
| 1018 | + colorRGBA = this._composeRGBA(
|
|
| 1019 | + colorRGBA,
|
|
| 1020 | + this._convertToRGBA(win, style, "--toolbox-bgcolor")
|
|
| 1021 | + );
|
|
| 1022 | + if (colorRGBA.a === 1) {
|
|
| 1023 | + return colorRGBA;
|
|
| 1024 | + }
|
|
| 1025 | + }
|
|
| 1026 | + |
|
| 1027 | + // Determine whether the urlbar is dark.
|
|
| 1028 | + // At this point, the urlbar background has some transparency, likely on top
|
|
| 1029 | + // of an image.
|
|
| 1030 | + // We use the theme's text colour to figure out whether the urlbar
|
|
| 1031 | + // background is overall meant to be light or dark. Unlike the urlbar, we
|
|
| 1032 | + // expect this colour to be (almost) opaque.
|
|
| 1033 | + const textRGBA = this._convertToRGBA(win, style, "--toolbar-field-color");
|
|
| 1034 | + const textColor = new lazy.Color(textRGBA.r, textRGBA.g, textRGBA.b);
|
|
| 1035 | + if (textColor.relativeLuminance >= 0.5) {
|
|
| 1036 | + // Light text, so assume it has a dark background.
|
|
| 1037 | + // Combine with a generic opaque dark colour. Copied from "frame" for the
|
|
| 1038 | + // built-in dark theme.
|
|
| 1039 | + lazy.logConsole.debug("Generic dark background used.");
|
|
| 1040 | + const darkFrameRGBA = { r: 28, g: 27, b: 34, a: 1 };
|
|
| 1041 | + return this._composeRGBA(colorRGBA, darkFrameRGBA);
|
|
| 1042 | + }
|
|
| 1043 | + // Combine with an opaque light colour. Copied from "frame" for the built-in
|
|
| 1044 | + // light theme.
|
|
| 1045 | + lazy.logConsole.debug("Generic light background used.");
|
|
| 1046 | + const lightFrameRGBA = { r: 234, g: 234, b: 237, a: 1 };
|
|
| 1047 | + return this._composeRGBA(colorRGBA, lightFrameRGBA);
|
|
| 1048 | + }
|
|
| 1049 | + |
|
| 1050 | + /**
|
|
| 1051 | + * Update the Letterboxing colors and related classes, or clear them if
|
|
| 1052 | + * Letterboxing is not enabled.
|
|
| 1053 | + *
|
|
| 1054 | + * @param {Window} win - The window to update the colors for.
|
|
| 1055 | + * @param {boolean} letterboxingEnabled - Whether Letterboxing is enabled.
|
|
| 1056 | + */
|
|
| 1057 | + _updateLetterboxingColors(win, letterboxingEnabled) {
|
|
| 1058 | + let urlbarBackgroundRGBA;
|
|
| 1059 | + let urlbarTextRGBA;
|
|
| 1060 | + let contentSeparatorRGBA;
|
|
| 1061 | + let urlbarBackgroundDark = false;
|
|
| 1062 | + let lowBackgroundOutlineContrast = false;
|
|
| 1063 | + |
|
| 1064 | + if (letterboxingEnabled) {
|
|
| 1065 | + // Want the effective colour of various elements without any alpha values
|
|
| 1066 | + // so they can be used consistently.
|
|
| 1067 | + const navbarStyle = win.getComputedStyle(
|
|
| 1068 | + win.document.getElementById("nav-bar")
|
|
| 1069 | + );
|
|
| 1070 | + const containerRGBA = this._calculateUrlbarContainerColor(
|
|
| 1071 | + win,
|
|
| 1072 | + navbarStyle
|
|
| 1073 | + );
|
|
| 1074 | + urlbarBackgroundRGBA = this._composeRGBA(
|
|
| 1075 | + this._convertToRGBA(
|
|
| 1076 | + win,
|
|
| 1077 | + navbarStyle,
|
|
| 1078 | + "--toolbar-field-background-color"
|
|
| 1079 | + ),
|
|
| 1080 | + containerRGBA
|
|
| 1081 | + );
|
|
| 1082 | + urlbarTextRGBA = this._composeRGBA(
|
|
| 1083 | + this._convertToRGBA(win, navbarStyle, "--toolbar-field-color"),
|
|
| 1084 | + urlbarBackgroundRGBA
|
|
| 1085 | + );
|
|
| 1086 | + /* Separator between the urlbar container #nav-bar and the tabbox. */
|
|
| 1087 | + const tabboxStyle = win.getComputedStyle(win.gBrowser.tabbox);
|
|
| 1088 | + contentSeparatorRGBA = this._composeRGBA(
|
|
| 1089 | + this._convertToRGBA(
|
|
| 1090 | + win,
|
|
| 1091 | + tabboxStyle,
|
|
| 1092 | + "--chrome-content-separator-color"
|
|
| 1093 | + ),
|
|
| 1094 | + containerRGBA
|
|
| 1095 | + );
|
|
| 1096 | + const bgColor = new lazy.Color(
|
|
| 1097 | + urlbarBackgroundRGBA.r,
|
|
| 1098 | + urlbarBackgroundRGBA.g,
|
|
| 1099 | + urlbarBackgroundRGBA.b
|
|
| 1100 | + );
|
|
| 1101 | + const outlineColor = new lazy.Color(
|
|
| 1102 | + contentSeparatorRGBA.r,
|
|
| 1103 | + contentSeparatorRGBA.g,
|
|
| 1104 | + contentSeparatorRGBA.b
|
|
| 1105 | + );
|
|
| 1106 | + const contrastRatio = bgColor.contrastRatio(outlineColor);
|
|
| 1107 | + lazy.logConsole.debug(
|
|
| 1108 | + "Outline-background contrast ratio.",
|
|
| 1109 | + contrastRatio
|
|
| 1110 | + );
|
|
| 1111 | + urlbarBackgroundDark = bgColor.relativeLuminance < 0.5;
|
|
| 1112 | + /* Very low contrast ratio. For reference the default light theme has
|
|
| 1113 | + * a contrast ratio of ~1.1. */
|
|
| 1114 | + lowBackgroundOutlineContrast = contrastRatio < 1.05;
|
|
| 1115 | + }
|
|
| 1116 | + for (const { name, colorRGBA } of [
|
|
| 1117 | + {
|
|
| 1118 | + name: "--letterboxing-urlbar-text-color",
|
|
| 1119 | + colorRGBA: urlbarTextRGBA,
|
|
| 1120 | + },
|
|
| 1121 | + {
|
|
| 1122 | + name: "--letterboxing-urlbar-background-color",
|
|
| 1123 | + colorRGBA: urlbarBackgroundRGBA,
|
|
| 1124 | + },
|
|
| 1125 | + {
|
|
| 1126 | + name: "--letterboxing-content-separator-color",
|
|
| 1127 | + colorRGBA: contentSeparatorRGBA,
|
|
| 1128 | + },
|
|
| 1129 | + ]) {
|
|
| 1130 | + if (letterboxingEnabled) {
|
|
| 1131 | + win.gBrowser.tabbox.style.setProperty(
|
|
| 1132 | + name,
|
|
| 1133 | + `rgb(${colorRGBA.r}, ${colorRGBA.g}, ${colorRGBA.b})`
|
|
| 1134 | + );
|
|
| 1135 | + } else {
|
|
| 1136 | + win.gBrowser.tabbox.style.removeProperty(name);
|
|
| 1137 | + }
|
|
| 1138 | + }
|
|
| 1139 | + win.gBrowser.tabbox.classList.toggle(
|
|
| 1140 | + "letterboxing-urlbar-background-dark",
|
|
| 1141 | + urlbarBackgroundDark
|
|
| 1142 | + );
|
|
| 1143 | + win.gBrowser.tabbox.classList.toggle(
|
|
| 1144 | + "letterboxing-low-background-outline-contrast",
|
|
| 1145 | + lowBackgroundOutlineContrast
|
|
| 1146 | + );
|
|
| 872 | 1147 | }
|
| 873 | 1148 | |
| 874 | 1149 | _detachWindow(aWindow) {
|
| ... | ... | @@ -886,7 +1161,7 @@ class _RFPHelper { |
| 886 | 1161 | aWindow.removeEventListener("TabOpen", this);
|
| 887 | 1162 | |
| 888 | 1163 | // revert tabpanel's style to default
|
| 889 | - tabBrowser.tabpanels?.classList.remove("letterboxing");
|
|
| 1164 | + tabBrowser.tabbox.classList.remove("letterboxing");
|
|
| 890 | 1165 | |
| 891 | 1166 | // and restore default size on each browser element
|
| 892 | 1167 | for (let tab of tabBrowser.tabs) {
|
| ... | ... | @@ -896,6 +1171,9 @@ class _RFPHelper { |
| 896 | 1171 | aWindow.removeEventListener("dblclick", this._onWindowDoubleClick);
|
| 897 | 1172 | delete aWindow.shrinkToLetterbox;
|
| 898 | 1173 | aWindow.removeEventListener("sizemodechange", windowResizeHandler);
|
| 1174 | + |
|
| 1175 | + aWindow.removeEventListener("nativethemechange", this);
|
|
| 1176 | + this._updateLetterboxingColors(aWindow, false);
|
|
| 899 | 1177 | }
|
| 900 | 1178 | |
| 901 | 1179 | _handleDOMWindowOpened(win) {
|
| ... | ... | @@ -7,17 +7,106 @@ |
| 7 | 7 | * RFPHelper.sys.mjs (LETTERBOX_CSS_SELECTOR and LETTERBOX_CSS_URL,
|
| 8 | 8 | * respectively), where --letterboxing-width & --letterboxing-height are
|
| 9 | 9 | * actually set.
|
| 10 | + * Keep this block first and separate to the rules that do not necessarily
|
|
| 11 | + * require --letterboxing-width or --letterboxing-height.
|
|
| 10 | 12 | */
|
| 11 | 13 | .letterboxing {
|
| 12 | - --letterboxing-bgcolor: var(--tabpanel-background-color);
|
|
| 13 | - --letterboxing-border-radius: 8px;
|
|
| 14 | - --letterboxing-border-top-radius: 0;
|
|
| 14 | + .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
|
|
| 15 | + width: var(--letterboxing-width) !important;
|
|
| 16 | + height: var(--letterboxing-height) !important;
|
|
| 17 | + }
|
|
| 18 | +}
|
|
| 19 | + |
|
| 20 | +#tabbrowser-tabbox.letterboxing {
|
|
| 21 | + --letterboxing-bgcolor: var(--background-color-canvas);
|
|
| 22 | + /* Match the border radius used for the sidebar. */
|
|
| 23 | + --letterboxing-border-radius: var(--border-radius-medium);
|
|
| 24 | + --letterboxing-border-radius-top: 0;
|
|
| 15 | 25 | --letterboxing-vertical-alignment: start;
|
| 16 | - --letterboxing-shadow-color: rgba(12, 12, 13, 0.10);
|
|
| 17 | - --letterboxing-gradient-color1: var(--letterboxing-bgcolor);
|
|
| 18 | - --letterboxing-gradient-color2: color-mix(in srgb, var(--chrome-content-separator-color) 50%, var(--letterboxing-bgcolor));
|
|
| 19 | - --letterboxing-border-color: var(--letterboxing-bgcolor);
|
|
| 20 | - --letterboxing-decorator-visibility: visible;
|
|
| 26 | + --letterboxing-shadow: none;
|
|
| 27 | + --letterboxing-outline-color: var(--border-color);
|
|
| 28 | + --letterboxing-outline-width: 1px;
|
|
| 29 | + |
|
| 30 | + @media not ((prefers-contrast) or (forced-colors)) {
|
|
| 31 | + /* Match the #sidebar outline width. */
|
|
| 32 | + --letterboxing-outline-width: 0.5px;
|
|
| 33 | + --letterboxing-shadow-color: rgba(58, 57, 68, 0.20);
|
|
| 34 | + --letterboxing-shadow: 0 2px 14px 0 var(--letterboxing-shadow-color);
|
|
| 35 | + |
|
| 36 | + /* Match the effective urlbar background colour. */
|
|
| 37 | + --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
|
|
| 38 | + /* Match the effective colour of the separator between the urlbar container
|
|
| 39 | + * and the content. */
|
|
| 40 | + --letterboxing-outline-color: var(--letterboxing-content-separator-color);
|
|
| 41 | + |
|
| 42 | + &.letterboxing-urlbar-background-dark {
|
|
| 43 | + --letterboxing-shadow-color: #15141a;
|
|
| 44 | + }
|
|
| 45 | + |
|
| 46 | + &.letterboxing-low-background-outline-contrast {
|
|
| 47 | + /* The default content separator colour has insufficient contrast. */
|
|
| 48 | + --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, black);
|
|
| 49 | + |
|
| 50 | + &.letterboxing-urlbar-background-dark {
|
|
| 51 | + /* Lighten the colour. */
|
|
| 52 | + --letterboxing-outline-color: color-mix(in srgb, var(--letterboxing-content-separator-color) 90%, white);
|
|
| 53 | + }
|
|
| 54 | + }
|
|
| 55 | + }
|
|
| 56 | + |
|
| 57 | + @media (prefers-contrast) and (not (forced-colors)) {
|
|
| 58 | + :root[lwtheme] & {
|
|
| 59 | + /* User with prefers-contrast coming from the system settings, but also an
|
|
| 60 | + * installed theme. */
|
|
| 61 | + --letterboxing-bgcolor: var(--letterboxing-urlbar-background-color);
|
|
| 62 | + /* Presumably a user with prefers-contrast and a custom theme has chosen
|
|
| 63 | + * a theme where the contrast between the urlbar and the text is
|
|
| 64 | + * sufficiently high or low. */
|
|
| 65 | + --letterboxing-outline-color: var(--letterboxing-urlbar-text-color);
|
|
| 66 | + }
|
|
| 67 | + }
|
|
| 68 | + |
|
| 69 | + background: var(--letterboxing-bgcolor);
|
|
| 70 | + |
|
| 71 | + &:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline) {
|
|
| 72 | + /* Letterboxing outline is visible for the current tab. Replace the usual
|
|
| 73 | + * outline to match the Letterboxing outline. For most scenarios, this
|
|
| 74 | + * should be mostly the same colour as when Letterboxing is not visible. But
|
|
| 75 | + * it may make a difference for some theme combinations. */
|
|
| 76 | + outline-color: var(--letterboxing-outline-color);
|
|
| 77 | + outline-width: var(--letterboxing-outline-width);
|
|
| 78 | + }
|
|
| 79 | + |
|
| 80 | + #tabbrowser-tabpanels {
|
|
| 81 | + /* Override the --tabpanel-background-color.
|
|
| 82 | + * Also, make sure this remains transparent, otherwise it will overlap the
|
|
| 83 | + * parent's corner's border-radius due to it's "position: relative" rule. */
|
|
| 84 | + /* TODO: FIX this for newtab pages. tor-browser#44085 */
|
|
| 85 | + background: transparent;
|
|
| 86 | + }
|
|
| 87 | + |
|
| 88 | + /* stylelint-disable-next-line media-query-no-invalid */
|
|
| 89 | + @media -moz-pref("sidebar.revamp") {
|
|
| 90 | + :root:not([inDOMFullscreen]) &[sidebar-shown]:not(.letterboxing-nav-toolbox-hidden):is(
|
|
| 91 | + /* When the Letterboxing area is aligned to the top, show the rounded
|
|
| 92 | + * corner if there is enough vertical space between the sidebar and the
|
|
| 93 | + * browser element, which is not rounded at the top. */
|
|
| 94 | + :not(.letterboxing-vcenter):has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-sidebar-corner),
|
|
| 95 | + /* When the Letterboxing area is aligned to the centre, show the rounded
|
|
| 96 | + * corner if the Letterboxing border is shown. */
|
|
| 97 | + .letterboxing-vcenter:has(.deck-selected .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing).letterboxing-show-outline)
|
|
| 98 | + ) {
|
|
| 99 | + /* stylelint-disable-next-line media-query-no-invalid */
|
|
| 100 | + @media -moz-pref("sidebar.position_start") {
|
|
| 101 | + border-start-start-radius: var(--letterboxing-border-radius);
|
|
| 102 | + }
|
|
| 103 | + |
|
| 104 | + /* stylelint-disable-next-line media-query-no-invalid */
|
|
| 105 | + @media not -moz-pref("sidebar.position_start") {
|
|
| 106 | + border-start-end-radius: var(--letterboxing-border-radius);
|
|
| 107 | + }
|
|
| 108 | + }
|
|
| 109 | + }
|
|
| 21 | 110 | |
| 22 | 111 | .browserContainer {
|
| 23 | 112 | /*
|
| ... | ... | @@ -26,101 +115,71 @@ |
| 26 | 115 | * doesn't get notified on horizontal shrinking.
|
| 27 | 116 | */
|
| 28 | 117 | overflow: hidden;
|
| 29 | - background: var(--letterboxing-bgcolor);
|
|
| 30 | 118 | }
|
| 31 | 119 | |
| 32 | - .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) > browser {
|
|
| 33 | - box-shadow: 0 4px 8px 0 var(--letterboxing-shadow-color);
|
|
| 34 | - border-radius: var(--letterboxing-border-radius);
|
|
| 35 | - border-top-left-radius: var(--letterboxing-border-top-radius);
|
|
| 36 | - border-top-right-radius: var(--letterboxing-border-top-radius);
|
|
| 37 | - width: var(--letterboxing-width) !important;
|
|
| 38 | - height: var(--letterboxing-height) !important;
|
|
| 39 | - background: var(--letterboxing-gradient-color2);
|
|
| 120 | + &.letterboxing-vcenter {
|
|
| 121 | + --letterboxing-border-radius-top: var(--letterboxing-border-radius);
|
|
| 122 | + --letterboxing-vertical-alignment: center;
|
|
| 40 | 123 | }
|
| 41 | 124 | }
|
| 42 | 125 | |
| 43 | -:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
|
|
| 44 | - > .browserStack:not(.exclude-letterboxing) {
|
|
| 45 | - place-content: start center;
|
|
| 46 | -}
|
|
| 47 | - |
|
| 48 | -.browserDecorator {
|
|
| 49 | - display: none;
|
|
| 50 | - pointer-events: none;
|
|
| 51 | - background: transparent;
|
|
| 52 | - position: relative;
|
|
| 53 | - z-index: 1;
|
|
| 54 | -}
|
|
| 126 | +.browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
|
|
| 127 | + :root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready & {
|
|
| 128 | + place-content: var(--letterboxing-vertical-alignment) center;
|
|
| 129 | + }
|
|
| 55 | 130 | |
| 56 | -.letterboxing.letterboxing-vcenter .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing) {
|
|
| 57 | - --letterboxing-border-top-radius: var(--letterboxing-border-radius);
|
|
| 58 | - --letterboxing-vertical-alignment: center;
|
|
| 59 | -}
|
|
| 131 | + :root:not([inDOMFullscreen]) .letterboxing &.letterboxing-show-outline {
|
|
| 132 | + browser {
|
|
| 133 | + /* We use clip-path rather than border-radius because border-radius on its
|
|
| 134 | + * own leads to rendering artefacts in the corners (tested with GNOME).
|
|
| 135 | + * See tor-browser#44214 (comment 3262962). */
|
|
| 136 | + /* TODO: Use border-radius once bugzilla bug 1991874 is resolved. */
|
|
| 137 | + clip-path: rect(auto auto auto auto round var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius));
|
|
| 138 | + }
|
|
| 60 | 139 | |
| 61 | -.letterboxing.letterboxing-gradient .browserContainer {
|
|
| 62 | - background: linear-gradient(283deg, var(--letterboxing-gradient-color1) 0%, var(--letterboxing-gradient-color2) 100%), var(--letterboxing-bgcolor);
|
|
| 63 | -}
|
|
| 140 | + .browserDecorator {
|
|
| 141 | + /* Need a separate browserDecorator element because the clip-path on the
|
|
| 142 | + * browser would exclude the outline and box-shadow. */
|
|
| 143 | + /* TODO: Move these rules to the browser element once bugzilla bug 1991874
|
|
| 144 | + * is resolved, and drop browserDecorator. */
|
|
| 145 | + display: block;
|
|
| 146 | + border-radius: var(--letterboxing-border-radius-top) var(--letterboxing-border-radius-top) var(--letterboxing-border-radius) var(--letterboxing-border-radius);
|
|
| 147 | + /* NOTE: The top outline will not be visible when this is aligned to the
|
|
| 148 | + * top. */
|
|
| 149 | + outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
|
|
| 150 | + box-shadow: var(--letterboxing-shadow);
|
|
| 151 | + }
|
|
| 64 | 152 | |
| 65 | -:root:not([inDOMFullscreen]) .letterboxing .browserContainer:not(.responsive-mode)
|
|
| 66 | - > .browserStack:not(.exclude-letterboxing)
|
|
| 67 | - > .browserDecorator {
|
|
| 68 | - display: initial;
|
|
| 69 | - visibility: var(--letterboxing-decorator-visibility);
|
|
| 70 | - border-radius: var(--letterboxing-border-radius);
|
|
| 71 | - border-top-left-radius: var(--letterboxing-border-top-radius);
|
|
| 72 | - border-top-right-radius: var(--letterboxing-border-top-radius);
|
|
| 73 | - box-shadow: var(--letterboxing-border-color) 0 0 .1px inset, var(--letterboxing-border-color) 0 0 .1px;
|
|
| 74 | - border: .1px solid var(--letterboxing-border-color);
|
|
| 75 | - outline: .1px solid var(--letterboxing-bgcolor);
|
|
| 76 | - height: calc(var(--letterboxing-height) + 1px);
|
|
| 77 | - top: -1px;
|
|
| 78 | -}
|
|
| 153 | + #statuspanel:not([mirror]) #statuspanel-label {
|
|
| 154 | + border-end-start-radius: var(--letterboxing-border-radius);
|
|
| 155 | + }
|
|
| 79 | 156 | |
| 80 | -.letterboxing-vcenter .browserDecorator {
|
|
| 81 | - height: auto !important;
|
|
| 82 | - top: 0 !important;
|
|
| 83 | -}
|
|
| 157 | + #statuspanel[mirror] #statuspanel-label {
|
|
| 158 | + border-end-end-radius: var(--letterboxing-border-radius);
|
|
| 159 | + }
|
|
| 160 | + }
|
|
| 84 | 161 | |
| 85 | -/*
|
|
| 86 | - Align status bar with content.
|
|
| 87 | - TODO: switch to nested CSS selectors for conciseness when available (Firefox >= 117)
|
|
| 88 | -*/
|
|
| 89 | -.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
|
|
| 90 | - > #statuspanel:not([hidden]) {
|
|
| 91 | - position: relative;
|
|
| 92 | - place-self: end left;
|
|
| 93 | - left: 0;
|
|
| 94 | - right: 0;
|
|
| 95 | - z-index: 2;
|
|
| 96 | - --letterboxing-status-left-radius: var(--letterboxing-border-radius);
|
|
| 97 | - --letterboxing-status-right-radius: 0;
|
|
| 98 | -}
|
|
| 99 | -.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
|
|
| 100 | - > #statuspanel:not([mirror]):-moz-locale-dir(rtl),
|
|
| 101 | -.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
|
|
| 102 | - > #statuspanel[mirror]:-moz-locale-dir(ltr) {
|
|
| 103 | - left: 0;
|
|
| 104 | - right: 0;
|
|
| 105 | - --letterboxing-status-right-radius: var(--letterboxing-border-radius);
|
|
| 106 | - --letterboxing-status-left-radius: 0;
|
|
| 107 | - justify-self: right;
|
|
| 108 | -}
|
|
| 162 | + #statuspanel {
|
|
| 163 | + position: relative;
|
|
| 164 | + place-self: end start;
|
|
| 165 | + z-index: 2;
|
|
| 109 | 166 | |
| 110 | -.letterboxing .browserContainer:not(.responsive-mode) > .browserStack:not(.exclude-letterboxing)
|
|
| 111 | -#statuspanel-label {
|
|
| 112 | - border-radius: 0 0 var(--letterboxing-status-right-radius) var(--letterboxing-status-left-radius);
|
|
| 113 | - margin: 0;
|
|
| 114 | - border: 1px solid var(--letterboxing-border-color);
|
|
| 115 | - max-width: calc(var(--letterboxing-width) * .5);
|
|
| 116 | -}
|
|
| 167 | + &[mirror] {
|
|
| 168 | + justify-self: end;
|
|
| 169 | + }
|
|
| 170 | + }
|
|
| 117 | 171 | |
| 118 | -browser:fullscreen {
|
|
| 119 | - --letterboxing-border-top-radius: 0;
|
|
| 120 | - --letterboxing-border-radius: 0;
|
|
| 172 | + #statuspanel-label {
|
|
| 173 | + margin: 0;
|
|
| 174 | + outline: var(--letterboxing-outline-width) solid var(--letterboxing-outline-color);
|
|
| 175 | + max-width: calc(var(--letterboxing-width) * .5);
|
|
| 176 | + }
|
|
| 121 | 177 | }
|
| 122 | 178 | |
| 123 | -:root:not([inDOMFullscreen]) .letterboxing.letterboxing-ready .browserContainer:not(.responsive-mode)
|
|
| 124 | - > .browserStack:not(.exclude-letterboxing) {
|
|
| 125 | - place-content: var(--letterboxing-vertical-alignment) center;
|
|
| 179 | +.browserDecorator {
|
|
| 180 | + display: none;
|
|
| 181 | + pointer-events: none;
|
|
| 182 | + background: transparent;
|
|
| 183 | + position: relative;
|
|
| 184 | + z-index: 1;
|
|
| 126 | 185 | } |