@percy/dom 1.31.0-alpha.3 → 1.31.0
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 +88 -13
- package/package.json +3 -3
package/dist/bundle.js
CHANGED
|
@@ -314,9 +314,21 @@
|
|
|
314
314
|
/* istanbul ignore next: tested, but coverage is stripped */
|
|
315
315
|
if (clone.constructor.name === 'HTMLDocument' || clone.constructor.name === 'DocumentFragment') {
|
|
316
316
|
// handle document and iframe
|
|
317
|
-
clone.body
|
|
317
|
+
// We are checking if we have multiple stylesheets present for the same clone or clone.body then we add
|
|
318
|
+
// them in the same order in which we receive them.
|
|
319
|
+
const lastLink = clone.body.querySelector('link[data-percy-adopted-stylesheets-serialized]:last-of-type');
|
|
320
|
+
if (lastLink) {
|
|
321
|
+
lastLink.after(styleLink);
|
|
322
|
+
} else {
|
|
323
|
+
clone.body.prepend(styleLink);
|
|
324
|
+
}
|
|
318
325
|
} else if (clone.constructor.name === 'ShadowRoot') {
|
|
319
|
-
clone.
|
|
326
|
+
const lastLink = clone.querySelector('link[data-percy-adopted-stylesheets-serialized]:last-of-type');
|
|
327
|
+
if (lastLink) {
|
|
328
|
+
lastLink.after(styleLink);
|
|
329
|
+
} else {
|
|
330
|
+
clone.prepend(styleLink);
|
|
331
|
+
}
|
|
320
332
|
}
|
|
321
333
|
}
|
|
322
334
|
} else {
|
|
@@ -441,7 +453,7 @@
|
|
|
441
453
|
base64Index += ';base64,'.length;
|
|
442
454
|
return src.substring(base64Index);
|
|
443
455
|
}
|
|
444
|
-
function serializeBase64(node, resources) {
|
|
456
|
+
function serializeBase64(node, resources, cache) {
|
|
445
457
|
let src = node.src;
|
|
446
458
|
let isHrefUsed = false;
|
|
447
459
|
|
|
@@ -455,14 +467,28 @@
|
|
|
455
467
|
let base64String = getBase64Substring(src.toString());
|
|
456
468
|
// skip if src is not base64
|
|
457
469
|
if (base64String == null) return;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
470
|
+
if (!cache.has(base64String)) {
|
|
471
|
+
// create a resource from the serialized data url
|
|
472
|
+
let resource = resourceFromText(uid(), mimetype, base64String);
|
|
473
|
+
resources.add(resource);
|
|
474
|
+
cache.set(base64String, resource.url);
|
|
475
|
+
}
|
|
462
476
|
if (isHrefUsed === true) {
|
|
463
|
-
node.href
|
|
477
|
+
if (node.hasAttribute('xlink:href')) {
|
|
478
|
+
node.removeAttribute('xlink:href');
|
|
479
|
+
node.setAttribute('data-percy-serialized-attribute-xlink:href', cache.get(base64String));
|
|
480
|
+
} else {
|
|
481
|
+
node.removeAttribute('href');
|
|
482
|
+
node.setAttribute('data-percy-serialized-attribute-href', cache.get(base64String));
|
|
483
|
+
}
|
|
464
484
|
} else {
|
|
465
|
-
|
|
485
|
+
// we use data-percy-serialized-attribute-src here instead of `src`.
|
|
486
|
+
// As soon as src is used the browser will try to load the resource,
|
|
487
|
+
// thus making a network call which would fail as this is a
|
|
488
|
+
// dynamic cached resource and not a resource that backend can serve.
|
|
489
|
+
// we later post converting domtree to html replace this with src
|
|
490
|
+
node.removeAttribute('src');
|
|
491
|
+
node.setAttribute('data-percy-serialized-attribute-src', cache.get(base64String));
|
|
466
492
|
}
|
|
467
493
|
}
|
|
468
494
|
|
|
@@ -478,11 +504,36 @@
|
|
|
478
504
|
*/
|
|
479
505
|
|
|
480
506
|
const ignoreTags = ['NOSCRIPT'];
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* if a custom element has attribute callback then cloneNode calls a callback that can
|
|
510
|
+
* increase CPU load or some other change.
|
|
511
|
+
* So we want to make sure that it is not called when doing serialization.
|
|
512
|
+
*/
|
|
513
|
+
function cloneElementWithoutLifecycle(element) {
|
|
514
|
+
if (!element.attributeChangedCallback || !element.tagName.includes('-')) {
|
|
515
|
+
return element.cloneNode(); // Standard clone for non-custom elements
|
|
516
|
+
}
|
|
517
|
+
const cloned = document.createElement('data-percy-custom-element-' + element.tagName);
|
|
518
|
+
|
|
519
|
+
// Clone attributes without triggering attributeChangedCallback
|
|
520
|
+
for (const attr of element.attributes) {
|
|
521
|
+
// handle src separately
|
|
522
|
+
if (attr.name.toLowerCase() === 'src') {
|
|
523
|
+
cloned.setAttribute('data-percy-serialized-attribute-src', attr.value);
|
|
524
|
+
} else {
|
|
525
|
+
cloned.setAttribute(attr.name, attr.value);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return cloned;
|
|
529
|
+
}
|
|
481
530
|
function cloneNodeAndShadow(ctx) {
|
|
482
531
|
let {
|
|
483
532
|
dom,
|
|
484
533
|
disableShadowDOM,
|
|
485
|
-
resources
|
|
534
|
+
resources,
|
|
535
|
+
cache,
|
|
536
|
+
enableJavaScript
|
|
486
537
|
} = ctx;
|
|
487
538
|
// clones shadow DOM and light DOM for a given node
|
|
488
539
|
let cloneNode = (node, parent) => {
|
|
@@ -498,15 +549,36 @@
|
|
|
498
549
|
|
|
499
550
|
// mark the node before cloning
|
|
500
551
|
markElement(node, disableShadowDOM);
|
|
501
|
-
let clone = node
|
|
552
|
+
let clone = cloneElementWithoutLifecycle(node);
|
|
553
|
+
|
|
554
|
+
// Handle <style> tag specifically for media queries
|
|
555
|
+
if (node.nodeName === 'STYLE' && !enableJavaScript) {
|
|
556
|
+
var _node$textContent;
|
|
557
|
+
let cssText = ((_node$textContent = node.textContent) === null || _node$textContent === void 0 ? void 0 : _node$textContent.trim()) || '';
|
|
558
|
+
if (!cssText && node.sheet) {
|
|
559
|
+
try {
|
|
560
|
+
const cssRules = node.sheet.cssRules;
|
|
561
|
+
if (cssRules && cssRules.length > 0) {
|
|
562
|
+
cssText = Array.from(cssRules).map(rule => rule.cssText).join('\n');
|
|
563
|
+
}
|
|
564
|
+
} catch (_) {
|
|
565
|
+
// ignore errors
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
if (cssText) {
|
|
569
|
+
clone.textContent = cssText;
|
|
570
|
+
clone.setAttribute('data-percy-cssom-serialized', 'true');
|
|
571
|
+
}
|
|
572
|
+
}
|
|
502
573
|
|
|
503
574
|
// We apply any element transformations here to avoid another treeWalk
|
|
504
575
|
applyElementTransformations(clone);
|
|
505
|
-
serializeBase64(clone, resources);
|
|
576
|
+
serializeBase64(clone, resources, cache);
|
|
506
577
|
parent.appendChild(clone);
|
|
507
578
|
|
|
508
579
|
// shallow clone should not contain children
|
|
509
580
|
if (clone.children) {
|
|
581
|
+
/* istanbul ignore next */
|
|
510
582
|
Array.from(clone.children).forEach(child => clone.removeChild(child));
|
|
511
583
|
}
|
|
512
584
|
|
|
@@ -598,6 +670,8 @@
|
|
|
598
670
|
let html = getOuterHTML(ctx.clone.documentElement, {
|
|
599
671
|
shadowRootElements: ctx.shadowRootElements
|
|
600
672
|
});
|
|
673
|
+
// this is replacing serialized data tag with real tag
|
|
674
|
+
html = html.replace(/(<\/?)data-percy-custom-element-/g, '$1');
|
|
601
675
|
// replace serialized data attributes with real attributes
|
|
602
676
|
html = html.replace(/ data-percy-serialized-attribute-(\w+?)=/ig, ' $1=');
|
|
603
677
|
// include the doctype with the html string
|
|
@@ -647,6 +721,7 @@
|
|
|
647
721
|
|
|
648
722
|
// Serializes a document and returns the resulting DOM string.
|
|
649
723
|
function serializeDOM(options) {
|
|
724
|
+
var _ctx$clone$body;
|
|
650
725
|
let {
|
|
651
726
|
dom = document,
|
|
652
727
|
// allow snake_case or camelCase
|
|
@@ -687,7 +762,7 @@
|
|
|
687
762
|
let sibling = clonedBody.nextSibling;
|
|
688
763
|
clonedBody.append(sibling);
|
|
689
764
|
}
|
|
690
|
-
} else if (ctx.clone.body.nextSibling) {
|
|
765
|
+
} else if ((_ctx$clone$body = ctx.clone.body) !== null && _ctx$clone$body !== void 0 && _ctx$clone$body.nextSibling) {
|
|
691
766
|
ctx.hints.add('DOM elements found outside </body>');
|
|
692
767
|
}
|
|
693
768
|
let cookies = '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/dom",
|
|
3
|
-
"version": "1.31.0
|
|
3
|
+
"version": "1.31.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public",
|
|
12
|
-
"tag": "
|
|
12
|
+
"tag": "latest"
|
|
13
13
|
},
|
|
14
14
|
"main": "dist/bundle.js",
|
|
15
15
|
"browser": "dist/bundle.js",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"interactor.js": "^2.0.0-beta.10"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "49895470c0dfa7242881db43e293317d1fb8f8b6"
|
|
39
39
|
}
|