@pie-players/pie-players-shared 0.3.66 → 0.3.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ui/content-styles.d.ts +11 -3
- package/dist/ui/content-styles.js +42 -13
- package/package.json +1 -1
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* The CSS text is passed in rather than imported here: this package builds with
|
|
19
19
|
* plain `tsc`, so it cannot inline a stylesheet. Bundler-built player packages
|
|
20
|
-
* import it with Vite's `?
|
|
20
|
+
* import it with Vite's `?raw` and hand the text over.
|
|
21
21
|
*/
|
|
22
22
|
export type ContentStylesResult = "installed" | "already-installed" | "opted-out" | "no-document";
|
|
23
23
|
/**
|
|
@@ -26,8 +26,16 @@ export type ContentStylesResult = "installed" | "already-installed" | "opted-out
|
|
|
26
26
|
*/
|
|
27
27
|
export declare function contentStylesOptedOut(): boolean;
|
|
28
28
|
/**
|
|
29
|
-
* True when `components.css` is applied to the document, by any route.
|
|
30
|
-
*
|
|
29
|
+
* True when `components.css` is applied to the document, by any route.
|
|
30
|
+
*
|
|
31
|
+
* Two probes, because neither alone covers both deliveries. The computed
|
|
32
|
+
* sentinel on `<html>` is authoritative for a stylesheet applying to the whole
|
|
33
|
+
* document. A host that confines its copy to its player subtree — `@scope
|
|
34
|
+
* (.item-content) { … }`, the documented remedy for these rules reaching host
|
|
35
|
+
* chrome — puts the stylesheet's `:root` rule somewhere it can never match,
|
|
36
|
+
* since `<html>` is not a descendant of the scoping root; the property then
|
|
37
|
+
* reads empty while the stylesheet is present and working. So an empty read
|
|
38
|
+
* falls back to scanning the document's sheets for the sentinel.
|
|
31
39
|
*
|
|
32
40
|
* Only meaningful once the document's stylesheets have been applied — a host
|
|
33
41
|
* that loads CSS via an async `<link>` reads as missing until it lands.
|
|
@@ -17,14 +17,15 @@
|
|
|
17
17
|
*
|
|
18
18
|
* The CSS text is passed in rather than imported here: this package builds with
|
|
19
19
|
* plain `tsc`, so it cannot inline a stylesheet. Bundler-built player packages
|
|
20
|
-
* import it with Vite's `?
|
|
20
|
+
* import it with Vite's `?raw` and hand the text over.
|
|
21
21
|
*/
|
|
22
22
|
/** Marks a `<style>` element this module owns, and keeps installs idempotent. */
|
|
23
23
|
const MARKER_ATTRIBUTE = "data-pie-content-styles";
|
|
24
24
|
/**
|
|
25
25
|
* Declared by `components.css` itself, so it is observable no matter how the
|
|
26
|
-
* stylesheet arrived — our injection or a host import.
|
|
27
|
-
* that opted out
|
|
26
|
+
* stylesheet arrived — our injection or a host import. Diagnostics only: it
|
|
27
|
+
* tells a host that opted out and then shipped nothing, and it spots a host copy
|
|
28
|
+
* sitting alongside ours.
|
|
28
29
|
*/
|
|
29
30
|
const SENTINEL_PROPERTY = "--pie-content-styles";
|
|
30
31
|
// Svelte's dev-mode custom-element reset expands `all: unset` into individual
|
|
@@ -43,7 +44,22 @@ const declaresContentStylesSentinel = (rule) => {
|
|
|
43
44
|
?.getPropertyValue(SENTINEL_PROPERTY)
|
|
44
45
|
.trim()
|
|
45
46
|
.toLowerCase();
|
|
46
|
-
|
|
47
|
+
if (value)
|
|
48
|
+
return !CSS_WIDE_RESET_VALUES.has(value);
|
|
49
|
+
// Grouping rules hold no declarations of their own, so the sentinel sits one
|
|
50
|
+
// or more levels down. A host that confines its copy — `@scope
|
|
51
|
+
// (.item-content) { … }`, `@layer pie-content { … }` — presents exactly one
|
|
52
|
+
// top-level rule with an empty `.style`, and a top-level-only scan reads that
|
|
53
|
+
// as "no copy here". That made both detection paths blind to the one host
|
|
54
|
+
// configuration this module most needs to recognise.
|
|
55
|
+
const nested = rule.cssRules;
|
|
56
|
+
if (!nested)
|
|
57
|
+
return false;
|
|
58
|
+
for (const child of Array.from(nested)) {
|
|
59
|
+
if (declaresContentStylesSentinel(child))
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
47
63
|
};
|
|
48
64
|
/** `<html data-pie-content-styles="host">` opts a host out of installation. */
|
|
49
65
|
const OPT_OUT_ATTRIBUTE = "data-pie-content-styles";
|
|
@@ -59,8 +75,16 @@ export function contentStylesOptedOut() {
|
|
|
59
75
|
return (document.documentElement.getAttribute(OPT_OUT_ATTRIBUTE) === OPT_OUT_VALUE);
|
|
60
76
|
}
|
|
61
77
|
/**
|
|
62
|
-
* True when `components.css` is applied to the document, by any route.
|
|
63
|
-
*
|
|
78
|
+
* True when `components.css` is applied to the document, by any route.
|
|
79
|
+
*
|
|
80
|
+
* Two probes, because neither alone covers both deliveries. The computed
|
|
81
|
+
* sentinel on `<html>` is authoritative for a stylesheet applying to the whole
|
|
82
|
+
* document. A host that confines its copy to its player subtree — `@scope
|
|
83
|
+
* (.item-content) { … }`, the documented remedy for these rules reaching host
|
|
84
|
+
* chrome — puts the stylesheet's `:root` rule somewhere it can never match,
|
|
85
|
+
* since `<html>` is not a descendant of the scoping root; the property then
|
|
86
|
+
* reads empty while the stylesheet is present and working. So an empty read
|
|
87
|
+
* falls back to scanning the document's sheets for the sentinel.
|
|
64
88
|
*
|
|
65
89
|
* Only meaningful once the document's stylesheets have been applied — a host
|
|
66
90
|
* that loads CSS via an async `<link>` reads as missing until it lands.
|
|
@@ -71,7 +95,9 @@ export function contentStylesPresent() {
|
|
|
71
95
|
const value = getComputedStyle(document.documentElement)
|
|
72
96
|
.getPropertyValue(SENTINEL_PROPERTY)
|
|
73
97
|
.trim();
|
|
74
|
-
|
|
98
|
+
if (value !== "")
|
|
99
|
+
return true;
|
|
100
|
+
return countContentStyleSheets({ excludeInstalled: false }) > 0;
|
|
75
101
|
}
|
|
76
102
|
/**
|
|
77
103
|
* Installs `cssText` as a document-level stylesheet, once per document.
|
|
@@ -109,21 +135,22 @@ export function installContentStyles(cssText, source) {
|
|
|
109
135
|
return "installed";
|
|
110
136
|
}
|
|
111
137
|
/**
|
|
112
|
-
* Counts content stylesheets in the document
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
138
|
+
* Counts content stylesheets in the document, detected by the sentinel property
|
|
139
|
+
* rather than by URL, so a copy arriving as a `<link>`, a bundler-injected
|
|
140
|
+
* `<style>`, or anything else all count the same. `excludeInstalled` narrows the
|
|
141
|
+
* count to copies the host loaded itself.
|
|
116
142
|
*
|
|
117
143
|
* Cross-origin sheets throw on `cssRules` access and are skipped; a host copy
|
|
118
144
|
* served from another origin therefore reads as absent. That only costs a
|
|
119
145
|
* diagnostic, never correctness.
|
|
120
146
|
*/
|
|
121
|
-
const
|
|
147
|
+
const countContentStyleSheets = ({ excludeInstalled, }) => {
|
|
122
148
|
// Walks the owning elements rather than document.styleSheets: the marker
|
|
123
149
|
// attribute lives on the element, and CSSStyleSheet.ownerNode is not
|
|
124
150
|
// universally implemented (happy-dom omits it), which would make our own
|
|
125
151
|
// installed copy look like a host copy.
|
|
126
|
-
const
|
|
152
|
+
const exclusion = excludeInstalled ? `:not([${MARKER_ATTRIBUTE}])` : "";
|
|
153
|
+
const nodes = document.querySelectorAll(`style${exclusion}, link[rel~="stylesheet"]${exclusion}`);
|
|
127
154
|
let count = 0;
|
|
128
155
|
for (const node of Array.from(nodes)) {
|
|
129
156
|
let rules;
|
|
@@ -144,6 +171,8 @@ const countHostContentStyleSheets = () => {
|
|
|
144
171
|
}
|
|
145
172
|
return count;
|
|
146
173
|
};
|
|
174
|
+
/** Copies the host loaded itself, i.e. not the one this module installed. */
|
|
175
|
+
const countHostContentStyleSheets = () => countContentStyleSheets({ excludeInstalled: true });
|
|
147
176
|
let auditWarningIssued = false;
|
|
148
177
|
const pendingChecks = [];
|
|
149
178
|
/**
|