@percy/dom 1.0.0-beta.9 → 1.0.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/README.md +23 -5
- package/dist/bundle.js +251 -0
- package/package.json +24 -31
- package/dist/index.js +0 -1
package/README.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Serializes a document's DOM into a DOM string suitable for re-rendering.
|
|
4
4
|
|
|
5
|
+
- [Usage](#usage)
|
|
6
|
+
- [ES6 imports](#es6-imports)
|
|
7
|
+
- [Browser injection](#browser-injection)
|
|
8
|
+
- [Options](#options)
|
|
9
|
+
- [Serialized Content](#serialize-content)
|
|
10
|
+
- [Input elements](#input-elements)
|
|
11
|
+
- [Frame elements](#frame-elements)
|
|
12
|
+
- [CSSOM rules](#cssom-rules)
|
|
13
|
+
- [Canvas elements](#canvas-elements)
|
|
14
|
+
- [Video elements](#video-elements)
|
|
15
|
+
- [Other elements](#other-elements)
|
|
16
|
+
|
|
5
17
|
## Usage
|
|
6
18
|
|
|
7
19
|
### ES6 imports
|
|
@@ -10,7 +22,7 @@ Serializes a document's DOM into a DOM string suitable for re-rendering.
|
|
|
10
22
|
import serializeDOM from '@percy/dom';
|
|
11
23
|
|
|
12
24
|
// optional arguments shown with defaults
|
|
13
|
-
const domSnapshot = serializeDOM(
|
|
25
|
+
const domSnapshot = serializeDOM(options)
|
|
14
26
|
```
|
|
15
27
|
|
|
16
28
|
### Browser injection
|
|
@@ -18,13 +30,13 @@ const domSnapshot = serializeDOM(/* options */)
|
|
|
18
30
|
```js
|
|
19
31
|
// via puppeteer
|
|
20
32
|
await page.addScriptTag({ path: require.resolve('@percy/dom') })
|
|
21
|
-
const domSnapshot = await page.evaluate(() => PercyDOM.serialize(
|
|
33
|
+
const domSnapshot = await page.evaluate(() => PercyDOM.serialize(options))
|
|
22
34
|
```
|
|
23
35
|
|
|
24
|
-
###
|
|
36
|
+
### Options
|
|
25
37
|
|
|
26
|
-
- `enableJavaScript`
|
|
27
|
-
- `domTransformation`
|
|
38
|
+
- `enableJavaScript` — When true, does not serialize some DOM elements
|
|
39
|
+
- `domTransformation` — Function to transform the DOM after serialization
|
|
28
40
|
|
|
29
41
|
## Serialized Content
|
|
30
42
|
|
|
@@ -53,6 +65,12 @@ with image elements. The image elements reference the serialized data URI and ha
|
|
|
53
65
|
attributes as their respective canvas elements. The image elements also have a max-width of 100% to
|
|
54
66
|
accomidate responsive layouts in situations where canvases may be expected to resize with JS.
|
|
55
67
|
|
|
68
|
+
### Video elements
|
|
69
|
+
|
|
70
|
+
Videos without a `poster` attribute will have the current frame of the video
|
|
71
|
+
serialized into an image and set as the `poster` attribute automatically. This is
|
|
72
|
+
to ensure videos have a stable image to display when screenshots are captured.
|
|
73
|
+
|
|
56
74
|
### Other elements
|
|
57
75
|
|
|
58
76
|
_All other elements are not serialized._ The resulting cloned document is passed to any provided
|
package/dist/bundle.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
(function (exports) {
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const process = (typeof globalThis !== "undefined" && globalThis.process) || {};
|
|
6
|
+
process.env = process.env || {};
|
|
7
|
+
process.env.__PERCY_BROWSERIFIED__ = true;
|
|
8
|
+
|
|
9
|
+
// Returns a mostly random uid.
|
|
10
|
+
function uid() {
|
|
11
|
+
return `_${Math.random().toString(36).substr(2, 9)}`;
|
|
12
|
+
} // Marks elements that are to be serialized later with a data attribute.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
function prepareDOM(dom) {
|
|
16
|
+
for (let elem of dom.querySelectorAll('input, textarea, select, iframe, canvas, video, style')) {
|
|
17
|
+
if (!elem.getAttribute('data-percy-element-id')) {
|
|
18
|
+
elem.setAttribute('data-percy-element-id', uid());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Translates JavaScript properties of inputs into DOM attributes.
|
|
24
|
+
function serializeInputElements(dom, clone) {
|
|
25
|
+
for (let elem of dom.querySelectorAll('input, textarea, select')) {
|
|
26
|
+
let inputId = elem.getAttribute('data-percy-element-id');
|
|
27
|
+
let cloneEl = clone.querySelector(`[data-percy-element-id="${inputId}"]`);
|
|
28
|
+
|
|
29
|
+
switch (elem.type) {
|
|
30
|
+
case 'checkbox':
|
|
31
|
+
case 'radio':
|
|
32
|
+
if (elem.checked) {
|
|
33
|
+
cloneEl.setAttribute('checked', '');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
break;
|
|
37
|
+
|
|
38
|
+
case 'select-one':
|
|
39
|
+
if (elem.selectedIndex !== -1) {
|
|
40
|
+
cloneEl.options[elem.selectedIndex].setAttribute('selected', 'true');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
break;
|
|
44
|
+
|
|
45
|
+
case 'select-multiple':
|
|
46
|
+
for (let option of elem.selectedOptions) {
|
|
47
|
+
cloneEl.options[option.index].setAttribute('selected', 'true');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
break;
|
|
51
|
+
|
|
52
|
+
case 'textarea':
|
|
53
|
+
cloneEl.innerHTML = elem.value;
|
|
54
|
+
break;
|
|
55
|
+
|
|
56
|
+
default:
|
|
57
|
+
cloneEl.setAttribute('value', elem.value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// embedded documents are serialized and their contents become root-relative.
|
|
63
|
+
|
|
64
|
+
function setBaseURI(dom) {
|
|
65
|
+
if (!new URL(dom.baseURI).hostname) return;
|
|
66
|
+
let $base = document.createElement('base');
|
|
67
|
+
$base.href = dom.baseURI;
|
|
68
|
+
dom.querySelector('head').prepend($base);
|
|
69
|
+
} // Recursively serializes iframe documents into srcdoc attributes.
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
function serializeFrames(dom, clone, _ref) {
|
|
73
|
+
let {
|
|
74
|
+
enableJavaScript
|
|
75
|
+
} = _ref;
|
|
76
|
+
|
|
77
|
+
for (let frame of dom.querySelectorAll('iframe')) {
|
|
78
|
+
let percyElementId = frame.getAttribute('data-percy-element-id');
|
|
79
|
+
let cloneEl = clone.querySelector(`[data-percy-element-id="${percyElementId}"]`);
|
|
80
|
+
let builtWithJs = !frame.srcdoc && (!frame.src || frame.src.split(':')[0] === 'javascript'); // delete frames within the head since they usually break pages when
|
|
81
|
+
// rerendered and do not effect the visuals of a page
|
|
82
|
+
|
|
83
|
+
if (clone.head.contains(cloneEl)) {
|
|
84
|
+
cloneEl.remove(); // if the frame document is accessible and not empty, we can serialize it
|
|
85
|
+
} else if (frame.contentDocument && frame.contentDocument.documentElement) {
|
|
86
|
+
// js is enabled and this frame was built with js, don't serialize it
|
|
87
|
+
if (enableJavaScript && builtWithJs) continue; // the frame has yet to load and wasn't built with js, it is unsafe to serialize
|
|
88
|
+
|
|
89
|
+
if (!builtWithJs && !frame.contentWindow.performance.timing.loadEventEnd) continue; // recersively serialize contents
|
|
90
|
+
|
|
91
|
+
let serialized = serializeDOM({
|
|
92
|
+
domTransformation: setBaseURI,
|
|
93
|
+
dom: frame.contentDocument,
|
|
94
|
+
enableJavaScript
|
|
95
|
+
}); // assign to srcdoc and remove src
|
|
96
|
+
|
|
97
|
+
cloneEl.setAttribute('srcdoc', serialized);
|
|
98
|
+
cloneEl.removeAttribute('src'); // delete inaccessible frames built with js when js is disabled because they
|
|
99
|
+
// break asset discovery by creating non-captured requests that hang
|
|
100
|
+
} else if (!enableJavaScript && builtWithJs) {
|
|
101
|
+
cloneEl.remove();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Returns true if a stylesheet is a CSSOM-based stylesheet.
|
|
107
|
+
function isCSSOM(styleSheet) {
|
|
108
|
+
var _styleSheet$ownerNode, _styleSheet$ownerNode2;
|
|
109
|
+
|
|
110
|
+
// no href, has a rulesheet, and isn't already in the DOM
|
|
111
|
+
return !styleSheet.href && styleSheet.cssRules && !((_styleSheet$ownerNode = styleSheet.ownerNode) !== null && _styleSheet$ownerNode !== void 0 && (_styleSheet$ownerNode2 = _styleSheet$ownerNode.innerText) !== null && _styleSheet$ownerNode2 !== void 0 && _styleSheet$ownerNode2.trim().length);
|
|
112
|
+
} // Outputs in-memory CSSOM into their respective DOM nodes.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
function serializeCSSOM(dom, clone) {
|
|
116
|
+
for (let styleSheet of dom.styleSheets) {
|
|
117
|
+
if (isCSSOM(styleSheet)) {
|
|
118
|
+
let style = clone.createElement('style');
|
|
119
|
+
let styleId = styleSheet.ownerNode.getAttribute('data-percy-element-id');
|
|
120
|
+
let cloneOwnerNode = clone.querySelector(`[data-percy-element-id="${styleId}"]`);
|
|
121
|
+
style.type = 'text/css';
|
|
122
|
+
style.setAttribute('data-percy-cssom-serialized', 'true');
|
|
123
|
+
style.innerHTML = Array.from(styleSheet.cssRules).reduce((prev, cssRule) => prev + cssRule.cssText, '');
|
|
124
|
+
cloneOwnerNode.parentNode.insertBefore(style, cloneOwnerNode.nextSibling);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Serialize in-memory canvas elements into images.
|
|
130
|
+
function serializeCanvas(dom, clone) {
|
|
131
|
+
for (let canvas of dom.querySelectorAll('canvas')) {
|
|
132
|
+
// Note: the `.toDataURL` API requires WebGL canvas elements to use
|
|
133
|
+
// `preserveDrawingBuffer: true`. This is because `.toDataURL` uses the
|
|
134
|
+
// drawing buffer, which is cleared after each render for WebGL by default.
|
|
135
|
+
let dataUrl = canvas.toDataURL(); // skip empty canvases
|
|
136
|
+
|
|
137
|
+
if (!dataUrl || dataUrl === 'data:,') continue; // create an image element in the cloned dom
|
|
138
|
+
|
|
139
|
+
let img = clone.createElement('img');
|
|
140
|
+
img.src = dataUrl; // copy canvas element attributes to the image element such as style, class,
|
|
141
|
+
// or data attributes that may be targeted by CSS
|
|
142
|
+
|
|
143
|
+
for (let {
|
|
144
|
+
name,
|
|
145
|
+
value
|
|
146
|
+
} of canvas.attributes) {
|
|
147
|
+
img.setAttribute(name, value);
|
|
148
|
+
} // mark the image as serialized (can be targeted by CSS)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
img.setAttribute('data-percy-canvas-serialized', ''); // set a default max width to account for canvases that might resize with JS
|
|
152
|
+
|
|
153
|
+
img.style.maxWidth = img.style.maxWidth || '100%'; // insert the image into the cloned DOM and remove the cloned canvas element
|
|
154
|
+
|
|
155
|
+
let percyElementId = canvas.getAttribute('data-percy-element-id');
|
|
156
|
+
let cloneEl = clone.querySelector(`[data-percy-element-id=${percyElementId}]`);
|
|
157
|
+
cloneEl.parentElement.insertBefore(img, cloneEl);
|
|
158
|
+
cloneEl.remove();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Captures the current frame of videos and sets the poster image
|
|
163
|
+
function serializeVideos(dom, clone) {
|
|
164
|
+
for (let video of dom.querySelectorAll('video')) {
|
|
165
|
+
// If the video already has a poster image, no work for us to do
|
|
166
|
+
if (video.getAttribute('poster')) continue;
|
|
167
|
+
let videoId = video.getAttribute('data-percy-element-id');
|
|
168
|
+
let cloneEl = clone.querySelector(`[data-percy-element-id="${videoId}"]`);
|
|
169
|
+
let canvas = document.createElement('canvas');
|
|
170
|
+
let width = canvas.width = video.videoWidth;
|
|
171
|
+
let height = canvas.height = video.videoHeight;
|
|
172
|
+
let dataUrl;
|
|
173
|
+
canvas.getContext('2d').drawImage(video, 0, 0, width, height);
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
dataUrl = canvas.toDataURL();
|
|
177
|
+
} catch {} // If the canvas produces a blank image, skip
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
if (!dataUrl || dataUrl === 'data:,') continue;
|
|
181
|
+
cloneEl.setAttribute('poster', dataUrl);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function doctype(dom) {
|
|
186
|
+
let {
|
|
187
|
+
name = 'html',
|
|
188
|
+
publicId = '',
|
|
189
|
+
systemId = ''
|
|
190
|
+
} = (dom === null || dom === void 0 ? void 0 : dom.doctype) ?? {};
|
|
191
|
+
let deprecated = '';
|
|
192
|
+
|
|
193
|
+
if (publicId && systemId) {
|
|
194
|
+
deprecated = ` PUBLIC "${publicId}" "${systemId}"`;
|
|
195
|
+
} else if (publicId) {
|
|
196
|
+
deprecated = ` PUBLIC "${publicId}"`;
|
|
197
|
+
} else if (systemId) {
|
|
198
|
+
deprecated = ` SYSTEM "${systemId}"`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return `<!DOCTYPE ${name}${deprecated}>`;
|
|
202
|
+
} // Serializes a document and returns the resulting DOM string.
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
function serializeDOM(options) {
|
|
206
|
+
let {
|
|
207
|
+
dom = document,
|
|
208
|
+
// allow snake_case or camelCase
|
|
209
|
+
enableJavaScript = options === null || options === void 0 ? void 0 : options.enable_javascript,
|
|
210
|
+
domTransformation = options === null || options === void 0 ? void 0 : options.dom_transformation
|
|
211
|
+
} = options || {};
|
|
212
|
+
prepareDOM(dom);
|
|
213
|
+
let clone = dom.cloneNode(true);
|
|
214
|
+
serializeInputElements(dom, clone);
|
|
215
|
+
serializeFrames(dom, clone, {
|
|
216
|
+
enableJavaScript
|
|
217
|
+
});
|
|
218
|
+
serializeVideos(dom, clone);
|
|
219
|
+
|
|
220
|
+
if (!enableJavaScript) {
|
|
221
|
+
serializeCSSOM(dom, clone);
|
|
222
|
+
serializeCanvas(dom, clone);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
let doc = clone.documentElement;
|
|
226
|
+
|
|
227
|
+
if (domTransformation) {
|
|
228
|
+
try {
|
|
229
|
+
domTransformation(doc);
|
|
230
|
+
} catch (err) {
|
|
231
|
+
console.error('Could not transform the dom:', err.message);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return doctype(dom) + doc.outerHTML;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
exports["default"] = serializeDOM;
|
|
239
|
+
exports.serialize = serializeDOM;
|
|
240
|
+
exports.serializeDOM = serializeDOM;
|
|
241
|
+
|
|
242
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
243
|
+
|
|
244
|
+
})(this.PercyDOM = this.PercyDOM || {});
|
|
245
|
+
}).call(window);
|
|
246
|
+
|
|
247
|
+
if (typeof define === "function" && define.amd) {
|
|
248
|
+
define([], () => window.PercyDOM);
|
|
249
|
+
} else if (typeof module === "object" && module.exports) {
|
|
250
|
+
module.exports = window.PercyDOM;
|
|
251
|
+
}
|
package/package.json
CHANGED
|
@@ -1,45 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/dom",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/percy/cli",
|
|
8
|
+
"directory": "packages/dom"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"main": "dist/bundle.js",
|
|
14
|
+
"browser": "dist/bundle.js",
|
|
6
15
|
"files": [
|
|
7
16
|
"dist"
|
|
8
17
|
],
|
|
9
18
|
"scripts": {
|
|
10
|
-
"build": "
|
|
19
|
+
"build": "node ../../scripts/build",
|
|
11
20
|
"lint": "eslint --ignore-path ../../.gitignore .",
|
|
12
|
-
"test": "
|
|
21
|
+
"test": "node ../../scripts/test",
|
|
13
22
|
"test:coverage": "yarn test --coverage"
|
|
14
23
|
},
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"targets": "last 2 version"
|
|
25
|
-
}
|
|
26
|
-
]
|
|
27
|
-
]
|
|
24
|
+
"rollup": {
|
|
25
|
+
"output": {
|
|
26
|
+
"name": "PercyDOM"
|
|
27
|
+
},
|
|
28
|
+
"test": {
|
|
29
|
+
"output": {
|
|
30
|
+
"exports": "named"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
28
33
|
},
|
|
29
34
|
"devDependencies": {
|
|
30
|
-
"
|
|
31
|
-
"cheerio": "^1.0.0-rc.3",
|
|
32
|
-
"interactor.js": "^1.6.0",
|
|
33
|
-
"karma": "^5.0.9",
|
|
34
|
-
"karma-chrome-launcher": "^3.1.0",
|
|
35
|
-
"karma-coverage": "^2.0.1",
|
|
36
|
-
"karma-firefox-launcher": "^1.3.0",
|
|
37
|
-
"karma-mocha": "^2.0.1",
|
|
38
|
-
"karma-mocha-reporter": "^2.2.5",
|
|
39
|
-
"karma-webpack": "^4.0.2",
|
|
40
|
-
"regenerator-runtime": "^0.13.3",
|
|
41
|
-
"webpack": "^4.41.6",
|
|
42
|
-
"webpack-cli": "^3.3.11"
|
|
35
|
+
"interactor.js": "^2.0.0-beta.10"
|
|
43
36
|
},
|
|
44
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "6df509421a60144e4f9f5d59dc57a5675372a0b2"
|
|
45
38
|
}
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.PercyDOM=t():e.PercyDOM=t()}(window,(function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){"use strict";function n(e,t){var r;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(r=function(e,t){if(!e)return;if("string"==typeof e)return o(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return o(e,t)}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,a=function(){};return{s:a,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,u=!0,c=!1;return{s:function(){r=e[Symbol.iterator]()},n:function(){var e=r.next();return u=e.done,e},e:function(e){c=!0,i=e},f:function(){try{u||null==r.return||r.return()}finally{if(c)throw i}}}}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function a(e,t){var r;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(r=function(e,t){if(!e)return;if("string"==typeof e)return i(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return i(e,t)}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,o=function(){};return{s:o,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,c=!1;return{s:function(){r=e[Symbol.iterator]()},n:function(){var e=r.next();return u=e.done,e},e:function(e){c=!0,a=e},f:function(){try{u||null==r.return||r.return()}finally{if(c)throw a}}}}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function u(e,t){var r;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(r=function(e,t){if(!e)return;if("string"==typeof e)return c(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return c(e,t)}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,o=function(){};return{s:o,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,i=!0,u=!1;return{s:function(){r=e[Symbol.iterator]()},n:function(){var e=r.next();return i=e.done,e},e:function(e){u=!0,a=e},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function l(e,t){var r;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(r=function(e,t){if(!e)return;if("string"==typeof e)return f(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return f(e,t)}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,o=function(){};return{s:o,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,i=!0,u=!1;return{s:function(){r=e[Symbol.iterator]()},n:function(){var e=r.next();return i=e.done,e},e:function(e){u=!0,a=e},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function s(e){var t;return!e.href&&e.cssRules&&!(null===(t=e.ownerNode)||void 0===t?void 0:t.innerText.trim().length)}function y(e,t){var r;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(r=function(e,t){if(!e)return;if("string"==typeof e)return d(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return d(e,t)}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,o=function(){};return{s:o,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,i=!0,u=!1;return{s:function(){r=e[Symbol.iterator]()},n:function(){var e=r.next();return i=e.done,e},e:function(e){u=!0,a=e},f:function(){try{i||null==r.return||r.return()}finally{if(u)throw a}}}}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function m(e){var t=e||{},r=t.dom,o=void 0===r?document:r,i=t.enableJavaScript,c=t.domTransformation;!function(e){var t,r=n(e.querySelectorAll("input, textarea, select, iframe, canvas"));try{for(r.s();!(t=r.n()).done;){var o=t.value;o.getAttribute("data-percy-element-id")||o.setAttribute("data-percy-element-id","_".concat(Math.random().toString(36).substr(2,9)))}}catch(e){r.e(e)}finally{r.f()}}(o);var f=o.cloneNode(!0);!function(e,t){var r,n=a(e.querySelectorAll("input, textarea, select"));try{for(n.s();!(r=n.n()).done;){var o=r.value,i=o.getAttribute("data-percy-element-id"),u=t.querySelector('[data-percy-element-id="'.concat(i,'"]'));switch(o.type){case"checkbox":case"radio":o.checked&&u.setAttribute("checked","");break;case"select-one":-1!==o.selectedIndex&&u.options[o.selectedIndex].setAttribute("selected","true");break;case"select-multiple":var c,l=a(o.selectedOptions);try{for(l.s();!(c=l.n()).done;){var f=c.value;u.options[f.index].setAttribute("selected","true")}}catch(e){l.e(e)}finally{l.f()}break;case"textarea":u.innerHTML=o.value;break;default:u.setAttribute("value",o.value)}}}catch(e){n.e(e)}finally{n.f()}}(o,f),function(e,t,r){var n,o=r.enableJavaScript,a=u(e.querySelectorAll("iframe"));try{for(a.s();!(n=a.n()).done;){var i=n.value,c=i.getAttribute("data-percy-element-id"),l=t.querySelector('[data-percy-element-id="'.concat(c,'"]')),f=!(i.srcdoc||i.src&&"javascript"!==i.src.split(":")[0]);if(t.head.contains(l))l.remove();else if(i.contentDocument){if(o&&f)continue;if(!f&&!i.contentWindow.performance.timing.loadEventEnd)continue;var s=m({dom:i.contentDocument,enableJavaScript:o});l.setAttribute("srcdoc",s),l.removeAttribute("src")}else!o&&f&&l.remove()}}catch(e){a.e(e)}finally{a.f()}}(o,f,{enableJavaScript:i}),i||(function(e,t){var r,n=l(e.styleSheets);try{for(n.s();!(r=n.n()).done;){var o=r.value;if(s(o)){var a=t.createElement("style");a.type="text/css",a.setAttribute("data-percy-cssom-serialized","true"),a.innerHTML=Array.from(o.cssRules).reduce((function(e,t){return e+t.cssText}),""),t.head.appendChild(a)}}}catch(e){n.e(e)}finally{n.f()}}(o,f),function(e,t){var r,n=y(e.querySelectorAll("canvas"));try{for(n.s();!(r=n.n()).done;){var o,a=r.value,i=t.createElement("img"),u=y(a.attributes);try{for(u.s();!(o=u.n()).done;){var c=o.value,l=c.name,f=c.value;i.setAttribute(l,f)}}catch(e){u.e(e)}finally{u.f()}i.src=a.toDataURL(),i.setAttribute("data-percy-canvas-serialized",""),i.style.maxWidth=i.style.maxWidth||"100%";var s=a.getAttribute("data-percy-element-id"),d=t.querySelector("[data-percy-element-id=".concat(s,"]"));d.parentElement.insertBefore(i,d),d.remove()}}catch(e){n.e(e)}finally{n.f()}}(o,f));var d=f.documentElement;if(c)try{c(d)}catch(e){console.error("Could not transform the dom:",e.message)}return function(e){var t,r=null!==(t=null==e?void 0:e.doctype)&&void 0!==t?t:{},n=r.name,o=void 0===n?"html":n,a=r.publicId,i=void 0===a?"":a,u=r.systemId,c=void 0===u?"":u,l="";return i&&c?l=' PUBLIC "'.concat(i,'" "').concat(c,'"'):i?l=' PUBLIC "'.concat(i,'"'):c&&(l=' SYSTEM "'.concat(c,'"')),"<!DOCTYPE ".concat(o).concat(l,">")}(o)+d.outerHTML}r.r(t),r.d(t,"default",(function(){return m})),r.d(t,"serialize",(function(){return m}))}])}));
|