@openreplay/tracker 15.0.3 → 15.0.5-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/index.js +272 -187
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/guards.d.ts +1 -0
- package/dist/lib/index.js +272 -187
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/guards.d.ts +1 -0
- package/dist/types/main/app/guards.d.ts +1 -0
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -2330,7 +2330,7 @@ const containerStyle = {
|
|
|
2330
2330
|
alignItems: 'center',
|
|
2331
2331
|
padding: '1.5rem',
|
|
2332
2332
|
borderRadius: '2px',
|
|
2333
|
-
border: '1px solid
|
|
2333
|
+
border: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2334
2334
|
background: '#FFF',
|
|
2335
2335
|
width: '22rem',
|
|
2336
2336
|
};
|
|
@@ -2342,7 +2342,7 @@ const containerWidgetStyle = {
|
|
|
2342
2342
|
padding: 'unset',
|
|
2343
2343
|
fontFamily: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`,
|
|
2344
2344
|
'border-radius': '2px',
|
|
2345
|
-
border: '1px solid
|
|
2345
|
+
border: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2346
2346
|
background: 'rgba(255, 255, 255, 0.75)',
|
|
2347
2347
|
width: '22rem',
|
|
2348
2348
|
};
|
|
@@ -2424,7 +2424,7 @@ const descriptionWidgetStyle = {
|
|
|
2424
2424
|
boxSizing: 'border-box',
|
|
2425
2425
|
display: 'block',
|
|
2426
2426
|
width: '100%',
|
|
2427
|
-
borderBottom: '1px solid
|
|
2427
|
+
borderBottom: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2428
2428
|
background: '#FFF',
|
|
2429
2429
|
padding: '0.65rem',
|
|
2430
2430
|
alignSelf: 'stretch',
|
|
@@ -3297,7 +3297,10 @@ function isNode(sth) {
|
|
|
3297
3297
|
return !!sth && sth.nodeType != null;
|
|
3298
3298
|
}
|
|
3299
3299
|
function isSVGElement(node) {
|
|
3300
|
-
return node.namespaceURI === 'http://www.w3.org/2000/svg';
|
|
3300
|
+
return (node.namespaceURI === 'http://www.w3.org/2000/svg' || node.localName === 'svg');
|
|
3301
|
+
}
|
|
3302
|
+
function isUseElement(node) {
|
|
3303
|
+
return node.localName === 'use';
|
|
3301
3304
|
}
|
|
3302
3305
|
function isElementNode(node) {
|
|
3303
3306
|
return node.nodeType === Node.ELEMENT_NODE;
|
|
@@ -3727,6 +3730,48 @@ class Nodes {
|
|
|
3727
3730
|
}
|
|
3728
3731
|
}
|
|
3729
3732
|
|
|
3733
|
+
const iconCache = {};
|
|
3734
|
+
const domParser = new DOMParser();
|
|
3735
|
+
async function parseUseEl(useElement, mode) {
|
|
3736
|
+
try {
|
|
3737
|
+
const href = useElement.getAttribute('xlink:href') || useElement.getAttribute('href');
|
|
3738
|
+
if (!href) {
|
|
3739
|
+
console.debug('Openreplay: xlink:href or href not found on <use>.');
|
|
3740
|
+
return;
|
|
3741
|
+
}
|
|
3742
|
+
const [url, symbolId] = href.split('#');
|
|
3743
|
+
if (!url || !symbolId) {
|
|
3744
|
+
console.debug('Openreplay: Invalid xlink:href or href found on <use>.');
|
|
3745
|
+
return;
|
|
3746
|
+
}
|
|
3747
|
+
if (iconCache[symbolId]) {
|
|
3748
|
+
return iconCache[symbolId];
|
|
3749
|
+
}
|
|
3750
|
+
const response = await fetch(url);
|
|
3751
|
+
const svgText = await response.text();
|
|
3752
|
+
const svgDoc = domParser.parseFromString(svgText, 'image/svg+xml');
|
|
3753
|
+
const symbol = svgDoc.getElementById(symbolId);
|
|
3754
|
+
if (!symbol) {
|
|
3755
|
+
console.debug('Openreplay: Symbol not found in SVG.');
|
|
3756
|
+
return;
|
|
3757
|
+
}
|
|
3758
|
+
if (mode === 'inline') ;
|
|
3759
|
+
if (mode === 'svgtext') {
|
|
3760
|
+
const inlineSvg = `
|
|
3761
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="${symbol.getAttribute('viewBox') || '0 0 24 24'}">
|
|
3762
|
+
${symbol.innerHTML}
|
|
3763
|
+
</svg>
|
|
3764
|
+
`.trim();
|
|
3765
|
+
iconCache[symbolId] = inlineSvg;
|
|
3766
|
+
return inlineSvg;
|
|
3767
|
+
}
|
|
3768
|
+
if (mode === 'dataurl') ;
|
|
3769
|
+
console.debug(`Openreplay: Unknown mode: ${mode}. Use "inline" or "dataurl".`);
|
|
3770
|
+
}
|
|
3771
|
+
catch (error) {
|
|
3772
|
+
console.error('Openreplay: Error processing <use> element:', error);
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3730
3775
|
function isIgnored(node) {
|
|
3731
3776
|
if (isCommentNode(node)) {
|
|
3732
3777
|
return true;
|
|
@@ -3865,7 +3910,19 @@ class Observer {
|
|
|
3865
3910
|
if (value === null) {
|
|
3866
3911
|
this.app.send(RemoveNodeAttribute(id, name));
|
|
3867
3912
|
}
|
|
3868
|
-
|
|
3913
|
+
if (isUseElement(node) && name === 'href') {
|
|
3914
|
+
parseUseEl(node, 'svgtext')
|
|
3915
|
+
.then((svgData) => {
|
|
3916
|
+
if (svgData) {
|
|
3917
|
+
this.app.send(SetNodeAttribute(id, name, `_$OPENREPLAY_SPRITE$_${svgData}`));
|
|
3918
|
+
}
|
|
3919
|
+
})
|
|
3920
|
+
.catch((e) => {
|
|
3921
|
+
console.error('Openreplay: Error parsing <use> element:', e);
|
|
3922
|
+
});
|
|
3923
|
+
return;
|
|
3924
|
+
}
|
|
3925
|
+
if (name === 'href') {
|
|
3869
3926
|
if (value.length > 1e5) {
|
|
3870
3927
|
value = '';
|
|
3871
3928
|
}
|
|
@@ -4648,7 +4705,7 @@ class App {
|
|
|
4648
4705
|
this.stopCallbacks = [];
|
|
4649
4706
|
this.commitCallbacks = [];
|
|
4650
4707
|
this.activityState = ActivityState.NotActive;
|
|
4651
|
-
this.version = '15.0.
|
|
4708
|
+
this.version = '15.0.5-beta.0'; // TODO: version compatability check inside each plugin.
|
|
4652
4709
|
this.socketMode = false;
|
|
4653
4710
|
this.compressionThreshold = 24 * 1000;
|
|
4654
4711
|
this.bc = null;
|
|
@@ -4994,6 +5051,9 @@ class App {
|
|
|
4994
5051
|
const host = location.hostname.split('.').slice(-2).join('_');
|
|
4995
5052
|
this.bc = new BroadcastChannel(`rick_${host}`);
|
|
4996
5053
|
}
|
|
5054
|
+
else if (this.options.forceSingleTab) {
|
|
5055
|
+
this.allowAppStart();
|
|
5056
|
+
}
|
|
4997
5057
|
this.revID = this.options.revID;
|
|
4998
5058
|
this.localStorage = this.options.localStorage ?? window.localStorage;
|
|
4999
5059
|
this.sessionStorage = this.options.sessionStorage ?? window.sessionStorage;
|
|
@@ -6678,122 +6738,170 @@ function Input (app, opts) {
|
|
|
6678
6738
|
// License: MIT
|
|
6679
6739
|
// Author: Anton Medvedev <anton@medv.io>
|
|
6680
6740
|
// Source: https://github.com/antonmedv/finder
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6741
|
+
const acceptedAttrNames = new Set(['role', 'name', 'aria-label', 'rel', 'href']);
|
|
6742
|
+
/** Check if attribute name and value are word-like. */
|
|
6743
|
+
function attr(name, value) {
|
|
6744
|
+
let nameIsOk = acceptedAttrNames.has(name);
|
|
6745
|
+
nameIsOk ||= name.startsWith('data-') && wordLike(name);
|
|
6746
|
+
let valueIsOk = wordLike(value) && value.length < 100;
|
|
6747
|
+
valueIsOk ||= value.startsWith('#') && wordLike(value.slice(1));
|
|
6748
|
+
return nameIsOk && valueIsOk;
|
|
6749
|
+
}
|
|
6750
|
+
/** Check if id name is word-like. */
|
|
6751
|
+
function idName(name) {
|
|
6752
|
+
return wordLike(name);
|
|
6753
|
+
}
|
|
6754
|
+
/** Check if class name is word-like. */
|
|
6755
|
+
function className(name) {
|
|
6756
|
+
return wordLike(name);
|
|
6757
|
+
}
|
|
6758
|
+
/** Check if tag name is word-like. */
|
|
6759
|
+
function tagName(name) {
|
|
6760
|
+
return true;
|
|
6761
|
+
}
|
|
6762
|
+
/** Finds unique CSS selectors for the given element. */
|
|
6684
6763
|
function finder(input, options) {
|
|
6685
|
-
start = new Date();
|
|
6686
6764
|
if (input.nodeType !== Node.ELEMENT_NODE) {
|
|
6687
6765
|
throw new Error(`Can't generate CSS selector for non-element node type.`);
|
|
6688
6766
|
}
|
|
6689
|
-
if (
|
|
6767
|
+
if (input.tagName.toLowerCase() === 'html') {
|
|
6690
6768
|
return 'html';
|
|
6691
6769
|
}
|
|
6692
6770
|
const defaults = {
|
|
6693
6771
|
root: document.body,
|
|
6694
|
-
idName:
|
|
6695
|
-
className:
|
|
6696
|
-
tagName:
|
|
6697
|
-
attr:
|
|
6698
|
-
|
|
6772
|
+
idName: idName,
|
|
6773
|
+
className: className,
|
|
6774
|
+
tagName: tagName,
|
|
6775
|
+
attr: attr,
|
|
6776
|
+
timeoutMs: 1000,
|
|
6777
|
+
seedMinLength: 3,
|
|
6699
6778
|
optimizedMinLength: 2,
|
|
6700
|
-
|
|
6701
|
-
maxNumberOfTries: 10000,
|
|
6702
|
-
timeoutMs: undefined,
|
|
6779
|
+
maxNumberOfPathChecks: Infinity,
|
|
6703
6780
|
};
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6781
|
+
const startTime = new Date();
|
|
6782
|
+
const config = { ...defaults, ...options };
|
|
6783
|
+
const rootDocument = findRootDocument(config.root, defaults);
|
|
6784
|
+
let foundPath;
|
|
6785
|
+
let count = 0;
|
|
6786
|
+
for (const candidate of search(input, config, rootDocument)) {
|
|
6787
|
+
const elapsedTimeMs = new Date().getTime() - startTime.getTime();
|
|
6788
|
+
if (elapsedTimeMs > config.timeoutMs ||
|
|
6789
|
+
count >= config.maxNumberOfPathChecks) {
|
|
6790
|
+
const fPath = fallback(input, rootDocument);
|
|
6791
|
+
if (!fPath) {
|
|
6792
|
+
throw new Error(`Timeout: Can't find a unique selector after ${config.timeoutMs}ms`);
|
|
6793
|
+
}
|
|
6794
|
+
return selector(fPath);
|
|
6795
|
+
}
|
|
6796
|
+
count++;
|
|
6797
|
+
if (unique(candidate, rootDocument)) {
|
|
6798
|
+
foundPath = candidate;
|
|
6799
|
+
break;
|
|
6711
6800
|
}
|
|
6712
|
-
return selector(path);
|
|
6713
6801
|
}
|
|
6714
|
-
|
|
6802
|
+
if (!foundPath) {
|
|
6715
6803
|
throw new Error(`Selector was not found.`);
|
|
6716
6804
|
}
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
return rootNode.ownerDocument;
|
|
6805
|
+
const optimized = [
|
|
6806
|
+
...optimize(foundPath, input, config, rootDocument, startTime),
|
|
6807
|
+
];
|
|
6808
|
+
optimized.sort(byPenalty);
|
|
6809
|
+
if (optimized.length > 0) {
|
|
6810
|
+
return selector(optimized[0]);
|
|
6724
6811
|
}
|
|
6725
|
-
return
|
|
6812
|
+
return selector(foundPath);
|
|
6726
6813
|
}
|
|
6727
|
-
function
|
|
6728
|
-
|
|
6729
|
-
let
|
|
6814
|
+
function* search(input, config, rootDocument) {
|
|
6815
|
+
const stack = [];
|
|
6816
|
+
let paths = [];
|
|
6730
6817
|
let current = input;
|
|
6731
6818
|
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) {
|
|
6819
|
+
while (current && current !== rootDocument) {
|
|
6820
|
+
const level = tie(current, config);
|
|
6821
|
+
for (const node of level) {
|
|
6766
6822
|
node.level = i;
|
|
6767
6823
|
}
|
|
6768
6824
|
stack.push(level);
|
|
6769
|
-
if (stack.length >= config.seedMinLength) {
|
|
6770
|
-
path = findUniquePath(stack, fallback);
|
|
6771
|
-
if (path) {
|
|
6772
|
-
break;
|
|
6773
|
-
}
|
|
6774
|
-
}
|
|
6775
6825
|
current = current.parentElement;
|
|
6776
6826
|
i++;
|
|
6827
|
+
paths.push(...combinations(stack));
|
|
6828
|
+
if (i >= config.seedMinLength) {
|
|
6829
|
+
paths.sort(byPenalty);
|
|
6830
|
+
for (const candidate of paths) {
|
|
6831
|
+
yield candidate;
|
|
6832
|
+
}
|
|
6833
|
+
paths = [];
|
|
6834
|
+
}
|
|
6777
6835
|
}
|
|
6778
|
-
|
|
6779
|
-
|
|
6836
|
+
paths.sort(byPenalty);
|
|
6837
|
+
for (const candidate of paths) {
|
|
6838
|
+
yield candidate;
|
|
6780
6839
|
}
|
|
6781
|
-
|
|
6782
|
-
|
|
6840
|
+
}
|
|
6841
|
+
function wordLike(name) {
|
|
6842
|
+
if (/^[a-z\-]{3,}$/i.test(name)) {
|
|
6843
|
+
const words = name.split(/-|[A-Z]/);
|
|
6844
|
+
for (const word of words) {
|
|
6845
|
+
if (word.length <= 2) {
|
|
6846
|
+
return false;
|
|
6847
|
+
}
|
|
6848
|
+
if (/[^aeiou]{4,}/i.test(word)) {
|
|
6849
|
+
return false;
|
|
6850
|
+
}
|
|
6851
|
+
}
|
|
6852
|
+
return true;
|
|
6783
6853
|
}
|
|
6784
|
-
return
|
|
6854
|
+
return false;
|
|
6785
6855
|
}
|
|
6786
|
-
function
|
|
6787
|
-
const
|
|
6788
|
-
|
|
6789
|
-
|
|
6856
|
+
function tie(element, config) {
|
|
6857
|
+
const level = [];
|
|
6858
|
+
const elementId = element.getAttribute('id');
|
|
6859
|
+
if (elementId && config.idName(elementId)) {
|
|
6860
|
+
level.push({
|
|
6861
|
+
name: '#' + CSS.escape(elementId),
|
|
6862
|
+
penalty: 0,
|
|
6863
|
+
});
|
|
6790
6864
|
}
|
|
6791
|
-
for (let
|
|
6792
|
-
|
|
6793
|
-
|
|
6865
|
+
for (let i = 0; i < element.classList.length; i++) {
|
|
6866
|
+
const name = element.classList[i];
|
|
6867
|
+
if (config.className(name)) {
|
|
6868
|
+
level.push({
|
|
6869
|
+
name: '.' + CSS.escape(name),
|
|
6870
|
+
penalty: 1,
|
|
6871
|
+
});
|
|
6794
6872
|
}
|
|
6795
6873
|
}
|
|
6796
|
-
|
|
6874
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
6875
|
+
const attr = element.attributes[i];
|
|
6876
|
+
if (config.attr(attr.name, attr.value)) {
|
|
6877
|
+
level.push({
|
|
6878
|
+
name: `[${CSS.escape(attr.name)}="${CSS.escape(attr.value)}"]`,
|
|
6879
|
+
penalty: 2,
|
|
6880
|
+
});
|
|
6881
|
+
}
|
|
6882
|
+
}
|
|
6883
|
+
const tagName = element.tagName.toLowerCase();
|
|
6884
|
+
if (config.tagName(tagName)) {
|
|
6885
|
+
level.push({
|
|
6886
|
+
name: tagName,
|
|
6887
|
+
penalty: 5,
|
|
6888
|
+
});
|
|
6889
|
+
const index = indexOf(element, tagName);
|
|
6890
|
+
if (index !== undefined) {
|
|
6891
|
+
level.push({
|
|
6892
|
+
name: nthOfType(tagName, index),
|
|
6893
|
+
penalty: 10,
|
|
6894
|
+
});
|
|
6895
|
+
}
|
|
6896
|
+
}
|
|
6897
|
+
const nth = indexOf(element);
|
|
6898
|
+
if (nth !== undefined) {
|
|
6899
|
+
level.push({
|
|
6900
|
+
name: nthChild(tagName, nth),
|
|
6901
|
+
penalty: 50,
|
|
6902
|
+
});
|
|
6903
|
+
}
|
|
6904
|
+
return level;
|
|
6797
6905
|
}
|
|
6798
6906
|
function selector(path) {
|
|
6799
6907
|
let node = path[0];
|
|
@@ -6813,69 +6921,23 @@ function selector(path) {
|
|
|
6813
6921
|
function penalty(path) {
|
|
6814
6922
|
return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);
|
|
6815
6923
|
}
|
|
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;
|
|
6860
|
-
}
|
|
6861
|
-
function any() {
|
|
6862
|
-
return {
|
|
6863
|
-
name: '*',
|
|
6864
|
-
penalty: 3,
|
|
6865
|
-
};
|
|
6924
|
+
function byPenalty(a, b) {
|
|
6925
|
+
return penalty(a) - penalty(b);
|
|
6866
6926
|
}
|
|
6867
|
-
function
|
|
6927
|
+
function indexOf(input, tagName) {
|
|
6868
6928
|
const parent = input.parentNode;
|
|
6869
6929
|
if (!parent) {
|
|
6870
|
-
return
|
|
6930
|
+
return undefined;
|
|
6871
6931
|
}
|
|
6872
6932
|
let child = parent.firstChild;
|
|
6873
6933
|
if (!child) {
|
|
6874
|
-
return
|
|
6934
|
+
return undefined;
|
|
6875
6935
|
}
|
|
6876
6936
|
let i = 0;
|
|
6877
6937
|
while (child) {
|
|
6878
|
-
if (child.nodeType === Node.ELEMENT_NODE
|
|
6938
|
+
if (child.nodeType === Node.ELEMENT_NODE &&
|
|
6939
|
+
(tagName === undefined ||
|
|
6940
|
+
child.tagName.toLowerCase() === tagName)) {
|
|
6879
6941
|
i++;
|
|
6880
6942
|
}
|
|
6881
6943
|
if (child === input) {
|
|
@@ -6885,24 +6947,39 @@ function index(input) {
|
|
|
6885
6947
|
}
|
|
6886
6948
|
return i;
|
|
6887
6949
|
}
|
|
6888
|
-
function
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6950
|
+
function fallback(input, rootDocument) {
|
|
6951
|
+
let i = 0;
|
|
6952
|
+
let current = input;
|
|
6953
|
+
const path = [];
|
|
6954
|
+
while (current && current !== rootDocument) {
|
|
6955
|
+
const tagName = current.tagName.toLowerCase();
|
|
6956
|
+
const index = indexOf(current, tagName);
|
|
6957
|
+
if (index === undefined) {
|
|
6958
|
+
return;
|
|
6959
|
+
}
|
|
6960
|
+
path.push({
|
|
6961
|
+
name: nthOfType(tagName, index),
|
|
6962
|
+
penalty: NaN,
|
|
6963
|
+
level: i,
|
|
6964
|
+
});
|
|
6965
|
+
current = current.parentElement;
|
|
6966
|
+
i++;
|
|
6967
|
+
}
|
|
6968
|
+
if (unique(path, rootDocument)) {
|
|
6969
|
+
return path;
|
|
6970
|
+
}
|
|
6896
6971
|
}
|
|
6897
|
-
function
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
return list;
|
|
6972
|
+
function nthChild(tagName, index) {
|
|
6973
|
+
if (tagName === 'html') {
|
|
6974
|
+
return 'html';
|
|
6901
6975
|
}
|
|
6902
|
-
return
|
|
6976
|
+
return `${tagName}:nth-child(${index})`;
|
|
6903
6977
|
}
|
|
6904
|
-
function
|
|
6905
|
-
|
|
6978
|
+
function nthOfType(tagName, index) {
|
|
6979
|
+
if (tagName === 'html') {
|
|
6980
|
+
return 'html';
|
|
6981
|
+
}
|
|
6982
|
+
return `${tagName}:nth-of-type(${index})`;
|
|
6906
6983
|
}
|
|
6907
6984
|
function* combinations(stack, path = []) {
|
|
6908
6985
|
if (stack.length > 0) {
|
|
@@ -6914,44 +6991,50 @@ function* combinations(stack, path = []) {
|
|
|
6914
6991
|
yield path;
|
|
6915
6992
|
}
|
|
6916
6993
|
}
|
|
6917
|
-
function
|
|
6918
|
-
|
|
6994
|
+
function findRootDocument(rootNode, defaults) {
|
|
6995
|
+
if (rootNode.nodeType === Node.DOCUMENT_NODE) {
|
|
6996
|
+
return rootNode;
|
|
6997
|
+
}
|
|
6998
|
+
if (rootNode === defaults.root) {
|
|
6999
|
+
return rootNode.ownerDocument;
|
|
7000
|
+
}
|
|
7001
|
+
return rootNode;
|
|
6919
7002
|
}
|
|
6920
|
-
function
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
7003
|
+
function unique(path, rootDocument) {
|
|
7004
|
+
const css = selector(path);
|
|
7005
|
+
switch (rootDocument.querySelectorAll(css).length) {
|
|
7006
|
+
case 0:
|
|
7007
|
+
throw new Error(`Can't select any node with this selector: ${css}`);
|
|
7008
|
+
case 1:
|
|
7009
|
+
return true;
|
|
7010
|
+
default:
|
|
7011
|
+
return false;
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
function* optimize(path, input, config, rootDocument, startTime) {
|
|
6924
7015
|
if (path.length > 2 && path.length > config.optimizedMinLength) {
|
|
6925
7016
|
for (let i = 1; i < path.length - 1; i++) {
|
|
6926
|
-
|
|
6927
|
-
|
|
7017
|
+
const elapsedTimeMs = new Date().getTime() - startTime.getTime();
|
|
7018
|
+
if (elapsedTimeMs > config.timeoutMs) {
|
|
7019
|
+
return;
|
|
6928
7020
|
}
|
|
6929
|
-
scope.counter += 1;
|
|
6930
7021
|
const newPath = [...path];
|
|
6931
7022
|
newPath.splice(i, 1);
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
return;
|
|
6935
|
-
}
|
|
6936
|
-
if (unique(newPath) && same(newPath, input)) {
|
|
7023
|
+
if (unique(newPath, rootDocument) &&
|
|
7024
|
+
rootDocument.querySelector(selector(newPath)) === input) {
|
|
6937
7025
|
yield newPath;
|
|
6938
|
-
|
|
6939
|
-
yield* optimize(newPath, input, scope);
|
|
7026
|
+
yield* optimize(newPath, input, config, rootDocument, startTime);
|
|
6940
7027
|
}
|
|
6941
7028
|
}
|
|
6942
7029
|
}
|
|
6943
7030
|
}
|
|
6944
|
-
function same(path, input) {
|
|
6945
|
-
return rootDocument.querySelector(selector(path)) === input;
|
|
6946
|
-
}
|
|
6947
7031
|
|
|
6948
7032
|
function _getSelector(target, document, options) {
|
|
6949
7033
|
const selector = finder(target, {
|
|
6950
7034
|
root: document.body,
|
|
6951
7035
|
seedMinLength: 3,
|
|
6952
7036
|
optimizedMinLength: options?.minSelectorDepth || 2,
|
|
6953
|
-
|
|
6954
|
-
maxNumberOfTries: options?.maxOptimiseTries || 10000,
|
|
7037
|
+
maxNumberOfPathChecks: options?.maxOptimiseTries || 10000,
|
|
6955
7038
|
});
|
|
6956
7039
|
return selector;
|
|
6957
7040
|
}
|
|
@@ -7218,6 +7301,11 @@ function Timing (app, opts) {
|
|
|
7218
7301
|
if (shouldSkip) {
|
|
7219
7302
|
return;
|
|
7220
7303
|
}
|
|
7304
|
+
const failed = entry.responseEnd === 0
|
|
7305
|
+
|| (entry.transferSize === 0 && entry.decodedBodySize === 0);
|
|
7306
|
+
if (failed) {
|
|
7307
|
+
app.send(ResourceTiming(entry.startTime + getTimeOrigin(), 0, 0, 0, 0, 0, entry.name, entry.initiatorType, 0, true));
|
|
7308
|
+
}
|
|
7221
7309
|
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
7310
|
// @ts-ignore
|
|
7223
7311
|
(entry.responseStatus && entry.responseStatus === 304) || entry.transferSize === 0));
|
|
@@ -9068,11 +9156,8 @@ class API {
|
|
|
9068
9156
|
};
|
|
9069
9157
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9070
9158
|
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',
|
|
9159
|
+
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9160
|
+
trackerVersion: '15.0.5-beta.0',
|
|
9076
9161
|
projectKey: this.options.projectKey,
|
|
9077
9162
|
doNotTrack,
|
|
9078
9163
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|