mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-29 01:41:33 +00:00
Merge branch 'dev' into library
This commit is contained in:
18
src/accessible/base/TextAttrs-cpp.patch
Normal file
18
src/accessible/base/TextAttrs-cpp.patch
Normal file
@@ -0,0 +1,18 @@
|
||||
diff --git a/accessible/base/TextAttrs.cpp b/accessible/base/TextAttrs.cpp
|
||||
index d2ce06bef67ecb6d6ccb798a62d7f2759dd9da18..fb4952df9aa54d4085a282dc269a48ad72979b8b 100644
|
||||
--- a/accessible/base/TextAttrs.cpp
|
||||
+++ b/accessible/base/TextAttrs.cpp
|
||||
@@ -237,11 +237,11 @@ bool TextAttrsMgr::BGColorTextAttr::GetColor(nsIFrame* aFrame,
|
||||
TextAttrsMgr::ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame,
|
||||
nsIFrame* aFrame)
|
||||
: TTextAttr<nscolor>(!aFrame) {
|
||||
- mRootNativeValue = aRootFrame->StyleText()->mColor.ToColor();
|
||||
+ mRootNativeValue = aRootFrame->StyleText()->mColor.ToColor(aRootFrame);
|
||||
mIsRootDefined = true;
|
||||
|
||||
if (aFrame) {
|
||||
- mNativeValue = aFrame->StyleText()->mColor.ToColor();
|
||||
+ mNativeValue = aFrame->StyleText()->mColor.ToColor(aFrame);
|
||||
mIsDefined = true;
|
||||
}
|
||||
}
|
||||
13
src/accessible/windows/ia2/ia2AccessibleComponent-cpp.patch
Normal file
13
src/accessible/windows/ia2/ia2AccessibleComponent-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/accessible/windows/ia2/ia2AccessibleComponent.cpp b/accessible/windows/ia2/ia2AccessibleComponent.cpp
|
||||
index 7837fdee3db339543f8b3d95dcb23ebe99aed8dc..207adf3ded9848b84ec89e94f80e8e02f161923c 100644
|
||||
--- a/accessible/windows/ia2/ia2AccessibleComponent.cpp
|
||||
+++ b/accessible/windows/ia2/ia2AccessibleComponent.cpp
|
||||
@@ -81,7 +81,7 @@ ia2AccessibleComponent::get_foreground(IA2Color* aForeground) {
|
||||
if (!acc) return CO_E_OBJNOTCONNECTED;
|
||||
|
||||
nsIFrame* frame = acc->GetFrame();
|
||||
- if (frame) *aForeground = frame->StyleText()->mColor.ToColor();
|
||||
+ if (frame) *aForeground = frame->StyleText()->mColor.ToColor(frame);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/customizableui/CustomizableUI.sys.mjs b/browser/components/customizableui/CustomizableUI.sys.mjs
|
||||
index 5905271a3343efa04b45f5d1a63bfca3de342755..af76922c1ba0b35a0072ec044f7d0860f9295d9d 100644
|
||||
index 5905271a3343efa04b45f5d1a63bfca3de342755..37f57de0ad72271d4c6e188ab9841b23b95f08d0 100644
|
||||
--- a/browser/components/customizableui/CustomizableUI.sys.mjs
|
||||
+++ b/browser/components/customizableui/CustomizableUI.sys.mjs
|
||||
@@ -13,6 +13,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
@@ -195,7 +195,7 @@ index 5905271a3343efa04b45f5d1a63bfca3de342755..af76922c1ba0b35a0072ec044f7d0860
|
||||
+ win.gZenVerticalTabsManager._hasSetSingleToolbar &&
|
||||
+ Services.prefs.getBoolPref("zen.view.overflow-webext-toolbar", true) &&
|
||||
+ !win.gURLBar.hasAttribute("breakout-extend")) {
|
||||
+ const availSelectors = ":is(#page-action-buttons, #zen-copy-url-button, .unified-extensions-item)";
|
||||
+ const availSelectors = ":is(#page-action-buttons, #zen-copy-url-button, .unified-extensions-item, .urlbar-addon-page-action)";
|
||||
+ const width = [
|
||||
+ ...win.gURLBar._inputContainer.querySelectorAll(availSelectors),
|
||||
+ ...win.document.getElementById("zen-overflow-extensions-list").querySelectorAll(availSelectors)
|
||||
|
||||
@@ -793,6 +793,7 @@ const zenMissingKeyboardShortcutL10n = {
|
||||
key_selectTab7: "zen-key-select-tab-7",
|
||||
key_selectTab8: "zen-key-select-tab-8",
|
||||
key_selectLastTab: "zen-key-select-tab-last",
|
||||
key_duplicateTab: "customkeys-file-duplicate-tab",
|
||||
|
||||
key_showAllTabs: "zen-key-show-all-tabs",
|
||||
key_gotoHistory: "zen-key-goto-history",
|
||||
@@ -801,6 +802,7 @@ const zenMissingKeyboardShortcutL10n = {
|
||||
key_redo: "zen-key-redo",
|
||||
|
||||
key_inspectorMac: "zen-key-inspector-mac",
|
||||
key_findSelection: "zen-key-find-selection",
|
||||
|
||||
// Devtools
|
||||
key_toggleToolbox: "zen-devtools-toggle-shortcut",
|
||||
@@ -1124,7 +1126,7 @@ var gZenCKSSettings = {
|
||||
this._hasSafed = false;
|
||||
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-invalid`);
|
||||
input.classList.remove(`${ZEN_CKS_INPUT_FIELD_CLASS}-not-set`);
|
||||
input.value = modifiers.toDisplayString() + shortcut;
|
||||
input.value = modifiers.toDisplayString() + gZenKeyboardShortcutsManager.getKeyDisplay(shortcut);
|
||||
this._latestValidKey = shortcut;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js
|
||||
index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c1a15b335 100644
|
||||
index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a064fea9b 100644
|
||||
--- a/browser/components/tabbrowser/content/tabgroup.js
|
||||
+++ b/browser/components/tabbrowser/content/tabgroup.js
|
||||
@@ -14,11 +14,11 @@
|
||||
@@ -147,7 +147,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c
|
||||
});
|
||||
}
|
||||
|
||||
@@ -478,13 +511,65 @@
|
||||
@@ -478,13 +511,68 @@
|
||||
* @returns {MozTabbrowserTab[]}
|
||||
*/
|
||||
get tabs() {
|
||||
@@ -162,8 +162,9 @@ index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c
|
||||
+ tabsCollect.push(item);
|
||||
+ if (gBrowser.isTabGroup(item)) {
|
||||
+ tabsCollect.push(...item.tabs);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
- return childrenArray.filter(node => node.matches("tab"));
|
||||
+ return tabsCollect.filter(node => node.matches("tab"));
|
||||
+ }
|
||||
+
|
||||
@@ -189,9 +190,8 @@ index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c
|
||||
+ result.push(labelContainer);
|
||||
+ }
|
||||
+ result.push(...item.childGroupsAndTabs);
|
||||
}
|
||||
}
|
||||
- return childrenArray.filter(node => node.matches("tab"));
|
||||
+ }
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
@@ -210,6 +210,9 @@ index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ if (this.pinned && gZenWorkspaces.activeWorkspaceElement?.hasCollapsedPinnedTabs) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
@@ -218,7 +221,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,7 +677,6 @@
|
||||
@@ -592,7 +680,6 @@
|
||||
);
|
||||
} else {
|
||||
if (tabOrSplitView.pinned) {
|
||||
@@ -226,7 +229,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c
|
||||
}
|
||||
let tabToMove =
|
||||
this.ownerGlobal === tabOrSplitView.ownerGlobal
|
||||
@@ -661,7 +745,7 @@
|
||||
@@ -661,7 +748,7 @@
|
||||
*/
|
||||
on_click(event) {
|
||||
let isToggleElement =
|
||||
@@ -235,7 +238,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..30e8dda663df8e96dbed5fe5f12f828c
|
||||
event.target === this.#overflowCountLabel;
|
||||
if (isToggleElement && event.button === 0) {
|
||||
event.preventDefault();
|
||||
@@ -740,5 +824,6 @@
|
||||
@@ -740,5 +827,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
diff --git a/browser/modules/URILoadingHelper.sys.mjs b/browser/modules/URILoadingHelper.sys.mjs
|
||||
index ed6b9fda700b2b4b35836a77a4da953377a72f4b..22acedcf1006f994ec8b6bf8991b4202e12a6f39 100644
|
||||
index bd2e54e914b171df9b8bcc7dcbc2388e9641f6c6..8b3cb6542bea3fb89e47adc93cb13f94447450e2 100644
|
||||
--- a/browser/modules/URILoadingHelper.sys.mjs
|
||||
+++ b/browser/modules/URILoadingHelper.sys.mjs
|
||||
@@ -224,6 +224,7 @@ function openInWindow(url, params, sourceWindow) {
|
||||
@@ -228,6 +228,7 @@ function openInWindow(url, params, sourceWindow) {
|
||||
features,
|
||||
sa
|
||||
);
|
||||
@@ -10,7 +10,7 @@ index ed6b9fda700b2b4b35836a77a4da953377a72f4b..22acedcf1006f994ec8b6bf8991b4202
|
||||
}
|
||||
|
||||
function openInCurrentTab(targetBrowser, url, uriObj, params) {
|
||||
@@ -541,7 +542,7 @@ export const URILoadingHelper = {
|
||||
@@ -545,7 +546,7 @@ export const URILoadingHelper = {
|
||||
// page. If a load request bounces off for the currently selected tab,
|
||||
// we'll open a new tab instead.
|
||||
let tab = w.gBrowser.getTabForBrowser(targetBrowser);
|
||||
@@ -19,7 +19,7 @@ index ed6b9fda700b2b4b35836a77a4da953377a72f4b..22acedcf1006f994ec8b6bf8991b4202
|
||||
where = "tab";
|
||||
targetBrowser = null;
|
||||
} else if (
|
||||
@@ -974,7 +975,7 @@ export const URILoadingHelper = {
|
||||
@@ -978,7 +979,7 @@ export const URILoadingHelper = {
|
||||
ignoreQueryString || replaceQueryString,
|
||||
ignoreFragmentWhenComparing
|
||||
);
|
||||
@@ -28,8 +28,8 @@ index ed6b9fda700b2b4b35836a77a4da953377a72f4b..22acedcf1006f994ec8b6bf8991b4202
|
||||
for (let i = 0; i < browsers.length; i++) {
|
||||
let browser = browsers[i];
|
||||
let browserCompare = cleanURL(
|
||||
@@ -1026,7 +1027,7 @@ export const URILoadingHelper = {
|
||||
aSplitView.replaceTab(tabToReplace, tabToMove);
|
||||
@@ -1034,7 +1035,7 @@ export const URILoadingHelper = {
|
||||
}
|
||||
aSplitView.ownerGlobal.focus();
|
||||
} else {
|
||||
- aWindow.gBrowser.tabContainer.selectedIndex = i;
|
||||
|
||||
@@ -436,6 +436,7 @@
|
||||
}
|
||||
|
||||
#zen-copy-current-url-button,
|
||||
#share-tab-button,
|
||||
#zen-site-data-header-share {
|
||||
list-style-image: url("share.svg");
|
||||
}
|
||||
@@ -925,7 +926,7 @@
|
||||
|
||||
position: relative;
|
||||
|
||||
list-style-image: url("paintbrush.svg");
|
||||
list-style-image: url("boost.svg");
|
||||
|
||||
& .toolbarbutton-text {
|
||||
display: none;
|
||||
@@ -938,6 +939,8 @@
|
||||
& image {
|
||||
-moz-context-properties: fill, fill-opacity;
|
||||
fill: currentColor;
|
||||
width: 14px;
|
||||
fill-opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1067,7 +1070,7 @@
|
||||
}
|
||||
|
||||
#zen-boost-shuffle {
|
||||
list-style-image: url("arrow-rotate-anticlockwise.svg");
|
||||
list-style-image: url("dice.svg");
|
||||
}
|
||||
|
||||
#zen-boost-css-picker {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* skin/classic/browser/zen-icons/autoplay-media-fill.svg (../shared/zen-icons/nucleo/autoplay-media-fill.svg)
|
||||
* skin/classic/browser/zen-icons/autoplay-media.svg (../shared/zen-icons/nucleo/autoplay-media.svg)
|
||||
* skin/classic/browser/zen-icons/back.svg (../shared/zen-icons/nucleo/back.svg)
|
||||
* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg)
|
||||
* skin/classic/browser/zen-icons/block.svg (../shared/zen-icons/nucleo/block.svg)
|
||||
* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg)
|
||||
* skin/classic/browser/zen-icons/bolt.svg (../shared/zen-icons/nucleo/bolt.svg)
|
||||
@@ -37,6 +38,7 @@
|
||||
* skin/classic/browser/zen-icons/desktop-notification-fill.svg (../shared/zen-icons/nucleo/desktop-notification-fill.svg)
|
||||
* skin/classic/browser/zen-icons/desktop-notification.svg (../shared/zen-icons/nucleo/desktop-notification.svg)
|
||||
* skin/classic/browser/zen-icons/developer.svg (../shared/zen-icons/nucleo/developer.svg)
|
||||
* skin/classic/browser/zen-icons/dice.svg (../shared/zen-icons/nucleo/dice.svg)
|
||||
* skin/classic/browser/zen-icons/downloads.svg (../shared/zen-icons/nucleo/downloads.svg)
|
||||
* skin/classic/browser/zen-icons/drag-indicator.svg (../shared/zen-icons/nucleo/drag-indicator.svg)
|
||||
* skin/classic/browser/zen-icons/duplicate-tab.svg (../shared/zen-icons/nucleo/duplicate-tab.svg)
|
||||
@@ -102,26 +104,26 @@
|
||||
* skin/classic/browser/zen-icons/popup-fill.svg (../shared/zen-icons/nucleo/popup-fill.svg)
|
||||
* skin/classic/browser/zen-icons/popup.svg (../shared/zen-icons/nucleo/popup.svg)
|
||||
* skin/classic/browser/zen-icons/print.svg (../shared/zen-icons/nucleo/print.svg)
|
||||
* skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg)
|
||||
* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg)
|
||||
* skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg)
|
||||
* skin/classic/browser/zen-icons/reader-mode.svg (../shared/zen-icons/nucleo/reader-mode.svg)
|
||||
* skin/classic/browser/zen-icons/reload.svg (../shared/zen-icons/nucleo/reload.svg)
|
||||
* skin/classic/browser/zen-icons/save.svg (../shared/zen-icons/nucleo/save.svg)
|
||||
* skin/classic/browser/zen-icons/screen-blocked.svg (../shared/zen-icons/nucleo/screen-blocked.svg)
|
||||
* skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg)
|
||||
* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg)
|
||||
* skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg)
|
||||
* skin/classic/browser/zen-icons/search-glass.svg (../shared/zen-icons/nucleo/search-glass.svg)
|
||||
* skin/classic/browser/zen-icons/search-page.svg (../shared/zen-icons/nucleo/search-page.svg)
|
||||
* skin/classic/browser/zen-icons/security-broken.svg (../shared/zen-icons/nucleo/security-broken.svg)
|
||||
* skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg)
|
||||
* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg)
|
||||
* skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg)
|
||||
* skin/classic/browser/zen-icons/send-to-device.svg (../shared/zen-icons/nucleo/send-to-device.svg)
|
||||
* skin/classic/browser/zen-icons/settings-fill.svg (../shared/zen-icons/nucleo/settings-fill.svg)
|
||||
* skin/classic/browser/zen-icons/settings.svg (../shared/zen-icons/nucleo/settings.svg)
|
||||
* skin/classic/browser/zen-icons/share.svg (../shared/zen-icons/nucleo/share.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar-right.svg (../shared/zen-icons/nucleo/sidebar-right.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg)
|
||||
* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg)
|
||||
* skin/classic/browser/zen-icons/sliders.svg (../shared/zen-icons/nucleo/sliders.svg)
|
||||
* skin/classic/browser/zen-icons/sparkles.svg (../shared/zen-icons/nucleo/sparkles.svg)
|
||||
* skin/classic/browser/zen-icons/spell-check.svg (../shared/zen-icons/nucleo/spell-check.svg)
|
||||
@@ -161,6 +163,7 @@
|
||||
* skin/classic/browser/zen-icons/autoplay-media-fill.svg (../shared/zen-icons/nucleo/autoplay-media-fill.svg)
|
||||
* skin/classic/browser/zen-icons/autoplay-media.svg (../shared/zen-icons/nucleo/autoplay-media.svg)
|
||||
* skin/classic/browser/zen-icons/back.svg (../shared/zen-icons/nucleo/back.svg)
|
||||
* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg)
|
||||
* skin/classic/browser/zen-icons/block.svg (../shared/zen-icons/nucleo/block.svg)
|
||||
* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg)
|
||||
* skin/classic/browser/zen-icons/bolt.svg (../shared/zen-icons/nucleo/bolt.svg)
|
||||
@@ -185,6 +188,7 @@
|
||||
* skin/classic/browser/zen-icons/desktop-notification-fill.svg (../shared/zen-icons/nucleo/desktop-notification-fill.svg)
|
||||
* skin/classic/browser/zen-icons/desktop-notification.svg (../shared/zen-icons/nucleo/desktop-notification.svg)
|
||||
* skin/classic/browser/zen-icons/developer.svg (../shared/zen-icons/nucleo/developer.svg)
|
||||
* skin/classic/browser/zen-icons/dice.svg (../shared/zen-icons/nucleo/dice.svg)
|
||||
* skin/classic/browser/zen-icons/downloads.svg (../shared/zen-icons/nucleo/downloads.svg)
|
||||
* skin/classic/browser/zen-icons/drag-indicator.svg (../shared/zen-icons/nucleo/drag-indicator.svg)
|
||||
* skin/classic/browser/zen-icons/duplicate-tab.svg (../shared/zen-icons/nucleo/duplicate-tab.svg)
|
||||
@@ -250,26 +254,26 @@
|
||||
* skin/classic/browser/zen-icons/popup-fill.svg (../shared/zen-icons/nucleo/popup-fill.svg)
|
||||
* skin/classic/browser/zen-icons/popup.svg (../shared/zen-icons/nucleo/popup.svg)
|
||||
* skin/classic/browser/zen-icons/print.svg (../shared/zen-icons/nucleo/print.svg)
|
||||
* skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg)
|
||||
* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg)
|
||||
* skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg)
|
||||
* skin/classic/browser/zen-icons/reader-mode.svg (../shared/zen-icons/nucleo/reader-mode.svg)
|
||||
* skin/classic/browser/zen-icons/reload.svg (../shared/zen-icons/nucleo/reload.svg)
|
||||
* skin/classic/browser/zen-icons/save.svg (../shared/zen-icons/nucleo/save.svg)
|
||||
* skin/classic/browser/zen-icons/screen-blocked.svg (../shared/zen-icons/nucleo/screen-blocked.svg)
|
||||
* skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg)
|
||||
* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg)
|
||||
* skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg)
|
||||
* skin/classic/browser/zen-icons/search-glass.svg (../shared/zen-icons/nucleo/search-glass.svg)
|
||||
* skin/classic/browser/zen-icons/search-page.svg (../shared/zen-icons/nucleo/search-page.svg)
|
||||
* skin/classic/browser/zen-icons/security-broken.svg (../shared/zen-icons/nucleo/security-broken.svg)
|
||||
* skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg)
|
||||
* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg)
|
||||
* skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg)
|
||||
* skin/classic/browser/zen-icons/send-to-device.svg (../shared/zen-icons/nucleo/send-to-device.svg)
|
||||
* skin/classic/browser/zen-icons/settings-fill.svg (../shared/zen-icons/nucleo/settings-fill.svg)
|
||||
* skin/classic/browser/zen-icons/settings.svg (../shared/zen-icons/nucleo/settings.svg)
|
||||
* skin/classic/browser/zen-icons/share.svg (../shared/zen-icons/nucleo/share.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar-right.svg (../shared/zen-icons/nucleo/sidebar-right.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg)
|
||||
* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg)
|
||||
* skin/classic/browser/zen-icons/sliders.svg (../shared/zen-icons/nucleo/sliders.svg)
|
||||
* skin/classic/browser/zen-icons/sparkles.svg (../shared/zen-icons/nucleo/sparkles.svg)
|
||||
* skin/classic/browser/zen-icons/spell-check.svg (../shared/zen-icons/nucleo/spell-check.svg)
|
||||
@@ -309,6 +313,7 @@
|
||||
* skin/classic/browser/zen-icons/autoplay-media-fill.svg (../shared/zen-icons/nucleo/autoplay-media-fill.svg)
|
||||
* skin/classic/browser/zen-icons/autoplay-media.svg (../shared/zen-icons/nucleo/autoplay-media.svg)
|
||||
* skin/classic/browser/zen-icons/back.svg (../shared/zen-icons/nucleo/back.svg)
|
||||
* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg)
|
||||
* skin/classic/browser/zen-icons/block.svg (../shared/zen-icons/nucleo/block.svg)
|
||||
* skin/classic/browser/zen-icons/blocked-element.svg (../shared/zen-icons/nucleo/blocked-element.svg)
|
||||
* skin/classic/browser/zen-icons/bolt.svg (../shared/zen-icons/nucleo/bolt.svg)
|
||||
@@ -333,6 +338,7 @@
|
||||
* skin/classic/browser/zen-icons/desktop-notification-fill.svg (../shared/zen-icons/nucleo/desktop-notification-fill.svg)
|
||||
* skin/classic/browser/zen-icons/desktop-notification.svg (../shared/zen-icons/nucleo/desktop-notification.svg)
|
||||
* skin/classic/browser/zen-icons/developer.svg (../shared/zen-icons/nucleo/developer.svg)
|
||||
* skin/classic/browser/zen-icons/dice.svg (../shared/zen-icons/nucleo/dice.svg)
|
||||
* skin/classic/browser/zen-icons/downloads.svg (../shared/zen-icons/nucleo/downloads.svg)
|
||||
* skin/classic/browser/zen-icons/drag-indicator.svg (../shared/zen-icons/nucleo/drag-indicator.svg)
|
||||
* skin/classic/browser/zen-icons/duplicate-tab.svg (../shared/zen-icons/nucleo/duplicate-tab.svg)
|
||||
@@ -398,26 +404,26 @@
|
||||
* skin/classic/browser/zen-icons/popup-fill.svg (../shared/zen-icons/nucleo/popup-fill.svg)
|
||||
* skin/classic/browser/zen-icons/popup.svg (../shared/zen-icons/nucleo/popup.svg)
|
||||
* skin/classic/browser/zen-icons/print.svg (../shared/zen-icons/nucleo/print.svg)
|
||||
* skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg)
|
||||
* skin/classic/browser/zen-icons/privateBrowsing.svg (../shared/zen-icons/nucleo/privateBrowsing.svg)
|
||||
* skin/classic/browser/zen-icons/private-window.svg (../shared/zen-icons/nucleo/private-window.svg)
|
||||
* skin/classic/browser/zen-icons/reader-mode.svg (../shared/zen-icons/nucleo/reader-mode.svg)
|
||||
* skin/classic/browser/zen-icons/reload.svg (../shared/zen-icons/nucleo/reload.svg)
|
||||
* skin/classic/browser/zen-icons/save.svg (../shared/zen-icons/nucleo/save.svg)
|
||||
* skin/classic/browser/zen-icons/screen-blocked.svg (../shared/zen-icons/nucleo/screen-blocked.svg)
|
||||
* skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg)
|
||||
* skin/classic/browser/zen-icons/screenshot.svg (../shared/zen-icons/nucleo/screenshot.svg)
|
||||
* skin/classic/browser/zen-icons/screen.svg (../shared/zen-icons/nucleo/screen.svg)
|
||||
* skin/classic/browser/zen-icons/search-glass.svg (../shared/zen-icons/nucleo/search-glass.svg)
|
||||
* skin/classic/browser/zen-icons/search-page.svg (../shared/zen-icons/nucleo/search-page.svg)
|
||||
* skin/classic/browser/zen-icons/security-broken.svg (../shared/zen-icons/nucleo/security-broken.svg)
|
||||
* skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg)
|
||||
* skin/classic/browser/zen-icons/security.svg (../shared/zen-icons/nucleo/security.svg)
|
||||
* skin/classic/browser/zen-icons/security-warning.svg (../shared/zen-icons/nucleo/security-warning.svg)
|
||||
* skin/classic/browser/zen-icons/send-to-device.svg (../shared/zen-icons/nucleo/send-to-device.svg)
|
||||
* skin/classic/browser/zen-icons/settings-fill.svg (../shared/zen-icons/nucleo/settings-fill.svg)
|
||||
* skin/classic/browser/zen-icons/settings.svg (../shared/zen-icons/nucleo/settings.svg)
|
||||
* skin/classic/browser/zen-icons/share.svg (../shared/zen-icons/nucleo/share.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar-right.svg (../shared/zen-icons/nucleo/sidebar-right.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg)
|
||||
* skin/classic/browser/zen-icons/sidebars-right.svg (../shared/zen-icons/nucleo/sidebars-right.svg)
|
||||
* skin/classic/browser/zen-icons/sidebar.svg (../shared/zen-icons/nucleo/sidebar.svg)
|
||||
* skin/classic/browser/zen-icons/sliders.svg (../shared/zen-icons/nucleo/sliders.svg)
|
||||
* skin/classic/browser/zen-icons/sparkles.svg (../shared/zen-icons/nucleo/sparkles.svg)
|
||||
* skin/classic/browser/zen-icons/spell-check.svg (../shared/zen-icons/nucleo/spell-check.svg)
|
||||
@@ -456,8 +462,8 @@
|
||||
* skin/classic/browser/zen-icons/selectable/basket.svg (../shared/zen-icons/common/selectable/basket.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/bed.svg (../shared/zen-icons/common/selectable/bed.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/bell.svg (../shared/zen-icons/common/selectable/bell.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/book.svg (../shared/zen-icons/common/selectable/book.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/bookmark.svg (../shared/zen-icons/common/selectable/bookmark.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/book.svg (../shared/zen-icons/common/selectable/book.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/briefcase.svg (../shared/zen-icons/common/selectable/briefcase.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/brush.svg (../shared/zen-icons/common/selectable/brush.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/bug.svg (../shared/zen-icons/common/selectable/bug.svg)
|
||||
@@ -519,8 +525,8 @@
|
||||
* skin/classic/browser/zen-icons/selectable/shapes.svg (../shared/zen-icons/common/selectable/shapes.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/shirt.svg (../shared/zen-icons/common/selectable/shirt.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/skull.svg (../shared/zen-icons/common/selectable/skull.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/square.svg (../shared/zen-icons/common/selectable/square.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/squares.svg (../shared/zen-icons/common/selectable/squares.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/square.svg (../shared/zen-icons/common/selectable/square.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/star-1.svg (../shared/zen-icons/common/selectable/star-1.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/star.svg (../shared/zen-icons/common/selectable/star.svg)
|
||||
* skin/classic/browser/zen-icons/selectable/stats-chart.svg (../shared/zen-icons/common/selectable/stats-chart.svg)
|
||||
|
||||
5
src/browser/themes/shared/zen-icons/nucleo/dice.svg
Normal file
5
src/browser/themes/shared/zen-icons/nucleo/dice.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
#filter dumbComments emptyLines substitution
|
||||
# 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/.
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="context-fill" fill-opacity="context-fill-opacity" viewBox="0 0 18 18"><path d="M5 13.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2M9.5 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2m-2.25 2.25a1 1 0 1 0 0-2 1 1 0 0 0 0 2M1 13.75v-7c.033-.705.349-1.488.805-1.945.456-.456 1.239-.773 1.945-.805h7c.706.033 1.488.349 1.945.805.456.456.773 1.239.805 1.945v7c-.033.705-.349 1.488-.805 1.945-.456.456-1.239.773-1.945.805h-7c-.706-.033-1.488-.349-1.945-.805-.456-.456-.773-1.239-.805-1.945m1.866.884c.267.267.485.399.884.366h7c.399.033.617-.099.884-.366s.399-.485.366-.884v-7c.033-.399-.099-.617-.366-.884s-.485-.399-.884-.366h-7c-.399-.033-.617.099-.884.366s-.399.485-.366.884v7c-.033.399.099.617.366.884m12.274-2.737a.75.75 0 0 0 .852-.632l.978-6.581c.071-.703-.127-1.524-.511-2.042-.384-.519-1.112-.946-1.805-1.082L7.73.53C7.191.469 6.557.562 6.11.783s-.897.66-1.167 1.092a.75.75 0 1 0 1.299.749c.129-.258.275-.37.531-.497.258-.127.437-.178.735-.114l6.924 1.03c.399.026.595.188.82.492s.323.538.232.928l-.978 6.581a.75.75 0 0 0 .632.852z"/></svg>
|
||||
14
src/dom/canvas/CanvasRenderingContext2D-cpp.patch
Normal file
14
src/dom/canvas/CanvasRenderingContext2D-cpp.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
|
||||
index ca400d3aed179ebef8e005206f29b419ae56afc4..4d4e56f4a222bd61dea82638f3e0b30fbe56a176 100644
|
||||
--- a/dom/canvas/CanvasRenderingContext2D.cpp
|
||||
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
|
||||
@@ -1326,7 +1326,8 @@ Maybe<nscolor> CanvasRenderingContext2D::ParseColor(
|
||||
RefPtr<const ComputedStyle> canvasStyle =
|
||||
nsComputedDOMStyle::GetComputedStyle(mCanvasElement);
|
||||
if (canvasStyle) {
|
||||
- return Some(canvasStyle->StyleText()->mColor.ToColor());
|
||||
+ return Some(canvasStyle->StyleText()->mColor.ToColor(
|
||||
+ mCanvasElement->GetPrimaryFrame()));
|
||||
}
|
||||
}
|
||||
return data.mColor;
|
||||
13
src/dom/html/HTMLInputElement-cpp.patch
Normal file
13
src/dom/html/HTMLInputElement-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
|
||||
index 3374a88b9335de1659df548fe8c18610f675b336..540f22697e7b85bca2fd6d3fe952ed3944216e17 100644
|
||||
--- a/dom/html/HTMLInputElement.cpp
|
||||
+++ b/dom/html/HTMLInputElement.cpp
|
||||
@@ -768,7 +768,7 @@ static void SerializeColorForHTMLCompatibility(const StyleAbsoluteColor& aColor,
|
||||
// Raw StyleAbsoluteColor can have floats outside of 0-1 range e.g. when
|
||||
// display-p3 color is converted to srgb, and ToColor guarantees to fit the
|
||||
// values within the range.
|
||||
- nscolor color = aColor.ToColor();
|
||||
+ nscolor color = aColor.ToColor(nullptr);
|
||||
aResult.Truncate();
|
||||
aResult.AppendPrintf("#%02x%02x%02x", NS_GET_R(color), NS_GET_G(color),
|
||||
NS_GET_B(color));
|
||||
13
src/editor/libeditor/HTMLAbsPositionEditor-cpp.patch
Normal file
13
src/editor/libeditor/HTMLAbsPositionEditor-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/editor/libeditor/HTMLAbsPositionEditor.cpp b/editor/libeditor/HTMLAbsPositionEditor.cpp
|
||||
index 44bd8ba90e9828423742d768e64ad6204b3cf134..49d5c9512137ce28ac463223098515f6912452b1 100644
|
||||
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
|
||||
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
|
||||
@@ -1001,7 +1001,7 @@ nsresult HTMLEditor::GetTemporaryStyleForFocusedPositionedElement(
|
||||
|
||||
static const uint8_t kBlackBgTrigger = 0xd0;
|
||||
|
||||
- auto color = style->StyleText()->mColor.ToColor();
|
||||
+ auto color = style->StyleText()->mColor.ToColor(aElement.GetPrimaryFrame());
|
||||
if (NS_GET_R(color) >= kBlackBgTrigger &&
|
||||
NS_GET_G(color) >= kBlackBgTrigger &&
|
||||
NS_GET_B(color) >= kBlackBgTrigger) {
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/gfx/layers/AnimationInfo.cpp b/gfx/layers/AnimationInfo.cpp
|
||||
index 1d330056bd7a4e89aac5e5296a3c164fb42b5c42..ef112715580b6bb7238e8f37bbe3133e187685dc 100644
|
||||
index 1d330056bd7a4e89aac5e5296a3c164fb42b5c42..629fbdd748310c31aeb16b0a8d8e862a99314cc9 100644
|
||||
--- a/gfx/layers/AnimationInfo.cpp
|
||||
+++ b/gfx/layers/AnimationInfo.cpp
|
||||
@@ -14,6 +14,7 @@
|
||||
@@ -10,12 +10,20 @@ index 1d330056bd7a4e89aac5e5296a3c164fb42b5c42..ef112715580b6bb7238e8f37bbe3133e
|
||||
#include "nsIContent.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
@@ -343,7 +344,7 @@ static void SetAnimatable(NonCustomCSSPropertyId aProperty,
|
||||
@@ -341,9 +342,13 @@ static void SetAnimatable(NonCustomCSSPropertyId aProperty,
|
||||
case eCSSProperty_background_color: {
|
||||
// We don't support color animation on the compositor yet so that we can
|
||||
// resolve currentColor at this moment.
|
||||
nscolor foreground =
|
||||
aFrame->Style()->GetVisitedDependentColor(&nsStyleText::mColor);
|
||||
- nscolor foreground =
|
||||
- aFrame->Style()->GetVisitedDependentColor(&nsStyleText::mColor);
|
||||
- aAnimatable = aAnimationValue.GetColor(foreground);
|
||||
+ aAnimatable = zen::nsZenBoostsBackend::FilterColorFromPresContext(aAnimationValue.GetColor(foreground), aFrame->PresContext());
|
||||
+ nscolor foreground = aFrame->Style()->GetVisitedDependentColor(
|
||||
+ &nsStyleText::mColor, nullptr);
|
||||
+ nscolor resolved = aAnimationValue.GetColor(foreground);
|
||||
+ aAnimatable = aAnimationValue.IsCurrentColor()
|
||||
+ ? resolved
|
||||
+ : zen::nsZenBoostsBackend::ResolveStyleColor(resolved,
|
||||
+ aFrame);
|
||||
break;
|
||||
}
|
||||
case eCSSProperty_opacity:
|
||||
|
||||
16
src/gfx/thebes/gfxUtils-cpp.patch
Normal file
16
src/gfx/thebes/gfxUtils-cpp.patch
Normal file
@@ -0,0 +1,16 @@
|
||||
diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp
|
||||
index 6c19c572f06e8c4c97ce3f9dd390a32832e2f527..d11cbad2ee32a1507316809893e9c42a883e6c12 100644
|
||||
--- a/gfx/thebes/gfxUtils.cpp
|
||||
+++ b/gfx/thebes/gfxUtils.cpp
|
||||
@@ -1743,8 +1743,9 @@ DeviceColor ToDeviceColor(nscolor aColor) {
|
||||
return ToDeviceColor(sRGBColor::FromABGR(aColor));
|
||||
}
|
||||
|
||||
-DeviceColor ToDeviceColor(const StyleAbsoluteColor& aColor) {
|
||||
- return ToDeviceColor(aColor.ToColor());
|
||||
+DeviceColor ToDeviceColor(const StyleAbsoluteColor& aColor,
|
||||
+ const nsIFrame* aFrame) {
|
||||
+ return ToDeviceColor(aColor.ToColor(aFrame));
|
||||
}
|
||||
|
||||
sRGBColor ToSRGBColor(const StyleAbsoluteColor& aColor) {
|
||||
23
src/gfx/thebes/gfxUtils-h.patch
Normal file
23
src/gfx/thebes/gfxUtils-h.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h
|
||||
index 55f874429fd8cbb7a0a469eba33f6c777a5bc5f7..8cf0567d81fcae7413cee6df9471d1fa1738fc4a 100644
|
||||
--- a/gfx/thebes/gfxUtils.h
|
||||
+++ b/gfx/thebes/gfxUtils.h
|
||||
@@ -598,6 +598,9 @@ class ElementOrArray {
|
||||
};
|
||||
|
||||
struct StyleAbsoluteColor;
|
||||
+} // namespace mozilla
|
||||
+class nsIFrame;
|
||||
+namespace mozilla {
|
||||
|
||||
namespace gfx {
|
||||
|
||||
@@ -609,7 +612,7 @@ namespace gfx {
|
||||
* applicable).
|
||||
*/
|
||||
DeviceColor ToDeviceColor(const sRGBColor&);
|
||||
-DeviceColor ToDeviceColor(const StyleAbsoluteColor&);
|
||||
+DeviceColor ToDeviceColor(const StyleAbsoluteColor&, const nsIFrame*);
|
||||
DeviceColor ToDeviceColor(nscolor);
|
||||
|
||||
sRGBColor ToSRGBColor(const StyleAbsoluteColor&);
|
||||
14
src/image/AutoRestoreSVGState-h.patch
Normal file
14
src/image/AutoRestoreSVGState-h.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/image/AutoRestoreSVGState.h b/image/AutoRestoreSVGState.h
|
||||
index be639a7b78c13c2d56be49a9690bf711ccaf0a8f..28bea58034ead1206d77521934e92d3a69bfd84b 100644
|
||||
--- a/image/AutoRestoreSVGState.h
|
||||
+++ b/image/AutoRestoreSVGState.h
|
||||
@@ -47,6 +47,9 @@ class MOZ_STACK_CLASS AutoRestoreSVGState final {
|
||||
}
|
||||
return dom::PrefersColorSchemeOverride::None;
|
||||
}());
|
||||
+ pc->SetZenBoostsOverride(aSVGContext.GetZenBoostsAccent(),
|
||||
+ aSVGContext.GetZenBoostsComplementaryRotation(),
|
||||
+ aSVGContext.GetZenBoostsInverted());
|
||||
}
|
||||
|
||||
aSVGDocumentWrapper->mIsDrawing = true;
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
|
||||
index b5930f71e362eb78f74888e1b33b2a6f9dbb4ea4..dc1ba0b462402f62e47fcb32e2d7cd1a671a7fd8 100644
|
||||
index b5930f71e362eb78f74888e1b33b2a6f9dbb4ea4..2105911a18b64e210d3125fec1bfa8058ca07d4e 100644
|
||||
--- a/layout/base/PresShell.cpp
|
||||
+++ b/layout/base/PresShell.cpp
|
||||
@@ -135,6 +135,7 @@
|
||||
@@ -10,12 +10,13 @@ index b5930f71e362eb78f74888e1b33b2a6f9dbb4ea4..dc1ba0b462402f62e47fcb32e2d7cd1a
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsAutoLayoutPhase.h"
|
||||
#include "nsCOMArray.h"
|
||||
@@ -5572,7 +5573,7 @@ nscolor PresShell::GetDefaultBackgroundColorToDraw() const {
|
||||
@@ -5572,7 +5573,8 @@ nscolor PresShell::GetDefaultBackgroundColorToDraw() const {
|
||||
if (!mPresContext) {
|
||||
return NS_RGB(255, 255, 255);
|
||||
}
|
||||
- return mPresContext->DefaultBackgroundColor();
|
||||
+ return zen::nsZenBoostsBackend::FilterColorFromPresContext(mPresContext->DefaultBackgroundColor(), mPresContext);
|
||||
+ return zen::nsZenBoostsBackend::ResolveStyleColor(
|
||||
+ mPresContext->DefaultBackgroundColor(), GetRootFrame());
|
||||
}
|
||||
|
||||
void PresShell::UpdateCanvasBackground() {
|
||||
|
||||
39
src/layout/base/nsPresContext-h.patch
Normal file
39
src/layout/base/nsPresContext-h.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h
|
||||
index 13aa7141c8e5297d0dd6aa9bd78fd32f050e8123..149a89e928d354f116c54f71605830f5ec6b7f8a 100644
|
||||
--- a/layout/base/nsPresContext.h
|
||||
+++ b/layout/base/nsPresContext.h
|
||||
@@ -594,6 +594,22 @@ class nsPresContext : public nsISupports,
|
||||
*/
|
||||
void SetColorSchemeOverride(mozilla::dom::PrefersColorSchemeOverride);
|
||||
|
||||
+ // Zen boosts override. SVG images render in their own document, which has no
|
||||
+ // BrowsingContext to carry the page's boost, so the host propagates it here.
|
||||
+ void SetZenBoostsOverride(nscolor aAccent, float aComplementaryRotation,
|
||||
+ bool aInverted) {
|
||||
+ mZenBoostsOverrideAccent = aAccent;
|
||||
+ mZenBoostsOverrideComplementaryRotation = aComplementaryRotation;
|
||||
+ mZenBoostsOverrideInverted = aInverted;
|
||||
+ mHasZenBoostsOverride = true;
|
||||
+ }
|
||||
+ bool HasZenBoostsOverride() const { return mHasZenBoostsOverride; }
|
||||
+ nscolor ZenBoostsOverrideAccent() const { return mZenBoostsOverrideAccent; }
|
||||
+ float ZenBoostsOverrideComplementaryRotation() const {
|
||||
+ return mZenBoostsOverrideComplementaryRotation;
|
||||
+ }
|
||||
+ bool ZenBoostsOverrideInverted() const { return mZenBoostsOverrideInverted; }
|
||||
+
|
||||
/**
|
||||
* Return the device's screen size in inches, for font size
|
||||
* inflation.
|
||||
@@ -1441,6 +1457,11 @@ class nsPresContext : public nsISupports,
|
||||
mozilla::dom::PrefersColorSchemeOverride mOverriddenOrEmbedderColorScheme;
|
||||
mozilla::StyleForcedColors mForcedColors;
|
||||
|
||||
+ nscolor mZenBoostsOverrideAccent = 0;
|
||||
+ float mZenBoostsOverrideComplementaryRotation = 0.0f;
|
||||
+ bool mZenBoostsOverrideInverted = false;
|
||||
+ bool mHasZenBoostsOverride = false;
|
||||
+
|
||||
protected:
|
||||
virtual ~nsPresContext();
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
diff --git a/layout/generic/ViewportFrame.cpp b/layout/generic/ViewportFrame.cpp
|
||||
index 9d1c25c3834da50fd7dfa3a9583144f5817ee231..08b69a63ea3a8067861984fa2fcd25435c921c0d 100644
|
||||
--- a/layout/generic/ViewportFrame.cpp
|
||||
+++ b/layout/generic/ViewportFrame.cpp
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
+#include "mozilla/nsZenBoostsBackend.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@@ -291,15 +292,20 @@ ViewportFrame::BuildDisplayListForViewTransitionsAndNACTopLayer(
|
||||
}
|
||||
}
|
||||
|
||||
+ bool isAnonContent = false;
|
||||
if (dom::Element* container = doc->GetCustomContentContainer()) {
|
||||
if (nsIFrame* frame = container->GetPrimaryFrame()) {
|
||||
MOZ_ASSERT(frame->StyleDisplay()->mTopLayer != StyleTopLayer::None,
|
||||
"ua.css should ensure this");
|
||||
MOZ_ASSERT(frame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW));
|
||||
+ isAnonContent = frame->ContentIsRootOfNativeAnonymousSubtree();
|
||||
BuildDisplayListForTopLayerFrame(aBuilder, frame, &topLayerList);
|
||||
}
|
||||
}
|
||||
|
||||
+ if (auto zenBackend = zen::nsZenBoostsBackend::GetInstance()) {
|
||||
+ zenBackend->mCurrentFrameIsAnonymousContent = isAnonContent;
|
||||
+ }
|
||||
return MaybeWrapTopLayerList(
|
||||
aBuilder, uint16_t(TopLayerIndex::ViewTransitionsAndAnonymousContent),
|
||||
topLayerList);
|
||||
47
src/layout/generic/nsContainerFrame-cpp.patch
Normal file
47
src/layout/generic/nsContainerFrame-cpp.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
|
||||
index c27fec39f9e32e61f0e335e5880ce3e97074965b..7b4f7760dcf92ead74c9f89cfc7a067892af9e34 100644
|
||||
--- a/layout/generic/nsContainerFrame.cpp
|
||||
+++ b/layout/generic/nsContainerFrame.cpp
|
||||
@@ -349,7 +349,8 @@ class nsDisplaySelectionOverlay final : public nsPaintedDisplayItem {
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
NS_DISPLAY_DECL_NAME("SelectionOverlay", TYPE_SELECTION_OVERLAY)
|
||||
|
||||
- static DeviceColor ComputeColorFromSelectionStyle(const ComputedStyle&);
|
||||
+ static DeviceColor ComputeColorFromSelectionStyle(const ComputedStyle&,
|
||||
+ const nsIFrame*);
|
||||
static DeviceColor ApplyTransparencyIfNecessary(nscolor);
|
||||
|
||||
private:
|
||||
@@ -371,9 +372,9 @@ DeviceColor nsDisplaySelectionOverlay::ApplyTransparencyIfNecessary(
|
||||
}
|
||||
|
||||
DeviceColor nsDisplaySelectionOverlay::ComputeColorFromSelectionStyle(
|
||||
- const ComputedStyle& aStyle) {
|
||||
- return ApplyTransparencyIfNecessary(
|
||||
- aStyle.GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor));
|
||||
+ const ComputedStyle& aStyle, const nsIFrame* aFrame) {
|
||||
+ return ApplyTransparencyIfNecessary(aStyle.GetVisitedDependentColor(
|
||||
+ &nsStyleBackground::mBackgroundColor, aFrame));
|
||||
}
|
||||
|
||||
void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder,
|
||||
@@ -472,7 +473,8 @@ void nsContainerFrame::DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
|
||||
ComputeHighlightSelectionStyle(sd->mHighlightData.mHighlightName)) {
|
||||
aList->AppendNewToTopWithIndex<nsDisplaySelectionOverlay>(
|
||||
aBuilder, this, index++,
|
||||
- nsDisplaySelectionOverlay::ComputeColorFromSelectionStyle(*style));
|
||||
+ nsDisplaySelectionOverlay::ComputeColorFromSelectionStyle(*style,
|
||||
+ this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,7 +482,8 @@ void nsContainerFrame::DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
|
||||
if (normal) {
|
||||
DeviceColor color;
|
||||
if (RefPtr<ComputedStyle> style = ComputeSelectionStyle(selectionValue)) {
|
||||
- color = nsDisplaySelectionOverlay::ComputeColorFromSelectionStyle(*style);
|
||||
+ color = nsDisplaySelectionOverlay::ComputeColorFromSelectionStyle(*style,
|
||||
+ this);
|
||||
} else {
|
||||
LookAndFeel::ColorID colorID;
|
||||
if (selectionValue == nsISelectionController::SELECTION_ON) {
|
||||
13
src/layout/generic/nsIFrame-h.patch
Normal file
13
src/layout/generic/nsIFrame-h.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
|
||||
index 588b00d7ee115f0a7513e357af7ab5eee28311c1..bf07b69c7e7957e6e558403e069f16e2dec3cad0 100644
|
||||
--- a/layout/generic/nsIFrame.h
|
||||
+++ b/layout/generic/nsIFrame.h
|
||||
@@ -1008,7 +1008,7 @@ class nsIFrame : public nsQueryFrame {
|
||||
/** Also forward GetVisitedDependentColor to the style */
|
||||
template <typename T, typename S>
|
||||
nscolor GetVisitedDependentColor(T S::* aField) {
|
||||
- return mComputedStyle->GetVisitedDependentColor(aField);
|
||||
+ return mComputedStyle->GetVisitedDependentColor(aField, this);
|
||||
}
|
||||
|
||||
/**
|
||||
13
src/layout/generic/nsImageFrame-cpp.patch
Normal file
13
src/layout/generic/nsImageFrame-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp
|
||||
index c4ff60477e3061aeeecbdedb5ad8054d3808ab6e..40857d430eda576c4fca613857860f32abb39e2d 100644
|
||||
--- a/layout/generic/nsImageFrame.cpp
|
||||
+++ b/layout/generic/nsImageFrame.cpp
|
||||
@@ -1764,7 +1764,7 @@ void nsImageFrame::DisplayAltText(nsPresContext* aPresContext,
|
||||
const nsRect& aRect) {
|
||||
// Set font and color
|
||||
aRenderingContext.SetColor(
|
||||
- sRGBColor::FromABGR(StyleText()->mColor.ToColor()));
|
||||
+ sRGBColor::FromABGR(StyleText()->mColor.ToColor(this)));
|
||||
RefPtr<nsFontMetrics> fm =
|
||||
nsLayoutUtils::GetInflatedFontMetricsForFrame(this);
|
||||
|
||||
13
src/layout/generic/nsTextFrame-cpp.patch
Normal file
13
src/layout/generic/nsTextFrame-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
|
||||
index e7f7943a19d3ac71872d0a8439b6ed90e8fd423d..eb3e84fabc67d95b6d194b5aaf3aaef7c38480c0 100644
|
||||
--- a/layout/generic/nsTextFrame.cpp
|
||||
+++ b/layout/generic/nsTextFrame.cpp
|
||||
@@ -6381,7 +6381,7 @@ void nsTextFrame::DrawSelectionDecorations(
|
||||
computedStyleFromPseudo->StyleTextReset()->mTextDecorationStyle;
|
||||
params.color =
|
||||
computedStyleFromPseudo->StyleTextReset()
|
||||
- ->mTextDecorationColor.CalcColor(*computedStyleFromPseudo);
|
||||
+ ->mTextDecorationColor.CalcColor(*computedStyleFromPseudo, this);
|
||||
params.decoration =
|
||||
computedStyleFromPseudo->StyleTextReset()->mTextDecorationLine;
|
||||
params.descentLimit = -1.f;
|
||||
67
src/layout/generic/nsTextPaintStyle-cpp.patch
Normal file
67
src/layout/generic/nsTextPaintStyle-cpp.patch
Normal file
@@ -0,0 +1,67 @@
|
||||
diff --git a/layout/generic/nsTextPaintStyle.cpp b/layout/generic/nsTextPaintStyle.cpp
|
||||
index 5d1bf44687e925aff67f44c8e0629f7f06e84e98..1fa60a4d91edc60ba733cefc5f73ab8b7684d02a 100644
|
||||
--- a/layout/generic/nsTextPaintStyle.cpp
|
||||
+++ b/layout/generic/nsTextPaintStyle.cpp
|
||||
@@ -240,7 +240,7 @@ bool nsTextPaintStyle::GetTargetTextColor(nscolor* aForeColor) {
|
||||
(mTargetTextPseudoStyle->HasAuthorSpecifiedTextColor() ||
|
||||
mTargetTextPseudoStyle->HasAuthorSpecifiedBorderOrBackground())) {
|
||||
*aForeColor = mTargetTextPseudoStyle->GetVisitedDependentColor(
|
||||
- &nsStyleText::mWebkitTextFillColor);
|
||||
+ &nsStyleText::mWebkitTextFillColor, mFrame);
|
||||
return mTargetTextPseudoStyle->HasAuthorSpecifiedTextColor();
|
||||
}
|
||||
*aForeColor = LookAndFeel::Color(
|
||||
@@ -257,7 +257,7 @@ bool nsTextPaintStyle::GetTargetTextBackgroundColor(nscolor* aBackColor) {
|
||||
(mTargetTextPseudoStyle->HasAuthorSpecifiedTextColor() ||
|
||||
mTargetTextPseudoStyle->HasAuthorSpecifiedBorderOrBackground())) {
|
||||
*aBackColor = mTargetTextPseudoStyle->GetVisitedDependentColor(
|
||||
- &nsStyleBackground::mBackgroundColor);
|
||||
+ &nsStyleBackground::mBackgroundColor, mFrame);
|
||||
return NS_GET_A(*aBackColor) != 0;
|
||||
}
|
||||
*aBackColor = LookAndFeel::Color(
|
||||
@@ -295,7 +295,8 @@ bool nsTextPaintStyle::GetCustomHighlightTextColor(nsAtom* aHighlightName,
|
||||
return false;
|
||||
}
|
||||
|
||||
- *aForeColor = highlightStyle->GetVisitedDependentColor(&nsStyleText::mColor);
|
||||
+ *aForeColor =
|
||||
+ highlightStyle->GetVisitedDependentColor(&nsStyleText::mColor, mFrame);
|
||||
|
||||
return highlightStyle->HasAuthorSpecifiedTextColor();
|
||||
}
|
||||
@@ -317,7 +318,7 @@ bool nsTextPaintStyle::GetCustomHighlightBackgroundColor(nsAtom* aHighlightName,
|
||||
}
|
||||
|
||||
*aBackColor = highlightStyle->GetVisitedDependentColor(
|
||||
- &nsStyleBackground::mBackgroundColor);
|
||||
+ &nsStyleBackground::mBackgroundColor, mFrame);
|
||||
return NS_GET_A(*aBackColor) != 0;
|
||||
}
|
||||
|
||||
@@ -466,19 +467,19 @@ bool nsTextPaintStyle::InitSelectionColorsAndShadow() {
|
||||
// this is web content or chrome content. See bug 2029839.
|
||||
if (!mFrame->PresContext()->Document()->ChromeRulesEnabled()) {
|
||||
mSelectionBGColor = mSelectionPseudoStyle->GetVisitedDependentColor(
|
||||
- &nsStyleBackground::mBackgroundColor);
|
||||
- mSelectionTextColor =
|
||||
- mSelectionPseudoStyle->GetVisitedDependentColor(&nsStyleText::mColor);
|
||||
+ &nsStyleBackground::mBackgroundColor, mFrame);
|
||||
+ mSelectionTextColor = mSelectionPseudoStyle->GetVisitedDependentColor(
|
||||
+ &nsStyleText::mColor, mFrame);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nscolor bgColor = mSelectionPseudoStyle->GetVisitedDependentColor(
|
||||
- &nsStyleBackground::mBackgroundColor);
|
||||
+ &nsStyleBackground::mBackgroundColor, mFrame);
|
||||
mSelectionPseudoStyle->HasAuthorSpecifiedTextColor() ||
|
||||
NS_GET_A(bgColor) > 0) {
|
||||
mSelectionBGColor = bgColor;
|
||||
- mSelectionTextColor =
|
||||
- mSelectionPseudoStyle->GetVisitedDependentColor(&nsStyleText::mColor);
|
||||
+ mSelectionTextColor = mSelectionPseudoStyle->GetVisitedDependentColor(
|
||||
+ &nsStyleText::mColor, mFrame);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
13
src/layout/mathml/nsMathMLChar-cpp.patch
Normal file
13
src/layout/mathml/nsMathMLChar-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp
|
||||
index befaf7fed81a486f61e1186775c138ce5473a057..c7eb36dc9fcd06f8641d2d1a974e75eb24e07669 100644
|
||||
--- a/layout/mathml/nsMathMLChar.cpp
|
||||
+++ b/layout/mathml/nsMathMLChar.cpp
|
||||
@@ -1686,7 +1686,7 @@ void nsMathMLChar::PaintForeground(nsIFrame* aForFrame,
|
||||
|
||||
// Set color ...
|
||||
nscolor fgColor = computedStyle->GetVisitedDependentColor(
|
||||
- &nsStyleText::mWebkitTextFillColor);
|
||||
+ &nsStyleText::mWebkitTextFillColor, aForFrame);
|
||||
if (aIsSelected) {
|
||||
// get color to use for selection from the look&feel object
|
||||
fgColor = LookAndFeel::Color(LookAndFeel::ColorID::Highlighttext, aForFrame,
|
||||
87
src/layout/painting/nsCSSRendering-cpp.patch
Normal file
87
src/layout/painting/nsCSSRendering-cpp.patch
Normal file
@@ -0,0 +1,87 @@
|
||||
diff --git a/layout/painting/nsCSSRendering.cpp b/layout/painting/nsCSSRendering.cpp
|
||||
index a581b039a8681f7d8191edfad100d287af38592e..4cd3d6695a04a42d806c36f8d5a324cac9efda34 100644
|
||||
--- a/layout/painting/nsCSSRendering.cpp
|
||||
+++ b/layout/painting/nsCSSRendering.cpp
|
||||
@@ -598,7 +598,8 @@ void nsCSSRendering::ComputePixelRadii(const nsRectCornerRadii& aRadii,
|
||||
}
|
||||
}
|
||||
|
||||
-static Maybe<nsStyleBorder> GetBorderIfVisited(const ComputedStyle& aStyle) {
|
||||
+static Maybe<nsStyleBorder> GetBorderIfVisited(const ComputedStyle& aStyle,
|
||||
+ const nsIFrame* aFrame) {
|
||||
Maybe<nsStyleBorder> result;
|
||||
// Don't check RelevantLinkVisited here, since we want to take the
|
||||
// same amount of time whether or not it's true.
|
||||
@@ -611,7 +612,7 @@ static Maybe<nsStyleBorder> GetBorderIfVisited(const ComputedStyle& aStyle) {
|
||||
auto& newBorder = result.ref();
|
||||
for (const auto side : mozilla::AllPhysicalSides()) {
|
||||
nscolor color = aStyle.GetVisitedDependentColor(
|
||||
- nsStyleBorder::BorderColorFieldFor(side));
|
||||
+ nsStyleBorder::BorderColorFieldFor(side), aFrame);
|
||||
newBorder.BorderColorFor(side) = StyleColor::FromColor(color);
|
||||
}
|
||||
|
||||
@@ -624,7 +625,7 @@ ImgDrawResult nsCSSRendering::PaintBorder(
|
||||
ComputedStyle* aStyle, PaintBorderFlags aFlags, Sides aSkipSides) {
|
||||
AUTO_PROFILER_LABEL("nsCSSRendering::PaintBorder", GRAPHICS);
|
||||
|
||||
- Maybe<nsStyleBorder> visitedBorder = GetBorderIfVisited(*aStyle);
|
||||
+ Maybe<nsStyleBorder> visitedBorder = GetBorderIfVisited(*aStyle, aForFrame);
|
||||
return PaintBorderWithStyleBorder(
|
||||
aPresContext, aRenderingContext, aForFrame, aDirtyRect, aBorderArea,
|
||||
visitedBorder.refOr(*aStyle->StyleBorder()), aStyle, aFlags, aSkipSides);
|
||||
@@ -634,7 +635,7 @@ Maybe<nsCSSBorderRenderer> nsCSSRendering::CreateBorderRenderer(
|
||||
nsPresContext* aPresContext, DrawTarget* aDrawTarget, nsIFrame* aForFrame,
|
||||
const nsRect& aDirtyRect, const nsRect& aBorderArea, ComputedStyle* aStyle,
|
||||
bool* aOutBorderIsEmpty, Sides aSkipSides) {
|
||||
- Maybe<nsStyleBorder> visitedBorder = GetBorderIfVisited(*aStyle);
|
||||
+ Maybe<nsStyleBorder> visitedBorder = GetBorderIfVisited(*aStyle, aForFrame);
|
||||
return CreateBorderRendererWithStyleBorder(
|
||||
aPresContext, aDrawTarget, aForFrame, aDirtyRect, aBorderArea,
|
||||
visitedBorder.refOr(*aStyle->StyleBorder()), aStyle, aOutBorderIsEmpty,
|
||||
@@ -649,7 +650,7 @@ ImgDrawResult nsCSSRendering::CreateWebRenderCommandsForBorder(
|
||||
mozilla::layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
const auto* style = aForFrame->Style();
|
||||
- Maybe<nsStyleBorder> visitedBorder = GetBorderIfVisited(*style);
|
||||
+ Maybe<nsStyleBorder> visitedBorder = GetBorderIfVisited(*style, aForFrame);
|
||||
return nsCSSRendering::CreateWebRenderCommandsForBorderWithStyleBorder(
|
||||
aItem, aForFrame, aBorderArea, aBuilder, aResources, aSc, aManager,
|
||||
aDisplayListBuilder, visitedBorder.refOr(*style->StyleBorder()));
|
||||
@@ -785,7 +786,7 @@ static nsCSSBorderRenderer ConstructBorderRenderer(
|
||||
// pull out styles, colors
|
||||
for (const auto i : mozilla::AllPhysicalSides()) {
|
||||
borderStyles[i] = aStyleBorder.GetBorderStyle(i);
|
||||
- borderColors[i] = aStyleBorder.BorderColorFor(i).CalcColor(*aStyle);
|
||||
+ borderColors[i] = aStyleBorder.BorderColorFor(i).CalcColor(*aStyle, aForFrame);
|
||||
}
|
||||
|
||||
PrintAsFormatString(
|
||||
@@ -1005,7 +1006,7 @@ nsCSSRendering::CreateBorderRendererForNonThemedOutline(
|
||||
// This handles treating the initial color as 'currentColor'; if we
|
||||
// ever want 'invert' back we'll need to do a bit of work here too.
|
||||
nscolor outlineColor =
|
||||
- aStyle->GetVisitedDependentColor(&nsStyleOutline::mOutlineColor);
|
||||
+ aStyle->GetVisitedDependentColor(&nsStyleOutline::mOutlineColor, aForFrame);
|
||||
nscolor outlineColors[4] = {outlineColor, outlineColor, outlineColor,
|
||||
outlineColor};
|
||||
|
||||
@@ -2341,7 +2342,7 @@ static Maybe<nscolor> CalcScrollbarColor(nsIFrame* aFrame,
|
||||
const auto& color = aKind == ScrollbarColorKind::Thumb
|
||||
? colors.AsColors().thumb
|
||||
: colors.AsColors().track;
|
||||
- return Some(color.CalcColor(*scrollbarStyle));
|
||||
+ return Some(color.CalcColor(*scrollbarStyle, aFrame));
|
||||
}
|
||||
|
||||
static nscolor GetBackgroundColor(nsIFrame* aFrame,
|
||||
@@ -2367,7 +2368,8 @@ static nscolor GetBackgroundColor(nsIFrame* aFrame,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
- return aStyle->GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
|
||||
+ return aStyle->GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor,
|
||||
+ aFrame);
|
||||
}
|
||||
|
||||
nscolor nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext,
|
||||
14
src/layout/painting/nsCSSRenderingBorders-cpp.patch
Normal file
14
src/layout/painting/nsCSSRenderingBorders-cpp.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/layout/painting/nsCSSRenderingBorders.cpp b/layout/painting/nsCSSRenderingBorders.cpp
|
||||
index fd2524fd78b1709363afda35e4b0d4320913d9ec..c5b90bc789cdd7f8b0b661ca99b8c7f4d01e6d68 100644
|
||||
--- a/layout/painting/nsCSSRenderingBorders.cpp
|
||||
+++ b/layout/painting/nsCSSRenderingBorders.cpp
|
||||
@@ -3624,7 +3624,8 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands(
|
||||
case StyleImage::Tag::Gradient: {
|
||||
const StyleGradient& gradient = *mImageRenderer.GetGradientData();
|
||||
nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create(
|
||||
- aForFrame->PresContext(), aForFrame->Style(), gradient, mImageSize);
|
||||
+ aForFrame->PresContext(), aForFrame->Style(), aForFrame, gradient,
|
||||
+ mImageSize);
|
||||
|
||||
wr::ExtendMode extendMode;
|
||||
nsTArray<wr::GradientStop> stops;
|
||||
78
src/layout/painting/nsCSSRenderingGradients-cpp.patch
Normal file
78
src/layout/painting/nsCSSRenderingGradients-cpp.patch
Normal file
@@ -0,0 +1,78 @@
|
||||
diff --git a/layout/painting/nsCSSRenderingGradients.cpp b/layout/painting/nsCSSRenderingGradients.cpp
|
||||
index 80a9d36ca865bbcd090d7aa556270a698447b016..2b1e0a70ed7e6f975c51a0912598c7903552ab20 100644
|
||||
--- a/layout/painting/nsCSSRenderingGradients.cpp
|
||||
+++ b/layout/painting/nsCSSRenderingGradients.cpp
|
||||
@@ -667,7 +667,8 @@ static nsTArray<ColorStop> ComputeColorStops(ComputedStyle* aComputedStyle,
|
||||
|
||||
nsCSSGradientRenderer nsCSSGradientRenderer::Create(
|
||||
nsPresContext* aPresContext, ComputedStyle* aComputedStyle,
|
||||
- const StyleGradient& aGradient, const nsSize& aIntrinsicSize) {
|
||||
+ const nsIFrame* aFrame, const StyleGradient& aGradient,
|
||||
+ const nsSize& aIntrinsicSize) {
|
||||
auto srcSize = CSSSize::FromAppUnits(aIntrinsicSize);
|
||||
|
||||
// Compute "gradient line" start and end relative to the intrinsic size of
|
||||
@@ -704,6 +705,7 @@ nsCSSGradientRenderer nsCSSGradientRenderer::Create(
|
||||
|
||||
nsCSSGradientRenderer renderer;
|
||||
renderer.mPresContext = aPresContext;
|
||||
+ renderer.mFrame = aFrame;
|
||||
renderer.mGradient = &aGradient;
|
||||
renderer.mStops = std::move(stops);
|
||||
renderer.mLineStart = {
|
||||
@@ -992,9 +994,10 @@ void nsCSSGradientRenderer::Paint(gfxContext& aContext, const nsRect& aDest,
|
||||
GradientStopInterpolator(
|
||||
const nsTArray<ColorStop>& aStops,
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod,
|
||||
- bool aExtend, nsTArray<gfx::GradientStop>& aResult)
|
||||
+ bool aExtend, nsTArray<gfx::GradientStop>& aResult,
|
||||
+ const nsIFrame* aFrame)
|
||||
: ColorStopInterpolator(aStops, aStyleColorInterpolationMethod,
|
||||
- aExtend),
|
||||
+ aExtend, aFrame),
|
||||
mStops(aResult) {}
|
||||
void CreateStop(float aPosition, gfx::DeviceColor aColor) {
|
||||
mStops.AppendElement(gfx::GradientStop{aPosition, aColor});
|
||||
@@ -1007,12 +1010,12 @@ void nsCSSGradientRenderer::Paint(gfxContext& aContext, const nsRect& aDest,
|
||||
bool extend = !isRepeat && styleColorInterpolationMethod.hue ==
|
||||
StyleHueInterpolationMethod::Longer;
|
||||
GradientStopInterpolator interpolator(mStops, styleColorInterpolationMethod,
|
||||
- extend, rawStops);
|
||||
+ extend, rawStops, mFrame);
|
||||
interpolator.CreateStops();
|
||||
} else {
|
||||
rawStops.SetLength(mStops.Length());
|
||||
for (uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
- rawStops[i].color = ToDeviceColor(mStops[i].mColor);
|
||||
+ rawStops[i].color = ToDeviceColor(mStops[i].mColor, mFrame);
|
||||
rawStops[i].color.a *= aOpacity;
|
||||
rawStops[i].offset = stopScale * (mStops[i].mPosition - stopOrigin);
|
||||
}
|
||||
@@ -1203,8 +1206,10 @@ class MOZ_STACK_CLASS WrColorStopInterpolator
|
||||
WrColorStopInterpolator(
|
||||
const nsTArray<ColorStop>& aStops,
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod,
|
||||
- float aOpacity, nsTArray<wr::GradientStop>& aResult, bool aExtend)
|
||||
- : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod, aExtend),
|
||||
+ float aOpacity, nsTArray<wr::GradientStop>& aResult, bool aExtend,
|
||||
+ const nsIFrame* aFrame)
|
||||
+ : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod, aExtend,
|
||||
+ aFrame),
|
||||
mResult(aResult),
|
||||
mOpacity(aOpacity),
|
||||
mOutputStop(0) {}
|
||||
@@ -1284,12 +1289,12 @@ void nsCSSGradientRenderer::BuildWebRenderParameters(
|
||||
styleColorInterpolationMethod.hue ==
|
||||
StyleHueInterpolationMethod::Longer;
|
||||
WrColorStopInterpolator interpolator(mStops, styleColorInterpolationMethod,
|
||||
- aOpacity, aStops, extend);
|
||||
+ aOpacity, aStops, extend, mFrame);
|
||||
interpolator.CreateStops();
|
||||
} else {
|
||||
aStops.SetLength(mStops.Length());
|
||||
for (uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
- aStops[i].color = wr::ToColorF(ToDeviceColor(mStops[i].mColor));
|
||||
+ aStops[i].color = wr::ToColorF(ToDeviceColor(mStops[i].mColor, mFrame));
|
||||
aStops[i].color.a *= aOpacity;
|
||||
aStops[i].offset = (float)mStops[i].mPosition;
|
||||
}
|
||||
59
src/layout/painting/nsCSSRenderingGradients-h.patch
Normal file
59
src/layout/painting/nsCSSRenderingGradients-h.patch
Normal file
@@ -0,0 +1,59 @@
|
||||
diff --git a/layout/painting/nsCSSRenderingGradients.h b/layout/painting/nsCSSRenderingGradients.h
|
||||
index 30f665f7cacabb15fb6a1656385c5936d42be48b..8c4c4147ee8ec6812e9418f95b7b7c0358dcb735 100644
|
||||
--- a/layout/painting/nsCSSRenderingGradients.h
|
||||
+++ b/layout/painting/nsCSSRenderingGradients.h
|
||||
@@ -42,10 +42,11 @@ class MOZ_STACK_CLASS ColorStopInterpolator {
|
||||
ColorStopInterpolator(
|
||||
const nsTArray<ColorStop>& aStops,
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod,
|
||||
- bool aExtend)
|
||||
+ bool aExtend, const nsIFrame* aFrame)
|
||||
: mStyleColorInterpolationMethod(aStyleColorInterpolationMethod),
|
||||
mStops(aStops),
|
||||
- mExtend(aExtend) {}
|
||||
+ mExtend(aExtend),
|
||||
+ mFrame(aFrame) {}
|
||||
|
||||
void CreateStops() {
|
||||
// This loop intentionally iterates extra stops at the beginning and end
|
||||
@@ -96,7 +97,7 @@ class MOZ_STACK_CLASS ColorStopInterpolator {
|
||||
Servo_InterpolateColor(mStyleColorInterpolationMethod,
|
||||
&start.mColor, &end.mColor, progress);
|
||||
static_cast<T*>(this)->CreateStop(float(position),
|
||||
- gfx::ToDeviceColor(color));
|
||||
+ gfx::ToDeviceColor(color, mFrame));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,6 +109,7 @@ class MOZ_STACK_CLASS ColorStopInterpolator {
|
||||
// which only matters if this is a CSS non-repeating gradient with
|
||||
// StyleHueInterpolationMethod::Longer (only valid for hsl/hwb/lch/oklch).
|
||||
bool mExtend;
|
||||
+ const nsIFrame* mFrame;
|
||||
|
||||
// This could be made tunable, but at 1.0/128 the error is largely
|
||||
// irrelevant, as WebRender re-encodes it to 128 pairs of stops.
|
||||
@@ -126,6 +128,7 @@ class nsCSSGradientRenderer final {
|
||||
*/
|
||||
static nsCSSGradientRenderer Create(nsPresContext* aPresContext,
|
||||
ComputedStyle* aComputedStyle,
|
||||
+ const nsIFrame* aFrame,
|
||||
const StyleGradient& aGradient,
|
||||
const nsSize& aIntrinsiceSize);
|
||||
|
||||
@@ -173,6 +176,7 @@ class nsCSSGradientRenderer final {
|
||||
private:
|
||||
nsCSSGradientRenderer()
|
||||
: mPresContext(nullptr),
|
||||
+ mFrame(nullptr),
|
||||
mGradient(nullptr),
|
||||
mRadiusX(0.0),
|
||||
mRadiusY(0.0),
|
||||
@@ -192,6 +196,7 @@ class nsCSSGradientRenderer final {
|
||||
const nsSize& aRepeatSize, bool aForceRepeatToCoverTiles);
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
+ const nsIFrame* mFrame;
|
||||
const StyleGradient* mGradient;
|
||||
nsTArray<ColorStop> mStops;
|
||||
gfxPoint mLineStart, mLineEnd; // only for linear/radial gradients
|
||||
@@ -1,23 +0,0 @@
|
||||
diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp
|
||||
index 4488dc2025da64fbad0e0ec998793a476de640ef..82990853e7279723666635ab8d9a929ede3f3aca 100644
|
||||
--- a/layout/painting/nsDisplayList.cpp
|
||||
+++ b/layout/painting/nsDisplayList.cpp
|
||||
@@ -81,6 +81,7 @@
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layers/WebRenderMessages.h"
|
||||
#include "mozilla/layers/WebRenderScrollData.h"
|
||||
+#include "mozilla/nsZenBoostsBackend.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsCSSRenderingGradients.h"
|
||||
@@ -1252,6 +1253,10 @@ void nsDisplayListBuilder::EnterPresShell(const nsIFrame* aReferenceFrame,
|
||||
docShell->GetWindowDraggingAllowed(&mWindowDraggingAllowed);
|
||||
}
|
||||
|
||||
+ if (auto zenBackend = zen::nsZenBoostsBackend::GetInstance(); zenBackend && !mIsInChromePresContext) {
|
||||
+ zenBackend->onPresShellEntered(pc->Document());
|
||||
+ }
|
||||
+
|
||||
state->mTouchEventPrefEnabledDoc = dom::TouchEvent::PrefEnabled(docShell);
|
||||
|
||||
if (auto* vt = pc->Document()->GetActiveViewTransition()) {
|
||||
49
src/layout/painting/nsImageRenderer-cpp.patch
Normal file
49
src/layout/painting/nsImageRenderer-cpp.patch
Normal file
@@ -0,0 +1,49 @@
|
||||
diff --git a/layout/painting/nsImageRenderer.cpp b/layout/painting/nsImageRenderer.cpp
|
||||
index 4acb7670e971024f9c63e48ff711bbdd1dc02301..518543f29f396d819a71edb984879de22f8434a8 100644
|
||||
--- a/layout/painting/nsImageRenderer.cpp
|
||||
+++ b/layout/painting/nsImageRenderer.cpp
|
||||
@@ -90,7 +90,7 @@ static already_AddRefed<imgIContainer> GetSymbolicIconImage(nsAtom* aName,
|
||||
if (NS_WARN_IF(!XRE_IsParentProcess())) {
|
||||
return nullptr;
|
||||
}
|
||||
- const auto fg = aFrame->StyleText()->mColor.ToColor();
|
||||
+ const auto fg = aFrame->StyleText()->mColor.ToColor(aFrame);
|
||||
auto key = std::make_tuple(aName, aScale, fg);
|
||||
auto* cache = aFrame->GetProperty(SymbolicImageCacheProp());
|
||||
if (!cache) {
|
||||
@@ -567,7 +567,7 @@ ImgDrawResult nsImageRenderer::Draw(nsPresContext* aPresContext,
|
||||
}
|
||||
case StyleImage::Tag::Gradient: {
|
||||
nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create(
|
||||
- aPresContext, mForFrame->Style(), *mGradientData, mSize);
|
||||
+ aPresContext, mForFrame->Style(), mForFrame, *mGradientData, mSize);
|
||||
|
||||
renderer.Paint(*ctx, aDest, aFill, aRepeatSize, aSrc, aDirtyRect,
|
||||
aOpacity);
|
||||
@@ -644,7 +644,7 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
|
||||
switch (mType) {
|
||||
case StyleImage::Tag::Gradient: {
|
||||
nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create(
|
||||
- aPresContext, mForFrame->Style(), *mGradientData, mSize);
|
||||
+ aPresContext, mForFrame->Style(), mForFrame, *mGradientData, mSize);
|
||||
|
||||
renderer.BuildWebRenderDisplayItems(aBuilder, aSc, aDest, aFill,
|
||||
aRepeatSize, aSrc,
|
||||
@@ -670,6 +670,8 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
|
||||
nsPresContext::AppUnitsToIntCSSPixels(aDest.height)};
|
||||
|
||||
SVGImageContext svgContext(Some(destCSSSize));
|
||||
+ SVGImageContext::MaybeStoreZenBoosts(svgContext,
|
||||
+ *mForFrame->PresContext());
|
||||
Maybe<ImageIntRegion> region;
|
||||
|
||||
const int32_t appUnitsPerDevPixel =
|
||||
@@ -1076,7 +1078,7 @@ ImgDrawResult nsImageRenderer::DrawShapeImage(nsPresContext* aPresContext,
|
||||
|
||||
if (mImage->IsGradient()) {
|
||||
nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create(
|
||||
- aPresContext, mForFrame->Style(), *mGradientData, mSize);
|
||||
+ aPresContext, mForFrame->Style(), mForFrame, *mGradientData, mSize);
|
||||
nsRect dest(nsPoint(0, 0), mSize);
|
||||
renderer.Paint(aRenderingContext, dest, dest, mSize,
|
||||
CSSIntRect::FromAppUnitsRounded(dest), dest, 1.0);
|
||||
65
src/layout/style/ComputedStyle-cpp.patch
Normal file
65
src/layout/style/ComputedStyle-cpp.patch
Normal file
@@ -0,0 +1,65 @@
|
||||
diff --git a/layout/style/ComputedStyle.cpp b/layout/style/ComputedStyle.cpp
|
||||
index 18308d7891aab4ff0542e774190abeed6aad7c59..453da8ffa14ee5f31fbce873721779cbadce240d 100644
|
||||
--- a/layout/style/ComputedStyle.cpp
|
||||
+++ b/layout/style/ComputedStyle.cpp
|
||||
@@ -285,29 +285,32 @@ static nscolor GetVisitedDependentColorInternal(const ComputedStyle& aStyle,
|
||||
}
|
||||
|
||||
static nscolor ExtractColor(const ComputedStyle& aStyle,
|
||||
- const StyleAbsoluteColor& aColor) {
|
||||
- return aColor.ToColor();
|
||||
+ const StyleAbsoluteColor& aColor,
|
||||
+ const nsIFrame* aFrame) {
|
||||
+ return aColor.ToColor(aFrame);
|
||||
}
|
||||
|
||||
static nscolor ExtractColor(const ComputedStyle& aStyle,
|
||||
- const StyleColor& aColor) {
|
||||
- return aColor.CalcColor(aStyle);
|
||||
+ const StyleColor& aColor, const nsIFrame* aFrame) {
|
||||
+ return aColor.CalcColor(aStyle, aFrame);
|
||||
}
|
||||
|
||||
// Currently caret-color, the only property in the list which is a ColorOrAuto,
|
||||
// always maps auto to currentcolor.
|
||||
static nscolor ExtractColor(const ComputedStyle& aStyle,
|
||||
- const StyleColorOrAuto& aColor) {
|
||||
+ const StyleColorOrAuto& aColor,
|
||||
+ const nsIFrame* aFrame) {
|
||||
if (aColor.IsAuto()) {
|
||||
- return ExtractColor(aStyle, StyleColor::CurrentColor());
|
||||
+ return ExtractColor(aStyle, StyleColor::CurrentColor(), aFrame);
|
||||
}
|
||||
- return ExtractColor(aStyle, aColor.AsColor());
|
||||
+ return ExtractColor(aStyle, aColor.AsColor(), aFrame);
|
||||
}
|
||||
|
||||
static nscolor ExtractColor(const ComputedStyle& aStyle,
|
||||
- const StyleSVGPaint& aPaintServer) {
|
||||
+ const StyleSVGPaint& aPaintServer,
|
||||
+ const nsIFrame* aFrame) {
|
||||
return aPaintServer.kind.IsColor()
|
||||
- ? ExtractColor(aStyle, aPaintServer.kind.AsColor())
|
||||
+ ? ExtractColor(aStyle, aPaintServer.kind.AsColor(), aFrame)
|
||||
: NS_RGBA(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@@ -315,14 +318,14 @@ static nscolor ExtractColor(const ComputedStyle& aStyle,
|
||||
#define GENERATE_VISITED_COLOR_TEMPLATE(name_, fields_) \
|
||||
template <> \
|
||||
nscolor ComputedStyle::GetVisitedDependentColor( \
|
||||
- decltype(nsStyle##name_::MOZ_ARG_1 fields_) nsStyle##name_::* aField) \
|
||||
- const { \
|
||||
+ decltype(nsStyle##name_::MOZ_ARG_1 fields_) nsStyle##name_::* aField, \
|
||||
+ const nsIFrame* aFrame) const { \
|
||||
MOZ_ASSERT(MOZ_FOR_EACH(STYLE_FIELD, (nsStyle##name_, ), fields_) false, \
|
||||
"Getting visited-dependent color for a field in nsStyle" #name_ \
|
||||
" which is not listed in nsCSSVisitedDependentPropList.h"); \
|
||||
return GetVisitedDependentColorInternal( \
|
||||
- *this, [aField](const ComputedStyle& aStyle) { \
|
||||
- return ExtractColor(aStyle, aStyle.Style##name_()->*aField); \
|
||||
+ *this, [aField, aFrame](const ComputedStyle& aStyle) { \
|
||||
+ return ExtractColor(aStyle, aStyle.Style##name_()->*aField, aFrame); \
|
||||
}); \
|
||||
}
|
||||
FOR_EACH_VISITED_DEPENDENT_STYLE_STRUCT(GENERATE_VISITED_COLOR_TEMPLATE)
|
||||
22
src/layout/style/ComputedStyle-h.patch
Normal file
22
src/layout/style/ComputedStyle-h.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
diff --git a/layout/style/ComputedStyle.h b/layout/style/ComputedStyle.h
|
||||
index 661ec439dea1bc59dbc4507c9788df8821ea9086..7aa21f5388d6e3b5f1a85e38acdd646254ca8b01 100644
|
||||
--- a/layout/style/ComputedStyle.h
|
||||
+++ b/layout/style/ComputedStyle.h
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
enum nsChangeHint : uint32_t;
|
||||
class nsWindowSizes;
|
||||
+class nsIFrame;
|
||||
|
||||
#define FORWARD_STRUCT(name_) struct nsStyle##name_;
|
||||
FOR_EACH_STYLE_STRUCT(FORWARD_STRUCT, FORWARD_STRUCT)
|
||||
@@ -338,7 +339,8 @@ class ComputedStyle {
|
||||
* been listed in nsCSSVisitedDependentPropList.h.
|
||||
*/
|
||||
template <typename T, typename S>
|
||||
- nscolor GetVisitedDependentColor(T S::* aField) const;
|
||||
+ nscolor GetVisitedDependentColor(T S::* aField,
|
||||
+ const nsIFrame* aFrame) const;
|
||||
|
||||
/**
|
||||
* aColors should be a two element array of nscolor in which the first
|
||||
13
src/layout/style/GeckoBindings-cpp.patch
Normal file
13
src/layout/style/GeckoBindings-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/style/GeckoBindings.cpp b/layout/style/GeckoBindings.cpp
|
||||
index 56a16d313a5d30d12edf1f94459db1027af87002..3722f2d6ce6c0864956fed2b00c71a3286edc674 100644
|
||||
--- a/layout/style/GeckoBindings.cpp
|
||||
+++ b/layout/style/GeckoBindings.cpp
|
||||
@@ -1068,7 +1068,7 @@ void Gecko_SetFontPaletteOverride(
|
||||
return;
|
||||
}
|
||||
aValues->mOverrides.AppendElement(gfx::FontPaletteValueSet::OverrideColor{
|
||||
- uint32_t(aIndex), gfx::sRGBColor::FromABGR(aColor->ToColor())});
|
||||
+ uint32_t(aIndex), gfx::sRGBColor::FromABGR(aColor->ToColor(nullptr))});
|
||||
}
|
||||
|
||||
void Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/layout/style/StyleColor.cpp b/layout/style/StyleColor.cpp
|
||||
index 95c7ae6abea5032bef0466e8d59d212374d7a4d0..8dbfbb846b786d51af288989163aacfae12e787c 100644
|
||||
index 95c7ae6abea5032bef0466e8d59d212374d7a4d0..85a48f27251756c72db8ed03a673a18e96cf76f9 100644
|
||||
--- a/layout/style/StyleColor.cpp
|
||||
+++ b/layout/style/StyleColor.cpp
|
||||
@@ -8,6 +8,7 @@
|
||||
@@ -10,25 +10,46 @@ index 95c7ae6abea5032bef0466e8d59d212374d7a4d0..8dbfbb846b786d51af288989163aacfa
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -21,6 +22,8 @@ bool StyleColor::MaybeTransparent() const {
|
||||
template <>
|
||||
StyleAbsoluteColor StyleColor::ResolveColor(
|
||||
const StyleAbsoluteColor& aForegroundColor) const {
|
||||
+ auto ResolveColorInner = [this,
|
||||
+ &aForegroundColor]() -> StyleAbsoluteColor {
|
||||
if (IsAbsolute()) {
|
||||
return AsAbsolute();
|
||||
}
|
||||
@@ -30,6 +33,8 @@ StyleAbsoluteColor StyleColor::ResolveColor(
|
||||
}
|
||||
@@ -34,23 +35,24 @@ StyleAbsoluteColor StyleColor::ResolveColor(
|
||||
|
||||
return Servo_ResolveColor(this, &aForegroundColor);
|
||||
+ };
|
||||
+ return zen::nsZenBoostsBackend::ResolveStyleColor(ResolveColorInner());
|
||||
template <>
|
||||
nscolor StyleColor::CalcColor(nscolor aColor) const {
|
||||
- return ResolveColor(StyleAbsoluteColor::FromColor(aColor)).ToColor();
|
||||
+ return ResolveColor(StyleAbsoluteColor::FromColor(aColor)).ToColor(nullptr);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -68,10 +73,11 @@ nscolor StyleAbsoluteColor::ToColor() const {
|
||||
nscolor StyleColor::CalcColor(
|
||||
const StyleAbsoluteColor& aForegroundColor) const {
|
||||
- return ResolveColor(aForegroundColor).ToColor();
|
||||
+ return ResolveColor(aForegroundColor).ToColor(nullptr);
|
||||
}
|
||||
|
||||
template <>
|
||||
-nscolor StyleColor::CalcColor(const ComputedStyle& aStyle) const {
|
||||
- return ResolveColor(aStyle.StyleText()->mColor).ToColor();
|
||||
+nscolor StyleColor::CalcColor(const ComputedStyle& aStyle,
|
||||
+ const nsIFrame* aFrame) const {
|
||||
+ return ResolveColor(aStyle.StyleText()->mColor).ToColor(aFrame);
|
||||
}
|
||||
|
||||
template <>
|
||||
nscolor StyleColor::CalcColor(const nsIFrame* aFrame) const {
|
||||
- return ResolveColor(aFrame->StyleText()->mColor).ToColor();
|
||||
+ return ResolveColor(aFrame->StyleText()->mColor).ToColor(aFrame);
|
||||
}
|
||||
|
||||
StyleAbsoluteColor StyleAbsoluteColor::ToColorSpace(
|
||||
@@ -58,7 +60,7 @@ StyleAbsoluteColor StyleAbsoluteColor::ToColorSpace(
|
||||
return Servo_ConvertColorSpace(this, aColorSpace);
|
||||
}
|
||||
|
||||
-nscolor StyleAbsoluteColor::ToColor() const {
|
||||
+nscolor StyleAbsoluteColor::ToColor(const nsIFrame* aFrame) const {
|
||||
auto srgb = ToColorSpace(StyleColorSpace::Srgb);
|
||||
|
||||
// TODO(tlouw): Needs gamut mapping here. Right now we just hard clip the
|
||||
@@ -68,10 +70,12 @@ nscolor StyleAbsoluteColor::ToColor() const {
|
||||
auto green = std::clamp(srgb.components._1, 0.0f, 1.0f);
|
||||
auto blue = std::clamp(srgb.components._2, 0.0f, 1.0f);
|
||||
|
||||
@@ -38,7 +59,8 @@ index 95c7ae6abea5032bef0466e8d59d212374d7a4d0..8dbfbb846b786d51af288989163aacfa
|
||||
nsStyleUtil::FloatToColorComponent(green),
|
||||
nsStyleUtil::FloatToColorComponent(blue),
|
||||
- nsStyleUtil::FloatToColorComponent(srgb.alpha));
|
||||
+ nsStyleUtil::FloatToColorComponent(srgb.alpha)));
|
||||
+ nsStyleUtil::FloatToColorComponent(srgb.alpha)),
|
||||
+ aFrame);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
13
src/layout/style/StyleColorInlines-h.patch
Normal file
13
src/layout/style/StyleColorInlines-h.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/style/StyleColorInlines.h b/layout/style/StyleColorInlines.h
|
||||
index 332f715ca2a11c98afcb80a870da98c038a7e4f0..a5bddde67165fcb40d40b3aec76a9d19d8880d64 100644
|
||||
--- a/layout/style/StyleColorInlines.h
|
||||
+++ b/layout/style/StyleColorInlines.h
|
||||
@@ -66,7 +66,7 @@ template <>
|
||||
nscolor StyleColor::CalcColor(nscolor) const;
|
||||
|
||||
template <>
|
||||
-nscolor StyleColor::CalcColor(const ComputedStyle&) const;
|
||||
+nscolor StyleColor::CalcColor(const ComputedStyle&, const nsIFrame*) const;
|
||||
|
||||
template <>
|
||||
nscolor StyleColor::CalcColor(const nsIFrame*) const;
|
||||
13
src/layout/style/nsStyleStruct-cpp.patch
Normal file
13
src/layout/style/nsStyleStruct-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
|
||||
index 80ca0cc08bc675359fbb09100eca43c8e3b9d413..d3ea525f6d84568c4e997a142bbfef6435d21034 100644
|
||||
--- a/layout/style/nsStyleStruct.cpp
|
||||
+++ b/layout/style/nsStyleStruct.cpp
|
||||
@@ -2208,7 +2208,7 @@ nscolor nsStyleBackground::BackgroundColor(const nsIFrame* aFrame) const {
|
||||
}
|
||||
|
||||
nscolor nsStyleBackground::BackgroundColor(const ComputedStyle* aStyle) const {
|
||||
- return mBackgroundColor.CalcColor(*aStyle);
|
||||
+ return mBackgroundColor.CalcColor(*aStyle, nullptr);
|
||||
}
|
||||
|
||||
bool nsStyleBackground::IsTransparent(const nsIFrame* aFrame) const {
|
||||
13
src/layout/svg/FilterInstance-cpp.patch
Normal file
13
src/layout/svg/FilterInstance-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/svg/FilterInstance.cpp b/layout/svg/FilterInstance.cpp
|
||||
index 499f824aaeed6ac014974ff11848cf40ac0bba09..bec724baf0ae97cd9dea59a1609d8ea9baaad715 100644
|
||||
--- a/layout/svg/FilterInstance.cpp
|
||||
+++ b/layout/svg/FilterInstance.cpp
|
||||
@@ -1681,7 +1681,7 @@ nsresult FilterInstance::BuildPrimitivesForFilter(
|
||||
// If we don't have a frame, use opaque black for shadows with unspecified
|
||||
// shadow colors.
|
||||
nscolor shadowFallbackColor =
|
||||
- mTargetFrame ? mTargetFrame->StyleText()->mColor.ToColor()
|
||||
+ mTargetFrame ? mTargetFrame->StyleText()->mColor.ToColor(mTargetFrame)
|
||||
: NS_RGB(0, 0, 0);
|
||||
|
||||
CSSFilterInstance cssFilterInstance(aFilter, shadowFallbackColor,
|
||||
13
src/layout/svg/SVGContextPaint-cpp.patch
Normal file
13
src/layout/svg/SVGContextPaint-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/svg/SVGContextPaint.cpp b/layout/svg/SVGContextPaint.cpp
|
||||
index 3df8728978c1b48ca326c852feb0553091a99673..9f9096205c3dd3551c41c547a1aee667c0a51238 100644
|
||||
--- a/layout/svg/SVGContextPaint.cpp
|
||||
+++ b/layout/svg/SVGContextPaint.cpp
|
||||
@@ -143,7 +143,7 @@ static void SetupInheritablePaint(const DrawTarget* aDrawTarget,
|
||||
}
|
||||
|
||||
nscolor color = SVGUtils::GetFallbackOrPaintColor(
|
||||
- *aFrame->Style(), aFillOrStroke, aDefaultFallbackColor);
|
||||
+ *aFrame->Style(), aFillOrStroke, aDefaultFallbackColor, aFrame);
|
||||
aTargetPaint.SetColor(color);
|
||||
}
|
||||
|
||||
42
src/layout/svg/SVGGradientFrame-cpp.patch
Normal file
42
src/layout/svg/SVGGradientFrame-cpp.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
diff --git a/layout/svg/SVGGradientFrame.cpp b/layout/svg/SVGGradientFrame.cpp
|
||||
index 9c66d90fc0292abcab30c912968d3f84c0e181ff..aec0b2e48965729ccff19d632ac5e8fd04fd09eb 100644
|
||||
--- a/layout/svg/SVGGradientFrame.cpp
|
||||
+++ b/layout/svg/SVGGradientFrame.cpp
|
||||
@@ -229,8 +229,9 @@ class MOZ_STACK_CLASS SVGColorStopInterpolator
|
||||
SVGColorStopInterpolator(
|
||||
gfxPattern* aGradient, const nsTArray<ColorStop>& aStops,
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod,
|
||||
- bool aExtend)
|
||||
- : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod, aExtend),
|
||||
+ bool aExtend, const nsIFrame* aFrame)
|
||||
+ : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod, aExtend,
|
||||
+ aFrame),
|
||||
mGradient(aGradient) {}
|
||||
|
||||
void CreateStop(float aPosition, DeviceColor aColor) {
|
||||
@@ -270,7 +271,8 @@ already_AddRefed<gfxPattern> SVGGradientFrame::GetPaintServerPattern(
|
||||
if (nStops == 1 || GradientVectorLengthIsZero()) {
|
||||
// The gradient paints a single colour, using the stop-color of the last
|
||||
// gradient step if there are more than one.
|
||||
- return do_AddRef(new gfxPattern(ToDeviceColor(stops.LastElement().mColor)));
|
||||
+ return do_AddRef(
|
||||
+ new gfxPattern(ToDeviceColor(stops.LastElement().mColor, aSource)));
|
||||
}
|
||||
|
||||
// Get the transform list (if there is one). We do this after the returns
|
||||
@@ -313,12 +315,13 @@ already_AddRefed<gfxPattern> SVGGradientFrame::GetPaintServerPattern(
|
||||
static constexpr auto interpolationMethod = StyleColorInterpolationMethod{
|
||||
StyleColorSpace::SrgbLinear, StyleHueInterpolationMethod::Shorter};
|
||||
SVGColorStopInterpolator interpolator(gradient, stops, interpolationMethod,
|
||||
- false);
|
||||
+ false, aSource);
|
||||
interpolator.CreateStops();
|
||||
} else {
|
||||
// setup standard sRGB stops
|
||||
for (const auto& stop : stops) {
|
||||
- gradient->AddColorStop(stop.mPosition, ToDeviceColor(stop.mColor));
|
||||
+ gradient->AddColorStop(stop.mPosition,
|
||||
+ ToDeviceColor(stop.mColor, aSource));
|
||||
}
|
||||
}
|
||||
|
||||
58
src/layout/svg/SVGImageContext-cpp.patch
Normal file
58
src/layout/svg/SVGImageContext-cpp.patch
Normal file
@@ -0,0 +1,58 @@
|
||||
diff --git a/layout/svg/SVGImageContext.cpp b/layout/svg/SVGImageContext.cpp
|
||||
index ecbda963b75fb70b62885a0c8f7a517011a8d5dc..5f55f0a4174db830656d434b5295835ab18e6619 100644
|
||||
--- a/layout/svg/SVGImageContext.cpp
|
||||
+++ b/layout/svg/SVGImageContext.cpp
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/ServoCSSParser.h"
|
||||
#include "mozilla/StaticPrefs_svg.h"
|
||||
+#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsISVGPaintContext.h"
|
||||
@@ -18,6 +19,19 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
+/* static */
|
||||
+void SVGImageContext::MaybeStoreZenBoosts(SVGImageContext& aContext,
|
||||
+ const nsPresContext& aPresContext) {
|
||||
+ if (dom::Document* doc = aPresContext.Document()) {
|
||||
+ if (dom::BrowsingContext* bc = doc->GetBrowsingContext()) {
|
||||
+ bc = bc->Top();
|
||||
+ aContext.SetZenBoosts(bc->ZenBoostsData(),
|
||||
+ bc->ZenBoostsComplementaryRotation(),
|
||||
+ bc->IsZenBoostsInverted());
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* static */
|
||||
void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext,
|
||||
nsIFrame* aFromFrame,
|
||||
@@ -43,6 +57,8 @@ void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext,
|
||||
aContext.SetColorScheme(Some(scheme));
|
||||
}
|
||||
|
||||
+ MaybeStoreZenBoosts(aContext, aPresContext);
|
||||
+
|
||||
const nsStyleSVG* style = aStyle.StyleSVG();
|
||||
if (!style->ExposesContextProperties()) {
|
||||
// Content must have '-moz-context-properties' set to the names of the
|
||||
@@ -57,12 +73,14 @@ void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext,
|
||||
if ((style->mMozContextProperties.bits & StyleContextPropertyBits::FILL) &&
|
||||
style->mFill.kind.IsColor()) {
|
||||
haveContextPaint = true;
|
||||
- contextPaint->SetFill(style->mFill.kind.AsColor().CalcColor(aStyle));
|
||||
+ contextPaint->SetFill(
|
||||
+ style->mFill.kind.AsColor().CalcColor(aStyle, nullptr));
|
||||
}
|
||||
if ((style->mMozContextProperties.bits & StyleContextPropertyBits::STROKE) &&
|
||||
style->mStroke.kind.IsColor()) {
|
||||
haveContextPaint = true;
|
||||
- contextPaint->SetStroke(style->mStroke.kind.AsColor().CalcColor(aStyle));
|
||||
+ contextPaint->SetStroke(
|
||||
+ style->mStroke.kind.AsColor().CalcColor(aStyle, nullptr));
|
||||
}
|
||||
if (style->mMozContextProperties.bits &
|
||||
StyleContextPropertyBits::FILL_OPACITY) {
|
||||
80
src/layout/svg/SVGImageContext-h.patch
Normal file
80
src/layout/svg/SVGImageContext-h.patch
Normal file
@@ -0,0 +1,80 @@
|
||||
diff --git a/layout/svg/SVGImageContext.h b/layout/svg/SVGImageContext.h
|
||||
index 159d9cbbd0711076ee6c2a71a3da04bd92a0102c..daefc40590c4d7d7fac9db25c6ec4ba2424dded5 100644
|
||||
--- a/layout/svg/SVGImageContext.h
|
||||
+++ b/layout/svg/SVGImageContext.h
|
||||
@@ -6,6 +6,7 @@
|
||||
#define LAYOUT_SVG_SVGIMAGECONTEXT_H_
|
||||
|
||||
#include "Units.h"
|
||||
+#include "nsColor.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/SVGContextPaint.h"
|
||||
#include "mozilla/SVGPreserveAspectRatio.h"
|
||||
@@ -63,6 +64,11 @@ class SVGImageContext {
|
||||
nsISVGPaintContext* aPaintContext,
|
||||
imgIContainer* aImgContainer);
|
||||
|
||||
+ // Carry the host document's Zen boost into the image context so the image
|
||||
+ // renders with the same accent/inversion as the page.
|
||||
+ static void MaybeStoreZenBoosts(SVGImageContext& aContext,
|
||||
+ const nsPresContext& aPresContext);
|
||||
+
|
||||
const Maybe<CSSIntSize>& GetViewportSize() const { return mViewportSize; }
|
||||
|
||||
void SetViewportSize(const Maybe<CSSIntSize>& aSize) {
|
||||
@@ -75,6 +81,21 @@ class SVGImageContext {
|
||||
mColorScheme = aScheme;
|
||||
}
|
||||
|
||||
+ // Zen boosts state carried from the host document so the image renders with
|
||||
+ // the same boost. Part of the cache key below so boosted and unboosted
|
||||
+ // renderings don't collide.
|
||||
+ void SetZenBoosts(nscolor aAccent, float aComplementaryRotation,
|
||||
+ bool aInverted) {
|
||||
+ mZenBoostsAccent = aAccent;
|
||||
+ mZenBoostsComplementaryRotation = aComplementaryRotation;
|
||||
+ mZenBoostsInverted = aInverted;
|
||||
+ }
|
||||
+ nscolor GetZenBoostsAccent() const { return mZenBoostsAccent; }
|
||||
+ float GetZenBoostsComplementaryRotation() const {
|
||||
+ return mZenBoostsComplementaryRotation;
|
||||
+ }
|
||||
+ bool GetZenBoostsInverted() const { return mZenBoostsInverted; }
|
||||
+
|
||||
const Maybe<SVGPreserveAspectRatio>& GetPreserveAspectRatio() const {
|
||||
return mPreserveAspectRatio;
|
||||
}
|
||||
@@ -107,7 +128,11 @@ class SVGImageContext {
|
||||
|
||||
return contextPaintIsEqual && mViewportSize == aOther.mViewportSize &&
|
||||
mPreserveAspectRatio == aOther.mPreserveAspectRatio &&
|
||||
- mColorScheme == aOther.mColorScheme;
|
||||
+ mColorScheme == aOther.mColorScheme &&
|
||||
+ mZenBoostsAccent == aOther.mZenBoostsAccent &&
|
||||
+ mZenBoostsComplementaryRotation ==
|
||||
+ aOther.mZenBoostsComplementaryRotation &&
|
||||
+ mZenBoostsInverted == aOther.mZenBoostsInverted;
|
||||
}
|
||||
|
||||
bool operator!=(const SVGImageContext&) const = default;
|
||||
@@ -119,7 +144,9 @@ class SVGImageContext {
|
||||
}
|
||||
return HashGeneric(hash, mViewportSize.map(HashSize).valueOr(0),
|
||||
mPreserveAspectRatio.map(HashPAR).valueOr(0),
|
||||
- mColorScheme.map(HashColorScheme).valueOr(0));
|
||||
+ mColorScheme.map(HashColorScheme).valueOr(0),
|
||||
+ mZenBoostsAccent, mZenBoostsComplementaryRotation,
|
||||
+ mZenBoostsInverted);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -138,6 +165,9 @@ class SVGImageContext {
|
||||
Maybe<CSSIntSize> mViewportSize;
|
||||
Maybe<SVGPreserveAspectRatio> mPreserveAspectRatio;
|
||||
Maybe<ColorScheme> mColorScheme;
|
||||
+ nscolor mZenBoostsAccent = 0;
|
||||
+ float mZenBoostsComplementaryRotation = 0.0f;
|
||||
+ bool mZenBoostsInverted = false;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
28
src/layout/svg/SVGTextFrame-cpp.patch
Normal file
28
src/layout/svg/SVGTextFrame-cpp.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp
|
||||
index 93f6f2a704734314586fa16b6a45b434f9c2304d..4503ee2b48be39bb2e61962316ef43ad292a7b27 100644
|
||||
--- a/layout/svg/SVGTextFrame.cpp
|
||||
+++ b/layout/svg/SVGTextFrame.cpp
|
||||
@@ -2662,9 +2662,9 @@ void SVGTextDrawPathCallbacks::ApplyOpacity(
|
||||
sRGBColor& aColor, const StyleSVGPaint& aPaint,
|
||||
const StyleSVGOpacity& aOpacity) const {
|
||||
if (aPaint.kind.tag == StyleSVGPaintKind::Tag::Color) {
|
||||
- aColor.a *=
|
||||
- sRGBColor::FromABGR(aPaint.kind.AsColor().CalcColor(*mFrame->Style()))
|
||||
- .a;
|
||||
+ aColor.a *= sRGBColor::FromABGR(
|
||||
+ aPaint.kind.AsColor().CalcColor(*mFrame->Style(), mFrame))
|
||||
+ .a;
|
||||
}
|
||||
aColor.a *= SVGUtils::GetOpacity(aOpacity, mContextPaint);
|
||||
}
|
||||
@@ -5076,8 +5076,8 @@ bool SVGTextFrame::ShouldRenderAsPath(nsTextFrame* aFrame,
|
||||
// It's possible nsTextFrame will support non-opaque shadows in the future,
|
||||
// in which case this test can be removed.
|
||||
if (style->mFill.kind.IsColor() && aFrame->StyleText()->HasTextShadow() &&
|
||||
- NS_GET_A(style->mFill.kind.AsColor().CalcColor(*aFrame->Style())) !=
|
||||
- 0xFF) {
|
||||
+ NS_GET_A(style->mFill.kind.AsColor().CalcColor(*aFrame->Style(),
|
||||
+ aFrame)) != 0xFF) {
|
||||
return true;
|
||||
}
|
||||
|
||||
60
src/layout/svg/SVGUtils-cpp.patch
Normal file
60
src/layout/svg/SVGUtils-cpp.patch
Normal file
@@ -0,0 +1,60 @@
|
||||
diff --git a/layout/svg/SVGUtils.cpp b/layout/svg/SVGUtils.cpp
|
||||
index 93b73e1c665ea8e011af7026810db6cd23c8049b..004d1d0637d62fcde25a924df5392a7dc64f75dc 100644
|
||||
--- a/layout/svg/SVGUtils.cpp
|
||||
+++ b/layout/svg/SVGUtils.cpp
|
||||
@@ -1154,23 +1154,23 @@ gfxRect SVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
||||
/* static */
|
||||
nscolor SVGUtils::GetFallbackOrPaintColor(
|
||||
const ComputedStyle& aStyle, StyleSVGPaint nsStyleSVG::* aFillOrStroke,
|
||||
- nscolor aDefaultContextFallbackColor) {
|
||||
+ nscolor aDefaultContextFallbackColor, const nsIFrame* aFrame) {
|
||||
const auto& paint = aStyle.StyleSVG()->*aFillOrStroke;
|
||||
nscolor color;
|
||||
switch (paint.kind.tag) {
|
||||
case StyleSVGPaintKind::Tag::PaintServer:
|
||||
color = paint.fallback.IsColor()
|
||||
- ? paint.fallback.AsColor().CalcColor(aStyle)
|
||||
+ ? paint.fallback.AsColor().CalcColor(aStyle, aFrame)
|
||||
: NS_RGBA(0, 0, 0, 0);
|
||||
break;
|
||||
case StyleSVGPaintKind::Tag::ContextStroke:
|
||||
case StyleSVGPaintKind::Tag::ContextFill:
|
||||
color = paint.fallback.IsColor()
|
||||
- ? paint.fallback.AsColor().CalcColor(aStyle)
|
||||
+ ? paint.fallback.AsColor().CalcColor(aStyle, aFrame)
|
||||
: aDefaultContextFallbackColor;
|
||||
break;
|
||||
default:
|
||||
- color = paint.kind.AsColor().CalcColor(aStyle);
|
||||
+ color = paint.kind.AsColor().CalcColor(aStyle, aFrame);
|
||||
break;
|
||||
}
|
||||
if (const auto* styleIfVisited = aStyle.GetStyleIfVisited()) {
|
||||
@@ -1184,7 +1184,8 @@ nscolor SVGUtils::GetFallbackOrPaintColor(
|
||||
// another simple color.
|
||||
if (paintIfVisited.kind.IsColor() && paint.kind.IsColor()) {
|
||||
nscolor colors[2] = {
|
||||
- color, paintIfVisited.kind.AsColor().CalcColor(*styleIfVisited)};
|
||||
+ color,
|
||||
+ paintIfVisited.kind.AsColor().CalcColor(*styleIfVisited, aFrame)};
|
||||
return ComputedStyle::CombineVisitedColors(colors,
|
||||
aStyle.RelevantLinkVisited());
|
||||
}
|
||||
@@ -1254,7 +1255,7 @@ void SVGUtils::MakeFillPatternFor(nsIFrame* aFrame, gfxContext* aContext,
|
||||
// objectBoundingBox where the width or height of the object is zero.
|
||||
// See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox
|
||||
sRGBColor color(sRGBColor::FromABGR(GetFallbackOrPaintColor(
|
||||
- *aFrame->Style(), &nsStyleSVG::mFill, NS_RGB(0, 0, 0))));
|
||||
+ *aFrame->Style(), &nsStyleSVG::mFill, NS_RGB(0, 0, 0), aFrame)));
|
||||
color.a *= fillOpacity;
|
||||
aOutPattern->InitColorPattern(ToDeviceColor(color));
|
||||
}
|
||||
@@ -1321,7 +1322,7 @@ void SVGUtils::MakeStrokePatternFor(nsIFrame* aFrame, gfxContext* aContext,
|
||||
// objectBoundingBox where the width or height of the object is zero.
|
||||
// See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox
|
||||
sRGBColor color(sRGBColor::FromABGR(GetFallbackOrPaintColor(
|
||||
- *aFrame->Style(), &nsStyleSVG::mStroke, NS_RGBA(0, 0, 0, 0))));
|
||||
+ *aFrame->Style(), &nsStyleSVG::mStroke, NS_RGBA(0, 0, 0, 0), aFrame)));
|
||||
color.a *= strokeOpacity;
|
||||
aOutPattern->InitColorPattern(ToDeviceColor(color));
|
||||
}
|
||||
13
src/layout/svg/SVGUtils-h.patch
Normal file
13
src/layout/svg/SVGUtils-h.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/svg/SVGUtils.h b/layout/svg/SVGUtils.h
|
||||
index 1f1f7ad6b78e5c411651fee30bbbfeb784257e0a..28c7332aae411c4220bd00af08b491d31d2eb090 100644
|
||||
--- a/layout/svg/SVGUtils.h
|
||||
+++ b/layout/svg/SVGUtils.h
|
||||
@@ -428,7 +428,7 @@ class SVGUtils final {
|
||||
|
||||
static nscolor GetFallbackOrPaintColor(
|
||||
const ComputedStyle&, StyleSVGPaint nsStyleSVG::* aFillOrStroke,
|
||||
- nscolor aDefaultContextFallbackColor);
|
||||
+ nscolor aDefaultContextFallbackColor, const nsIFrame* aFrame);
|
||||
|
||||
static void MakeFillPatternFor(nsIFrame* aFrame, gfxContext* aContext,
|
||||
GeneralPattern* aOutPattern,
|
||||
13
src/layout/tables/nsTableFrame-cpp.patch
Normal file
13
src/layout/tables/nsTableFrame-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
|
||||
index 7c39ea94392dc158656621dfbee1be72bbcd46f8..e2fe47662b92ac6fb7fe2177d1d2cdab500bb969 100644
|
||||
--- a/layout/tables/nsTableFrame.cpp
|
||||
+++ b/layout/tables/nsTableFrame.cpp
|
||||
@@ -4088,7 +4088,7 @@ static void GetColorAndStyle(const nsIFrame* aFrame, WritingMode aTableWM,
|
||||
return;
|
||||
}
|
||||
*aColor = aFrame->Style()->GetVisitedDependentColor(
|
||||
- nsStyleBorder::BorderColorFieldFor(physicalSide));
|
||||
+ nsStyleBorder::BorderColorFieldFor(physicalSide), aFrame);
|
||||
|
||||
if (aWidth) {
|
||||
*aWidth = styleData->GetComputedBorderWidth(physicalSide);
|
||||
32
src/layout/xul/tree/nsTreeBodyFrame-cpp.patch
Normal file
32
src/layout/xul/tree/nsTreeBodyFrame-cpp.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp
|
||||
index b6aa10336e7994c830e0326298820c3a534f8094..7747c52e5c5d227894d8f7fb377c65861dc51c4c 100644
|
||||
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
|
||||
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
|
||||
@@ -2865,7 +2865,8 @@ ImgDrawResult nsTreeBodyFrame::PaintCell(
|
||||
|
||||
const nsStyleBorder* borderStyle = lineContext->StyleBorder();
|
||||
// Resolve currentcolor values against the treeline context
|
||||
- nscolor color = borderStyle->mBorderLeftColor.CalcColor(*lineContext);
|
||||
+ nscolor color =
|
||||
+ borderStyle->mBorderLeftColor.CalcColor(*lineContext, this);
|
||||
ColorPattern colorPatt(ToDeviceColor(color));
|
||||
|
||||
StyleBorderStyle style = borderStyle->GetBorderStyle(eSideLeft);
|
||||
@@ -3300,7 +3301,7 @@ ImgDrawResult nsTreeBodyFrame::PaintText(
|
||||
textRect.Deflate(bp);
|
||||
|
||||
// Set our color.
|
||||
- ColorPattern color(ToDeviceColor(textContext->StyleText()->mColor));
|
||||
+ ColorPattern color(ToDeviceColor(textContext->StyleText()->mColor, this));
|
||||
|
||||
// Draw decorations.
|
||||
StyleTextDecorationLine decorations =
|
||||
@@ -3340,7 +3341,7 @@ ImgDrawResult nsTreeBodyFrame::PaintText(
|
||||
}
|
||||
|
||||
aRenderingContext.SetColor(
|
||||
- sRGBColor::FromABGR(textContext->StyleText()->mColor.ToColor()));
|
||||
+ sRGBColor::FromABGR(textContext->StyleText()->mColor.ToColor(this)));
|
||||
nsLayoutUtils::DrawString(
|
||||
this, *fontMet, &aRenderingContext, text.get(), text.Length(),
|
||||
textRect.TopLeft() + nsPoint(0, baseline), cellContext);
|
||||
30
src/servo/ports/geckolib/cbindgen-toml.patch
Normal file
30
src/servo/ports/geckolib/cbindgen-toml.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
diff --git a/servo/ports/geckolib/cbindgen.toml b/servo/ports/geckolib/cbindgen.toml
|
||||
index e9ae0149e80a241b2a32ce445deb923af2fac445..0dc5768ab8bf89f7d6c31ff4c7bd4bb805d64509 100644
|
||||
--- a/servo/ports/geckolib/cbindgen.toml
|
||||
+++ b/servo/ports/geckolib/cbindgen.toml
|
||||
@@ -679,9 +679,9 @@ renaming_overrides_prefixing = true
|
||||
nscolor CalcColor(const nsIFrame*) const;
|
||||
/**
|
||||
* Compute the final color, taking into account the foreground color from the
|
||||
- * style.
|
||||
+ * style. The frame, when supplied, is used to resolve Zen boosts.
|
||||
*/
|
||||
- nscolor CalcColor(const ComputedStyle&) const;
|
||||
+ nscolor CalcColor(const ComputedStyle&, const nsIFrame*) const;
|
||||
/**
|
||||
* Compute the final color, making the argument the foreground color.
|
||||
*/
|
||||
@@ -704,9 +704,11 @@ renaming_overrides_prefixing = true
|
||||
|
||||
/**
|
||||
* Convert this color to an nscolor. The color will be converted to sRGB first
|
||||
- * if required.
|
||||
+ * if required. The frame, when supplied, is used to resolve Zen boosts; pass
|
||||
+ * the frame the color is being resolved for so boosts can be derived from its
|
||||
+ * document, or null to skip boost resolution.
|
||||
*/
|
||||
- nscolor ToColor() const;
|
||||
+ nscolor ToColor(const nsIFrame*) const;
|
||||
"""
|
||||
|
||||
"OwnedSlice" = """
|
||||
23
src/widget/ScrollbarDrawing-cpp.patch
Normal file
23
src/widget/ScrollbarDrawing-cpp.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
diff --git a/widget/ScrollbarDrawing.cpp b/widget/ScrollbarDrawing.cpp
|
||||
index fec73f8a8cbfbf952f1d14f1a4eb2b20f9b5aad4..375ef5654cf61e4dea102588679d2ac2060d299a 100644
|
||||
--- a/widget/ScrollbarDrawing.cpp
|
||||
+++ b/widget/ScrollbarDrawing.cpp
|
||||
@@ -121,7 +121,7 @@ sRGBColor ScrollbarDrawing::ComputeScrollbarTrackColor(
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (ui->mScrollbarColor.IsColors()) {
|
||||
return sRGBColor::FromABGR(
|
||||
- ui->mScrollbarColor.AsColors().track.CalcColor(aStyle));
|
||||
+ ui->mScrollbarColor.AsColors().track.CalcColor(aStyle, aFrame));
|
||||
}
|
||||
static constexpr sRGBColor sDefaultDarkTrackColor =
|
||||
sRGBColor::FromU8(20, 20, 25, 77);
|
||||
@@ -143,7 +143,8 @@ sRGBColor ScrollbarDrawing::ComputeScrollbarThumbColor(
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (ui->mScrollbarColor.IsColors()) {
|
||||
return sRGBColor::FromABGR(ThemeColors::AdjustUnthemedScrollbarThumbColor(
|
||||
- ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle), aElementState));
|
||||
+ ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle, aFrame),
|
||||
+ aElementState));
|
||||
}
|
||||
|
||||
auto systemColor = [&] {
|
||||
15
src/widget/ScrollbarDrawingCocoa-cpp.patch
Normal file
15
src/widget/ScrollbarDrawingCocoa-cpp.patch
Normal file
@@ -0,0 +1,15 @@
|
||||
diff --git a/widget/ScrollbarDrawingCocoa.cpp b/widget/ScrollbarDrawingCocoa.cpp
|
||||
index f0dff9276f9880034c800413c4afc2400136b35a..1dd5b53bfda64e1d3b4c1870680fa1a43de0e6fb 100644
|
||||
--- a/widget/ScrollbarDrawingCocoa.cpp
|
||||
+++ b/widget/ScrollbarDrawingCocoa.cpp
|
||||
@@ -61,8 +61,8 @@ static ScrollbarParams ComputeScrollbarParams(nsIFrame* aFrame,
|
||||
if (ui->HasCustomScrollbars()) {
|
||||
const auto& colors = ui->mScrollbarColor.AsColors();
|
||||
params.isCustom = true;
|
||||
- params.trackColor = colors.track.CalcColor(aStyle);
|
||||
- params.faceColor = colors.thumb.CalcColor(aStyle);
|
||||
+ params.trackColor = colors.track.CalcColor(aStyle, aFrame);
|
||||
+ params.faceColor = colors.thumb.CalcColor(aStyle, aFrame);
|
||||
}
|
||||
|
||||
return params;
|
||||
22
src/widget/ScrollbarDrawingWin11-cpp.patch
Normal file
22
src/widget/ScrollbarDrawingWin11-cpp.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
diff --git a/widget/ScrollbarDrawingWin11.cpp b/widget/ScrollbarDrawingWin11.cpp
|
||||
index be059ca615d1e0281af64984cfc8121be2f6e305..6326c98b369d948052c3cb1df13c8cfaaa472f5c 100644
|
||||
--- a/widget/ScrollbarDrawingWin11.cpp
|
||||
+++ b/widget/ScrollbarDrawingWin11.cpp
|
||||
@@ -78,7 +78,7 @@ sRGBColor ScrollbarDrawingWin11::ComputeScrollbarTrackColor(
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (ui->mScrollbarColor.IsColors()) {
|
||||
return sRGBColor::FromABGR(
|
||||
- ui->mScrollbarColor.AsColors().track.CalcColor(aStyle));
|
||||
+ ui->mScrollbarColor.AsColors().track.CalcColor(aStyle, aFrame));
|
||||
}
|
||||
return aColors.IsDark() ? sRGBColor::FromU8(23, 23, 23, 255)
|
||||
: sRGBColor::FromU8(240, 240, 240, 255);
|
||||
@@ -94,7 +94,7 @@ sRGBColor ScrollbarDrawingWin11::ComputeScrollbarThumbColor(
|
||||
const nscolor baseColor = [&] {
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (ui->mScrollbarColor.IsColors()) {
|
||||
- return ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle);
|
||||
+ return ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle, aFrame);
|
||||
}
|
||||
return aColors.IsDark() ? NS_RGBA(149, 149, 149, 255)
|
||||
: NS_RGBA(133, 133, 133, 255);
|
||||
56
src/widget/Theme-cpp.patch
Normal file
56
src/widget/Theme-cpp.patch
Normal file
@@ -0,0 +1,56 @@
|
||||
diff --git a/widget/Theme.cpp b/widget/Theme.cpp
|
||||
index 766a8ca4bc6fcc98f719ad4f472b20bc1d198ac9..be4419cfafb55e5cac8f5de741185ee3cabc4722 100644
|
||||
--- a/widget/Theme.cpp
|
||||
+++ b/widget/Theme.cpp
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mozilla/RelativeLuminanceUtils.h"
|
||||
#include "mozilla/ScrollContainerFrame.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
+#include "mozilla/nsZenBoostsBackend.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "nsCSSColorUtils.h"
|
||||
#include "nsCSSRendering.h"
|
||||
@@ -670,10 +671,15 @@ template <typename PaintBackendData>
|
||||
void Theme::PaintTextField(PaintBackendData& aPaintData,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const ElementState& aState, const Colors& aColors,
|
||||
- DPIRatio aDpiRatio) {
|
||||
+ DPIRatio aDpiRatio, const nsIFrame* aFrame) {
|
||||
auto [backgroundColor, borderColor] =
|
||||
ComputeTextfieldColors(aState, aColors, OutlineCoversBorder::Yes);
|
||||
|
||||
+ // The default field background comes from a theme/system color rather than a
|
||||
+ // resolved style color, so apply Zen boosts here to match boosted content.
|
||||
+ backgroundColor = sRGBColor::FromABGR(zen::nsZenBoostsBackend::ResolveStyleColor(
|
||||
+ backgroundColor.ToABGR(), aFrame));
|
||||
+
|
||||
const CSSCoord radius = 2.0f;
|
||||
|
||||
ThemeDrawing::PaintRoundedRectWithRadius(aPaintData, aRect, backgroundColor,
|
||||
@@ -690,9 +696,9 @@ template <typename PaintBackendData>
|
||||
void Theme::PaintListbox(PaintBackendData& aPaintData,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const ElementState& aState, const Colors& aColors,
|
||||
- DPIRatio aDpiRatio) {
|
||||
+ DPIRatio aDpiRatio, const nsIFrame* aFrame) {
|
||||
// We happen to share style between text fields and list boxes.
|
||||
- return PaintTextField(aPaintData, aRect, aState, aColors, aDpiRatio);
|
||||
+ return PaintTextField(aPaintData, aRect, aState, aColors, aDpiRatio, aFrame);
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
@@ -1158,10 +1164,12 @@ bool Theme::DoDrawWidgetBackground(PaintBackendData& aPaintData,
|
||||
case StyleAppearance::Textfield:
|
||||
case StyleAppearance::NumberInput:
|
||||
case StyleAppearance::PasswordInput:
|
||||
- PaintTextField(aPaintData, devPxRect, elementState, colors, dpiRatio);
|
||||
+ PaintTextField(aPaintData, devPxRect, elementState, colors, dpiRatio,
|
||||
+ aFrame);
|
||||
break;
|
||||
case StyleAppearance::Listbox:
|
||||
- PaintListbox(aPaintData, devPxRect, elementState, colors, dpiRatio);
|
||||
+ PaintListbox(aPaintData, devPxRect, elementState, colors, dpiRatio,
|
||||
+ aFrame);
|
||||
break;
|
||||
case StyleAppearance::Menulist:
|
||||
PaintMenulist(aPaintData, devPxRect, elementState, colors, dpiRatio);
|
||||
19
src/widget/Theme-h.patch
Normal file
19
src/widget/Theme-h.patch
Normal file
@@ -0,0 +1,19 @@
|
||||
diff --git a/widget/Theme.h b/widget/Theme.h
|
||||
index 4e0acbb25b9e39b712a2d96d8dee366dfdce4a01..9aa377ca9f0d7f96d938339d198b797ceebbc602 100644
|
||||
--- a/widget/Theme.h
|
||||
+++ b/widget/Theme.h
|
||||
@@ -161,10 +161,12 @@ class Theme : protected nsNativeTheme, public nsITheme {
|
||||
const ElementState&, DPIRatio);
|
||||
template <typename PaintBackendData>
|
||||
void PaintTextField(PaintBackendData&, const LayoutDeviceRect&,
|
||||
- const ElementState&, const Colors&, DPIRatio);
|
||||
+ const ElementState&, const Colors&, DPIRatio,
|
||||
+ const nsIFrame*);
|
||||
template <typename PaintBackendData>
|
||||
void PaintListbox(PaintBackendData&, const LayoutDeviceRect&,
|
||||
- const ElementState&, const Colors&, DPIRatio);
|
||||
+ const ElementState&, const Colors&, DPIRatio,
|
||||
+ const nsIFrame*);
|
||||
template <typename PaintBackendData>
|
||||
void PaintMenulist(PaintBackendData&, const LayoutDeviceRect&,
|
||||
const ElementState&, const Colors&, DPIRatio);
|
||||
13
src/widget/ThemeColors-cpp.patch
Normal file
13
src/widget/ThemeColors-cpp.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/widget/ThemeColors.cpp b/widget/ThemeColors.cpp
|
||||
index 0ac3a8cbb04258312cba20a89a23700c6fd1b49f..dfd5203c1a795fc14befa88a474f241dd16e9c8f 100644
|
||||
--- a/widget/ThemeColors.cpp
|
||||
+++ b/widget/ThemeColors.cpp
|
||||
@@ -113,7 +113,7 @@ ThemeAccentColor::ThemeAccentColor(const ComputedStyle& aStyle,
|
||||
}
|
||||
MOZ_ASSERT(color.IsColor());
|
||||
nscolor accentColor =
|
||||
- ColorPalette::EnsureOpaque(color.AsColor().CalcColor(aStyle));
|
||||
+ ColorPalette::EnsureOpaque(color.AsColor().CalcColor(aStyle, nullptr));
|
||||
if (sRGBColor::FromABGR(accentColor) == mDefaultPalette->mAccent) {
|
||||
return;
|
||||
}
|
||||
@@ -65,6 +65,7 @@ export class nsZenBoostEditor {
|
||||
once: true,
|
||||
});
|
||||
|
||||
this.doc.getElementById("zenBoostWindow").setAttribute("editor", "boost");
|
||||
this.doc.getElementById("zen-boost-editor-root").style.display = "flex";
|
||||
this.doc.getElementById("zen-boost-code-editor-root").style.display =
|
||||
"none";
|
||||
@@ -366,20 +367,22 @@ export class nsZenBoostEditor {
|
||||
// being smaller than it should be
|
||||
this._boostEditorWidth = this.editorWindow.outerWidth;
|
||||
|
||||
this.editorWindow.resizeTo(
|
||||
this._codeEditorWidth,
|
||||
this.editorWindow.outerHeight
|
||||
);
|
||||
if (openRightAligned) {
|
||||
this.editorWindow.moveTo(
|
||||
this.editorWindow.screenX - offset,
|
||||
this.editorWindow.screenY
|
||||
this.editorWindow.requestAnimationFrame(() => {
|
||||
this.editorWindow.resizeTo(
|
||||
this._codeEditorWidth,
|
||||
this.editorWindow.outerHeight
|
||||
);
|
||||
}
|
||||
if (openRightAligned) {
|
||||
this.editorWindow.moveTo(
|
||||
this.editorWindow.screenX - offset,
|
||||
this.editorWindow.screenY
|
||||
);
|
||||
}
|
||||
|
||||
this.doc.getElementById("zen-boost-editor-root").style.display = "none";
|
||||
this.doc.getElementById("zen-boost-code-editor-root").style.display =
|
||||
"initial";
|
||||
this.doc.getElementById("zen-boost-editor-root").style.display = "none";
|
||||
this.doc.getElementById("zen-boost-code-editor-root").style.display =
|
||||
"initial";
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,20 +400,22 @@ export class nsZenBoostEditor {
|
||||
}
|
||||
windowElem.setAttribute("editor", "boost");
|
||||
|
||||
this.editorWindow.resizeTo(
|
||||
this._boostEditorWidth,
|
||||
this.editorWindow.outerHeight
|
||||
);
|
||||
if (openRightAligned) {
|
||||
this.editorWindow.moveTo(
|
||||
this.editorWindow.screenX + offset,
|
||||
this.editorWindow.screenY
|
||||
this.editorWindow.requestAnimationFrame(() => {
|
||||
this.editorWindow.resizeTo(
|
||||
this._boostEditorWidth,
|
||||
this.editorWindow.outerHeight
|
||||
);
|
||||
}
|
||||
if (openRightAligned) {
|
||||
this.editorWindow.moveTo(
|
||||
this.editorWindow.screenX + offset,
|
||||
this.editorWindow.screenY
|
||||
);
|
||||
}
|
||||
|
||||
this.doc.getElementById("zen-boost-editor-root").style.display = "flex";
|
||||
this.doc.getElementById("zen-boost-code-editor-root").style.display =
|
||||
"none";
|
||||
this.doc.getElementById("zen-boost-editor-root").style.display = "flex";
|
||||
this.doc.getElementById("zen-boost-code-editor-root").style.display =
|
||||
"none";
|
||||
});
|
||||
|
||||
// Disable picker mode
|
||||
this.disableAllPickers();
|
||||
@@ -564,6 +569,9 @@ ${cssSelector} {
|
||||
this.wasDragging = true;
|
||||
event.preventDefault();
|
||||
|
||||
this.currentBoostData.changeWasMade = true;
|
||||
this.updateButtonToggleVisuals();
|
||||
|
||||
if (this.dragTarget == "zen-boost-color-picker-dot-secondary") {
|
||||
this.setSecondaryDotPos(event.clientX, event.clientY);
|
||||
} else if (event.target.id != "zen-boost-magic-theme") {
|
||||
@@ -670,20 +678,6 @@ ${cssSelector} {
|
||||
panel.openPopup(event.target, "bottomcenter topcenter", 0, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the color picker dot to the default position (default state).
|
||||
*/
|
||||
resetDotPosition() {
|
||||
const gradient = this.doc.querySelector(".zen-boost-color-picker-gradient");
|
||||
const rect = gradient.getBoundingClientRect();
|
||||
const padding = 50;
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
const radius = (rect.width - padding) / 2;
|
||||
|
||||
this.setDotPos(centerX + radius / 1.25, centerY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles clicks on the theme picker gradient or magic theme button.
|
||||
* Updates the dot position or toggles auto-theme mode based on the click target.
|
||||
@@ -695,14 +689,16 @@ ${cssSelector} {
|
||||
|
||||
this.currentBoostData.changeWasMade = true;
|
||||
|
||||
this.currentBoostData.enableColorBoost = true;
|
||||
|
||||
if (event.target.id == "zen-boost-magic-theme") {
|
||||
this.currentBoostData.enableColorBoost = true;
|
||||
this.currentBoostData.autoTheme = !this.currentBoostData.autoTheme;
|
||||
this.updateButtonToggleVisuals();
|
||||
this.updateCurrentBoost();
|
||||
} else if (this.dragTarget != "zen-boost-color-picker-dot-secondary") {
|
||||
this.setDotPos(event.clientX, event.clientY, !this.wasDragging);
|
||||
}
|
||||
|
||||
this.updateButtonToggleVisuals();
|
||||
this.wasDragging = false;
|
||||
}
|
||||
|
||||
@@ -1310,6 +1306,23 @@ ${cssSelector} {
|
||||
const resetBoost = this.doc.getElementById("zen-boost-edit-reset");
|
||||
|
||||
const popup = this.doc.getElementById("zenBoostContextMenu");
|
||||
popup.addEventListener(
|
||||
"popupshown",
|
||||
() => {
|
||||
// Don't give the user following options if the boost
|
||||
// is not going to save / not currently saved (unchanged)
|
||||
let shouldDisable = !this.currentBoostData.changeWasMade;
|
||||
const items = [renameBoost, deleteBoost, resetBoost];
|
||||
for (let item of items) {
|
||||
if (shouldDisable) {
|
||||
item.setAttribute("disabled", "");
|
||||
} else {
|
||||
item.removeAttribute("disabled");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
popup.openPopup(
|
||||
event.target,
|
||||
"bottomcenter topcenter",
|
||||
@@ -1319,12 +1332,6 @@ ${cssSelector} {
|
||||
false /* attributesOverride */,
|
||||
event
|
||||
);
|
||||
|
||||
// Don't give the user following options if the boost
|
||||
// is not going to save / not currently saved (unchanged)
|
||||
renameBoost.disabled = !this.currentBoostData.changeWasMade;
|
||||
deleteBoost.disabled = !this.currentBoostData.changeWasMade;
|
||||
resetBoost.disabled = !this.currentBoostData.changeWasMade;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1566,44 +1573,32 @@ ${cssSelector} {
|
||||
}
|
||||
|
||||
if (
|
||||
this.currentBoostData.dotPos.x == null ||
|
||||
this.currentBoostData.dotPos.y == null
|
||||
) {
|
||||
this.resetDotPosition();
|
||||
} else {
|
||||
// Test if the stored position is a non-normalized dot position
|
||||
if (
|
||||
this.currentBoostData.dotPos.x > 1 ||
|
||||
this.currentBoostData.dotPos.x < 0 ||
|
||||
this.currentBoostData.dotPos.y > 1 ||
|
||||
this.currentBoostData.dotPos.y < 0
|
||||
) {
|
||||
// Normalize position
|
||||
this.currentBoostData.dotPos.x =
|
||||
this.currentBoostData.dotPos.x / rect.width;
|
||||
this.currentBoostData.dotPos.y =
|
||||
this.currentBoostData.dotPos.y / rect.height;
|
||||
}
|
||||
|
||||
// Convert normalized position to relative position
|
||||
const xPos = this.currentBoostData.dotPos.x * rect.width;
|
||||
const yPos = this.currentBoostData.dotPos.y * rect.height;
|
||||
|
||||
dot.style.left = `${xPos}px`;
|
||||
dot.style.top = `${yPos}px`;
|
||||
}
|
||||
|
||||
if (
|
||||
this.currentBoostData.secondaryDotPos?.x != null &&
|
||||
this.currentBoostData.secondaryDotPos?.y != null
|
||||
this.currentBoostData.dotPos.x > 1 ||
|
||||
this.currentBoostData.dotPos.x < 0 ||
|
||||
this.currentBoostData.dotPos.y > 1 ||
|
||||
this.currentBoostData.dotPos.y < 0
|
||||
) {
|
||||
const xPosSec = this.currentBoostData.secondaryDotPos.x * rect.width;
|
||||
const yPosSec = this.currentBoostData.secondaryDotPos.y * rect.height;
|
||||
|
||||
dotSec.style.left = `${xPosSec}px`;
|
||||
dotSec.style.top = `${yPosSec}px`;
|
||||
// Normalize position
|
||||
this.currentBoostData.dotPos.x =
|
||||
this.currentBoostData.dotPos.x / rect.width;
|
||||
this.currentBoostData.dotPos.y =
|
||||
this.currentBoostData.dotPos.y / rect.height;
|
||||
}
|
||||
|
||||
// Convert normalized position to relative position
|
||||
const xPos = this.currentBoostData.dotPos.x * rect.width;
|
||||
const yPos = this.currentBoostData.dotPos.y * rect.height;
|
||||
|
||||
dot.style.left = `${xPos}px`;
|
||||
dot.style.top = `${yPos}px`;
|
||||
|
||||
const xPosSec = this.currentBoostData.secondaryDotPos.x * rect.width;
|
||||
const yPosSec = this.currentBoostData.secondaryDotPos.y * rect.height;
|
||||
|
||||
dotSec.style.left = `${xPosSec}px`;
|
||||
dotSec.style.top = `${yPosSec}px`;
|
||||
|
||||
this.editorWindow._editor.setText(this.currentBoostData.customCSS || "");
|
||||
|
||||
this.updateFontButtonVisuals();
|
||||
|
||||
@@ -115,11 +115,11 @@ class nsZenBoostsManager {
|
||||
boostName: "My Boost",
|
||||
|
||||
dotAngleDeg: 0,
|
||||
dotPos: { x: null, y: null },
|
||||
dotPos: { x: 0.76, y: 0.66 },
|
||||
dotDistance: 0,
|
||||
|
||||
secondaryDotAngleDegDelta: 55,
|
||||
secondaryDotPos: { x: null, y: null },
|
||||
secondaryDotPos: { x: 0.5, y: 0.81 },
|
||||
|
||||
brightness: 0.5,
|
||||
saturation: 0.5,
|
||||
@@ -312,6 +312,7 @@ class nsZenBoostsManager {
|
||||
|
||||
Services.obs.notifyObservers(null, "zen-boosts-active-change", { id });
|
||||
|
||||
this.#writeToDisk(this.registeredDomains);
|
||||
this.#stylesManager.invalidateStyleForDomain(domain);
|
||||
this.notify();
|
||||
}
|
||||
@@ -327,23 +328,23 @@ class nsZenBoostsManager {
|
||||
|
||||
if (domainEntry) {
|
||||
if (domainEntry.boostEntries.has(id)) {
|
||||
let unloadStyles = false;
|
||||
if (domainEntry.activeBoostId === id) {
|
||||
domainEntry.activeBoostId = null;
|
||||
Services.obs.notifyObservers(null, "zen-boosts-active-change", {
|
||||
id: null,
|
||||
});
|
||||
|
||||
this.#stylesManager.invalidateStyleForDomain(domain);
|
||||
this.notify(true);
|
||||
unloadStyles = true;
|
||||
} else {
|
||||
domainEntry.activeBoostId = id;
|
||||
Services.obs.notifyObservers(null, "zen-boosts-active-change", {
|
||||
id,
|
||||
});
|
||||
|
||||
this.#stylesManager.invalidateStyleForDomain(domain);
|
||||
this.notify();
|
||||
}
|
||||
|
||||
this.#writeToDisk(this.registeredDomains);
|
||||
this.#stylesManager.invalidateStyleForDomain(domain);
|
||||
this.notify(unloadStyles);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -539,6 +540,12 @@ class nsZenBoostsManager {
|
||||
const directoryPath = this.#cssPath;
|
||||
const savePath = PathUtils.join(directoryPath, fileName);
|
||||
|
||||
if (!css || css.trim() === "") {
|
||||
if (await IOUtils.exists(savePath)) {
|
||||
await IOUtils.remove(savePath);
|
||||
}
|
||||
return;
|
||||
}
|
||||
await IOUtils.makeDirectory(directoryPath, { createAncestors: true });
|
||||
await IOUtils.writeUTF8(savePath, css);
|
||||
}
|
||||
@@ -553,7 +560,8 @@ class nsZenBoostsManager {
|
||||
const domainEntry = this.#getDomainEntry(domain);
|
||||
|
||||
if (domainEntry) {
|
||||
return domainEntry.boostEntries.has(domainEntry.activeBoostId);
|
||||
const boost = this.loadActiveBoostFromStore(domain);
|
||||
return boost?.boostEntry.boostData.changeWasMade ?? false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -26,6 +26,7 @@ export class ZapOverlay {
|
||||
#dissolvePoolSize = 5;
|
||||
#dissolveEffectPool = [];
|
||||
#currentDissolveIndex = 0;
|
||||
#onZapDoneClick = null;
|
||||
|
||||
/**
|
||||
* @param {*} document Webpage document
|
||||
@@ -77,10 +78,8 @@ export class ZapOverlay {
|
||||
*/
|
||||
#initializeElements() {
|
||||
this.zapDoneButton = this.getElementById("zap-done");
|
||||
this.zapDoneButton.addEventListener(
|
||||
"click",
|
||||
this.#disableZapMode.bind(this)
|
||||
);
|
||||
this.#onZapDoneClick = this.#disableZapMode.bind(this);
|
||||
this.zapDoneButton.addEventListener("click", this.#onZapDoneClick);
|
||||
|
||||
this.#updateZappedList();
|
||||
}
|
||||
@@ -355,6 +354,12 @@ export class ZapOverlay {
|
||||
dissolve.tearDown();
|
||||
});
|
||||
|
||||
if (this.zapDoneButton && this.#onZapDoneClick) {
|
||||
this.zapDoneButton.removeEventListener("click", this.#onZapDoneClick);
|
||||
}
|
||||
this.#onZapDoneClick = null;
|
||||
this.zapDoneButton = null;
|
||||
|
||||
if (this.#content) {
|
||||
try {
|
||||
this.document.removeAnonymousContent(this.#content);
|
||||
|
||||
@@ -70,6 +70,17 @@ export class ZenBoostsChild extends JSWindowActorChild {
|
||||
|
||||
static PREVENTABLE_SET = new Set(ZenBoostsChild.PREVENTABLE_EVENTS);
|
||||
|
||||
actorCreated() {
|
||||
this.#applyBoostForPageIfAvailable();
|
||||
}
|
||||
|
||||
didDestroy() {
|
||||
if (this.#currentState === ZenBoostsChild.STATES.ZAP) {
|
||||
this.disableZapMode();
|
||||
}
|
||||
this.#removeEventListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse of https://searchfox.org/firefox-main/rev/1a8c62b86277005f907151bc5389cf5c5091e76f/gfx/src/nsColor.h#23-27
|
||||
*
|
||||
@@ -179,28 +190,6 @@ export class ZenBoostsChild extends JSWindowActorChild {
|
||||
return [h * 60, s, l];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles DOM events for the actor. Applies boost settings when a document
|
||||
* element is inserted.
|
||||
*
|
||||
* @param {Event} event - The DOM event to handle.
|
||||
*/
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "unload":
|
||||
if (this.#currentState === ZenBoostsChild.STATES.ZAP) {
|
||||
this.disableZapMode();
|
||||
}
|
||||
this.#removeEventListeners();
|
||||
break;
|
||||
case "DOMWindowCreated":
|
||||
this.#applyBoostForPageIfAvailable();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handleZapEvent(event) {
|
||||
if (ZenBoostsChild.ALL_EVENTS_SET.has(event.type)) {
|
||||
this.#overlay.handleEvent(
|
||||
@@ -322,13 +311,18 @@ export class ZenBoostsChild extends JSWindowActorChild {
|
||||
return p;
|
||||
}
|
||||
|
||||
get #hostWithoutPort() {
|
||||
const host = this.browsingContext.topWindow?.location.host;
|
||||
return host?.split(":")[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Aquires the boost data for this website
|
||||
*
|
||||
* @returns {object} Boost data for the current website
|
||||
*/
|
||||
getWebsiteBoost() {
|
||||
const domain = this.browsingContext.topWindow?.location?.host;
|
||||
const domain = this.#hostWithoutPort;
|
||||
if (!domain) {
|
||||
return null;
|
||||
}
|
||||
@@ -362,6 +356,14 @@ export class ZenBoostsChild extends JSWindowActorChild {
|
||||
this.#loadStyleSheet(boost.styleSheet);
|
||||
}
|
||||
|
||||
if (
|
||||
boostData.sizeOverride &&
|
||||
isFinite(boostData.sizeOverride) &&
|
||||
boostData.sizeOverride !== 1
|
||||
) {
|
||||
browsingContext.fullZoom = boostData.sizeOverride;
|
||||
}
|
||||
|
||||
browsingContext.isZenBoostsInverted = boostData.smartInvert;
|
||||
if (boostData.enableColorBoost) {
|
||||
let primaryColor;
|
||||
@@ -384,17 +386,17 @@ export class ZenBoostsChild extends JSWindowActorChild {
|
||||
// using the same modifiers as the color above
|
||||
primaryColor = this.#buildBoostColor(
|
||||
primaryGradientColor[0],
|
||||
primaryGradientColor[1] * (1 - boostData.saturation),
|
||||
0.1 + primaryGradientColor[2] * 0.9 * boostData.brightness,
|
||||
1 - boostData.saturation,
|
||||
0.1 + 0.9 * boostData.brightness,
|
||||
boostData
|
||||
);
|
||||
} else {
|
||||
primaryColor = this.#buildBoostColor(
|
||||
boostData.dotAngleDeg,
|
||||
/* already is [0, 1] */
|
||||
boostData.dotDistance * (1 - boostData.saturation),
|
||||
1 - boostData.saturation,
|
||||
/* lightness range from [0.1, 0.9] */
|
||||
0.1 + boostData.dotDistance * 0.8 * boostData.brightness,
|
||||
0.1 + 0.9 * boostData.brightness,
|
||||
boostData
|
||||
);
|
||||
}
|
||||
@@ -484,7 +486,7 @@ export class ZenBoostsChild extends JSWindowActorChild {
|
||||
}
|
||||
|
||||
addZapSelector(selector) {
|
||||
const domain = this.browsingContext.topWindow?.location?.host;
|
||||
const domain = this.#hostWithoutPort;
|
||||
this.sendQuery("ZenBoost:ZapSelector", {
|
||||
action: "add",
|
||||
selector,
|
||||
@@ -493,7 +495,7 @@ export class ZenBoostsChild extends JSWindowActorChild {
|
||||
}
|
||||
|
||||
removeZapSelector(selector) {
|
||||
const domain = this.browsingContext.topWindow?.location?.host;
|
||||
const domain = this.#hostWithoutPort;
|
||||
this.sendQuery("ZenBoost:ZapSelector", {
|
||||
action: "remove",
|
||||
selector,
|
||||
|
||||
121
src/zen/boosts/gtest/TestZenBoostsColorFilter.cpp
Normal file
121
src/zen/boosts/gtest/TestZenBoostsColorFilter.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/nsZenBoostsBackend.h"
|
||||
|
||||
using zen::detail::FilterColorChannel;
|
||||
using zen::detail::InvertColorChannel;
|
||||
using zen::detail::PrecomputeAccent;
|
||||
using zen::detail::RotateAccent;
|
||||
|
||||
namespace {
|
||||
|
||||
// A spread of representative input colors (opaque unless noted).
|
||||
const nscolor kColors[] = {
|
||||
NS_RGBA(255, 0, 0, 255), // pure red
|
||||
NS_RGBA(0, 255, 0, 255), // pure green
|
||||
NS_RGBA(0, 0, 255, 255), // pure blue
|
||||
NS_RGBA(0, 0, 0, 255), // black
|
||||
NS_RGBA(255, 255, 255, 255), // white
|
||||
NS_RGBA(128, 128, 128, 255), // mid gray
|
||||
NS_RGBA(18, 52, 86, 200), // arbitrary, semi-transparent
|
||||
NS_RGBA(240, 17, 99, 1), // near-min alpha
|
||||
};
|
||||
|
||||
// The accent stores the contrast/strength in its alpha byte
|
||||
// (NS_GET_CONTRAST == NS_GET_A). 0 means "no tint".
|
||||
zen::nsZenAccentOklab MakeAccent(uint8_t r, uint8_t g, uint8_t b,
|
||||
uint8_t contrast) {
|
||||
return PrecomputeAccent(NS_RGBA(r, g, b, contrast));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// The headline invariant: filtering must never change opacity. The whole
|
||||
// pipeline overloads the alpha byte for contrast on the *accent*, but a
|
||||
// filtered *content* color must keep its original alpha.
|
||||
TEST(ZenBoostsColorFilter, PreservesAlpha)
|
||||
{
|
||||
const zen::nsZenAccentOklab accent = MakeAccent(80, 120, 200, 180);
|
||||
const zen::nsZenAccentOklab complementary = RotateAccent(accent, 180.0f);
|
||||
|
||||
for (nscolor c : kColors) {
|
||||
const nscolor out = FilterColorChannel(c, accent, complementary);
|
||||
EXPECT_EQ(NS_GET_A(out), NS_GET_A(c)) << "alpha changed for input " << c;
|
||||
}
|
||||
}
|
||||
|
||||
// Fully transparent colors are invisible; the filter must pass them through
|
||||
// untouched (and must not interpret their zero alpha as contrast).
|
||||
TEST(ZenBoostsColorFilter, TransparentPassthrough)
|
||||
{
|
||||
const zen::nsZenAccentOklab accent = MakeAccent(80, 120, 200, 180);
|
||||
const zen::nsZenAccentOklab complementary = RotateAccent(accent, 90.0f);
|
||||
|
||||
const nscolor transparent = NS_RGBA(255, 0, 0, 0);
|
||||
EXPECT_EQ(FilterColorChannel(transparent, accent, complementary),
|
||||
transparent);
|
||||
EXPECT_EQ(InvertColorChannel(transparent), transparent);
|
||||
}
|
||||
|
||||
// Same inputs must always yield the same output (no hidden global state in
|
||||
// the math itself; the production cache lives outside these primitives).
|
||||
TEST(ZenBoostsColorFilter, Deterministic)
|
||||
{
|
||||
const zen::nsZenAccentOklab accent = MakeAccent(33, 200, 90, 200);
|
||||
const zen::nsZenAccentOklab complementary = RotateAccent(accent, 200.0f);
|
||||
|
||||
for (nscolor c : kColors) {
|
||||
const nscolor a = FilterColorChannel(c, accent, complementary);
|
||||
const nscolor b = FilterColorChannel(c, accent, complementary);
|
||||
EXPECT_EQ(a, b);
|
||||
EXPECT_EQ(InvertColorChannel(c), InvertColorChannel(c));
|
||||
}
|
||||
}
|
||||
|
||||
// A zero-contrast accent means "no boost strength": the color must come back
|
||||
// essentially unchanged (allow +/-1 per channel for sRGB<->Oklab rounding).
|
||||
TEST(ZenBoostsColorFilter, ZeroContrastIsNearIdentity)
|
||||
{
|
||||
const zen::nsZenAccentOklab accent = MakeAccent(200, 50, 50, 0);
|
||||
const zen::nsZenAccentOklab complementary = RotateAccent(accent, 180.0f);
|
||||
|
||||
for (nscolor c : kColors) {
|
||||
if (NS_GET_A(c) == 0) {
|
||||
continue;
|
||||
}
|
||||
const nscolor out = FilterColorChannel(c, accent, complementary);
|
||||
EXPECT_NEAR(NS_GET_R(out), NS_GET_R(c), 1);
|
||||
EXPECT_NEAR(NS_GET_G(out), NS_GET_G(c), 1);
|
||||
EXPECT_NEAR(NS_GET_B(out), NS_GET_B(c), 1);
|
||||
EXPECT_EQ(NS_GET_A(out), NS_GET_A(c));
|
||||
}
|
||||
}
|
||||
|
||||
// Guards against a regression that turns the filter into a no-op: a strong
|
||||
// accent applied to a neutral gray must actually move the color.
|
||||
TEST(ZenBoostsColorFilter, StrongAccentActuallyTints)
|
||||
{
|
||||
const zen::nsZenAccentOklab accent = MakeAccent(20, 130, 240, 255);
|
||||
const zen::nsZenAccentOklab complementary = RotateAccent(accent, 30.0f);
|
||||
|
||||
const nscolor gray = NS_RGBA(128, 128, 128, 255);
|
||||
const nscolor out = FilterColorChannel(gray, accent, complementary);
|
||||
|
||||
const bool moved = NS_GET_R(out) != NS_GET_R(gray) ||
|
||||
NS_GET_G(out) != NS_GET_G(gray) ||
|
||||
NS_GET_B(out) != NS_GET_B(gray);
|
||||
EXPECT_TRUE(moved) << "a full-strength accent should tint mid gray";
|
||||
EXPECT_EQ(NS_GET_A(out), NS_GET_A(gray));
|
||||
}
|
||||
|
||||
// Inversion must also preserve opacity.
|
||||
TEST(ZenBoostsColorFilter, InvertPreservesAlpha)
|
||||
{
|
||||
for (nscolor c : kColors) {
|
||||
EXPECT_EQ(NS_GET_A(InvertColorChannel(c)), NS_GET_A(c));
|
||||
}
|
||||
}
|
||||
9
src/zen/boosts/gtest/moz.build
Normal file
9
src/zen/boosts/gtest/moz.build
Normal file
@@ -0,0 +1,9 @@
|
||||
# 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/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"TestZenBoostsColorFilter.cpp",
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = "xul-gtest"
|
||||
@@ -26,3 +26,7 @@ SOURCES += [
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
|
||||
TEST_DIRS += [
|
||||
"gtest",
|
||||
]
|
||||
|
||||
@@ -38,18 +38,6 @@ void BrowsingContext::WalkPresContexts(Callback&& aCallback) {
|
||||
});
|
||||
}
|
||||
|
||||
static void RefreshBoostCacheIfMatchesCurrent(BrowsingContext* aChanged) {
|
||||
auto* backend = zen::nsZenBoostsBackend::GetInstance();
|
||||
if (!backend) {
|
||||
return;
|
||||
}
|
||||
auto current = backend->GetCurrentBrowsingContext();
|
||||
if (!current || current->Top() != aChanged) {
|
||||
return;
|
||||
}
|
||||
backend->RefreshCachedBoostState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called when the ZenBoostsData field is set on a browsing context.
|
||||
* Triggers a restyle if the boost data has changed.
|
||||
@@ -61,7 +49,6 @@ void BrowsingContext::DidSet(FieldIndex<IDX_ZenBoostsData>,
|
||||
if (ZenBoostsData() == aOldValue) {
|
||||
return;
|
||||
}
|
||||
RefreshBoostCacheIfMatchesCurrent(this);
|
||||
PresContextAffectingFieldChanged();
|
||||
TRIGGER_PRES_CONTEXT_RESTYLE();
|
||||
}
|
||||
@@ -79,7 +66,6 @@ void BrowsingContext::DidSet(FieldIndex<IDX_ZenBoostsComplementaryRotation>,
|
||||
if (ZenBoostsComplementaryRotation() == aOldValue) {
|
||||
return;
|
||||
}
|
||||
RefreshBoostCacheIfMatchesCurrent(this);
|
||||
PresContextAffectingFieldChanged();
|
||||
TRIGGER_PRES_CONTEXT_RESTYLE();
|
||||
}
|
||||
@@ -95,7 +81,6 @@ void BrowsingContext::DidSet(FieldIndex<IDX_IsZenBoostsInverted>,
|
||||
if (IsZenBoostsInverted() == aOldValue) {
|
||||
return;
|
||||
}
|
||||
RefreshBoostCacheIfMatchesCurrent(this);
|
||||
PresContextAffectingFieldChanged();
|
||||
TRIGGER_PRES_CONTEXT_RESTYLE();
|
||||
}
|
||||
|
||||
@@ -4,12 +4,16 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "nsZenBoostsBackend.h"
|
||||
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
@@ -21,6 +25,8 @@
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/DocumentInlines.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/PseudoStyleType.h"
|
||||
|
||||
#include "mozilla/StaticPrefs_zen.h"
|
||||
|
||||
@@ -29,9 +35,6 @@
|
||||
#define INVERT_CHANNEL_FLOOR() \
|
||||
(mozilla::StaticPrefs::zen_boosts_invert_channel_floor_AtStartup())
|
||||
|
||||
#define SHOULD_APPLY_BOOSTS_TO_ANONYMOUS_CONTENT() \
|
||||
(!mozilla::StaticPrefs::zen_boosts_disable_on_anonymous_content_AtStartup())
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
# define ZEN_HOT_FUNCTION __attribute__((hot))
|
||||
#else
|
||||
@@ -48,10 +51,6 @@ namespace zen {
|
||||
|
||||
NS_IMPL_ISUPPORTS0(nsZenBoostsBackend)
|
||||
|
||||
nsZenAccentOklab nsZenBoostsBackend::mCachedAccent{0};
|
||||
nsZenAccentOklab nsZenBoostsBackend::mCachedComplementary{0};
|
||||
float nsZenBoostsBackend::mCachedComplementaryRotationDeg = 0.0f;
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
@@ -83,17 +82,43 @@ static inline float linearToSrgb(float c) {
|
||||
static inline float fastCbrt(float x) {
|
||||
if (x == 0.0f) return 0.0f;
|
||||
float a = std::abs(x);
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
} u = {a};
|
||||
u.i = u.i / 3 + 0x2a504a2e;
|
||||
float y = u.f;
|
||||
// Bit-level initial guess. Use memcpy rather than a union to avoid the
|
||||
// undefined behaviour of type-punning through a union member in C++.
|
||||
uint32_t i;
|
||||
std::memcpy(&i, &a, sizeof(i));
|
||||
i = i / 3 + 0x2a504a2e;
|
||||
float y;
|
||||
std::memcpy(&y, &i, sizeof(y));
|
||||
y = (2.0f * y + a / (y * y)) * (1.0f / 3.0f);
|
||||
y = (2.0f * y + a / (y * y)) * (1.0f / 3.0f);
|
||||
return x < 0.0f ? -y : y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sRGB(0..255) -> linear lookup table. The filter only ever feeds
|
||||
* integer 8-bit channels through srgbToLinear, so the 256 possible results
|
||||
* are precomputed once instead of calling std::pow three times per color on
|
||||
* the per-color hot path. Built lazily on first use; the function-local
|
||||
* static makes initialization thread-safe.
|
||||
*/
|
||||
static inline const std::array<float, 256>& SrgbLinearTable() {
|
||||
static const std::array<float, 256> kTable = [] {
|
||||
std::array<float, 256> table{};
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
table[i] = srgbToLinear(i * (1.0f / 255.0f));
|
||||
}
|
||||
return table;
|
||||
}();
|
||||
return kTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Linearizes an 8-bit sRGB channel via the precomputed table.
|
||||
*/
|
||||
static inline float srgbToLinear8(uint8_t aChannel) {
|
||||
return SrgbLinearTable()[aChannel];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Precomputes the Oklab values for a given accent color. This allows us
|
||||
* to efficiently apply the accent color as a filter to other colors without
|
||||
@@ -107,13 +132,9 @@ ZEN_HOT_FUNCTION
|
||||
inline static auto zenPrecomputeAccent(nscolor aAccentColor) {
|
||||
constexpr float inv255 = 1.0f / 255.0f;
|
||||
|
||||
const float r = NS_GET_R(aAccentColor) * inv255;
|
||||
const float g = NS_GET_G(aAccentColor) * inv255;
|
||||
const float b = NS_GET_B(aAccentColor) * inv255;
|
||||
|
||||
const float lr = srgbToLinear(r);
|
||||
const float lg = srgbToLinear(g);
|
||||
const float lb = srgbToLinear(b);
|
||||
const float lr = srgbToLinear8(NS_GET_R(aAccentColor));
|
||||
const float lg = srgbToLinear8(NS_GET_G(aAccentColor));
|
||||
const float lb = srgbToLinear8(NS_GET_B(aAccentColor));
|
||||
|
||||
const float l_ =
|
||||
fastCbrt(0.4122214708f * lr + 0.5363325363f * lg + 0.0514459929f * lb);
|
||||
@@ -156,6 +177,45 @@ inline static nsZenAccentOklab zenRotateAccent(const nsZenAccentOklab& aBase,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Small round-robin cache of precomputed accents. Painting several
|
||||
* boosted tabs with different accents interleaved would otherwise recompute
|
||||
* the Oklab base accent (with cbrt) and the rotated complementary accent on
|
||||
* every single color. Keyed by the accent nscolor and the complementary hue
|
||||
* rotation. Main-thread only (same threading assumption as the per-color
|
||||
* paint path it serves).
|
||||
*/
|
||||
struct AccentCacheEntry {
|
||||
nscolor accentNS = 0;
|
||||
float rotationDeg = 0.0f;
|
||||
bool valid = false;
|
||||
nsZenAccentOklab accent{};
|
||||
nsZenAccentOklab complementary{};
|
||||
};
|
||||
|
||||
static constexpr size_t kAccentCacheSize = 4;
|
||||
static AccentCacheEntry sAccentCache[kAccentCacheSize];
|
||||
static size_t sAccentCacheNext = 0;
|
||||
|
||||
ZEN_HOT_FUNCTION
|
||||
static const AccentCacheEntry& GetCachedAccent(nscolor aAccentNS,
|
||||
float aRotationDeg) {
|
||||
for (const auto& entry : sAccentCache) {
|
||||
if (entry.valid && entry.accentNS == aAccentNS &&
|
||||
entry.rotationDeg == aRotationDeg) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
AccentCacheEntry& slot = sAccentCache[sAccentCacheNext];
|
||||
sAccentCacheNext = (sAccentCacheNext + 1) % kAccentCacheSize;
|
||||
slot.accentNS = aAccentNS;
|
||||
slot.rotationDeg = aRotationDeg;
|
||||
slot.accent = zenPrecomputeAccent(aAccentNS);
|
||||
slot.complementary = zenRotateAccent(slot.accent, aRotationDeg);
|
||||
slot.valid = true;
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Applies a duotone color filter to transform an original color toward
|
||||
* one of two accent colors. The original color's perceived lightness decides
|
||||
@@ -183,10 +243,10 @@ inline static nsZenAccentOklab zenRotateAccent(const nsZenAccentOklab& aBase,
|
||||
constexpr float inv255 = 1.0f / 255.0f;
|
||||
const float blendFactor = contrast * inv255;
|
||||
|
||||
// sRGB -> linear
|
||||
const float lr = srgbToLinear(NS_GET_R(aOriginalColor) * inv255);
|
||||
const float lg = srgbToLinear(NS_GET_G(aOriginalColor) * inv255);
|
||||
const float lb = srgbToLinear(NS_GET_B(aOriginalColor) * inv255);
|
||||
// sRGB -> linear (8-bit channels via the precomputed table)
|
||||
const float lr = srgbToLinear8(NS_GET_R(aOriginalColor));
|
||||
const float lg = srgbToLinear8(NS_GET_G(aOriginalColor));
|
||||
const float lb = srgbToLinear8(NS_GET_B(aOriginalColor));
|
||||
|
||||
// Linear RGB -> LMS -> cube root -> Oklab (fused)
|
||||
const float l_ =
|
||||
@@ -300,40 +360,83 @@ inline static nscolor zenInvertColorChannel(nscolor aColor) {
|
||||
const auto gShifted = sum - gInv;
|
||||
const auto bShifted = sum - bInv;
|
||||
|
||||
// Compress the channel range into [FLOOR, 255] so dark inversions are
|
||||
// lifted while light inversions are left untouched. This preserves hue
|
||||
// since all three channels are scaled by the same factor.
|
||||
// If the resulting color is light, leave it untouched: mixing in the floor
|
||||
// would raise its lowest channel and wash the color out toward grey. Only
|
||||
// dark results get the floor lift, which keeps them off pure black.
|
||||
const auto luma = (rShifted * 54 + gShifted * 183 + bShifted * 19) >> 8;
|
||||
if (luma > 127) {
|
||||
return NS_RGBA(static_cast<uint8_t>(rShifted),
|
||||
static_cast<uint8_t>(gShifted),
|
||||
static_cast<uint8_t>(bShifted), a);
|
||||
}
|
||||
|
||||
// Compress the dark channel range into [FLOOR, 255] so dark inversions are
|
||||
// lifted off pure black. This preserves hue since all three channels are
|
||||
// scaled by the same factor.
|
||||
const auto channelFloor = INVERT_CHANNEL_FLOOR();
|
||||
const uint32_t range = 255 - channelFloor;
|
||||
const auto lift = [channelFloor, range](uint8_t c) -> uint8_t {
|
||||
return static_cast<uint8_t>(channelFloor + (c * range) / 255);
|
||||
};
|
||||
|
||||
return NS_RGBA(lift(rShifted), lift(gShifted), lift(bShifted), a);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the current boost data from the browsing context. When
|
||||
* called without aPresContext, reads the precomputed cache populated on
|
||||
* presshell entry; otherwise resolves from the supplied PresContext.
|
||||
* @brief Whether the given frame belongs to anonymous content that boosts must
|
||||
* not touch (devtools highlighters, screenshots, the boosts overlays
|
||||
* themselves, and other native-anonymous UI such as scrollbars). A null frame
|
||||
* gives no document to anchor the boost on, so it is treated the same way.
|
||||
* Author-facing content that happens to be native-anonymous is not exempt:
|
||||
* UA-widget form-control internals (including the text the user types into an
|
||||
* input), and pseudo-elements such as ::before/::after/::marker/::placeholder.
|
||||
*/
|
||||
ZEN_HOT_FUNCTION
|
||||
inline static void GetZenBoostsDataFromBrowsingContext(
|
||||
ZenBoostData* aData, float* aComplementaryRotation, bool* aIsInverted,
|
||||
nsPresContext* aPresContext = nullptr) {
|
||||
auto zenBoosts = nsZenBoostsBackend::GetInstance();
|
||||
if (!zenBoosts || (zenBoosts->mCurrentFrameIsAnonymousContent &&
|
||||
!SHOULD_APPLY_BOOSTS_TO_ANONYMOUS_CONTENT())) {
|
||||
inline static bool IsBoostExemptFrame(const nsIFrame* aFrame) {
|
||||
if (!aFrame) {
|
||||
return true;
|
||||
}
|
||||
const nsIContent* content = aFrame->GetContent();
|
||||
if (!content || !content->IsInNativeAnonymousSubtree()) {
|
||||
return false;
|
||||
}
|
||||
// Form-control internals (and media controls) live in UA-widget shadow
|
||||
// trees; the text typed into an input is author content and should be
|
||||
// boosted. Classic native-anonymous UI (scrollbars, devtools) has no
|
||||
// containing shadow and falls through to the pseudo-element check below.
|
||||
if (content->GetContainingShadow()) {
|
||||
return false;
|
||||
}
|
||||
const nsIContent* root = content->GetClosestNativeAnonymousSubtreeRoot();
|
||||
return !root || !root->IsElement() ||
|
||||
!mozilla::PseudoStyle::IsPseudoElement(
|
||||
root->AsElement()->GetPseudoElementType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the boost data for the document the given frame belongs to.
|
||||
* Resolves from the frame's PresContext -> Document -> top BrowsingContext,
|
||||
* which carries the accent/inversion fields.
|
||||
*/
|
||||
ZEN_HOT_FUNCTION
|
||||
inline static void GetZenBoostsDataForFrame(const nsIFrame* aFrame,
|
||||
ZenBoostData* aData,
|
||||
float* aComplementaryRotation,
|
||||
bool* aIsInverted) {
|
||||
nsPresContext* presContext = aFrame->PresContext();
|
||||
if (!presContext) {
|
||||
return;
|
||||
}
|
||||
if (!aPresContext) {
|
||||
*aData = zenBoosts->mCachedCurrentAccent;
|
||||
*aComplementaryRotation = zenBoosts->mCachedCurrentComplementaryRotation;
|
||||
*aIsInverted = zenBoosts->mCachedCurrentInverted;
|
||||
// SVG images render in their own document with no BrowsingContext; the host
|
||||
// propagates its boost onto the image document's PresContext instead.
|
||||
if (presContext->HasZenBoostsOverride()) {
|
||||
*aData = presContext->ZenBoostsOverrideAccent();
|
||||
*aComplementaryRotation =
|
||||
presContext->ZenBoostsOverrideComplementaryRotation();
|
||||
*aIsInverted = presContext->ZenBoostsOverrideInverted();
|
||||
return;
|
||||
}
|
||||
mozilla::dom::BrowsingContext* browsingContext = nullptr;
|
||||
if (auto document = aPresContext->Document()) {
|
||||
const mozilla::dom::BrowsingContext* browsingContext = nullptr;
|
||||
if (auto document = presContext->Document()) {
|
||||
browsingContext = document->GetBrowsingContext();
|
||||
}
|
||||
if (!browsingContext) {
|
||||
@@ -347,6 +450,32 @@ inline static void GetZenBoostsDataFromBrowsingContext(
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Thin forwarders that give unit tests access to the pure color math without
|
||||
// pulling in the singleton / BrowsingContext. They are defined here, after the
|
||||
// anonymous namespace, so they can reach those file-local implementations.
|
||||
nsZenAccentOklab PrecomputeAccent(nscolor aAccentColor) {
|
||||
return zenPrecomputeAccent(aAccentColor);
|
||||
}
|
||||
|
||||
nsZenAccentOklab RotateAccent(const nsZenAccentOklab& aBase,
|
||||
float aRotationDeg) {
|
||||
return zenRotateAccent(aBase, aRotationDeg);
|
||||
}
|
||||
|
||||
nscolor FilterColorChannel(nscolor aOriginalColor,
|
||||
const nsZenAccentOklab& aAccent,
|
||||
const nsZenAccentOklab& aComplementary) {
|
||||
return zenFilterColorChannel(aOriginalColor, aAccent, aComplementary);
|
||||
}
|
||||
|
||||
nscolor InvertColorChannel(nscolor aColor) {
|
||||
return zenInvertColorChannel(aColor);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
static mozilla::StaticRefPtr<nsZenBoostsBackend> sZenBoostsBackend;
|
||||
|
||||
auto nsZenBoostsBackend::GetInstance() -> nsZenBoostsBackend* {
|
||||
@@ -362,68 +491,34 @@ auto nsZenBoostsBackend::GetInstance() -> nsZenBoostsBackend* {
|
||||
return sZenBoostsBackend.get();
|
||||
}
|
||||
|
||||
auto nsZenBoostsBackend::onPresShellEntered(mozilla::dom::Document* aDocument)
|
||||
-> void {
|
||||
if (auto displayDoc = aDocument->GetDisplayDocument()) {
|
||||
onPresShellEntered(displayDoc);
|
||||
return;
|
||||
[[nodiscard]] ZEN_HOT_FUNCTION auto nsZenBoostsBackend::ResolveStyleColor(
|
||||
nscolor aColor, const nsIFrame* aFrame) -> nscolor {
|
||||
if (NS_GET_A(aColor) == 0) {
|
||||
// Skip processing fully transparent colors since they won't be visible and
|
||||
// we want to avoid unnecessary computations. This also prevents issues with
|
||||
// using the alpha channel for contrast information in the accent color.
|
||||
return aColor;
|
||||
}
|
||||
// Note that aDocument can be null when entering anonymous content frames.
|
||||
// We explicitly do this to prevent applying boosts to anonymous content, such
|
||||
// as devtools or screenshots.
|
||||
mozilla::dom::BrowsingContext* browsingContext =
|
||||
aDocument ? aDocument->GetBrowsingContext() : nullptr;
|
||||
if (!browsingContext) {
|
||||
return;
|
||||
// Boosts are only supported in content; GetInstance() is null in the parent
|
||||
// process, which keeps the browser chrome from being tinted.
|
||||
if (!GetInstance() || IsBoostExemptFrame(aFrame)) {
|
||||
return aColor;
|
||||
}
|
||||
mCurrentBrowsingContext = browsingContext;
|
||||
RefreshCachedBoostState();
|
||||
}
|
||||
|
||||
auto nsZenBoostsBackend::RefreshCachedBoostState() -> void {
|
||||
if (!mCurrentBrowsingContext) {
|
||||
mCachedCurrentAccent = 0;
|
||||
mCachedCurrentComplementaryRotation = 0.0f;
|
||||
mCachedCurrentInverted = false;
|
||||
return;
|
||||
}
|
||||
auto top = mCurrentBrowsingContext->Top();
|
||||
mCachedCurrentAccent = top->ZenBoostsData();
|
||||
mCachedCurrentComplementaryRotation = top->ZenBoostsComplementaryRotation();
|
||||
mCachedCurrentInverted = top->IsZenBoostsInverted();
|
||||
}
|
||||
|
||||
[[nodiscard]] ZEN_HOT_FUNCTION auto
|
||||
nsZenBoostsBackend::FilterColorFromPresContext(nscolor aColor,
|
||||
nsPresContext* aPresContext)
|
||||
-> nscolor {
|
||||
ZenBoostData accentNS = 0;
|
||||
float complementaryRotation = 0.0f;
|
||||
bool invertColors = false;
|
||||
GetZenBoostsDataFromBrowsingContext(&accentNS, &complementaryRotation,
|
||||
&invertColors, aPresContext);
|
||||
GetZenBoostsDataForFrame(aFrame, &accentNS, &complementaryRotation,
|
||||
&invertColors);
|
||||
if (accentNS) {
|
||||
if (mCachedAccent.accentNS != accentNS) {
|
||||
mCachedAccent = zenPrecomputeAccent(accentNS);
|
||||
// Trigger a recompute of the complementary accent since
|
||||
// it depends on the base accent.
|
||||
mCachedComplementary.accentNS = 0;
|
||||
}
|
||||
// Derive the complementary accent by rotating the base accent's hue by the
|
||||
// boost's complementary rotation. Cached so the per-color hot path only
|
||||
// recomputes it when the base accent or rotation changes.
|
||||
if (mCachedComplementary.accentNS != accentNS ||
|
||||
mCachedComplementaryRotationDeg != complementaryRotation) {
|
||||
mCachedComplementary =
|
||||
zenRotateAccent(mCachedAccent, complementaryRotation);
|
||||
mCachedComplementaryRotationDeg = complementaryRotation;
|
||||
}
|
||||
// Apply a filter-like tint:
|
||||
// Resolve (and cache) the base + complementary accent for this accent and
|
||||
// complementary rotation. Apply a filter-like tint:
|
||||
// - Preserve the original color's perceived luminance
|
||||
// - Map hue/chroma toward the base or complementary accent depending on
|
||||
// the original color's lightness
|
||||
// - Keep the original alpha
|
||||
aColor = zenFilterColorChannel(aColor, mCachedAccent, mCachedComplementary);
|
||||
const AccentCacheEntry& cached =
|
||||
GetCachedAccent(accentNS, complementaryRotation);
|
||||
aColor = zenFilterColorChannel(aColor, cached.accent, cached.complementary);
|
||||
}
|
||||
if (invertColors) {
|
||||
aColor = zenInvertColorChannel(aColor);
|
||||
@@ -431,21 +526,4 @@ nsZenBoostsBackend::FilterColorFromPresContext(nscolor aColor,
|
||||
return aColor;
|
||||
}
|
||||
|
||||
[[nodiscard]] ZEN_HOT_FUNCTION auto nsZenBoostsBackend::ResolveStyleColor(
|
||||
mozilla::StyleAbsoluteColor aColor) -> mozilla::StyleAbsoluteColor {
|
||||
const auto resultColor = FilterColorFromPresContext(aColor.ToColor());
|
||||
return mozilla::StyleAbsoluteColor::FromColor(resultColor);
|
||||
}
|
||||
|
||||
[[nodiscard]] ZEN_HOT_FUNCTION auto nsZenBoostsBackend::ResolveStyleColor(
|
||||
nscolor aColor) -> nscolor {
|
||||
if (NS_GET_A(aColor) == 0) {
|
||||
// Skip processing fully transparent colors since they won't be visible and
|
||||
// we want to avoid unnecessary computations. This also prevents issues with
|
||||
// using the alpha channel for contrast information in the accent color.
|
||||
return aColor;
|
||||
}
|
||||
return FilterColorFromPresContext(aColor);
|
||||
}
|
||||
|
||||
} // namespace zen
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsPresContext.h"
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
class nsIFrame;
|
||||
|
||||
namespace mozilla::dom {
|
||||
class BrowsingContext;
|
||||
}
|
||||
|
||||
#define ZEN_BOOSTS_BACKEND_CONTRACTID "@mozilla.org/zen/boosts-backend;1"
|
||||
|
||||
@@ -23,6 +27,19 @@ struct nsZenAccentOklab {
|
||||
float contrastFactor;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
// Pure color-math primitives, exposed for unit testing. These have no
|
||||
// dependency on the singleton, the BrowsingContext, or the process type, so
|
||||
// they can be exercised directly from gtest.
|
||||
nsZenAccentOklab PrecomputeAccent(nscolor aAccentColor);
|
||||
nsZenAccentOklab RotateAccent(const nsZenAccentOklab& aBase,
|
||||
float aRotationDeg);
|
||||
nscolor FilterColorChannel(nscolor aOriginalColor,
|
||||
const nsZenAccentOklab& aAccent,
|
||||
const nsZenAccentOklab& aComplementary);
|
||||
nscolor InvertColorChannel(nscolor aColor);
|
||||
} // namespace detail
|
||||
|
||||
class nsZenBoostsBackend final : public nsISupports {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@@ -30,81 +47,28 @@ class nsZenBoostsBackend final : public nsISupports {
|
||||
explicit nsZenBoostsBackend() = default;
|
||||
|
||||
/**
|
||||
* Indicates whether the current frame being rendered is for anonymous
|
||||
* content.
|
||||
*/
|
||||
bool mCurrentFrameIsAnonymousContent = false;
|
||||
|
||||
/**
|
||||
* @brief Resolve a StyleAbsoluteColor to take into account Zen boosts.
|
||||
* @brief Resolve a color to take into account Zen boosts. This is the single
|
||||
* place style colors are filtered; it is reached for every style color via
|
||||
* StyleAbsoluteColor::ToColor. Do not add a second StyleColor::ResolveColor
|
||||
* filter on top of this or colors get filtered multiple times (which also
|
||||
* makes resting colors disagree with composited transition endpoints).
|
||||
*
|
||||
* The boost state is derived from the frame the color is being resolved for:
|
||||
* its document's top BrowsingContext carries the accent/inversion data. When
|
||||
* @p aFrame is null, or belongs to anonymous content (devtools, screenshots,
|
||||
* the boosts overlays themselves), the color is returned unfiltered.
|
||||
* @param aColor The color to resolve.
|
||||
* @param aFrame The frame the color is being resolved for, or null.
|
||||
* @return The resolved color with Zen boost filters applied, or the original
|
||||
* color if no boost is active.
|
||||
* @see StyleColor::ResolveColor for reference.
|
||||
* @see StyleAbsoluteColor::ToColor for reference.
|
||||
*/
|
||||
static auto ResolveStyleColor(mozilla::StyleAbsoluteColor aColor)
|
||||
-> mozilla::StyleAbsoluteColor;
|
||||
|
||||
/**
|
||||
* @see ResolveStyleColor for reference.
|
||||
*/
|
||||
static auto ResolveStyleColor(nscolor aColor) -> nscolor;
|
||||
|
||||
/**
|
||||
* @brief Filter a color based on the current Zen boost settings.
|
||||
* @param aColor The color to filter.
|
||||
* @param aPresContext The presentation context to use for filtering.
|
||||
* @return The filtered color.
|
||||
*/
|
||||
static auto FilterColorFromPresContext(nscolor aColor,
|
||||
nsPresContext* aPresContext = nullptr)
|
||||
static auto ResolveStyleColor(nscolor aColor, const nsIFrame* aFrame)
|
||||
-> nscolor;
|
||||
|
||||
/**
|
||||
* @brief Called when a presshell is entered during rendering.
|
||||
* @param aDocument The document associated with the presshell being entered.
|
||||
*/
|
||||
auto onPresShellEntered(mozilla::dom::Document* aDocument) -> void;
|
||||
|
||||
/**
|
||||
* @brief Refresh the cached boost state from the current top BrowsingContext.
|
||||
* Called from onPresShellEntered and from BrowsingContext::DidSet hooks when
|
||||
* the underlying boost fields change.
|
||||
*/
|
||||
auto RefreshCachedBoostState() -> void;
|
||||
|
||||
[[nodiscard]]
|
||||
inline auto GetCurrentBrowsingContext() const {
|
||||
return mCurrentBrowsingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached boost data for the current top BrowsingContext, refreshed on
|
||||
* presshell entry and on DidSet hooks. Read by the per-color hot path so
|
||||
* that boost-off pages don't pay for a BrowsingContext walk on every color
|
||||
* resolve.
|
||||
*/
|
||||
ZenBoostData mCachedCurrentAccent = 0;
|
||||
// Hue rotation in degrees applied to the base accent to derive the
|
||||
// complementary accent. Zero means the complementary accent equals the base
|
||||
// accent (the duotone collapses to a single-accent tint).
|
||||
float mCachedCurrentComplementaryRotation = 0.0f;
|
||||
bool mCachedCurrentInverted = false;
|
||||
|
||||
private:
|
||||
~nsZenBoostsBackend() = default;
|
||||
|
||||
/**
|
||||
* The presshell of the current document being rendered.
|
||||
*/
|
||||
RefPtr<mozilla::dom::BrowsingContext> mCurrentBrowsingContext;
|
||||
|
||||
static nsZenAccentOklab mCachedAccent;
|
||||
// Base accent with its Oklab hue rotated by mCachedComplementaryRotationDeg,
|
||||
// recomputed only when the base accent or rotation changes.
|
||||
static nsZenAccentOklab mCachedComplementary;
|
||||
static float mCachedComplementaryRotationDeg;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Get the singleton instance of the ZenBoostsBackend.
|
||||
|
||||
@@ -132,18 +132,18 @@
|
||||
<html:input id="zen-boost-color-saturation" type="range" min="0" max="1" value="0.5" step="0.01"/>
|
||||
</vbox>
|
||||
</panel>
|
||||
</popupset>
|
||||
|
||||
<menupopup id="zenBoostContextMenu">
|
||||
<menuitem data-l10n-id="zen-boost-edit-rename" id="zen-boost-edit-rename" command="cmd_zenBoostEditName" />
|
||||
<menuitem data-l10n-id="zen-boost-edit-shuffle" id="zen-boost-edit-shuffle" command="cmd_zenBoostShuffle" />
|
||||
<menuitem data-l10n-id="zen-boost-edit-reset" id="zen-boost-edit-reset" command="cmd_zenBoostReset" />
|
||||
<menuseparator/>
|
||||
<menuitem data-l10n-id="zen-boost-load" id="zen-boost-load" command="cmd_zenBoostLoad" />
|
||||
<menuitem data-l10n-id="zen-boost-save" id="zen-boost-save" command="cmd_zenBoostSave" />
|
||||
<menuseparator/>
|
||||
<menuitem data-l10n-id="zen-boost-edit-delete" id="zen-boost-edit-delete" command="cmd_zenBoostDelete" />
|
||||
</menupopup>
|
||||
<menupopup id="zenBoostContextMenu">
|
||||
<menuitem data-l10n-id="zen-boost-edit-rename" id="zen-boost-edit-rename" command="cmd_zenBoostEditName" />
|
||||
<menuitem data-l10n-id="zen-boost-edit-shuffle" id="zen-boost-edit-shuffle" command="cmd_zenBoostShuffle" />
|
||||
<menuitem data-l10n-id="zen-boost-edit-reset" id="zen-boost-edit-reset" command="cmd_zenBoostReset" />
|
||||
<menuseparator/>
|
||||
<menuitem data-l10n-id="zen-boost-load" id="zen-boost-load" command="cmd_zenBoostLoad" />
|
||||
<menuitem data-l10n-id="zen-boost-save" id="zen-boost-save" command="cmd_zenBoostSave" />
|
||||
<menuseparator/>
|
||||
<menuitem data-l10n-id="zen-boost-edit-delete" id="zen-boost-edit-delete" command="cmd_zenBoostDelete" />
|
||||
</menupopup>
|
||||
</popupset>
|
||||
|
||||
<commandset id="zenBoostCommandSet">
|
||||
<command id="cmd_zenBoostEditName"
|
||||
|
||||
@@ -11,6 +11,19 @@
|
||||
}
|
||||
appearance: none;
|
||||
border: none;
|
||||
|
||||
min-height: 582px;
|
||||
max-height: 582px;
|
||||
}
|
||||
|
||||
#zenBoostWindow[editor="boost"] {
|
||||
min-width: 184px;
|
||||
max-width: 184px;
|
||||
}
|
||||
|
||||
#zenBoostWindow[editor="code"] {
|
||||
min-width: 452px;
|
||||
max-width: 452px;
|
||||
}
|
||||
|
||||
.source-editor-frame {
|
||||
@@ -106,9 +119,6 @@ body {
|
||||
|
||||
& button {
|
||||
border-radius: 6px;
|
||||
@media (-moz-platform: macos) {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
padding: 0 !important;
|
||||
min-width: fit-content !important;
|
||||
@@ -229,9 +239,9 @@ body {
|
||||
}
|
||||
|
||||
#zen-boost-filter-wrapper {
|
||||
padding: 20px;
|
||||
padding: 16px;
|
||||
gap: 14px;
|
||||
padding-top: 10px;
|
||||
padding-top: 6px;
|
||||
|
||||
background-color: #fcfcfe;
|
||||
|
||||
@@ -543,6 +553,7 @@ body {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
transform-origin: center center;
|
||||
aspect-ratio: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: #9a9a9a30;
|
||||
|
||||
@@ -1358,6 +1358,7 @@ window.gZenVerticalTabsManager = {
|
||||
if (!this._hasSetSingleToolbar) {
|
||||
buttonsTarget.append(this._topButtonsSeparatorElement);
|
||||
}
|
||||
this._hasSetSingleToolbar = true;
|
||||
for (const button of elements) {
|
||||
this.appendCustomizableItem(this._topButtonsSeparatorElement, button);
|
||||
}
|
||||
@@ -1381,7 +1382,6 @@ window.gZenVerticalTabsManager = {
|
||||
titlebar.parentNode.moveBefore(navBar, titlebar);
|
||||
}
|
||||
document.documentElement.setAttribute("zen-single-toolbar", true);
|
||||
this._hasSetSingleToolbar = true;
|
||||
} else if (this._hasSetSingleToolbar) {
|
||||
this._hasSetSingleToolbar = false;
|
||||
// Do the opposite
|
||||
@@ -1510,7 +1510,7 @@ window.gZenVerticalTabsManager = {
|
||||
this.navigatorToolbox.after(splitter);
|
||||
window.dispatchEvent(new Event("resize"));
|
||||
if (!isCompactMode) {
|
||||
gZenCompactModeManager.getAndApplySidebarWidth();
|
||||
gZenCompactModeManager.getAndApplySidebarWidth({});
|
||||
}
|
||||
gZenUIManager.updateTabsToolbar();
|
||||
this.rebuildURLBarMenus();
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
@import url("chrome://browser/content/zen-styles/zen-panels/dialog.css");
|
||||
|
||||
:root {
|
||||
--panel-subview-body-padding: 2px 0;
|
||||
--arrowpanel-menuitem-border-radius: 5px;
|
||||
--arrowpanel-menuitem-margin: var(--uc-arrowpanel-menuitem-margin-block) var(--uc-arrowpanel-menuitem-margin-inline);
|
||||
--arrowpanel-menuitem-padding-block: 8px;
|
||||
@@ -68,8 +67,7 @@ panel {
|
||||
}
|
||||
|
||||
.widget-overflow-list .toolbarbutton-1:not(.toolbarbutton-combined) > .toolbarbutton-text,
|
||||
.subviewbutton:not(#appMenu-zoom-controls > .subviewbutton) > .toolbarbutton-icon + .toolbarbutton-text,
|
||||
#appMenu-fxa-label2 > vbox {
|
||||
.subviewbutton:not(#appMenu-zoom-controls > .subviewbutton) > .toolbarbutton-icon + .toolbarbutton-text {
|
||||
padding-inline-start: var(--uc-arrowpanel-menuicon-margin-inline);
|
||||
}
|
||||
|
||||
@@ -88,17 +86,6 @@ panel {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Firefox profile avatar in appmenu */
|
||||
#appMenu-fxa-label2::before {
|
||||
content: "";
|
||||
display: -moz-box;
|
||||
height: var(--size-item-small);
|
||||
width: var(--size-item-small);
|
||||
background: var(--avatar-image-url) 0/16px;
|
||||
scale: 1.25;
|
||||
border-radius: 99px;
|
||||
}
|
||||
|
||||
/* disable proton account separator */
|
||||
#appMenu-fxa-separator {
|
||||
border-image: none;
|
||||
@@ -108,10 +95,6 @@ panel {
|
||||
padding-block: 0;
|
||||
}
|
||||
|
||||
#appMenu-fxa-status2:not([fxastatus]) > #appMenu-fxa-label2 {
|
||||
margin-inline-end: calc(var(--arrowpanel-menuitem-padding-inline) * -1);
|
||||
}
|
||||
|
||||
/* zoom controls */
|
||||
#appMenu-zoom-controls {
|
||||
border-top: 1px solid var(--panel-separator-color);
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
--toolbarbutton-hover-background: var(--zen-toolbar-element-bg-hover) !important;
|
||||
--zen-toolbar-button-size: 16px;
|
||||
@media (-moz-platform: macos) {
|
||||
--zen-toolbar-button-size: 18px;
|
||||
--zen-toolbar-button-size: 17px;
|
||||
}
|
||||
|
||||
/* Using a semitransparent background preserves the tinting from the backdrop.
|
||||
|
||||
@@ -67,8 +67,9 @@ if (!Services.appinfo.inSafeMode) {
|
||||
child: {
|
||||
esModuleURI: "resource:///actors/ZenBoostsChild.sys.mjs",
|
||||
events: {
|
||||
// Needed to let the actor be created, please don't remove
|
||||
// without checking if boosts still work without it, thanks <3
|
||||
DOMWindowCreated: {},
|
||||
unload: {},
|
||||
},
|
||||
},
|
||||
allFrames: true,
|
||||
|
||||
@@ -169,7 +169,15 @@
|
||||
} else {
|
||||
document.documentElement.removeAttribute("zen-no-padding");
|
||||
if (domFullscreen) {
|
||||
window.windowUtils.flushLayoutWithoutThrottledAnimations();
|
||||
const selectedBrowser = gBrowser.selectedBrowser;
|
||||
selectedBrowser.style.paddingRight = "0.5px";
|
||||
window.addEventListener(
|
||||
"MozAfterPaint",
|
||||
() => {
|
||||
selectedBrowser.style.paddingRight = "";
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -724,6 +724,7 @@ window.gZenCompactModeManager = {
|
||||
} else {
|
||||
if (attr === "zen-has-hover") {
|
||||
element.removeAttribute("zen-has-implicit-hover");
|
||||
gURLBar.updateTextOverflow();
|
||||
}
|
||||
element.removeAttribute(attr);
|
||||
// Only remove if none of the verified attributes are present
|
||||
|
||||
@@ -725,7 +725,7 @@
|
||||
.changeWorkspaceShortcut(
|
||||
isNearLeftEdge ? -1 : 1,
|
||||
false,
|
||||
/* Disable wrapping */ true
|
||||
/* Disable wrapping */ false
|
||||
)
|
||||
.then(spaceChanged => {
|
||||
this.#onSpaceChanged(spaceChanged, dt);
|
||||
|
||||
@@ -1566,7 +1566,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
|
||||
const tabsContainer = group.groupContainer;
|
||||
tabsContainer.removeAttribute("hidden");
|
||||
tabsContainer.style.overflow = "hidden";
|
||||
tabsContainer.style.overflowY = "hidden";
|
||||
|
||||
const groupStart = group.groupStartElement;
|
||||
const itemsToShow = this.#normalizeGroupItems(group.childGroupsAndTabs);
|
||||
@@ -1615,7 +1615,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
|
||||
const afterMarginTop = () => {
|
||||
tabsContainer.style.overflow = "";
|
||||
tabsContainer.style.overflowY = "";
|
||||
if (group.hasAttribute("has-active")) {
|
||||
const activeTabs = group.activeTabs;
|
||||
const folders = new Map();
|
||||
@@ -1859,14 +1859,14 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
|
||||
const tabsContainer = currentGroup.groupContainer;
|
||||
const groupStart = currentGroup.groupStartElement;
|
||||
tabsContainer.style.overflow = "clip";
|
||||
tabsContainer.style.overflowY = "clip";
|
||||
|
||||
if (tabsContainer.hasAttribute("hidden")) {
|
||||
tabsContainer.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
const afterMarginTop = () => {
|
||||
tabsContainer.style.overflow = "";
|
||||
tabsContainer.style.overflowY = "";
|
||||
};
|
||||
|
||||
animations.push(
|
||||
@@ -1972,7 +1972,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
const heightContainer = expand
|
||||
? 0
|
||||
: this.#calculateHeightShift(tabsContainer, []);
|
||||
tabsContainer.style.overflow = "clip";
|
||||
tabsContainer.style.overflowY = "clip";
|
||||
|
||||
this.#createAnimation(
|
||||
groupStart,
|
||||
|
||||
@@ -35,7 +35,7 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
// Arc animation configuration
|
||||
#ARC_CONFIG = Object.freeze({
|
||||
ARC_STEPS: 80, // Browser interpolates between keyframes natively
|
||||
MAX_ARC_HEIGHT: 25,
|
||||
MAX_ARC_HEIGHT: 20,
|
||||
ARC_HEIGHT_RATIO: 0.2, // Arc height = distance * ratio (capped at MAX_ARC_HEIGHT)
|
||||
});
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ const KEYCODE_MAP = {
|
||||
TAB: "VK_TAB",
|
||||
ENTER: "VK_RETURN",
|
||||
ESCAPE: "VK_ESCAPE",
|
||||
SPACE: "VK_SPACE",
|
||||
ARROWLEFT: "VK_LEFT",
|
||||
ARROWRIGHT: "VK_RIGHT",
|
||||
ARROWUP: "VK_UP",
|
||||
@@ -44,6 +43,10 @@ const KEYCODE_MAP = {
|
||||
SCROLL_LOCK: "VK_SCROLL",
|
||||
};
|
||||
|
||||
const REVERSE_KEYCODE_MAP = Object.fromEntries(
|
||||
Object.entries(KEYCODE_MAP).map(([k, v]) => [v, k])
|
||||
);
|
||||
|
||||
const defaultKeyboardGroups = {
|
||||
windowAndTabManagement: [
|
||||
"zen-window-new-shortcut",
|
||||
@@ -430,11 +433,14 @@ class KeyShortcut {
|
||||
if (this.#keycode) {
|
||||
key.setAttribute("keycode", this.#keycode);
|
||||
key.removeAttribute("key");
|
||||
} else {
|
||||
} else if (this.#key) {
|
||||
// note to "mr. macos": Better use setAttribute, because without it, there's a
|
||||
// risk of malforming the XUL element.
|
||||
key.setAttribute("key", this.#key);
|
||||
key.removeAttribute("keycode");
|
||||
} else {
|
||||
key.removeAttribute("key");
|
||||
key.removeAttribute("keycode");
|
||||
}
|
||||
key.setAttribute("group", this.#group);
|
||||
|
||||
@@ -553,16 +559,21 @@ class KeyShortcut {
|
||||
};
|
||||
}
|
||||
|
||||
toDisplayString() {
|
||||
let str = this.#modifiers.toDisplayString();
|
||||
|
||||
if (this.#key) {
|
||||
str += this.#key.toUpperCase();
|
||||
} else if (this.#keycode) {
|
||||
static keyToDisplayString(key, keycode) {
|
||||
let str = "";
|
||||
if (key) {
|
||||
switch (key) {
|
||||
case " ":
|
||||
str += AppConstants.platform == "macosx" ? "␣" : "Space";
|
||||
break;
|
||||
default:
|
||||
str += key.toUpperCase();
|
||||
}
|
||||
} else if (keycode) {
|
||||
// Get the key from the value
|
||||
for (let [key, value] of Object.entries(KEYCODE_MAP)) {
|
||||
if (value == this.#keycode) {
|
||||
const normalizedKey = key.toLowerCase();
|
||||
for (let [k, value] of Object.entries(KEYCODE_MAP)) {
|
||||
if (value == keycode) {
|
||||
const normalizedKey = k.toLowerCase();
|
||||
switch (normalizedKey) {
|
||||
case "arrowleft":
|
||||
str += "←";
|
||||
@@ -582,18 +593,23 @@ class KeyShortcut {
|
||||
case "enter":
|
||||
str += AppConstants.platform == "macosx" ? "↩" : "Enter";
|
||||
break;
|
||||
case "space":
|
||||
str += AppConstants.platform == "macosx" ? "␣" : "Space";
|
||||
break;
|
||||
default:
|
||||
str += normalizedKey;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
toDisplayString() {
|
||||
if (!this.#key && !this.#keycode) {
|
||||
return "";
|
||||
}
|
||||
|
||||
let str = this.#modifiers.toDisplayString();
|
||||
str += KeyShortcut.keyToDisplayString(this.#key, this.#keycode);
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -832,7 +848,7 @@ class nsZenKeyboardShortcutsLoader {
|
||||
}
|
||||
|
||||
class nsZenKeyboardShortcutsVersioner {
|
||||
static LATEST_KBS_VERSION = 18;
|
||||
static LATEST_KBS_VERSION = 19;
|
||||
|
||||
constructor() {}
|
||||
|
||||
@@ -1228,6 +1244,18 @@ class nsZenKeyboardShortcutsVersioner {
|
||||
);
|
||||
}
|
||||
|
||||
if (version < 19) {
|
||||
// Migrate from version 18 to 19.
|
||||
// Disable "key_duplicateTab" since we already had "cmd_zenDuplicateTab" before Firefox 151.
|
||||
for (let shortcut of data) {
|
||||
if (shortcut.getID() == "key_duplicateTab") {
|
||||
shortcut.shouldBeEmpty = true;
|
||||
shortcut.setDisabled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -1500,9 +1528,11 @@ window.gZenKeyboardShortcutsManager = {
|
||||
continue;
|
||||
}
|
||||
|
||||
const keyNameOrCode = targetShortcut.getKeyNameOrCode();
|
||||
const key = REVERSE_KEYCODE_MAP[keyNameOrCode] ?? keyNameOrCode;
|
||||
if (
|
||||
targetShortcut.getModifiers().equals(modifiers) &&
|
||||
targetShortcut.getKeyNameOrCode()?.toLowerCase() == realShortcut
|
||||
key?.toLowerCase() == realShortcut
|
||||
) {
|
||||
return {
|
||||
hasConflicts: true,
|
||||
@@ -1541,4 +1571,22 @@ window.gZenKeyboardShortcutsManager = {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getKeyDisplay(shortcut) {
|
||||
if (shortcut == "") {
|
||||
return "";
|
||||
}
|
||||
|
||||
let key = shortcut;
|
||||
let keycode = "";
|
||||
for (let kc of Object.keys(KEYCODE_MAP)) {
|
||||
if (kc == shortcut.toUpperCase()) {
|
||||
keycode = KEYCODE_MAP[kc];
|
||||
key = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return KeyShortcut.keyToDisplayString(key, keycode);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1534,7 +1534,14 @@ class nsZenWindowSync {
|
||||
window.removeEventListener(eventName, this);
|
||||
}
|
||||
delete window.gZenWindowSync;
|
||||
this.#moveAllActiveTabsToOtherWindowsForClose(window);
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
this.#docShellSwitchPromise = promise;
|
||||
try {
|
||||
this.#moveAllActiveTabsToOtherWindowsForClose(window);
|
||||
} catch (e) {
|
||||
console.error(`Error moving active tabs to other windows on close:`, e);
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
|
||||
on_WindowCloseAndBrowserFlushed(aBrowsers) {
|
||||
@@ -1657,7 +1664,9 @@ class nsZenWindowSync {
|
||||
this.#runOnAllWindows(window, win => {
|
||||
const targetTab = this.getItemFromWindow(win, tab.id);
|
||||
if (targetTab && win.gZenViewSplitter) {
|
||||
win.gZenViewSplitter.removeTabFromGroup(targetTab);
|
||||
win.gZenViewSplitter.removeTabFromGroup(targetTab, undefined, {
|
||||
changeTab: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ class nsZenWorkspaceCreation extends MozXULElement {
|
||||
document.getElementById("nav-bar").style.visibility = "collapse";
|
||||
}
|
||||
this.style.visibility = "visible";
|
||||
gZenCompactModeManager.getAndApplySidebarWidth();
|
||||
gZenCompactModeManager.getAndApplySidebarWidth({});
|
||||
this.resolveInitialized();
|
||||
let animation = gZenUIManager.motion.animate(
|
||||
this.elementsToAnimate,
|
||||
@@ -261,6 +261,7 @@ class nsZenWorkspaceCreation extends MozXULElement {
|
||||
}
|
||||
|
||||
async onCancelButtonCommand() {
|
||||
document.documentElement.removeAttribute("zen-creating-workspace");
|
||||
await gZenWorkspaces.changeWorkspaceWithID(this.previousWorkspaceId);
|
||||
}
|
||||
|
||||
|
||||
@@ -926,11 +926,7 @@ class nsZenWorkspaces {
|
||||
if (gZenUIManager.testingEnabled || !this.workspaceEnabled) {
|
||||
return;
|
||||
}
|
||||
// note: We cant access `gZenVerticalTabsManager._canReplaceNewTab` this early
|
||||
if (
|
||||
isEmpty &&
|
||||
Services.prefs.getBoolPref("zen.urlbar.replace-newtab", true)
|
||||
) {
|
||||
if (isEmpty) {
|
||||
tab._markedForReplacement = true;
|
||||
this._tabToRemoveForEmpty = tab;
|
||||
} else {
|
||||
@@ -1741,13 +1737,26 @@ class nsZenWorkspaces {
|
||||
const otherContainersEssentials = document.querySelectorAll(
|
||||
`#zen-essentials .zen-workspace-tabs-section`
|
||||
);
|
||||
let nextSpaceIdx;
|
||||
const spaceLen = workspaces.length;
|
||||
if (offsetPixels > 0) {
|
||||
nextSpaceIdx = (workspaceIndex - 1 + spaceLen) % spaceLen;
|
||||
} else if (offsetPixels < 0) {
|
||||
nextSpaceIdx = (workspaceIndex + 1) % spaceLen;
|
||||
} else {
|
||||
nextSpaceIdx = workspaceIndex;
|
||||
}
|
||||
const workspaceContextId = workspace.containerTabId;
|
||||
const nextWorkspaceContextId =
|
||||
workspaces[workspaceIndex + (offsetPixels > 0 ? -1 : 1)]?.containerTabId;
|
||||
const nextWorkspaceContextId = workspaces[nextSpaceIdx]?.containerTabId;
|
||||
for (const otherWorkspace of workspaces) {
|
||||
const element = this.workspaceElement(otherWorkspace.uuid);
|
||||
const newTransform =
|
||||
-(workspaceIndex - workspaces.indexOf(otherWorkspace)) * 100;
|
||||
let diff = workspaces.indexOf(otherWorkspace) - workspaceIndex;
|
||||
if (diff > Math.floor(spaceLen / 2)) {
|
||||
diff -= spaceLen;
|
||||
} else if (diff < -Math.floor(spaceLen / 2)) {
|
||||
diff += spaceLen;
|
||||
}
|
||||
const newTransform = diff * 100;
|
||||
element.style.transform = `translateX(${newTransform + offsetPixels / 2}%)`;
|
||||
}
|
||||
// Hide other essentials with different containerTabId
|
||||
@@ -1781,8 +1790,7 @@ class nsZenWorkspaces {
|
||||
}
|
||||
if (offsetPixels) {
|
||||
// Find the next workspace we are scrolling to
|
||||
const nextWorkspace =
|
||||
workspaces[workspaceIndex + (offsetPixels > 0 ? -1 : 1)];
|
||||
const nextWorkspace = workspaces[nextSpaceIdx];
|
||||
if (nextWorkspace) {
|
||||
const {
|
||||
gradient: nextGradient,
|
||||
@@ -1892,10 +1900,17 @@ class nsZenWorkspaces {
|
||||
this._animatingChange = true;
|
||||
const animations = [];
|
||||
const workspaces = this.getWorkspaces();
|
||||
const spaceLen = workspaces.length;
|
||||
const newWorkspaceIndex = workspaces.findIndex(
|
||||
w => w.uuid === newWorkspace.uuid
|
||||
);
|
||||
const isGoingLeft = newWorkspaceIndex <= previousWorkspaceIndex;
|
||||
let diff = newWorkspaceIndex - previousWorkspaceIndex;
|
||||
if (diff > Math.floor(spaceLen / 2)) {
|
||||
diff -= spaceLen;
|
||||
} else if (diff < -Math.floor(spaceLen / 2)) {
|
||||
diff += spaceLen;
|
||||
}
|
||||
const isGoingLeft = diff < 0;
|
||||
const clonedEssentials = [];
|
||||
if (shouldAnimate && this.shouldAnimateEssentials && previousWorkspace) {
|
||||
for (const workspace of workspaces) {
|
||||
@@ -1974,19 +1989,23 @@ class nsZenWorkspaces {
|
||||
const elementWorkspaceIndex = workspaces.findIndex(
|
||||
w => w.uuid === elementWorkspaceId
|
||||
);
|
||||
const offset = -(newWorkspaceIndex - elementWorkspaceIndex) * 100;
|
||||
let offset = elementWorkspaceIndex - newWorkspaceIndex;
|
||||
if (offset > Math.floor(spaceLen / 2)) {
|
||||
offset -= spaceLen;
|
||||
} else if (offset < -Math.floor(spaceLen / 2)) {
|
||||
offset += spaceLen;
|
||||
}
|
||||
offset = offset * 100;
|
||||
const newTransform = `translateX(${offset}%)`;
|
||||
// Only animate the workspace that is coming in, to avoid having multiple workspaces
|
||||
// animating off-screen at the same time which can cause performance issues. With an off
|
||||
// set of 1 or -1, so we animate the current workspace and the next one.
|
||||
const goingLeft = newWorkspaceIndex < previousWorkspaceIndex;
|
||||
const willBeVisible =
|
||||
(goingLeft &&
|
||||
elementWorkspaceIndex >= newWorkspaceIndex &&
|
||||
elementWorkspaceIndex <= previousWorkspaceIndex) ||
|
||||
(!goingLeft &&
|
||||
elementWorkspaceIndex <= newWorkspaceIndex &&
|
||||
elementWorkspaceIndex >= previousWorkspaceIndex);
|
||||
const totalDistance = Math.abs(diff);
|
||||
const distanceToElement = isGoingLeft
|
||||
? (previousWorkspaceIndex - elementWorkspaceIndex + spaceLen) % spaceLen
|
||||
: (elementWorkspaceIndex - previousWorkspaceIndex + spaceLen) %
|
||||
spaceLen;
|
||||
const willBeVisible = distanceToElement <= totalDistance;
|
||||
if (shouldAnimate) {
|
||||
if (!willBeVisible) {
|
||||
element.style.transform = newTransform;
|
||||
|
||||
@@ -314,6 +314,8 @@
|
||||
|
||||
/* mark: workspace element */
|
||||
zen-workspace {
|
||||
--toolbar-color: var(--toolbox-textcolor) !important;
|
||||
|
||||
flex-direction: column;
|
||||
width: calc(100% + var(--zen-toolbox-padding) * 2);
|
||||
position: absolute;
|
||||
|
||||
@@ -2294,7 +2294,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
// Unsplit the tab and exit from the drag view
|
||||
this.dropZone?.removeAttribute("enabled");
|
||||
this.disableTabRearrangeView(event);
|
||||
this.removeTabFromSplit(browserContainer);
|
||||
this.removeTabFromSplit(event, browserContainer);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -702,6 +702,10 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
return tab;
|
||||
});
|
||||
if (!fromDifferentWindow) {
|
||||
// See gh-13796 and gh-12156
|
||||
ownedTabs = ownedTabs.reverse();
|
||||
}
|
||||
movingTabs = [...ownedTabs];
|
||||
if (fromDifferentWindow) {
|
||||
gBrowser.addRangeToMultiSelectedTabs(
|
||||
|
||||
@@ -8,5 +8,6 @@ support-files = [
|
||||
]
|
||||
|
||||
["browser_boost_selector_basic.js"]
|
||||
["browser_boost_selector_escaping.js"]
|
||||
["browser_boost_selector_invalid.js"]
|
||||
["browser_boost_selector_nthchild.js"]
|
||||
|
||||
94
src/zen/tests/boosts/browser_boost_selector_escaping.js
Normal file
94
src/zen/tests/boosts/browser_boost_selector_escaping.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Covers code paths the basic/invalid/nthchild tests don't:
|
||||
// - getIdentification() running ids/classes through CSS.escape()
|
||||
// - the ancestor-disambiguation while-loop in traverse(), which only runs
|
||||
// when the exact path still matches more than one element.
|
||||
|
||||
add_task(async function test_getSelectionPath_escapesSpecialChars() {
|
||||
const doc = document.implementation.createHTMLDocument("TestEscape");
|
||||
|
||||
const container = doc.createElement("div");
|
||||
// Characters that are invalid in a CSS selector unless escaped.
|
||||
container.id = "with.dot:and#hash";
|
||||
const target = doc.createElement("span");
|
||||
target.className = "foo:bar baz.qux";
|
||||
target.textContent = "target";
|
||||
container.appendChild(target);
|
||||
doc.body.appendChild(container);
|
||||
|
||||
const component = new SelectorComponent(doc, null, [], () => {});
|
||||
|
||||
const path = component.getSelectionPath(doc, 0, target);
|
||||
ok(path, "A path should be generated for an element with special chars");
|
||||
|
||||
// The unescaped raw strings must not leak into the selector verbatim.
|
||||
ok(
|
||||
!path.includes("with.dot:and#hash"),
|
||||
"Raw unescaped id must not appear in the selector"
|
||||
);
|
||||
|
||||
// The generated selector must be valid and resolve back to the target.
|
||||
let matched;
|
||||
try {
|
||||
matched = doc.querySelectorAll(path);
|
||||
} catch (e) {
|
||||
ok(false, `Generated selector should be parseable, got: ${e}`);
|
||||
return;
|
||||
}
|
||||
ok(
|
||||
Array.from(matched).includes(target),
|
||||
"Escaped selector must still match the original element"
|
||||
);
|
||||
Assert.equal(
|
||||
matched.length,
|
||||
1,
|
||||
"Selector should uniquely identify the element"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_getSelectionPath_disambiguatesAncestors() {
|
||||
const doc = document.implementation.createHTMLDocument("TestAncestors");
|
||||
|
||||
// Two structurally identical subtrees. The leaf elements carry no id/class,
|
||||
// so disambiguation must climb ancestors until the path is unique. The two
|
||||
// wrappers differ only by id, forcing the ancestor-walk loop in traverse().
|
||||
const makeBranch = wrapperId => {
|
||||
const wrapper = doc.createElement("section");
|
||||
wrapper.id = wrapperId;
|
||||
const mid = doc.createElement("div");
|
||||
const leaf = doc.createElement("span");
|
||||
leaf.textContent = "leaf";
|
||||
mid.appendChild(leaf);
|
||||
wrapper.appendChild(mid);
|
||||
doc.body.appendChild(wrapper);
|
||||
return leaf;
|
||||
};
|
||||
|
||||
const leafA = makeBranch("branch-a");
|
||||
const leafB = makeBranch("branch-b");
|
||||
|
||||
const component = new SelectorComponent(doc, null, [], () => {});
|
||||
|
||||
for (const [leaf, label] of [
|
||||
[leafA, "branch-a"],
|
||||
[leafB, "branch-b"],
|
||||
]) {
|
||||
const path = component.getSelectionPath(doc, 0, leaf);
|
||||
ok(path, `Path generated for the leaf under ${label}`);
|
||||
|
||||
const matched = doc.querySelectorAll(path);
|
||||
Assert.equal(
|
||||
matched.length,
|
||||
1,
|
||||
`Selector for the ${label} leaf must be unique despite an identical sibling subtree`
|
||||
);
|
||||
ok(
|
||||
matched[0] === leaf,
|
||||
`Selector must resolve to the correct ${label} leaf, not the other branch`
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -81,6 +81,49 @@ const globalActionsTemplate = [
|
||||
return !tab.hasAttribute("zen-empty-tab") && tab.pinned;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "New Boost",
|
||||
icon: "chrome://browser/skin/zen-icons/boost.svg",
|
||||
isAvailable: window => {
|
||||
if (!isNotEmptyTab(window)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keep this action consistent with the rest of the Boosts UI.
|
||||
if (!Services.prefs.getBoolPref("zen.boosts.enabled", false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uri = window.gBrowser.currentURI;
|
||||
return !!uri?.schemeIs && (uri.schemeIs("http") || uri.schemeIs("https"));
|
||||
},
|
||||
command: window => {
|
||||
const uri = window.gBrowser.currentURI;
|
||||
if (!uri?.schemeIs || !(uri.schemeIs("http") || uri.schemeIs("https"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
let domain = "";
|
||||
try {
|
||||
domain = uri.host;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!domain) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { gZenBoostsManager } = ChromeUtils.importESModule(
|
||||
"resource:///modules/zen/boosts/ZenBoostsManager.sys.mjs"
|
||||
);
|
||||
const boost = gZenBoostsManager.createNewBoost(domain);
|
||||
if (!boost) {
|
||||
return;
|
||||
}
|
||||
gZenBoostsManager.openBoostWindow(window, boost, uri);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Next Space",
|
||||
command: "cmd_zenWorkspaceForward",
|
||||
|
||||
Reference in New Issue
Block a user