@percy/dom 1.32.11-beta.0 → 1.32.11-beta.2

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 +41 -5
  2. package/package.json +2 -2
package/dist/bundle.js CHANGED
@@ -102,6 +102,9 @@
102
102
  try {
103
103
  let inputId = elem.getAttribute('data-percy-element-id');
104
104
  let cloneEl = clone.querySelector(`[data-percy-element-id="${inputId}"]`);
105
+ // no counterpart in the clone means the element wasn't serialized — e.g.
106
+ // light DOM content no <slot> projected, which the browser doesn't render
107
+ if (!cloneEl) continue;
105
108
  switch (elem.type) {
106
109
  case 'checkbox':
107
110
  case 'radio':
@@ -295,12 +298,12 @@
295
298
  try {
296
299
  cloneEl.setAttribute('srcdoc', p.createHTML ? p.createHTML(serialized.html) : serialized.html);
297
300
  } catch {}
298
- cloneEl.removeAttribute('src');
301
+ cloneEl === null || cloneEl === void 0 || cloneEl.removeAttribute('src');
299
302
 
300
303
  // delete inaccessible frames built with js when js is disabled because they
301
304
  // break asset discovery by creating non-captured requests that hang
302
305
  } else if (!enableJavaScript && builtWithJs) {
303
- cloneEl.remove();
306
+ cloneEl === null || cloneEl === void 0 || cloneEl.remove();
304
307
  }
305
308
  }
306
309
  }
@@ -590,6 +593,10 @@
590
593
  // skip empty canvases
591
594
  if (!dataUrl || dataUrl === 'data:,') continue;
592
595
 
596
+ // no counterpart in the clone means the canvas wasn't serialized — e.g.
597
+ // light DOM content no <slot> projected, which the browser doesn't render
598
+ if (!clone.querySelector(`[data-percy-element-id=${percyElementId}]`)) continue;
599
+
593
600
  // create a resource for the canvas data
594
601
  let resource = resourceFromDataURL(percyElementId, dataUrl);
595
602
  resources.add(resource);
@@ -627,6 +634,9 @@
627
634
  if (video.getAttribute('poster')) continue;
628
635
  let videoId = video.getAttribute('data-percy-element-id');
629
636
  let cloneEl = clone.querySelector(`[data-percy-element-id="${videoId}"]`);
637
+ // no counterpart in the clone means the element wasn't serialized — e.g.
638
+ // light DOM content no <slot> projected, which the browser doesn't render
639
+ if (!cloneEl) continue;
630
640
  let canvas = document.createElement('canvas');
631
641
  let width = canvas.width = video.videoWidth;
632
642
  let height = canvas.height = video.videoHeight;
@@ -1424,6 +1434,7 @@
1424
1434
  // clones shadow DOM and light DOM for a given node
1425
1435
  let cloneNode = (node, parent) => {
1426
1436
  try {
1437
+ var _node$getRootNode;
1427
1438
  let walkTree = (nextn, nextp) => {
1428
1439
  while (nextn) {
1429
1440
  if (!ignoreTags.includes(nextn.nodeName)) {
@@ -1438,6 +1449,25 @@
1438
1449
  return;
1439
1450
  }
1440
1451
 
1452
+ // Slotted content lives in the host's light DOM and is only *rendered* at
1453
+ // the slot's position by the shadow root. Flattening the root away leaves
1454
+ // an inert <slot> and strands that content outside its container, so
1455
+ // resolve the projection here instead (PER-10812). Every shadow root is
1456
+ // flattened when forceShadowAsLightDOM is set, so any slot belonging to
1457
+ // one needs resolving — including slots reached indirectly, as projected
1458
+ // content nested inside another component's slotted markup. The slot
1459
+ // itself never renders and isn't cloned.
1460
+ if (forceShadowAsLightDOM && node.nodeName === 'SLOT' && typeof node.assignedNodes === 'function' && (_node$getRootNode = node.getRootNode()) !== null && _node$getRootNode !== void 0 && _node$getRootNode.host) {
1461
+ for (let assigned of node.assignedNodes({
1462
+ flatten: true
1463
+ })) {
1464
+ if (!ignoreTags.includes(assigned.nodeName)) {
1465
+ cloneNode(assigned, parent);
1466
+ }
1467
+ }
1468
+ return;
1469
+ }
1470
+
1441
1471
  // mark the node before cloning
1442
1472
  markElement(node, disableShadowDOM, forceShadowAsLightDOM);
1443
1473
  let clone = cloneElementWithoutLifecycle(node);
@@ -1483,8 +1513,10 @@
1483
1513
  // clone shadow DOM (including closed shadow roots captured via CDP
1484
1514
  // and stored on window.__percyClosedShadowRoots)
1485
1515
  let nodeShadowRoot = node.shadowRoot || getClosedShadowRoot(node);
1516
+ let flattenedHost = false;
1486
1517
  if (nodeShadowRoot && !disableShadowDOM) {
1487
- if (forceShadowAsLightDOM) {
1518
+ flattenedHost = !!forceShadowAsLightDOM;
1519
+ if (flattenedHost) {
1488
1520
  // When forceShadowAsLightDOM is true, treat shadow content as normal DOM
1489
1521
  walkTree(nodeShadowRoot.firstChild, clone);
1490
1522
  } else {
@@ -1503,8 +1535,12 @@
1503
1535
  }
1504
1536
  }
1505
1537
 
1506
- // clone light DOM
1507
- walkTree(node.firstChild, clone);
1538
+ // clone light DOM — skipped for a flattened host, whose light children were
1539
+ // already placed at their <slot> positions above. Children assigned to no
1540
+ // slot are dropped, matching what the browser renders for them: nothing.
1541
+ if (!flattenedHost) {
1542
+ walkTree(node.firstChild, clone);
1543
+ }
1508
1544
  } catch (err) {
1509
1545
  if (!err.handled) {
1510
1546
  handleErrors(err, 'Error cloning node: ', node);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/dom",
3
- "version": "1.32.11-beta.0",
3
+ "version": "1.32.11-beta.2",
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": "db20253878f6ee43d2c277698ba021ae41adaa86"
38
+ "gitHead": "a05b0ac1efc0d136fa15c2330b55e1e207c6e797"
39
39
  }