diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/contentScopeIsolated.js b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/contentScopeIsolated.js
index 5ecd57fe8ff..7a78ecf0e1b 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/contentScopeIsolated.js
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/contentScopeIsolated.js
@@ -12314,7 +12314,7 @@ ul.messages {
}
});
}
- async function getExpandedPerformanceMetrics() {
+ async function getExpandedPerformanceMetrics(timeoutMs = 500) {
try {
if (document.readyState !== "complete") {
return returnError("Document not ready");
@@ -12331,7 +12331,7 @@ ul.messages {
const fcp = paint.find((p) => p.name === "first-contentful-paint");
let largestContentfulPaint = null;
if (PerformanceObserver.supportedEntryTypes.includes("largest-contentful-paint")) {
- largestContentfulPaint = await waitForLCP();
+ largestContentfulPaint = await waitForLCP(timeoutMs);
}
const totalResourceSize = resources.reduce((sum, r) => sum + (r.transferSize || 0), 0);
if (navigation) {
@@ -12552,7 +12552,8 @@ ul.messages {
}
}
async triggerExpandedPerformanceMetrics() {
- const expandedPerformanceMetrics = await getExpandedPerformanceMetrics();
+ const permissableDelayMs = this.getFeatureSetting("expandedTimeoutMs") ?? 5e3;
+ const expandedPerformanceMetrics = await getExpandedPerformanceMetrics(permissableDelayMs);
this.messaging.notify("expandedPerformanceMetricsResult", expandedPerformanceMetrics);
}
};
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/index.html b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/index.html
index 0f6befc66c7..0f7e5e5d977 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/index.html
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/index.html
@@ -74,9 +74,32 @@
color: rgb(210, 210, 210);
}
}
+
+/* TODO: Use colour variables from design-tokens */
+
+/* Theme variants - light mode */
+[data-theme-variant="coolGray"] { background: #d2d5e3; }
+[data-theme-variant="slateBlue"] { background: #d2e5f3; }
+[data-theme-variant="green"] { background: #e3eee1; }
+[data-theme-variant="violet"] { background: #e7e4f5; }
+[data-theme-variant="rose"] { background: #f8ebf5; }
+[data-theme-variant="orange"] { background: #fcedd8; }
+[data-theme-variant="desert"] { background: #eee9e1; }
+
+/* Theme variants - dark mode */
+@media (prefers-color-scheme: dark) {
+ [data-theme-variant="coolGray"] { background: #2b2f45; }
+ [data-theme-variant="slateBlue"] { background: #1e3347; }
+ [data-theme-variant="green"] { background: #203b30; }
+ [data-theme-variant="violet"] { background: #2e2158; }
+ [data-theme-variant="rose"] { background: #5b194b; }
+ [data-theme-variant="orange"] { background: #54240c; }
+ [data-theme-variant="desert"] { background: #3c3833; }
+}
+
-
+
+
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/style.css b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/style.css
index 87d0488c935..c8449bd9f13 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/style.css
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/errorpage/style.css
@@ -65,4 +65,26 @@ body {
.error-description, .error-header {
color: rgb(210, 210, 210);
}
-}
\ No newline at end of file
+}
+
+/* TODO: Use colour variables from design-tokens */
+
+/* Theme variants - light mode */
+[data-theme-variant="coolGray"] { background: #d2d5e3; }
+[data-theme-variant="slateBlue"] { background: #d2e5f3; }
+[data-theme-variant="green"] { background: #e3eee1; }
+[data-theme-variant="violet"] { background: #e7e4f5; }
+[data-theme-variant="rose"] { background: #f8ebf5; }
+[data-theme-variant="orange"] { background: #fcedd8; }
+[data-theme-variant="desert"] { background: #eee9e1; }
+
+/* Theme variants - dark mode */
+@media (prefers-color-scheme: dark) {
+ [data-theme-variant="coolGray"] { background: #2b2f45; }
+ [data-theme-variant="slateBlue"] { background: #1e3347; }
+ [data-theme-variant="green"] { background: #203b30; }
+ [data-theme-variant="violet"] { background: #2e2158; }
+ [data-theme-variant="rose"] { background: #5b194b; }
+ [data-theme-variant="orange"] { background: #54240c; }
+ [data-theme-variant="desert"] { background: #3c3833; }
+}
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/history/index.html b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/history/index.html
index c17fd166bf2..1456b50bbbf 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/history/index.html
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/history/index.html
@@ -11,6 +11,15 @@
}
}
+
History
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.css b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.css
index b4bb0ba883c..0824e2b068f 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.css
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.css
@@ -1995,7 +1995,7 @@ body:not([data-background-kind=default]) .TabSwitcher_tabSwitcher {
--background: rgba(255, 255, 255, 0.09);
}
.Protections_block {
- margin-top: 32px;
+ margin-top: 16px;
}
.Protections_blockLegacy {
margin-top: 24px;
@@ -2090,6 +2090,7 @@ body:not([data-background-kind=default]) .TabSwitcher_tabSwitcher {
height: 16px;
display: inline-block;
vertical-align: middle;
+ margin-top: 2px;
}
.PrivacyStats_widgetExpander {
position: relative;
@@ -2229,6 +2230,24 @@ body:not([data-background-kind=default]) .TabSwitcher_tabSwitcher {
background: var(--color-white-at-9);
}
+/* pages/new-tab/app/components/NewBadge.module.css */
+.NewBadge_badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: fit-content;
+ height: 16px;
+ padding: 0 8px;
+ background-color: #F9BE1A;
+ border-radius: 4px;
+ font-family: var(--theme-font-family, system-ui);
+ font-weight: 700;
+ font-size: 11px;
+ color: var(--color-black-at-96);
+ letter-spacing: -0.015em;
+ flex-shrink: 0;
+}
+
/* pages/new-tab/app/components/Tooltip/Tooltip.module.css */
.Tooltip_tooltipContainer {
position: relative;
@@ -2956,9 +2975,9 @@ body:not([data-background-kind=default]) .TabSwitcher_tabSwitcher {
.TickPill_tickPill {
display: flex;
align-items: center;
- gap: 6px;
- padding: 8px 10px;
- border-radius: 100px;
+ gap: 4px;
+ padding: 8px 8px;
+ border-radius: 1000px;
background-color: var(--color-white-at-3);
border: 1px solid var(--color-white-at-12);
height: 20px;
@@ -2982,8 +3001,8 @@ body:not([data-background-kind=default]) .TabSwitcher_tabSwitcher {
white-space: nowrap;
}
[data-theme=light] .TickPill_tickPill {
- background-color: var(--color-black-at-4);
- border: 1px solid var(--color-black-at-12);
+ background-color: var(--color-black-at-1);
+ border: 1px solid var(--color-black-at-9);
}
[data-theme=light] .TickPill_text {
color: var(--color-black-at-84);
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.js b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.js
index b7d78c5ada3..3a0cdcf9e91 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.js
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/dist/index.js
@@ -1858,36 +1858,6 @@
}
));
}
- function NewBadgeIcon(props) {
- return /* @__PURE__ */ _("svg", { xmlns: "http://www.w3.org/2000/svg", width: "42", height: "16", viewBox: "0 0 42 16", fill: "none", ...props }, /* @__PURE__ */ _(
- "path",
- {
- d: "M0 3.99792C0 1.78879 1.79086 -0.0020752 4 -0.0020752H38C40.2091 -0.0020752 42 1.78879 42 3.99792V11.9979C42 14.2071 40.2091 15.9979 38 15.9979H4C1.79086 15.9979 0 14.2071 0 11.9979V3.99792Z",
- fill: "#F9BE1A"
- }
- ), /* @__PURE__ */ _(
- "path",
- {
- d: "M13.0913 9.1073H13.1812V3.94617H14.8032V12.0497H13.3999L9.64893 6.86707H9.55908V12.0497H7.93604V3.94617H9.35107L13.0913 9.1073Z",
- fill: "black",
- "fill-opacity": "0.96"
- }
- ), /* @__PURE__ */ _(
- "path",
- {
- d: "M22.144 5.3446H18.4722V7.29871H21.936V8.60144H18.4722V10.6512H22.144V12.0497H16.7759V3.94617H22.144V5.3446Z",
- fill: "black",
- "fill-opacity": "0.96"
- }
- ), /* @__PURE__ */ _(
- "path",
- {
- d: "M26.4663 9.73621H26.5562L28.0337 3.94617H29.4653L30.9702 9.73621H31.0601L32.312 3.94617H34.064L31.9136 12.0497H30.3247L28.7915 6.59167H28.7017L27.1851 12.0497H25.5854L23.4399 3.94617H25.2036L26.4663 9.73621Z",
- fill: "black",
- "fill-opacity": "0.96"
- }
- ));
- }
function InfoIcon(props) {
return /* @__PURE__ */ _("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", class: "info-icon", ...props }, /* @__PURE__ */ _(
"path",
@@ -9753,6 +9723,28 @@
}
});
+ // pages/new-tab/app/components/NewBadge.module.css
+ var NewBadge_default;
+ var init_NewBadge = __esm({
+ "pages/new-tab/app/components/NewBadge.module.css"() {
+ NewBadge_default = {
+ badge: "NewBadge_badge"
+ };
+ }
+ });
+
+ // pages/new-tab/app/components/NewBadge.js
+ function NewBadge({ text: text2, ...rest }) {
+ return /* @__PURE__ */ _("span", { class: NewBadge_default.badge, ...rest }, text2?.toUpperCase() || "NEW");
+ }
+ var init_NewBadge2 = __esm({
+ "pages/new-tab/app/components/NewBadge.js"() {
+ "use strict";
+ init_preact_module();
+ init_NewBadge();
+ }
+ });
+
// pages/new-tab/app/components/Tooltip/Tooltip.module.css
var Tooltip_default;
var init_Tooltip = __esm({
@@ -9874,7 +9866,14 @@
function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed * inverseDuration, 1);
- const eased = progress < 0.5 ? 4 * progress * progress * progress : 1 - Math.pow(-2 * progress + 2, 3) / 2;
+ let eased;
+ if (progress < 0.5) {
+ const p22 = progress * progress;
+ eased = 4 * p22 * progress;
+ } else {
+ const t4 = -2 * progress + 2;
+ eased = 1 - t4 * t4 * t4 / 2;
+ }
const currentValue = Math.floor(startValue + animationRange * eased);
onUpdate(currentValue);
if (progress < 1) {
@@ -9907,12 +9906,24 @@
});
// pages/new-tab/app/protections/utils/useAnimatedCount.js
- function useAnimatedCount(targetValue) {
+ function useAnimatedCount(targetValue, elementRef) {
const [animatedValue, setAnimatedValue] = d2(0);
const animatedValueRef = A2(
/** @type {number} */
0
);
+ const [isInViewport, setIsInViewport] = d2(false);
+ const hasAnimatedRef = A2(false);
+ const lastSeenValueRef = A2(
+ /** @type {number | null} */
+ null
+ );
+ const wasInViewportRef = A2(false);
+ const observerSetupRef = A2(false);
+ const observerRef = A2(
+ /** @type {IntersectionObserver | null} */
+ null
+ );
const updateAnimatedCount = q2(
/** @type {import('./animateCount.js').AnimationUpdateCallback} */
((value2) => {
@@ -9921,23 +9932,91 @@
}),
[]
);
+ const setupIntersectionObserver = q2((element) => {
+ if (observerSetupRef.current || observerRef.current) {
+ return;
+ }
+ observerSetupRef.current = true;
+ observerRef.current = new IntersectionObserver(
+ (entries4) => {
+ entries4.forEach((entry) => {
+ const wasInViewport = wasInViewportRef.current;
+ const isNowInViewport = entry.isIntersecting;
+ if (wasInViewport && !isNowInViewport) {
+ lastSeenValueRef.current = animatedValueRef.current;
+ }
+ wasInViewportRef.current = isNowInViewport;
+ setIsInViewport(isNowInViewport);
+ });
+ },
+ {
+ // Trigger when any part of the element is visible
+ threshold: 0,
+ // Optional: add some margin to trigger slightly before visible
+ rootMargin: "0px"
+ }
+ );
+ observerRef.current.observe(element);
+ }, []);
+ y2(() => {
+ if (!elementRef) {
+ setIsInViewport(true);
+ return;
+ }
+ const element = elementRef.current;
+ let cancelled = false;
+ if (element) {
+ setupIntersectionObserver(element);
+ } else {
+ (async () => {
+ await Promise.resolve();
+ if (cancelled) {
+ return;
+ }
+ const delayedElement = elementRef.current;
+ if (delayedElement) {
+ setupIntersectionObserver(delayedElement);
+ }
+ })();
+ }
+ return () => {
+ cancelled = true;
+ observerSetupRef.current = false;
+ if (observerRef.current) {
+ observerRef.current.disconnect();
+ observerRef.current = null;
+ }
+ };
+ }, []);
y2(() => {
let cancelAnimation = () => {
};
- if (document.visibilityState === "visible") {
- cancelAnimation = animateCount(targetValue, updateAnimatedCount, void 0, animatedValueRef.current);
- } else {
+ const shouldAnimate = document.visibilityState === "visible" && isInViewport;
+ if (shouldAnimate) {
+ let startValue = animatedValueRef.current;
+ if (lastSeenValueRef.current !== null && lastSeenValueRef.current !== targetValue) {
+ startValue = lastSeenValueRef.current;
+ lastSeenValueRef.current = null;
+ }
+ cancelAnimation = animateCount(targetValue, updateAnimatedCount, void 0, startValue);
+ hasAnimatedRef.current = true;
+ } else if (hasAnimatedRef.current) {
setAnimatedValue(targetValue);
animatedValueRef.current = targetValue;
+ lastSeenValueRef.current = null;
}
const handleVisibilityChange = () => {
- if (document.visibilityState === "visible") {
+ if (document.visibilityState === "visible" && isInViewport) {
cancelAnimation();
cancelAnimation = animateCount(targetValue, updateAnimatedCount, void 0, animatedValueRef.current);
- } else {
+ hasAnimatedRef.current = true;
+ } else if (document.visibilityState === "hidden") {
cancelAnimation();
- setAnimatedValue(targetValue);
- animatedValueRef.current = targetValue;
+ if (hasAnimatedRef.current) {
+ setAnimatedValue(targetValue);
+ animatedValueRef.current = targetValue;
+ lastSeenValueRef.current = null;
+ }
}
};
document.addEventListener("visibilitychange", handleVisibilityChange);
@@ -9945,7 +10024,7 @@
cancelAnimation();
document.removeEventListener("visibilitychange", handleVisibilityChange);
};
- }, [targetValue, updateAnimatedCount]);
+ }, [targetValue, updateAnimatedCount, isInViewport]);
return animatedValue;
}
var init_useAnimatedCount = __esm({
@@ -9969,15 +10048,29 @@
/** @type {Strings} */
{}
);
+ const ntp = useMessaging();
+ const headingRef = A2(
+ /** @type {HTMLDivElement|null} */
+ null
+ );
+ const counterContainerRef = A2(
+ /** @type {HTMLDivElement|null} */
+ null
+ );
const totalTrackersBlocked = blockedCountSignal.value;
const totalCookiePopUpsBlockedValue = totalCookiePopUpsBlockedSignal.value;
const totalCookiePopUpsBlocked = typeof totalCookiePopUpsBlockedValue === "number" && Number.isFinite(totalCookiePopUpsBlockedValue) ? Math.max(0, Math.floor(totalCookiePopUpsBlockedValue)) : 0;
- const animatedTrackersBlocked = useAnimatedCount(totalTrackersBlocked);
- const animatedCookiePopUpsBlocked = useAnimatedCount(totalCookiePopUpsBlocked);
+ const animatedTrackersBlocked = useAnimatedCount(totalTrackersBlocked, counterContainerRef);
+ const animatedCookiePopUpsBlocked = useAnimatedCount(totalCookiePopUpsBlocked, counterContainerRef);
+ y2(() => {
+ return ntp.messaging.subscribe("protections_scroll", () => {
+ headingRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
+ });
+ }, [ntp]);
const isCpmEnabled = totalCookiePopUpsBlockedValue !== void 0 && totalCookiePopUpsBlockedValue !== null;
const trackersBlockedHeading = animatedTrackersBlocked === 1 ? t4("stats_countBlockedSingular") : t4("stats_countBlockedPlural");
const cookiePopUpsBlockedHeading = animatedCookiePopUpsBlocked === 1 ? t4("stats_totalCookiePopUpsBlockedSingular") : t4("stats_totalCookiePopUpsBlockedPlural");
- return /* @__PURE__ */ _("div", { class: PrivacyStats_default.heading, "data-testid": "ProtectionsHeading" }, /* @__PURE__ */ _("div", { class: (0, import_classnames9.default)(PrivacyStats_default.control, animatedTrackersBlocked === 0 && PrivacyStats_default.noTrackers) }, /* @__PURE__ */ _("span", { class: PrivacyStats_default.headingIcon }, /* @__PURE__ */ _("img", { src: "./icons/Shield-Check-Color-16.svg", alt: "Privacy Shield" })), /* @__PURE__ */ _("h2", { class: PrivacyStats_default.caption }, t4("protections_menuTitle")), /* @__PURE__ */ _(Tooltip, { content: t4("stats_protectionsReportInfo") }, /* @__PURE__ */ _(InfoIcon, { class: PrivacyStats_default.infoIcon })), canExpand && /* @__PURE__ */ _("span", { class: PrivacyStats_default.widgetExpander }, /* @__PURE__ */ _(
+ return /* @__PURE__ */ _("div", { class: PrivacyStats_default.heading, "data-testid": "ProtectionsHeading", ref: headingRef }, /* @__PURE__ */ _("div", { class: (0, import_classnames9.default)(PrivacyStats_default.control, animatedTrackersBlocked === 0 && PrivacyStats_default.noTrackers) }, /* @__PURE__ */ _("span", { class: PrivacyStats_default.headingIcon }, /* @__PURE__ */ _("img", { src: "./icons/Shield-Check-Color-16.svg", alt: "Privacy Shield" })), /* @__PURE__ */ _("h2", { class: PrivacyStats_default.caption }, t4("protections_menuTitle")), /* @__PURE__ */ _(Tooltip, { content: t4("stats_protectionsReportInfo") }, /* @__PURE__ */ _(InfoIcon, { class: PrivacyStats_default.infoIcon })), canExpand && /* @__PURE__ */ _("span", { class: PrivacyStats_default.widgetExpander }, /* @__PURE__ */ _(
ShowHideButtonCircle,
{
buttonAttrs: {
@@ -9988,7 +10081,7 @@
onClick: onToggle,
label: expansion === "expanded" ? t4("stats_hideLabel") : t4("stats_toggleLabel")
}
- ))), /* @__PURE__ */ _("div", { class: PrivacyStats_default.counterContainer }, /* @__PURE__ */ _("div", { class: PrivacyStats_default.counter }, animatedTrackersBlocked === 0 && /* @__PURE__ */ _("h3", { class: PrivacyStats_default.noRecentTitle }, t4("protections_noRecent")), animatedTrackersBlocked > 0 && /* @__PURE__ */ _("h3", { class: PrivacyStats_default.title }, animatedTrackersBlocked, " ", /* @__PURE__ */ _("span", null, trackersBlockedHeading))), isCpmEnabled && animatedTrackersBlocked > 0 && totalCookiePopUpsBlocked > 0 && /* @__PURE__ */ _("div", { class: PrivacyStats_default.counter }, /* @__PURE__ */ _("h3", { class: PrivacyStats_default.title }, animatedCookiePopUpsBlocked, " ", /* @__PURE__ */ _("span", null, cookiePopUpsBlockedHeading)), /* @__PURE__ */ _(NewBadgeIcon, null))));
+ ))), /* @__PURE__ */ _("div", { class: PrivacyStats_default.counterContainer, ref: counterContainerRef }, /* @__PURE__ */ _("div", { class: PrivacyStats_default.counter }, animatedTrackersBlocked === 0 && /* @__PURE__ */ _("h3", { class: PrivacyStats_default.noRecentTitle }, t4("protections_noRecent")), animatedTrackersBlocked > 0 && /* @__PURE__ */ _("h3", { class: PrivacyStats_default.title }, animatedTrackersBlocked, " ", /* @__PURE__ */ _("span", null, trackersBlockedHeading))), isCpmEnabled && animatedTrackersBlocked > 0 && totalCookiePopUpsBlocked > 0 && /* @__PURE__ */ _("div", { class: PrivacyStats_default.counter }, /* @__PURE__ */ _("h3", { class: PrivacyStats_default.title }, animatedCookiePopUpsBlocked, " ", /* @__PURE__ */ _("span", null, cookiePopUpsBlockedHeading)), /* @__PURE__ */ _(NewBadge, { text: t4("protections_newBadge") }))));
}
var import_classnames9;
var init_ProtectionsHeading = __esm({
@@ -10000,8 +10093,10 @@
import_classnames9 = __toESM(require_classnames(), 1);
init_preact_module();
init_Icons2();
+ init_NewBadge2();
init_Tooltip2();
init_useAnimatedCount();
+ init_hooks_module();
}
});
@@ -30464,6 +30559,10 @@
title: "No recent tracking activity",
note: "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ protections_newBadge: {
+ title: "NEW",
+ note: "Text displayed in a badge to indicate a new feature or statistic."
+ },
stats_menuTitle: {
title: "Blocked Tracking Attempts",
note: "Used as a label in a customization menu"
@@ -30521,7 +30620,7 @@
note: "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
stats_protectionsReportInfo: {
- title: "Displays tracking attempts blocked in the last 7 days, and the number of cookie pop-ups blocked since you started using the browser.
You can reset these stats using the Fire Button.",
+ title: "Displays tracking attempts blocked in the last 7 days, and the number of cookie pop-ups blocked since you started using the browser.",
note: "Text explaining how to reset the protections stats"
},
stats_feedCountBlockedSingular: {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/de/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/de/new-tab.json
index d0591f92f54..d5b8c307166 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/de/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/de/new-tab.json
@@ -60,6 +60,10 @@
"title" : "Keine aktuellen Tracking-Aktivitäten",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Neu",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Blockierte Tracking-Versuche",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Zeigt die in den letzten 7 Tagen blockierten Tracking-Versuche sowie die Anzahl der seit deiner ersten Nutzung des Browsers blockierten Cookie-Pop-ups an.
Du kannst diese Werte mit dem Fire Button zurücksetzen.",
+ "title" : "Zeigt die in den letzten 7 Tagen blockierten Tracking-Versuche sowie die Anzahl der seit deiner ersten Nutzung des Browsers blockierten Cookie-Pop-ups an.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/en/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/en/new-tab.json
index 04f3159954a..42f0b89deba 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/en/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/en/new-tab.json
@@ -61,6 +61,10 @@
"title": "No recent tracking activity",
"note": "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge": {
+ "title": "NEW",
+ "note": "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle": {
"title": "Blocked Tracking Attempts",
"note": "Used as a label in a customization menu"
@@ -118,7 +122,7 @@
"note": "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo": {
- "title": "Displays tracking attempts blocked in the last 7 days, and the number of cookie pop-ups blocked since you started using the browser.
You can reset these stats using the Fire Button.",
+ "title": "Displays tracking attempts blocked in the last 7 days, and the number of cookie pop-ups blocked since you started using the browser.",
"note": "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular": {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/es/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/es/new-tab.json
index 37df1903601..57999d24a9c 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/es/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/es/new-tab.json
@@ -60,6 +60,10 @@
"title" : "No hay actividad de rastreo reciente",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Nuevo",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Intentos de rastreo bloqueados",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Muestra los intentos de rastreo bloqueados en los últimos 7 días y el número de ventanas emergentes de cookies bloqueadas desde que empezaste a usar el navegador.
Puedes restablecer estas estadísticas usando el Fire Button.",
+ "title" : "Muestra los intentos de rastreo bloqueados en los últimos 7 días y el número de ventanas emergentes de cookies bloqueadas desde que empezaste a usar el navegador.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/fr/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/fr/new-tab.json
index bc62c3bc31d..bc3c4783b19 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/fr/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/fr/new-tab.json
@@ -60,6 +60,10 @@
"title" : "Aucune activité de pistage récente",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Nouveau",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Tentatives de pistage bloquées",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Affiche les tentatives de pistage bloquées au cours des 7 derniers jours et le nombre de fenêtres contextuelles de cookies bloquées depuis que vous avez commencé à utiliser le navigateur.
Vous pouvez réinitialiser ces statistiques en utilisant le Fire Button.",
+ "title" : "Affiche les tentatives de pistage bloquées au cours des 7 derniers jours et le nombre de fenêtres contextuelles de cookies bloquées depuis que vous avez commencé à utiliser le navigateur.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/it/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/it/new-tab.json
index bbd47ea3c96..02fb1c67612 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/it/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/it/new-tab.json
@@ -60,6 +60,10 @@
"title" : "Nessuna attività di tracciamento recente",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Nuova",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Tentativi di tracciamento bloccati",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Mostra i tentativi di tracciamento bloccati negli ultimi 7 giorni e il numero di pop-up di cookie bloccati da quando hai iniziato a usare il browser.
Puoi reimpostare queste statistiche usando il Fire Button.",
+ "title" : "Mostra i tentativi di tracciamento bloccati negli ultimi 7 giorni e il numero di pop-up di cookie bloccati da quando hai iniziato a usare il browser.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/nl/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/nl/new-tab.json
index f778ab5cae9..60bc1a91ddf 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/nl/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/nl/new-tab.json
@@ -60,6 +60,10 @@
"title" : "Geen recente trackingactiviteit",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Nieuw",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Geblokkeerde trackingpogingen",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Toont trackingpogingen die in de afgelopen 7 dagen zijn geblokkeerd en het aantal cookiepop-ups dat is geblokkeerd sinds je de browser bent gaan gebruiken.
Je kunt deze statistieken resetten met de Fire Button.",
+ "title" : "Toont trackingpogingen die in de afgelopen 7 dagen zijn geblokkeerd en het aantal cookiepop-ups dat is geblokkeerd sinds je de browser bent gaan gebruiken.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pl/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pl/new-tab.json
index 124b6223718..eeb5895ab9c 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pl/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pl/new-tab.json
@@ -60,6 +60,10 @@
"title" : "Brak ostatniej aktywności w zakresie śledzenia",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Nowa",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Zablokowane próby śledzenia",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Wyświetla próby śledzenia zablokowane w ciągu ostatnich 7 dni oraz liczbę wyskakujących okienek z informacją o plikach cookie zablokowanych od czasu rozpoczęcia korzystania z przeglądarki.
Możesz zresetować te statystyki za pomocą przycisku Fire Button.",
+ "title" : "Wyświetla próby śledzenia zablokowane w ciągu ostatnich 7 dni oraz liczbę wyskakujących okienek z informacją o plikach cookie zablokowanych od czasu rozpoczęcia korzystania z przeglądarki.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pt/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pt/new-tab.json
index f04f37555ea..4c2d782deda 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pt/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/pt/new-tab.json
@@ -60,6 +60,10 @@
"title" : "Nenhuma atividade de rastreamento recente",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Novo",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Tentativas de rastreamento bloqueadas",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Mostra as tentativas de rastreamento bloqueadas nos últimos 7 dias e o número de pop-ups de cookies bloqueados desde que começaste a usar o navegador.
Podes repor estas estatísticas usando o Fire Button.",
+ "title" : "Mostra as tentativas de rastreamento bloqueadas nos últimos 7 dias e o número de pop-ups de cookies bloqueados desde que começaste a usar o navegador.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/ru/new-tab.json b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/ru/new-tab.json
index 71bf69b6120..bef8eda1e2c 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/ru/new-tab.json
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/new-tab/locales/ru/new-tab.json
@@ -60,6 +60,10 @@
"title" : "Нет недавних отслеживаний",
"note" : "Placeholder text shown in the Details view when no tracking activity was blocked in the last 7 days. Keep concise if possible."
},
+ "protections_newBadge" : {
+ "title" : "Новинка",
+ "note" : "Text displayed in a badge to indicate a new feature or statistic."
+ },
"stats_menuTitle" : {
"title" : "Заблокированные попытки отслеживания",
"note" : "Used as a label in a customization menu"
@@ -117,7 +121,7 @@
"note" : "The heading indicating multiple cookie pop-ups were handled by the CPM"
},
"stats_protectionsReportInfo" : {
- "title" : "Отображает попытки отслеживания, заблокированные за последние 7 дней, а также количество всплывающих окон куки, заблокированных с начала использования браузера.
Эту статистику можно сбросить с помощью кнопки Fire Button.",
+ "title" : "Отображает попытки отслеживания, заблокированные за последние 7 дней, а также количество всплывающих окон куки, заблокированных с начала использования браузера.",
"note" : "Text explaining how to reset the protections stats"
},
"stats_feedCountBlockedSingular" : {
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.css b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.css
index 472b2b508c0..49ba13fb4a8 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.css
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.css
@@ -966,7 +966,11 @@ li {
/* pages/special-error/app/styles/variables.css */
:root {
- --theme-background-color: var(--color-gray-20);
+ --default-light-background-color: var(--color-gray-20);
+ --default-dark-background-color: var(--color-gray-85);
+}
+body[data-theme=light] {
+ --theme-background-color: var(--default-light-background-color);
--theme-text-primary-color: var(--color-black-at-84);
--link-color: var(--color-black);
--border-color: rgba(0, 0, 0, 0.1);
@@ -974,17 +978,43 @@ li {
--advanced-info-bg: var(--color-black-at-3);
--visit-site-color: var(--color-black);
}
-@media (prefers-color-scheme: dark) {
- :root {
- --theme-background-color: var(--color-gray-85);
- --theme-text-primary-color: var(--color-white-at-84);
- --link-color: var(--color-gray-40);
- --border-color: var(--color-white-at-18);
- --container-bg: var(--color-gray-90);
- --advanced-info-bg: #2f2f2f;
- --visit-site-color: var(--color-gray-40);
- }
- [data-platform-name=ios] {
- --theme-background-color: #222;
- }
+body[data-theme=dark] {
+ --theme-background-color: var(--default-dark-background-color);
+ --theme-text-primary-color: var(--color-white-at-84);
+ --link-color: var(--color-gray-40);
+ --border-color: var(--color-white-at-18);
+ --container-bg: var(--color-gray-90);
+ --advanced-info-bg: #2f2f2f;
+ --visit-site-color: var(--color-gray-40);
+}
+body[data-theme=dark][data-platform-name=ios][data-theme-variant=default] {
+ --theme-background-color: #222;
+}
+body[data-theme-variant=coolGray] {
+ --default-light-background-color: #d2d5e3;
+ --default-dark-background-color: #2b2f45;
+}
+body[data-theme-variant=slateBlue] {
+ --default-light-background-color: #d2e5f3;
+ --default-dark-background-color: #1e3347;
+}
+body[data-theme-variant=green] {
+ --default-light-background-color: #e3eee1;
+ --default-dark-background-color: #203b30;
+}
+body[data-theme-variant=violet] {
+ --default-light-background-color: #e7e4f5;
+ --default-dark-background-color: #2e2158;
+}
+body[data-theme-variant=rose] {
+ --default-light-background-color: #f8ebf5;
+ --default-dark-background-color: #5b194b;
+}
+body[data-theme-variant=orange] {
+ --default-light-background-color: #fcedd8;
+ --default-dark-background-color: #54240c;
+}
+body[data-theme-variant=desert] {
+ --default-light-background-color: #eee9e1;
+ --default-dark-background-color: #3c3833;
}
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.js b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.js
index 897c20dba56..f6958baa82a 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.js
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/dist/index.js
@@ -2601,13 +2601,12 @@
}
function App() {
const { messaging: messaging2 } = useMessaging();
- const { isDarkMode } = useEnv();
function didCatch(error) {
const message = error?.message || "unknown";
console.error("ErrorBoundary", message);
messaging2?.reportPageException({ message });
}
- return /* @__PURE__ */ _("main", { className: App_default.main, "data-theme": isDarkMode ? "dark" : "light" }, /* @__PURE__ */ _(PageTitle, null), /* @__PURE__ */ _(ErrorBoundary, { didCatch: ({ error }) => didCatch(error), fallback: /* @__PURE__ */ _(ErrorFallback, null) }, /* @__PURE__ */ _(SpecialErrorView, null), /* @__PURE__ */ _(WillThrow, null)));
+ return /* @__PURE__ */ _("main", { className: App_default.main }, /* @__PURE__ */ _(PageTitle, null), /* @__PURE__ */ _(ErrorBoundary, { didCatch: ({ error }) => didCatch(error), fallback: /* @__PURE__ */ _(ErrorFallback, null) }, /* @__PURE__ */ _(SpecialErrorView, null), /* @__PURE__ */ _(WillThrow, null)));
}
function WillThrow() {
const env = useEnv();
@@ -2667,6 +2666,43 @@
} }))), /* @__PURE__ */ _("section", null, /* @__PURE__ */ _("h2", null, "Advanced Info"), /* @__PURE__ */ _("div", null, /* @__PURE__ */ _(AdvancedInfo, null))), /* @__PURE__ */ _("section", null, /* @__PURE__ */ _("h2", null, "Special Error View"), /* @__PURE__ */ _("div", null, /* @__PURE__ */ _(SpecialErrorView, null)))));
}
+ // pages/special-error/app/providers/ThemeProvider.js
+ var ThemeContext = K({
+ /** @type {BrowserTheme} */
+ theme: "light",
+ /** @type {ThemeVariant} */
+ themeVariant: "default"
+ });
+ function ThemeProvider({ children, initialTheme, initialThemeVariant }) {
+ const { isDarkMode } = useEnv();
+ const { messaging: messaging2 } = useMessaging();
+ const [explicitTheme, setExplicitTheme] = d2(
+ /** @type {BrowserTheme | undefined} */
+ void 0
+ );
+ const [explicitThemeVariant, setExplicitThemeVariant] = d2(
+ /** @type {ThemeVariant | undefined} */
+ void 0
+ );
+ y2(() => {
+ if (!messaging2) return;
+ const unsubscribe = messaging2.onThemeUpdate((data) => {
+ setExplicitTheme(data.theme);
+ setExplicitThemeVariant(data.themeVariant);
+ });
+ return unsubscribe;
+ }, [messaging2]);
+ const theme = explicitTheme ?? initialTheme ?? (isDarkMode ? "dark" : "light");
+ const themeVariant = explicitThemeVariant ?? initialThemeVariant ?? "default";
+ y2(() => {
+ document.body.dataset.theme = theme;
+ }, [theme]);
+ y2(() => {
+ document.body.dataset.themeVariant = themeVariant;
+ }, [themeVariant]);
+ return /* @__PURE__ */ _(ThemeContext.Provider, { value: { theme, themeVariant } }, children);
+ }
+
// shared/call-with-retry.js
async function callWithRetry(fn, params = {}) {
const { maxAttempts = 10, intervalMs = 300 } = params;
@@ -2734,12 +2770,12 @@
if (!root) throw new Error("could not render, root element missing");
if (environment.display === "app") {
E(
- /* @__PURE__ */ _(EnvironmentProvider, { debugState: environment.debugState, injectName: environment.injectName, willThrow: environment.willThrow }, /* @__PURE__ */ _(UpdateEnvironment, { search: window.location.search }), /* @__PURE__ */ _(TranslationProvider, { translationObject: strings, fallback: special_error_default, textLength: environment.textLength }, /* @__PURE__ */ _(MessagingProvider, { messaging: messaging2 }, /* @__PURE__ */ _(SettingsProvider, { settings }, /* @__PURE__ */ _(SpecialErrorProvider, { specialError }, /* @__PURE__ */ _(App, null)))))),
+ /* @__PURE__ */ _(EnvironmentProvider, { debugState: environment.debugState, injectName: environment.injectName, willThrow: environment.willThrow }, /* @__PURE__ */ _(UpdateEnvironment, { search: window.location.search }), /* @__PURE__ */ _(TranslationProvider, { translationObject: strings, fallback: special_error_default, textLength: environment.textLength }, /* @__PURE__ */ _(MessagingProvider, { messaging: messaging2 }, /* @__PURE__ */ _(ThemeProvider, { initialTheme: init2.theme, initialThemeVariant: init2.themeVariant }, /* @__PURE__ */ _(SettingsProvider, { settings }, /* @__PURE__ */ _(SpecialErrorProvider, { specialError }, /* @__PURE__ */ _(App, null))))))),
root
);
} else if (environment.display === "components") {
E(
- /* @__PURE__ */ _(EnvironmentProvider, { debugState: false, injectName: environment.injectName }, /* @__PURE__ */ _(TranslationProvider, { translationObject: strings, fallback: special_error_default, textLength: environment.textLength }, /* @__PURE__ */ _(SettingsProvider, { settings }, /* @__PURE__ */ _(SpecialErrorProvider, { specialError }, /* @__PURE__ */ _(Components, null))))),
+ /* @__PURE__ */ _(EnvironmentProvider, { debugState: false, injectName: environment.injectName }, /* @__PURE__ */ _(TranslationProvider, { translationObject: strings, fallback: special_error_default, textLength: environment.textLength }, /* @__PURE__ */ _(ThemeProvider, { initialTheme: init2.theme, initialThemeVariant: init2.themeVariant }, /* @__PURE__ */ _(SettingsProvider, { settings }, /* @__PURE__ */ _(SpecialErrorProvider, { specialError }, /* @__PURE__ */ _(Components, null)))))),
root
);
}
@@ -2822,6 +2858,14 @@
advancedInfo() {
this.messaging.notify("advancedInfo");
}
+ /**
+ * Subscribe to theme update notifications from the native layer.
+ * @param {(data: import('../types/special-error.ts').OnThemeUpdateSubscribe) => void} callback
+ * @returns {() => void} Unsubscribe function
+ */
+ onThemeUpdate(callback) {
+ return this.messaging.subscribe("onThemeUpdate", callback);
+ }
};
var baseEnvironment = new Environment().withInjectName(document.documentElement.dataset.platform).withEnv("production");
var messaging = createSpecialPageMessaging({
diff --git a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/index.html b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/index.html
index 71b68acf6f2..0c06028c2fb 100644
--- a/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/index.html
+++ b/SharedPackages/BrowserServicesKit/Sources/ContentScopeScripts/Resources/pages/special-error/index.html
@@ -4,6 +4,13 @@
Error
+