@percy/dom 1.32.8-beta.2 → 1.32.8-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.
Files changed (2) hide show
  1. package/dist/bundle.js +49 -11
  2. package/package.json +2 -2
package/dist/bundle.js CHANGED
@@ -209,7 +209,9 @@
209
209
  ignoreIframeSelectors,
210
210
  forceShadowAsLightDOM,
211
211
  maxIframeDepth,
212
- iframeDepth = 0
212
+ iframeDepth = 0,
213
+ pseudoClassEnabledElements,
214
+ pseudoClassSerialization
213
215
  }) {
214
216
  maxIframeDepth = clampIframeDepth(maxIframeDepth);
215
217
  for (let frame of dom.querySelectorAll('iframe')) {
@@ -278,7 +280,9 @@
278
280
  forceShadowAsLightDOM,
279
281
  ignoreIframeSelectors,
280
282
  maxIframeDepth,
281
- iframeDepth: iframeDepth + 1
283
+ iframeDepth: iframeDepth + 1,
284
+ pseudoClassEnabledElements,
285
+ enablePseudoClassSerialization: pseudoClassSerialization
282
286
  });
283
287
 
284
288
  // append serialized warnings and resources
@@ -778,6 +782,35 @@
778
782
  return re.test(selectorText);
779
783
  });
780
784
  }
785
+ function splitSelectorList(selectorText) {
786
+ const parts = [];
787
+ let depth = 0;
788
+ let quote = null;
789
+ let start = 0;
790
+ for (let i = 0; i < selectorText.length; i++) {
791
+ const char = selectorText[i];
792
+ if (quote) {
793
+ if (char === '\\') i++;else if (char === quote) quote = null;
794
+ continue;
795
+ }
796
+ if (char === '"' || char === "'") quote = char;else if (char === '(' || char === '[') depth++;else if (char === ')' || char === ']') depth--;else if (char === ',' && depth === 0) {
797
+ parts.push(selectorText.slice(start, i));
798
+ start = i + 1;
799
+ }
800
+ }
801
+ parts.push(selectorText.slice(start));
802
+ return parts;
803
+ }
804
+ function rewritePseudoSelectorList(selectorText, pseudoList) {
805
+ const pseudoParts = [];
806
+ for (const part of splitSelectorList(selectorText)) {
807
+ const trimmed = part.trim();
808
+ if (trimmed && selectorContainsPseudo(trimmed, pseudoList)) {
809
+ pseudoParts.push(rewritePseudoSelector(trimmed));
810
+ }
811
+ }
812
+ return pseudoParts.length ? pseudoParts.join(', ') : null;
813
+ }
781
814
  function rewritePseudoSelector(selectorText) {
782
815
  let out = selectorText;
783
816
  for (const [pseudo, re] of PSEUDO_RES) out = out.replace(re, PSEUDO_TO_ATTR[pseudo]);
@@ -978,8 +1011,9 @@
978
1011
  // the data-attributes are copied through to the clone via cloneNode.
979
1012
  function markPseudoClassElements(ctx, config) {
980
1013
  ctx._liveMutations = [];
981
- markInteractiveStates(ctx);
982
1014
  markOpenPopovers(ctx);
1015
+ if (!ctx.pseudoClassSerialization) return;
1016
+ markInteractiveStates(ctx);
983
1017
  if (config) getElementsToProcess(ctx, config, true);
984
1018
  }
985
1019
 
@@ -1118,8 +1152,8 @@
1118
1152
  // interactive pseudo. Skips most rules on most stylesheets without
1119
1153
  // touching the regex bank.
1120
1154
  if (!rule.selectorText.includes(':')) continue;
1121
- if (!selectorContainsPseudo(rule.selectorText, ALL_INTERACTIVE_PSEUDO)) continue;
1122
- const rewrittenSelector = rewritePseudoSelector(rule.selectorText);
1155
+ const rewrittenSelector = rewritePseudoSelectorList(rule.selectorText, ALL_INTERACTIVE_PSEUDO);
1156
+ if (!rewrittenSelector) continue;
1123
1157
  const cssText = `${rewrittenSelector} { ${rule.style.cssText} }`;
1124
1158
  const wrapped = rule.wrapper ? `${rule.wrapper} { ${cssText} }` : cssText;
1125
1159
  (rewrittenRules || (rewrittenRules = [])).push(wrapped);
@@ -1184,10 +1218,11 @@
1184
1218
  }
1185
1219
  }
1186
1220
  function serializePseudoClasses(ctx) {
1187
- // Auto-detect path runs unconditionally so `:focus`/`:focus-within`
1188
- // rules are rewritten regardless of whether the user configured a
1189
- // pseudoClassEnabledElements list (and regardless of whether that list
1190
- // matched anything on this page).
1221
+ if (!ctx.pseudoClassSerialization) return;
1222
+
1223
+ // Auto-detect path rewrites `:focus`/`:focus-within` rules whether or not
1224
+ // a pseudoClassEnabledElements list was configured (and regardless of
1225
+ // whether that list matched anything on this page).
1191
1226
  extractPseudoClassRules(ctx);
1192
1227
  if (!ctx.pseudoClassEnabledElements) return;
1193
1228
  const elements = ctx.dom.querySelectorAll(`[${PSEUDO_ELEMENT_MARKER_ATTR}]`);
@@ -1614,8 +1649,10 @@
1614
1649
  ignoreIframeSelectors = options === null || options === void 0 ? void 0 : options.ignore_iframe_selectors,
1615
1650
  maxIframeDepth = options === null || options === void 0 ? void 0 : options.max_iframe_depth,
1616
1651
  iframeDepth = (options === null || options === void 0 ? void 0 : options.iframe_depth) ?? 0,
1617
- pseudoClassEnabledElements = options === null || options === void 0 ? void 0 : options.pseudo_class_enabled_elements
1652
+ pseudoClassEnabledElements = options === null || options === void 0 ? void 0 : options.pseudo_class_enabled_elements,
1653
+ enablePseudoClassSerialization = options === null || options === void 0 ? void 0 : options.enable_pseudo_class_serialization
1618
1654
  } = options || {};
1655
+ const pseudoClassSerialization = !!(enablePseudoClassSerialization || pseudoClassEnabledElements);
1619
1656
 
1620
1657
  // keep certain records throughout serialization
1621
1658
  let ctx = {
@@ -1632,7 +1669,8 @@
1632
1669
  ignoreIframeSelectors,
1633
1670
  maxIframeDepth,
1634
1671
  iframeDepth,
1635
- pseudoClassEnabledElements
1672
+ pseudoClassEnabledElements,
1673
+ pseudoClassSerialization
1636
1674
  };
1637
1675
  ctx.dom = dom;
1638
1676
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/dom",
3
- "version": "1.32.8-beta.2",
3
+ "version": "1.32.8-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": "3886c115aa583e2c5af3b16643dd34c379415f5b"
38
+ "gitHead": "719021a0565d18a6b47d9d494961eaccb6d63009"
39
39
  }