@highlight-run/rrweb 2.0.0-lambda.8 → 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 +326 -42
- package/dist/rrweb.cjs.map +1 -1
- package/dist/rrweb.d.cts +5 -2
- package/dist/rrweb.d.ts +5 -2
- package/dist/rrweb.js +326 -42
- package/dist/rrweb.js.map +1 -1
- package/dist/rrweb.umd.cjs +326 -42
- package/dist/rrweb.umd.cjs.map +2 -2
- package/dist/rrweb.umd.min.cjs +46 -46
- package/dist/rrweb.umd.min.cjs.map +3 -3
- package/package.json +5 -5
- package/umd/rrweb.js +326 -42
- package/umd/rrweb.min.js +46 -46
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highlight-run/rrweb",
|
|
3
|
-
"version": "2.0.0-lambda.
|
|
3
|
+
"version": "2.0.0-lambda.9",
|
|
4
4
|
"description": "record and replay the web",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepare": "npm run prepack",
|
|
@@ -90,10 +90,10 @@
|
|
|
90
90
|
"vitest": "^3.2.6"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
|
-
"@highlight-run/rrdom": "2.0.0-lambda.
|
|
94
|
-
"@highlight-run/rrweb-snapshot": "2.0.0-lambda.
|
|
95
|
-
"@highlight-run/rrweb-types": "2.0.0-lambda.
|
|
96
|
-
"@highlight-run/rrweb-utils": "2.0.0-lambda.
|
|
93
|
+
"@highlight-run/rrdom": "2.0.0-lambda.9",
|
|
94
|
+
"@highlight-run/rrweb-snapshot": "2.0.0-lambda.9",
|
|
95
|
+
"@highlight-run/rrweb-types": "2.0.0-lambda.9",
|
|
96
|
+
"@highlight-run/rrweb-utils": "2.0.0-lambda.9",
|
|
97
97
|
"@types/css-font-loading-module": "0.0.7",
|
|
98
98
|
"@xstate/fsm": "^1.4.0",
|
|
99
99
|
"base64-arraybuffer": "^1.0.1",
|
package/umd/rrweb.js
CHANGED
|
@@ -13686,66 +13686,142 @@ function getIdAndStyleId(sheet, mirror2, styleMirror) {
|
|
|
13686
13686
|
id
|
|
13687
13687
|
};
|
|
13688
13688
|
}
|
|
13689
|
-
function
|
|
13689
|
+
function restorePatchedMethod(target, key, ours, restoreTo) {
|
|
13690
|
+
if (target[key] === ours) {
|
|
13691
|
+
target[key] = restoreTo;
|
|
13692
|
+
}
|
|
13693
|
+
}
|
|
13694
|
+
const MAX_CSSOM_REPATCH_ATTEMPTS = 5;
|
|
13695
|
+
function initStyleSheetObserver({
|
|
13696
|
+
styleSheetRuleCb,
|
|
13697
|
+
mirror: mirror2,
|
|
13698
|
+
stylesheetManager,
|
|
13699
|
+
doc,
|
|
13700
|
+
styleSheetResyncInterval
|
|
13701
|
+
}, { win }) {
|
|
13690
13702
|
if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
|
|
13691
13703
|
return () => {
|
|
13692
13704
|
};
|
|
13693
13705
|
}
|
|
13694
|
-
const
|
|
13695
|
-
|
|
13706
|
+
const reportedRuleCounts = /* @__PURE__ */ new WeakMap();
|
|
13707
|
+
const unreconcilableSheets = /* @__PURE__ */ new WeakSet();
|
|
13708
|
+
let probing = false;
|
|
13709
|
+
let probeInsertObserved = false;
|
|
13710
|
+
let probeDeleteObserved = false;
|
|
13711
|
+
let probeSheet;
|
|
13712
|
+
let stopped = false;
|
|
13713
|
+
let insideInsertRule = false;
|
|
13714
|
+
let insideDeleteRule = false;
|
|
13715
|
+
const noteReportedRules = (sheet, delta) => {
|
|
13716
|
+
const state = reportedRuleCounts.get(sheet);
|
|
13717
|
+
if (state) {
|
|
13718
|
+
state.reported = Math.max(0, state.reported + delta);
|
|
13719
|
+
state.everSeen = Math.max(state.everSeen, state.reported);
|
|
13720
|
+
}
|
|
13721
|
+
};
|
|
13722
|
+
const patchInsertRule = (target) => new Proxy(target, {
|
|
13696
13723
|
apply: callbackWrapper(
|
|
13697
|
-
(
|
|
13724
|
+
(nativeFn, thisArg, argumentsList) => {
|
|
13725
|
+
if (probing) {
|
|
13726
|
+
probeInsertObserved = true;
|
|
13727
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13728
|
+
}
|
|
13729
|
+
if (stopped || insideInsertRule) {
|
|
13730
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13731
|
+
}
|
|
13698
13732
|
const [rule2, index2] = argumentsList;
|
|
13699
13733
|
const { id, styleId } = getIdAndStyleId(
|
|
13700
13734
|
thisArg,
|
|
13701
13735
|
mirror2,
|
|
13702
13736
|
stylesheetManager.styleMirror
|
|
13703
13737
|
);
|
|
13704
|
-
|
|
13738
|
+
const reported = id && id !== -1 || styleId && styleId !== -1;
|
|
13739
|
+
if (reported) {
|
|
13705
13740
|
styleSheetRuleCb({
|
|
13706
13741
|
id,
|
|
13707
13742
|
styleId,
|
|
13708
13743
|
adds: [{ rule: rule2, index: index2 }]
|
|
13709
13744
|
});
|
|
13710
13745
|
}
|
|
13711
|
-
|
|
13746
|
+
insideInsertRule = true;
|
|
13747
|
+
let result2;
|
|
13748
|
+
try {
|
|
13749
|
+
result2 = nativeFn.apply(thisArg, argumentsList);
|
|
13750
|
+
} finally {
|
|
13751
|
+
insideInsertRule = false;
|
|
13752
|
+
}
|
|
13753
|
+
if (reported) {
|
|
13754
|
+
noteReportedRules(thisArg, 1);
|
|
13755
|
+
}
|
|
13756
|
+
return result2;
|
|
13712
13757
|
}
|
|
13713
13758
|
)
|
|
13714
13759
|
});
|
|
13715
|
-
|
|
13716
|
-
const rule2 = `${selector} { ${styleBlock} }`;
|
|
13717
|
-
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
|
|
13718
|
-
};
|
|
13719
|
-
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
|
13720
|
-
win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
|
|
13760
|
+
const patchDeleteRule = (target) => new Proxy(target, {
|
|
13721
13761
|
apply: callbackWrapper(
|
|
13722
|
-
(
|
|
13762
|
+
(nativeFn, thisArg, argumentsList) => {
|
|
13763
|
+
if (probing) {
|
|
13764
|
+
probeDeleteObserved = true;
|
|
13765
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13766
|
+
}
|
|
13767
|
+
if (stopped || insideDeleteRule) {
|
|
13768
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13769
|
+
}
|
|
13723
13770
|
const [index2] = argumentsList;
|
|
13724
13771
|
const { id, styleId } = getIdAndStyleId(
|
|
13725
13772
|
thisArg,
|
|
13726
13773
|
mirror2,
|
|
13727
13774
|
stylesheetManager.styleMirror
|
|
13728
13775
|
);
|
|
13729
|
-
|
|
13776
|
+
const reported = id && id !== -1 || styleId && styleId !== -1;
|
|
13777
|
+
if (reported) {
|
|
13730
13778
|
styleSheetRuleCb({
|
|
13731
13779
|
id,
|
|
13732
13780
|
styleId,
|
|
13733
13781
|
removes: [{ index: index2 }]
|
|
13734
13782
|
});
|
|
13735
13783
|
}
|
|
13736
|
-
|
|
13784
|
+
insideDeleteRule = true;
|
|
13785
|
+
let result2;
|
|
13786
|
+
try {
|
|
13787
|
+
result2 = nativeFn.apply(thisArg, argumentsList);
|
|
13788
|
+
} finally {
|
|
13789
|
+
insideDeleteRule = false;
|
|
13790
|
+
}
|
|
13791
|
+
if (reported) {
|
|
13792
|
+
noteReportedRules(thisArg, -1);
|
|
13793
|
+
}
|
|
13794
|
+
return result2;
|
|
13737
13795
|
}
|
|
13738
13796
|
)
|
|
13739
13797
|
});
|
|
13740
|
-
win.CSSStyleSheet.prototype.
|
|
13798
|
+
const insertRule = win.CSSStyleSheet.prototype.insertRule;
|
|
13799
|
+
let insertRuleProxy = patchInsertRule(insertRule);
|
|
13800
|
+
let restoreInsertRuleTo = insertRule;
|
|
13801
|
+
win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
|
|
13802
|
+
const addRule = win.CSSStyleSheet.prototype.addRule;
|
|
13803
|
+
const addRuleShim = function(selector, styleBlock, index2 = this.cssRules.length) {
|
|
13804
|
+
const rule2 = `${selector} { ${styleBlock} }`;
|
|
13805
|
+
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
|
|
13806
|
+
};
|
|
13807
|
+
win.CSSStyleSheet.prototype.addRule = addRuleShim;
|
|
13808
|
+
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
|
13809
|
+
let deleteRuleProxy = patchDeleteRule(deleteRule);
|
|
13810
|
+
let restoreDeleteRuleTo = deleteRule;
|
|
13811
|
+
win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
|
|
13812
|
+
const removeRule = win.CSSStyleSheet.prototype.removeRule;
|
|
13813
|
+
const removeRuleShim = function(index2) {
|
|
13741
13814
|
return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);
|
|
13742
13815
|
};
|
|
13816
|
+
win.CSSStyleSheet.prototype.removeRule = removeRuleShim;
|
|
13743
13817
|
let replace;
|
|
13818
|
+
let replaceProxy;
|
|
13744
13819
|
if (win.CSSStyleSheet.prototype.replace) {
|
|
13745
13820
|
replace = win.CSSStyleSheet.prototype.replace;
|
|
13746
|
-
|
|
13821
|
+
replaceProxy = new Proxy(replace, {
|
|
13747
13822
|
apply: callbackWrapper(
|
|
13748
13823
|
(target, thisArg, argumentsList) => {
|
|
13824
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13749
13825
|
const [text] = argumentsList;
|
|
13750
13826
|
const { id, styleId } = getIdAndStyleId(
|
|
13751
13827
|
thisArg,
|
|
@@ -13763,13 +13839,16 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13763
13839
|
}
|
|
13764
13840
|
)
|
|
13765
13841
|
});
|
|
13842
|
+
win.CSSStyleSheet.prototype.replace = replaceProxy;
|
|
13766
13843
|
}
|
|
13767
13844
|
let replaceSync;
|
|
13845
|
+
let replaceSyncProxy;
|
|
13768
13846
|
if (win.CSSStyleSheet.prototype.replaceSync) {
|
|
13769
13847
|
replaceSync = win.CSSStyleSheet.prototype.replaceSync;
|
|
13770
|
-
|
|
13848
|
+
replaceSyncProxy = new Proxy(replaceSync, {
|
|
13771
13849
|
apply: callbackWrapper(
|
|
13772
13850
|
(target, thisArg, argumentsList) => {
|
|
13851
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13773
13852
|
const [text] = argumentsList;
|
|
13774
13853
|
const { id, styleId } = getIdAndStyleId(
|
|
13775
13854
|
thisArg,
|
|
@@ -13787,6 +13866,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13787
13866
|
}
|
|
13788
13867
|
)
|
|
13789
13868
|
});
|
|
13869
|
+
win.CSSStyleSheet.prototype.replaceSync = replaceSyncProxy;
|
|
13790
13870
|
}
|
|
13791
13871
|
const supportedNestedCSSRuleTypes = {};
|
|
13792
13872
|
if (canMonkeyPatchNestedCSSRule("CSSGroupingRule")) {
|
|
@@ -13803,6 +13883,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13803
13883
|
}
|
|
13804
13884
|
}
|
|
13805
13885
|
const unmodifiedFunctions = {};
|
|
13886
|
+
const nestedProxies = {};
|
|
13806
13887
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
13807
13888
|
unmodifiedFunctions[typeKey] = {
|
|
13808
13889
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
@@ -13810,11 +13891,13 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13810
13891
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
13811
13892
|
deleteRule: type.prototype.deleteRule
|
|
13812
13893
|
};
|
|
13813
|
-
|
|
13894
|
+
nestedProxies[typeKey] = {};
|
|
13895
|
+
nestedProxies[typeKey].insertRule = new Proxy(
|
|
13814
13896
|
unmodifiedFunctions[typeKey].insertRule,
|
|
13815
13897
|
{
|
|
13816
13898
|
apply: callbackWrapper(
|
|
13817
13899
|
(target, thisArg, argumentsList) => {
|
|
13900
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13818
13901
|
const [rule2, index2] = argumentsList;
|
|
13819
13902
|
const { id, styleId } = getIdAndStyleId(
|
|
13820
13903
|
thisArg.parentStyleSheet,
|
|
@@ -13842,11 +13925,12 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13842
13925
|
)
|
|
13843
13926
|
}
|
|
13844
13927
|
);
|
|
13845
|
-
|
|
13928
|
+
nestedProxies[typeKey].deleteRule = new Proxy(
|
|
13846
13929
|
unmodifiedFunctions[typeKey].deleteRule,
|
|
13847
13930
|
{
|
|
13848
13931
|
apply: callbackWrapper(
|
|
13849
13932
|
(target, thisArg, argumentsList) => {
|
|
13933
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13850
13934
|
const [index2] = argumentsList;
|
|
13851
13935
|
const { id, styleId } = getIdAndStyleId(
|
|
13852
13936
|
thisArg.parentStyleSheet,
|
|
@@ -13867,15 +13951,148 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13867
13951
|
)
|
|
13868
13952
|
}
|
|
13869
13953
|
);
|
|
13954
|
+
type.prototype.insertRule = nestedProxies[typeKey].insertRule;
|
|
13955
|
+
type.prototype.deleteRule = nestedProxies[typeKey].deleteRule;
|
|
13870
13956
|
});
|
|
13957
|
+
const captureIsHealthy = () => {
|
|
13958
|
+
probing = true;
|
|
13959
|
+
probeInsertObserved = false;
|
|
13960
|
+
probeDeleteObserved = false;
|
|
13961
|
+
try {
|
|
13962
|
+
const probe = probeSheet != null ? probeSheet : probeSheet = new win.CSSStyleSheet();
|
|
13963
|
+
probe.insertRule(":root {}", 0);
|
|
13964
|
+
probe.deleteRule(0);
|
|
13965
|
+
} catch (error) {
|
|
13966
|
+
return {
|
|
13967
|
+
insertRule: win.CSSStyleSheet.prototype.insertRule === insertRuleProxy,
|
|
13968
|
+
deleteRule: win.CSSStyleSheet.prototype.deleteRule === deleteRuleProxy
|
|
13969
|
+
};
|
|
13970
|
+
} finally {
|
|
13971
|
+
probing = false;
|
|
13972
|
+
}
|
|
13973
|
+
return {
|
|
13974
|
+
insertRule: probeInsertObserved,
|
|
13975
|
+
deleteRule: probeDeleteObserved
|
|
13976
|
+
};
|
|
13977
|
+
};
|
|
13978
|
+
let repatchAttempts = 0;
|
|
13979
|
+
const repatch = (health) => {
|
|
13980
|
+
if (repatchAttempts >= MAX_CSSOM_REPATCH_ATTEMPTS) return;
|
|
13981
|
+
repatchAttempts += 1;
|
|
13982
|
+
if (!health.insertRule) {
|
|
13983
|
+
restoreInsertRuleTo = win.CSSStyleSheet.prototype.insertRule;
|
|
13984
|
+
insertRuleProxy = patchInsertRule(restoreInsertRuleTo);
|
|
13985
|
+
win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
|
|
13986
|
+
}
|
|
13987
|
+
if (!health.deleteRule) {
|
|
13988
|
+
restoreDeleteRuleTo = win.CSSStyleSheet.prototype.deleteRule;
|
|
13989
|
+
deleteRuleProxy = patchDeleteRule(restoreDeleteRuleTo);
|
|
13990
|
+
win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
|
|
13991
|
+
}
|
|
13992
|
+
};
|
|
13993
|
+
const resyncCssomStyleSheets = (trusted) => {
|
|
13994
|
+
for (let i2 = 0; i2 < doc.styleSheets.length; i2++) {
|
|
13995
|
+
const sheet = doc.styleSheets[i2];
|
|
13996
|
+
if (unreconcilableSheets.has(sheet)) continue;
|
|
13997
|
+
const owner = sheet.ownerNode;
|
|
13998
|
+
if (!owner || toLowerCase(owner.nodeName) !== "style") continue;
|
|
13999
|
+
if ((owner.textContent || "").trim().length) continue;
|
|
14000
|
+
const id = mirror2.getId(owner);
|
|
14001
|
+
if (!id || id === -1) continue;
|
|
14002
|
+
let rules2;
|
|
14003
|
+
try {
|
|
14004
|
+
rules2 = sheet.cssRules;
|
|
14005
|
+
} catch (error) {
|
|
14006
|
+
continue;
|
|
14007
|
+
}
|
|
14008
|
+
const live = rules2.length;
|
|
14009
|
+
let state = reportedRuleCounts.get(sheet);
|
|
14010
|
+
if (!state) {
|
|
14011
|
+
if (Array.from(rules2).some((rule2) => isCSSImportRule(rule2))) {
|
|
14012
|
+
unreconcilableSheets.add(sheet);
|
|
14013
|
+
continue;
|
|
14014
|
+
}
|
|
14015
|
+
state = { reported: live, everSeen: live };
|
|
14016
|
+
reportedRuleCounts.set(sheet, state);
|
|
14017
|
+
if (trusted) continue;
|
|
14018
|
+
replaceReplayerCopy(id, state, rules2);
|
|
14019
|
+
continue;
|
|
14020
|
+
}
|
|
14021
|
+
state.everSeen = Math.max(state.everSeen, live);
|
|
14022
|
+
if (live === state.reported) continue;
|
|
14023
|
+
if (live > state.reported) {
|
|
14024
|
+
const adds = [];
|
|
14025
|
+
for (let index2 = state.reported; index2 < live; index2++) {
|
|
14026
|
+
adds.push({ rule: rules2[index2].cssText, index: index2 });
|
|
14027
|
+
}
|
|
14028
|
+
styleSheetRuleCb({ id, adds });
|
|
14029
|
+
state.reported = live;
|
|
14030
|
+
} else {
|
|
14031
|
+
replaceReplayerCopy(id, state, rules2);
|
|
14032
|
+
}
|
|
14033
|
+
}
|
|
14034
|
+
};
|
|
14035
|
+
function replaceReplayerCopy(id, state, rules2) {
|
|
14036
|
+
const removes = [];
|
|
14037
|
+
for (let index2 = state.everSeen - 1; index2 >= 0; index2--) {
|
|
14038
|
+
removes.push({ index: index2 });
|
|
14039
|
+
}
|
|
14040
|
+
if (removes.length) styleSheetRuleCb({ id, removes });
|
|
14041
|
+
styleSheetRuleCb({
|
|
14042
|
+
id,
|
|
14043
|
+
adds: Array.from(rules2, (rule2, index2) => ({
|
|
14044
|
+
rule: rule2.cssText,
|
|
14045
|
+
index: index2
|
|
14046
|
+
}))
|
|
14047
|
+
});
|
|
14048
|
+
state.reported = rules2.length;
|
|
14049
|
+
state.everSeen = rules2.length;
|
|
14050
|
+
}
|
|
14051
|
+
let resyncTimer;
|
|
14052
|
+
if (styleSheetResyncInterval > 0) {
|
|
14053
|
+
resyncTimer = win.setInterval(
|
|
14054
|
+
callbackWrapper(() => {
|
|
14055
|
+
const health = captureIsHealthy();
|
|
14056
|
+
const healthy = health.insertRule && health.deleteRule;
|
|
14057
|
+
if (!healthy) repatch(health);
|
|
14058
|
+
resyncCssomStyleSheets(healthy);
|
|
14059
|
+
}),
|
|
14060
|
+
styleSheetResyncInterval
|
|
14061
|
+
);
|
|
14062
|
+
}
|
|
13871
14063
|
return callbackWrapper(() => {
|
|
13872
|
-
win.
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
14064
|
+
if (resyncTimer !== void 0) win.clearInterval(resyncTimer);
|
|
14065
|
+
stopped = true;
|
|
14066
|
+
const proto = win.CSSStyleSheet.prototype;
|
|
14067
|
+
restorePatchedMethod(
|
|
14068
|
+
proto,
|
|
14069
|
+
"insertRule",
|
|
14070
|
+
insertRuleProxy,
|
|
14071
|
+
restoreInsertRuleTo
|
|
14072
|
+
);
|
|
14073
|
+
restorePatchedMethod(
|
|
14074
|
+
proto,
|
|
14075
|
+
"deleteRule",
|
|
14076
|
+
deleteRuleProxy,
|
|
14077
|
+
restoreDeleteRuleTo
|
|
14078
|
+
);
|
|
14079
|
+
restorePatchedMethod(proto, "addRule", addRuleShim, addRule);
|
|
14080
|
+
restorePatchedMethod(proto, "removeRule", removeRuleShim, removeRule);
|
|
14081
|
+
replaceProxy && restorePatchedMethod(proto, "replace", replaceProxy, replace);
|
|
14082
|
+
replaceSyncProxy && restorePatchedMethod(proto, "replaceSync", replaceSyncProxy, replaceSync);
|
|
13876
14083
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
13877
|
-
|
|
13878
|
-
|
|
14084
|
+
restorePatchedMethod(
|
|
14085
|
+
type.prototype,
|
|
14086
|
+
"insertRule",
|
|
14087
|
+
nestedProxies[typeKey].insertRule,
|
|
14088
|
+
unmodifiedFunctions[typeKey].insertRule
|
|
14089
|
+
);
|
|
14090
|
+
restorePatchedMethod(
|
|
14091
|
+
type.prototype,
|
|
14092
|
+
"deleteRule",
|
|
14093
|
+
nestedProxies[typeKey].deleteRule,
|
|
14094
|
+
unmodifiedFunctions[typeKey].deleteRule
|
|
14095
|
+
);
|
|
13879
14096
|
});
|
|
13880
14097
|
});
|
|
13881
14098
|
}
|
|
@@ -15641,6 +15858,7 @@ function record(options = {}) {
|
|
|
15641
15858
|
keepIframeSrcFn = () => false,
|
|
15642
15859
|
privacySetting = "default",
|
|
15643
15860
|
ignoreCSSAttributes = /* @__PURE__ */ new Set([]),
|
|
15861
|
+
styleSheetResyncInterval = 2e3,
|
|
15644
15862
|
errorHandler: errorHandler2,
|
|
15645
15863
|
logger
|
|
15646
15864
|
} = options;
|
|
@@ -16003,6 +16221,7 @@ function record(options = {}) {
|
|
|
16003
16221
|
processedNodeManager,
|
|
16004
16222
|
canvasManager,
|
|
16005
16223
|
ignoreCSSAttributes,
|
|
16224
|
+
styleSheetResyncInterval,
|
|
16006
16225
|
privacySetting,
|
|
16007
16226
|
plugins: ((_a3 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a3.map((p) => ({
|
|
16008
16227
|
observer: p.observer,
|
|
@@ -16887,12 +17106,36 @@ function variableListFor(ctx, ctor) {
|
|
|
16887
17106
|
}
|
|
16888
17107
|
return contextMap.get(ctor);
|
|
16889
17108
|
}
|
|
16890
|
-
|
|
17109
|
+
const canvasArgConstructors = /* @__PURE__ */ new Set([
|
|
17110
|
+
"Int8Array",
|
|
17111
|
+
"Int16Array",
|
|
17112
|
+
"Int32Array",
|
|
17113
|
+
"Uint8Array",
|
|
17114
|
+
"Uint8ClampedArray",
|
|
17115
|
+
"Uint16Array",
|
|
17116
|
+
"Uint32Array",
|
|
17117
|
+
"Float32Array",
|
|
17118
|
+
"Float64Array",
|
|
17119
|
+
"DataView",
|
|
17120
|
+
"ImageData",
|
|
17121
|
+
// normally serialized as base64, but reachable in `args` form through
|
|
17122
|
+
// recordings made by older clients and through nested `DataView` args.
|
|
17123
|
+
"ArrayBuffer",
|
|
17124
|
+
// wraps nested args in recordings made by older clients — see the
|
|
17125
|
+
// `preloadAllImages` tests for the shape.
|
|
17126
|
+
"Array"
|
|
17127
|
+
]);
|
|
17128
|
+
function deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist = false) {
|
|
16891
17129
|
return async (arg) => {
|
|
16892
17130
|
if (arg && typeof arg === "object" && "rr_type" in arg) {
|
|
16893
17131
|
if (preload) preload.isUnchanged = false;
|
|
16894
17132
|
if (arg.rr_type === "ImageBitmap" && "args" in arg) {
|
|
16895
|
-
const args = await deserializeArg(
|
|
17133
|
+
const args = await deserializeArg(
|
|
17134
|
+
imageMap,
|
|
17135
|
+
ctx,
|
|
17136
|
+
preload,
|
|
17137
|
+
enforceCanvasArgAllowlist
|
|
17138
|
+
)(arg.args);
|
|
16896
17139
|
return await createImageBitmap.apply(null, args);
|
|
16897
17140
|
} else if ("index" in arg) {
|
|
16898
17141
|
if (preload || ctx === null) return arg;
|
|
@@ -16900,10 +17143,18 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16900
17143
|
return variableListFor(ctx, name)[index2];
|
|
16901
17144
|
} else if ("args" in arg) {
|
|
16902
17145
|
const { rr_type: name, args } = arg;
|
|
17146
|
+
if (enforceCanvasArgAllowlist && !canvasArgConstructors.has(name)) {
|
|
17147
|
+
console.warn(
|
|
17148
|
+
`[replayer] refusing to construct canvas arg of unknown type: ${name}`
|
|
17149
|
+
);
|
|
17150
|
+
return null;
|
|
17151
|
+
}
|
|
16903
17152
|
const ctor = window[name];
|
|
16904
17153
|
return new ctor(
|
|
16905
17154
|
...await Promise.all(
|
|
16906
|
-
args.map(
|
|
17155
|
+
args.map(
|
|
17156
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17157
|
+
)
|
|
16907
17158
|
)
|
|
16908
17159
|
);
|
|
16909
17160
|
} else if ("base64" in arg) {
|
|
@@ -16920,7 +17171,9 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16920
17171
|
}
|
|
16921
17172
|
} else if ("data" in arg && arg.rr_type === "Blob") {
|
|
16922
17173
|
const blobContents = await Promise.all(
|
|
16923
|
-
arg.data.map(
|
|
17174
|
+
arg.data.map(
|
|
17175
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17176
|
+
)
|
|
16924
17177
|
);
|
|
16925
17178
|
const blob2 = new Blob(blobContents, {
|
|
16926
17179
|
type: arg.type
|
|
@@ -16929,7 +17182,9 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16929
17182
|
}
|
|
16930
17183
|
} else if (Array.isArray(arg)) {
|
|
16931
17184
|
const result2 = await Promise.all(
|
|
16932
|
-
arg.map(
|
|
17185
|
+
arg.map(
|
|
17186
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17187
|
+
)
|
|
16933
17188
|
);
|
|
16934
17189
|
return result2;
|
|
16935
17190
|
}
|
|
@@ -16970,7 +17225,8 @@ async function webglMutation({
|
|
|
16970
17225
|
target,
|
|
16971
17226
|
type,
|
|
16972
17227
|
imageMap,
|
|
16973
|
-
errorHandler: errorHandler2
|
|
17228
|
+
errorHandler: errorHandler2,
|
|
17229
|
+
enforceCanvasArgAllowlist
|
|
16974
17230
|
}) {
|
|
16975
17231
|
try {
|
|
16976
17232
|
const ctx = getContext(target, type);
|
|
@@ -16981,7 +17237,9 @@ async function webglMutation({
|
|
|
16981
17237
|
}
|
|
16982
17238
|
const original = ctx[mutation.property];
|
|
16983
17239
|
const args = await Promise.all(
|
|
16984
|
-
mutation.args.map(
|
|
17240
|
+
mutation.args.map(
|
|
17241
|
+
deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
|
|
17242
|
+
)
|
|
16985
17243
|
);
|
|
16986
17244
|
const result2 = original.apply(ctx, args);
|
|
16987
17245
|
saveToWebGLVarMap(ctx, result2);
|
|
@@ -16996,7 +17254,8 @@ async function canvasMutation$1({
|
|
|
16996
17254
|
mutations,
|
|
16997
17255
|
target,
|
|
16998
17256
|
imageMap,
|
|
16999
|
-
errorHandler: errorHandler2
|
|
17257
|
+
errorHandler: errorHandler2,
|
|
17258
|
+
enforceCanvasArgAllowlist
|
|
17000
17259
|
}) {
|
|
17001
17260
|
const ctx = target.getContext("2d");
|
|
17002
17261
|
if (!ctx) {
|
|
@@ -17006,7 +17265,11 @@ async function canvasMutation$1({
|
|
|
17006
17265
|
wrapCanvasContextDrawImage(ctx);
|
|
17007
17266
|
const mutationArgsPromises = mutations.map(
|
|
17008
17267
|
async (mutation) => {
|
|
17009
|
-
return Promise.all(
|
|
17268
|
+
return Promise.all(
|
|
17269
|
+
mutation.args.map(
|
|
17270
|
+
deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
|
|
17271
|
+
)
|
|
17272
|
+
);
|
|
17010
17273
|
}
|
|
17011
17274
|
);
|
|
17012
17275
|
const args = await Promise.all(mutationArgsPromises);
|
|
@@ -17036,7 +17299,8 @@ async function canvasMutation({
|
|
|
17036
17299
|
target,
|
|
17037
17300
|
imageMap,
|
|
17038
17301
|
canvasEventMap,
|
|
17039
|
-
errorHandler: errorHandler2
|
|
17302
|
+
errorHandler: errorHandler2,
|
|
17303
|
+
enforceCanvasArgAllowlist
|
|
17040
17304
|
}) {
|
|
17041
17305
|
try {
|
|
17042
17306
|
const precomputedMutation = canvasEventMap.get(event) || mutation;
|
|
@@ -17049,7 +17313,8 @@ async function canvasMutation({
|
|
|
17049
17313
|
type: mutation.type,
|
|
17050
17314
|
target,
|
|
17051
17315
|
imageMap,
|
|
17052
|
-
errorHandler: errorHandler2
|
|
17316
|
+
errorHandler: errorHandler2,
|
|
17317
|
+
enforceCanvasArgAllowlist
|
|
17053
17318
|
});
|
|
17054
17319
|
}
|
|
17055
17320
|
return;
|
|
@@ -17059,7 +17324,8 @@ async function canvasMutation({
|
|
|
17059
17324
|
mutations: commands,
|
|
17060
17325
|
target,
|
|
17061
17326
|
imageMap,
|
|
17062
|
-
errorHandler: errorHandler2
|
|
17327
|
+
errorHandler: errorHandler2,
|
|
17328
|
+
enforceCanvasArgAllowlist
|
|
17063
17329
|
});
|
|
17064
17330
|
} catch (error) {
|
|
17065
17331
|
errorHandler2(mutation, error);
|
|
@@ -17495,6 +17761,7 @@ class Replayer {
|
|
|
17495
17761
|
insertStyleRules: [],
|
|
17496
17762
|
triggerFocus: true,
|
|
17497
17763
|
UNSAFE_replayCanvas: false,
|
|
17764
|
+
enforceCanvasArgAllowlist: false,
|
|
17498
17765
|
pauseAnimation: true,
|
|
17499
17766
|
mouseTail: defaultMouseTailConfig,
|
|
17500
17767
|
useVirtualDom: true,
|
|
@@ -17523,7 +17790,8 @@ class Replayer {
|
|
|
17523
17790
|
target,
|
|
17524
17791
|
imageMap: this.imageMap,
|
|
17525
17792
|
canvasEventMap: this.canvasEventMap,
|
|
17526
|
-
errorHandler: this.warnCanvasMutationFailed.bind(this)
|
|
17793
|
+
errorHandler: this.warnCanvasMutationFailed.bind(this),
|
|
17794
|
+
enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
|
|
17527
17795
|
});
|
|
17528
17796
|
},
|
|
17529
17797
|
applyInput: this.applyInput.bind(this),
|
|
@@ -18235,7 +18503,14 @@ class Replayer {
|
|
|
18235
18503
|
const commands = await Promise.all(
|
|
18236
18504
|
data.commands.map(async (c2) => {
|
|
18237
18505
|
const args = await Promise.all(
|
|
18238
|
-
c2.args.map(
|
|
18506
|
+
c2.args.map(
|
|
18507
|
+
deserializeArg(
|
|
18508
|
+
this.imageMap,
|
|
18509
|
+
null,
|
|
18510
|
+
status,
|
|
18511
|
+
this.config.enforceCanvasArgAllowlist
|
|
18512
|
+
)
|
|
18513
|
+
)
|
|
18239
18514
|
);
|
|
18240
18515
|
return __spreadProps(__spreadValues({}, c2), { args });
|
|
18241
18516
|
})
|
|
@@ -18244,7 +18519,14 @@ class Replayer {
|
|
|
18244
18519
|
this.canvasEventMap.set(event, __spreadProps(__spreadValues({}, data), { commands }));
|
|
18245
18520
|
} else {
|
|
18246
18521
|
const args = await Promise.all(
|
|
18247
|
-
data.args.map(
|
|
18522
|
+
data.args.map(
|
|
18523
|
+
deserializeArg(
|
|
18524
|
+
this.imageMap,
|
|
18525
|
+
null,
|
|
18526
|
+
status,
|
|
18527
|
+
this.config.enforceCanvasArgAllowlist
|
|
18528
|
+
)
|
|
18529
|
+
)
|
|
18248
18530
|
);
|
|
18249
18531
|
if (status.isUnchanged === false)
|
|
18250
18532
|
this.canvasEventMap.set(event, __spreadProps(__spreadValues({}, data), { args }));
|
|
@@ -18457,7 +18739,8 @@ class Replayer {
|
|
|
18457
18739
|
target,
|
|
18458
18740
|
imageMap: this.imageMap,
|
|
18459
18741
|
canvasEventMap: this.canvasEventMap,
|
|
18460
|
-
errorHandler: this.warnCanvasMutationFailed.bind(this)
|
|
18742
|
+
errorHandler: this.warnCanvasMutationFailed.bind(this),
|
|
18743
|
+
enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
|
|
18461
18744
|
});
|
|
18462
18745
|
}
|
|
18463
18746
|
break;
|
|
@@ -19189,6 +19472,7 @@ const SERIALIZABLE_CONFIG_KEYS = [
|
|
|
19189
19472
|
"insertStyleRules",
|
|
19190
19473
|
"triggerFocus",
|
|
19191
19474
|
"UNSAFE_replayCanvas",
|
|
19475
|
+
"enforceCanvasArgAllowlist",
|
|
19192
19476
|
"cspContent",
|
|
19193
19477
|
"pauseAnimation",
|
|
19194
19478
|
"mouseTail",
|