@openreplay/tracker 15.0.3 → 15.0.5-beta.1
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/index.js +293 -206
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/guards.d.ts +1 -0
- package/dist/cjs/main/modules/network.d.ts +1 -0
- package/dist/lib/index.js +293 -206
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/guards.d.ts +1 -0
- package/dist/lib/main/modules/network.d.ts +1 -0
- package/dist/types/main/app/guards.d.ts +1 -0
- package/dist/types/main/modules/network.d.ts +1 -0
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -774,13 +774,10 @@ class ConditionsManager {
|
|
|
774
774
|
this.conditions = [];
|
|
775
775
|
this.hasStarted = false;
|
|
776
776
|
this.createConditionFromFilter = (filter) => {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
return resultCondition;
|
|
781
|
-
}
|
|
777
|
+
const resultCondition = mapCondition(filter);
|
|
778
|
+
if (resultCondition.type) {
|
|
779
|
+
return resultCondition;
|
|
782
780
|
}
|
|
783
|
-
return undefined;
|
|
784
781
|
};
|
|
785
782
|
this.durationInt = null;
|
|
786
783
|
}
|
|
@@ -1063,8 +1060,9 @@ const mapCondition = (condition) => {
|
|
|
1063
1060
|
con = {
|
|
1064
1061
|
type: 'session_duration',
|
|
1065
1062
|
// @ts-ignore
|
|
1066
|
-
value: condition.value
|
|
1063
|
+
value: condition.value,
|
|
1067
1064
|
key: '',
|
|
1065
|
+
operator: 'is',
|
|
1068
1066
|
};
|
|
1069
1067
|
break;
|
|
1070
1068
|
case 'fetchUrl':
|
|
@@ -2330,7 +2328,7 @@ const containerStyle = {
|
|
|
2330
2328
|
alignItems: 'center',
|
|
2331
2329
|
padding: '1.5rem',
|
|
2332
2330
|
borderRadius: '2px',
|
|
2333
|
-
border: '1px solid
|
|
2331
|
+
border: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2334
2332
|
background: '#FFF',
|
|
2335
2333
|
width: '22rem',
|
|
2336
2334
|
};
|
|
@@ -2342,7 +2340,7 @@ const containerWidgetStyle = {
|
|
|
2342
2340
|
padding: 'unset',
|
|
2343
2341
|
fontFamily: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`,
|
|
2344
2342
|
'border-radius': '2px',
|
|
2345
|
-
border: '1px solid
|
|
2343
|
+
border: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2346
2344
|
background: 'rgba(255, 255, 255, 0.75)',
|
|
2347
2345
|
width: '22rem',
|
|
2348
2346
|
};
|
|
@@ -2424,7 +2422,7 @@ const descriptionWidgetStyle = {
|
|
|
2424
2422
|
boxSizing: 'border-box',
|
|
2425
2423
|
display: 'block',
|
|
2426
2424
|
width: '100%',
|
|
2427
|
-
borderBottom: '1px solid
|
|
2425
|
+
borderBottom: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2428
2426
|
background: '#FFF',
|
|
2429
2427
|
padding: '0.65rem',
|
|
2430
2428
|
alignSelf: 'stretch',
|
|
@@ -3297,7 +3295,10 @@ function isNode(sth) {
|
|
|
3297
3295
|
return !!sth && sth.nodeType != null;
|
|
3298
3296
|
}
|
|
3299
3297
|
function isSVGElement(node) {
|
|
3300
|
-
return node.namespaceURI === 'http://www.w3.org/2000/svg';
|
|
3298
|
+
return (node.namespaceURI === 'http://www.w3.org/2000/svg' || node.localName === 'svg');
|
|
3299
|
+
}
|
|
3300
|
+
function isUseElement(node) {
|
|
3301
|
+
return node.localName === 'use';
|
|
3301
3302
|
}
|
|
3302
3303
|
function isElementNode(node) {
|
|
3303
3304
|
return node.nodeType === Node.ELEMENT_NODE;
|
|
@@ -3727,6 +3728,48 @@ class Nodes {
|
|
|
3727
3728
|
}
|
|
3728
3729
|
}
|
|
3729
3730
|
|
|
3731
|
+
const iconCache = {};
|
|
3732
|
+
const domParser = new DOMParser();
|
|
3733
|
+
async function parseUseEl(useElement, mode) {
|
|
3734
|
+
try {
|
|
3735
|
+
const href = useElement.getAttribute('xlink:href') || useElement.getAttribute('href');
|
|
3736
|
+
if (!href) {
|
|
3737
|
+
console.debug('Openreplay: xlink:href or href not found on <use>.');
|
|
3738
|
+
return;
|
|
3739
|
+
}
|
|
3740
|
+
const [url, symbolId] = href.split('#');
|
|
3741
|
+
if (!url || !symbolId) {
|
|
3742
|
+
console.debug('Openreplay: Invalid xlink:href or href found on <use>.');
|
|
3743
|
+
return;
|
|
3744
|
+
}
|
|
3745
|
+
if (iconCache[symbolId]) {
|
|
3746
|
+
return iconCache[symbolId];
|
|
3747
|
+
}
|
|
3748
|
+
const response = await fetch(url);
|
|
3749
|
+
const svgText = await response.text();
|
|
3750
|
+
const svgDoc = domParser.parseFromString(svgText, 'image/svg+xml');
|
|
3751
|
+
const symbol = svgDoc.getElementById(symbolId);
|
|
3752
|
+
if (!symbol) {
|
|
3753
|
+
console.debug('Openreplay: Symbol not found in SVG.');
|
|
3754
|
+
return;
|
|
3755
|
+
}
|
|
3756
|
+
if (mode === 'inline') ;
|
|
3757
|
+
if (mode === 'svgtext') {
|
|
3758
|
+
const inlineSvg = `
|
|
3759
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="${symbol.getAttribute('viewBox') || '0 0 24 24'}">
|
|
3760
|
+
${symbol.innerHTML}
|
|
3761
|
+
</svg>
|
|
3762
|
+
`.trim();
|
|
3763
|
+
iconCache[symbolId] = inlineSvg;
|
|
3764
|
+
return inlineSvg;
|
|
3765
|
+
}
|
|
3766
|
+
if (mode === 'dataurl') ;
|
|
3767
|
+
console.debug(`Openreplay: Unknown mode: ${mode}. Use "inline" or "dataurl".`);
|
|
3768
|
+
}
|
|
3769
|
+
catch (error) {
|
|
3770
|
+
console.error('Openreplay: Error processing <use> element:', error);
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3730
3773
|
function isIgnored(node) {
|
|
3731
3774
|
if (isCommentNode(node)) {
|
|
3732
3775
|
return true;
|
|
@@ -3865,7 +3908,19 @@ class Observer {
|
|
|
3865
3908
|
if (value === null) {
|
|
3866
3909
|
this.app.send(RemoveNodeAttribute(id, name));
|
|
3867
3910
|
}
|
|
3868
|
-
|
|
3911
|
+
if (isUseElement(node) && name === 'href') {
|
|
3912
|
+
parseUseEl(node, 'svgtext')
|
|
3913
|
+
.then((svgData) => {
|
|
3914
|
+
if (svgData) {
|
|
3915
|
+
this.app.send(SetNodeAttribute(id, name, `_$OPENREPLAY_SPRITE$_${svgData}`));
|
|
3916
|
+
}
|
|
3917
|
+
})
|
|
3918
|
+
.catch((e) => {
|
|
3919
|
+
console.error('Openreplay: Error parsing <use> element:', e);
|
|
3920
|
+
});
|
|
3921
|
+
return;
|
|
3922
|
+
}
|
|
3923
|
+
if (name === 'href') {
|
|
3869
3924
|
if (value.length > 1e5) {
|
|
3870
3925
|
value = '';
|
|
3871
3926
|
}
|
|
@@ -4648,7 +4703,7 @@ class App {
|
|
|
4648
4703
|
this.stopCallbacks = [];
|
|
4649
4704
|
this.commitCallbacks = [];
|
|
4650
4705
|
this.activityState = ActivityState.NotActive;
|
|
4651
|
-
this.version = '15.0.
|
|
4706
|
+
this.version = '15.0.5-beta.1'; // TODO: version compatability check inside each plugin.
|
|
4652
4707
|
this.socketMode = false;
|
|
4653
4708
|
this.compressionThreshold = 24 * 1000;
|
|
4654
4709
|
this.bc = null;
|
|
@@ -4920,17 +4975,16 @@ class App {
|
|
|
4920
4975
|
};
|
|
4921
4976
|
this.flushBuffer = async (buffer) => {
|
|
4922
4977
|
return new Promise((res) => {
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
messagesBatch.push(buffer.shift());
|
|
4932
|
-
}
|
|
4978
|
+
if (buffer.length === 0) {
|
|
4979
|
+
res(null);
|
|
4980
|
+
return;
|
|
4981
|
+
}
|
|
4982
|
+
// Since the first element is always a Timestamp, include it by default.
|
|
4983
|
+
let endIndex = 1;
|
|
4984
|
+
while (endIndex < buffer.length && buffer[endIndex][0] !== 0 /* MType.Timestamp */) {
|
|
4985
|
+
endIndex++;
|
|
4933
4986
|
}
|
|
4987
|
+
const messagesBatch = buffer.splice(0, endIndex);
|
|
4934
4988
|
this.postToWorker(messagesBatch);
|
|
4935
4989
|
res(null);
|
|
4936
4990
|
});
|
|
@@ -4994,6 +5048,9 @@ class App {
|
|
|
4994
5048
|
const host = location.hostname.split('.').slice(-2).join('_');
|
|
4995
5049
|
this.bc = new BroadcastChannel(`rick_${host}`);
|
|
4996
5050
|
}
|
|
5051
|
+
else if (this.options.forceSingleTab) {
|
|
5052
|
+
this.allowAppStart();
|
|
5053
|
+
}
|
|
4997
5054
|
this.revID = this.options.revID;
|
|
4998
5055
|
this.localStorage = this.options.localStorage ?? window.localStorage;
|
|
4999
5056
|
this.sessionStorage = this.options.sessionStorage ?? window.sessionStorage;
|
|
@@ -5311,7 +5368,6 @@ class App {
|
|
|
5311
5368
|
postToWorker(messages) {
|
|
5312
5369
|
this.worker?.postMessage(messages);
|
|
5313
5370
|
this.commitCallbacks.forEach((cb) => cb(messages));
|
|
5314
|
-
messages.length = 0;
|
|
5315
5371
|
}
|
|
5316
5372
|
timestamp() {
|
|
5317
5373
|
return now() + this.delay;
|
|
@@ -6678,122 +6734,170 @@ function Input (app, opts) {
|
|
|
6678
6734
|
// License: MIT
|
|
6679
6735
|
// Author: Anton Medvedev <anton@medv.io>
|
|
6680
6736
|
// Source: https://github.com/antonmedv/finder
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6737
|
+
const acceptedAttrNames = new Set(['role', 'name', 'aria-label', 'rel', 'href']);
|
|
6738
|
+
/** Check if attribute name and value are word-like. */
|
|
6739
|
+
function attr(name, value) {
|
|
6740
|
+
let nameIsOk = acceptedAttrNames.has(name);
|
|
6741
|
+
nameIsOk ||= name.startsWith('data-') && wordLike(name);
|
|
6742
|
+
let valueIsOk = wordLike(value) && value.length < 100;
|
|
6743
|
+
valueIsOk ||= value.startsWith('#') && wordLike(value.slice(1));
|
|
6744
|
+
return nameIsOk && valueIsOk;
|
|
6745
|
+
}
|
|
6746
|
+
/** Check if id name is word-like. */
|
|
6747
|
+
function idName(name) {
|
|
6748
|
+
return wordLike(name);
|
|
6749
|
+
}
|
|
6750
|
+
/** Check if class name is word-like. */
|
|
6751
|
+
function className(name) {
|
|
6752
|
+
return wordLike(name);
|
|
6753
|
+
}
|
|
6754
|
+
/** Check if tag name is word-like. */
|
|
6755
|
+
function tagName(name) {
|
|
6756
|
+
return true;
|
|
6757
|
+
}
|
|
6758
|
+
/** Finds unique CSS selectors for the given element. */
|
|
6684
6759
|
function finder(input, options) {
|
|
6685
|
-
start = new Date();
|
|
6686
6760
|
if (input.nodeType !== Node.ELEMENT_NODE) {
|
|
6687
6761
|
throw new Error(`Can't generate CSS selector for non-element node type.`);
|
|
6688
6762
|
}
|
|
6689
|
-
if (
|
|
6763
|
+
if (input.tagName.toLowerCase() === 'html') {
|
|
6690
6764
|
return 'html';
|
|
6691
6765
|
}
|
|
6692
6766
|
const defaults = {
|
|
6693
6767
|
root: document.body,
|
|
6694
|
-
idName:
|
|
6695
|
-
className:
|
|
6696
|
-
tagName:
|
|
6697
|
-
attr:
|
|
6698
|
-
|
|
6768
|
+
idName: idName,
|
|
6769
|
+
className: className,
|
|
6770
|
+
tagName: tagName,
|
|
6771
|
+
attr: attr,
|
|
6772
|
+
timeoutMs: 1000,
|
|
6773
|
+
seedMinLength: 3,
|
|
6699
6774
|
optimizedMinLength: 2,
|
|
6700
|
-
|
|
6701
|
-
maxNumberOfTries: 10000,
|
|
6702
|
-
timeoutMs: undefined,
|
|
6775
|
+
maxNumberOfPathChecks: Infinity,
|
|
6703
6776
|
};
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6777
|
+
const startTime = new Date();
|
|
6778
|
+
const config = { ...defaults, ...options };
|
|
6779
|
+
const rootDocument = findRootDocument(config.root, defaults);
|
|
6780
|
+
let foundPath;
|
|
6781
|
+
let count = 0;
|
|
6782
|
+
for (const candidate of search(input, config, rootDocument)) {
|
|
6783
|
+
const elapsedTimeMs = new Date().getTime() - startTime.getTime();
|
|
6784
|
+
if (elapsedTimeMs > config.timeoutMs ||
|
|
6785
|
+
count >= config.maxNumberOfPathChecks) {
|
|
6786
|
+
const fPath = fallback(input, rootDocument);
|
|
6787
|
+
if (!fPath) {
|
|
6788
|
+
throw new Error(`Timeout: Can't find a unique selector after ${config.timeoutMs}ms`);
|
|
6789
|
+
}
|
|
6790
|
+
return selector(fPath);
|
|
6791
|
+
}
|
|
6792
|
+
count++;
|
|
6793
|
+
if (unique(candidate, rootDocument)) {
|
|
6794
|
+
foundPath = candidate;
|
|
6795
|
+
break;
|
|
6711
6796
|
}
|
|
6712
|
-
return selector(path);
|
|
6713
6797
|
}
|
|
6714
|
-
|
|
6798
|
+
if (!foundPath) {
|
|
6715
6799
|
throw new Error(`Selector was not found.`);
|
|
6716
6800
|
}
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
return rootNode.ownerDocument;
|
|
6801
|
+
const optimized = [
|
|
6802
|
+
...optimize(foundPath, input, config, rootDocument, startTime),
|
|
6803
|
+
];
|
|
6804
|
+
optimized.sort(byPenalty);
|
|
6805
|
+
if (optimized.length > 0) {
|
|
6806
|
+
return selector(optimized[0]);
|
|
6724
6807
|
}
|
|
6725
|
-
return
|
|
6808
|
+
return selector(foundPath);
|
|
6726
6809
|
}
|
|
6727
|
-
function
|
|
6728
|
-
|
|
6729
|
-
let
|
|
6810
|
+
function* search(input, config, rootDocument) {
|
|
6811
|
+
const stack = [];
|
|
6812
|
+
let paths = [];
|
|
6730
6813
|
let current = input;
|
|
6731
6814
|
let i = 0;
|
|
6732
|
-
while (current) {
|
|
6733
|
-
const
|
|
6734
|
-
|
|
6735
|
-
throw new Error(`Timeout: Can't find a unique selector after ${elapsedTime}ms`);
|
|
6736
|
-
}
|
|
6737
|
-
let level = maybe(id(current)) ||
|
|
6738
|
-
maybe(...attr(current)) ||
|
|
6739
|
-
maybe(...classNames(current)) ||
|
|
6740
|
-
maybe(tagName(current)) || [any()];
|
|
6741
|
-
const nth = index(current);
|
|
6742
|
-
if (limit == 'all') {
|
|
6743
|
-
if (nth) {
|
|
6744
|
-
level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));
|
|
6745
|
-
}
|
|
6746
|
-
}
|
|
6747
|
-
else if (limit == 'two') {
|
|
6748
|
-
level = level.slice(0, 1);
|
|
6749
|
-
if (nth) {
|
|
6750
|
-
level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));
|
|
6751
|
-
}
|
|
6752
|
-
}
|
|
6753
|
-
else if (limit == 'one') {
|
|
6754
|
-
const [node] = (level = level.slice(0, 1));
|
|
6755
|
-
if (nth && dispensableNth(node)) {
|
|
6756
|
-
level = [nthChild(node, nth)];
|
|
6757
|
-
}
|
|
6758
|
-
}
|
|
6759
|
-
else if (limit == 'none') {
|
|
6760
|
-
level = [any()];
|
|
6761
|
-
if (nth) {
|
|
6762
|
-
level = [nthChild(level[0], nth)];
|
|
6763
|
-
}
|
|
6764
|
-
}
|
|
6765
|
-
for (let node of level) {
|
|
6815
|
+
while (current && current !== rootDocument) {
|
|
6816
|
+
const level = tie(current, config);
|
|
6817
|
+
for (const node of level) {
|
|
6766
6818
|
node.level = i;
|
|
6767
6819
|
}
|
|
6768
6820
|
stack.push(level);
|
|
6769
|
-
if (stack.length >= config.seedMinLength) {
|
|
6770
|
-
path = findUniquePath(stack, fallback);
|
|
6771
|
-
if (path) {
|
|
6772
|
-
break;
|
|
6773
|
-
}
|
|
6774
|
-
}
|
|
6775
6821
|
current = current.parentElement;
|
|
6776
6822
|
i++;
|
|
6823
|
+
paths.push(...combinations(stack));
|
|
6824
|
+
if (i >= config.seedMinLength) {
|
|
6825
|
+
paths.sort(byPenalty);
|
|
6826
|
+
for (const candidate of paths) {
|
|
6827
|
+
yield candidate;
|
|
6828
|
+
}
|
|
6829
|
+
paths = [];
|
|
6830
|
+
}
|
|
6777
6831
|
}
|
|
6778
|
-
|
|
6779
|
-
|
|
6832
|
+
paths.sort(byPenalty);
|
|
6833
|
+
for (const candidate of paths) {
|
|
6834
|
+
yield candidate;
|
|
6780
6835
|
}
|
|
6781
|
-
|
|
6782
|
-
|
|
6836
|
+
}
|
|
6837
|
+
function wordLike(name) {
|
|
6838
|
+
if (/^[a-z\-]{3,}$/i.test(name)) {
|
|
6839
|
+
const words = name.split(/-|[A-Z]/);
|
|
6840
|
+
for (const word of words) {
|
|
6841
|
+
if (word.length <= 2) {
|
|
6842
|
+
return false;
|
|
6843
|
+
}
|
|
6844
|
+
if (/[^aeiou]{4,}/i.test(word)) {
|
|
6845
|
+
return false;
|
|
6846
|
+
}
|
|
6847
|
+
}
|
|
6848
|
+
return true;
|
|
6783
6849
|
}
|
|
6784
|
-
return
|
|
6850
|
+
return false;
|
|
6785
6851
|
}
|
|
6786
|
-
function
|
|
6787
|
-
const
|
|
6788
|
-
|
|
6789
|
-
|
|
6852
|
+
function tie(element, config) {
|
|
6853
|
+
const level = [];
|
|
6854
|
+
const elementId = element.getAttribute('id');
|
|
6855
|
+
if (elementId && config.idName(elementId)) {
|
|
6856
|
+
level.push({
|
|
6857
|
+
name: '#' + CSS.escape(elementId),
|
|
6858
|
+
penalty: 0,
|
|
6859
|
+
});
|
|
6790
6860
|
}
|
|
6791
|
-
for (let
|
|
6792
|
-
|
|
6793
|
-
|
|
6861
|
+
for (let i = 0; i < element.classList.length; i++) {
|
|
6862
|
+
const name = element.classList[i];
|
|
6863
|
+
if (config.className(name)) {
|
|
6864
|
+
level.push({
|
|
6865
|
+
name: '.' + CSS.escape(name),
|
|
6866
|
+
penalty: 1,
|
|
6867
|
+
});
|
|
6794
6868
|
}
|
|
6795
6869
|
}
|
|
6796
|
-
|
|
6870
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
6871
|
+
const attr = element.attributes[i];
|
|
6872
|
+
if (config.attr(attr.name, attr.value)) {
|
|
6873
|
+
level.push({
|
|
6874
|
+
name: `[${CSS.escape(attr.name)}="${CSS.escape(attr.value)}"]`,
|
|
6875
|
+
penalty: 2,
|
|
6876
|
+
});
|
|
6877
|
+
}
|
|
6878
|
+
}
|
|
6879
|
+
const tagName = element.tagName.toLowerCase();
|
|
6880
|
+
if (config.tagName(tagName)) {
|
|
6881
|
+
level.push({
|
|
6882
|
+
name: tagName,
|
|
6883
|
+
penalty: 5,
|
|
6884
|
+
});
|
|
6885
|
+
const index = indexOf(element, tagName);
|
|
6886
|
+
if (index !== undefined) {
|
|
6887
|
+
level.push({
|
|
6888
|
+
name: nthOfType(tagName, index),
|
|
6889
|
+
penalty: 10,
|
|
6890
|
+
});
|
|
6891
|
+
}
|
|
6892
|
+
}
|
|
6893
|
+
const nth = indexOf(element);
|
|
6894
|
+
if (nth !== undefined) {
|
|
6895
|
+
level.push({
|
|
6896
|
+
name: nthChild(tagName, nth),
|
|
6897
|
+
penalty: 50,
|
|
6898
|
+
});
|
|
6899
|
+
}
|
|
6900
|
+
return level;
|
|
6797
6901
|
}
|
|
6798
6902
|
function selector(path) {
|
|
6799
6903
|
let node = path[0];
|
|
@@ -6813,69 +6917,23 @@ function selector(path) {
|
|
|
6813
6917
|
function penalty(path) {
|
|
6814
6918
|
return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);
|
|
6815
6919
|
}
|
|
6816
|
-
function
|
|
6817
|
-
|
|
6818
|
-
switch (rootDocument.querySelectorAll(css).length) {
|
|
6819
|
-
case 0:
|
|
6820
|
-
throw new Error(`Can't select any node with this selector: ${css}`);
|
|
6821
|
-
case 1:
|
|
6822
|
-
return true;
|
|
6823
|
-
default:
|
|
6824
|
-
return false;
|
|
6825
|
-
}
|
|
6826
|
-
}
|
|
6827
|
-
function id(input) {
|
|
6828
|
-
const elementId = input.getAttribute('id');
|
|
6829
|
-
if (elementId && config.idName(elementId)) {
|
|
6830
|
-
return {
|
|
6831
|
-
name: '#' + CSS.escape(elementId),
|
|
6832
|
-
penalty: 0,
|
|
6833
|
-
};
|
|
6834
|
-
}
|
|
6835
|
-
return null;
|
|
6836
|
-
}
|
|
6837
|
-
function attr(input) {
|
|
6838
|
-
const attrs = Array.from(input.attributes).filter((attr) => config.attr(attr.name, attr.value));
|
|
6839
|
-
return attrs.map((attr) => ({
|
|
6840
|
-
name: `[${CSS.escape(attr.name)}="${CSS.escape(attr.value)}"]`,
|
|
6841
|
-
penalty: 0.5,
|
|
6842
|
-
}));
|
|
6843
|
-
}
|
|
6844
|
-
function classNames(input) {
|
|
6845
|
-
const names = Array.from(input.classList).filter(config.className);
|
|
6846
|
-
return names.map((name) => ({
|
|
6847
|
-
name: '.' + CSS.escape(name),
|
|
6848
|
-
penalty: 1,
|
|
6849
|
-
}));
|
|
6850
|
-
}
|
|
6851
|
-
function tagName(input) {
|
|
6852
|
-
const name = input.tagName.toLowerCase();
|
|
6853
|
-
if (config.tagName(name)) {
|
|
6854
|
-
return {
|
|
6855
|
-
name,
|
|
6856
|
-
penalty: 2,
|
|
6857
|
-
};
|
|
6858
|
-
}
|
|
6859
|
-
return null;
|
|
6920
|
+
function byPenalty(a, b) {
|
|
6921
|
+
return penalty(a) - penalty(b);
|
|
6860
6922
|
}
|
|
6861
|
-
function
|
|
6862
|
-
return {
|
|
6863
|
-
name: '*',
|
|
6864
|
-
penalty: 3,
|
|
6865
|
-
};
|
|
6866
|
-
}
|
|
6867
|
-
function index(input) {
|
|
6923
|
+
function indexOf(input, tagName) {
|
|
6868
6924
|
const parent = input.parentNode;
|
|
6869
6925
|
if (!parent) {
|
|
6870
|
-
return
|
|
6926
|
+
return undefined;
|
|
6871
6927
|
}
|
|
6872
6928
|
let child = parent.firstChild;
|
|
6873
6929
|
if (!child) {
|
|
6874
|
-
return
|
|
6930
|
+
return undefined;
|
|
6875
6931
|
}
|
|
6876
6932
|
let i = 0;
|
|
6877
6933
|
while (child) {
|
|
6878
|
-
if (child.nodeType === Node.ELEMENT_NODE
|
|
6934
|
+
if (child.nodeType === Node.ELEMENT_NODE &&
|
|
6935
|
+
(tagName === undefined ||
|
|
6936
|
+
child.tagName.toLowerCase() === tagName)) {
|
|
6879
6937
|
i++;
|
|
6880
6938
|
}
|
|
6881
6939
|
if (child === input) {
|
|
@@ -6885,24 +6943,39 @@ function index(input) {
|
|
|
6885
6943
|
}
|
|
6886
6944
|
return i;
|
|
6887
6945
|
}
|
|
6888
|
-
function
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6946
|
+
function fallback(input, rootDocument) {
|
|
6947
|
+
let i = 0;
|
|
6948
|
+
let current = input;
|
|
6949
|
+
const path = [];
|
|
6950
|
+
while (current && current !== rootDocument) {
|
|
6951
|
+
const tagName = current.tagName.toLowerCase();
|
|
6952
|
+
const index = indexOf(current, tagName);
|
|
6953
|
+
if (index === undefined) {
|
|
6954
|
+
return;
|
|
6955
|
+
}
|
|
6956
|
+
path.push({
|
|
6957
|
+
name: nthOfType(tagName, index),
|
|
6958
|
+
penalty: NaN,
|
|
6959
|
+
level: i,
|
|
6960
|
+
});
|
|
6961
|
+
current = current.parentElement;
|
|
6962
|
+
i++;
|
|
6963
|
+
}
|
|
6964
|
+
if (unique(path, rootDocument)) {
|
|
6965
|
+
return path;
|
|
6966
|
+
}
|
|
6896
6967
|
}
|
|
6897
|
-
function
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
return list;
|
|
6968
|
+
function nthChild(tagName, index) {
|
|
6969
|
+
if (tagName === 'html') {
|
|
6970
|
+
return 'html';
|
|
6901
6971
|
}
|
|
6902
|
-
return
|
|
6972
|
+
return `${tagName}:nth-child(${index})`;
|
|
6903
6973
|
}
|
|
6904
|
-
function
|
|
6905
|
-
|
|
6974
|
+
function nthOfType(tagName, index) {
|
|
6975
|
+
if (tagName === 'html') {
|
|
6976
|
+
return 'html';
|
|
6977
|
+
}
|
|
6978
|
+
return `${tagName}:nth-of-type(${index})`;
|
|
6906
6979
|
}
|
|
6907
6980
|
function* combinations(stack, path = []) {
|
|
6908
6981
|
if (stack.length > 0) {
|
|
@@ -6914,44 +6987,50 @@ function* combinations(stack, path = []) {
|
|
|
6914
6987
|
yield path;
|
|
6915
6988
|
}
|
|
6916
6989
|
}
|
|
6917
|
-
function
|
|
6918
|
-
|
|
6990
|
+
function findRootDocument(rootNode, defaults) {
|
|
6991
|
+
if (rootNode.nodeType === Node.DOCUMENT_NODE) {
|
|
6992
|
+
return rootNode;
|
|
6993
|
+
}
|
|
6994
|
+
if (rootNode === defaults.root) {
|
|
6995
|
+
return rootNode.ownerDocument;
|
|
6996
|
+
}
|
|
6997
|
+
return rootNode;
|
|
6998
|
+
}
|
|
6999
|
+
function unique(path, rootDocument) {
|
|
7000
|
+
const css = selector(path);
|
|
7001
|
+
switch (rootDocument.querySelectorAll(css).length) {
|
|
7002
|
+
case 0:
|
|
7003
|
+
throw new Error(`Can't select any node with this selector: ${css}`);
|
|
7004
|
+
case 1:
|
|
7005
|
+
return true;
|
|
7006
|
+
default:
|
|
7007
|
+
return false;
|
|
7008
|
+
}
|
|
6919
7009
|
}
|
|
6920
|
-
function* optimize(path, input,
|
|
6921
|
-
counter: 0,
|
|
6922
|
-
visited: new Map(),
|
|
6923
|
-
}) {
|
|
7010
|
+
function* optimize(path, input, config, rootDocument, startTime) {
|
|
6924
7011
|
if (path.length > 2 && path.length > config.optimizedMinLength) {
|
|
6925
7012
|
for (let i = 1; i < path.length - 1; i++) {
|
|
6926
|
-
|
|
6927
|
-
|
|
7013
|
+
const elapsedTimeMs = new Date().getTime() - startTime.getTime();
|
|
7014
|
+
if (elapsedTimeMs > config.timeoutMs) {
|
|
7015
|
+
return;
|
|
6928
7016
|
}
|
|
6929
|
-
scope.counter += 1;
|
|
6930
7017
|
const newPath = [...path];
|
|
6931
7018
|
newPath.splice(i, 1);
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
return;
|
|
6935
|
-
}
|
|
6936
|
-
if (unique(newPath) && same(newPath, input)) {
|
|
7019
|
+
if (unique(newPath, rootDocument) &&
|
|
7020
|
+
rootDocument.querySelector(selector(newPath)) === input) {
|
|
6937
7021
|
yield newPath;
|
|
6938
|
-
|
|
6939
|
-
yield* optimize(newPath, input, scope);
|
|
7022
|
+
yield* optimize(newPath, input, config, rootDocument, startTime);
|
|
6940
7023
|
}
|
|
6941
7024
|
}
|
|
6942
7025
|
}
|
|
6943
7026
|
}
|
|
6944
|
-
function same(path, input) {
|
|
6945
|
-
return rootDocument.querySelector(selector(path)) === input;
|
|
6946
|
-
}
|
|
6947
7027
|
|
|
6948
7028
|
function _getSelector(target, document, options) {
|
|
6949
7029
|
const selector = finder(target, {
|
|
6950
7030
|
root: document.body,
|
|
6951
7031
|
seedMinLength: 3,
|
|
6952
7032
|
optimizedMinLength: options?.minSelectorDepth || 2,
|
|
6953
|
-
|
|
6954
|
-
maxNumberOfTries: options?.maxOptimiseTries || 10000,
|
|
7033
|
+
maxNumberOfPathChecks: options?.maxOptimiseTries || 10000,
|
|
6955
7034
|
});
|
|
6956
7035
|
return selector;
|
|
6957
7036
|
}
|
|
@@ -7218,6 +7297,11 @@ function Timing (app, opts) {
|
|
|
7218
7297
|
if (shouldSkip) {
|
|
7219
7298
|
return;
|
|
7220
7299
|
}
|
|
7300
|
+
const failed = entry.responseEnd === 0
|
|
7301
|
+
|| (entry.transferSize === 0 && entry.decodedBodySize === 0);
|
|
7302
|
+
if (failed) {
|
|
7303
|
+
app.send(ResourceTiming(entry.startTime + getTimeOrigin(), 0, 0, 0, 0, 0, entry.name, entry.initiatorType, 0, true));
|
|
7304
|
+
}
|
|
7221
7305
|
app.send(ResourceTiming(entry.startTime + getTimeOrigin(), entry.duration, entry.responseStart && entry.startTime ? entry.responseStart - entry.startTime : 0, entry.transferSize > entry.encodedBodySize ? entry.transferSize - entry.encodedBodySize : 0, entry.encodedBodySize || 0, entry.decodedBodySize || 0, entry.name, entry.initiatorType, entry.transferSize,
|
|
7222
7306
|
// @ts-ignore
|
|
7223
7307
|
(entry.responseStatus && entry.responseStatus === 304) || entry.transferSize === 0));
|
|
@@ -8749,6 +8833,9 @@ function strMethod(method) {
|
|
|
8749
8833
|
return typeof method === 'string' ? method.toUpperCase() : 'GET';
|
|
8750
8834
|
}
|
|
8751
8835
|
function Network (app, opts = {}) {
|
|
8836
|
+
if (opts.disabled) {
|
|
8837
|
+
return;
|
|
8838
|
+
}
|
|
8752
8839
|
const options = Object.assign({
|
|
8753
8840
|
failuresOnly: false,
|
|
8754
8841
|
ignoreHeaders: ['cookie', 'set-cookie', 'authorization'],
|
|
@@ -9068,11 +9155,8 @@ class API {
|
|
|
9068
9155
|
};
|
|
9069
9156
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9070
9157
|
const doNotTrack = this.checkDoNotTrack();
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
req.open('POST', orig + '/v1/web/not-started');
|
|
9074
|
-
req.send(JSON.stringify({
|
|
9075
|
-
trackerVersion: '15.0.3',
|
|
9158
|
+
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9159
|
+
trackerVersion: '15.0.5-beta.1',
|
|
9076
9160
|
projectKey: this.options.projectKey,
|
|
9077
9161
|
doNotTrack,
|
|
9078
9162
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|
|
@@ -9180,7 +9264,10 @@ class API {
|
|
|
9180
9264
|
Timing(app, options);
|
|
9181
9265
|
Focus(app);
|
|
9182
9266
|
Fonts(app);
|
|
9183
|
-
|
|
9267
|
+
const skipNetwork = options.network?.disabled;
|
|
9268
|
+
if (!skipNetwork) {
|
|
9269
|
+
Network(app, options.network);
|
|
9270
|
+
}
|
|
9184
9271
|
selection(app);
|
|
9185
9272
|
window.__OPENREPLAY__ = this;
|
|
9186
9273
|
if (options.flags && options.flags.onFlagsLoad) {
|