@openreplay/tracker 15.0.2 → 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 +275 -187
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/guards.d.ts +1 -0
- package/dist/lib/index.js +275 -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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function isNode(sth: any): sth is Node;
|
|
2
2
|
export declare function isSVGElement(node: Element): node is SVGElement;
|
|
3
|
+
export declare function isUseElement(node: Element): node is SVGUseElement;
|
|
3
4
|
export declare function isElementNode(node: Node): node is Element;
|
|
4
5
|
export declare function isCommentNode(node: Node): node is Comment;
|
|
5
6
|
export declare function isTextNode(node: Node): node is Text;
|
package/dist/lib/index.js
CHANGED
|
@@ -2326,7 +2326,7 @@ const containerStyle = {
|
|
|
2326
2326
|
alignItems: 'center',
|
|
2327
2327
|
padding: '1.5rem',
|
|
2328
2328
|
borderRadius: '2px',
|
|
2329
|
-
border: '1px solid
|
|
2329
|
+
border: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2330
2330
|
background: '#FFF',
|
|
2331
2331
|
width: '22rem',
|
|
2332
2332
|
};
|
|
@@ -2338,7 +2338,7 @@ const containerWidgetStyle = {
|
|
|
2338
2338
|
padding: 'unset',
|
|
2339
2339
|
fontFamily: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`,
|
|
2340
2340
|
'border-radius': '2px',
|
|
2341
|
-
border: '1px solid
|
|
2341
|
+
border: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2342
2342
|
background: 'rgba(255, 255, 255, 0.75)',
|
|
2343
2343
|
width: '22rem',
|
|
2344
2344
|
};
|
|
@@ -2420,7 +2420,7 @@ const descriptionWidgetStyle = {
|
|
|
2420
2420
|
boxSizing: 'border-box',
|
|
2421
2421
|
display: 'block',
|
|
2422
2422
|
width: '100%',
|
|
2423
|
-
borderBottom: '1px solid
|
|
2423
|
+
borderBottom: '1px solid rgb(255 255 255 / var(--tw-bg-opacity, 1))',
|
|
2424
2424
|
background: '#FFF',
|
|
2425
2425
|
padding: '0.65rem',
|
|
2426
2426
|
alignSelf: 'stretch',
|
|
@@ -3293,7 +3293,10 @@ function isNode(sth) {
|
|
|
3293
3293
|
return !!sth && sth.nodeType != null;
|
|
3294
3294
|
}
|
|
3295
3295
|
function isSVGElement(node) {
|
|
3296
|
-
return node.namespaceURI === 'http://www.w3.org/2000/svg';
|
|
3296
|
+
return (node.namespaceURI === 'http://www.w3.org/2000/svg' || node.localName === 'svg');
|
|
3297
|
+
}
|
|
3298
|
+
function isUseElement(node) {
|
|
3299
|
+
return node.localName === 'use';
|
|
3297
3300
|
}
|
|
3298
3301
|
function isElementNode(node) {
|
|
3299
3302
|
return node.nodeType === Node.ELEMENT_NODE;
|
|
@@ -3723,6 +3726,48 @@ class Nodes {
|
|
|
3723
3726
|
}
|
|
3724
3727
|
}
|
|
3725
3728
|
|
|
3729
|
+
const iconCache = {};
|
|
3730
|
+
const domParser = new DOMParser();
|
|
3731
|
+
async function parseUseEl(useElement, mode) {
|
|
3732
|
+
try {
|
|
3733
|
+
const href = useElement.getAttribute('xlink:href') || useElement.getAttribute('href');
|
|
3734
|
+
if (!href) {
|
|
3735
|
+
console.debug('Openreplay: xlink:href or href not found on <use>.');
|
|
3736
|
+
return;
|
|
3737
|
+
}
|
|
3738
|
+
const [url, symbolId] = href.split('#');
|
|
3739
|
+
if (!url || !symbolId) {
|
|
3740
|
+
console.debug('Openreplay: Invalid xlink:href or href found on <use>.');
|
|
3741
|
+
return;
|
|
3742
|
+
}
|
|
3743
|
+
if (iconCache[symbolId]) {
|
|
3744
|
+
return iconCache[symbolId];
|
|
3745
|
+
}
|
|
3746
|
+
const response = await fetch(url);
|
|
3747
|
+
const svgText = await response.text();
|
|
3748
|
+
const svgDoc = domParser.parseFromString(svgText, 'image/svg+xml');
|
|
3749
|
+
const symbol = svgDoc.getElementById(symbolId);
|
|
3750
|
+
if (!symbol) {
|
|
3751
|
+
console.debug('Openreplay: Symbol not found in SVG.');
|
|
3752
|
+
return;
|
|
3753
|
+
}
|
|
3754
|
+
if (mode === 'inline') ;
|
|
3755
|
+
if (mode === 'svgtext') {
|
|
3756
|
+
const inlineSvg = `
|
|
3757
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="${symbol.getAttribute('viewBox') || '0 0 24 24'}">
|
|
3758
|
+
${symbol.innerHTML}
|
|
3759
|
+
</svg>
|
|
3760
|
+
`.trim();
|
|
3761
|
+
iconCache[symbolId] = inlineSvg;
|
|
3762
|
+
return inlineSvg;
|
|
3763
|
+
}
|
|
3764
|
+
if (mode === 'dataurl') ;
|
|
3765
|
+
console.debug(`Openreplay: Unknown mode: ${mode}. Use "inline" or "dataurl".`);
|
|
3766
|
+
}
|
|
3767
|
+
catch (error) {
|
|
3768
|
+
console.error('Openreplay: Error processing <use> element:', error);
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3726
3771
|
function isIgnored(node) {
|
|
3727
3772
|
if (isCommentNode(node)) {
|
|
3728
3773
|
return true;
|
|
@@ -3861,7 +3906,19 @@ class Observer {
|
|
|
3861
3906
|
if (value === null) {
|
|
3862
3907
|
this.app.send(RemoveNodeAttribute(id, name));
|
|
3863
3908
|
}
|
|
3864
|
-
|
|
3909
|
+
if (isUseElement(node) && name === 'href') {
|
|
3910
|
+
parseUseEl(node, 'svgtext')
|
|
3911
|
+
.then((svgData) => {
|
|
3912
|
+
if (svgData) {
|
|
3913
|
+
this.app.send(SetNodeAttribute(id, name, `_$OPENREPLAY_SPRITE$_${svgData}`));
|
|
3914
|
+
}
|
|
3915
|
+
})
|
|
3916
|
+
.catch((e) => {
|
|
3917
|
+
console.error('Openreplay: Error parsing <use> element:', e);
|
|
3918
|
+
});
|
|
3919
|
+
return;
|
|
3920
|
+
}
|
|
3921
|
+
if (name === 'href') {
|
|
3865
3922
|
if (value.length > 1e5) {
|
|
3866
3923
|
value = '';
|
|
3867
3924
|
}
|
|
@@ -4644,7 +4701,7 @@ class App {
|
|
|
4644
4701
|
this.stopCallbacks = [];
|
|
4645
4702
|
this.commitCallbacks = [];
|
|
4646
4703
|
this.activityState = ActivityState.NotActive;
|
|
4647
|
-
this.version = '15.0.
|
|
4704
|
+
this.version = '15.0.5-beta.0'; // TODO: version compatability check inside each plugin.
|
|
4648
4705
|
this.socketMode = false;
|
|
4649
4706
|
this.compressionThreshold = 24 * 1000;
|
|
4650
4707
|
this.bc = null;
|
|
@@ -4990,6 +5047,9 @@ class App {
|
|
|
4990
5047
|
const host = location.hostname.split('.').slice(-2).join('_');
|
|
4991
5048
|
this.bc = new BroadcastChannel(`rick_${host}`);
|
|
4992
5049
|
}
|
|
5050
|
+
else if (this.options.forceSingleTab) {
|
|
5051
|
+
this.allowAppStart();
|
|
5052
|
+
}
|
|
4993
5053
|
this.revID = this.options.revID;
|
|
4994
5054
|
this.localStorage = this.options.localStorage ?? window.localStorage;
|
|
4995
5055
|
this.sessionStorage = this.options.sessionStorage ?? window.sessionStorage;
|
|
@@ -6674,122 +6734,170 @@ function Input (app, opts) {
|
|
|
6674
6734
|
// License: MIT
|
|
6675
6735
|
// Author: Anton Medvedev <anton@medv.io>
|
|
6676
6736
|
// Source: https://github.com/antonmedv/finder
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
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. */
|
|
6680
6759
|
function finder(input, options) {
|
|
6681
|
-
start = new Date();
|
|
6682
6760
|
if (input.nodeType !== Node.ELEMENT_NODE) {
|
|
6683
6761
|
throw new Error(`Can't generate CSS selector for non-element node type.`);
|
|
6684
6762
|
}
|
|
6685
|
-
if (
|
|
6763
|
+
if (input.tagName.toLowerCase() === 'html') {
|
|
6686
6764
|
return 'html';
|
|
6687
6765
|
}
|
|
6688
6766
|
const defaults = {
|
|
6689
6767
|
root: document.body,
|
|
6690
|
-
idName:
|
|
6691
|
-
className:
|
|
6692
|
-
tagName:
|
|
6693
|
-
attr:
|
|
6694
|
-
|
|
6768
|
+
idName: idName,
|
|
6769
|
+
className: className,
|
|
6770
|
+
tagName: tagName,
|
|
6771
|
+
attr: attr,
|
|
6772
|
+
timeoutMs: 1000,
|
|
6773
|
+
seedMinLength: 3,
|
|
6695
6774
|
optimizedMinLength: 2,
|
|
6696
|
-
|
|
6697
|
-
maxNumberOfTries: 10000,
|
|
6698
|
-
timeoutMs: undefined,
|
|
6775
|
+
maxNumberOfPathChecks: Infinity,
|
|
6699
6776
|
};
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
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;
|
|
6707
6796
|
}
|
|
6708
|
-
return selector(path);
|
|
6709
6797
|
}
|
|
6710
|
-
|
|
6798
|
+
if (!foundPath) {
|
|
6711
6799
|
throw new Error(`Selector was not found.`);
|
|
6712
6800
|
}
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
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]);
|
|
6720
6807
|
}
|
|
6721
|
-
return
|
|
6808
|
+
return selector(foundPath);
|
|
6722
6809
|
}
|
|
6723
|
-
function
|
|
6724
|
-
|
|
6725
|
-
let
|
|
6810
|
+
function* search(input, config, rootDocument) {
|
|
6811
|
+
const stack = [];
|
|
6812
|
+
let paths = [];
|
|
6726
6813
|
let current = input;
|
|
6727
6814
|
let i = 0;
|
|
6728
|
-
while (current) {
|
|
6729
|
-
const
|
|
6730
|
-
|
|
6731
|
-
throw new Error(`Timeout: Can't find a unique selector after ${elapsedTime}ms`);
|
|
6732
|
-
}
|
|
6733
|
-
let level = maybe(id(current)) ||
|
|
6734
|
-
maybe(...attr(current)) ||
|
|
6735
|
-
maybe(...classNames(current)) ||
|
|
6736
|
-
maybe(tagName(current)) || [any()];
|
|
6737
|
-
const nth = index(current);
|
|
6738
|
-
if (limit == 'all') {
|
|
6739
|
-
if (nth) {
|
|
6740
|
-
level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));
|
|
6741
|
-
}
|
|
6742
|
-
}
|
|
6743
|
-
else if (limit == 'two') {
|
|
6744
|
-
level = level.slice(0, 1);
|
|
6745
|
-
if (nth) {
|
|
6746
|
-
level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));
|
|
6747
|
-
}
|
|
6748
|
-
}
|
|
6749
|
-
else if (limit == 'one') {
|
|
6750
|
-
const [node] = (level = level.slice(0, 1));
|
|
6751
|
-
if (nth && dispensableNth(node)) {
|
|
6752
|
-
level = [nthChild(node, nth)];
|
|
6753
|
-
}
|
|
6754
|
-
}
|
|
6755
|
-
else if (limit == 'none') {
|
|
6756
|
-
level = [any()];
|
|
6757
|
-
if (nth) {
|
|
6758
|
-
level = [nthChild(level[0], nth)];
|
|
6759
|
-
}
|
|
6760
|
-
}
|
|
6761
|
-
for (let node of level) {
|
|
6815
|
+
while (current && current !== rootDocument) {
|
|
6816
|
+
const level = tie(current, config);
|
|
6817
|
+
for (const node of level) {
|
|
6762
6818
|
node.level = i;
|
|
6763
6819
|
}
|
|
6764
6820
|
stack.push(level);
|
|
6765
|
-
if (stack.length >= config.seedMinLength) {
|
|
6766
|
-
path = findUniquePath(stack, fallback);
|
|
6767
|
-
if (path) {
|
|
6768
|
-
break;
|
|
6769
|
-
}
|
|
6770
|
-
}
|
|
6771
6821
|
current = current.parentElement;
|
|
6772
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
|
+
}
|
|
6773
6831
|
}
|
|
6774
|
-
|
|
6775
|
-
|
|
6832
|
+
paths.sort(byPenalty);
|
|
6833
|
+
for (const candidate of paths) {
|
|
6834
|
+
yield candidate;
|
|
6776
6835
|
}
|
|
6777
|
-
|
|
6778
|
-
|
|
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;
|
|
6779
6849
|
}
|
|
6780
|
-
return
|
|
6850
|
+
return false;
|
|
6781
6851
|
}
|
|
6782
|
-
function
|
|
6783
|
-
const
|
|
6784
|
-
|
|
6785
|
-
|
|
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
|
+
});
|
|
6786
6860
|
}
|
|
6787
|
-
for (let
|
|
6788
|
-
|
|
6789
|
-
|
|
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
|
+
});
|
|
6790
6868
|
}
|
|
6791
6869
|
}
|
|
6792
|
-
|
|
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;
|
|
6793
6901
|
}
|
|
6794
6902
|
function selector(path) {
|
|
6795
6903
|
let node = path[0];
|
|
@@ -6809,69 +6917,23 @@ function selector(path) {
|
|
|
6809
6917
|
function penalty(path) {
|
|
6810
6918
|
return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);
|
|
6811
6919
|
}
|
|
6812
|
-
function
|
|
6813
|
-
|
|
6814
|
-
switch (rootDocument.querySelectorAll(css).length) {
|
|
6815
|
-
case 0:
|
|
6816
|
-
throw new Error(`Can't select any node with this selector: ${css}`);
|
|
6817
|
-
case 1:
|
|
6818
|
-
return true;
|
|
6819
|
-
default:
|
|
6820
|
-
return false;
|
|
6821
|
-
}
|
|
6822
|
-
}
|
|
6823
|
-
function id(input) {
|
|
6824
|
-
const elementId = input.getAttribute('id');
|
|
6825
|
-
if (elementId && config.idName(elementId)) {
|
|
6826
|
-
return {
|
|
6827
|
-
name: '#' + CSS.escape(elementId),
|
|
6828
|
-
penalty: 0,
|
|
6829
|
-
};
|
|
6830
|
-
}
|
|
6831
|
-
return null;
|
|
6832
|
-
}
|
|
6833
|
-
function attr(input) {
|
|
6834
|
-
const attrs = Array.from(input.attributes).filter((attr) => config.attr(attr.name, attr.value));
|
|
6835
|
-
return attrs.map((attr) => ({
|
|
6836
|
-
name: `[${CSS.escape(attr.name)}="${CSS.escape(attr.value)}"]`,
|
|
6837
|
-
penalty: 0.5,
|
|
6838
|
-
}));
|
|
6839
|
-
}
|
|
6840
|
-
function classNames(input) {
|
|
6841
|
-
const names = Array.from(input.classList).filter(config.className);
|
|
6842
|
-
return names.map((name) => ({
|
|
6843
|
-
name: '.' + CSS.escape(name),
|
|
6844
|
-
penalty: 1,
|
|
6845
|
-
}));
|
|
6846
|
-
}
|
|
6847
|
-
function tagName(input) {
|
|
6848
|
-
const name = input.tagName.toLowerCase();
|
|
6849
|
-
if (config.tagName(name)) {
|
|
6850
|
-
return {
|
|
6851
|
-
name,
|
|
6852
|
-
penalty: 2,
|
|
6853
|
-
};
|
|
6854
|
-
}
|
|
6855
|
-
return null;
|
|
6856
|
-
}
|
|
6857
|
-
function any() {
|
|
6858
|
-
return {
|
|
6859
|
-
name: '*',
|
|
6860
|
-
penalty: 3,
|
|
6861
|
-
};
|
|
6920
|
+
function byPenalty(a, b) {
|
|
6921
|
+
return penalty(a) - penalty(b);
|
|
6862
6922
|
}
|
|
6863
|
-
function
|
|
6923
|
+
function indexOf(input, tagName) {
|
|
6864
6924
|
const parent = input.parentNode;
|
|
6865
6925
|
if (!parent) {
|
|
6866
|
-
return
|
|
6926
|
+
return undefined;
|
|
6867
6927
|
}
|
|
6868
6928
|
let child = parent.firstChild;
|
|
6869
6929
|
if (!child) {
|
|
6870
|
-
return
|
|
6930
|
+
return undefined;
|
|
6871
6931
|
}
|
|
6872
6932
|
let i = 0;
|
|
6873
6933
|
while (child) {
|
|
6874
|
-
if (child.nodeType === Node.ELEMENT_NODE
|
|
6934
|
+
if (child.nodeType === Node.ELEMENT_NODE &&
|
|
6935
|
+
(tagName === undefined ||
|
|
6936
|
+
child.tagName.toLowerCase() === tagName)) {
|
|
6875
6937
|
i++;
|
|
6876
6938
|
}
|
|
6877
6939
|
if (child === input) {
|
|
@@ -6881,24 +6943,39 @@ function index(input) {
|
|
|
6881
6943
|
}
|
|
6882
6944
|
return i;
|
|
6883
6945
|
}
|
|
6884
|
-
function
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
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
|
+
}
|
|
6892
6967
|
}
|
|
6893
|
-
function
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
return list;
|
|
6968
|
+
function nthChild(tagName, index) {
|
|
6969
|
+
if (tagName === 'html') {
|
|
6970
|
+
return 'html';
|
|
6897
6971
|
}
|
|
6898
|
-
return
|
|
6972
|
+
return `${tagName}:nth-child(${index})`;
|
|
6899
6973
|
}
|
|
6900
|
-
function
|
|
6901
|
-
|
|
6974
|
+
function nthOfType(tagName, index) {
|
|
6975
|
+
if (tagName === 'html') {
|
|
6976
|
+
return 'html';
|
|
6977
|
+
}
|
|
6978
|
+
return `${tagName}:nth-of-type(${index})`;
|
|
6902
6979
|
}
|
|
6903
6980
|
function* combinations(stack, path = []) {
|
|
6904
6981
|
if (stack.length > 0) {
|
|
@@ -6910,44 +6987,50 @@ function* combinations(stack, path = []) {
|
|
|
6910
6987
|
yield path;
|
|
6911
6988
|
}
|
|
6912
6989
|
}
|
|
6913
|
-
function
|
|
6914
|
-
|
|
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
|
+
}
|
|
6915
7009
|
}
|
|
6916
|
-
function* optimize(path, input,
|
|
6917
|
-
counter: 0,
|
|
6918
|
-
visited: new Map(),
|
|
6919
|
-
}) {
|
|
7010
|
+
function* optimize(path, input, config, rootDocument, startTime) {
|
|
6920
7011
|
if (path.length > 2 && path.length > config.optimizedMinLength) {
|
|
6921
7012
|
for (let i = 1; i < path.length - 1; i++) {
|
|
6922
|
-
|
|
6923
|
-
|
|
7013
|
+
const elapsedTimeMs = new Date().getTime() - startTime.getTime();
|
|
7014
|
+
if (elapsedTimeMs > config.timeoutMs) {
|
|
7015
|
+
return;
|
|
6924
7016
|
}
|
|
6925
|
-
scope.counter += 1;
|
|
6926
7017
|
const newPath = [...path];
|
|
6927
7018
|
newPath.splice(i, 1);
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
return;
|
|
6931
|
-
}
|
|
6932
|
-
if (unique(newPath) && same(newPath, input)) {
|
|
7019
|
+
if (unique(newPath, rootDocument) &&
|
|
7020
|
+
rootDocument.querySelector(selector(newPath)) === input) {
|
|
6933
7021
|
yield newPath;
|
|
6934
|
-
|
|
6935
|
-
yield* optimize(newPath, input, scope);
|
|
7022
|
+
yield* optimize(newPath, input, config, rootDocument, startTime);
|
|
6936
7023
|
}
|
|
6937
7024
|
}
|
|
6938
7025
|
}
|
|
6939
7026
|
}
|
|
6940
|
-
function same(path, input) {
|
|
6941
|
-
return rootDocument.querySelector(selector(path)) === input;
|
|
6942
|
-
}
|
|
6943
7027
|
|
|
6944
7028
|
function _getSelector(target, document, options) {
|
|
6945
7029
|
const selector = finder(target, {
|
|
6946
7030
|
root: document.body,
|
|
6947
7031
|
seedMinLength: 3,
|
|
6948
7032
|
optimizedMinLength: options?.minSelectorDepth || 2,
|
|
6949
|
-
|
|
6950
|
-
maxNumberOfTries: options?.maxOptimiseTries || 10000,
|
|
7033
|
+
maxNumberOfPathChecks: options?.maxOptimiseTries || 10000,
|
|
6951
7034
|
});
|
|
6952
7035
|
return selector;
|
|
6953
7036
|
}
|
|
@@ -7214,6 +7297,11 @@ function Timing (app, opts) {
|
|
|
7214
7297
|
if (shouldSkip) {
|
|
7215
7298
|
return;
|
|
7216
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
|
+
}
|
|
7217
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,
|
|
7218
7306
|
// @ts-ignore
|
|
7219
7307
|
(entry.responseStatus && entry.responseStatus === 304) || entry.transferSize === 0));
|
|
@@ -8805,6 +8893,9 @@ function Network (app, opts = {}) {
|
|
|
8805
8893
|
/* ====== modern way ====== */
|
|
8806
8894
|
if (options.useProxy) {
|
|
8807
8895
|
return createNetworkProxy(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => {
|
|
8896
|
+
if (options.failuresOnly && message.status < 400) {
|
|
8897
|
+
return;
|
|
8898
|
+
}
|
|
8808
8899
|
app.send(NetworkRequest(message.requestType, message.method, message.url, message.request, message.response, message.status, message.startTime + getTimeOrigin(), message.duration, message.responseSize));
|
|
8809
8900
|
}, (url) => app.isServiceURL(url), { xhr: true, fetch: true, beacon: true }, options.tokenUrlMatcher);
|
|
8810
8901
|
}
|
|
@@ -9061,11 +9152,8 @@ class API {
|
|
|
9061
9152
|
};
|
|
9062
9153
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9063
9154
|
const doNotTrack = this.checkDoNotTrack();
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
req.open('POST', orig + '/v1/web/not-started');
|
|
9067
|
-
req.send(JSON.stringify({
|
|
9068
|
-
trackerVersion: '15.0.2',
|
|
9155
|
+
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9156
|
+
trackerVersion: '15.0.5-beta.0',
|
|
9069
9157
|
projectKey: this.options.projectKey,
|
|
9070
9158
|
doNotTrack,
|
|
9071
9159
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|