@highlight-run/rrweb 2.0.0-lambda.7 → 2.0.0-lambda.9
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/rrweb.cjs +916 -76
- package/dist/rrweb.cjs.map +1 -1
- package/dist/rrweb.d.cts +179 -1
- package/dist/rrweb.d.ts +179 -1
- package/dist/rrweb.js +916 -76
- package/dist/rrweb.js.map +1 -1
- package/dist/rrweb.umd.cjs +908 -76
- package/dist/rrweb.umd.cjs.map +4 -4
- package/dist/rrweb.umd.min.cjs +57 -47
- package/dist/rrweb.umd.min.cjs.map +4 -4
- package/package.json +5 -5
- package/umd/rrweb.js +908 -76
- package/umd/rrweb.min.js +57 -47
package/dist/rrweb.js
CHANGED
|
@@ -1873,6 +1873,7 @@ function requireStringifier$1() {
|
|
|
1873
1873
|
hasRequiredStringifier$1 = 1;
|
|
1874
1874
|
const STYLE_TAG = /(<)(\/?style\b)/gi;
|
|
1875
1875
|
const COMMENT_OPEN = /(<)(!--)/g;
|
|
1876
|
+
const AT_NAME_END = /[\t\n\f\r "#'()/;[\\\]{}]/;
|
|
1876
1877
|
function escapeHTMLInCSS(str) {
|
|
1877
1878
|
if (typeof str !== "string") return str;
|
|
1878
1879
|
if (!str.includes("<")) return str;
|
|
@@ -1898,12 +1899,13 @@ function requireStringifier$1() {
|
|
|
1898
1899
|
function atruleStart(str, node2) {
|
|
1899
1900
|
let name = "@" + node2.name;
|
|
1900
1901
|
let params = node2.params ? str.rawValue(node2, "params") : "";
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1902
|
+
let afterName = node2.raws.afterName;
|
|
1903
|
+
if (typeof afterName === "undefined") {
|
|
1904
|
+
afterName = params ? " " : "";
|
|
1905
|
+
} else if (afterName === "" && params && !AT_NAME_END.test(params[0])) {
|
|
1906
|
+
afterName = " ";
|
|
1905
1907
|
}
|
|
1906
|
-
return name + params;
|
|
1908
|
+
return name + afterName + params;
|
|
1907
1909
|
}
|
|
1908
1910
|
function pushBody(str, stack, node2) {
|
|
1909
1911
|
let nodes = node2.nodes;
|
|
@@ -1915,10 +1917,15 @@ function requireStringifier$1() {
|
|
|
1915
1917
|
let semicolon = str.raw(node2, "semicolon");
|
|
1916
1918
|
let isDocument = node2.type === "document";
|
|
1917
1919
|
for (let i2 = nodes.length - 1; i2 >= 0; i2--) {
|
|
1920
|
+
let child = nodes[i2];
|
|
1921
|
+
let childSemicolon = last !== i2 || semicolon;
|
|
1922
|
+
if (!childSemicolon && i2 < nodes.length - 1 && (child.type === "atrule" && !child.nodes || child.type === "decl" && child.prop.startsWith("--"))) {
|
|
1923
|
+
childSemicolon = true;
|
|
1924
|
+
}
|
|
1918
1925
|
stack.push({
|
|
1919
1926
|
document: isDocument,
|
|
1920
|
-
node:
|
|
1921
|
-
semicolon:
|
|
1927
|
+
node: child,
|
|
1928
|
+
semicolon: childSemicolon
|
|
1922
1929
|
});
|
|
1923
1930
|
}
|
|
1924
1931
|
}
|
|
@@ -2209,6 +2216,9 @@ function requireStringifier$1() {
|
|
|
2209
2216
|
return value;
|
|
2210
2217
|
}
|
|
2211
2218
|
root(node2) {
|
|
2219
|
+
if (node2.source && node2.source.input.hasBOM) {
|
|
2220
|
+
this.builder("\uFEFF", node2, "start");
|
|
2221
|
+
}
|
|
2212
2222
|
this.body(node2);
|
|
2213
2223
|
if (node2.raws.after) {
|
|
2214
2224
|
let after = node2.raws.after;
|
|
@@ -3281,15 +3291,12 @@ function requirePreviousMap$1() {
|
|
|
3281
3291
|
}
|
|
3282
3292
|
loadFile(path, cssFile, trusted) {
|
|
3283
3293
|
if (!trusted && !this.unsafeMap) {
|
|
3284
|
-
if (!/\.map$/i.test(path))
|
|
3294
|
+
if (!/\.map$/i.test(path)) return void 0;
|
|
3295
|
+
if (!cssFile) return void 0;
|
|
3296
|
+
let rel = relative(dirname(cssFile), path);
|
|
3297
|
+
if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) {
|
|
3285
3298
|
return void 0;
|
|
3286
3299
|
}
|
|
3287
|
-
if (cssFile) {
|
|
3288
|
-
let relativePath = relative(dirname(cssFile), path);
|
|
3289
|
-
if (relativePath === ".." || relativePath.startsWith(".." + sep) || isAbsolute(relativePath)) {
|
|
3290
|
-
return void 0;
|
|
3291
|
-
}
|
|
3292
|
-
}
|
|
3293
3300
|
}
|
|
3294
3301
|
this.root = dirname(path);
|
|
3295
3302
|
if (existsSync(path)) {
|
|
@@ -3661,6 +3668,7 @@ function requireList$1() {
|
|
|
3661
3668
|
return list.split(string, spaces);
|
|
3662
3669
|
},
|
|
3663
3670
|
split(string, separators, last) {
|
|
3671
|
+
if (!string) return [];
|
|
3664
3672
|
let array = [];
|
|
3665
3673
|
let current = "";
|
|
3666
3674
|
let split = false;
|
|
@@ -4947,11 +4955,16 @@ var hasRequiredWarning$1;
|
|
|
4947
4955
|
function requireWarning$1() {
|
|
4948
4956
|
if (hasRequiredWarning$1) return warning$1;
|
|
4949
4957
|
hasRequiredWarning$1 = 1;
|
|
4958
|
+
let Container = requireContainer$1();
|
|
4959
|
+
let { my } = requireSymbols$1();
|
|
4950
4960
|
class Warning {
|
|
4951
4961
|
constructor(text, opts = {}) {
|
|
4952
4962
|
this.type = "warning";
|
|
4953
4963
|
this.text = text;
|
|
4954
4964
|
if (opts.node && opts.node.source) {
|
|
4965
|
+
if (!opts.node[my]) {
|
|
4966
|
+
Container.rebuild(opts.node);
|
|
4967
|
+
}
|
|
4955
4968
|
let range = opts.node.rangeBy(opts);
|
|
4956
4969
|
this.line = range.start.line;
|
|
4957
4970
|
this.column = range.start.column;
|
|
@@ -5461,14 +5474,19 @@ function requireLazyResult$1() {
|
|
|
5461
5474
|
}
|
|
5462
5475
|
if (visit2.iterator !== 0) {
|
|
5463
5476
|
let iterator = visit2.iterator;
|
|
5477
|
+
if (visit2.descending) {
|
|
5478
|
+
visit2.descending = false;
|
|
5479
|
+
node2.indexes[iterator] += 1;
|
|
5480
|
+
}
|
|
5464
5481
|
let child;
|
|
5465
5482
|
while (child = node2.nodes[node2.indexes[iterator]]) {
|
|
5466
|
-
node2.indexes[iterator] += 1;
|
|
5467
5483
|
if (!child[isClean]) {
|
|
5468
5484
|
child[isClean] = true;
|
|
5485
|
+
visit2.descending = true;
|
|
5469
5486
|
stack.push(toStack(child));
|
|
5470
5487
|
return;
|
|
5471
5488
|
}
|
|
5489
|
+
node2.indexes[iterator] += 1;
|
|
5472
5490
|
}
|
|
5473
5491
|
visit2.iterator = 0;
|
|
5474
5492
|
delete node2.indexes[iterator];
|
|
@@ -5498,12 +5516,16 @@ function requireLazyResult$1() {
|
|
|
5498
5516
|
let visitNode = visit2.node;
|
|
5499
5517
|
if (visit2.iterator !== 0) {
|
|
5500
5518
|
let iterator = visit2.iterator;
|
|
5519
|
+
if (visit2.descending) {
|
|
5520
|
+
visit2.descending = false;
|
|
5521
|
+
visitNode.indexes[iterator] += 1;
|
|
5522
|
+
}
|
|
5501
5523
|
let child;
|
|
5502
5524
|
let descended = false;
|
|
5503
5525
|
while (child = visitNode.nodes[visitNode.indexes[iterator]]) {
|
|
5504
|
-
visitNode.indexes[iterator] += 1;
|
|
5505
5526
|
if (!child[isClean]) {
|
|
5506
5527
|
child[isClean] = true;
|
|
5528
|
+
visit2.descending = true;
|
|
5507
5529
|
stack.push({
|
|
5508
5530
|
eventIndex: 0,
|
|
5509
5531
|
events: getEvents(child),
|
|
@@ -5513,6 +5535,7 @@ function requireLazyResult$1() {
|
|
|
5513
5535
|
descended = true;
|
|
5514
5536
|
break;
|
|
5515
5537
|
}
|
|
5538
|
+
visitNode.indexes[iterator] += 1;
|
|
5516
5539
|
}
|
|
5517
5540
|
if (descended) continue;
|
|
5518
5541
|
visit2.iterator = 0;
|
|
@@ -5675,7 +5698,7 @@ function requireProcessor$1() {
|
|
|
5675
5698
|
let Root = requireRoot$1();
|
|
5676
5699
|
class Processor {
|
|
5677
5700
|
constructor(plugins = []) {
|
|
5678
|
-
this.version = "8.5.
|
|
5701
|
+
this.version = "8.5.25";
|
|
5679
5702
|
this.plugins = this.normalize(plugins);
|
|
5680
5703
|
}
|
|
5681
5704
|
normalize(plugins) {
|
|
@@ -6542,6 +6565,7 @@ function requireStringifier() {
|
|
|
6542
6565
|
hasRequiredStringifier = 1;
|
|
6543
6566
|
const STYLE_TAG = /(<)(\/?style\b)/gi;
|
|
6544
6567
|
const COMMENT_OPEN = /(<)(!--)/g;
|
|
6568
|
+
const AT_NAME_END = /[\t\n\f\r "#'()/;[\\\]{}]/;
|
|
6545
6569
|
function escapeHTMLInCSS(str) {
|
|
6546
6570
|
if (typeof str !== "string") return str;
|
|
6547
6571
|
if (!str.includes("<")) return str;
|
|
@@ -6567,12 +6591,13 @@ function requireStringifier() {
|
|
|
6567
6591
|
function atruleStart(str, node2) {
|
|
6568
6592
|
let name = "@" + node2.name;
|
|
6569
6593
|
let params = node2.params ? str.rawValue(node2, "params") : "";
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6594
|
+
let afterName = node2.raws.afterName;
|
|
6595
|
+
if (typeof afterName === "undefined") {
|
|
6596
|
+
afterName = params ? " " : "";
|
|
6597
|
+
} else if (afterName === "" && params && !AT_NAME_END.test(params[0])) {
|
|
6598
|
+
afterName = " ";
|
|
6574
6599
|
}
|
|
6575
|
-
return name + params;
|
|
6600
|
+
return name + afterName + params;
|
|
6576
6601
|
}
|
|
6577
6602
|
function pushBody(str, stack, node2) {
|
|
6578
6603
|
let nodes = node2.nodes;
|
|
@@ -6584,10 +6609,15 @@ function requireStringifier() {
|
|
|
6584
6609
|
let semicolon = str.raw(node2, "semicolon");
|
|
6585
6610
|
let isDocument = node2.type === "document";
|
|
6586
6611
|
for (let i2 = nodes.length - 1; i2 >= 0; i2--) {
|
|
6612
|
+
let child = nodes[i2];
|
|
6613
|
+
let childSemicolon = last !== i2 || semicolon;
|
|
6614
|
+
if (!childSemicolon && i2 < nodes.length - 1 && (child.type === "atrule" && !child.nodes || child.type === "decl" && child.prop.startsWith("--"))) {
|
|
6615
|
+
childSemicolon = true;
|
|
6616
|
+
}
|
|
6587
6617
|
stack.push({
|
|
6588
6618
|
document: isDocument,
|
|
6589
|
-
node:
|
|
6590
|
-
semicolon:
|
|
6619
|
+
node: child,
|
|
6620
|
+
semicolon: childSemicolon
|
|
6591
6621
|
});
|
|
6592
6622
|
}
|
|
6593
6623
|
}
|
|
@@ -6878,6 +6908,9 @@ function requireStringifier() {
|
|
|
6878
6908
|
return value;
|
|
6879
6909
|
}
|
|
6880
6910
|
root(node2) {
|
|
6911
|
+
if (node2.source && node2.source.input.hasBOM) {
|
|
6912
|
+
this.builder("\uFEFF", node2, "start");
|
|
6913
|
+
}
|
|
6881
6914
|
this.body(node2);
|
|
6882
6915
|
if (node2.raws.after) {
|
|
6883
6916
|
let after = node2.raws.after;
|
|
@@ -7950,15 +7983,12 @@ function requirePreviousMap() {
|
|
|
7950
7983
|
}
|
|
7951
7984
|
loadFile(path, cssFile, trusted) {
|
|
7952
7985
|
if (!trusted && !this.unsafeMap) {
|
|
7953
|
-
if (!/\.map$/i.test(path))
|
|
7986
|
+
if (!/\.map$/i.test(path)) return void 0;
|
|
7987
|
+
if (!cssFile) return void 0;
|
|
7988
|
+
let rel = relative(dirname(cssFile), path);
|
|
7989
|
+
if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) {
|
|
7954
7990
|
return void 0;
|
|
7955
7991
|
}
|
|
7956
|
-
if (cssFile) {
|
|
7957
|
-
let relativePath = relative(dirname(cssFile), path);
|
|
7958
|
-
if (relativePath === ".." || relativePath.startsWith(".." + sep) || isAbsolute(relativePath)) {
|
|
7959
|
-
return void 0;
|
|
7960
|
-
}
|
|
7961
|
-
}
|
|
7962
7992
|
}
|
|
7963
7993
|
this.root = dirname(path);
|
|
7964
7994
|
if (existsSync(path)) {
|
|
@@ -8330,6 +8360,7 @@ function requireList() {
|
|
|
8330
8360
|
return list.split(string, spaces);
|
|
8331
8361
|
},
|
|
8332
8362
|
split(string, separators, last) {
|
|
8363
|
+
if (!string) return [];
|
|
8333
8364
|
let array = [];
|
|
8334
8365
|
let current = "";
|
|
8335
8366
|
let split = false;
|
|
@@ -9616,11 +9647,16 @@ var hasRequiredWarning;
|
|
|
9616
9647
|
function requireWarning() {
|
|
9617
9648
|
if (hasRequiredWarning) return warning;
|
|
9618
9649
|
hasRequiredWarning = 1;
|
|
9650
|
+
let Container = requireContainer();
|
|
9651
|
+
let { my } = requireSymbols();
|
|
9619
9652
|
class Warning {
|
|
9620
9653
|
constructor(text, opts = {}) {
|
|
9621
9654
|
this.type = "warning";
|
|
9622
9655
|
this.text = text;
|
|
9623
9656
|
if (opts.node && opts.node.source) {
|
|
9657
|
+
if (!opts.node[my]) {
|
|
9658
|
+
Container.rebuild(opts.node);
|
|
9659
|
+
}
|
|
9624
9660
|
let range = opts.node.rangeBy(opts);
|
|
9625
9661
|
this.line = range.start.line;
|
|
9626
9662
|
this.column = range.start.column;
|
|
@@ -10130,14 +10166,19 @@ function requireLazyResult() {
|
|
|
10130
10166
|
}
|
|
10131
10167
|
if (visit2.iterator !== 0) {
|
|
10132
10168
|
let iterator = visit2.iterator;
|
|
10169
|
+
if (visit2.descending) {
|
|
10170
|
+
visit2.descending = false;
|
|
10171
|
+
node2.indexes[iterator] += 1;
|
|
10172
|
+
}
|
|
10133
10173
|
let child;
|
|
10134
10174
|
while (child = node2.nodes[node2.indexes[iterator]]) {
|
|
10135
|
-
node2.indexes[iterator] += 1;
|
|
10136
10175
|
if (!child[isClean]) {
|
|
10137
10176
|
child[isClean] = true;
|
|
10177
|
+
visit2.descending = true;
|
|
10138
10178
|
stack.push(toStack(child));
|
|
10139
10179
|
return;
|
|
10140
10180
|
}
|
|
10181
|
+
node2.indexes[iterator] += 1;
|
|
10141
10182
|
}
|
|
10142
10183
|
visit2.iterator = 0;
|
|
10143
10184
|
delete node2.indexes[iterator];
|
|
@@ -10167,12 +10208,16 @@ function requireLazyResult() {
|
|
|
10167
10208
|
let visitNode = visit2.node;
|
|
10168
10209
|
if (visit2.iterator !== 0) {
|
|
10169
10210
|
let iterator = visit2.iterator;
|
|
10211
|
+
if (visit2.descending) {
|
|
10212
|
+
visit2.descending = false;
|
|
10213
|
+
visitNode.indexes[iterator] += 1;
|
|
10214
|
+
}
|
|
10170
10215
|
let child;
|
|
10171
10216
|
let descended = false;
|
|
10172
10217
|
while (child = visitNode.nodes[visitNode.indexes[iterator]]) {
|
|
10173
|
-
visitNode.indexes[iterator] += 1;
|
|
10174
10218
|
if (!child[isClean]) {
|
|
10175
10219
|
child[isClean] = true;
|
|
10220
|
+
visit2.descending = true;
|
|
10176
10221
|
stack.push({
|
|
10177
10222
|
eventIndex: 0,
|
|
10178
10223
|
events: getEvents(child),
|
|
@@ -10182,6 +10227,7 @@ function requireLazyResult() {
|
|
|
10182
10227
|
descended = true;
|
|
10183
10228
|
break;
|
|
10184
10229
|
}
|
|
10230
|
+
visitNode.indexes[iterator] += 1;
|
|
10185
10231
|
}
|
|
10186
10232
|
if (descended) continue;
|
|
10187
10233
|
visit2.iterator = 0;
|
|
@@ -10344,7 +10390,7 @@ function requireProcessor() {
|
|
|
10344
10390
|
let Root = requireRoot();
|
|
10345
10391
|
class Processor {
|
|
10346
10392
|
constructor(plugins = []) {
|
|
10347
|
-
this.version = "8.5.
|
|
10393
|
+
this.version = "8.5.25";
|
|
10348
10394
|
this.plugins = this.normalize(plugins);
|
|
10349
10395
|
}
|
|
10350
10396
|
normalize(plugins) {
|
|
@@ -13626,66 +13672,142 @@ function getIdAndStyleId(sheet, mirror2, styleMirror) {
|
|
|
13626
13672
|
id
|
|
13627
13673
|
};
|
|
13628
13674
|
}
|
|
13629
|
-
function
|
|
13675
|
+
function restorePatchedMethod(target, key, ours, restoreTo) {
|
|
13676
|
+
if (target[key] === ours) {
|
|
13677
|
+
target[key] = restoreTo;
|
|
13678
|
+
}
|
|
13679
|
+
}
|
|
13680
|
+
const MAX_CSSOM_REPATCH_ATTEMPTS = 5;
|
|
13681
|
+
function initStyleSheetObserver({
|
|
13682
|
+
styleSheetRuleCb,
|
|
13683
|
+
mirror: mirror2,
|
|
13684
|
+
stylesheetManager,
|
|
13685
|
+
doc,
|
|
13686
|
+
styleSheetResyncInterval
|
|
13687
|
+
}, { win }) {
|
|
13630
13688
|
if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
|
|
13631
13689
|
return () => {
|
|
13632
13690
|
};
|
|
13633
13691
|
}
|
|
13634
|
-
const
|
|
13635
|
-
|
|
13692
|
+
const reportedRuleCounts = /* @__PURE__ */ new WeakMap();
|
|
13693
|
+
const unreconcilableSheets = /* @__PURE__ */ new WeakSet();
|
|
13694
|
+
let probing = false;
|
|
13695
|
+
let probeInsertObserved = false;
|
|
13696
|
+
let probeDeleteObserved = false;
|
|
13697
|
+
let probeSheet;
|
|
13698
|
+
let stopped = false;
|
|
13699
|
+
let insideInsertRule = false;
|
|
13700
|
+
let insideDeleteRule = false;
|
|
13701
|
+
const noteReportedRules = (sheet, delta) => {
|
|
13702
|
+
const state = reportedRuleCounts.get(sheet);
|
|
13703
|
+
if (state) {
|
|
13704
|
+
state.reported = Math.max(0, state.reported + delta);
|
|
13705
|
+
state.everSeen = Math.max(state.everSeen, state.reported);
|
|
13706
|
+
}
|
|
13707
|
+
};
|
|
13708
|
+
const patchInsertRule = (target) => new Proxy(target, {
|
|
13636
13709
|
apply: callbackWrapper(
|
|
13637
|
-
(
|
|
13710
|
+
(nativeFn, thisArg, argumentsList) => {
|
|
13711
|
+
if (probing) {
|
|
13712
|
+
probeInsertObserved = true;
|
|
13713
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13714
|
+
}
|
|
13715
|
+
if (stopped || insideInsertRule) {
|
|
13716
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13717
|
+
}
|
|
13638
13718
|
const [rule2, index2] = argumentsList;
|
|
13639
13719
|
const { id, styleId } = getIdAndStyleId(
|
|
13640
13720
|
thisArg,
|
|
13641
13721
|
mirror2,
|
|
13642
13722
|
stylesheetManager.styleMirror
|
|
13643
13723
|
);
|
|
13644
|
-
|
|
13724
|
+
const reported = id && id !== -1 || styleId && styleId !== -1;
|
|
13725
|
+
if (reported) {
|
|
13645
13726
|
styleSheetRuleCb({
|
|
13646
13727
|
id,
|
|
13647
13728
|
styleId,
|
|
13648
13729
|
adds: [{ rule: rule2, index: index2 }]
|
|
13649
13730
|
});
|
|
13650
13731
|
}
|
|
13651
|
-
|
|
13732
|
+
insideInsertRule = true;
|
|
13733
|
+
let result2;
|
|
13734
|
+
try {
|
|
13735
|
+
result2 = nativeFn.apply(thisArg, argumentsList);
|
|
13736
|
+
} finally {
|
|
13737
|
+
insideInsertRule = false;
|
|
13738
|
+
}
|
|
13739
|
+
if (reported) {
|
|
13740
|
+
noteReportedRules(thisArg, 1);
|
|
13741
|
+
}
|
|
13742
|
+
return result2;
|
|
13652
13743
|
}
|
|
13653
13744
|
)
|
|
13654
13745
|
});
|
|
13655
|
-
|
|
13656
|
-
const rule2 = `${selector} { ${styleBlock} }`;
|
|
13657
|
-
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
|
|
13658
|
-
};
|
|
13659
|
-
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
|
13660
|
-
win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
|
|
13746
|
+
const patchDeleteRule = (target) => new Proxy(target, {
|
|
13661
13747
|
apply: callbackWrapper(
|
|
13662
|
-
(
|
|
13748
|
+
(nativeFn, thisArg, argumentsList) => {
|
|
13749
|
+
if (probing) {
|
|
13750
|
+
probeDeleteObserved = true;
|
|
13751
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13752
|
+
}
|
|
13753
|
+
if (stopped || insideDeleteRule) {
|
|
13754
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13755
|
+
}
|
|
13663
13756
|
const [index2] = argumentsList;
|
|
13664
13757
|
const { id, styleId } = getIdAndStyleId(
|
|
13665
13758
|
thisArg,
|
|
13666
13759
|
mirror2,
|
|
13667
13760
|
stylesheetManager.styleMirror
|
|
13668
13761
|
);
|
|
13669
|
-
|
|
13762
|
+
const reported = id && id !== -1 || styleId && styleId !== -1;
|
|
13763
|
+
if (reported) {
|
|
13670
13764
|
styleSheetRuleCb({
|
|
13671
13765
|
id,
|
|
13672
13766
|
styleId,
|
|
13673
13767
|
removes: [{ index: index2 }]
|
|
13674
13768
|
});
|
|
13675
13769
|
}
|
|
13676
|
-
|
|
13770
|
+
insideDeleteRule = true;
|
|
13771
|
+
let result2;
|
|
13772
|
+
try {
|
|
13773
|
+
result2 = nativeFn.apply(thisArg, argumentsList);
|
|
13774
|
+
} finally {
|
|
13775
|
+
insideDeleteRule = false;
|
|
13776
|
+
}
|
|
13777
|
+
if (reported) {
|
|
13778
|
+
noteReportedRules(thisArg, -1);
|
|
13779
|
+
}
|
|
13780
|
+
return result2;
|
|
13677
13781
|
}
|
|
13678
13782
|
)
|
|
13679
13783
|
});
|
|
13680
|
-
win.CSSStyleSheet.prototype.
|
|
13784
|
+
const insertRule = win.CSSStyleSheet.prototype.insertRule;
|
|
13785
|
+
let insertRuleProxy = patchInsertRule(insertRule);
|
|
13786
|
+
let restoreInsertRuleTo = insertRule;
|
|
13787
|
+
win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
|
|
13788
|
+
const addRule = win.CSSStyleSheet.prototype.addRule;
|
|
13789
|
+
const addRuleShim = function(selector, styleBlock, index2 = this.cssRules.length) {
|
|
13790
|
+
const rule2 = `${selector} { ${styleBlock} }`;
|
|
13791
|
+
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
|
|
13792
|
+
};
|
|
13793
|
+
win.CSSStyleSheet.prototype.addRule = addRuleShim;
|
|
13794
|
+
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
|
13795
|
+
let deleteRuleProxy = patchDeleteRule(deleteRule);
|
|
13796
|
+
let restoreDeleteRuleTo = deleteRule;
|
|
13797
|
+
win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
|
|
13798
|
+
const removeRule = win.CSSStyleSheet.prototype.removeRule;
|
|
13799
|
+
const removeRuleShim = function(index2) {
|
|
13681
13800
|
return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);
|
|
13682
13801
|
};
|
|
13802
|
+
win.CSSStyleSheet.prototype.removeRule = removeRuleShim;
|
|
13683
13803
|
let replace;
|
|
13804
|
+
let replaceProxy;
|
|
13684
13805
|
if (win.CSSStyleSheet.prototype.replace) {
|
|
13685
13806
|
replace = win.CSSStyleSheet.prototype.replace;
|
|
13686
|
-
|
|
13807
|
+
replaceProxy = new Proxy(replace, {
|
|
13687
13808
|
apply: callbackWrapper(
|
|
13688
13809
|
(target, thisArg, argumentsList) => {
|
|
13810
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13689
13811
|
const [text] = argumentsList;
|
|
13690
13812
|
const { id, styleId } = getIdAndStyleId(
|
|
13691
13813
|
thisArg,
|
|
@@ -13703,13 +13825,16 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13703
13825
|
}
|
|
13704
13826
|
)
|
|
13705
13827
|
});
|
|
13828
|
+
win.CSSStyleSheet.prototype.replace = replaceProxy;
|
|
13706
13829
|
}
|
|
13707
13830
|
let replaceSync;
|
|
13831
|
+
let replaceSyncProxy;
|
|
13708
13832
|
if (win.CSSStyleSheet.prototype.replaceSync) {
|
|
13709
13833
|
replaceSync = win.CSSStyleSheet.prototype.replaceSync;
|
|
13710
|
-
|
|
13834
|
+
replaceSyncProxy = new Proxy(replaceSync, {
|
|
13711
13835
|
apply: callbackWrapper(
|
|
13712
13836
|
(target, thisArg, argumentsList) => {
|
|
13837
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13713
13838
|
const [text] = argumentsList;
|
|
13714
13839
|
const { id, styleId } = getIdAndStyleId(
|
|
13715
13840
|
thisArg,
|
|
@@ -13727,6 +13852,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13727
13852
|
}
|
|
13728
13853
|
)
|
|
13729
13854
|
});
|
|
13855
|
+
win.CSSStyleSheet.prototype.replaceSync = replaceSyncProxy;
|
|
13730
13856
|
}
|
|
13731
13857
|
const supportedNestedCSSRuleTypes = {};
|
|
13732
13858
|
if (canMonkeyPatchNestedCSSRule("CSSGroupingRule")) {
|
|
@@ -13743,6 +13869,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13743
13869
|
}
|
|
13744
13870
|
}
|
|
13745
13871
|
const unmodifiedFunctions = {};
|
|
13872
|
+
const nestedProxies = {};
|
|
13746
13873
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
13747
13874
|
unmodifiedFunctions[typeKey] = {
|
|
13748
13875
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
@@ -13750,11 +13877,13 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13750
13877
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
13751
13878
|
deleteRule: type.prototype.deleteRule
|
|
13752
13879
|
};
|
|
13753
|
-
|
|
13880
|
+
nestedProxies[typeKey] = {};
|
|
13881
|
+
nestedProxies[typeKey].insertRule = new Proxy(
|
|
13754
13882
|
unmodifiedFunctions[typeKey].insertRule,
|
|
13755
13883
|
{
|
|
13756
13884
|
apply: callbackWrapper(
|
|
13757
13885
|
(target, thisArg, argumentsList) => {
|
|
13886
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13758
13887
|
const [rule2, index2] = argumentsList;
|
|
13759
13888
|
const { id, styleId } = getIdAndStyleId(
|
|
13760
13889
|
thisArg.parentStyleSheet,
|
|
@@ -13782,11 +13911,12 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13782
13911
|
)
|
|
13783
13912
|
}
|
|
13784
13913
|
);
|
|
13785
|
-
|
|
13914
|
+
nestedProxies[typeKey].deleteRule = new Proxy(
|
|
13786
13915
|
unmodifiedFunctions[typeKey].deleteRule,
|
|
13787
13916
|
{
|
|
13788
13917
|
apply: callbackWrapper(
|
|
13789
13918
|
(target, thisArg, argumentsList) => {
|
|
13919
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13790
13920
|
const [index2] = argumentsList;
|
|
13791
13921
|
const { id, styleId } = getIdAndStyleId(
|
|
13792
13922
|
thisArg.parentStyleSheet,
|
|
@@ -13807,15 +13937,148 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13807
13937
|
)
|
|
13808
13938
|
}
|
|
13809
13939
|
);
|
|
13940
|
+
type.prototype.insertRule = nestedProxies[typeKey].insertRule;
|
|
13941
|
+
type.prototype.deleteRule = nestedProxies[typeKey].deleteRule;
|
|
13810
13942
|
});
|
|
13943
|
+
const captureIsHealthy = () => {
|
|
13944
|
+
probing = true;
|
|
13945
|
+
probeInsertObserved = false;
|
|
13946
|
+
probeDeleteObserved = false;
|
|
13947
|
+
try {
|
|
13948
|
+
const probe = probeSheet ?? (probeSheet = new win.CSSStyleSheet());
|
|
13949
|
+
probe.insertRule(":root {}", 0);
|
|
13950
|
+
probe.deleteRule(0);
|
|
13951
|
+
} catch (error) {
|
|
13952
|
+
return {
|
|
13953
|
+
insertRule: win.CSSStyleSheet.prototype.insertRule === insertRuleProxy,
|
|
13954
|
+
deleteRule: win.CSSStyleSheet.prototype.deleteRule === deleteRuleProxy
|
|
13955
|
+
};
|
|
13956
|
+
} finally {
|
|
13957
|
+
probing = false;
|
|
13958
|
+
}
|
|
13959
|
+
return {
|
|
13960
|
+
insertRule: probeInsertObserved,
|
|
13961
|
+
deleteRule: probeDeleteObserved
|
|
13962
|
+
};
|
|
13963
|
+
};
|
|
13964
|
+
let repatchAttempts = 0;
|
|
13965
|
+
const repatch = (health) => {
|
|
13966
|
+
if (repatchAttempts >= MAX_CSSOM_REPATCH_ATTEMPTS) return;
|
|
13967
|
+
repatchAttempts += 1;
|
|
13968
|
+
if (!health.insertRule) {
|
|
13969
|
+
restoreInsertRuleTo = win.CSSStyleSheet.prototype.insertRule;
|
|
13970
|
+
insertRuleProxy = patchInsertRule(restoreInsertRuleTo);
|
|
13971
|
+
win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
|
|
13972
|
+
}
|
|
13973
|
+
if (!health.deleteRule) {
|
|
13974
|
+
restoreDeleteRuleTo = win.CSSStyleSheet.prototype.deleteRule;
|
|
13975
|
+
deleteRuleProxy = patchDeleteRule(restoreDeleteRuleTo);
|
|
13976
|
+
win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
|
|
13977
|
+
}
|
|
13978
|
+
};
|
|
13979
|
+
const resyncCssomStyleSheets = (trusted) => {
|
|
13980
|
+
for (let i2 = 0; i2 < doc.styleSheets.length; i2++) {
|
|
13981
|
+
const sheet = doc.styleSheets[i2];
|
|
13982
|
+
if (unreconcilableSheets.has(sheet)) continue;
|
|
13983
|
+
const owner = sheet.ownerNode;
|
|
13984
|
+
if (!owner || toLowerCase(owner.nodeName) !== "style") continue;
|
|
13985
|
+
if ((owner.textContent || "").trim().length) continue;
|
|
13986
|
+
const id = mirror2.getId(owner);
|
|
13987
|
+
if (!id || id === -1) continue;
|
|
13988
|
+
let rules2;
|
|
13989
|
+
try {
|
|
13990
|
+
rules2 = sheet.cssRules;
|
|
13991
|
+
} catch (error) {
|
|
13992
|
+
continue;
|
|
13993
|
+
}
|
|
13994
|
+
const live = rules2.length;
|
|
13995
|
+
let state = reportedRuleCounts.get(sheet);
|
|
13996
|
+
if (!state) {
|
|
13997
|
+
if (Array.from(rules2).some((rule2) => isCSSImportRule(rule2))) {
|
|
13998
|
+
unreconcilableSheets.add(sheet);
|
|
13999
|
+
continue;
|
|
14000
|
+
}
|
|
14001
|
+
state = { reported: live, everSeen: live };
|
|
14002
|
+
reportedRuleCounts.set(sheet, state);
|
|
14003
|
+
if (trusted) continue;
|
|
14004
|
+
replaceReplayerCopy(id, state, rules2);
|
|
14005
|
+
continue;
|
|
14006
|
+
}
|
|
14007
|
+
state.everSeen = Math.max(state.everSeen, live);
|
|
14008
|
+
if (live === state.reported) continue;
|
|
14009
|
+
if (live > state.reported) {
|
|
14010
|
+
const adds = [];
|
|
14011
|
+
for (let index2 = state.reported; index2 < live; index2++) {
|
|
14012
|
+
adds.push({ rule: rules2[index2].cssText, index: index2 });
|
|
14013
|
+
}
|
|
14014
|
+
styleSheetRuleCb({ id, adds });
|
|
14015
|
+
state.reported = live;
|
|
14016
|
+
} else {
|
|
14017
|
+
replaceReplayerCopy(id, state, rules2);
|
|
14018
|
+
}
|
|
14019
|
+
}
|
|
14020
|
+
};
|
|
14021
|
+
function replaceReplayerCopy(id, state, rules2) {
|
|
14022
|
+
const removes = [];
|
|
14023
|
+
for (let index2 = state.everSeen - 1; index2 >= 0; index2--) {
|
|
14024
|
+
removes.push({ index: index2 });
|
|
14025
|
+
}
|
|
14026
|
+
if (removes.length) styleSheetRuleCb({ id, removes });
|
|
14027
|
+
styleSheetRuleCb({
|
|
14028
|
+
id,
|
|
14029
|
+
adds: Array.from(rules2, (rule2, index2) => ({
|
|
14030
|
+
rule: rule2.cssText,
|
|
14031
|
+
index: index2
|
|
14032
|
+
}))
|
|
14033
|
+
});
|
|
14034
|
+
state.reported = rules2.length;
|
|
14035
|
+
state.everSeen = rules2.length;
|
|
14036
|
+
}
|
|
14037
|
+
let resyncTimer;
|
|
14038
|
+
if (styleSheetResyncInterval > 0) {
|
|
14039
|
+
resyncTimer = win.setInterval(
|
|
14040
|
+
callbackWrapper(() => {
|
|
14041
|
+
const health = captureIsHealthy();
|
|
14042
|
+
const healthy = health.insertRule && health.deleteRule;
|
|
14043
|
+
if (!healthy) repatch(health);
|
|
14044
|
+
resyncCssomStyleSheets(healthy);
|
|
14045
|
+
}),
|
|
14046
|
+
styleSheetResyncInterval
|
|
14047
|
+
);
|
|
14048
|
+
}
|
|
13811
14049
|
return callbackWrapper(() => {
|
|
13812
|
-
win.
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
14050
|
+
if (resyncTimer !== void 0) win.clearInterval(resyncTimer);
|
|
14051
|
+
stopped = true;
|
|
14052
|
+
const proto = win.CSSStyleSheet.prototype;
|
|
14053
|
+
restorePatchedMethod(
|
|
14054
|
+
proto,
|
|
14055
|
+
"insertRule",
|
|
14056
|
+
insertRuleProxy,
|
|
14057
|
+
restoreInsertRuleTo
|
|
14058
|
+
);
|
|
14059
|
+
restorePatchedMethod(
|
|
14060
|
+
proto,
|
|
14061
|
+
"deleteRule",
|
|
14062
|
+
deleteRuleProxy,
|
|
14063
|
+
restoreDeleteRuleTo
|
|
14064
|
+
);
|
|
14065
|
+
restorePatchedMethod(proto, "addRule", addRuleShim, addRule);
|
|
14066
|
+
restorePatchedMethod(proto, "removeRule", removeRuleShim, removeRule);
|
|
14067
|
+
replaceProxy && restorePatchedMethod(proto, "replace", replaceProxy, replace);
|
|
14068
|
+
replaceSyncProxy && restorePatchedMethod(proto, "replaceSync", replaceSyncProxy, replaceSync);
|
|
13816
14069
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
13817
|
-
|
|
13818
|
-
|
|
14070
|
+
restorePatchedMethod(
|
|
14071
|
+
type.prototype,
|
|
14072
|
+
"insertRule",
|
|
14073
|
+
nestedProxies[typeKey].insertRule,
|
|
14074
|
+
unmodifiedFunctions[typeKey].insertRule
|
|
14075
|
+
);
|
|
14076
|
+
restorePatchedMethod(
|
|
14077
|
+
type.prototype,
|
|
14078
|
+
"deleteRule",
|
|
14079
|
+
nestedProxies[typeKey].deleteRule,
|
|
14080
|
+
unmodifiedFunctions[typeKey].deleteRule
|
|
14081
|
+
);
|
|
13819
14082
|
});
|
|
13820
14083
|
});
|
|
13821
14084
|
}
|
|
@@ -15583,6 +15846,7 @@ function record(options = {}) {
|
|
|
15583
15846
|
keepIframeSrcFn = () => false,
|
|
15584
15847
|
privacySetting = "default",
|
|
15585
15848
|
ignoreCSSAttributes = /* @__PURE__ */ new Set([]),
|
|
15849
|
+
styleSheetResyncInterval = 2e3,
|
|
15586
15850
|
errorHandler: errorHandler2,
|
|
15587
15851
|
logger
|
|
15588
15852
|
} = options;
|
|
@@ -15961,6 +16225,7 @@ function record(options = {}) {
|
|
|
15961
16225
|
processedNodeManager,
|
|
15962
16226
|
canvasManager,
|
|
15963
16227
|
ignoreCSSAttributes,
|
|
16228
|
+
styleSheetResyncInterval,
|
|
15964
16229
|
privacySetting,
|
|
15965
16230
|
plugins: ((_a3 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a3.map((p) => ({
|
|
15966
16231
|
observer: p.observer,
|
|
@@ -16847,12 +17112,36 @@ function variableListFor(ctx, ctor) {
|
|
|
16847
17112
|
}
|
|
16848
17113
|
return contextMap.get(ctor);
|
|
16849
17114
|
}
|
|
16850
|
-
|
|
17115
|
+
const canvasArgConstructors = /* @__PURE__ */ new Set([
|
|
17116
|
+
"Int8Array",
|
|
17117
|
+
"Int16Array",
|
|
17118
|
+
"Int32Array",
|
|
17119
|
+
"Uint8Array",
|
|
17120
|
+
"Uint8ClampedArray",
|
|
17121
|
+
"Uint16Array",
|
|
17122
|
+
"Uint32Array",
|
|
17123
|
+
"Float32Array",
|
|
17124
|
+
"Float64Array",
|
|
17125
|
+
"DataView",
|
|
17126
|
+
"ImageData",
|
|
17127
|
+
// normally serialized as base64, but reachable in `args` form through
|
|
17128
|
+
// recordings made by older clients and through nested `DataView` args.
|
|
17129
|
+
"ArrayBuffer",
|
|
17130
|
+
// wraps nested args in recordings made by older clients — see the
|
|
17131
|
+
// `preloadAllImages` tests for the shape.
|
|
17132
|
+
"Array"
|
|
17133
|
+
]);
|
|
17134
|
+
function deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist = false) {
|
|
16851
17135
|
return async (arg) => {
|
|
16852
17136
|
if (arg && typeof arg === "object" && "rr_type" in arg) {
|
|
16853
17137
|
if (preload) preload.isUnchanged = false;
|
|
16854
17138
|
if (arg.rr_type === "ImageBitmap" && "args" in arg) {
|
|
16855
|
-
const args = await deserializeArg(
|
|
17139
|
+
const args = await deserializeArg(
|
|
17140
|
+
imageMap,
|
|
17141
|
+
ctx,
|
|
17142
|
+
preload,
|
|
17143
|
+
enforceCanvasArgAllowlist
|
|
17144
|
+
)(arg.args);
|
|
16856
17145
|
return await createImageBitmap.apply(null, args);
|
|
16857
17146
|
} else if ("index" in arg) {
|
|
16858
17147
|
if (preload || ctx === null) return arg;
|
|
@@ -16860,10 +17149,18 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16860
17149
|
return variableListFor(ctx, name)[index2];
|
|
16861
17150
|
} else if ("args" in arg) {
|
|
16862
17151
|
const { rr_type: name, args } = arg;
|
|
17152
|
+
if (enforceCanvasArgAllowlist && !canvasArgConstructors.has(name)) {
|
|
17153
|
+
console.warn(
|
|
17154
|
+
`[replayer] refusing to construct canvas arg of unknown type: ${name}`
|
|
17155
|
+
);
|
|
17156
|
+
return null;
|
|
17157
|
+
}
|
|
16863
17158
|
const ctor = window[name];
|
|
16864
17159
|
return new ctor(
|
|
16865
17160
|
...await Promise.all(
|
|
16866
|
-
args.map(
|
|
17161
|
+
args.map(
|
|
17162
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17163
|
+
)
|
|
16867
17164
|
)
|
|
16868
17165
|
);
|
|
16869
17166
|
} else if ("base64" in arg) {
|
|
@@ -16880,7 +17177,9 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16880
17177
|
}
|
|
16881
17178
|
} else if ("data" in arg && arg.rr_type === "Blob") {
|
|
16882
17179
|
const blobContents = await Promise.all(
|
|
16883
|
-
arg.data.map(
|
|
17180
|
+
arg.data.map(
|
|
17181
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17182
|
+
)
|
|
16884
17183
|
);
|
|
16885
17184
|
const blob2 = new Blob(blobContents, {
|
|
16886
17185
|
type: arg.type
|
|
@@ -16889,7 +17188,9 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16889
17188
|
}
|
|
16890
17189
|
} else if (Array.isArray(arg)) {
|
|
16891
17190
|
const result2 = await Promise.all(
|
|
16892
|
-
arg.map(
|
|
17191
|
+
arg.map(
|
|
17192
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17193
|
+
)
|
|
16893
17194
|
);
|
|
16894
17195
|
return result2;
|
|
16895
17196
|
}
|
|
@@ -16930,7 +17231,8 @@ async function webglMutation({
|
|
|
16930
17231
|
target,
|
|
16931
17232
|
type,
|
|
16932
17233
|
imageMap,
|
|
16933
|
-
errorHandler: errorHandler2
|
|
17234
|
+
errorHandler: errorHandler2,
|
|
17235
|
+
enforceCanvasArgAllowlist
|
|
16934
17236
|
}) {
|
|
16935
17237
|
try {
|
|
16936
17238
|
const ctx = getContext(target, type);
|
|
@@ -16941,7 +17243,9 @@ async function webglMutation({
|
|
|
16941
17243
|
}
|
|
16942
17244
|
const original = ctx[mutation.property];
|
|
16943
17245
|
const args = await Promise.all(
|
|
16944
|
-
mutation.args.map(
|
|
17246
|
+
mutation.args.map(
|
|
17247
|
+
deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
|
|
17248
|
+
)
|
|
16945
17249
|
);
|
|
16946
17250
|
const result2 = original.apply(ctx, args);
|
|
16947
17251
|
saveToWebGLVarMap(ctx, result2);
|
|
@@ -16956,7 +17260,8 @@ async function canvasMutation$1({
|
|
|
16956
17260
|
mutations,
|
|
16957
17261
|
target,
|
|
16958
17262
|
imageMap,
|
|
16959
|
-
errorHandler: errorHandler2
|
|
17263
|
+
errorHandler: errorHandler2,
|
|
17264
|
+
enforceCanvasArgAllowlist
|
|
16960
17265
|
}) {
|
|
16961
17266
|
const ctx = target.getContext("2d");
|
|
16962
17267
|
if (!ctx) {
|
|
@@ -16966,7 +17271,11 @@ async function canvasMutation$1({
|
|
|
16966
17271
|
wrapCanvasContextDrawImage(ctx);
|
|
16967
17272
|
const mutationArgsPromises = mutations.map(
|
|
16968
17273
|
async (mutation) => {
|
|
16969
|
-
return Promise.all(
|
|
17274
|
+
return Promise.all(
|
|
17275
|
+
mutation.args.map(
|
|
17276
|
+
deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
|
|
17277
|
+
)
|
|
17278
|
+
);
|
|
16970
17279
|
}
|
|
16971
17280
|
);
|
|
16972
17281
|
const args = await Promise.all(mutationArgsPromises);
|
|
@@ -16996,7 +17305,8 @@ async function canvasMutation({
|
|
|
16996
17305
|
target,
|
|
16997
17306
|
imageMap,
|
|
16998
17307
|
canvasEventMap,
|
|
16999
|
-
errorHandler: errorHandler2
|
|
17308
|
+
errorHandler: errorHandler2,
|
|
17309
|
+
enforceCanvasArgAllowlist
|
|
17000
17310
|
}) {
|
|
17001
17311
|
try {
|
|
17002
17312
|
const precomputedMutation = canvasEventMap.get(event) || mutation;
|
|
@@ -17009,7 +17319,8 @@ async function canvasMutation({
|
|
|
17009
17319
|
type: mutation.type,
|
|
17010
17320
|
target,
|
|
17011
17321
|
imageMap,
|
|
17012
|
-
errorHandler: errorHandler2
|
|
17322
|
+
errorHandler: errorHandler2,
|
|
17323
|
+
enforceCanvasArgAllowlist
|
|
17013
17324
|
});
|
|
17014
17325
|
}
|
|
17015
17326
|
return;
|
|
@@ -17019,7 +17330,8 @@ async function canvasMutation({
|
|
|
17019
17330
|
mutations: commands,
|
|
17020
17331
|
target,
|
|
17021
17332
|
imageMap,
|
|
17022
|
-
errorHandler: errorHandler2
|
|
17333
|
+
errorHandler: errorHandler2,
|
|
17334
|
+
enforceCanvasArgAllowlist
|
|
17023
17335
|
});
|
|
17024
17336
|
} catch (error) {
|
|
17025
17337
|
errorHandler2(mutation, error);
|
|
@@ -17462,6 +17774,7 @@ class Replayer {
|
|
|
17462
17774
|
insertStyleRules: [],
|
|
17463
17775
|
triggerFocus: true,
|
|
17464
17776
|
UNSAFE_replayCanvas: false,
|
|
17777
|
+
enforceCanvasArgAllowlist: false,
|
|
17465
17778
|
pauseAnimation: true,
|
|
17466
17779
|
mouseTail: defaultMouseTailConfig,
|
|
17467
17780
|
useVirtualDom: true,
|
|
@@ -17490,7 +17803,8 @@ class Replayer {
|
|
|
17490
17803
|
target,
|
|
17491
17804
|
imageMap: this.imageMap,
|
|
17492
17805
|
canvasEventMap: this.canvasEventMap,
|
|
17493
|
-
errorHandler: this.warnCanvasMutationFailed.bind(this)
|
|
17806
|
+
errorHandler: this.warnCanvasMutationFailed.bind(this),
|
|
17807
|
+
enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
|
|
17494
17808
|
});
|
|
17495
17809
|
},
|
|
17496
17810
|
applyInput: this.applyInput.bind(this),
|
|
@@ -18202,7 +18516,14 @@ class Replayer {
|
|
|
18202
18516
|
const commands = await Promise.all(
|
|
18203
18517
|
data.commands.map(async (c2) => {
|
|
18204
18518
|
const args = await Promise.all(
|
|
18205
|
-
c2.args.map(
|
|
18519
|
+
c2.args.map(
|
|
18520
|
+
deserializeArg(
|
|
18521
|
+
this.imageMap,
|
|
18522
|
+
null,
|
|
18523
|
+
status,
|
|
18524
|
+
this.config.enforceCanvasArgAllowlist
|
|
18525
|
+
)
|
|
18526
|
+
)
|
|
18206
18527
|
);
|
|
18207
18528
|
return { ...c2, args };
|
|
18208
18529
|
})
|
|
@@ -18211,7 +18532,14 @@ class Replayer {
|
|
|
18211
18532
|
this.canvasEventMap.set(event, { ...data, commands });
|
|
18212
18533
|
} else {
|
|
18213
18534
|
const args = await Promise.all(
|
|
18214
|
-
data.args.map(
|
|
18535
|
+
data.args.map(
|
|
18536
|
+
deserializeArg(
|
|
18537
|
+
this.imageMap,
|
|
18538
|
+
null,
|
|
18539
|
+
status,
|
|
18540
|
+
this.config.enforceCanvasArgAllowlist
|
|
18541
|
+
)
|
|
18542
|
+
)
|
|
18215
18543
|
);
|
|
18216
18544
|
if (status.isUnchanged === false)
|
|
18217
18545
|
this.canvasEventMap.set(event, { ...data, args });
|
|
@@ -18424,7 +18752,8 @@ class Replayer {
|
|
|
18424
18752
|
target,
|
|
18425
18753
|
imageMap: this.imageMap,
|
|
18426
18754
|
canvasEventMap: this.canvasEventMap,
|
|
18427
|
-
errorHandler: this.warnCanvasMutationFailed.bind(this)
|
|
18755
|
+
errorHandler: this.warnCanvasMutationFailed.bind(this),
|
|
18756
|
+
enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
|
|
18428
18757
|
});
|
|
18429
18758
|
}
|
|
18430
18759
|
break;
|
|
@@ -19147,20 +19476,531 @@ class Replayer {
|
|
|
19147
19476
|
this.config.logger.log(REPLAY_CONSOLE_PREFIX, ...args);
|
|
19148
19477
|
}
|
|
19149
19478
|
}
|
|
19479
|
+
const RRWEB_EMBEDDED_CHANNEL = "rrweb-embedded";
|
|
19480
|
+
const RRWEB_EMBEDDED_PROTOCOL_VERSION = 1;
|
|
19481
|
+
const SERIALIZABLE_CONFIG_KEYS = [
|
|
19482
|
+
"speed",
|
|
19483
|
+
"maxSpeed",
|
|
19484
|
+
"loadTimeout",
|
|
19485
|
+
"skipInactive",
|
|
19486
|
+
"inactivePeriodThreshold",
|
|
19487
|
+
"showWarning",
|
|
19488
|
+
"showDebug",
|
|
19489
|
+
"blockClass",
|
|
19490
|
+
"liveMode",
|
|
19491
|
+
"insertStyleRules",
|
|
19492
|
+
"triggerFocus",
|
|
19493
|
+
"UNSAFE_replayCanvas",
|
|
19494
|
+
"enforceCanvasArgAllowlist",
|
|
19495
|
+
"cspContent",
|
|
19496
|
+
"pauseAnimation",
|
|
19497
|
+
"mouseTail",
|
|
19498
|
+
"useVirtualDom",
|
|
19499
|
+
"inactiveThreshold",
|
|
19500
|
+
"inactiveSkipTime"
|
|
19501
|
+
];
|
|
19502
|
+
function pickSerializableConfig(config) {
|
|
19503
|
+
const out = {};
|
|
19504
|
+
if (config && typeof config === "object") {
|
|
19505
|
+
for (const key of SERIALIZABLE_CONFIG_KEYS) {
|
|
19506
|
+
const value = config[key];
|
|
19507
|
+
if (value !== void 0 && typeof value !== "function") {
|
|
19508
|
+
out[key] = value;
|
|
19509
|
+
}
|
|
19510
|
+
}
|
|
19511
|
+
}
|
|
19512
|
+
return out;
|
|
19513
|
+
}
|
|
19514
|
+
function wrap(message) {
|
|
19515
|
+
return {
|
|
19516
|
+
channel: RRWEB_EMBEDDED_CHANNEL,
|
|
19517
|
+
version: RRWEB_EMBEDDED_PROTOCOL_VERSION,
|
|
19518
|
+
message
|
|
19519
|
+
};
|
|
19520
|
+
}
|
|
19521
|
+
function isEnvelope(data) {
|
|
19522
|
+
if (!data || typeof data !== "object") return false;
|
|
19523
|
+
const e2 = data;
|
|
19524
|
+
return e2.channel === RRWEB_EMBEDDED_CHANNEL && e2.version === RRWEB_EMBEDDED_PROTOCOL_VERSION && !!e2.message && typeof e2.message === "object" && typeof e2.message.type === "string";
|
|
19525
|
+
}
|
|
19526
|
+
const PAYLOAD_EVENTS = /* @__PURE__ */ new Set([
|
|
19527
|
+
ReplayerEvents.Resize,
|
|
19528
|
+
ReplayerEvents.EventCast,
|
|
19529
|
+
ReplayerEvents.CustomEvent
|
|
19530
|
+
]);
|
|
19531
|
+
class EmbeddedReplayerHost {
|
|
19532
|
+
constructor(options = {}) {
|
|
19533
|
+
__publicField(this, "root");
|
|
19534
|
+
__publicField(this, "parentWindow");
|
|
19535
|
+
__publicField(this, "timeUpdateIntervalMs");
|
|
19536
|
+
__publicField(this, "expectedParentOrigin");
|
|
19537
|
+
__publicField(this, "replayer", null);
|
|
19538
|
+
__publicField(this, "playing", false);
|
|
19539
|
+
__publicField(this, "timer", null);
|
|
19540
|
+
__publicField(this, "started", false);
|
|
19541
|
+
/**
|
|
19542
|
+
* Last layout the parent asked for. Retained because each `Replayer` builds
|
|
19543
|
+
* its own wrapper element, so a re-init would otherwise drop the scaling and
|
|
19544
|
+
* render the replay at 1:1 in the corner.
|
|
19545
|
+
*/
|
|
19546
|
+
__publicField(this, "layout", null);
|
|
19547
|
+
__publicField(this, "onMessage", (event) => {
|
|
19548
|
+
if (event.source !== this.parentWindow) return;
|
|
19549
|
+
if (this.expectedParentOrigin === null) return;
|
|
19550
|
+
if (event.origin !== this.expectedParentOrigin) return;
|
|
19551
|
+
if (!isEnvelope(event.data)) return;
|
|
19552
|
+
try {
|
|
19553
|
+
this.handle(event.data.message);
|
|
19554
|
+
} catch (err) {
|
|
19555
|
+
this.post({
|
|
19556
|
+
type: "error",
|
|
19557
|
+
message: err instanceof Error ? err.message : String(err)
|
|
19558
|
+
});
|
|
19559
|
+
}
|
|
19560
|
+
});
|
|
19561
|
+
this.root = options.root ?? document.body;
|
|
19562
|
+
this.parentWindow = options.parentWindow ?? window.parent;
|
|
19563
|
+
this.timeUpdateIntervalMs = options.timeUpdateIntervalMs ?? 50;
|
|
19564
|
+
this.expectedParentOrigin = options.expectedParentOrigin ?? new URLSearchParams(location.search).get("parentOrigin") ?? null;
|
|
19565
|
+
}
|
|
19566
|
+
/** Install the message listener and announce readiness to the parent. */
|
|
19567
|
+
start() {
|
|
19568
|
+
if (this.started) return;
|
|
19569
|
+
this.started = true;
|
|
19570
|
+
if (this.expectedParentOrigin === null) {
|
|
19571
|
+
console.warn(
|
|
19572
|
+
"[rrweb-embedded] no parentOrigin configured; all incoming messages will be ignored"
|
|
19573
|
+
);
|
|
19574
|
+
}
|
|
19575
|
+
window.addEventListener("message", this.onMessage);
|
|
19576
|
+
this.post({ type: "ready" });
|
|
19577
|
+
}
|
|
19578
|
+
/** Tear everything down (also invoked on a `destroy` command). */
|
|
19579
|
+
stop() {
|
|
19580
|
+
var _a2;
|
|
19581
|
+
window.removeEventListener("message", this.onMessage);
|
|
19582
|
+
this.setPlaying(false);
|
|
19583
|
+
(_a2 = this.replayer) == null ? void 0 : _a2.destroy();
|
|
19584
|
+
this.replayer = null;
|
|
19585
|
+
this.started = false;
|
|
19586
|
+
}
|
|
19587
|
+
handle(command) {
|
|
19588
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
19589
|
+
switch (command.type) {
|
|
19590
|
+
case "ping":
|
|
19591
|
+
this.post({ type: "ready" });
|
|
19592
|
+
return;
|
|
19593
|
+
case "init":
|
|
19594
|
+
this.init(command.events, command.config, command.autoplay);
|
|
19595
|
+
return;
|
|
19596
|
+
case "play":
|
|
19597
|
+
(_a2 = this.replayer) == null ? void 0 : _a2.play(command.timeOffset ?? 0);
|
|
19598
|
+
this.setPlaying(true);
|
|
19599
|
+
return;
|
|
19600
|
+
case "pause":
|
|
19601
|
+
(_b = this.replayer) == null ? void 0 : _b.pause(command.timeOffset);
|
|
19602
|
+
this.setPlaying(false);
|
|
19603
|
+
this.postTime();
|
|
19604
|
+
return;
|
|
19605
|
+
case "resume":
|
|
19606
|
+
(_c = this.replayer) == null ? void 0 : _c.resume(command.timeOffset ?? 0);
|
|
19607
|
+
this.setPlaying(true);
|
|
19608
|
+
return;
|
|
19609
|
+
case "setLayout":
|
|
19610
|
+
this.layout = {
|
|
19611
|
+
scale: command.scale,
|
|
19612
|
+
anchor: command.anchor ?? "center"
|
|
19613
|
+
};
|
|
19614
|
+
this.applyLayout();
|
|
19615
|
+
this.postDimensions();
|
|
19616
|
+
return;
|
|
19617
|
+
case "setConfig":
|
|
19618
|
+
(_d = this.replayer) == null ? void 0 : _d.setConfig(pickSerializableConfig(command.config));
|
|
19619
|
+
return;
|
|
19620
|
+
case "replaceEvents":
|
|
19621
|
+
if (this.replayer) {
|
|
19622
|
+
this.replayer.replaceEvents(command.events);
|
|
19623
|
+
this.postInitialized();
|
|
19624
|
+
}
|
|
19625
|
+
return;
|
|
19626
|
+
case "addEvent":
|
|
19627
|
+
(_e = this.replayer) == null ? void 0 : _e.addEvent(command.event);
|
|
19628
|
+
return;
|
|
19629
|
+
case "enableInteract":
|
|
19630
|
+
(_f = this.replayer) == null ? void 0 : _f.enableInteract();
|
|
19631
|
+
return;
|
|
19632
|
+
case "disableInteract":
|
|
19633
|
+
(_g = this.replayer) == null ? void 0 : _g.disableInteract();
|
|
19634
|
+
return;
|
|
19635
|
+
case "destroy":
|
|
19636
|
+
this.stop();
|
|
19637
|
+
return;
|
|
19638
|
+
}
|
|
19639
|
+
}
|
|
19640
|
+
init(events, config, autoplay) {
|
|
19641
|
+
if (this.replayer) {
|
|
19642
|
+
this.setPlaying(false);
|
|
19643
|
+
this.replayer.destroy();
|
|
19644
|
+
}
|
|
19645
|
+
const replayerConfig = {
|
|
19646
|
+
...pickSerializableConfig(config),
|
|
19647
|
+
root: this.root
|
|
19648
|
+
};
|
|
19649
|
+
this.replayer = new Replayer(events, replayerConfig);
|
|
19650
|
+
this.wireEvents(this.replayer);
|
|
19651
|
+
this.applyLayout();
|
|
19652
|
+
this.postInitialized();
|
|
19653
|
+
this.postDimensions();
|
|
19654
|
+
if (autoplay) {
|
|
19655
|
+
this.replayer.play(0);
|
|
19656
|
+
this.setPlaying(true);
|
|
19657
|
+
}
|
|
19658
|
+
}
|
|
19659
|
+
/**
|
|
19660
|
+
* Translate the parent's layout intent into styles on the replay wrapper.
|
|
19661
|
+
*
|
|
19662
|
+
* Mirrors what an embedder would otherwise apply from its own stylesheet:
|
|
19663
|
+
* `transform-origin: top left` with `left: 50%` to center horizontally, and
|
|
19664
|
+
* either `top: 50%` + a -50% Y translate to center vertically, or `top: 0`
|
|
19665
|
+
* with no Y translate to anchor at the top edge.
|
|
19666
|
+
*/
|
|
19667
|
+
applyLayout() {
|
|
19668
|
+
var _a2;
|
|
19669
|
+
const wrapper = (_a2 = this.replayer) == null ? void 0 : _a2.wrapper;
|
|
19670
|
+
if (!wrapper || !this.layout) return;
|
|
19671
|
+
const { scale, anchor } = this.layout;
|
|
19672
|
+
const top = anchor === "top";
|
|
19673
|
+
wrapper.style.position = "absolute";
|
|
19674
|
+
wrapper.style.transformOrigin = "top left";
|
|
19675
|
+
wrapper.style.left = "50%";
|
|
19676
|
+
wrapper.style.top = top ? "0" : "50%";
|
|
19677
|
+
wrapper.style.transform = top ? `scale(${scale}) translate(-50%, 0)` : `scale(${scale}) translate(-50%, -50%)`;
|
|
19678
|
+
}
|
|
19679
|
+
/** Report the wrapper's rendered geometry; the parent cannot measure it. */
|
|
19680
|
+
postDimensions() {
|
|
19681
|
+
var _a2;
|
|
19682
|
+
const wrapper = (_a2 = this.replayer) == null ? void 0 : _a2.wrapper;
|
|
19683
|
+
if (!wrapper) return;
|
|
19684
|
+
const rect = wrapper.getBoundingClientRect();
|
|
19685
|
+
this.post({
|
|
19686
|
+
type: "dimensions",
|
|
19687
|
+
width: rect.width,
|
|
19688
|
+
height: rect.height,
|
|
19689
|
+
top: rect.top,
|
|
19690
|
+
left: rect.left
|
|
19691
|
+
});
|
|
19692
|
+
}
|
|
19693
|
+
/** Push the stable getters (metadata, activity intervals) to the parent. */
|
|
19694
|
+
postInitialized() {
|
|
19695
|
+
if (!this.replayer) return;
|
|
19696
|
+
this.post({
|
|
19697
|
+
type: "initialized",
|
|
19698
|
+
metadata: this.replayer.getMetaData(),
|
|
19699
|
+
activityIntervals: this.replayer.getActivityIntervals()
|
|
19700
|
+
});
|
|
19701
|
+
}
|
|
19702
|
+
wireEvents(replayer) {
|
|
19703
|
+
for (const name of Object.values(ReplayerEvents)) {
|
|
19704
|
+
replayer.on(name, (payload) => {
|
|
19705
|
+
if (name === ReplayerEvents.Finish) {
|
|
19706
|
+
this.setPlaying(false);
|
|
19707
|
+
this.postTime();
|
|
19708
|
+
}
|
|
19709
|
+
if (name === ReplayerEvents.Resize) {
|
|
19710
|
+
this.postDimensions();
|
|
19711
|
+
}
|
|
19712
|
+
this.post(
|
|
19713
|
+
PAYLOAD_EVENTS.has(name) && payload !== void 0 ? { type: "replayer-event", event: name, payload } : { type: "replayer-event", event: name }
|
|
19714
|
+
);
|
|
19715
|
+
});
|
|
19716
|
+
}
|
|
19717
|
+
}
|
|
19718
|
+
/* --- current-time telemetry ------------------------------------------- */
|
|
19719
|
+
setPlaying(playing) {
|
|
19720
|
+
if (this.playing === playing) return;
|
|
19721
|
+
this.playing = playing;
|
|
19722
|
+
if (playing) this.startTimePump();
|
|
19723
|
+
else this.stopTimePump();
|
|
19724
|
+
}
|
|
19725
|
+
startTimePump() {
|
|
19726
|
+
if (this.timer !== null) return;
|
|
19727
|
+
this.timer = setInterval(() => this.postTime(), this.timeUpdateIntervalMs);
|
|
19728
|
+
}
|
|
19729
|
+
/**
|
|
19730
|
+
* Push the current playback position across the bridge.
|
|
19731
|
+
*
|
|
19732
|
+
* The parent cannot read the position synchronously — it lives in this realm
|
|
19733
|
+
* behind an origin boundary — so the client's `getCurrentTime()` is only ever
|
|
19734
|
+
* as fresh as the last push. While playing, the pump keeps it current. When
|
|
19735
|
+
* playback stops the pump stops too, so the last pumped value would be up to
|
|
19736
|
+
* one interval stale; callers that seek from it (`play(getCurrentTime())` to
|
|
19737
|
+
* resume) would drift backwards. Pausing and finishing therefore push one
|
|
19738
|
+
* final, settled value.
|
|
19739
|
+
*/
|
|
19740
|
+
postTime() {
|
|
19741
|
+
if (!this.replayer) return;
|
|
19742
|
+
this.post({ type: "time", currentTime: this.replayer.getCurrentTime() });
|
|
19743
|
+
}
|
|
19744
|
+
stopTimePump() {
|
|
19745
|
+
if (this.timer !== null) {
|
|
19746
|
+
clearInterval(this.timer);
|
|
19747
|
+
this.timer = null;
|
|
19748
|
+
}
|
|
19749
|
+
}
|
|
19750
|
+
post(message) {
|
|
19751
|
+
this.parentWindow.postMessage(
|
|
19752
|
+
wrap(message),
|
|
19753
|
+
this.expectedParentOrigin ?? "*"
|
|
19754
|
+
);
|
|
19755
|
+
}
|
|
19756
|
+
}
|
|
19757
|
+
function startEmbeddedReplayerHost(options) {
|
|
19758
|
+
const host2 = new EmbeddedReplayerHost(options);
|
|
19759
|
+
host2.start();
|
|
19760
|
+
return host2;
|
|
19761
|
+
}
|
|
19762
|
+
class EmbeddedReplayerClient {
|
|
19763
|
+
constructor(iframe, options = {}) {
|
|
19764
|
+
__publicField(this, "iframe");
|
|
19765
|
+
__publicField(this, "hostOrigin");
|
|
19766
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
19767
|
+
__publicField(this, "metadata", null);
|
|
19768
|
+
__publicField(this, "activityIntervals", []);
|
|
19769
|
+
__publicField(this, "dimensions", null);
|
|
19770
|
+
__publicField(this, "lastCurrentTime", 0);
|
|
19771
|
+
__publicField(this, "ready", false);
|
|
19772
|
+
__publicField(this, "readyResolvers", []);
|
|
19773
|
+
__publicField(this, "disposed", false);
|
|
19774
|
+
/**
|
|
19775
|
+
* Commands issued before the host handshakes. A command posted while the
|
|
19776
|
+
* iframe is still on its initial `about:blank` (which carries the PARENT's
|
|
19777
|
+
* origin) is rejected by the browser as an origin mismatch and lost — the
|
|
19778
|
+
* viewer calls `setLayout` on mount, well before the host boots. Buffer until
|
|
19779
|
+
* `ready`, then flush; by then the frame is on the host origin.
|
|
19780
|
+
*/
|
|
19781
|
+
__publicField(this, "pending", []);
|
|
19782
|
+
__publicField(this, "onMessage", (event) => {
|
|
19783
|
+
if (event.source !== this.iframe.contentWindow) return;
|
|
19784
|
+
if (!isEnvelope(event.data)) return;
|
|
19785
|
+
this.handle(event.data.message);
|
|
19786
|
+
});
|
|
19787
|
+
this.iframe = iframe;
|
|
19788
|
+
this.hostOrigin = options.hostOrigin ?? "*";
|
|
19789
|
+
window.addEventListener("message", this.onMessage);
|
|
19790
|
+
this.probe();
|
|
19791
|
+
}
|
|
19792
|
+
/** Resolves once the host iframe has loaded and announced readiness. */
|
|
19793
|
+
whenReady() {
|
|
19794
|
+
if (this.ready) return Promise.resolve();
|
|
19795
|
+
return new Promise((resolve) => this.readyResolvers.push(resolve));
|
|
19796
|
+
}
|
|
19797
|
+
/* --- commands --------------------------------------------------------- */
|
|
19798
|
+
init(events, config, autoplay = false) {
|
|
19799
|
+
this.send({ type: "init", events, config, autoplay });
|
|
19800
|
+
}
|
|
19801
|
+
play(timeOffset) {
|
|
19802
|
+
this.send({ type: "play", timeOffset });
|
|
19803
|
+
}
|
|
19804
|
+
pause(timeOffset) {
|
|
19805
|
+
this.send({ type: "pause", timeOffset });
|
|
19806
|
+
}
|
|
19807
|
+
resume(timeOffset) {
|
|
19808
|
+
this.send({ type: "resume", timeOffset });
|
|
19809
|
+
}
|
|
19810
|
+
setConfig(config) {
|
|
19811
|
+
this.send({ type: "setConfig", config });
|
|
19812
|
+
}
|
|
19813
|
+
/**
|
|
19814
|
+
* Scale and position the replay. Compute `scale` from your own container size
|
|
19815
|
+
* and the recorded viewport, as you would when driving a local `Replayer`;
|
|
19816
|
+
* the host applies it, since the wrapper element is not reachable from here.
|
|
19817
|
+
* The layout is retained across re-inits.
|
|
19818
|
+
*/
|
|
19819
|
+
setLayout(scale, anchor) {
|
|
19820
|
+
this.send({ type: "setLayout", scale, anchor });
|
|
19821
|
+
}
|
|
19822
|
+
replaceEvents(events) {
|
|
19823
|
+
this.send({ type: "replaceEvents", events });
|
|
19824
|
+
}
|
|
19825
|
+
addEvent(event) {
|
|
19826
|
+
this.send({ type: "addEvent", event });
|
|
19827
|
+
}
|
|
19828
|
+
enableInteract() {
|
|
19829
|
+
this.send({ type: "enableInteract" });
|
|
19830
|
+
}
|
|
19831
|
+
disableInteract() {
|
|
19832
|
+
this.send({ type: "disableInteract" });
|
|
19833
|
+
}
|
|
19834
|
+
/** Tear down: destroys the host replayer and detaches the listener. */
|
|
19835
|
+
destroy() {
|
|
19836
|
+
if (this.disposed) return;
|
|
19837
|
+
this.disposed = true;
|
|
19838
|
+
try {
|
|
19839
|
+
this.send({ type: "destroy" });
|
|
19840
|
+
} finally {
|
|
19841
|
+
window.removeEventListener("message", this.onMessage);
|
|
19842
|
+
this.listeners.clear();
|
|
19843
|
+
}
|
|
19844
|
+
}
|
|
19845
|
+
/* --- event surface ---------------------------------------------------- */
|
|
19846
|
+
on(event, listener) {
|
|
19847
|
+
let set = this.listeners.get(event);
|
|
19848
|
+
if (!set) {
|
|
19849
|
+
set = /* @__PURE__ */ new Set();
|
|
19850
|
+
this.listeners.set(event, set);
|
|
19851
|
+
}
|
|
19852
|
+
set.add(listener);
|
|
19853
|
+
}
|
|
19854
|
+
off(event, listener) {
|
|
19855
|
+
var _a2;
|
|
19856
|
+
(_a2 = this.listeners.get(event)) == null ? void 0 : _a2.delete(listener);
|
|
19857
|
+
}
|
|
19858
|
+
/* --- getters ---------------------------------------------------------- */
|
|
19859
|
+
// Cached getters mirroring the local Replayer's synchronous ones. Metadata
|
|
19860
|
+
// and activity intervals arrive on `initialized` (re-sent on replaceEvents);
|
|
19861
|
+
// current time is streamed by the host while playing.
|
|
19862
|
+
/** Last-known current time (pushed by the host while playing). */
|
|
19863
|
+
getCurrentTime() {
|
|
19864
|
+
return this.lastCurrentTime;
|
|
19865
|
+
}
|
|
19866
|
+
getMetaData() {
|
|
19867
|
+
return this.metadata;
|
|
19868
|
+
}
|
|
19869
|
+
getActivityIntervals() {
|
|
19870
|
+
return this.activityIntervals;
|
|
19871
|
+
}
|
|
19872
|
+
/**
|
|
19873
|
+
* Rendered geometry of the replay, in the host document's coordinate space —
|
|
19874
|
+
* the cross-origin stand-in for `replayer.wrapper.getBoundingClientRect()`.
|
|
19875
|
+
* Null until the host has reported it (listen for `'dimensions'`).
|
|
19876
|
+
*/
|
|
19877
|
+
getDimensions() {
|
|
19878
|
+
return this.dimensions;
|
|
19879
|
+
}
|
|
19880
|
+
/* --- internals -------------------------------------------------------- */
|
|
19881
|
+
send(command) {
|
|
19882
|
+
if (!this.ready) {
|
|
19883
|
+
this.pending.push(command);
|
|
19884
|
+
return;
|
|
19885
|
+
}
|
|
19886
|
+
this.postToHost(command);
|
|
19887
|
+
}
|
|
19888
|
+
postToHost(command) {
|
|
19889
|
+
const target = this.iframe.contentWindow;
|
|
19890
|
+
if (!target) return;
|
|
19891
|
+
target.postMessage(wrap(command), this.hostOrigin);
|
|
19892
|
+
}
|
|
19893
|
+
flushPending() {
|
|
19894
|
+
const queued = this.pending;
|
|
19895
|
+
this.pending = [];
|
|
19896
|
+
queued.forEach((command) => this.postToHost(command));
|
|
19897
|
+
}
|
|
19898
|
+
/** Data-free handshake probe; see the note in the constructor. */
|
|
19899
|
+
probe() {
|
|
19900
|
+
var _a2;
|
|
19901
|
+
(_a2 = this.iframe.contentWindow) == null ? void 0 : _a2.postMessage(wrap({ type: "ping" }), "*");
|
|
19902
|
+
}
|
|
19903
|
+
handle(message) {
|
|
19904
|
+
switch (message.type) {
|
|
19905
|
+
case "ready":
|
|
19906
|
+
this.ready = true;
|
|
19907
|
+
this.flushPending();
|
|
19908
|
+
this.readyResolvers.forEach((r2) => r2());
|
|
19909
|
+
this.readyResolvers = [];
|
|
19910
|
+
return;
|
|
19911
|
+
case "initialized":
|
|
19912
|
+
this.metadata = message.metadata;
|
|
19913
|
+
this.activityIntervals = message.activityIntervals;
|
|
19914
|
+
this.emit("initialized", message.metadata);
|
|
19915
|
+
return;
|
|
19916
|
+
case "replayer-event":
|
|
19917
|
+
this.emit(message.event, message.payload);
|
|
19918
|
+
return;
|
|
19919
|
+
case "time":
|
|
19920
|
+
this.lastCurrentTime = message.currentTime;
|
|
19921
|
+
this.emit("time", message.currentTime);
|
|
19922
|
+
return;
|
|
19923
|
+
case "dimensions":
|
|
19924
|
+
this.dimensions = {
|
|
19925
|
+
width: message.width,
|
|
19926
|
+
height: message.height,
|
|
19927
|
+
top: message.top,
|
|
19928
|
+
left: message.left
|
|
19929
|
+
};
|
|
19930
|
+
this.emit("dimensions", this.dimensions);
|
|
19931
|
+
return;
|
|
19932
|
+
case "error":
|
|
19933
|
+
this.emit("error", message.message);
|
|
19934
|
+
return;
|
|
19935
|
+
}
|
|
19936
|
+
}
|
|
19937
|
+
emit(event, payload) {
|
|
19938
|
+
var _a2;
|
|
19939
|
+
(_a2 = this.listeners.get(event)) == null ? void 0 : _a2.forEach((listener) => listener(payload));
|
|
19940
|
+
}
|
|
19941
|
+
}
|
|
19942
|
+
function originOf(url) {
|
|
19943
|
+
try {
|
|
19944
|
+
return new URL(url).origin;
|
|
19945
|
+
} catch {
|
|
19946
|
+
return "'self'";
|
|
19947
|
+
}
|
|
19948
|
+
}
|
|
19949
|
+
function buildHostDocument(options) {
|
|
19950
|
+
const scriptOrigin = originOf(options.scriptUrl);
|
|
19951
|
+
const styleSources = [
|
|
19952
|
+
"'unsafe-inline'",
|
|
19953
|
+
scriptOrigin,
|
|
19954
|
+
...options.extraStyleSources ?? []
|
|
19955
|
+
].join(" ");
|
|
19956
|
+
const csp = [
|
|
19957
|
+
`default-src 'none'`,
|
|
19958
|
+
`script-src ${scriptOrigin}`,
|
|
19959
|
+
`style-src ${styleSources}`,
|
|
19960
|
+
`img-src * data: blob:`,
|
|
19961
|
+
`font-src * data:`,
|
|
19962
|
+
`media-src * data: blob:`,
|
|
19963
|
+
`frame-src *`,
|
|
19964
|
+
`connect-src 'none'`,
|
|
19965
|
+
`worker-src 'none'`
|
|
19966
|
+
].join("; ");
|
|
19967
|
+
const styleTag = options.styleUrl ? `<link rel="stylesheet" href="${escapeAttr(options.styleUrl)}">` : "";
|
|
19968
|
+
return `<!DOCTYPE html>
|
|
19969
|
+
<html>
|
|
19970
|
+
<head>
|
|
19971
|
+
<meta charset="utf-8">
|
|
19972
|
+
<meta http-equiv="Content-Security-Policy" content="${escapeAttr(csp)}">
|
|
19973
|
+
<style>html,body{margin:0;padding:0;height:100%;overflow:hidden;background:transparent}</style>
|
|
19974
|
+
${styleTag}
|
|
19975
|
+
<script type="module" src="${escapeAttr(options.scriptUrl)}"><\/script>
|
|
19976
|
+
</head>
|
|
19977
|
+
<body></body>
|
|
19978
|
+
</html>`;
|
|
19979
|
+
}
|
|
19980
|
+
function escapeAttr(value) {
|
|
19981
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
19982
|
+
}
|
|
19150
19983
|
const { addCustomEvent } = record;
|
|
19151
19984
|
const { freezePage } = record;
|
|
19152
19985
|
const { takeFullSnapshot } = record;
|
|
19153
19986
|
export {
|
|
19987
|
+
EmbeddedReplayerClient,
|
|
19988
|
+
EmbeddedReplayerHost,
|
|
19154
19989
|
EventType,
|
|
19155
19990
|
IncrementalSource,
|
|
19156
19991
|
MouseInteractions,
|
|
19992
|
+
RRWEB_EMBEDDED_CHANNEL,
|
|
19993
|
+
RRWEB_EMBEDDED_PROTOCOL_VERSION,
|
|
19157
19994
|
Replayer,
|
|
19158
19995
|
ReplayerEvents,
|
|
19159
19996
|
addCustomEvent,
|
|
19997
|
+
buildHostDocument,
|
|
19160
19998
|
canvasMutation,
|
|
19161
19999
|
freezePage,
|
|
19162
20000
|
_mirror as mirror,
|
|
20001
|
+
pickSerializableConfig,
|
|
19163
20002
|
record,
|
|
20003
|
+
startEmbeddedReplayerHost,
|
|
19164
20004
|
takeFullSnapshot,
|
|
19165
20005
|
utils
|
|
19166
20006
|
};
|