@highlight-run/rrweb 2.0.0-lambda.7 → 2.0.0-lambda.8
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 +590 -34
- package/dist/rrweb.cjs.map +1 -1
- package/dist/rrweb.d.cts +175 -0
- package/dist/rrweb.d.ts +175 -0
- package/dist/rrweb.js +590 -34
- package/dist/rrweb.js.map +1 -1
- package/dist/rrweb.umd.cjs +582 -34
- package/dist/rrweb.umd.cjs.map +4 -4
- package/dist/rrweb.umd.min.cjs +55 -45
- package/dist/rrweb.umd.min.cjs.map +4 -4
- package/package.json +5 -5
- package/umd/rrweb.js +582 -34
- package/umd/rrweb.min.js +55 -45
package/dist/rrweb.umd.cjs
CHANGED
|
@@ -1909,6 +1909,7 @@ function requireStringifier$1() {
|
|
|
1909
1909
|
hasRequiredStringifier$1 = 1;
|
|
1910
1910
|
const STYLE_TAG = /(<)(\/?style\b)/gi;
|
|
1911
1911
|
const COMMENT_OPEN = /(<)(!--)/g;
|
|
1912
|
+
const AT_NAME_END = /[\t\n\f\r "#'()/;[\\\]{}]/;
|
|
1912
1913
|
function escapeHTMLInCSS(str) {
|
|
1913
1914
|
if (typeof str !== "string") return str;
|
|
1914
1915
|
if (!str.includes("<")) return str;
|
|
@@ -1934,12 +1935,13 @@ function requireStringifier$1() {
|
|
|
1934
1935
|
function atruleStart(str, node2) {
|
|
1935
1936
|
let name = "@" + node2.name;
|
|
1936
1937
|
let params = node2.params ? str.rawValue(node2, "params") : "";
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1938
|
+
let afterName = node2.raws.afterName;
|
|
1939
|
+
if (typeof afterName === "undefined") {
|
|
1940
|
+
afterName = params ? " " : "";
|
|
1941
|
+
} else if (afterName === "" && params && !AT_NAME_END.test(params[0])) {
|
|
1942
|
+
afterName = " ";
|
|
1941
1943
|
}
|
|
1942
|
-
return name + params;
|
|
1944
|
+
return name + afterName + params;
|
|
1943
1945
|
}
|
|
1944
1946
|
function pushBody(str, stack, node2) {
|
|
1945
1947
|
let nodes = node2.nodes;
|
|
@@ -1951,10 +1953,15 @@ function requireStringifier$1() {
|
|
|
1951
1953
|
let semicolon = str.raw(node2, "semicolon");
|
|
1952
1954
|
let isDocument = node2.type === "document";
|
|
1953
1955
|
for (let i2 = nodes.length - 1; i2 >= 0; i2--) {
|
|
1956
|
+
let child = nodes[i2];
|
|
1957
|
+
let childSemicolon = last !== i2 || semicolon;
|
|
1958
|
+
if (!childSemicolon && i2 < nodes.length - 1 && (child.type === "atrule" && !child.nodes || child.type === "decl" && child.prop.startsWith("--"))) {
|
|
1959
|
+
childSemicolon = true;
|
|
1960
|
+
}
|
|
1954
1961
|
stack.push({
|
|
1955
1962
|
document: isDocument,
|
|
1956
|
-
node:
|
|
1957
|
-
semicolon:
|
|
1963
|
+
node: child,
|
|
1964
|
+
semicolon: childSemicolon
|
|
1958
1965
|
});
|
|
1959
1966
|
}
|
|
1960
1967
|
}
|
|
@@ -2245,6 +2252,9 @@ function requireStringifier$1() {
|
|
|
2245
2252
|
return value;
|
|
2246
2253
|
}
|
|
2247
2254
|
root(node2) {
|
|
2255
|
+
if (node2.source && node2.source.input.hasBOM) {
|
|
2256
|
+
this.builder("\uFEFF", node2, "start");
|
|
2257
|
+
}
|
|
2248
2258
|
this.body(node2);
|
|
2249
2259
|
if (node2.raws.after) {
|
|
2250
2260
|
let after = node2.raws.after;
|
|
@@ -3317,15 +3327,12 @@ function requirePreviousMap$1() {
|
|
|
3317
3327
|
}
|
|
3318
3328
|
loadFile(path, cssFile, trusted) {
|
|
3319
3329
|
if (!trusted && !this.unsafeMap) {
|
|
3320
|
-
if (!/\.map$/i.test(path))
|
|
3330
|
+
if (!/\.map$/i.test(path)) return void 0;
|
|
3331
|
+
if (!cssFile) return void 0;
|
|
3332
|
+
let rel = relative(dirname(cssFile), path);
|
|
3333
|
+
if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) {
|
|
3321
3334
|
return void 0;
|
|
3322
3335
|
}
|
|
3323
|
-
if (cssFile) {
|
|
3324
|
-
let relativePath = relative(dirname(cssFile), path);
|
|
3325
|
-
if (relativePath === ".." || relativePath.startsWith(".." + sep) || isAbsolute(relativePath)) {
|
|
3326
|
-
return void 0;
|
|
3327
|
-
}
|
|
3328
|
-
}
|
|
3329
3336
|
}
|
|
3330
3337
|
this.root = dirname(path);
|
|
3331
3338
|
if (existsSync(path)) {
|
|
@@ -3697,6 +3704,7 @@ function requireList$1() {
|
|
|
3697
3704
|
return list.split(string, spaces);
|
|
3698
3705
|
},
|
|
3699
3706
|
split(string, separators, last) {
|
|
3707
|
+
if (!string) return [];
|
|
3700
3708
|
let array = [];
|
|
3701
3709
|
let current = "";
|
|
3702
3710
|
let split = false;
|
|
@@ -4982,11 +4990,16 @@ var hasRequiredWarning$1;
|
|
|
4982
4990
|
function requireWarning$1() {
|
|
4983
4991
|
if (hasRequiredWarning$1) return warning$1;
|
|
4984
4992
|
hasRequiredWarning$1 = 1;
|
|
4993
|
+
let Container = requireContainer$1();
|
|
4994
|
+
let { my } = requireSymbols$1();
|
|
4985
4995
|
class Warning {
|
|
4986
4996
|
constructor(text, opts = {}) {
|
|
4987
4997
|
this.type = "warning";
|
|
4988
4998
|
this.text = text;
|
|
4989
4999
|
if (opts.node && opts.node.source) {
|
|
5000
|
+
if (!opts.node[my]) {
|
|
5001
|
+
Container.rebuild(opts.node);
|
|
5002
|
+
}
|
|
4990
5003
|
let range = opts.node.rangeBy(opts);
|
|
4991
5004
|
this.line = range.start.line;
|
|
4992
5005
|
this.column = range.start.column;
|
|
@@ -5496,14 +5509,19 @@ function requireLazyResult$1() {
|
|
|
5496
5509
|
}
|
|
5497
5510
|
if (visit2.iterator !== 0) {
|
|
5498
5511
|
let iterator = visit2.iterator;
|
|
5512
|
+
if (visit2.descending) {
|
|
5513
|
+
visit2.descending = false;
|
|
5514
|
+
node2.indexes[iterator] += 1;
|
|
5515
|
+
}
|
|
5499
5516
|
let child;
|
|
5500
5517
|
while (child = node2.nodes[node2.indexes[iterator]]) {
|
|
5501
|
-
node2.indexes[iterator] += 1;
|
|
5502
5518
|
if (!child[isClean]) {
|
|
5503
5519
|
child[isClean] = true;
|
|
5520
|
+
visit2.descending = true;
|
|
5504
5521
|
stack.push(toStack(child));
|
|
5505
5522
|
return;
|
|
5506
5523
|
}
|
|
5524
|
+
node2.indexes[iterator] += 1;
|
|
5507
5525
|
}
|
|
5508
5526
|
visit2.iterator = 0;
|
|
5509
5527
|
delete node2.indexes[iterator];
|
|
@@ -5533,12 +5551,16 @@ function requireLazyResult$1() {
|
|
|
5533
5551
|
let visitNode = visit2.node;
|
|
5534
5552
|
if (visit2.iterator !== 0) {
|
|
5535
5553
|
let iterator = visit2.iterator;
|
|
5554
|
+
if (visit2.descending) {
|
|
5555
|
+
visit2.descending = false;
|
|
5556
|
+
visitNode.indexes[iterator] += 1;
|
|
5557
|
+
}
|
|
5536
5558
|
let child;
|
|
5537
5559
|
let descended = false;
|
|
5538
5560
|
while (child = visitNode.nodes[visitNode.indexes[iterator]]) {
|
|
5539
|
-
visitNode.indexes[iterator] += 1;
|
|
5540
5561
|
if (!child[isClean]) {
|
|
5541
5562
|
child[isClean] = true;
|
|
5563
|
+
visit2.descending = true;
|
|
5542
5564
|
stack.push({
|
|
5543
5565
|
eventIndex: 0,
|
|
5544
5566
|
events: getEvents(child),
|
|
@@ -5548,6 +5570,7 @@ function requireLazyResult$1() {
|
|
|
5548
5570
|
descended = true;
|
|
5549
5571
|
break;
|
|
5550
5572
|
}
|
|
5573
|
+
visitNode.indexes[iterator] += 1;
|
|
5551
5574
|
}
|
|
5552
5575
|
if (descended) continue;
|
|
5553
5576
|
visit2.iterator = 0;
|
|
@@ -5710,7 +5733,7 @@ function requireProcessor$1() {
|
|
|
5710
5733
|
let Root = requireRoot$1();
|
|
5711
5734
|
class Processor {
|
|
5712
5735
|
constructor(plugins = []) {
|
|
5713
|
-
this.version = "8.5.
|
|
5736
|
+
this.version = "8.5.25";
|
|
5714
5737
|
this.plugins = this.normalize(plugins);
|
|
5715
5738
|
}
|
|
5716
5739
|
normalize(plugins) {
|
|
@@ -6577,6 +6600,7 @@ function requireStringifier() {
|
|
|
6577
6600
|
hasRequiredStringifier = 1;
|
|
6578
6601
|
const STYLE_TAG = /(<)(\/?style\b)/gi;
|
|
6579
6602
|
const COMMENT_OPEN = /(<)(!--)/g;
|
|
6603
|
+
const AT_NAME_END = /[\t\n\f\r "#'()/;[\\\]{}]/;
|
|
6580
6604
|
function escapeHTMLInCSS(str) {
|
|
6581
6605
|
if (typeof str !== "string") return str;
|
|
6582
6606
|
if (!str.includes("<")) return str;
|
|
@@ -6602,12 +6626,13 @@ function requireStringifier() {
|
|
|
6602
6626
|
function atruleStart(str, node2) {
|
|
6603
6627
|
let name = "@" + node2.name;
|
|
6604
6628
|
let params = node2.params ? str.rawValue(node2, "params") : "";
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6629
|
+
let afterName = node2.raws.afterName;
|
|
6630
|
+
if (typeof afterName === "undefined") {
|
|
6631
|
+
afterName = params ? " " : "";
|
|
6632
|
+
} else if (afterName === "" && params && !AT_NAME_END.test(params[0])) {
|
|
6633
|
+
afterName = " ";
|
|
6609
6634
|
}
|
|
6610
|
-
return name + params;
|
|
6635
|
+
return name + afterName + params;
|
|
6611
6636
|
}
|
|
6612
6637
|
function pushBody(str, stack, node2) {
|
|
6613
6638
|
let nodes = node2.nodes;
|
|
@@ -6619,10 +6644,15 @@ function requireStringifier() {
|
|
|
6619
6644
|
let semicolon = str.raw(node2, "semicolon");
|
|
6620
6645
|
let isDocument = node2.type === "document";
|
|
6621
6646
|
for (let i2 = nodes.length - 1; i2 >= 0; i2--) {
|
|
6647
|
+
let child = nodes[i2];
|
|
6648
|
+
let childSemicolon = last !== i2 || semicolon;
|
|
6649
|
+
if (!childSemicolon && i2 < nodes.length - 1 && (child.type === "atrule" && !child.nodes || child.type === "decl" && child.prop.startsWith("--"))) {
|
|
6650
|
+
childSemicolon = true;
|
|
6651
|
+
}
|
|
6622
6652
|
stack.push({
|
|
6623
6653
|
document: isDocument,
|
|
6624
|
-
node:
|
|
6625
|
-
semicolon:
|
|
6654
|
+
node: child,
|
|
6655
|
+
semicolon: childSemicolon
|
|
6626
6656
|
});
|
|
6627
6657
|
}
|
|
6628
6658
|
}
|
|
@@ -6913,6 +6943,9 @@ function requireStringifier() {
|
|
|
6913
6943
|
return value;
|
|
6914
6944
|
}
|
|
6915
6945
|
root(node2) {
|
|
6946
|
+
if (node2.source && node2.source.input.hasBOM) {
|
|
6947
|
+
this.builder("\uFEFF", node2, "start");
|
|
6948
|
+
}
|
|
6916
6949
|
this.body(node2);
|
|
6917
6950
|
if (node2.raws.after) {
|
|
6918
6951
|
let after = node2.raws.after;
|
|
@@ -7985,15 +8018,12 @@ function requirePreviousMap() {
|
|
|
7985
8018
|
}
|
|
7986
8019
|
loadFile(path, cssFile, trusted) {
|
|
7987
8020
|
if (!trusted && !this.unsafeMap) {
|
|
7988
|
-
if (!/\.map$/i.test(path))
|
|
8021
|
+
if (!/\.map$/i.test(path)) return void 0;
|
|
8022
|
+
if (!cssFile) return void 0;
|
|
8023
|
+
let rel = relative(dirname(cssFile), path);
|
|
8024
|
+
if (rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) {
|
|
7989
8025
|
return void 0;
|
|
7990
8026
|
}
|
|
7991
|
-
if (cssFile) {
|
|
7992
|
-
let relativePath = relative(dirname(cssFile), path);
|
|
7993
|
-
if (relativePath === ".." || relativePath.startsWith(".." + sep) || isAbsolute(relativePath)) {
|
|
7994
|
-
return void 0;
|
|
7995
|
-
}
|
|
7996
|
-
}
|
|
7997
8027
|
}
|
|
7998
8028
|
this.root = dirname(path);
|
|
7999
8029
|
if (existsSync(path)) {
|
|
@@ -8365,6 +8395,7 @@ function requireList() {
|
|
|
8365
8395
|
return list.split(string, spaces);
|
|
8366
8396
|
},
|
|
8367
8397
|
split(string, separators, last) {
|
|
8398
|
+
if (!string) return [];
|
|
8368
8399
|
let array = [];
|
|
8369
8400
|
let current = "";
|
|
8370
8401
|
let split = false;
|
|
@@ -9650,11 +9681,16 @@ var hasRequiredWarning;
|
|
|
9650
9681
|
function requireWarning() {
|
|
9651
9682
|
if (hasRequiredWarning) return warning;
|
|
9652
9683
|
hasRequiredWarning = 1;
|
|
9684
|
+
let Container = requireContainer();
|
|
9685
|
+
let { my } = requireSymbols();
|
|
9653
9686
|
class Warning {
|
|
9654
9687
|
constructor(text, opts = {}) {
|
|
9655
9688
|
this.type = "warning";
|
|
9656
9689
|
this.text = text;
|
|
9657
9690
|
if (opts.node && opts.node.source) {
|
|
9691
|
+
if (!opts.node[my]) {
|
|
9692
|
+
Container.rebuild(opts.node);
|
|
9693
|
+
}
|
|
9658
9694
|
let range = opts.node.rangeBy(opts);
|
|
9659
9695
|
this.line = range.start.line;
|
|
9660
9696
|
this.column = range.start.column;
|
|
@@ -10164,14 +10200,19 @@ function requireLazyResult() {
|
|
|
10164
10200
|
}
|
|
10165
10201
|
if (visit2.iterator !== 0) {
|
|
10166
10202
|
let iterator = visit2.iterator;
|
|
10203
|
+
if (visit2.descending) {
|
|
10204
|
+
visit2.descending = false;
|
|
10205
|
+
node2.indexes[iterator] += 1;
|
|
10206
|
+
}
|
|
10167
10207
|
let child;
|
|
10168
10208
|
while (child = node2.nodes[node2.indexes[iterator]]) {
|
|
10169
|
-
node2.indexes[iterator] += 1;
|
|
10170
10209
|
if (!child[isClean]) {
|
|
10171
10210
|
child[isClean] = true;
|
|
10211
|
+
visit2.descending = true;
|
|
10172
10212
|
stack.push(toStack(child));
|
|
10173
10213
|
return;
|
|
10174
10214
|
}
|
|
10215
|
+
node2.indexes[iterator] += 1;
|
|
10175
10216
|
}
|
|
10176
10217
|
visit2.iterator = 0;
|
|
10177
10218
|
delete node2.indexes[iterator];
|
|
@@ -10201,12 +10242,16 @@ function requireLazyResult() {
|
|
|
10201
10242
|
let visitNode = visit2.node;
|
|
10202
10243
|
if (visit2.iterator !== 0) {
|
|
10203
10244
|
let iterator = visit2.iterator;
|
|
10245
|
+
if (visit2.descending) {
|
|
10246
|
+
visit2.descending = false;
|
|
10247
|
+
visitNode.indexes[iterator] += 1;
|
|
10248
|
+
}
|
|
10204
10249
|
let child;
|
|
10205
10250
|
let descended = false;
|
|
10206
10251
|
while (child = visitNode.nodes[visitNode.indexes[iterator]]) {
|
|
10207
|
-
visitNode.indexes[iterator] += 1;
|
|
10208
10252
|
if (!child[isClean]) {
|
|
10209
10253
|
child[isClean] = true;
|
|
10254
|
+
visit2.descending = true;
|
|
10210
10255
|
stack.push({
|
|
10211
10256
|
eventIndex: 0,
|
|
10212
10257
|
events: getEvents(child),
|
|
@@ -10216,6 +10261,7 @@ function requireLazyResult() {
|
|
|
10216
10261
|
descended = true;
|
|
10217
10262
|
break;
|
|
10218
10263
|
}
|
|
10264
|
+
visitNode.indexes[iterator] += 1;
|
|
10219
10265
|
}
|
|
10220
10266
|
if (descended) continue;
|
|
10221
10267
|
visit2.iterator = 0;
|
|
@@ -10378,7 +10424,7 @@ function requireProcessor() {
|
|
|
10378
10424
|
let Root = requireRoot();
|
|
10379
10425
|
class Processor {
|
|
10380
10426
|
constructor(plugins = []) {
|
|
10381
|
-
this.version = "8.5.
|
|
10427
|
+
this.version = "8.5.25";
|
|
10382
10428
|
this.plugins = this.normalize(plugins);
|
|
10383
10429
|
}
|
|
10384
10430
|
normalize(plugins) {
|
|
@@ -19128,18 +19174,520 @@ class Replayer {
|
|
|
19128
19174
|
this.config.logger.log(REPLAY_CONSOLE_PREFIX, ...args);
|
|
19129
19175
|
}
|
|
19130
19176
|
}
|
|
19177
|
+
const RRWEB_EMBEDDED_CHANNEL = "rrweb-embedded";
|
|
19178
|
+
const RRWEB_EMBEDDED_PROTOCOL_VERSION = 1;
|
|
19179
|
+
const SERIALIZABLE_CONFIG_KEYS = [
|
|
19180
|
+
"speed",
|
|
19181
|
+
"maxSpeed",
|
|
19182
|
+
"loadTimeout",
|
|
19183
|
+
"skipInactive",
|
|
19184
|
+
"inactivePeriodThreshold",
|
|
19185
|
+
"showWarning",
|
|
19186
|
+
"showDebug",
|
|
19187
|
+
"blockClass",
|
|
19188
|
+
"liveMode",
|
|
19189
|
+
"insertStyleRules",
|
|
19190
|
+
"triggerFocus",
|
|
19191
|
+
"UNSAFE_replayCanvas",
|
|
19192
|
+
"cspContent",
|
|
19193
|
+
"pauseAnimation",
|
|
19194
|
+
"mouseTail",
|
|
19195
|
+
"useVirtualDom",
|
|
19196
|
+
"inactiveThreshold",
|
|
19197
|
+
"inactiveSkipTime"
|
|
19198
|
+
];
|
|
19199
|
+
function pickSerializableConfig(config) {
|
|
19200
|
+
const out = {};
|
|
19201
|
+
if (config && typeof config === "object") {
|
|
19202
|
+
for (const key of SERIALIZABLE_CONFIG_KEYS) {
|
|
19203
|
+
const value = config[key];
|
|
19204
|
+
if (value !== void 0 && typeof value !== "function") {
|
|
19205
|
+
out[key] = value;
|
|
19206
|
+
}
|
|
19207
|
+
}
|
|
19208
|
+
}
|
|
19209
|
+
return out;
|
|
19210
|
+
}
|
|
19211
|
+
function wrap(message) {
|
|
19212
|
+
return {
|
|
19213
|
+
channel: RRWEB_EMBEDDED_CHANNEL,
|
|
19214
|
+
version: RRWEB_EMBEDDED_PROTOCOL_VERSION,
|
|
19215
|
+
message
|
|
19216
|
+
};
|
|
19217
|
+
}
|
|
19218
|
+
function isEnvelope(data) {
|
|
19219
|
+
if (!data || typeof data !== "object") return false;
|
|
19220
|
+
const e2 = data;
|
|
19221
|
+
return e2.channel === RRWEB_EMBEDDED_CHANNEL && e2.version === RRWEB_EMBEDDED_PROTOCOL_VERSION && !!e2.message && typeof e2.message === "object" && typeof e2.message.type === "string";
|
|
19222
|
+
}
|
|
19223
|
+
const PAYLOAD_EVENTS = /* @__PURE__ */ new Set([
|
|
19224
|
+
ReplayerEvents.Resize,
|
|
19225
|
+
ReplayerEvents.EventCast,
|
|
19226
|
+
ReplayerEvents.CustomEvent
|
|
19227
|
+
]);
|
|
19228
|
+
class EmbeddedReplayerHost {
|
|
19229
|
+
constructor(options = {}) {
|
|
19230
|
+
var _a2, _b, _c, _d, _e;
|
|
19231
|
+
__publicField(this, "root");
|
|
19232
|
+
__publicField(this, "parentWindow");
|
|
19233
|
+
__publicField(this, "timeUpdateIntervalMs");
|
|
19234
|
+
__publicField(this, "expectedParentOrigin");
|
|
19235
|
+
__publicField(this, "replayer", null);
|
|
19236
|
+
__publicField(this, "playing", false);
|
|
19237
|
+
__publicField(this, "timer", null);
|
|
19238
|
+
__publicField(this, "started", false);
|
|
19239
|
+
__publicField(this, "layout", null);
|
|
19240
|
+
__publicField(this, "onMessage", (event) => {
|
|
19241
|
+
if (event.source !== this.parentWindow) return;
|
|
19242
|
+
if (this.expectedParentOrigin === null) return;
|
|
19243
|
+
if (event.origin !== this.expectedParentOrigin) return;
|
|
19244
|
+
if (!isEnvelope(event.data)) return;
|
|
19245
|
+
try {
|
|
19246
|
+
this.handle(event.data.message);
|
|
19247
|
+
} catch (err) {
|
|
19248
|
+
this.post({
|
|
19249
|
+
type: "error",
|
|
19250
|
+
message: err instanceof Error ? err.message : String(err)
|
|
19251
|
+
});
|
|
19252
|
+
}
|
|
19253
|
+
});
|
|
19254
|
+
this.root = (_a2 = options.root) != null ? _a2 : document.body;
|
|
19255
|
+
this.parentWindow = (_b = options.parentWindow) != null ? _b : window.parent;
|
|
19256
|
+
this.timeUpdateIntervalMs = (_c = options.timeUpdateIntervalMs) != null ? _c : 50;
|
|
19257
|
+
this.expectedParentOrigin = (_e = (_d = options.expectedParentOrigin) != null ? _d : new URLSearchParams(location.search).get("parentOrigin")) != null ? _e : null;
|
|
19258
|
+
}
|
|
19259
|
+
/** Install the message listener and announce readiness to the parent. */
|
|
19260
|
+
start() {
|
|
19261
|
+
if (this.started) return;
|
|
19262
|
+
this.started = true;
|
|
19263
|
+
if (this.expectedParentOrigin === null) {
|
|
19264
|
+
console.warn(
|
|
19265
|
+
"[rrweb-embedded] no parentOrigin configured; all incoming messages will be ignored"
|
|
19266
|
+
);
|
|
19267
|
+
}
|
|
19268
|
+
window.addEventListener("message", this.onMessage);
|
|
19269
|
+
this.post({ type: "ready" });
|
|
19270
|
+
}
|
|
19271
|
+
/** Tear everything down (also invoked on a `destroy` command). */
|
|
19272
|
+
stop() {
|
|
19273
|
+
var _a2;
|
|
19274
|
+
window.removeEventListener("message", this.onMessage);
|
|
19275
|
+
this.setPlaying(false);
|
|
19276
|
+
(_a2 = this.replayer) == null ? void 0 : _a2.destroy();
|
|
19277
|
+
this.replayer = null;
|
|
19278
|
+
this.started = false;
|
|
19279
|
+
}
|
|
19280
|
+
handle(command) {
|
|
19281
|
+
var _a3, _b2, _c2;
|
|
19282
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
19283
|
+
switch (command.type) {
|
|
19284
|
+
case "ping":
|
|
19285
|
+
this.post({ type: "ready" });
|
|
19286
|
+
return;
|
|
19287
|
+
case "init":
|
|
19288
|
+
this.init(command.events, command.config, command.autoplay);
|
|
19289
|
+
return;
|
|
19290
|
+
case "play":
|
|
19291
|
+
(_a2 = this.replayer) == null ? void 0 : _a2.play((_a3 = command.timeOffset) != null ? _a3 : 0);
|
|
19292
|
+
this.setPlaying(true);
|
|
19293
|
+
return;
|
|
19294
|
+
case "pause":
|
|
19295
|
+
(_b = this.replayer) == null ? void 0 : _b.pause(command.timeOffset);
|
|
19296
|
+
this.setPlaying(false);
|
|
19297
|
+
this.postTime();
|
|
19298
|
+
return;
|
|
19299
|
+
case "resume":
|
|
19300
|
+
(_c = this.replayer) == null ? void 0 : _c.resume((_b2 = command.timeOffset) != null ? _b2 : 0);
|
|
19301
|
+
this.setPlaying(true);
|
|
19302
|
+
return;
|
|
19303
|
+
case "setLayout":
|
|
19304
|
+
this.layout = {
|
|
19305
|
+
scale: command.scale,
|
|
19306
|
+
anchor: (_c2 = command.anchor) != null ? _c2 : "center"
|
|
19307
|
+
};
|
|
19308
|
+
this.applyLayout();
|
|
19309
|
+
this.postDimensions();
|
|
19310
|
+
return;
|
|
19311
|
+
case "setConfig":
|
|
19312
|
+
(_d = this.replayer) == null ? void 0 : _d.setConfig(pickSerializableConfig(command.config));
|
|
19313
|
+
return;
|
|
19314
|
+
case "replaceEvents":
|
|
19315
|
+
if (this.replayer) {
|
|
19316
|
+
this.replayer.replaceEvents(command.events);
|
|
19317
|
+
this.postInitialized();
|
|
19318
|
+
}
|
|
19319
|
+
return;
|
|
19320
|
+
case "addEvent":
|
|
19321
|
+
(_e = this.replayer) == null ? void 0 : _e.addEvent(command.event);
|
|
19322
|
+
return;
|
|
19323
|
+
case "enableInteract":
|
|
19324
|
+
(_f = this.replayer) == null ? void 0 : _f.enableInteract();
|
|
19325
|
+
return;
|
|
19326
|
+
case "disableInteract":
|
|
19327
|
+
(_g = this.replayer) == null ? void 0 : _g.disableInteract();
|
|
19328
|
+
return;
|
|
19329
|
+
case "destroy":
|
|
19330
|
+
this.stop();
|
|
19331
|
+
return;
|
|
19332
|
+
}
|
|
19333
|
+
}
|
|
19334
|
+
init(events, config, autoplay) {
|
|
19335
|
+
if (this.replayer) {
|
|
19336
|
+
this.setPlaying(false);
|
|
19337
|
+
this.replayer.destroy();
|
|
19338
|
+
}
|
|
19339
|
+
const replayerConfig = __spreadProps(__spreadValues({}, pickSerializableConfig(config)), {
|
|
19340
|
+
root: this.root
|
|
19341
|
+
});
|
|
19342
|
+
this.replayer = new Replayer(events, replayerConfig);
|
|
19343
|
+
this.wireEvents(this.replayer);
|
|
19344
|
+
this.applyLayout();
|
|
19345
|
+
this.postInitialized();
|
|
19346
|
+
this.postDimensions();
|
|
19347
|
+
if (autoplay) {
|
|
19348
|
+
this.replayer.play(0);
|
|
19349
|
+
this.setPlaying(true);
|
|
19350
|
+
}
|
|
19351
|
+
}
|
|
19352
|
+
/**
|
|
19353
|
+
* Translate the parent's layout intent into styles on the replay wrapper.
|
|
19354
|
+
*
|
|
19355
|
+
* Mirrors what an embedder would otherwise apply from its own stylesheet:
|
|
19356
|
+
* `transform-origin: top left` with `left: 50%` to center horizontally, and
|
|
19357
|
+
* either `top: 50%` + a -50% Y translate to center vertically, or `top: 0`
|
|
19358
|
+
* with no Y translate to anchor at the top edge.
|
|
19359
|
+
*/
|
|
19360
|
+
applyLayout() {
|
|
19361
|
+
var _a2;
|
|
19362
|
+
const wrapper = (_a2 = this.replayer) == null ? void 0 : _a2.wrapper;
|
|
19363
|
+
if (!wrapper || !this.layout) return;
|
|
19364
|
+
const { scale, anchor } = this.layout;
|
|
19365
|
+
const top = anchor === "top";
|
|
19366
|
+
wrapper.style.position = "absolute";
|
|
19367
|
+
wrapper.style.transformOrigin = "top left";
|
|
19368
|
+
wrapper.style.left = "50%";
|
|
19369
|
+
wrapper.style.top = top ? "0" : "50%";
|
|
19370
|
+
wrapper.style.transform = top ? `scale(${scale}) translate(-50%, 0)` : `scale(${scale}) translate(-50%, -50%)`;
|
|
19371
|
+
}
|
|
19372
|
+
/** Report the wrapper's rendered geometry; the parent cannot measure it. */
|
|
19373
|
+
postDimensions() {
|
|
19374
|
+
var _a2;
|
|
19375
|
+
const wrapper = (_a2 = this.replayer) == null ? void 0 : _a2.wrapper;
|
|
19376
|
+
if (!wrapper) return;
|
|
19377
|
+
const rect = wrapper.getBoundingClientRect();
|
|
19378
|
+
this.post({
|
|
19379
|
+
type: "dimensions",
|
|
19380
|
+
width: rect.width,
|
|
19381
|
+
height: rect.height,
|
|
19382
|
+
top: rect.top,
|
|
19383
|
+
left: rect.left
|
|
19384
|
+
});
|
|
19385
|
+
}
|
|
19386
|
+
/** Push the stable getters (metadata, activity intervals) to the parent. */
|
|
19387
|
+
postInitialized() {
|
|
19388
|
+
if (!this.replayer) return;
|
|
19389
|
+
this.post({
|
|
19390
|
+
type: "initialized",
|
|
19391
|
+
metadata: this.replayer.getMetaData(),
|
|
19392
|
+
activityIntervals: this.replayer.getActivityIntervals()
|
|
19393
|
+
});
|
|
19394
|
+
}
|
|
19395
|
+
wireEvents(replayer) {
|
|
19396
|
+
for (const name of Object.values(ReplayerEvents)) {
|
|
19397
|
+
replayer.on(name, (payload) => {
|
|
19398
|
+
if (name === ReplayerEvents.Finish) {
|
|
19399
|
+
this.setPlaying(false);
|
|
19400
|
+
this.postTime();
|
|
19401
|
+
}
|
|
19402
|
+
if (name === ReplayerEvents.Resize) {
|
|
19403
|
+
this.postDimensions();
|
|
19404
|
+
}
|
|
19405
|
+
this.post(
|
|
19406
|
+
PAYLOAD_EVENTS.has(name) && payload !== void 0 ? { type: "replayer-event", event: name, payload } : { type: "replayer-event", event: name }
|
|
19407
|
+
);
|
|
19408
|
+
});
|
|
19409
|
+
}
|
|
19410
|
+
}
|
|
19411
|
+
/* --- current-time telemetry ------------------------------------------- */
|
|
19412
|
+
setPlaying(playing) {
|
|
19413
|
+
if (this.playing === playing) return;
|
|
19414
|
+
this.playing = playing;
|
|
19415
|
+
if (playing) this.startTimePump();
|
|
19416
|
+
else this.stopTimePump();
|
|
19417
|
+
}
|
|
19418
|
+
startTimePump() {
|
|
19419
|
+
if (this.timer !== null) return;
|
|
19420
|
+
this.timer = setInterval(() => this.postTime(), this.timeUpdateIntervalMs);
|
|
19421
|
+
}
|
|
19422
|
+
/**
|
|
19423
|
+
* Push the current playback position across the bridge.
|
|
19424
|
+
*
|
|
19425
|
+
* The parent cannot read the position synchronously — it lives in this realm
|
|
19426
|
+
* behind an origin boundary — so the client's `getCurrentTime()` is only ever
|
|
19427
|
+
* as fresh as the last push. While playing, the pump keeps it current. When
|
|
19428
|
+
* playback stops the pump stops too, so the last pumped value would be up to
|
|
19429
|
+
* one interval stale; callers that seek from it (`play(getCurrentTime())` to
|
|
19430
|
+
* resume) would drift backwards. Pausing and finishing therefore push one
|
|
19431
|
+
* final, settled value.
|
|
19432
|
+
*/
|
|
19433
|
+
postTime() {
|
|
19434
|
+
if (!this.replayer) return;
|
|
19435
|
+
this.post({ type: "time", currentTime: this.replayer.getCurrentTime() });
|
|
19436
|
+
}
|
|
19437
|
+
stopTimePump() {
|
|
19438
|
+
if (this.timer !== null) {
|
|
19439
|
+
clearInterval(this.timer);
|
|
19440
|
+
this.timer = null;
|
|
19441
|
+
}
|
|
19442
|
+
}
|
|
19443
|
+
post(message) {
|
|
19444
|
+
var _a2;
|
|
19445
|
+
this.parentWindow.postMessage(
|
|
19446
|
+
wrap(message),
|
|
19447
|
+
(_a2 = this.expectedParentOrigin) != null ? _a2 : "*"
|
|
19448
|
+
);
|
|
19449
|
+
}
|
|
19450
|
+
}
|
|
19451
|
+
function startEmbeddedReplayerHost(options) {
|
|
19452
|
+
const host2 = new EmbeddedReplayerHost(options);
|
|
19453
|
+
host2.start();
|
|
19454
|
+
return host2;
|
|
19455
|
+
}
|
|
19456
|
+
class EmbeddedReplayerClient {
|
|
19457
|
+
constructor(iframe, options = {}) {
|
|
19458
|
+
var _a2;
|
|
19459
|
+
__publicField(this, "iframe");
|
|
19460
|
+
__publicField(this, "hostOrigin");
|
|
19461
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
19462
|
+
__publicField(this, "metadata", null);
|
|
19463
|
+
__publicField(this, "activityIntervals", []);
|
|
19464
|
+
__publicField(this, "dimensions", null);
|
|
19465
|
+
__publicField(this, "lastCurrentTime", 0);
|
|
19466
|
+
__publicField(this, "ready", false);
|
|
19467
|
+
__publicField(this, "readyResolvers", []);
|
|
19468
|
+
__publicField(this, "disposed", false);
|
|
19469
|
+
__publicField(this, "pending", []);
|
|
19470
|
+
__publicField(this, "onMessage", (event) => {
|
|
19471
|
+
if (event.source !== this.iframe.contentWindow) return;
|
|
19472
|
+
if (!isEnvelope(event.data)) return;
|
|
19473
|
+
this.handle(event.data.message);
|
|
19474
|
+
});
|
|
19475
|
+
this.iframe = iframe;
|
|
19476
|
+
this.hostOrigin = (_a2 = options.hostOrigin) != null ? _a2 : "*";
|
|
19477
|
+
window.addEventListener("message", this.onMessage);
|
|
19478
|
+
this.probe();
|
|
19479
|
+
}
|
|
19480
|
+
/** Resolves once the host iframe has loaded and announced readiness. */
|
|
19481
|
+
whenReady() {
|
|
19482
|
+
if (this.ready) return Promise.resolve();
|
|
19483
|
+
return new Promise((resolve) => this.readyResolvers.push(resolve));
|
|
19484
|
+
}
|
|
19485
|
+
/* --- commands --------------------------------------------------------- */
|
|
19486
|
+
init(events, config, autoplay = false) {
|
|
19487
|
+
this.send({ type: "init", events, config, autoplay });
|
|
19488
|
+
}
|
|
19489
|
+
play(timeOffset) {
|
|
19490
|
+
this.send({ type: "play", timeOffset });
|
|
19491
|
+
}
|
|
19492
|
+
pause(timeOffset) {
|
|
19493
|
+
this.send({ type: "pause", timeOffset });
|
|
19494
|
+
}
|
|
19495
|
+
resume(timeOffset) {
|
|
19496
|
+
this.send({ type: "resume", timeOffset });
|
|
19497
|
+
}
|
|
19498
|
+
setConfig(config) {
|
|
19499
|
+
this.send({ type: "setConfig", config });
|
|
19500
|
+
}
|
|
19501
|
+
/**
|
|
19502
|
+
* Scale and position the replay. Compute `scale` from your own container size
|
|
19503
|
+
* and the recorded viewport, as you would when driving a local `Replayer`;
|
|
19504
|
+
* the host applies it, since the wrapper element is not reachable from here.
|
|
19505
|
+
* The layout is retained across re-inits.
|
|
19506
|
+
*/
|
|
19507
|
+
setLayout(scale, anchor) {
|
|
19508
|
+
this.send({ type: "setLayout", scale, anchor });
|
|
19509
|
+
}
|
|
19510
|
+
replaceEvents(events) {
|
|
19511
|
+
this.send({ type: "replaceEvents", events });
|
|
19512
|
+
}
|
|
19513
|
+
addEvent(event) {
|
|
19514
|
+
this.send({ type: "addEvent", event });
|
|
19515
|
+
}
|
|
19516
|
+
enableInteract() {
|
|
19517
|
+
this.send({ type: "enableInteract" });
|
|
19518
|
+
}
|
|
19519
|
+
disableInteract() {
|
|
19520
|
+
this.send({ type: "disableInteract" });
|
|
19521
|
+
}
|
|
19522
|
+
/** Tear down: destroys the host replayer and detaches the listener. */
|
|
19523
|
+
destroy() {
|
|
19524
|
+
if (this.disposed) return;
|
|
19525
|
+
this.disposed = true;
|
|
19526
|
+
try {
|
|
19527
|
+
this.send({ type: "destroy" });
|
|
19528
|
+
} finally {
|
|
19529
|
+
window.removeEventListener("message", this.onMessage);
|
|
19530
|
+
this.listeners.clear();
|
|
19531
|
+
}
|
|
19532
|
+
}
|
|
19533
|
+
/* --- event surface ---------------------------------------------------- */
|
|
19534
|
+
on(event, listener) {
|
|
19535
|
+
let set = this.listeners.get(event);
|
|
19536
|
+
if (!set) {
|
|
19537
|
+
set = /* @__PURE__ */ new Set();
|
|
19538
|
+
this.listeners.set(event, set);
|
|
19539
|
+
}
|
|
19540
|
+
set.add(listener);
|
|
19541
|
+
}
|
|
19542
|
+
off(event, listener) {
|
|
19543
|
+
var _a2;
|
|
19544
|
+
(_a2 = this.listeners.get(event)) == null ? void 0 : _a2.delete(listener);
|
|
19545
|
+
}
|
|
19546
|
+
/* --- getters ---------------------------------------------------------- */
|
|
19547
|
+
// Cached getters mirroring the local Replayer's synchronous ones. Metadata
|
|
19548
|
+
// and activity intervals arrive on `initialized` (re-sent on replaceEvents);
|
|
19549
|
+
// current time is streamed by the host while playing.
|
|
19550
|
+
/** Last-known current time (pushed by the host while playing). */
|
|
19551
|
+
getCurrentTime() {
|
|
19552
|
+
return this.lastCurrentTime;
|
|
19553
|
+
}
|
|
19554
|
+
getMetaData() {
|
|
19555
|
+
return this.metadata;
|
|
19556
|
+
}
|
|
19557
|
+
getActivityIntervals() {
|
|
19558
|
+
return this.activityIntervals;
|
|
19559
|
+
}
|
|
19560
|
+
/**
|
|
19561
|
+
* Rendered geometry of the replay, in the host document's coordinate space —
|
|
19562
|
+
* the cross-origin stand-in for `replayer.wrapper.getBoundingClientRect()`.
|
|
19563
|
+
* Null until the host has reported it (listen for `'dimensions'`).
|
|
19564
|
+
*/
|
|
19565
|
+
getDimensions() {
|
|
19566
|
+
return this.dimensions;
|
|
19567
|
+
}
|
|
19568
|
+
/* --- internals -------------------------------------------------------- */
|
|
19569
|
+
send(command) {
|
|
19570
|
+
if (!this.ready) {
|
|
19571
|
+
this.pending.push(command);
|
|
19572
|
+
return;
|
|
19573
|
+
}
|
|
19574
|
+
this.postToHost(command);
|
|
19575
|
+
}
|
|
19576
|
+
postToHost(command) {
|
|
19577
|
+
const target = this.iframe.contentWindow;
|
|
19578
|
+
if (!target) return;
|
|
19579
|
+
target.postMessage(wrap(command), this.hostOrigin);
|
|
19580
|
+
}
|
|
19581
|
+
flushPending() {
|
|
19582
|
+
const queued = this.pending;
|
|
19583
|
+
this.pending = [];
|
|
19584
|
+
queued.forEach((command) => this.postToHost(command));
|
|
19585
|
+
}
|
|
19586
|
+
/** Data-free handshake probe; see the note in the constructor. */
|
|
19587
|
+
probe() {
|
|
19588
|
+
var _a2;
|
|
19589
|
+
(_a2 = this.iframe.contentWindow) == null ? void 0 : _a2.postMessage(wrap({ type: "ping" }), "*");
|
|
19590
|
+
}
|
|
19591
|
+
handle(message) {
|
|
19592
|
+
switch (message.type) {
|
|
19593
|
+
case "ready":
|
|
19594
|
+
this.ready = true;
|
|
19595
|
+
this.flushPending();
|
|
19596
|
+
this.readyResolvers.forEach((r2) => r2());
|
|
19597
|
+
this.readyResolvers = [];
|
|
19598
|
+
return;
|
|
19599
|
+
case "initialized":
|
|
19600
|
+
this.metadata = message.metadata;
|
|
19601
|
+
this.activityIntervals = message.activityIntervals;
|
|
19602
|
+
this.emit("initialized", message.metadata);
|
|
19603
|
+
return;
|
|
19604
|
+
case "replayer-event":
|
|
19605
|
+
this.emit(message.event, message.payload);
|
|
19606
|
+
return;
|
|
19607
|
+
case "time":
|
|
19608
|
+
this.lastCurrentTime = message.currentTime;
|
|
19609
|
+
this.emit("time", message.currentTime);
|
|
19610
|
+
return;
|
|
19611
|
+
case "dimensions":
|
|
19612
|
+
this.dimensions = {
|
|
19613
|
+
width: message.width,
|
|
19614
|
+
height: message.height,
|
|
19615
|
+
top: message.top,
|
|
19616
|
+
left: message.left
|
|
19617
|
+
};
|
|
19618
|
+
this.emit("dimensions", this.dimensions);
|
|
19619
|
+
return;
|
|
19620
|
+
case "error":
|
|
19621
|
+
this.emit("error", message.message);
|
|
19622
|
+
return;
|
|
19623
|
+
}
|
|
19624
|
+
}
|
|
19625
|
+
emit(event, payload) {
|
|
19626
|
+
var _a2;
|
|
19627
|
+
(_a2 = this.listeners.get(event)) == null ? void 0 : _a2.forEach((listener) => listener(payload));
|
|
19628
|
+
}
|
|
19629
|
+
}
|
|
19630
|
+
function originOf(url) {
|
|
19631
|
+
try {
|
|
19632
|
+
return new URL(url).origin;
|
|
19633
|
+
} catch (e2) {
|
|
19634
|
+
return "'self'";
|
|
19635
|
+
}
|
|
19636
|
+
}
|
|
19637
|
+
function buildHostDocument(options) {
|
|
19638
|
+
var _a2;
|
|
19639
|
+
const scriptOrigin = originOf(options.scriptUrl);
|
|
19640
|
+
const styleSources = [
|
|
19641
|
+
"'unsafe-inline'",
|
|
19642
|
+
scriptOrigin,
|
|
19643
|
+
...(_a2 = options.extraStyleSources) != null ? _a2 : []
|
|
19644
|
+
].join(" ");
|
|
19645
|
+
const csp = [
|
|
19646
|
+
`default-src 'none'`,
|
|
19647
|
+
`script-src ${scriptOrigin}`,
|
|
19648
|
+
`style-src ${styleSources}`,
|
|
19649
|
+
`img-src * data: blob:`,
|
|
19650
|
+
`font-src * data:`,
|
|
19651
|
+
`media-src * data: blob:`,
|
|
19652
|
+
`frame-src *`,
|
|
19653
|
+
`connect-src 'none'`,
|
|
19654
|
+
`worker-src 'none'`
|
|
19655
|
+
].join("; ");
|
|
19656
|
+
const styleTag = options.styleUrl ? `<link rel="stylesheet" href="${escapeAttr(options.styleUrl)}">` : "";
|
|
19657
|
+
return `<!DOCTYPE html>
|
|
19658
|
+
<html>
|
|
19659
|
+
<head>
|
|
19660
|
+
<meta charset="utf-8">
|
|
19661
|
+
<meta http-equiv="Content-Security-Policy" content="${escapeAttr(csp)}">
|
|
19662
|
+
<style>html,body{margin:0;padding:0;height:100%;overflow:hidden;background:transparent}</style>
|
|
19663
|
+
${styleTag}
|
|
19664
|
+
<script type="module" src="${escapeAttr(options.scriptUrl)}"><\/script>
|
|
19665
|
+
</head>
|
|
19666
|
+
<body></body>
|
|
19667
|
+
</html>`;
|
|
19668
|
+
}
|
|
19669
|
+
function escapeAttr(value) {
|
|
19670
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
19671
|
+
}
|
|
19131
19672
|
const { addCustomEvent } = record;
|
|
19132
19673
|
const { freezePage } = record;
|
|
19133
19674
|
const { takeFullSnapshot } = record;
|
|
19675
|
+
exports.EmbeddedReplayerClient = EmbeddedReplayerClient;
|
|
19676
|
+
exports.EmbeddedReplayerHost = EmbeddedReplayerHost;
|
|
19134
19677
|
exports.EventType = EventType;
|
|
19135
19678
|
exports.IncrementalSource = IncrementalSource;
|
|
19136
19679
|
exports.MouseInteractions = MouseInteractions;
|
|
19680
|
+
exports.RRWEB_EMBEDDED_CHANNEL = RRWEB_EMBEDDED_CHANNEL;
|
|
19681
|
+
exports.RRWEB_EMBEDDED_PROTOCOL_VERSION = RRWEB_EMBEDDED_PROTOCOL_VERSION;
|
|
19137
19682
|
exports.Replayer = Replayer;
|
|
19138
19683
|
exports.ReplayerEvents = ReplayerEvents;
|
|
19139
19684
|
exports.addCustomEvent = addCustomEvent;
|
|
19685
|
+
exports.buildHostDocument = buildHostDocument;
|
|
19140
19686
|
exports.canvasMutation = canvasMutation;
|
|
19141
19687
|
exports.freezePage = freezePage;
|
|
19688
|
+
exports.pickSerializableConfig = pickSerializableConfig;
|
|
19142
19689
|
exports.record = record;
|
|
19690
|
+
exports.startEmbeddedReplayerHost = startEmbeddedReplayerHost;
|
|
19143
19691
|
exports.takeFullSnapshot = takeFullSnapshot;
|
|
19144
19692
|
exports.utils = utils;
|
|
19145
19693
|
;if (typeof module.exports == "object" && typeof exports == "object") {
|