@highlight-run/rrweb 2.0.18 → 2.1.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/plugins/console-record.js +8 -8
- package/dist/plugins/console-record.min.js +8 -8
- package/dist/plugins/console-record.min.js.map +1 -1
- package/dist/plugins/console-replay.min.js.map +1 -1
- package/dist/record/rrweb-record-pack.min.js.map +1 -1
- package/dist/record/rrweb-record.js +3 -3
- package/dist/record/rrweb-record.min.js +3 -3
- package/dist/record/rrweb-record.min.js.map +1 -1
- package/dist/replay/rrweb-replay-unpack.js +4 -4
- package/dist/replay/rrweb-replay-unpack.min.js +4 -4
- package/dist/replay/rrweb-replay-unpack.min.js.map +1 -1
- package/dist/replay/rrweb-replay.js +4 -4
- package/dist/replay/rrweb-replay.min.js +4 -4
- package/dist/replay/rrweb-replay.min.js.map +1 -1
- package/dist/rrweb-all.js +12 -12
- package/dist/rrweb-all.min.js +12 -12
- package/dist/rrweb-all.min.js.map +1 -1
- package/dist/rrweb.js +5 -5
- package/dist/rrweb.min.js +5 -5
- package/dist/rrweb.min.js.map +1 -1
- package/es/rrweb/ext/mitt/dist/mitt.mjs.js +3 -0
- package/es/rrweb/packages/rrdom/es/rrdom.js +66 -10
- package/es/rrweb/packages/rrweb/src/plugins/console/record/error-stack-parser.js +3 -11
- package/es/rrweb/packages/rrweb/src/plugins/console/record/index.js +10 -7
- package/es/rrweb/packages/rrweb/src/plugins/console/record/stringify.js +9 -6
- package/es/rrweb/packages/rrweb/src/record/mutation.js +5 -3
- package/es/rrweb/packages/rrweb/src/record/observer.js +22 -14
- package/es/rrweb/packages/rrweb/src/record/observers/canvas/canvas-manager.js +1 -1
- package/es/rrweb/packages/rrweb/src/record/shadow-dom-manager.js +7 -4
- package/es/rrweb/packages/rrweb/src/replay/canvas/2d.js +3 -2
- package/es/rrweb/packages/rrweb/src/replay/canvas/webgl.js +1 -2
- package/es/rrweb/packages/rrweb/src/replay/index.js +151 -180
- package/es/rrweb/packages/rrweb/src/replay/timer.js +6 -7
- package/es/rrweb/packages/rrweb/src/utils.js +8 -6
- package/es/rrweb/packages/rrweb-snapshot/es/rrweb-snapshot.js +60 -10
- package/lib/plugins/console-record.js +26 -26
- package/lib/record/rrweb-record.js +91 -31
- package/lib/replay/rrweb-replay-unpack.js +236 -265
- package/lib/replay/rrweb-replay.js +236 -265
- package/lib/rrweb-all.js +346 -318
- package/lib/rrweb.js +324 -294
- package/package.json +7 -6
- package/typings/entries/all.d.ts +0 -0
- package/typings/entries/record-pack.d.ts +0 -0
- package/typings/entries/replay-unpack.d.ts +0 -0
- package/typings/index.d.ts +0 -0
- package/typings/packer/base.d.ts +0 -0
- package/typings/packer/index.d.ts +0 -0
- package/typings/packer/pack.d.ts +0 -0
- package/typings/packer/unpack.d.ts +0 -0
- package/typings/plugins/console/record/error-stack-parser.d.ts +0 -0
- package/typings/plugins/console/record/index.d.ts +1 -1
- package/typings/plugins/console/record/stringify.d.ts +1 -1
- package/typings/plugins/console/replay/index.d.ts +0 -0
- package/typings/plugins/sequential-id/record/index.d.ts +0 -0
- package/typings/plugins/sequential-id/replay/index.d.ts +0 -0
- package/typings/record/iframe-manager.d.ts +0 -0
- package/typings/record/index.d.ts +0 -0
- package/typings/record/mutation.d.ts +0 -0
- package/typings/record/observer.d.ts +0 -0
- package/typings/record/observers/canvas/2d.d.ts +0 -0
- package/typings/record/observers/canvas/canvas-manager.d.ts +0 -0
- package/typings/record/observers/canvas/canvas.d.ts +0 -0
- package/typings/record/observers/canvas/serialize-args.d.ts +5 -5
- package/typings/record/observers/canvas/webgl.d.ts +0 -0
- package/typings/record/shadow-dom-manager.d.ts +1 -1
- package/typings/record/stylesheet-manager.d.ts +0 -0
- package/typings/record/workers/image-bitmap-data-url-worker.d.ts +0 -0
- package/typings/replay/canvas/2d.d.ts +0 -0
- package/typings/replay/canvas/deserialize-args.d.ts +0 -0
- package/typings/replay/canvas/index.d.ts +0 -0
- package/typings/replay/canvas/webgl.d.ts +0 -0
- package/typings/replay/index.d.ts +0 -2
- package/typings/replay/machine.d.ts +0 -0
- package/typings/replay/smoothscroll.d.ts +0 -0
- package/typings/replay/styles/inject-style.d.ts +0 -0
- package/typings/replay/timer.d.ts +0 -0
- package/typings/rrdom/index.d.ts +0 -0
- package/typings/rrdom/tree-node.d.ts +0 -0
- package/typings/types.d.ts +5 -6
- package/typings/utils.d.ts +2 -2
- package/es/rrweb/ext/mitt/dist/mitt.es.js +0 -63
- package/typings/record/observers/canvas/webgl2.d.ts +0 -2
|
@@ -127,7 +127,7 @@ function parse(css, options) {
|
|
|
127
127
|
Position.prototype.content = css;
|
|
128
128
|
var errorsList = [];
|
|
129
129
|
function error(msg) {
|
|
130
|
-
var err = new Error(options.source
|
|
130
|
+
var err = new Error("".concat(options.source || '', ":").concat(lineno, ":").concat(column, ": ").concat(msg));
|
|
131
131
|
err.reason = msg;
|
|
132
132
|
err.filename = options.source;
|
|
133
133
|
err.line = lineno;
|
|
@@ -640,7 +640,7 @@ function buildNode(n, options) {
|
|
|
640
640
|
return doc.implementation.createDocument(null, '', null);
|
|
641
641
|
case NodeType$2.DocumentType:
|
|
642
642
|
return doc.implementation.createDocumentType(n.name || 'html', n.publicId, n.systemId);
|
|
643
|
-
case NodeType$2.Element:
|
|
643
|
+
case NodeType$2.Element: {
|
|
644
644
|
var tagName = getTagName(n);
|
|
645
645
|
var node_1;
|
|
646
646
|
if (n.isSVG) {
|
|
@@ -650,7 +650,7 @@ function buildNode(n, options) {
|
|
|
650
650
|
node_1 = doc.createElement(tagName);
|
|
651
651
|
}
|
|
652
652
|
var _loop_1 = function (name_1) {
|
|
653
|
-
if (!
|
|
653
|
+
if (!Object.prototype.hasOwnProperty.call(n.attributes, name_1)) {
|
|
654
654
|
return "continue";
|
|
655
655
|
}
|
|
656
656
|
var value = n.attributes[name_1];
|
|
@@ -738,13 +738,15 @@ function buildNode(n, options) {
|
|
|
738
738
|
else {
|
|
739
739
|
if (tagName === 'canvas' && name_1 === 'rr_dataURL') {
|
|
740
740
|
var image_1 = document.createElement('img');
|
|
741
|
-
image_1.src = value;
|
|
742
741
|
image_1.onload = function () {
|
|
743
742
|
var ctx = node_1.getContext('2d');
|
|
744
743
|
if (ctx) {
|
|
745
744
|
ctx.drawImage(image_1, 0, 0, image_1.width, image_1.height);
|
|
746
745
|
}
|
|
747
746
|
};
|
|
747
|
+
image_1.src = value;
|
|
748
|
+
if (node_1.RRNodeType)
|
|
749
|
+
node_1.rr_dataURL = value;
|
|
748
750
|
}
|
|
749
751
|
else if (tagName === 'img' && name_1 === 'rr_dataURL') {
|
|
750
752
|
var image = node_1;
|
|
@@ -800,6 +802,7 @@ function buildNode(n, options) {
|
|
|
800
802
|
}
|
|
801
803
|
}
|
|
802
804
|
return node_1;
|
|
805
|
+
}
|
|
803
806
|
case NodeType$2.Text:
|
|
804
807
|
return doc.createTextNode(n.isStyle && hackCss
|
|
805
808
|
? addHoverClass(n.textContent, cache)
|
|
@@ -886,7 +889,8 @@ function handleScroll(node, mirror) {
|
|
|
886
889
|
}
|
|
887
890
|
var el = node;
|
|
888
891
|
for (var name_2 in n.attributes) {
|
|
889
|
-
if (!(
|
|
892
|
+
if (!(Object.prototype.hasOwnProperty.call(n.attributes, name_2) &&
|
|
893
|
+
name_2.startsWith('rr_'))) {
|
|
890
894
|
continue;
|
|
891
895
|
}
|
|
892
896
|
var value = n.attributes[name_2];
|
|
@@ -1021,7 +1025,7 @@ const hyphenate = (str) => {
|
|
|
1021
1025
|
};
|
|
1022
1026
|
|
|
1023
1027
|
class BaseRRNode {
|
|
1024
|
-
constructor(...
|
|
1028
|
+
constructor(..._args) {
|
|
1025
1029
|
this.childNodes = [];
|
|
1026
1030
|
this.parentElement = null;
|
|
1027
1031
|
this.parentNode = null;
|
|
@@ -1057,7 +1061,7 @@ class BaseRRNode {
|
|
|
1057
1061
|
insertBefore(_newChild, _refChild) {
|
|
1058
1062
|
throw new Error(`RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`);
|
|
1059
1063
|
}
|
|
1060
|
-
removeChild(
|
|
1064
|
+
removeChild(_node) {
|
|
1061
1065
|
throw new Error(`RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`);
|
|
1062
1066
|
}
|
|
1063
1067
|
toString() {
|
|
@@ -1436,6 +1440,44 @@ const NAMESPACES = {
|
|
|
1436
1440
|
'xlink:href': 'http://www.w3.org/1999/xlink',
|
|
1437
1441
|
xmlns: 'http://www.w3.org/2000/xmlns/',
|
|
1438
1442
|
};
|
|
1443
|
+
const SVGTagMap = {
|
|
1444
|
+
altglyph: 'altGlyph',
|
|
1445
|
+
altglyphdef: 'altGlyphDef',
|
|
1446
|
+
altglyphitem: 'altGlyphItem',
|
|
1447
|
+
animatecolor: 'animateColor',
|
|
1448
|
+
animatemotion: 'animateMotion',
|
|
1449
|
+
animatetransform: 'animateTransform',
|
|
1450
|
+
clippath: 'clipPath',
|
|
1451
|
+
feblend: 'feBlend',
|
|
1452
|
+
fecolormatrix: 'feColorMatrix',
|
|
1453
|
+
fecomponenttransfer: 'feComponentTransfer',
|
|
1454
|
+
fecomposite: 'feComposite',
|
|
1455
|
+
feconvolvematrix: 'feConvolveMatrix',
|
|
1456
|
+
fediffuselighting: 'feDiffuseLighting',
|
|
1457
|
+
fedisplacementmap: 'feDisplacementMap',
|
|
1458
|
+
fedistantlight: 'feDistantLight',
|
|
1459
|
+
fedropshadow: 'feDropShadow',
|
|
1460
|
+
feflood: 'feFlood',
|
|
1461
|
+
fefunca: 'feFuncA',
|
|
1462
|
+
fefuncb: 'feFuncB',
|
|
1463
|
+
fefuncg: 'feFuncG',
|
|
1464
|
+
fefuncr: 'feFuncR',
|
|
1465
|
+
fegaussianblur: 'feGaussianBlur',
|
|
1466
|
+
feimage: 'feImage',
|
|
1467
|
+
femerge: 'feMerge',
|
|
1468
|
+
femergenode: 'feMergeNode',
|
|
1469
|
+
femorphology: 'feMorphology',
|
|
1470
|
+
feoffset: 'feOffset',
|
|
1471
|
+
fepointlight: 'fePointLight',
|
|
1472
|
+
fespecularlighting: 'feSpecularLighting',
|
|
1473
|
+
fespotlight: 'feSpotLight',
|
|
1474
|
+
fetile: 'feTile',
|
|
1475
|
+
feturbulence: 'feTurbulence',
|
|
1476
|
+
foreignobject: 'foreignObject',
|
|
1477
|
+
glyphref: 'glyphRef',
|
|
1478
|
+
lineargradient: 'linearGradient',
|
|
1479
|
+
radialgradient: 'radialGradient',
|
|
1480
|
+
};
|
|
1439
1481
|
function diff(oldTree, newTree, replayer, rrnodeMirror) {
|
|
1440
1482
|
const oldChildren = oldTree.childNodes;
|
|
1441
1483
|
const newChildren = newTree.childNodes;
|
|
@@ -1466,8 +1508,8 @@ function diff(oldTree, newTree, replayer, rrnodeMirror) {
|
|
|
1466
1508
|
const newMediaRRElement = newRRElement;
|
|
1467
1509
|
if (newMediaRRElement.paused !== undefined)
|
|
1468
1510
|
newMediaRRElement.paused
|
|
1469
|
-
? oldMediaElement.pause()
|
|
1470
|
-
: oldMediaElement.play();
|
|
1511
|
+
? void oldMediaElement.pause()
|
|
1512
|
+
: void oldMediaElement.play();
|
|
1471
1513
|
if (newMediaRRElement.muted !== undefined)
|
|
1472
1514
|
oldMediaElement.muted = newMediaRRElement.muted;
|
|
1473
1515
|
if (newMediaRRElement.volume !== undefined)
|
|
@@ -1477,7 +1519,20 @@ function diff(oldTree, newTree, replayer, rrnodeMirror) {
|
|
|
1477
1519
|
break;
|
|
1478
1520
|
}
|
|
1479
1521
|
case 'CANVAS':
|
|
1480
|
-
|
|
1522
|
+
{
|
|
1523
|
+
const rrCanvasElement = newTree;
|
|
1524
|
+
if (rrCanvasElement.rr_dataURL !== null) {
|
|
1525
|
+
const image = document.createElement('img');
|
|
1526
|
+
image.onload = () => {
|
|
1527
|
+
const ctx = oldElement.getContext('2d');
|
|
1528
|
+
if (ctx) {
|
|
1529
|
+
ctx.drawImage(image, 0, 0, image.width, image.height);
|
|
1530
|
+
}
|
|
1531
|
+
};
|
|
1532
|
+
image.src = rrCanvasElement.rr_dataURL;
|
|
1533
|
+
}
|
|
1534
|
+
rrCanvasElement.canvasMutations.forEach((canvasMutation) => replayer.applyCanvas(canvasMutation.event, canvasMutation.mutation, oldTree));
|
|
1535
|
+
}
|
|
1481
1536
|
break;
|
|
1482
1537
|
case 'STYLE':
|
|
1483
1538
|
applyVirtualStyleRulesToNode(oldElement, newTree.rules);
|
|
@@ -1655,9 +1710,10 @@ function createOrGetNode(rrNode, domMirror, rrnodeMirror) {
|
|
|
1655
1710
|
node = document.implementation.createDocumentType(rrNode.name, rrNode.publicId, rrNode.systemId);
|
|
1656
1711
|
break;
|
|
1657
1712
|
case NodeType$1.Element: {
|
|
1658
|
-
rrNode.tagName.toLowerCase();
|
|
1713
|
+
let tagName = rrNode.tagName.toLowerCase();
|
|
1714
|
+
tagName = SVGTagMap[tagName] || tagName;
|
|
1659
1715
|
if (sn && 'isSVG' in sn && (sn === null || sn === void 0 ? void 0 : sn.isSVG)) {
|
|
1660
|
-
node = document.createElementNS(NAMESPACES['svg'],
|
|
1716
|
+
node = document.createElementNS(NAMESPACES['svg'], tagName);
|
|
1661
1717
|
}
|
|
1662
1718
|
else
|
|
1663
1719
|
node = document.createElement(rrNode.tagName);
|
|
@@ -1823,6 +1879,7 @@ class RRMediaElement extends BaseRRMediaElementImpl(RRElement) {
|
|
|
1823
1879
|
class RRCanvasElement extends RRElement {
|
|
1824
1880
|
constructor() {
|
|
1825
1881
|
super(...arguments);
|
|
1882
|
+
this.rr_dataURL = null;
|
|
1826
1883
|
this.canvasMutations = [];
|
|
1827
1884
|
}
|
|
1828
1885
|
getContext() {
|
|
@@ -1862,11 +1919,12 @@ function buildFromNode(node, rrdom, domMirror, parentRRNode) {
|
|
|
1862
1919
|
rrNode.compatMode = node.compatMode;
|
|
1863
1920
|
}
|
|
1864
1921
|
break;
|
|
1865
|
-
case NodeType.DOCUMENT_TYPE_NODE:
|
|
1922
|
+
case NodeType.DOCUMENT_TYPE_NODE: {
|
|
1866
1923
|
const documentType = node;
|
|
1867
1924
|
rrNode = rrdom.createDocumentType(documentType.name, documentType.publicId, documentType.systemId);
|
|
1868
1925
|
break;
|
|
1869
|
-
|
|
1926
|
+
}
|
|
1927
|
+
case NodeType.ELEMENT_NODE: {
|
|
1870
1928
|
const elementNode = node;
|
|
1871
1929
|
const tagName = getValidTagName(elementNode);
|
|
1872
1930
|
rrNode = rrdom.createElement(tagName);
|
|
@@ -1877,6 +1935,7 @@ function buildFromNode(node, rrdom, domMirror, parentRRNode) {
|
|
|
1877
1935
|
elementNode.scrollLeft && (rrElement.scrollLeft = elementNode.scrollLeft);
|
|
1878
1936
|
elementNode.scrollTop && (rrElement.scrollTop = elementNode.scrollTop);
|
|
1879
1937
|
break;
|
|
1938
|
+
}
|
|
1880
1939
|
case NodeType.TEXT_NODE:
|
|
1881
1940
|
rrNode = rrdom.createTextNode(node.textContent || '');
|
|
1882
1941
|
break;
|
|
@@ -1986,7 +2045,7 @@ function getDefaultSN(node, id) {
|
|
|
1986
2045
|
type: node.RRNodeType,
|
|
1987
2046
|
childNodes: [],
|
|
1988
2047
|
};
|
|
1989
|
-
case NodeType$1.DocumentType:
|
|
2048
|
+
case NodeType$1.DocumentType: {
|
|
1990
2049
|
const doctype = node;
|
|
1991
2050
|
return {
|
|
1992
2051
|
id,
|
|
@@ -1995,6 +2054,7 @@ function getDefaultSN(node, id) {
|
|
|
1995
2054
|
publicId: doctype.publicId,
|
|
1996
2055
|
systemId: doctype.systemId,
|
|
1997
2056
|
};
|
|
2057
|
+
}
|
|
1998
2058
|
case NodeType$1.Element:
|
|
1999
2059
|
return {
|
|
2000
2060
|
id,
|
|
@@ -2024,67 +2084,7 @@ function getDefaultSN(node, id) {
|
|
|
2024
2084
|
}
|
|
2025
2085
|
}
|
|
2026
2086
|
|
|
2027
|
-
|
|
2028
|
-
// An event handler can take an optional event argument
|
|
2029
|
-
// and should not return a value
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
// An array of all currently registered event handlers for a type
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
// A map of event types and their corresponding event handlers.
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
/** Mitt: Tiny (~200b) functional event emitter / pubsub.
|
|
2043
|
-
* @name mitt
|
|
2044
|
-
* @returns {Mitt}
|
|
2045
|
-
*/
|
|
2046
|
-
function mitt$1(all ) {
|
|
2047
|
-
all = all || Object.create(null);
|
|
2048
|
-
|
|
2049
|
-
return {
|
|
2050
|
-
/**
|
|
2051
|
-
* Register an event handler for the given type.
|
|
2052
|
-
*
|
|
2053
|
-
* @param {String} type Type of event to listen for, or `"*"` for all events
|
|
2054
|
-
* @param {Function} handler Function to call in response to given event
|
|
2055
|
-
* @memberOf mitt
|
|
2056
|
-
*/
|
|
2057
|
-
on: function on(type , handler ) {
|
|
2058
|
-
(all[type] || (all[type] = [])).push(handler);
|
|
2059
|
-
},
|
|
2060
|
-
|
|
2061
|
-
/**
|
|
2062
|
-
* Remove an event handler for the given type.
|
|
2063
|
-
*
|
|
2064
|
-
* @param {String} type Type of event to unregister `handler` from, or `"*"`
|
|
2065
|
-
* @param {Function} handler Handler function to remove
|
|
2066
|
-
* @memberOf mitt
|
|
2067
|
-
*/
|
|
2068
|
-
off: function off(type , handler ) {
|
|
2069
|
-
if (all[type]) {
|
|
2070
|
-
all[type].splice(all[type].indexOf(handler) >>> 0, 1);
|
|
2071
|
-
}
|
|
2072
|
-
},
|
|
2073
|
-
|
|
2074
|
-
/**
|
|
2075
|
-
* Invoke all handlers for the given type.
|
|
2076
|
-
* If present, `"*"` handlers are invoked after type-matched handlers.
|
|
2077
|
-
*
|
|
2078
|
-
* @param {String} type The event type to invoke
|
|
2079
|
-
* @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
|
|
2080
|
-
* @memberOf mitt
|
|
2081
|
-
*/
|
|
2082
|
-
emit: function emit(type , evt ) {
|
|
2083
|
-
(all[type] || []).slice().map(function (handler) { handler(evt); });
|
|
2084
|
-
(all['*'] || []).slice().map(function (handler) { handler(type, evt); });
|
|
2085
|
-
}
|
|
2086
|
-
};
|
|
2087
|
-
}
|
|
2087
|
+
function mitt$1(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e]);},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]));},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e);}),(i=n.get("*"))&&i.slice().map(function(n){n(t,e);});}}}
|
|
2088
2088
|
|
|
2089
2089
|
var mittProxy = /*#__PURE__*/Object.freeze({
|
|
2090
2090
|
__proto__: null,
|
|
@@ -2405,14 +2405,13 @@ class Timer {
|
|
|
2405
2405
|
this.timeOffset = 0;
|
|
2406
2406
|
let lastTimestamp = performance.now();
|
|
2407
2407
|
const { actions } = this;
|
|
2408
|
-
const
|
|
2409
|
-
function check() {
|
|
2408
|
+
const check = () => {
|
|
2410
2409
|
const time = performance.now();
|
|
2411
|
-
|
|
2410
|
+
this.timeOffset += (time - lastTimestamp) * this.speed;
|
|
2412
2411
|
lastTimestamp = time;
|
|
2413
2412
|
while (actions.length) {
|
|
2414
2413
|
const action = actions[0];
|
|
2415
|
-
if (
|
|
2414
|
+
if (this.timeOffset >= action.delay) {
|
|
2416
2415
|
actions.shift();
|
|
2417
2416
|
action.doAction();
|
|
2418
2417
|
}
|
|
@@ -2420,10 +2419,10 @@ class Timer {
|
|
|
2420
2419
|
break;
|
|
2421
2420
|
}
|
|
2422
2421
|
}
|
|
2423
|
-
if (actions.length > 0 ||
|
|
2424
|
-
|
|
2422
|
+
if (actions.length > 0 || this.liveMode) {
|
|
2423
|
+
this.raf = requestAnimationFrame(check);
|
|
2425
2424
|
}
|
|
2426
|
-
}
|
|
2425
|
+
};
|
|
2427
2426
|
this.raf = requestAnimationFrame(check);
|
|
2428
2427
|
}
|
|
2429
2428
|
clear() {
|
|
@@ -2810,8 +2809,9 @@ function polyfill(win = window) {
|
|
|
2810
2809
|
.forEach;
|
|
2811
2810
|
}
|
|
2812
2811
|
if (!Node.prototype.contains) {
|
|
2813
|
-
Node.prototype.contains =
|
|
2814
|
-
|
|
2812
|
+
Node.prototype.contains = (...args) => {
|
|
2813
|
+
let node = args[0];
|
|
2814
|
+
if (!(0 in args)) {
|
|
2815
2815
|
throw new TypeError('1 argument is required');
|
|
2816
2816
|
}
|
|
2817
2817
|
do {
|
|
@@ -3024,8 +3024,7 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
3024
3024
|
function getContext(target, type) {
|
|
3025
3025
|
try {
|
|
3026
3026
|
if (type === CanvasContext.WebGL) {
|
|
3027
|
-
return (target.getContext('webgl') ||
|
|
3028
|
-
target.getContext('experimental-webgl'));
|
|
3027
|
+
return (target.getContext('webgl') || target.getContext('experimental-webgl'));
|
|
3029
3028
|
}
|
|
3030
3029
|
return target.getContext('webgl2');
|
|
3031
3030
|
}
|
|
@@ -3083,13 +3082,14 @@ function canvasMutation$1({ event, mutation, target, imageMap, errorHandler, })
|
|
|
3083
3082
|
try {
|
|
3084
3083
|
const ctx = target.getContext('2d');
|
|
3085
3084
|
if (mutation.setter) {
|
|
3086
|
-
ctx[mutation.property] =
|
|
3085
|
+
ctx[mutation.property] =
|
|
3086
|
+
mutation.args[0];
|
|
3087
3087
|
return;
|
|
3088
3088
|
}
|
|
3089
3089
|
const original = ctx[mutation.property];
|
|
3090
3090
|
if (mutation.property === 'drawImage' &&
|
|
3091
3091
|
typeof mutation.args[0] === 'string') {
|
|
3092
|
-
|
|
3092
|
+
imageMap.get(event);
|
|
3093
3093
|
original.apply(ctx, mutation.args);
|
|
3094
3094
|
}
|
|
3095
3095
|
else {
|
|
@@ -3175,6 +3175,142 @@ class Replayer {
|
|
|
3175
3175
|
this.newDocumentQueue = [];
|
|
3176
3176
|
this.mousePos = null;
|
|
3177
3177
|
this.touchActive = null;
|
|
3178
|
+
this.handleResize = (dimension) => {
|
|
3179
|
+
this.iframe.style.display = 'inherit';
|
|
3180
|
+
for (const el of [this.mouseTail, this.iframe]) {
|
|
3181
|
+
if (!el) {
|
|
3182
|
+
continue;
|
|
3183
|
+
}
|
|
3184
|
+
el.setAttribute('width', String(dimension.width));
|
|
3185
|
+
el.setAttribute('height', String(dimension.height));
|
|
3186
|
+
}
|
|
3187
|
+
};
|
|
3188
|
+
this.applyEventsSynchronously = (events) => {
|
|
3189
|
+
for (const event of events) {
|
|
3190
|
+
switch (event.type) {
|
|
3191
|
+
case EventType.DomContentLoaded:
|
|
3192
|
+
case EventType.Load:
|
|
3193
|
+
case EventType.Custom:
|
|
3194
|
+
continue;
|
|
3195
|
+
case EventType.FullSnapshot:
|
|
3196
|
+
case EventType.Meta:
|
|
3197
|
+
case EventType.Plugin:
|
|
3198
|
+
case EventType.IncrementalSnapshot:
|
|
3199
|
+
break;
|
|
3200
|
+
}
|
|
3201
|
+
const castFn = this.getCastFn(event, true);
|
|
3202
|
+
castFn();
|
|
3203
|
+
}
|
|
3204
|
+
if (this.touchActive === true) {
|
|
3205
|
+
this.mouse.classList.add('touch-active');
|
|
3206
|
+
}
|
|
3207
|
+
else if (this.touchActive === false) {
|
|
3208
|
+
this.mouse.classList.remove('touch-active');
|
|
3209
|
+
}
|
|
3210
|
+
this.touchActive = null;
|
|
3211
|
+
};
|
|
3212
|
+
this.getCastFn = (event, isSync = false) => {
|
|
3213
|
+
let castFn;
|
|
3214
|
+
switch (event.type) {
|
|
3215
|
+
case EventType.DomContentLoaded:
|
|
3216
|
+
case EventType.Load:
|
|
3217
|
+
break;
|
|
3218
|
+
case EventType.Custom:
|
|
3219
|
+
castFn = () => {
|
|
3220
|
+
this.emitter.emit(ReplayerEvents.CustomEvent, event);
|
|
3221
|
+
};
|
|
3222
|
+
break;
|
|
3223
|
+
case EventType.Meta:
|
|
3224
|
+
castFn = () => this.emitter.emit(ReplayerEvents.Resize, {
|
|
3225
|
+
width: event.data.width,
|
|
3226
|
+
height: event.data.height,
|
|
3227
|
+
});
|
|
3228
|
+
break;
|
|
3229
|
+
case EventType.FullSnapshot:
|
|
3230
|
+
castFn = () => {
|
|
3231
|
+
if (this.firstFullSnapshot) {
|
|
3232
|
+
if (this.firstFullSnapshot === event) {
|
|
3233
|
+
this.firstFullSnapshot = true;
|
|
3234
|
+
return;
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
else {
|
|
3238
|
+
this.firstFullSnapshot = true;
|
|
3239
|
+
}
|
|
3240
|
+
this.rebuildFullSnapshot(event, isSync);
|
|
3241
|
+
this.iframe.contentWindow.scrollTo(event.data.initialOffset);
|
|
3242
|
+
};
|
|
3243
|
+
break;
|
|
3244
|
+
case EventType.IncrementalSnapshot:
|
|
3245
|
+
castFn = () => {
|
|
3246
|
+
this.applyIncremental(event, isSync);
|
|
3247
|
+
if (isSync) {
|
|
3248
|
+
return;
|
|
3249
|
+
}
|
|
3250
|
+
this.handleInactivity(event.timestamp);
|
|
3251
|
+
if (event === this.nextUserInteractionEvent) {
|
|
3252
|
+
this.nextUserInteractionEvent = null;
|
|
3253
|
+
this.backToNormal();
|
|
3254
|
+
}
|
|
3255
|
+
if (this.config.skipInactive && !this.nextUserInteractionEvent) {
|
|
3256
|
+
for (const _event of this.service.state.context.events) {
|
|
3257
|
+
if (_event.timestamp <= event.timestamp) {
|
|
3258
|
+
continue;
|
|
3259
|
+
}
|
|
3260
|
+
if (this.isUserInteraction(_event)) {
|
|
3261
|
+
if (_event.delay - event.delay >
|
|
3262
|
+
SKIP_TIME_THRESHOLD *
|
|
3263
|
+
this.speedService.state.context.timer.speed) {
|
|
3264
|
+
this.nextUserInteractionEvent = _event;
|
|
3265
|
+
}
|
|
3266
|
+
break;
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
if (this.nextUserInteractionEvent) {
|
|
3270
|
+
const skipTime = this.nextUserInteractionEvent.delay - event.delay;
|
|
3271
|
+
const payload = {
|
|
3272
|
+
speed: Math.min(Math.round(skipTime / SKIP_TIME_INTERVAL), this.config.maxSpeed),
|
|
3273
|
+
};
|
|
3274
|
+
this.speedService.send({ type: 'FAST_FORWARD', payload });
|
|
3275
|
+
this.emitter.emit(ReplayerEvents.SkipStart, payload);
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
};
|
|
3279
|
+
break;
|
|
3280
|
+
}
|
|
3281
|
+
const wrappedCastFn = () => {
|
|
3282
|
+
if (castFn) {
|
|
3283
|
+
castFn();
|
|
3284
|
+
}
|
|
3285
|
+
for (const plugin of this.config.plugins || []) {
|
|
3286
|
+
plugin.handler(event, isSync, { replayer: this });
|
|
3287
|
+
}
|
|
3288
|
+
this.service.send({ type: 'CAST_EVENT', payload: { event } });
|
|
3289
|
+
const last_index = this.service.state.context.events.length - 1;
|
|
3290
|
+
if (event === this.service.state.context.events[last_index]) {
|
|
3291
|
+
const finish = () => {
|
|
3292
|
+
if (last_index < this.service.state.context.events.length - 1) {
|
|
3293
|
+
return;
|
|
3294
|
+
}
|
|
3295
|
+
this.backToNormal();
|
|
3296
|
+
this.service.send('END');
|
|
3297
|
+
this.emitter.emit(ReplayerEvents.Finish);
|
|
3298
|
+
};
|
|
3299
|
+
if (event.type === EventType.IncrementalSnapshot &&
|
|
3300
|
+
event.data.source === IncrementalSource.MouseMove &&
|
|
3301
|
+
event.data.positions.length) {
|
|
3302
|
+
setTimeout(() => {
|
|
3303
|
+
finish();
|
|
3304
|
+
}, Math.max(0, -event.data.positions[0].timeOffset + 50));
|
|
3305
|
+
}
|
|
3306
|
+
else {
|
|
3307
|
+
finish();
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
this.emitter.emit(ReplayerEvents.EventCast, event);
|
|
3311
|
+
};
|
|
3312
|
+
return wrappedCastFn;
|
|
3313
|
+
};
|
|
3178
3314
|
if (!(config === null || config === void 0 ? void 0 : config.liveMode) && events.length < 2) {
|
|
3179
3315
|
throw new Error('Replayer need at least 2 events.');
|
|
3180
3316
|
}
|
|
@@ -3208,7 +3344,7 @@ class Replayer {
|
|
|
3208
3344
|
const replayerHandler = {
|
|
3209
3345
|
mirror: this.mirror,
|
|
3210
3346
|
applyCanvas: (canvasEvent, canvasMutationData, target) => {
|
|
3211
|
-
canvasMutation({
|
|
3347
|
+
void canvasMutation({
|
|
3212
3348
|
event: canvasEvent,
|
|
3213
3349
|
mutation: canvasMutationData,
|
|
3214
3350
|
target,
|
|
@@ -3321,6 +3457,7 @@ class Replayer {
|
|
|
3321
3457
|
}
|
|
3322
3458
|
setConfig(config) {
|
|
3323
3459
|
Object.keys(config).forEach((key) => {
|
|
3460
|
+
config[key];
|
|
3324
3461
|
this.config[key] = config[key];
|
|
3325
3462
|
});
|
|
3326
3463
|
if (!this.config.skipInactive) {
|
|
@@ -3492,7 +3629,7 @@ class Replayer {
|
|
|
3492
3629
|
if (indicatesTouchDevice(event)) {
|
|
3493
3630
|
this.mouse.classList.add('touch-device');
|
|
3494
3631
|
}
|
|
3495
|
-
Promise.resolve().then(() => this.service.send({ type: 'ADD_EVENT', payload: { event } }));
|
|
3632
|
+
void Promise.resolve().then(() => this.service.send({ type: 'ADD_EVENT', payload: { event } }));
|
|
3496
3633
|
}
|
|
3497
3634
|
replaceEvents(events) {
|
|
3498
3635
|
for (const event of events) {
|
|
@@ -3541,142 +3678,6 @@ class Replayer {
|
|
|
3541
3678
|
polyfill(this.iframe.contentWindow);
|
|
3542
3679
|
}
|
|
3543
3680
|
}
|
|
3544
|
-
handleResize(dimension) {
|
|
3545
|
-
this.iframe.style.display = 'inherit';
|
|
3546
|
-
for (const el of [this.mouseTail, this.iframe]) {
|
|
3547
|
-
if (!el) {
|
|
3548
|
-
continue;
|
|
3549
|
-
}
|
|
3550
|
-
el.setAttribute('width', String(dimension.width));
|
|
3551
|
-
el.setAttribute('height', String(dimension.height));
|
|
3552
|
-
}
|
|
3553
|
-
}
|
|
3554
|
-
applyEventsSynchronously(events) {
|
|
3555
|
-
for (const event of events) {
|
|
3556
|
-
switch (event.type) {
|
|
3557
|
-
case EventType.DomContentLoaded:
|
|
3558
|
-
case EventType.Load:
|
|
3559
|
-
case EventType.Custom:
|
|
3560
|
-
continue;
|
|
3561
|
-
case EventType.FullSnapshot:
|
|
3562
|
-
case EventType.Meta:
|
|
3563
|
-
case EventType.Plugin:
|
|
3564
|
-
case EventType.IncrementalSnapshot:
|
|
3565
|
-
break;
|
|
3566
|
-
}
|
|
3567
|
-
const castFn = this.getCastFn(event, true);
|
|
3568
|
-
castFn();
|
|
3569
|
-
}
|
|
3570
|
-
if (this.touchActive === true) {
|
|
3571
|
-
this.mouse.classList.add('touch-active');
|
|
3572
|
-
}
|
|
3573
|
-
else if (this.touchActive === false) {
|
|
3574
|
-
this.mouse.classList.remove('touch-active');
|
|
3575
|
-
}
|
|
3576
|
-
this.touchActive = null;
|
|
3577
|
-
}
|
|
3578
|
-
getCastFn(event, isSync = false) {
|
|
3579
|
-
let castFn;
|
|
3580
|
-
switch (event.type) {
|
|
3581
|
-
case EventType.DomContentLoaded:
|
|
3582
|
-
case EventType.Load:
|
|
3583
|
-
break;
|
|
3584
|
-
case EventType.Custom:
|
|
3585
|
-
castFn = () => {
|
|
3586
|
-
this.emitter.emit(ReplayerEvents.CustomEvent, event);
|
|
3587
|
-
};
|
|
3588
|
-
break;
|
|
3589
|
-
case EventType.Meta:
|
|
3590
|
-
castFn = () => this.emitter.emit(ReplayerEvents.Resize, {
|
|
3591
|
-
width: event.data.width,
|
|
3592
|
-
height: event.data.height,
|
|
3593
|
-
});
|
|
3594
|
-
break;
|
|
3595
|
-
case EventType.FullSnapshot:
|
|
3596
|
-
castFn = () => {
|
|
3597
|
-
if (this.firstFullSnapshot) {
|
|
3598
|
-
if (this.firstFullSnapshot === event) {
|
|
3599
|
-
this.firstFullSnapshot = true;
|
|
3600
|
-
return;
|
|
3601
|
-
}
|
|
3602
|
-
}
|
|
3603
|
-
else {
|
|
3604
|
-
this.firstFullSnapshot = true;
|
|
3605
|
-
}
|
|
3606
|
-
this.rebuildFullSnapshot(event, isSync);
|
|
3607
|
-
this.iframe.contentWindow.scrollTo(event.data.initialOffset);
|
|
3608
|
-
};
|
|
3609
|
-
break;
|
|
3610
|
-
case EventType.IncrementalSnapshot:
|
|
3611
|
-
castFn = () => {
|
|
3612
|
-
this.applyIncremental(event, isSync);
|
|
3613
|
-
if (isSync) {
|
|
3614
|
-
return;
|
|
3615
|
-
}
|
|
3616
|
-
this.handleInactivity(event.timestamp);
|
|
3617
|
-
if (event === this.nextUserInteractionEvent) {
|
|
3618
|
-
this.nextUserInteractionEvent = null;
|
|
3619
|
-
this.backToNormal();
|
|
3620
|
-
}
|
|
3621
|
-
if (this.config.skipInactive && !this.nextUserInteractionEvent) {
|
|
3622
|
-
for (const _event of this.service.state.context.events) {
|
|
3623
|
-
if (_event.timestamp <= event.timestamp) {
|
|
3624
|
-
continue;
|
|
3625
|
-
}
|
|
3626
|
-
if (this.isUserInteraction(_event)) {
|
|
3627
|
-
if (_event.delay - event.delay >
|
|
3628
|
-
SKIP_TIME_THRESHOLD *
|
|
3629
|
-
this.speedService.state.context.timer.speed) {
|
|
3630
|
-
this.nextUserInteractionEvent = _event;
|
|
3631
|
-
}
|
|
3632
|
-
break;
|
|
3633
|
-
}
|
|
3634
|
-
}
|
|
3635
|
-
if (this.nextUserInteractionEvent) {
|
|
3636
|
-
const skipTime = this.nextUserInteractionEvent.delay - event.delay;
|
|
3637
|
-
const payload = {
|
|
3638
|
-
speed: Math.min(Math.round(skipTime / SKIP_TIME_INTERVAL), this.config.maxSpeed),
|
|
3639
|
-
};
|
|
3640
|
-
this.speedService.send({ type: 'FAST_FORWARD', payload });
|
|
3641
|
-
this.emitter.emit(ReplayerEvents.SkipStart, payload);
|
|
3642
|
-
}
|
|
3643
|
-
}
|
|
3644
|
-
};
|
|
3645
|
-
break;
|
|
3646
|
-
}
|
|
3647
|
-
const wrappedCastFn = () => {
|
|
3648
|
-
if (castFn) {
|
|
3649
|
-
castFn();
|
|
3650
|
-
}
|
|
3651
|
-
for (const plugin of this.config.plugins || []) {
|
|
3652
|
-
plugin.handler(event, isSync, { replayer: this });
|
|
3653
|
-
}
|
|
3654
|
-
this.service.send({ type: 'CAST_EVENT', payload: { event } });
|
|
3655
|
-
const last_index = this.service.state.context.events.length - 1;
|
|
3656
|
-
if (event === this.service.state.context.events[last_index]) {
|
|
3657
|
-
const finish = () => {
|
|
3658
|
-
if (last_index < this.service.state.context.events.length - 1) {
|
|
3659
|
-
return;
|
|
3660
|
-
}
|
|
3661
|
-
this.backToNormal();
|
|
3662
|
-
this.service.send('END');
|
|
3663
|
-
this.emitter.emit(ReplayerEvents.Finish);
|
|
3664
|
-
};
|
|
3665
|
-
if (event.type === EventType.IncrementalSnapshot &&
|
|
3666
|
-
event.data.source === IncrementalSource.MouseMove &&
|
|
3667
|
-
event.data.positions.length) {
|
|
3668
|
-
setTimeout(() => {
|
|
3669
|
-
finish();
|
|
3670
|
-
}, Math.max(0, -event.data.positions[0].timeOffset + 50));
|
|
3671
|
-
}
|
|
3672
|
-
else {
|
|
3673
|
-
finish();
|
|
3674
|
-
}
|
|
3675
|
-
}
|
|
3676
|
-
this.emitter.emit(ReplayerEvents.EventCast, event);
|
|
3677
|
-
};
|
|
3678
|
-
return wrappedCastFn;
|
|
3679
|
-
}
|
|
3680
3681
|
handleInactivity(timestamp, resetNext) {
|
|
3681
3682
|
if (timestamp === this.inactiveEndTimestamp || resetNext) {
|
|
3682
3683
|
this.inactiveEndTimestamp = null;
|
|
@@ -3738,7 +3739,7 @@ class Replayer {
|
|
|
3738
3739
|
this.waitForStylesheetLoad();
|
|
3739
3740
|
}
|
|
3740
3741
|
if (this.config.UNSAFE_replayCanvas) {
|
|
3741
|
-
this.preloadAllImages();
|
|
3742
|
+
void this.preloadAllImages();
|
|
3742
3743
|
}
|
|
3743
3744
|
}
|
|
3744
3745
|
insertStyleRules(documentElement, head) {
|
|
@@ -3852,39 +3853,6 @@ class Replayer {
|
|
|
3852
3853
|
}
|
|
3853
3854
|
}
|
|
3854
3855
|
}
|
|
3855
|
-
hasImageArg(args) {
|
|
3856
|
-
for (const arg of args) {
|
|
3857
|
-
if (!arg || typeof arg !== 'object') ;
|
|
3858
|
-
else if ('rr_type' in arg && 'args' in arg) {
|
|
3859
|
-
if (this.hasImageArg(arg.args))
|
|
3860
|
-
return true;
|
|
3861
|
-
}
|
|
3862
|
-
else if ('rr_type' in arg && arg.rr_type === 'HTMLImageElement') {
|
|
3863
|
-
return true;
|
|
3864
|
-
}
|
|
3865
|
-
else if (arg instanceof Array) {
|
|
3866
|
-
if (this.hasImageArg(arg))
|
|
3867
|
-
return true;
|
|
3868
|
-
}
|
|
3869
|
-
}
|
|
3870
|
-
return false;
|
|
3871
|
-
}
|
|
3872
|
-
getImageArgs(args) {
|
|
3873
|
-
const images = [];
|
|
3874
|
-
for (const arg of args) {
|
|
3875
|
-
if (!arg || typeof arg !== 'object') ;
|
|
3876
|
-
else if ('rr_type' in arg && 'args' in arg) {
|
|
3877
|
-
images.push(...this.getImageArgs(arg.args));
|
|
3878
|
-
}
|
|
3879
|
-
else if ('rr_type' in arg && arg.rr_type === 'HTMLImageElement') {
|
|
3880
|
-
images.push(arg.src);
|
|
3881
|
-
}
|
|
3882
|
-
else if (arg instanceof Array) {
|
|
3883
|
-
images.push(...this.getImageArgs(arg));
|
|
3884
|
-
}
|
|
3885
|
-
}
|
|
3886
|
-
return images;
|
|
3887
|
-
}
|
|
3888
3856
|
preloadAllImages() {
|
|
3889
3857
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3890
3858
|
this.service.state;
|
|
@@ -3979,7 +3947,8 @@ class Replayer {
|
|
|
3979
3947
|
this.timer.addAction(action);
|
|
3980
3948
|
});
|
|
3981
3949
|
this.timer.addAction({
|
|
3982
|
-
doAction() {
|
|
3950
|
+
doAction() {
|
|
3951
|
+
},
|
|
3983
3952
|
delay: e.delay - ((_a = d.positions[0]) === null || _a === void 0 ? void 0 : _a.timeOffset),
|
|
3984
3953
|
});
|
|
3985
3954
|
}
|
|
@@ -4118,7 +4087,7 @@ class Replayer {
|
|
|
4118
4087
|
mediaEl.pause();
|
|
4119
4088
|
}
|
|
4120
4089
|
if (d.type === 0) {
|
|
4121
|
-
mediaEl.play();
|
|
4090
|
+
void mediaEl.play();
|
|
4122
4091
|
}
|
|
4123
4092
|
}
|
|
4124
4093
|
catch (error) {
|
|
@@ -4230,7 +4199,7 @@ class Replayer {
|
|
|
4230
4199
|
if (!target) {
|
|
4231
4200
|
return this.debugNodeNotFound(d, d.id);
|
|
4232
4201
|
}
|
|
4233
|
-
canvasMutation({
|
|
4202
|
+
void canvasMutation({
|
|
4234
4203
|
event: e,
|
|
4235
4204
|
mutation: d,
|
|
4236
4205
|
target: target,
|
|
@@ -4243,7 +4212,9 @@ class Replayer {
|
|
|
4243
4212
|
}
|
|
4244
4213
|
case IncrementalSource.Font: {
|
|
4245
4214
|
try {
|
|
4246
|
-
const fontFace = new FontFace(d.family, d.buffer
|
|
4215
|
+
const fontFace = new FontFace(d.family, d.buffer
|
|
4216
|
+
? new Uint8Array(JSON.parse(d.fontSource))
|
|
4217
|
+
: d.fontSource, d.descriptors);
|
|
4247
4218
|
(_f = this.iframe.contentDocument) === null || _f === void 0 ? void 0 : _f.fonts.add(fontFace);
|
|
4248
4219
|
}
|
|
4249
4220
|
catch (error) {
|