@percy/dom 1.32.3-beta.1 → 1.32.3-beta.3
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/bundle.js +31 -3
- package/package.json +2 -2
package/dist/bundle.js
CHANGED
|
@@ -1030,10 +1030,26 @@
|
|
|
1030
1030
|
return decls.join(' ');
|
|
1031
1031
|
}
|
|
1032
1032
|
|
|
1033
|
+
// Resolve a nested rule's selector against its parent per CSS Nesting.
|
|
1034
|
+
// The CSSOM serializes nested selectors with the implicit nesting selector
|
|
1035
|
+
// made explicit, so every nested selector — including each item of a
|
|
1036
|
+
// selector list — carries its own `&`. Replacing every `&` with :is(parent)
|
|
1037
|
+
// therefore fully scopes the rule. Without this, a bare top-level `&`
|
|
1038
|
+
// resolves to :root on engines that support nesting, so component-scoped
|
|
1039
|
+
// interactive-state rules leak page-wide (PER-9775). :is(...) preserves the
|
|
1040
|
+
// parent's grouping/specificity.
|
|
1041
|
+
function resolveNestedSelector(selectorText, parentSelector) {
|
|
1042
|
+
if (!parentSelector) return selectorText;
|
|
1043
|
+
return selectorText.replace(/&/g, `:is(${parentSelector})`);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1033
1046
|
// Walk a CSSRule list yielding every reachable style rule. Nested rules
|
|
1034
1047
|
// inside @media/@layer/@supports are emitted with the at-rule prelude
|
|
1035
1048
|
// preserved as a wrapper string; flat-emitting would drop the guard.
|
|
1036
|
-
|
|
1049
|
+
// `parentSelector` carries the enclosing style rule's (already-resolved)
|
|
1050
|
+
// selector down through native CSS nesting so `&`-relative children are
|
|
1051
|
+
// resolved against it rather than leaking as a bare top-level `&`.
|
|
1052
|
+
function walkCSSRules(ruleList, parentSelector = null) {
|
|
1037
1053
|
const result = [];
|
|
1038
1054
|
for (let i = 0; i < ruleList.length; i++) {
|
|
1039
1055
|
const rule = ruleList[i];
|
|
@@ -1042,7 +1058,19 @@
|
|
|
1042
1058
|
var _rule$media;
|
|
1043
1059
|
const conditionText = rule.conditionText || ((_rule$media = rule.media) === null || _rule$media === void 0 ? void 0 : _rule$media.mediaText);
|
|
1044
1060
|
const atRulePrelude = conditionText && rule.cssText ? rule.cssText.split('{')[0].trim() : null;
|
|
1045
|
-
|
|
1061
|
+
// An at-rule (@media/@layer/@supports) keeps the current parent scope
|
|
1062
|
+
// and is re-applied as a wrapper. A style rule with nested children
|
|
1063
|
+
// (native CSS nesting) becomes the scope for its children — resolve
|
|
1064
|
+
// its own selector against any outer parent first so deeper nesting
|
|
1065
|
+
// composes correctly.
|
|
1066
|
+
// Default to the current scope (also covers at-rules and nested-decl
|
|
1067
|
+
// rules that have no selector of their own). A style rule with nested
|
|
1068
|
+
// children resolves its own selector first and becomes the new scope.
|
|
1069
|
+
let childParent = parentSelector;
|
|
1070
|
+
if (!atRulePrelude && rule.selectorText) {
|
|
1071
|
+
childParent = resolveNestedSelector(rule.selectorText, parentSelector);
|
|
1072
|
+
}
|
|
1073
|
+
for (const inner of walkCSSRules(rule.cssRules, childParent)) {
|
|
1046
1074
|
if (atRulePrelude && inner.selectorText) {
|
|
1047
1075
|
result.push({
|
|
1048
1076
|
selectorText: inner.selectorText,
|
|
@@ -1058,7 +1086,7 @@
|
|
|
1058
1086
|
// @charset, @counter-style, etc.) are skipped — they can't contain
|
|
1059
1087
|
// interactive pseudos.
|
|
1060
1088
|
result.push({
|
|
1061
|
-
selectorText: rule.selectorText,
|
|
1089
|
+
selectorText: resolveNestedSelector(rule.selectorText, parentSelector),
|
|
1062
1090
|
style: rule.style,
|
|
1063
1091
|
wrapper: null
|
|
1064
1092
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/dom",
|
|
3
|
-
"version": "1.32.3-beta.
|
|
3
|
+
"version": "1.32.3-beta.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"interactor.js": "^2.0.0-beta.10"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "f2029c138431bb176dd41ea0d1df1f3a3120cc8d"
|
|
39
39
|
}
|