@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/dist/rrweb.d.cts
CHANGED
|
@@ -54,13 +54,14 @@ declare type AppendedIframe = {
|
|
|
54
54
|
|
|
55
55
|
export declare function buildHostDocument(options: HostDocumentOptions): string;
|
|
56
56
|
|
|
57
|
-
export declare function canvasMutation({ event, mutation, target, imageMap, canvasEventMap, errorHandler, }: {
|
|
57
|
+
export declare function canvasMutation({ event, mutation, target, imageMap, canvasEventMap, errorHandler, enforceCanvasArgAllowlist, }: {
|
|
58
58
|
event: Parameters<Replayer['applyIncremental']>[0];
|
|
59
59
|
mutation: canvasMutationData;
|
|
60
60
|
target: HTMLCanvasElement;
|
|
61
61
|
imageMap: Replayer['imageMap'];
|
|
62
62
|
canvasEventMap: Replayer['canvasEventMap'];
|
|
63
63
|
errorHandler: Replayer['warnCanvasMutationFailed'];
|
|
64
|
+
enforceCanvasArgAllowlist?: boolean;
|
|
64
65
|
}): Promise<void>;
|
|
65
66
|
|
|
66
67
|
declare function closestElementOfNode(node: Node | null): HTMLElement | null;
|
|
@@ -302,6 +303,7 @@ export declare type playerConfig = {
|
|
|
302
303
|
insertStyleRules: string[];
|
|
303
304
|
triggerFocus: boolean;
|
|
304
305
|
UNSAFE_replayCanvas: boolean;
|
|
306
|
+
enforceCanvasArgAllowlist: boolean;
|
|
305
307
|
cspContent?: string;
|
|
306
308
|
pauseAnimation?: boolean;
|
|
307
309
|
mouseTail: boolean | {
|
|
@@ -405,6 +407,7 @@ export declare type recordOptions<T> = {
|
|
|
405
407
|
maskTextFn?: MaskTextFn;
|
|
406
408
|
slimDOMOptions?: SlimDOMOptions | 'all' | true;
|
|
407
409
|
ignoreCSSAttributes?: Set<string>;
|
|
410
|
+
styleSheetResyncInterval?: number;
|
|
408
411
|
inlineStylesheet?: boolean;
|
|
409
412
|
hooks?: hooksParam;
|
|
410
413
|
packFn?: PackFn;
|
|
@@ -550,7 +553,7 @@ export declare const RRWEB_EMBEDDED_CHANNEL: "rrweb-embedded";
|
|
|
550
553
|
|
|
551
554
|
export declare const RRWEB_EMBEDDED_PROTOCOL_VERSION: 1;
|
|
552
555
|
|
|
553
|
-
declare const SERIALIZABLE_CONFIG_KEYS: readonly ["speed", "maxSpeed", "loadTimeout", "skipInactive", "inactivePeriodThreshold", "showWarning", "showDebug", "blockClass", "liveMode", "insertStyleRules", "triggerFocus", "UNSAFE_replayCanvas", "cspContent", "pauseAnimation", "mouseTail", "useVirtualDom", "inactiveThreshold", "inactiveSkipTime"];
|
|
556
|
+
declare const SERIALIZABLE_CONFIG_KEYS: readonly ["speed", "maxSpeed", "loadTimeout", "skipInactive", "inactivePeriodThreshold", "showWarning", "showDebug", "blockClass", "liveMode", "insertStyleRules", "triggerFocus", "UNSAFE_replayCanvas", "enforceCanvasArgAllowlist", "cspContent", "pauseAnimation", "mouseTail", "useVirtualDom", "inactiveThreshold", "inactiveSkipTime"];
|
|
554
557
|
|
|
555
558
|
declare type SerializableConfigKey = (typeof SERIALIZABLE_CONFIG_KEYS)[number];
|
|
556
559
|
|
package/dist/rrweb.d.ts
CHANGED
|
@@ -54,13 +54,14 @@ declare type AppendedIframe = {
|
|
|
54
54
|
|
|
55
55
|
export declare function buildHostDocument(options: HostDocumentOptions): string;
|
|
56
56
|
|
|
57
|
-
export declare function canvasMutation({ event, mutation, target, imageMap, canvasEventMap, errorHandler, }: {
|
|
57
|
+
export declare function canvasMutation({ event, mutation, target, imageMap, canvasEventMap, errorHandler, enforceCanvasArgAllowlist, }: {
|
|
58
58
|
event: Parameters<Replayer['applyIncremental']>[0];
|
|
59
59
|
mutation: canvasMutationData;
|
|
60
60
|
target: HTMLCanvasElement;
|
|
61
61
|
imageMap: Replayer['imageMap'];
|
|
62
62
|
canvasEventMap: Replayer['canvasEventMap'];
|
|
63
63
|
errorHandler: Replayer['warnCanvasMutationFailed'];
|
|
64
|
+
enforceCanvasArgAllowlist?: boolean;
|
|
64
65
|
}): Promise<void>;
|
|
65
66
|
|
|
66
67
|
declare function closestElementOfNode(node: Node | null): HTMLElement | null;
|
|
@@ -302,6 +303,7 @@ export declare type playerConfig = {
|
|
|
302
303
|
insertStyleRules: string[];
|
|
303
304
|
triggerFocus: boolean;
|
|
304
305
|
UNSAFE_replayCanvas: boolean;
|
|
306
|
+
enforceCanvasArgAllowlist: boolean;
|
|
305
307
|
cspContent?: string;
|
|
306
308
|
pauseAnimation?: boolean;
|
|
307
309
|
mouseTail: boolean | {
|
|
@@ -405,6 +407,7 @@ export declare type recordOptions<T> = {
|
|
|
405
407
|
maskTextFn?: MaskTextFn;
|
|
406
408
|
slimDOMOptions?: SlimDOMOptions | 'all' | true;
|
|
407
409
|
ignoreCSSAttributes?: Set<string>;
|
|
410
|
+
styleSheetResyncInterval?: number;
|
|
408
411
|
inlineStylesheet?: boolean;
|
|
409
412
|
hooks?: hooksParam;
|
|
410
413
|
packFn?: PackFn;
|
|
@@ -550,7 +553,7 @@ export declare const RRWEB_EMBEDDED_CHANNEL: "rrweb-embedded";
|
|
|
550
553
|
|
|
551
554
|
export declare const RRWEB_EMBEDDED_PROTOCOL_VERSION: 1;
|
|
552
555
|
|
|
553
|
-
declare const SERIALIZABLE_CONFIG_KEYS: readonly ["speed", "maxSpeed", "loadTimeout", "skipInactive", "inactivePeriodThreshold", "showWarning", "showDebug", "blockClass", "liveMode", "insertStyleRules", "triggerFocus", "UNSAFE_replayCanvas", "cspContent", "pauseAnimation", "mouseTail", "useVirtualDom", "inactiveThreshold", "inactiveSkipTime"];
|
|
556
|
+
declare const SERIALIZABLE_CONFIG_KEYS: readonly ["speed", "maxSpeed", "loadTimeout", "skipInactive", "inactivePeriodThreshold", "showWarning", "showDebug", "blockClass", "liveMode", "insertStyleRules", "triggerFocus", "UNSAFE_replayCanvas", "enforceCanvasArgAllowlist", "cspContent", "pauseAnimation", "mouseTail", "useVirtualDom", "inactiveThreshold", "inactiveSkipTime"];
|
|
554
557
|
|
|
555
558
|
declare type SerializableConfigKey = (typeof SERIALIZABLE_CONFIG_KEYS)[number];
|
|
556
559
|
|
package/dist/rrweb.js
CHANGED
|
@@ -13672,66 +13672,142 @@ function getIdAndStyleId(sheet, mirror2, styleMirror) {
|
|
|
13672
13672
|
id
|
|
13673
13673
|
};
|
|
13674
13674
|
}
|
|
13675
|
-
function
|
|
13675
|
+
function restorePatchedMethod(target, key, ours, restoreTo) {
|
|
13676
|
+
if (target[key] === ours) {
|
|
13677
|
+
target[key] = restoreTo;
|
|
13678
|
+
}
|
|
13679
|
+
}
|
|
13680
|
+
const MAX_CSSOM_REPATCH_ATTEMPTS = 5;
|
|
13681
|
+
function initStyleSheetObserver({
|
|
13682
|
+
styleSheetRuleCb,
|
|
13683
|
+
mirror: mirror2,
|
|
13684
|
+
stylesheetManager,
|
|
13685
|
+
doc,
|
|
13686
|
+
styleSheetResyncInterval
|
|
13687
|
+
}, { win }) {
|
|
13676
13688
|
if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
|
|
13677
13689
|
return () => {
|
|
13678
13690
|
};
|
|
13679
13691
|
}
|
|
13680
|
-
const
|
|
13681
|
-
|
|
13692
|
+
const reportedRuleCounts = /* @__PURE__ */ new WeakMap();
|
|
13693
|
+
const unreconcilableSheets = /* @__PURE__ */ new WeakSet();
|
|
13694
|
+
let probing = false;
|
|
13695
|
+
let probeInsertObserved = false;
|
|
13696
|
+
let probeDeleteObserved = false;
|
|
13697
|
+
let probeSheet;
|
|
13698
|
+
let stopped = false;
|
|
13699
|
+
let insideInsertRule = false;
|
|
13700
|
+
let insideDeleteRule = false;
|
|
13701
|
+
const noteReportedRules = (sheet, delta) => {
|
|
13702
|
+
const state = reportedRuleCounts.get(sheet);
|
|
13703
|
+
if (state) {
|
|
13704
|
+
state.reported = Math.max(0, state.reported + delta);
|
|
13705
|
+
state.everSeen = Math.max(state.everSeen, state.reported);
|
|
13706
|
+
}
|
|
13707
|
+
};
|
|
13708
|
+
const patchInsertRule = (target) => new Proxy(target, {
|
|
13682
13709
|
apply: callbackWrapper(
|
|
13683
|
-
(
|
|
13710
|
+
(nativeFn, thisArg, argumentsList) => {
|
|
13711
|
+
if (probing) {
|
|
13712
|
+
probeInsertObserved = true;
|
|
13713
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13714
|
+
}
|
|
13715
|
+
if (stopped || insideInsertRule) {
|
|
13716
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13717
|
+
}
|
|
13684
13718
|
const [rule2, index2] = argumentsList;
|
|
13685
13719
|
const { id, styleId } = getIdAndStyleId(
|
|
13686
13720
|
thisArg,
|
|
13687
13721
|
mirror2,
|
|
13688
13722
|
stylesheetManager.styleMirror
|
|
13689
13723
|
);
|
|
13690
|
-
|
|
13724
|
+
const reported = id && id !== -1 || styleId && styleId !== -1;
|
|
13725
|
+
if (reported) {
|
|
13691
13726
|
styleSheetRuleCb({
|
|
13692
13727
|
id,
|
|
13693
13728
|
styleId,
|
|
13694
13729
|
adds: [{ rule: rule2, index: index2 }]
|
|
13695
13730
|
});
|
|
13696
13731
|
}
|
|
13697
|
-
|
|
13732
|
+
insideInsertRule = true;
|
|
13733
|
+
let result2;
|
|
13734
|
+
try {
|
|
13735
|
+
result2 = nativeFn.apply(thisArg, argumentsList);
|
|
13736
|
+
} finally {
|
|
13737
|
+
insideInsertRule = false;
|
|
13738
|
+
}
|
|
13739
|
+
if (reported) {
|
|
13740
|
+
noteReportedRules(thisArg, 1);
|
|
13741
|
+
}
|
|
13742
|
+
return result2;
|
|
13698
13743
|
}
|
|
13699
13744
|
)
|
|
13700
13745
|
});
|
|
13701
|
-
|
|
13702
|
-
const rule2 = `${selector} { ${styleBlock} }`;
|
|
13703
|
-
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
|
|
13704
|
-
};
|
|
13705
|
-
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
|
13706
|
-
win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
|
|
13746
|
+
const patchDeleteRule = (target) => new Proxy(target, {
|
|
13707
13747
|
apply: callbackWrapper(
|
|
13708
|
-
(
|
|
13748
|
+
(nativeFn, thisArg, argumentsList) => {
|
|
13749
|
+
if (probing) {
|
|
13750
|
+
probeDeleteObserved = true;
|
|
13751
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13752
|
+
}
|
|
13753
|
+
if (stopped || insideDeleteRule) {
|
|
13754
|
+
return nativeFn.apply(thisArg, argumentsList);
|
|
13755
|
+
}
|
|
13709
13756
|
const [index2] = argumentsList;
|
|
13710
13757
|
const { id, styleId } = getIdAndStyleId(
|
|
13711
13758
|
thisArg,
|
|
13712
13759
|
mirror2,
|
|
13713
13760
|
stylesheetManager.styleMirror
|
|
13714
13761
|
);
|
|
13715
|
-
|
|
13762
|
+
const reported = id && id !== -1 || styleId && styleId !== -1;
|
|
13763
|
+
if (reported) {
|
|
13716
13764
|
styleSheetRuleCb({
|
|
13717
13765
|
id,
|
|
13718
13766
|
styleId,
|
|
13719
13767
|
removes: [{ index: index2 }]
|
|
13720
13768
|
});
|
|
13721
13769
|
}
|
|
13722
|
-
|
|
13770
|
+
insideDeleteRule = true;
|
|
13771
|
+
let result2;
|
|
13772
|
+
try {
|
|
13773
|
+
result2 = nativeFn.apply(thisArg, argumentsList);
|
|
13774
|
+
} finally {
|
|
13775
|
+
insideDeleteRule = false;
|
|
13776
|
+
}
|
|
13777
|
+
if (reported) {
|
|
13778
|
+
noteReportedRules(thisArg, -1);
|
|
13779
|
+
}
|
|
13780
|
+
return result2;
|
|
13723
13781
|
}
|
|
13724
13782
|
)
|
|
13725
13783
|
});
|
|
13726
|
-
win.CSSStyleSheet.prototype.
|
|
13784
|
+
const insertRule = win.CSSStyleSheet.prototype.insertRule;
|
|
13785
|
+
let insertRuleProxy = patchInsertRule(insertRule);
|
|
13786
|
+
let restoreInsertRuleTo = insertRule;
|
|
13787
|
+
win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
|
|
13788
|
+
const addRule = win.CSSStyleSheet.prototype.addRule;
|
|
13789
|
+
const addRuleShim = function(selector, styleBlock, index2 = this.cssRules.length) {
|
|
13790
|
+
const rule2 = `${selector} { ${styleBlock} }`;
|
|
13791
|
+
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
|
|
13792
|
+
};
|
|
13793
|
+
win.CSSStyleSheet.prototype.addRule = addRuleShim;
|
|
13794
|
+
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
|
13795
|
+
let deleteRuleProxy = patchDeleteRule(deleteRule);
|
|
13796
|
+
let restoreDeleteRuleTo = deleteRule;
|
|
13797
|
+
win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
|
|
13798
|
+
const removeRule = win.CSSStyleSheet.prototype.removeRule;
|
|
13799
|
+
const removeRuleShim = function(index2) {
|
|
13727
13800
|
return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);
|
|
13728
13801
|
};
|
|
13802
|
+
win.CSSStyleSheet.prototype.removeRule = removeRuleShim;
|
|
13729
13803
|
let replace;
|
|
13804
|
+
let replaceProxy;
|
|
13730
13805
|
if (win.CSSStyleSheet.prototype.replace) {
|
|
13731
13806
|
replace = win.CSSStyleSheet.prototype.replace;
|
|
13732
|
-
|
|
13807
|
+
replaceProxy = new Proxy(replace, {
|
|
13733
13808
|
apply: callbackWrapper(
|
|
13734
13809
|
(target, thisArg, argumentsList) => {
|
|
13810
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13735
13811
|
const [text] = argumentsList;
|
|
13736
13812
|
const { id, styleId } = getIdAndStyleId(
|
|
13737
13813
|
thisArg,
|
|
@@ -13749,13 +13825,16 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13749
13825
|
}
|
|
13750
13826
|
)
|
|
13751
13827
|
});
|
|
13828
|
+
win.CSSStyleSheet.prototype.replace = replaceProxy;
|
|
13752
13829
|
}
|
|
13753
13830
|
let replaceSync;
|
|
13831
|
+
let replaceSyncProxy;
|
|
13754
13832
|
if (win.CSSStyleSheet.prototype.replaceSync) {
|
|
13755
13833
|
replaceSync = win.CSSStyleSheet.prototype.replaceSync;
|
|
13756
|
-
|
|
13834
|
+
replaceSyncProxy = new Proxy(replaceSync, {
|
|
13757
13835
|
apply: callbackWrapper(
|
|
13758
13836
|
(target, thisArg, argumentsList) => {
|
|
13837
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13759
13838
|
const [text] = argumentsList;
|
|
13760
13839
|
const { id, styleId } = getIdAndStyleId(
|
|
13761
13840
|
thisArg,
|
|
@@ -13773,6 +13852,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13773
13852
|
}
|
|
13774
13853
|
)
|
|
13775
13854
|
});
|
|
13855
|
+
win.CSSStyleSheet.prototype.replaceSync = replaceSyncProxy;
|
|
13776
13856
|
}
|
|
13777
13857
|
const supportedNestedCSSRuleTypes = {};
|
|
13778
13858
|
if (canMonkeyPatchNestedCSSRule("CSSGroupingRule")) {
|
|
@@ -13789,6 +13869,7 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13789
13869
|
}
|
|
13790
13870
|
}
|
|
13791
13871
|
const unmodifiedFunctions = {};
|
|
13872
|
+
const nestedProxies = {};
|
|
13792
13873
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
13793
13874
|
unmodifiedFunctions[typeKey] = {
|
|
13794
13875
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
@@ -13796,11 +13877,13 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13796
13877
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
13797
13878
|
deleteRule: type.prototype.deleteRule
|
|
13798
13879
|
};
|
|
13799
|
-
|
|
13880
|
+
nestedProxies[typeKey] = {};
|
|
13881
|
+
nestedProxies[typeKey].insertRule = new Proxy(
|
|
13800
13882
|
unmodifiedFunctions[typeKey].insertRule,
|
|
13801
13883
|
{
|
|
13802
13884
|
apply: callbackWrapper(
|
|
13803
13885
|
(target, thisArg, argumentsList) => {
|
|
13886
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13804
13887
|
const [rule2, index2] = argumentsList;
|
|
13805
13888
|
const { id, styleId } = getIdAndStyleId(
|
|
13806
13889
|
thisArg.parentStyleSheet,
|
|
@@ -13828,11 +13911,12 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13828
13911
|
)
|
|
13829
13912
|
}
|
|
13830
13913
|
);
|
|
13831
|
-
|
|
13914
|
+
nestedProxies[typeKey].deleteRule = new Proxy(
|
|
13832
13915
|
unmodifiedFunctions[typeKey].deleteRule,
|
|
13833
13916
|
{
|
|
13834
13917
|
apply: callbackWrapper(
|
|
13835
13918
|
(target, thisArg, argumentsList) => {
|
|
13919
|
+
if (stopped) return target.apply(thisArg, argumentsList);
|
|
13836
13920
|
const [index2] = argumentsList;
|
|
13837
13921
|
const { id, styleId } = getIdAndStyleId(
|
|
13838
13922
|
thisArg.parentStyleSheet,
|
|
@@ -13853,15 +13937,148 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
|
|
|
13853
13937
|
)
|
|
13854
13938
|
}
|
|
13855
13939
|
);
|
|
13940
|
+
type.prototype.insertRule = nestedProxies[typeKey].insertRule;
|
|
13941
|
+
type.prototype.deleteRule = nestedProxies[typeKey].deleteRule;
|
|
13856
13942
|
});
|
|
13943
|
+
const captureIsHealthy = () => {
|
|
13944
|
+
probing = true;
|
|
13945
|
+
probeInsertObserved = false;
|
|
13946
|
+
probeDeleteObserved = false;
|
|
13947
|
+
try {
|
|
13948
|
+
const probe = probeSheet ?? (probeSheet = new win.CSSStyleSheet());
|
|
13949
|
+
probe.insertRule(":root {}", 0);
|
|
13950
|
+
probe.deleteRule(0);
|
|
13951
|
+
} catch (error) {
|
|
13952
|
+
return {
|
|
13953
|
+
insertRule: win.CSSStyleSheet.prototype.insertRule === insertRuleProxy,
|
|
13954
|
+
deleteRule: win.CSSStyleSheet.prototype.deleteRule === deleteRuleProxy
|
|
13955
|
+
};
|
|
13956
|
+
} finally {
|
|
13957
|
+
probing = false;
|
|
13958
|
+
}
|
|
13959
|
+
return {
|
|
13960
|
+
insertRule: probeInsertObserved,
|
|
13961
|
+
deleteRule: probeDeleteObserved
|
|
13962
|
+
};
|
|
13963
|
+
};
|
|
13964
|
+
let repatchAttempts = 0;
|
|
13965
|
+
const repatch = (health) => {
|
|
13966
|
+
if (repatchAttempts >= MAX_CSSOM_REPATCH_ATTEMPTS) return;
|
|
13967
|
+
repatchAttempts += 1;
|
|
13968
|
+
if (!health.insertRule) {
|
|
13969
|
+
restoreInsertRuleTo = win.CSSStyleSheet.prototype.insertRule;
|
|
13970
|
+
insertRuleProxy = patchInsertRule(restoreInsertRuleTo);
|
|
13971
|
+
win.CSSStyleSheet.prototype.insertRule = insertRuleProxy;
|
|
13972
|
+
}
|
|
13973
|
+
if (!health.deleteRule) {
|
|
13974
|
+
restoreDeleteRuleTo = win.CSSStyleSheet.prototype.deleteRule;
|
|
13975
|
+
deleteRuleProxy = patchDeleteRule(restoreDeleteRuleTo);
|
|
13976
|
+
win.CSSStyleSheet.prototype.deleteRule = deleteRuleProxy;
|
|
13977
|
+
}
|
|
13978
|
+
};
|
|
13979
|
+
const resyncCssomStyleSheets = (trusted) => {
|
|
13980
|
+
for (let i2 = 0; i2 < doc.styleSheets.length; i2++) {
|
|
13981
|
+
const sheet = doc.styleSheets[i2];
|
|
13982
|
+
if (unreconcilableSheets.has(sheet)) continue;
|
|
13983
|
+
const owner = sheet.ownerNode;
|
|
13984
|
+
if (!owner || toLowerCase(owner.nodeName) !== "style") continue;
|
|
13985
|
+
if ((owner.textContent || "").trim().length) continue;
|
|
13986
|
+
const id = mirror2.getId(owner);
|
|
13987
|
+
if (!id || id === -1) continue;
|
|
13988
|
+
let rules2;
|
|
13989
|
+
try {
|
|
13990
|
+
rules2 = sheet.cssRules;
|
|
13991
|
+
} catch (error) {
|
|
13992
|
+
continue;
|
|
13993
|
+
}
|
|
13994
|
+
const live = rules2.length;
|
|
13995
|
+
let state = reportedRuleCounts.get(sheet);
|
|
13996
|
+
if (!state) {
|
|
13997
|
+
if (Array.from(rules2).some((rule2) => isCSSImportRule(rule2))) {
|
|
13998
|
+
unreconcilableSheets.add(sheet);
|
|
13999
|
+
continue;
|
|
14000
|
+
}
|
|
14001
|
+
state = { reported: live, everSeen: live };
|
|
14002
|
+
reportedRuleCounts.set(sheet, state);
|
|
14003
|
+
if (trusted) continue;
|
|
14004
|
+
replaceReplayerCopy(id, state, rules2);
|
|
14005
|
+
continue;
|
|
14006
|
+
}
|
|
14007
|
+
state.everSeen = Math.max(state.everSeen, live);
|
|
14008
|
+
if (live === state.reported) continue;
|
|
14009
|
+
if (live > state.reported) {
|
|
14010
|
+
const adds = [];
|
|
14011
|
+
for (let index2 = state.reported; index2 < live; index2++) {
|
|
14012
|
+
adds.push({ rule: rules2[index2].cssText, index: index2 });
|
|
14013
|
+
}
|
|
14014
|
+
styleSheetRuleCb({ id, adds });
|
|
14015
|
+
state.reported = live;
|
|
14016
|
+
} else {
|
|
14017
|
+
replaceReplayerCopy(id, state, rules2);
|
|
14018
|
+
}
|
|
14019
|
+
}
|
|
14020
|
+
};
|
|
14021
|
+
function replaceReplayerCopy(id, state, rules2) {
|
|
14022
|
+
const removes = [];
|
|
14023
|
+
for (let index2 = state.everSeen - 1; index2 >= 0; index2--) {
|
|
14024
|
+
removes.push({ index: index2 });
|
|
14025
|
+
}
|
|
14026
|
+
if (removes.length) styleSheetRuleCb({ id, removes });
|
|
14027
|
+
styleSheetRuleCb({
|
|
14028
|
+
id,
|
|
14029
|
+
adds: Array.from(rules2, (rule2, index2) => ({
|
|
14030
|
+
rule: rule2.cssText,
|
|
14031
|
+
index: index2
|
|
14032
|
+
}))
|
|
14033
|
+
});
|
|
14034
|
+
state.reported = rules2.length;
|
|
14035
|
+
state.everSeen = rules2.length;
|
|
14036
|
+
}
|
|
14037
|
+
let resyncTimer;
|
|
14038
|
+
if (styleSheetResyncInterval > 0) {
|
|
14039
|
+
resyncTimer = win.setInterval(
|
|
14040
|
+
callbackWrapper(() => {
|
|
14041
|
+
const health = captureIsHealthy();
|
|
14042
|
+
const healthy = health.insertRule && health.deleteRule;
|
|
14043
|
+
if (!healthy) repatch(health);
|
|
14044
|
+
resyncCssomStyleSheets(healthy);
|
|
14045
|
+
}),
|
|
14046
|
+
styleSheetResyncInterval
|
|
14047
|
+
);
|
|
14048
|
+
}
|
|
13857
14049
|
return callbackWrapper(() => {
|
|
13858
|
-
win.
|
|
13859
|
-
|
|
13860
|
-
|
|
13861
|
-
|
|
14050
|
+
if (resyncTimer !== void 0) win.clearInterval(resyncTimer);
|
|
14051
|
+
stopped = true;
|
|
14052
|
+
const proto = win.CSSStyleSheet.prototype;
|
|
14053
|
+
restorePatchedMethod(
|
|
14054
|
+
proto,
|
|
14055
|
+
"insertRule",
|
|
14056
|
+
insertRuleProxy,
|
|
14057
|
+
restoreInsertRuleTo
|
|
14058
|
+
);
|
|
14059
|
+
restorePatchedMethod(
|
|
14060
|
+
proto,
|
|
14061
|
+
"deleteRule",
|
|
14062
|
+
deleteRuleProxy,
|
|
14063
|
+
restoreDeleteRuleTo
|
|
14064
|
+
);
|
|
14065
|
+
restorePatchedMethod(proto, "addRule", addRuleShim, addRule);
|
|
14066
|
+
restorePatchedMethod(proto, "removeRule", removeRuleShim, removeRule);
|
|
14067
|
+
replaceProxy && restorePatchedMethod(proto, "replace", replaceProxy, replace);
|
|
14068
|
+
replaceSyncProxy && restorePatchedMethod(proto, "replaceSync", replaceSyncProxy, replaceSync);
|
|
13862
14069
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
13863
|
-
|
|
13864
|
-
|
|
14070
|
+
restorePatchedMethod(
|
|
14071
|
+
type.prototype,
|
|
14072
|
+
"insertRule",
|
|
14073
|
+
nestedProxies[typeKey].insertRule,
|
|
14074
|
+
unmodifiedFunctions[typeKey].insertRule
|
|
14075
|
+
);
|
|
14076
|
+
restorePatchedMethod(
|
|
14077
|
+
type.prototype,
|
|
14078
|
+
"deleteRule",
|
|
14079
|
+
nestedProxies[typeKey].deleteRule,
|
|
14080
|
+
unmodifiedFunctions[typeKey].deleteRule
|
|
14081
|
+
);
|
|
13865
14082
|
});
|
|
13866
14083
|
});
|
|
13867
14084
|
}
|
|
@@ -15629,6 +15846,7 @@ function record(options = {}) {
|
|
|
15629
15846
|
keepIframeSrcFn = () => false,
|
|
15630
15847
|
privacySetting = "default",
|
|
15631
15848
|
ignoreCSSAttributes = /* @__PURE__ */ new Set([]),
|
|
15849
|
+
styleSheetResyncInterval = 2e3,
|
|
15632
15850
|
errorHandler: errorHandler2,
|
|
15633
15851
|
logger
|
|
15634
15852
|
} = options;
|
|
@@ -16007,6 +16225,7 @@ function record(options = {}) {
|
|
|
16007
16225
|
processedNodeManager,
|
|
16008
16226
|
canvasManager,
|
|
16009
16227
|
ignoreCSSAttributes,
|
|
16228
|
+
styleSheetResyncInterval,
|
|
16010
16229
|
privacySetting,
|
|
16011
16230
|
plugins: ((_a3 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a3.map((p) => ({
|
|
16012
16231
|
observer: p.observer,
|
|
@@ -16893,12 +17112,36 @@ function variableListFor(ctx, ctor) {
|
|
|
16893
17112
|
}
|
|
16894
17113
|
return contextMap.get(ctor);
|
|
16895
17114
|
}
|
|
16896
|
-
|
|
17115
|
+
const canvasArgConstructors = /* @__PURE__ */ new Set([
|
|
17116
|
+
"Int8Array",
|
|
17117
|
+
"Int16Array",
|
|
17118
|
+
"Int32Array",
|
|
17119
|
+
"Uint8Array",
|
|
17120
|
+
"Uint8ClampedArray",
|
|
17121
|
+
"Uint16Array",
|
|
17122
|
+
"Uint32Array",
|
|
17123
|
+
"Float32Array",
|
|
17124
|
+
"Float64Array",
|
|
17125
|
+
"DataView",
|
|
17126
|
+
"ImageData",
|
|
17127
|
+
// normally serialized as base64, but reachable in `args` form through
|
|
17128
|
+
// recordings made by older clients and through nested `DataView` args.
|
|
17129
|
+
"ArrayBuffer",
|
|
17130
|
+
// wraps nested args in recordings made by older clients — see the
|
|
17131
|
+
// `preloadAllImages` tests for the shape.
|
|
17132
|
+
"Array"
|
|
17133
|
+
]);
|
|
17134
|
+
function deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist = false) {
|
|
16897
17135
|
return async (arg) => {
|
|
16898
17136
|
if (arg && typeof arg === "object" && "rr_type" in arg) {
|
|
16899
17137
|
if (preload) preload.isUnchanged = false;
|
|
16900
17138
|
if (arg.rr_type === "ImageBitmap" && "args" in arg) {
|
|
16901
|
-
const args = await deserializeArg(
|
|
17139
|
+
const args = await deserializeArg(
|
|
17140
|
+
imageMap,
|
|
17141
|
+
ctx,
|
|
17142
|
+
preload,
|
|
17143
|
+
enforceCanvasArgAllowlist
|
|
17144
|
+
)(arg.args);
|
|
16902
17145
|
return await createImageBitmap.apply(null, args);
|
|
16903
17146
|
} else if ("index" in arg) {
|
|
16904
17147
|
if (preload || ctx === null) return arg;
|
|
@@ -16906,10 +17149,18 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16906
17149
|
return variableListFor(ctx, name)[index2];
|
|
16907
17150
|
} else if ("args" in arg) {
|
|
16908
17151
|
const { rr_type: name, args } = arg;
|
|
17152
|
+
if (enforceCanvasArgAllowlist && !canvasArgConstructors.has(name)) {
|
|
17153
|
+
console.warn(
|
|
17154
|
+
`[replayer] refusing to construct canvas arg of unknown type: ${name}`
|
|
17155
|
+
);
|
|
17156
|
+
return null;
|
|
17157
|
+
}
|
|
16909
17158
|
const ctor = window[name];
|
|
16910
17159
|
return new ctor(
|
|
16911
17160
|
...await Promise.all(
|
|
16912
|
-
args.map(
|
|
17161
|
+
args.map(
|
|
17162
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17163
|
+
)
|
|
16913
17164
|
)
|
|
16914
17165
|
);
|
|
16915
17166
|
} else if ("base64" in arg) {
|
|
@@ -16926,7 +17177,9 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16926
17177
|
}
|
|
16927
17178
|
} else if ("data" in arg && arg.rr_type === "Blob") {
|
|
16928
17179
|
const blobContents = await Promise.all(
|
|
16929
|
-
arg.data.map(
|
|
17180
|
+
arg.data.map(
|
|
17181
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17182
|
+
)
|
|
16930
17183
|
);
|
|
16931
17184
|
const blob2 = new Blob(blobContents, {
|
|
16932
17185
|
type: arg.type
|
|
@@ -16935,7 +17188,9 @@ function deserializeArg(imageMap, ctx, preload) {
|
|
|
16935
17188
|
}
|
|
16936
17189
|
} else if (Array.isArray(arg)) {
|
|
16937
17190
|
const result2 = await Promise.all(
|
|
16938
|
-
arg.map(
|
|
17191
|
+
arg.map(
|
|
17192
|
+
deserializeArg(imageMap, ctx, preload, enforceCanvasArgAllowlist)
|
|
17193
|
+
)
|
|
16939
17194
|
);
|
|
16940
17195
|
return result2;
|
|
16941
17196
|
}
|
|
@@ -16976,7 +17231,8 @@ async function webglMutation({
|
|
|
16976
17231
|
target,
|
|
16977
17232
|
type,
|
|
16978
17233
|
imageMap,
|
|
16979
|
-
errorHandler: errorHandler2
|
|
17234
|
+
errorHandler: errorHandler2,
|
|
17235
|
+
enforceCanvasArgAllowlist
|
|
16980
17236
|
}) {
|
|
16981
17237
|
try {
|
|
16982
17238
|
const ctx = getContext(target, type);
|
|
@@ -16987,7 +17243,9 @@ async function webglMutation({
|
|
|
16987
17243
|
}
|
|
16988
17244
|
const original = ctx[mutation.property];
|
|
16989
17245
|
const args = await Promise.all(
|
|
16990
|
-
mutation.args.map(
|
|
17246
|
+
mutation.args.map(
|
|
17247
|
+
deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
|
|
17248
|
+
)
|
|
16991
17249
|
);
|
|
16992
17250
|
const result2 = original.apply(ctx, args);
|
|
16993
17251
|
saveToWebGLVarMap(ctx, result2);
|
|
@@ -17002,7 +17260,8 @@ async function canvasMutation$1({
|
|
|
17002
17260
|
mutations,
|
|
17003
17261
|
target,
|
|
17004
17262
|
imageMap,
|
|
17005
|
-
errorHandler: errorHandler2
|
|
17263
|
+
errorHandler: errorHandler2,
|
|
17264
|
+
enforceCanvasArgAllowlist
|
|
17006
17265
|
}) {
|
|
17007
17266
|
const ctx = target.getContext("2d");
|
|
17008
17267
|
if (!ctx) {
|
|
@@ -17012,7 +17271,11 @@ async function canvasMutation$1({
|
|
|
17012
17271
|
wrapCanvasContextDrawImage(ctx);
|
|
17013
17272
|
const mutationArgsPromises = mutations.map(
|
|
17014
17273
|
async (mutation) => {
|
|
17015
|
-
return Promise.all(
|
|
17274
|
+
return Promise.all(
|
|
17275
|
+
mutation.args.map(
|
|
17276
|
+
deserializeArg(imageMap, ctx, void 0, enforceCanvasArgAllowlist)
|
|
17277
|
+
)
|
|
17278
|
+
);
|
|
17016
17279
|
}
|
|
17017
17280
|
);
|
|
17018
17281
|
const args = await Promise.all(mutationArgsPromises);
|
|
@@ -17042,7 +17305,8 @@ async function canvasMutation({
|
|
|
17042
17305
|
target,
|
|
17043
17306
|
imageMap,
|
|
17044
17307
|
canvasEventMap,
|
|
17045
|
-
errorHandler: errorHandler2
|
|
17308
|
+
errorHandler: errorHandler2,
|
|
17309
|
+
enforceCanvasArgAllowlist
|
|
17046
17310
|
}) {
|
|
17047
17311
|
try {
|
|
17048
17312
|
const precomputedMutation = canvasEventMap.get(event) || mutation;
|
|
@@ -17055,7 +17319,8 @@ async function canvasMutation({
|
|
|
17055
17319
|
type: mutation.type,
|
|
17056
17320
|
target,
|
|
17057
17321
|
imageMap,
|
|
17058
|
-
errorHandler: errorHandler2
|
|
17322
|
+
errorHandler: errorHandler2,
|
|
17323
|
+
enforceCanvasArgAllowlist
|
|
17059
17324
|
});
|
|
17060
17325
|
}
|
|
17061
17326
|
return;
|
|
@@ -17065,7 +17330,8 @@ async function canvasMutation({
|
|
|
17065
17330
|
mutations: commands,
|
|
17066
17331
|
target,
|
|
17067
17332
|
imageMap,
|
|
17068
|
-
errorHandler: errorHandler2
|
|
17333
|
+
errorHandler: errorHandler2,
|
|
17334
|
+
enforceCanvasArgAllowlist
|
|
17069
17335
|
});
|
|
17070
17336
|
} catch (error) {
|
|
17071
17337
|
errorHandler2(mutation, error);
|
|
@@ -17508,6 +17774,7 @@ class Replayer {
|
|
|
17508
17774
|
insertStyleRules: [],
|
|
17509
17775
|
triggerFocus: true,
|
|
17510
17776
|
UNSAFE_replayCanvas: false,
|
|
17777
|
+
enforceCanvasArgAllowlist: false,
|
|
17511
17778
|
pauseAnimation: true,
|
|
17512
17779
|
mouseTail: defaultMouseTailConfig,
|
|
17513
17780
|
useVirtualDom: true,
|
|
@@ -17536,7 +17803,8 @@ class Replayer {
|
|
|
17536
17803
|
target,
|
|
17537
17804
|
imageMap: this.imageMap,
|
|
17538
17805
|
canvasEventMap: this.canvasEventMap,
|
|
17539
|
-
errorHandler: this.warnCanvasMutationFailed.bind(this)
|
|
17806
|
+
errorHandler: this.warnCanvasMutationFailed.bind(this),
|
|
17807
|
+
enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
|
|
17540
17808
|
});
|
|
17541
17809
|
},
|
|
17542
17810
|
applyInput: this.applyInput.bind(this),
|
|
@@ -18248,7 +18516,14 @@ class Replayer {
|
|
|
18248
18516
|
const commands = await Promise.all(
|
|
18249
18517
|
data.commands.map(async (c2) => {
|
|
18250
18518
|
const args = await Promise.all(
|
|
18251
|
-
c2.args.map(
|
|
18519
|
+
c2.args.map(
|
|
18520
|
+
deserializeArg(
|
|
18521
|
+
this.imageMap,
|
|
18522
|
+
null,
|
|
18523
|
+
status,
|
|
18524
|
+
this.config.enforceCanvasArgAllowlist
|
|
18525
|
+
)
|
|
18526
|
+
)
|
|
18252
18527
|
);
|
|
18253
18528
|
return { ...c2, args };
|
|
18254
18529
|
})
|
|
@@ -18257,7 +18532,14 @@ class Replayer {
|
|
|
18257
18532
|
this.canvasEventMap.set(event, { ...data, commands });
|
|
18258
18533
|
} else {
|
|
18259
18534
|
const args = await Promise.all(
|
|
18260
|
-
data.args.map(
|
|
18535
|
+
data.args.map(
|
|
18536
|
+
deserializeArg(
|
|
18537
|
+
this.imageMap,
|
|
18538
|
+
null,
|
|
18539
|
+
status,
|
|
18540
|
+
this.config.enforceCanvasArgAllowlist
|
|
18541
|
+
)
|
|
18542
|
+
)
|
|
18261
18543
|
);
|
|
18262
18544
|
if (status.isUnchanged === false)
|
|
18263
18545
|
this.canvasEventMap.set(event, { ...data, args });
|
|
@@ -18470,7 +18752,8 @@ class Replayer {
|
|
|
18470
18752
|
target,
|
|
18471
18753
|
imageMap: this.imageMap,
|
|
18472
18754
|
canvasEventMap: this.canvasEventMap,
|
|
18473
|
-
errorHandler: this.warnCanvasMutationFailed.bind(this)
|
|
18755
|
+
errorHandler: this.warnCanvasMutationFailed.bind(this),
|
|
18756
|
+
enforceCanvasArgAllowlist: this.config.enforceCanvasArgAllowlist
|
|
18474
18757
|
});
|
|
18475
18758
|
}
|
|
18476
18759
|
break;
|
|
@@ -19208,6 +19491,7 @@ const SERIALIZABLE_CONFIG_KEYS = [
|
|
|
19208
19491
|
"insertStyleRules",
|
|
19209
19492
|
"triggerFocus",
|
|
19210
19493
|
"UNSAFE_replayCanvas",
|
|
19494
|
+
"enforceCanvasArgAllowlist",
|
|
19211
19495
|
"cspContent",
|
|
19212
19496
|
"pauseAnimation",
|
|
19213
19497
|
"mouseTail",
|