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