@openreplay/tracker 16.2.1 → 16.3.0-beta.0
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/cjs/entry.js +130 -39
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +130 -39
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/index.d.ts +2 -0
- package/dist/cjs/main/modules/cssrules.d.ts +15 -1
- package/dist/lib/entry.js +130 -39
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +130 -39
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/index.d.ts +2 -0
- package/dist/lib/main/modules/cssrules.d.ts +15 -1
- package/dist/types/main/index.d.ts +2 -0
- package/dist/types/main/modules/cssrules.d.ts +15 -1
- package/package.json +1 -1
package/dist/cjs/entry.js
CHANGED
|
@@ -3564,7 +3564,7 @@ function isNodeStillActive(node) {
|
|
|
3564
3564
|
return [false, e];
|
|
3565
3565
|
}
|
|
3566
3566
|
}
|
|
3567
|
-
const defaults = {
|
|
3567
|
+
const defaults$1 = {
|
|
3568
3568
|
interval: SECOND * 30,
|
|
3569
3569
|
batchSize: 2500,
|
|
3570
3570
|
enabled: true,
|
|
@@ -3592,7 +3592,7 @@ class Maintainer {
|
|
|
3592
3592
|
clearInterval(this.interval);
|
|
3593
3593
|
}
|
|
3594
3594
|
};
|
|
3595
|
-
this.options = { ...defaults, ...options };
|
|
3595
|
+
this.options = { ...defaults$1, ...options };
|
|
3596
3596
|
}
|
|
3597
3597
|
}
|
|
3598
3598
|
|
|
@@ -5206,7 +5206,7 @@ class App {
|
|
|
5206
5206
|
this.stopCallbacks = [];
|
|
5207
5207
|
this.commitCallbacks = [];
|
|
5208
5208
|
this.activityState = ActivityState.NotActive;
|
|
5209
|
-
this.version = '16.
|
|
5209
|
+
this.version = '16.3.0-beta.0'; // TODO: version compatability check inside each plugin.
|
|
5210
5210
|
this.socketMode = false;
|
|
5211
5211
|
this.compressionThreshold = 24 * 1000;
|
|
5212
5212
|
this.bc = null;
|
|
@@ -8041,60 +8041,137 @@ function Viewport (app) {
|
|
|
8041
8041
|
app.ticker.attach(sendSetViewportSize, 5, false);
|
|
8042
8042
|
}
|
|
8043
8043
|
|
|
8044
|
-
|
|
8045
|
-
|
|
8044
|
+
const defaults = {
|
|
8045
|
+
checkCssInterval: 200,
|
|
8046
|
+
scanInMemoryCSS: false,
|
|
8047
|
+
checkLimit: undefined,
|
|
8048
|
+
};
|
|
8049
|
+
function CSSRules (app, opts) {
|
|
8050
|
+
if (app === null)
|
|
8046
8051
|
return;
|
|
8047
|
-
}
|
|
8048
8052
|
if (!window.CSSStyleSheet) {
|
|
8049
8053
|
app.send(TechnicalInfo('no_stylesheet_prototype_in_window', ''));
|
|
8050
8054
|
return;
|
|
8051
8055
|
}
|
|
8056
|
+
const options = { ...defaults, ...opts };
|
|
8057
|
+
// sheetID:index -> ruleText
|
|
8058
|
+
const ruleSnapshots = new Map();
|
|
8059
|
+
let checkInterval = null;
|
|
8060
|
+
const trackedSheets = new Set();
|
|
8061
|
+
const checkIntervalMs = options.checkCssInterval || 200;
|
|
8062
|
+
let checkIterations = {};
|
|
8063
|
+
function checkRuleChanges() {
|
|
8064
|
+
if (!options.scanInMemoryCSS)
|
|
8065
|
+
return;
|
|
8066
|
+
const allSheets = trackedSheets.values();
|
|
8067
|
+
for (const sheet of allSheets) {
|
|
8068
|
+
try {
|
|
8069
|
+
const sheetID = styleSheetIDMap.get(sheet);
|
|
8070
|
+
if (!sheetID)
|
|
8071
|
+
continue;
|
|
8072
|
+
if (options.checkLimit) {
|
|
8073
|
+
if (!checkIterations[sheetID]) {
|
|
8074
|
+
checkIterations[sheetID] = 0;
|
|
8075
|
+
}
|
|
8076
|
+
else {
|
|
8077
|
+
checkIterations[sheetID]++;
|
|
8078
|
+
}
|
|
8079
|
+
if (checkIterations[sheetID] > options.checkLimit) {
|
|
8080
|
+
trackedSheets.delete(sheet);
|
|
8081
|
+
return;
|
|
8082
|
+
}
|
|
8083
|
+
}
|
|
8084
|
+
for (let j = 0; j < sheet.cssRules.length; j++) {
|
|
8085
|
+
try {
|
|
8086
|
+
const rule = sheet.cssRules[j];
|
|
8087
|
+
const key = `${sheetID}:${j}`;
|
|
8088
|
+
const oldText = ruleSnapshots.get(key);
|
|
8089
|
+
const newText = rule.cssText;
|
|
8090
|
+
if (oldText !== newText) {
|
|
8091
|
+
if (oldText !== undefined) {
|
|
8092
|
+
// Rule is changed
|
|
8093
|
+
app.send(AdoptedSSDeleteRule(sheetID, j));
|
|
8094
|
+
app.send(AdoptedSSInsertRuleURLBased(sheetID, newText, j, app.getBaseHref()));
|
|
8095
|
+
}
|
|
8096
|
+
else {
|
|
8097
|
+
// Rule added
|
|
8098
|
+
app.send(AdoptedSSInsertRuleURLBased(sheetID, newText, j, app.getBaseHref()));
|
|
8099
|
+
}
|
|
8100
|
+
ruleSnapshots.set(key, newText);
|
|
8101
|
+
}
|
|
8102
|
+
}
|
|
8103
|
+
catch (e) {
|
|
8104
|
+
/* Skip inaccessible rules */
|
|
8105
|
+
}
|
|
8106
|
+
}
|
|
8107
|
+
const keysToCheck = Array.from(ruleSnapshots.keys()).filter((key) => key.startsWith(`${sheetID}:`));
|
|
8108
|
+
for (const key of keysToCheck) {
|
|
8109
|
+
const index = parseInt(key.split(':')[1], 10);
|
|
8110
|
+
if (index >= sheet.cssRules.length) {
|
|
8111
|
+
ruleSnapshots.delete(key);
|
|
8112
|
+
}
|
|
8113
|
+
}
|
|
8114
|
+
}
|
|
8115
|
+
catch (e) {
|
|
8116
|
+
/* Skip inaccessible sheets */
|
|
8117
|
+
trackedSheets.delete(sheet);
|
|
8118
|
+
}
|
|
8119
|
+
}
|
|
8120
|
+
}
|
|
8121
|
+
const emptyRuleReg = /{\s*}/;
|
|
8122
|
+
function isRuleEmpty(rule) {
|
|
8123
|
+
return emptyRuleReg.test(rule);
|
|
8124
|
+
}
|
|
8052
8125
|
const sendInsertDeleteRule = app.safe((sheet, index, rule) => {
|
|
8053
8126
|
const sheetID = styleSheetIDMap.get(sheet);
|
|
8054
|
-
if (!sheetID)
|
|
8055
|
-
// OK-case. Sheet haven't been registered yet. Rules will be sent on registration.
|
|
8127
|
+
if (!sheetID)
|
|
8056
8128
|
return;
|
|
8057
|
-
}
|
|
8058
8129
|
if (typeof rule === 'string') {
|
|
8059
8130
|
app.send(AdoptedSSInsertRuleURLBased(sheetID, rule, index, app.getBaseHref()));
|
|
8131
|
+
if (isRuleEmpty(rule)) {
|
|
8132
|
+
ruleSnapshots.set(`${sheetID}:${index}`, rule);
|
|
8133
|
+
trackedSheets.add(sheet);
|
|
8134
|
+
}
|
|
8060
8135
|
}
|
|
8061
8136
|
else {
|
|
8062
8137
|
app.send(AdoptedSSDeleteRule(sheetID, index));
|
|
8138
|
+
if (ruleSnapshots.has(`${sheetID}:${index}`)) {
|
|
8139
|
+
ruleSnapshots.delete(`${sheetID}:${index}`);
|
|
8140
|
+
}
|
|
8063
8141
|
}
|
|
8064
8142
|
});
|
|
8065
|
-
// TODO: proper rule insertion/removal (how?)
|
|
8066
8143
|
const sendReplaceGroupingRule = app.safe((rule) => {
|
|
8067
8144
|
let topmostRule = rule;
|
|
8068
|
-
while (topmostRule.parentRule)
|
|
8145
|
+
while (topmostRule.parentRule)
|
|
8069
8146
|
topmostRule = topmostRule.parentRule;
|
|
8070
|
-
}
|
|
8071
8147
|
const sheet = topmostRule.parentStyleSheet;
|
|
8072
|
-
if (!sheet)
|
|
8073
|
-
app.debug.warn('No parent StyleSheet found for', topmostRule, rule);
|
|
8148
|
+
if (!sheet)
|
|
8074
8149
|
return;
|
|
8075
|
-
}
|
|
8076
8150
|
const sheetID = styleSheetIDMap.get(sheet);
|
|
8077
|
-
if (!sheetID)
|
|
8078
|
-
app.debug.warn('No sheedID found for', sheet, styleSheetIDMap);
|
|
8151
|
+
if (!sheetID)
|
|
8079
8152
|
return;
|
|
8080
|
-
}
|
|
8081
8153
|
const cssText = topmostRule.cssText;
|
|
8082
|
-
const
|
|
8083
|
-
const idx = Array.from(ruleList).indexOf(topmostRule);
|
|
8154
|
+
const idx = Array.from(sheet.cssRules).indexOf(topmostRule);
|
|
8084
8155
|
if (idx >= 0) {
|
|
8085
8156
|
app.send(AdoptedSSInsertRuleURLBased(sheetID, cssText, idx, app.getBaseHref()));
|
|
8086
|
-
app.send(AdoptedSSDeleteRule(sheetID, idx + 1));
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8157
|
+
app.send(AdoptedSSDeleteRule(sheetID, idx + 1));
|
|
8158
|
+
if (isRuleEmpty(cssText)) {
|
|
8159
|
+
ruleSnapshots.set(`${sheetID}:${idx}`, cssText);
|
|
8160
|
+
trackedSheets.add(sheet);
|
|
8161
|
+
}
|
|
8090
8162
|
}
|
|
8091
8163
|
});
|
|
8164
|
+
// Patch prototype methods
|
|
8092
8165
|
const patchContext = app.safe((context) => {
|
|
8166
|
+
if (context.__css_tracking_patched__)
|
|
8167
|
+
return;
|
|
8168
|
+
context.__css_tracking_patched__ = true;
|
|
8093
8169
|
const { insertRule, deleteRule } = context.CSSStyleSheet.prototype;
|
|
8094
8170
|
const { insertRule: groupInsertRule, deleteRule: groupDeleteRule } = context.CSSGroupingRule.prototype;
|
|
8095
8171
|
context.CSSStyleSheet.prototype.insertRule = function (rule, index = 0) {
|
|
8096
|
-
|
|
8097
|
-
|
|
8172
|
+
const result = insertRule.call(this, rule, index);
|
|
8173
|
+
sendInsertDeleteRule(this, result, rule);
|
|
8174
|
+
return result;
|
|
8098
8175
|
};
|
|
8099
8176
|
context.CSSStyleSheet.prototype.deleteRule = function (index) {
|
|
8100
8177
|
sendInsertDeleteRule(this, index);
|
|
@@ -8105,7 +8182,7 @@ function CSSRules (app) {
|
|
|
8105
8182
|
sendReplaceGroupingRule(this);
|
|
8106
8183
|
return result;
|
|
8107
8184
|
};
|
|
8108
|
-
context.CSSGroupingRule.prototype.deleteRule = function (index
|
|
8185
|
+
context.CSSGroupingRule.prototype.deleteRule = function (index) {
|
|
8109
8186
|
const result = groupDeleteRule.call(this, index);
|
|
8110
8187
|
sendReplaceGroupingRule(this);
|
|
8111
8188
|
return result;
|
|
@@ -8114,24 +8191,38 @@ function CSSRules (app) {
|
|
|
8114
8191
|
patchContext(window);
|
|
8115
8192
|
app.observer.attachContextCallback(patchContext);
|
|
8116
8193
|
app.nodes.attachNodeCallback((node) => {
|
|
8117
|
-
if (!hasTag(node, 'style') || !node.sheet)
|
|
8194
|
+
if (!hasTag(node, 'style') || !node.sheet)
|
|
8195
|
+
return;
|
|
8196
|
+
if (node.textContent !== null && node.textContent.trim().length > 0)
|
|
8118
8197
|
return;
|
|
8119
|
-
}
|
|
8120
|
-
if (node.textContent !== null && node.textContent.trim().length > 0) {
|
|
8121
|
-
return; // Non-virtual styles captured by the observer as a text
|
|
8122
|
-
}
|
|
8123
8198
|
const nodeID = app.nodes.getID(node);
|
|
8124
|
-
if (!nodeID)
|
|
8199
|
+
if (!nodeID)
|
|
8125
8200
|
return;
|
|
8126
|
-
}
|
|
8127
8201
|
const sheet = node.sheet;
|
|
8128
8202
|
const sheetID = nextID();
|
|
8129
8203
|
styleSheetIDMap.set(sheet, sheetID);
|
|
8130
8204
|
app.send(AdoptedSSAddOwner(sheetID, nodeID));
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8205
|
+
for (let i = 0; i < sheet.cssRules.length; i++) {
|
|
8206
|
+
try {
|
|
8207
|
+
sendInsertDeleteRule(sheet, i, sheet.cssRules[i].cssText);
|
|
8208
|
+
}
|
|
8209
|
+
catch (e) {
|
|
8210
|
+
// Skip inaccessible rules
|
|
8211
|
+
}
|
|
8212
|
+
}
|
|
8213
|
+
});
|
|
8214
|
+
function startChecking() {
|
|
8215
|
+
if (checkInterval || !options.scanInMemoryCSS)
|
|
8216
|
+
return;
|
|
8217
|
+
checkInterval = window.setInterval(checkRuleChanges, checkIntervalMs);
|
|
8218
|
+
}
|
|
8219
|
+
setTimeout(startChecking, 50);
|
|
8220
|
+
app.attachStopCallback(() => {
|
|
8221
|
+
if (checkInterval) {
|
|
8222
|
+
clearInterval(checkInterval);
|
|
8223
|
+
checkInterval = null;
|
|
8134
8224
|
}
|
|
8225
|
+
ruleSnapshots.clear();
|
|
8135
8226
|
});
|
|
8136
8227
|
}
|
|
8137
8228
|
|
|
@@ -9696,7 +9787,7 @@ class API {
|
|
|
9696
9787
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9697
9788
|
const doNotTrack = this.checkDoNotTrack();
|
|
9698
9789
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9699
|
-
trackerVersion: '16.
|
|
9790
|
+
trackerVersion: '16.3.0-beta.0',
|
|
9700
9791
|
projectKey: this.options.projectKey,
|
|
9701
9792
|
doNotTrack,
|
|
9702
9793
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|
|
@@ -9795,7 +9886,7 @@ class API {
|
|
|
9795
9886
|
Mouse(app, options.mouse);
|
|
9796
9887
|
// inside iframe, we ignore viewport scroll
|
|
9797
9888
|
Scroll(app, this.crossdomainMode);
|
|
9798
|
-
CSSRules(app);
|
|
9889
|
+
CSSRules(app, options.css);
|
|
9799
9890
|
ConstructedStyleSheets(app);
|
|
9800
9891
|
Console(app, options);
|
|
9801
9892
|
Exception(app, options);
|