clarity-js 0.7.2 → 0.7.4
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/build/clarity.insight.js +1 -0
- package/build/clarity.js +2054 -2076
- package/build/clarity.min.js +1 -1
- package/build/clarity.module.js +2051 -2071
- package/package.json +15 -13
- package/rollup.config.ts +29 -5
- package/src/core/blank.ts +9 -0
- package/src/core/config.ts +0 -1
- package/src/core/version.ts +1 -1
- package/src/data/encode.ts +1 -1
- package/src/data/extract.ts +45 -34
- package/src/data/upload.ts +22 -14
- package/src/diagnostic/index.ts +3 -3
- package/src/interaction/encode.ts +12 -12
- package/src/layout/dom.ts +4 -35
- package/src/layout/mutation.ts +4 -4
- package/src/performance/observer.ts +1 -6
- package/tsconfig.json +1 -1
- package/types/core.d.ts +0 -2
- package/types/data.d.ts +8 -3
- package/types/layout.d.ts +0 -1
package/build/clarity.js
CHANGED
|
@@ -1,96 +1,76 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var dom = /*#__PURE__*/Object.freeze({
|
|
6
|
-
__proto__: null,
|
|
7
|
-
get start () { return start$i; },
|
|
8
|
-
get stop () { return stop$g; },
|
|
9
|
-
get parse () { return parse$1; },
|
|
10
|
-
get getId () { return getId; },
|
|
11
|
-
get add () { return add; },
|
|
12
|
-
get update () { return update$1; },
|
|
13
|
-
get sameorigin () { return sameorigin; },
|
|
14
|
-
get iframe () { return iframe; },
|
|
15
|
-
get hashText () { return hashText; },
|
|
16
|
-
get getNode () { return getNode; },
|
|
17
|
-
get getValue () { return getValue; },
|
|
18
|
-
get get () { return get; },
|
|
19
|
-
get lookup () { return lookup; },
|
|
20
|
-
get has () { return has; },
|
|
21
|
-
get updates () { return updates$2; }
|
|
22
|
-
});
|
|
23
3
|
var upload$1 = /*#__PURE__*/Object.freeze({
|
|
24
4
|
__proto__: null,
|
|
25
|
-
get track () { return track$1; },
|
|
26
|
-
get start () { return start$f; },
|
|
27
5
|
get queue () { return queue; },
|
|
28
|
-
get
|
|
6
|
+
get start () { return start$f; },
|
|
7
|
+
get stop () { return stop$d; },
|
|
8
|
+
get track () { return track$1; }
|
|
29
9
|
});
|
|
30
10
|
var extract = /*#__PURE__*/Object.freeze({
|
|
31
11
|
__proto__: null,
|
|
32
|
-
get data () { return data$5; },
|
|
33
|
-
get keys () { return keys; },
|
|
34
|
-
get fragments () { return fragments; },
|
|
35
|
-
get start () { return start$c; },
|
|
36
12
|
get clone () { return clone; },
|
|
37
13
|
get compute () { return compute$4; },
|
|
14
|
+
get data () { return data$5; },
|
|
15
|
+
get keys () { return keys; },
|
|
38
16
|
get reset () { return reset$4; },
|
|
39
|
-
get
|
|
40
|
-
get stop () { return stop$b; }
|
|
17
|
+
get start () { return start$c; },
|
|
18
|
+
get stop () { return stop$b; },
|
|
19
|
+
get trigger () { return trigger$1; },
|
|
20
|
+
get update () { return update; }
|
|
41
21
|
});
|
|
42
22
|
var limit = /*#__PURE__*/Object.freeze({
|
|
43
23
|
__proto__: null,
|
|
44
|
-
get data () { return data$4; },
|
|
45
|
-
get start () { return start$b; },
|
|
46
24
|
get check () { return check$2; },
|
|
47
|
-
get trigger () { return trigger; },
|
|
48
25
|
get compute () { return compute$3; },
|
|
49
|
-
get
|
|
26
|
+
get data () { return data$4; },
|
|
27
|
+
get start () { return start$b; },
|
|
28
|
+
get stop () { return stop$a; },
|
|
29
|
+
get trigger () { return trigger; }
|
|
50
30
|
});
|
|
51
31
|
var dimension = /*#__PURE__*/Object.freeze({
|
|
52
32
|
__proto__: null,
|
|
33
|
+
get compute () { return compute$2; },
|
|
53
34
|
get data () { return data$3; },
|
|
54
|
-
get
|
|
35
|
+
get log () { return log; },
|
|
36
|
+
get reset () { return reset$3; },
|
|
55
37
|
get start () { return start$a; },
|
|
56
38
|
get stop () { return stop$9; },
|
|
57
|
-
get
|
|
58
|
-
get compute () { return compute$2; },
|
|
59
|
-
get reset () { return reset$3; }
|
|
39
|
+
get updates () { return updates; }
|
|
60
40
|
});
|
|
61
41
|
var metadata$1 = /*#__PURE__*/Object.freeze({
|
|
62
42
|
__proto__: null,
|
|
63
|
-
get data () { return data$2; },
|
|
64
43
|
get callbacks () { return callbacks; },
|
|
65
|
-
get start () { return start$9; },
|
|
66
|
-
get stop () { return stop$8; },
|
|
67
|
-
get metadata () { return metadata; },
|
|
68
|
-
get id () { return id; },
|
|
69
|
-
get consent () { return consent; },
|
|
70
44
|
get clear () { return clear; },
|
|
71
|
-
get
|
|
45
|
+
get consent () { return consent; },
|
|
46
|
+
get data () { return data$2; },
|
|
47
|
+
get id () { return id; },
|
|
48
|
+
get metadata () { return metadata; },
|
|
49
|
+
get save () { return save; },
|
|
50
|
+
get start () { return start$9; },
|
|
51
|
+
get stop () { return stop$8; }
|
|
72
52
|
});
|
|
73
53
|
var envelope$1 = /*#__PURE__*/Object.freeze({
|
|
74
54
|
__proto__: null,
|
|
75
55
|
get data () { return data$1; },
|
|
56
|
+
get envelope () { return envelope; },
|
|
76
57
|
get start () { return start$8; },
|
|
77
|
-
get stop () { return stop$7; }
|
|
78
|
-
get envelope () { return envelope; }
|
|
58
|
+
get stop () { return stop$7; }
|
|
79
59
|
});
|
|
80
60
|
var clarity = /*#__PURE__*/Object.freeze({
|
|
81
61
|
__proto__: null,
|
|
82
|
-
get version () { return version$1; },
|
|
83
|
-
get start () { return start; },
|
|
84
|
-
get pause () { return pause; },
|
|
85
|
-
get resume () { return resume; },
|
|
86
|
-
get stop () { return stop; },
|
|
87
62
|
get consent () { return consent; },
|
|
88
63
|
get event () { return event; },
|
|
64
|
+
get hashText () { return hashText; },
|
|
89
65
|
get identify () { return identify; },
|
|
66
|
+
get metadata () { return metadata; },
|
|
67
|
+
get pause () { return pause; },
|
|
68
|
+
get resume () { return resume; },
|
|
90
69
|
get set () { return set; },
|
|
70
|
+
get start () { return start; },
|
|
71
|
+
get stop () { return stop; },
|
|
91
72
|
get upgrade () { return upgrade; },
|
|
92
|
-
get
|
|
93
|
-
get hashText () { return hashText; }
|
|
73
|
+
get version () { return version$1; }
|
|
94
74
|
});
|
|
95
75
|
|
|
96
76
|
var w = window;
|
|
@@ -139,7 +119,6 @@ var config$1 = {
|
|
|
139
119
|
mask: [],
|
|
140
120
|
unmask: [],
|
|
141
121
|
regions: [],
|
|
142
|
-
extract: [],
|
|
143
122
|
cookies: [],
|
|
144
123
|
fraud: true,
|
|
145
124
|
checksum: [],
|
|
@@ -170,7 +149,7 @@ function stop$C() {
|
|
|
170
149
|
startTime = 0;
|
|
171
150
|
}
|
|
172
151
|
|
|
173
|
-
var version$1 = "0.7.
|
|
152
|
+
var version$1 = "0.7.4";
|
|
174
153
|
|
|
175
154
|
// tslint:disable: no-bitwise
|
|
176
155
|
function hash (input, precision) {
|
|
@@ -418,14 +397,14 @@ function stop$B() {
|
|
|
418
397
|
|
|
419
398
|
var baseline = /*#__PURE__*/Object.freeze({
|
|
420
399
|
__proto__: null,
|
|
421
|
-
get state () { return state$a; },
|
|
422
|
-
start: start$F,
|
|
423
|
-
reset: reset$q,
|
|
424
|
-
track: track$7,
|
|
425
400
|
activity: activity,
|
|
426
|
-
visibility: visibility,
|
|
427
401
|
compute: compute$c,
|
|
428
|
-
|
|
402
|
+
reset: reset$q,
|
|
403
|
+
start: start$F,
|
|
404
|
+
get state () { return state$a; },
|
|
405
|
+
stop: stop$B,
|
|
406
|
+
track: track$7,
|
|
407
|
+
visibility: visibility
|
|
429
408
|
});
|
|
430
409
|
|
|
431
410
|
var data$j = null;
|
|
@@ -536,8 +515,8 @@ function stop$z() {
|
|
|
536
515
|
var ping$1 = /*#__PURE__*/Object.freeze({
|
|
537
516
|
__proto__: null,
|
|
538
517
|
get data () { return data$h; },
|
|
539
|
-
start: start$D,
|
|
540
518
|
reset: reset$o,
|
|
519
|
+
start: start$D,
|
|
541
520
|
stop: stop$z
|
|
542
521
|
});
|
|
543
522
|
|
|
@@ -574,12 +553,12 @@ function reset$n() {
|
|
|
574
553
|
|
|
575
554
|
var summary = /*#__PURE__*/Object.freeze({
|
|
576
555
|
__proto__: null,
|
|
556
|
+
compute: compute$a,
|
|
577
557
|
get data () { return data$g; },
|
|
558
|
+
reset: reset$n,
|
|
578
559
|
start: start$C,
|
|
579
560
|
stop: stop$y,
|
|
580
|
-
track: track$6
|
|
581
|
-
compute: compute$a,
|
|
582
|
-
reset: reset$n
|
|
561
|
+
track: track$6
|
|
583
562
|
});
|
|
584
563
|
|
|
585
564
|
var data$f = null;
|
|
@@ -615,8 +594,8 @@ var upgrade$1 = /*#__PURE__*/Object.freeze({
|
|
|
615
594
|
__proto__: null,
|
|
616
595
|
get data () { return data$f; },
|
|
617
596
|
start: start$B,
|
|
618
|
-
|
|
619
|
-
|
|
597
|
+
stop: stop$x,
|
|
598
|
+
upgrade: upgrade
|
|
620
599
|
});
|
|
621
600
|
|
|
622
601
|
var data$e = null;
|
|
@@ -661,12 +640,12 @@ function stop$w() {
|
|
|
661
640
|
|
|
662
641
|
var variable = /*#__PURE__*/Object.freeze({
|
|
663
642
|
__proto__: null,
|
|
643
|
+
compute: compute$9,
|
|
664
644
|
get data () { return data$e; },
|
|
665
|
-
start: start$A,
|
|
666
|
-
set: set,
|
|
667
645
|
identify: identify,
|
|
668
|
-
compute: compute$9,
|
|
669
646
|
reset: reset$m,
|
|
647
|
+
set: set,
|
|
648
|
+
start: start$A,
|
|
670
649
|
stop: stop$w
|
|
671
650
|
});
|
|
672
651
|
|
|
@@ -701,7 +680,7 @@ function __generator(thisArg, body) {
|
|
|
701
680
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
702
681
|
function step(op) {
|
|
703
682
|
if (f) throw new TypeError("Generator is already executing.");
|
|
704
|
-
while (_) try {
|
|
683
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
705
684
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
706
685
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
707
686
|
switch (op[0]) {
|
|
@@ -919,2112 +898,2100 @@ function filter(value) {
|
|
|
919
898
|
|
|
920
899
|
var selector = /*#__PURE__*/Object.freeze({
|
|
921
900
|
__proto__: null,
|
|
922
|
-
|
|
923
|
-
|
|
901
|
+
get: get$1,
|
|
902
|
+
reset: reset$l
|
|
924
903
|
});
|
|
925
904
|
|
|
926
|
-
|
|
927
|
-
var
|
|
928
|
-
var
|
|
929
|
-
var
|
|
930
|
-
var
|
|
931
|
-
var
|
|
932
|
-
var
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
905
|
+
var index = 1;
|
|
906
|
+
var nodes = [];
|
|
907
|
+
var values = [];
|
|
908
|
+
var updateMap = [];
|
|
909
|
+
var hashMap = {};
|
|
910
|
+
var override = [];
|
|
911
|
+
var unmask = [];
|
|
912
|
+
var maskText = [];
|
|
913
|
+
var maskExclude = [];
|
|
914
|
+
var maskDisable = [];
|
|
915
|
+
var maskTags = [];
|
|
916
|
+
// The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
|
|
917
|
+
var idMap = null; // Maps node => id.
|
|
918
|
+
var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
|
|
919
|
+
var privacyMap = null; // Maps node => Privacy (enum)
|
|
920
|
+
var fraudMap = null; // Maps node => FraudId (number)
|
|
921
|
+
function start$x() {
|
|
922
|
+
reset$k();
|
|
923
|
+
parse$1(document, true);
|
|
939
924
|
}
|
|
940
|
-
function
|
|
941
|
-
|
|
942
|
-
resumeResolve();
|
|
943
|
-
pauseTask = null;
|
|
944
|
-
if (activeTask === null) {
|
|
945
|
-
run();
|
|
946
|
-
}
|
|
947
|
-
}
|
|
925
|
+
function stop$u() {
|
|
926
|
+
reset$k();
|
|
948
927
|
}
|
|
949
928
|
function reset$k() {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
}
|
|
967
|
-
promise = new Promise(function (resolve) {
|
|
968
|
-
var insert = priority === 1 /* Priority.High */ ? "unshift" : "push";
|
|
969
|
-
// Queue this task for asynchronous execution later
|
|
970
|
-
// We also store a unique page identifier (id) along with the task to ensure
|
|
971
|
-
// ensure that we do not accidentally execute this task in context of a different page
|
|
972
|
-
queuedTasks[insert]({ task: task, resolve: resolve, id: id() });
|
|
973
|
-
});
|
|
974
|
-
// If there is no active task running, and Clarity is not in pause state,
|
|
975
|
-
// invoke the first task in the queue synchronously. This ensures that we don't yield the thread during unload event
|
|
976
|
-
if (activeTask === null && pauseTask === null) {
|
|
977
|
-
run();
|
|
978
|
-
}
|
|
979
|
-
return [2 /*return*/, promise];
|
|
980
|
-
});
|
|
981
|
-
});
|
|
929
|
+
index = 1;
|
|
930
|
+
nodes = [];
|
|
931
|
+
values = [];
|
|
932
|
+
updateMap = [];
|
|
933
|
+
hashMap = {};
|
|
934
|
+
override = [];
|
|
935
|
+
unmask = [];
|
|
936
|
+
maskText = "address,password,contact" /* Mask.Text */.split("," /* Constant.Comma */);
|
|
937
|
+
maskExclude = "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.split("," /* Constant.Comma */);
|
|
938
|
+
maskDisable = "radio,checkbox,range,button,reset,submit" /* Mask.Disable */.split("," /* Constant.Comma */);
|
|
939
|
+
maskTags = "INPUT,SELECT,TEXTAREA" /* Mask.Tags */.split("," /* Constant.Comma */);
|
|
940
|
+
idMap = new WeakMap();
|
|
941
|
+
iframeMap = new WeakMap();
|
|
942
|
+
privacyMap = new WeakMap();
|
|
943
|
+
fraudMap = new WeakMap();
|
|
944
|
+
reset$l();
|
|
982
945
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
if (error) {
|
|
1003
|
-
log$1(0 /* Code.RunTask */, 1 /* Severity.Warning */, error.name, error.message, error.stack);
|
|
1004
|
-
}
|
|
1005
|
-
activeTask = null;
|
|
1006
|
-
run();
|
|
1007
|
-
});
|
|
946
|
+
// We parse new root nodes for any regions or masked nodes in the beginning (document) and
|
|
947
|
+
// later whenever there are new additions or modifications to DOM (mutations)
|
|
948
|
+
function parse$1(root, init) {
|
|
949
|
+
if (init === void 0) { init = false; }
|
|
950
|
+
// Wrap selectors in a try / catch block.
|
|
951
|
+
// It's possible for script to receive invalid selectors, e.g. "'#id'" with extra quotes, and cause the code below to fail
|
|
952
|
+
try {
|
|
953
|
+
// Parse unmask configuration into separate query selectors and override tokens as part of initialization
|
|
954
|
+
if (init) {
|
|
955
|
+
config$1.unmask.forEach(function (x) { return x.indexOf("!" /* Constant.Bang */) < 0 ? unmask.push(x) : override.push(x.substr(1)); });
|
|
956
|
+
}
|
|
957
|
+
// Since mutations may happen on leaf nodes too, e.g. text nodes, which may not support all selector APIs.
|
|
958
|
+
// We ensure that the root note supports querySelectorAll API before executing the code below to identify new regions.
|
|
959
|
+
if ("querySelectorAll" in root) {
|
|
960
|
+
config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$c(e, "".concat(x[0])); }); }); // Regions
|
|
961
|
+
config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
|
|
962
|
+
config$1.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
|
|
963
|
+
unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
|
|
964
|
+
}
|
|
1008
965
|
}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
var id = key(timer);
|
|
1012
|
-
if (id in tracker) {
|
|
1013
|
-
var elapsed = performance.now() - tracker[id].start;
|
|
1014
|
-
return (elapsed > tracker[id].yield) ? 0 /* Task.Wait */ : 1 /* Task.Run */;
|
|
966
|
+
catch (e) {
|
|
967
|
+
log$1(5 /* Code.Selector */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
1015
968
|
}
|
|
1016
|
-
// If this task is no longer being tracked, send stop message to the caller
|
|
1017
|
-
return 2 /* Task.Stop */;
|
|
1018
|
-
}
|
|
1019
|
-
function start$x(timer) {
|
|
1020
|
-
tracker[key(timer)] = { start: performance.now(), calls: 0, yield: 30 /* Setting.LongTask */ };
|
|
1021
969
|
}
|
|
1022
|
-
function
|
|
1023
|
-
|
|
1024
|
-
if (
|
|
1025
|
-
|
|
1026
|
-
var y = tracker[id].yield;
|
|
1027
|
-
start$x(timer);
|
|
1028
|
-
tracker[id].calls = c + 1;
|
|
1029
|
-
tracker[id].yield = y;
|
|
970
|
+
function getId(node, autogen) {
|
|
971
|
+
if (autogen === void 0) { autogen = false; }
|
|
972
|
+
if (node === null) {
|
|
973
|
+
return null;
|
|
1030
974
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
var duration = end - tracker[id].start;
|
|
1036
|
-
sum(timer.cost, duration);
|
|
1037
|
-
count$1(5 /* Metric.InvokeCount */);
|
|
1038
|
-
// For the first execution, which is synchronous, time is automatically counted towards TotalDuration.
|
|
1039
|
-
// However, for subsequent asynchronous runs, we need to manually update TotalDuration metric.
|
|
1040
|
-
if (tracker[id].calls > 0) {
|
|
1041
|
-
sum(4 /* Metric.TotalCost */, duration);
|
|
975
|
+
var id = idMap.get(node);
|
|
976
|
+
if (!id && autogen) {
|
|
977
|
+
id = index++;
|
|
978
|
+
idMap.set(node, id);
|
|
1042
979
|
}
|
|
980
|
+
return id ? id : null;
|
|
1043
981
|
}
|
|
1044
|
-
function
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
if (!pauseTask) return [3 /*break*/, 2];
|
|
1076
|
-
return [4 /*yield*/, pauseTask];
|
|
1077
|
-
case 1:
|
|
1078
|
-
_a.sent();
|
|
1079
|
-
_a.label = 2;
|
|
1080
|
-
case 2: return [2 /*return*/, new Promise(function (resolve) {
|
|
1081
|
-
requestIdleCallback(resolve, { timeout: idleTimeout });
|
|
1082
|
-
})];
|
|
1083
|
-
}
|
|
1084
|
-
});
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
// Use native implementation of requestIdleCallback if it exists.
|
|
1088
|
-
// Otherwise, fall back to a custom implementation using requestAnimationFrame & MessageChannel.
|
|
1089
|
-
// While it's not possible to build a perfect polyfill given the nature of this API, the following code attempts to get close.
|
|
1090
|
-
// Background context: requestAnimationFrame invokes the js code right before: style, layout and paint computation within the frame.
|
|
1091
|
-
// This means, that any code that runs as part of requestAnimationFrame will by default be blocking in nature. Not what we want.
|
|
1092
|
-
// For non-blocking behavior, We need to know when browser has finished painiting. This can be accomplished in two different ways (hacks):
|
|
1093
|
-
// (1) Use MessageChannel to pass the message, and browser will receive the message right after pain event has occured.
|
|
1094
|
-
// (2) Use setTimeout call within requestAnimationFrame. This also works, but there's a risk that browser may throttle setTimeout calls.
|
|
1095
|
-
// Given this information, we are currently using (1) from above. More information on (2) as well as some additional context is below:
|
|
1096
|
-
// https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Performance_best_practices_for_Firefox_fe_engineers
|
|
1097
|
-
function requestIdleCallbackPolyfill(callback, options) {
|
|
1098
|
-
var startTime = performance.now();
|
|
1099
|
-
var channel = new MessageChannel();
|
|
1100
|
-
var incoming = channel.port1;
|
|
1101
|
-
var outgoing = channel.port2;
|
|
1102
|
-
incoming.onmessage = function (event) {
|
|
1103
|
-
var currentTime = performance.now();
|
|
1104
|
-
var elapsed = currentTime - startTime;
|
|
1105
|
-
var duration = currentTime - event.data;
|
|
1106
|
-
if (duration > 30 /* Setting.LongTask */ && elapsed < options.timeout) {
|
|
1107
|
-
requestAnimationFrame(function () { outgoing.postMessage(currentTime); });
|
|
1108
|
-
}
|
|
1109
|
-
else {
|
|
1110
|
-
var didTimeout_1 = elapsed > options.timeout;
|
|
1111
|
-
callback({
|
|
1112
|
-
didTimeout: didTimeout_1,
|
|
1113
|
-
timeRemaining: function () { return didTimeout_1 ? 30 /* Setting.LongTask */ : Math.max(0, 30 /* Setting.LongTask */ - duration); }
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
982
|
+
function add(node, parent, data, source) {
|
|
983
|
+
var id = getId(node, true);
|
|
984
|
+
var parentId = parent ? getId(parent) : null;
|
|
985
|
+
var previousId = getPreviousId(node);
|
|
986
|
+
var parentValue = null;
|
|
987
|
+
var regionId = exists(node) ? id : null;
|
|
988
|
+
var fraudId = fraudMap.has(node) ? fraudMap.get(node) : null;
|
|
989
|
+
var privacyId = config$1.content ? 1 /* Privacy.Sensitive */ : 3 /* Privacy.TextImage */;
|
|
990
|
+
if (parentId >= 0 && values[parentId]) {
|
|
991
|
+
parentValue = values[parentId];
|
|
992
|
+
parentValue.children.push(id);
|
|
993
|
+
regionId = regionId === null ? parentValue.region : regionId;
|
|
994
|
+
fraudId = fraudId === null ? parentValue.metadata.fraud : fraudId;
|
|
995
|
+
privacyId = parentValue.metadata.privacy;
|
|
996
|
+
}
|
|
997
|
+
// If there's an explicit region attribute set on the element, use it to mark a region on the page
|
|
998
|
+
if (data.attributes && "data-clarity-region" /* Constant.RegionData */ in data.attributes) {
|
|
999
|
+
observe$c(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
|
|
1000
|
+
regionId = id;
|
|
1001
|
+
}
|
|
1002
|
+
nodes[id] = node;
|
|
1003
|
+
values[id] = {
|
|
1004
|
+
id: id,
|
|
1005
|
+
parent: parentId,
|
|
1006
|
+
previous: previousId,
|
|
1007
|
+
children: [],
|
|
1008
|
+
data: data,
|
|
1009
|
+
selector: null,
|
|
1010
|
+
hash: null,
|
|
1011
|
+
region: regionId,
|
|
1012
|
+
metadata: { active: true, suspend: false, privacy: privacyId, position: null, fraud: fraudId, size: null },
|
|
1116
1013
|
};
|
|
1117
|
-
|
|
1014
|
+
privacy(node, values[id], parentValue);
|
|
1015
|
+
updateSelector(values[id]);
|
|
1016
|
+
size$1(values[id]);
|
|
1017
|
+
track$5(id, source);
|
|
1118
1018
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
//
|
|
1134
|
-
if (
|
|
1135
|
-
|
|
1136
|
-
var
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
pointer++;
|
|
1145
|
-
}
|
|
1019
|
+
function update$1(node, parent, data, source) {
|
|
1020
|
+
var id = getId(node);
|
|
1021
|
+
var parentId = parent ? getId(parent) : null;
|
|
1022
|
+
var previousId = getPreviousId(node);
|
|
1023
|
+
var changed = false;
|
|
1024
|
+
var parentChanged = false;
|
|
1025
|
+
if (id in values) {
|
|
1026
|
+
var value = values[id];
|
|
1027
|
+
value.metadata.active = true;
|
|
1028
|
+
// Handle case where internal ordering may have changed
|
|
1029
|
+
if (value.previous !== previousId) {
|
|
1030
|
+
changed = true;
|
|
1031
|
+
value.previous = previousId;
|
|
1032
|
+
}
|
|
1033
|
+
// Handle case where parent might have been updated
|
|
1034
|
+
if (value.parent !== parentId) {
|
|
1035
|
+
changed = true;
|
|
1036
|
+
var oldParentId = value.parent;
|
|
1037
|
+
value.parent = parentId;
|
|
1038
|
+
// Move this node to the right location under new parent
|
|
1039
|
+
if (parentId !== null && parentId >= 0) {
|
|
1040
|
+
var childIndex = previousId === null ? 0 : values[parentId].children.indexOf(previousId) + 1;
|
|
1041
|
+
values[parentId].children.splice(childIndex, 0, id);
|
|
1042
|
+
// Update region after the move
|
|
1043
|
+
value.region = exists(node) ? id : values[parentId].region;
|
|
1146
1044
|
}
|
|
1147
1045
|
else {
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1046
|
+
// Mark this element as deleted if the parent has been updated to null
|
|
1047
|
+
remove(id, source);
|
|
1048
|
+
}
|
|
1049
|
+
// Remove reference to this node from the old parent
|
|
1050
|
+
if (oldParentId !== null && oldParentId >= 0) {
|
|
1051
|
+
var nodeIndex = values[oldParentId].children.indexOf(id);
|
|
1052
|
+
if (nodeIndex >= 0) {
|
|
1053
|
+
values[oldParentId].children.splice(nodeIndex, 1);
|
|
1054
|
+
}
|
|
1151
1055
|
}
|
|
1056
|
+
parentChanged = true;
|
|
1152
1057
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1058
|
+
// Update data
|
|
1059
|
+
for (var key in data) {
|
|
1060
|
+
if (diff(value["data"], data, key)) {
|
|
1061
|
+
changed = true;
|
|
1062
|
+
value["data"][key] = data[key];
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
// Update selector
|
|
1066
|
+
updateSelector(value);
|
|
1067
|
+
track$5(id, source, changed, parentChanged);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
function sameorigin(node) {
|
|
1071
|
+
var output = false;
|
|
1072
|
+
if (node.nodeType === Node.ELEMENT_NODE && node.tagName === "IFRAME" /* Constant.IFrameTag */) {
|
|
1073
|
+
var frame = node;
|
|
1074
|
+
// To determine if the iframe is same-origin or not, we try accessing it's contentDocument.
|
|
1075
|
+
// If the browser throws an exception, we assume it's cross-origin and move on.
|
|
1076
|
+
// However, if we do a get a valid document object back, we assume the contents are accessible and iframe is same-origin.
|
|
1077
|
+
try {
|
|
1078
|
+
var doc = frame.contentDocument;
|
|
1079
|
+
if (doc) {
|
|
1080
|
+
iframeMap.set(frame.contentDocument, frame);
|
|
1081
|
+
output = true;
|
|
1082
|
+
}
|
|
1159
1083
|
}
|
|
1084
|
+
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
1160
1085
|
}
|
|
1161
1086
|
return output;
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
function encode$4 (type, timer, ts) {
|
|
1165
|
-
if (timer === void 0) { timer = null; }
|
|
1166
|
-
if (ts === void 0) { ts = null; }
|
|
1167
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1168
|
-
var eventTime, tokens, _a, d, _i, _b, r, values, _c, values_1, value, state, data, active, suspend, privacy, mangle, keys, _d, keys_1, key, box, factor, attr;
|
|
1169
|
-
return __generator(this, function (_e) {
|
|
1170
|
-
switch (_e.label) {
|
|
1171
|
-
case 0:
|
|
1172
|
-
eventTime = ts || time();
|
|
1173
|
-
tokens = [eventTime, type];
|
|
1174
|
-
_a = type;
|
|
1175
|
-
switch (_a) {
|
|
1176
|
-
case 8 /* Event.Document */: return [3 /*break*/, 1];
|
|
1177
|
-
case 7 /* Event.Region */: return [3 /*break*/, 2];
|
|
1178
|
-
case 5 /* Event.Discover */: return [3 /*break*/, 3];
|
|
1179
|
-
case 6 /* Event.Mutation */: return [3 /*break*/, 3];
|
|
1180
|
-
}
|
|
1181
|
-
return [3 /*break*/, 10];
|
|
1182
|
-
case 1:
|
|
1183
|
-
d = data$c;
|
|
1184
|
-
tokens.push(d.width);
|
|
1185
|
-
tokens.push(d.height);
|
|
1186
|
-
track$7(type, d.width, d.height);
|
|
1187
|
-
queue(tokens);
|
|
1188
|
-
return [3 /*break*/, 10];
|
|
1189
|
-
case 2:
|
|
1190
|
-
for (_i = 0, _b = state$1; _i < _b.length; _i++) {
|
|
1191
|
-
r = _b[_i];
|
|
1192
|
-
tokens = [r.time, 7 /* Event.Region */];
|
|
1193
|
-
tokens.push(r.data.id);
|
|
1194
|
-
tokens.push(r.data.interaction);
|
|
1195
|
-
tokens.push(r.data.visibility);
|
|
1196
|
-
tokens.push(r.data.name);
|
|
1197
|
-
queue(tokens);
|
|
1198
|
-
}
|
|
1199
|
-
reset$6();
|
|
1200
|
-
return [3 /*break*/, 10];
|
|
1201
|
-
case 3:
|
|
1202
|
-
// Check if we are operating within the context of the current page
|
|
1203
|
-
if (state$9(timer) === 2 /* Task.Stop */) {
|
|
1204
|
-
return [3 /*break*/, 10];
|
|
1205
|
-
}
|
|
1206
|
-
values = updates$2();
|
|
1207
|
-
if (!(values.length > 0)) return [3 /*break*/, 9];
|
|
1208
|
-
_c = 0, values_1 = values;
|
|
1209
|
-
_e.label = 4;
|
|
1210
|
-
case 4:
|
|
1211
|
-
if (!(_c < values_1.length)) return [3 /*break*/, 8];
|
|
1212
|
-
value = values_1[_c];
|
|
1213
|
-
state = state$9(timer);
|
|
1214
|
-
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 6];
|
|
1215
|
-
return [4 /*yield*/, suspend$1(timer)];
|
|
1216
|
-
case 5:
|
|
1217
|
-
state = _e.sent();
|
|
1218
|
-
_e.label = 6;
|
|
1219
|
-
case 6:
|
|
1220
|
-
if (state === 2 /* Task.Stop */) {
|
|
1221
|
-
return [3 /*break*/, 8];
|
|
1222
|
-
}
|
|
1223
|
-
data = value.data;
|
|
1224
|
-
active = value.metadata.active;
|
|
1225
|
-
suspend = value.metadata.suspend;
|
|
1226
|
-
privacy = value.metadata.privacy;
|
|
1227
|
-
mangle = shouldMangle(value);
|
|
1228
|
-
keys = active ? ["tag", "attributes", "value"] : ["tag"];
|
|
1229
|
-
for (_d = 0, keys_1 = keys; _d < keys_1.length; _d++) {
|
|
1230
|
-
key = keys_1[_d];
|
|
1231
|
-
if (data[key]) {
|
|
1232
|
-
switch (key) {
|
|
1233
|
-
case "tag":
|
|
1234
|
-
box = size$1(value);
|
|
1235
|
-
factor = mangle ? -1 : 1;
|
|
1236
|
-
tokens.push(value.id * factor);
|
|
1237
|
-
if (value.parent && active) {
|
|
1238
|
-
tokens.push(value.parent);
|
|
1239
|
-
}
|
|
1240
|
-
if (value.previous && active) {
|
|
1241
|
-
tokens.push(value.previous);
|
|
1242
|
-
}
|
|
1243
|
-
tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
|
|
1244
|
-
if (box && box.length === 2) {
|
|
1245
|
-
tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
|
|
1246
|
-
}
|
|
1247
|
-
break;
|
|
1248
|
-
case "attributes":
|
|
1249
|
-
for (attr in data[key]) {
|
|
1250
|
-
if (data[key][attr] !== undefined) {
|
|
1251
|
-
tokens.push(attribute(attr, data[key][attr], privacy));
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
break;
|
|
1255
|
-
case "value":
|
|
1256
|
-
check$4(value.metadata.fraud, value.id, data[key]);
|
|
1257
|
-
tokens.push(text$1(data[key], data.tag, privacy, mangle));
|
|
1258
|
-
break;
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
_e.label = 7;
|
|
1263
|
-
case 7:
|
|
1264
|
-
_c++;
|
|
1265
|
-
return [3 /*break*/, 4];
|
|
1266
|
-
case 8:
|
|
1267
|
-
if (type === 6 /* Event.Mutation */) {
|
|
1268
|
-
activity(eventTime);
|
|
1269
|
-
}
|
|
1270
|
-
queue(tokenize(tokens), !config$1.lean);
|
|
1271
|
-
_e.label = 9;
|
|
1272
|
-
case 9: return [3 /*break*/, 10];
|
|
1273
|
-
case 10: return [2 /*return*/];
|
|
1274
|
-
}
|
|
1275
|
-
});
|
|
1276
|
-
});
|
|
1277
1087
|
}
|
|
1278
|
-
function
|
|
1279
|
-
var
|
|
1280
|
-
return
|
|
1088
|
+
function iframe(node) {
|
|
1089
|
+
var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
|
|
1090
|
+
return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
|
|
1281
1091
|
}
|
|
1282
|
-
function
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1092
|
+
function privacy(node, value, parent) {
|
|
1093
|
+
var data = value.data;
|
|
1094
|
+
var metadata = value.metadata;
|
|
1095
|
+
var current = metadata.privacy;
|
|
1096
|
+
var attributes = data.attributes || {};
|
|
1097
|
+
var tag = data.tag.toUpperCase();
|
|
1098
|
+
switch (true) {
|
|
1099
|
+
case maskTags.indexOf(tag) >= 0:
|
|
1100
|
+
var type = attributes["type" /* Constant.Type */];
|
|
1101
|
+
var meta_1 = "" /* Constant.Empty */;
|
|
1102
|
+
Object.keys(attributes).forEach(function (x) { return meta_1 += attributes[x].toLowerCase(); });
|
|
1103
|
+
var exclude = maskExclude.some(function (x) { return meta_1.indexOf(x) >= 0; });
|
|
1104
|
+
// Regardless of privacy mode, always mask off user input from input boxes or drop downs with two exceptions:
|
|
1105
|
+
// (1) The node is detected to be one of the excluded fields, in which case we drop everything
|
|
1106
|
+
// (2) The node's type is one of the allowed types (like checkboxes)
|
|
1107
|
+
metadata.privacy = tag === "INPUT" /* Constant.InputTag */ && maskDisable.indexOf(type) >= 0 ? current : (exclude ? 4 /* Privacy.Exclude */ : 2 /* Privacy.Text */);
|
|
1108
|
+
break;
|
|
1109
|
+
case "data-clarity-mask" /* Constant.MaskData */ in attributes:
|
|
1110
|
+
metadata.privacy = 3 /* Privacy.TextImage */;
|
|
1111
|
+
break;
|
|
1112
|
+
case "data-clarity-unmask" /* Constant.UnmaskData */ in attributes:
|
|
1113
|
+
metadata.privacy = 0 /* Privacy.None */;
|
|
1114
|
+
break;
|
|
1115
|
+
case privacyMap.has(node):
|
|
1116
|
+
// If this node was explicitly configured to contain sensitive content, honor that privacy setting
|
|
1117
|
+
metadata.privacy = privacyMap.get(node);
|
|
1118
|
+
break;
|
|
1119
|
+
case fraudMap.has(node):
|
|
1120
|
+
// If this node was explicitly configured to be evaluated for fraud, then also mask content
|
|
1121
|
+
metadata.privacy = 2 /* Privacy.Text */;
|
|
1122
|
+
break;
|
|
1123
|
+
case tag === "*T" /* Constant.TextTag */:
|
|
1124
|
+
// If it's a text node belonging to a STYLE or TITLE tag or one of scrub exceptions, then capture content
|
|
1125
|
+
var pTag = parent && parent.data ? parent.data.tag : "" /* Constant.Empty */;
|
|
1126
|
+
var pSelector_1 = parent && parent.selector ? parent.selector[1 /* Selector.Default */] : "" /* Constant.Empty */;
|
|
1127
|
+
var tags = ["STYLE" /* Constant.StyleTag */, "TITLE" /* Constant.TitleTag */, "svg:style" /* Constant.SvgStyle */];
|
|
1128
|
+
metadata.privacy = tags.includes(pTag) || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* Privacy.None */ : current;
|
|
1129
|
+
break;
|
|
1130
|
+
case current === 1 /* Privacy.Sensitive */:
|
|
1131
|
+
// In a mode where we mask sensitive information by default, look through class names to aggressively mask content
|
|
1132
|
+
metadata.privacy = inspect(attributes["class" /* Constant.Class */], maskText, metadata);
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
function inspect(input, lookup, metadata) {
|
|
1137
|
+
if (input && lookup.some(function (x) { return input.indexOf(x) >= 0; })) {
|
|
1138
|
+
return 2 /* Privacy.Text */;
|
|
1139
|
+
}
|
|
1140
|
+
return metadata.privacy;
|
|
1141
|
+
}
|
|
1142
|
+
function diff(a, b, field) {
|
|
1143
|
+
if (typeof a[field] === "object" && typeof b[field] === "object") {
|
|
1144
|
+
for (var key in a[field]) {
|
|
1145
|
+
if (a[field][key] !== b[field][key]) {
|
|
1146
|
+
return true;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
for (var key in b[field]) {
|
|
1150
|
+
if (b[field][key] !== a[field][key]) {
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1287
1153
|
}
|
|
1154
|
+
return false;
|
|
1288
1155
|
}
|
|
1289
|
-
return
|
|
1156
|
+
return a[field] !== b[field];
|
|
1290
1157
|
}
|
|
1291
|
-
function
|
|
1292
|
-
|
|
1158
|
+
function position(parent, child) {
|
|
1159
|
+
child.metadata.position = 1;
|
|
1160
|
+
var idx = parent ? parent.children.indexOf(child.id) : -1;
|
|
1161
|
+
while (idx-- > 0) {
|
|
1162
|
+
var sibling = values[parent.children[idx]];
|
|
1163
|
+
if (child.data.tag === sibling.data.tag) {
|
|
1164
|
+
child.metadata.position = sibling.metadata.position + 1;
|
|
1165
|
+
break;
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
return child.metadata.position;
|
|
1293
1169
|
}
|
|
1294
|
-
function
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
var
|
|
1299
|
-
|
|
1300
|
-
|
|
1170
|
+
function updateSelector(value) {
|
|
1171
|
+
var parent = value.parent && value.parent in values ? values[value.parent] : null;
|
|
1172
|
+
var prefix = parent ? parent.selector : null;
|
|
1173
|
+
var d = value.data;
|
|
1174
|
+
var p = position(parent, value);
|
|
1175
|
+
var s = { id: value.id, tag: d.tag, prefix: prefix, position: p, attributes: d.attributes };
|
|
1176
|
+
value.selector = [get$1(s, 0 /* Selector.Alpha */), get$1(s, 1 /* Selector.Beta */)];
|
|
1177
|
+
value.hash = value.selector.map(function (x) { return x ? hash(x) : null; });
|
|
1178
|
+
value.hash.forEach(function (h) { return hashMap[h] = value.id; });
|
|
1301
1179
|
}
|
|
1302
|
-
function
|
|
1303
|
-
|
|
1304
|
-
|
|
1180
|
+
function hashText(hash) {
|
|
1181
|
+
var id = lookup(hash);
|
|
1182
|
+
var node = getNode(id);
|
|
1183
|
+
return node !== null && node.textContent !== null ? node.textContent.substr(0, 25 /* Setting.ClickText */) : '';
|
|
1305
1184
|
}
|
|
1306
|
-
function
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
var bodyClientWidth = body ? body.clientWidth : null;
|
|
1310
|
-
var bodyScrollWidth = body ? body.scrollWidth : null;
|
|
1311
|
-
var bodyOffsetWidth = body ? body.offsetWidth : null;
|
|
1312
|
-
var documentClientWidth = d ? d.clientWidth : null;
|
|
1313
|
-
var documentScrollWidth = d ? d.scrollWidth : null;
|
|
1314
|
-
var documentOffsetWidth = d ? d.offsetWidth : null;
|
|
1315
|
-
var width = Math.max(bodyClientWidth, bodyScrollWidth, bodyOffsetWidth, documentClientWidth, documentScrollWidth, documentOffsetWidth);
|
|
1316
|
-
var bodyClientHeight = body ? body.clientHeight : null;
|
|
1317
|
-
var bodyScrollHeight = body ? body.scrollHeight : null;
|
|
1318
|
-
var bodyOffsetHeight = body ? body.offsetHeight : null;
|
|
1319
|
-
var documentClientHeight = d ? d.clientHeight : null;
|
|
1320
|
-
var documentScrollHeight = d ? d.scrollHeight : null;
|
|
1321
|
-
var documentOffsetHeight = d ? d.offsetHeight : null;
|
|
1322
|
-
var height = Math.max(bodyClientHeight, bodyScrollHeight, bodyOffsetHeight, documentClientHeight, documentScrollHeight, documentOffsetHeight);
|
|
1323
|
-
// Check that width or height has changed from before, and also that width & height are not null values
|
|
1324
|
-
if ((data$c === null || width !== data$c.width || height !== data$c.height) && width !== null && height !== null) {
|
|
1325
|
-
data$c = { width: width, height: height };
|
|
1326
|
-
encode$4(8 /* Event.Document */);
|
|
1185
|
+
function getNode(id) {
|
|
1186
|
+
if (id in nodes) {
|
|
1187
|
+
return nodes[id];
|
|
1327
1188
|
}
|
|
1189
|
+
return null;
|
|
1328
1190
|
}
|
|
1329
|
-
function
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
function start$v() {
|
|
1335
|
-
reset$i();
|
|
1191
|
+
function getValue(id) {
|
|
1192
|
+
if (id in values) {
|
|
1193
|
+
return values[id];
|
|
1194
|
+
}
|
|
1195
|
+
return null;
|
|
1336
1196
|
}
|
|
1337
|
-
function
|
|
1338
|
-
|
|
1197
|
+
function get(node) {
|
|
1198
|
+
var id = getId(node);
|
|
1199
|
+
return id in values ? values[id] : null;
|
|
1339
1200
|
}
|
|
1340
|
-
function
|
|
1341
|
-
|
|
1342
|
-
if (element) {
|
|
1343
|
-
var value = element.value;
|
|
1344
|
-
var checksum = value && value.length >= 5 /* Setting.WordLength */ && config$1.fraud ? hash(value, 24 /* Setting.ChecksumPrecision */) : "" /* Constant.Empty */;
|
|
1345
|
-
state$8.push({ time: time(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
|
|
1346
|
-
schedule$1(encode$3.bind(this, 42 /* Event.Change */));
|
|
1347
|
-
}
|
|
1201
|
+
function lookup(hash) {
|
|
1202
|
+
return hash in hashMap ? hashMap[hash] : null;
|
|
1348
1203
|
}
|
|
1349
|
-
function
|
|
1350
|
-
|
|
1204
|
+
function has(node) {
|
|
1205
|
+
return getId(node) in nodes;
|
|
1351
1206
|
}
|
|
1352
|
-
function
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
// In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
|
|
1360
|
-
if (element && element.offsetParent) {
|
|
1361
|
-
do {
|
|
1362
|
-
var parent_1 = element.offsetParent;
|
|
1363
|
-
var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
|
|
1364
|
-
output.x += element.offsetLeft;
|
|
1365
|
-
output.y += element.offsetTop;
|
|
1366
|
-
element = frame ? frame : parent_1;
|
|
1367
|
-
} while (element);
|
|
1207
|
+
function updates$2() {
|
|
1208
|
+
var output = [];
|
|
1209
|
+
for (var _i = 0, updateMap_1 = updateMap; _i < updateMap_1.length; _i++) {
|
|
1210
|
+
var id = updateMap_1[_i];
|
|
1211
|
+
if (id in values) {
|
|
1212
|
+
output.push(values[id]);
|
|
1213
|
+
}
|
|
1368
1214
|
}
|
|
1215
|
+
updateMap = [];
|
|
1369
1216
|
return output;
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
|
|
1373
|
-
var state$7 = [];
|
|
1374
|
-
function start$u() {
|
|
1375
|
-
reset$h();
|
|
1376
|
-
}
|
|
1377
|
-
function observe$b(root) {
|
|
1378
|
-
bind(root, "click", handler$3.bind(this, 9 /* Event.Click */, root), true);
|
|
1379
1217
|
}
|
|
1380
|
-
function
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
if (frame) {
|
|
1387
|
-
var distance = offset(frame);
|
|
1388
|
-
x = x ? x + Math.round(distance.x) : x;
|
|
1389
|
-
y = y ? y + Math.round(distance.y) : y;
|
|
1218
|
+
function remove(id, source) {
|
|
1219
|
+
if (id in values) {
|
|
1220
|
+
var value = values[id];
|
|
1221
|
+
value.metadata.active = false;
|
|
1222
|
+
value.parent = null;
|
|
1223
|
+
track$5(id, source);
|
|
1390
1224
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
// If
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
var l = layout$1(t);
|
|
1397
|
-
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
|
|
1398
|
-
// This property helps differentiate between a keyboard navigation vs. pointer click
|
|
1399
|
-
// In case of a keyboard navigation, we use center of target element as (x,y)
|
|
1400
|
-
if (evt.detail === 0 && l) {
|
|
1401
|
-
x = Math.round(l.x + (l.w / 2));
|
|
1402
|
-
y = Math.round(l.y + (l.h / 2));
|
|
1225
|
+
}
|
|
1226
|
+
function size$1(value) {
|
|
1227
|
+
// If this element is a image node, and is masked, then track box model for the current element
|
|
1228
|
+
if (value.data.tag === "IMG" /* Constant.ImageTag */ && value.metadata.privacy === 3 /* Privacy.TextImage */) {
|
|
1229
|
+
value.metadata.size = [];
|
|
1403
1230
|
}
|
|
1404
|
-
var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1405
|
-
var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1406
|
-
// Check for null values before processing this event
|
|
1407
|
-
if (x !== null && y !== null) {
|
|
1408
|
-
state$7.push({
|
|
1409
|
-
time: time(evt),
|
|
1410
|
-
event: event,
|
|
1411
|
-
data: {
|
|
1412
|
-
target: t,
|
|
1413
|
-
x: x,
|
|
1414
|
-
y: y,
|
|
1415
|
-
eX: eX,
|
|
1416
|
-
eY: eY,
|
|
1417
|
-
button: evt.button,
|
|
1418
|
-
reaction: reaction(t),
|
|
1419
|
-
context: context(a),
|
|
1420
|
-
text: text(t),
|
|
1421
|
-
link: a ? a.href : null,
|
|
1422
|
-
hash: null,
|
|
1423
|
-
trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
|
|
1424
|
-
}
|
|
1425
|
-
});
|
|
1426
|
-
schedule$1(encode$3.bind(this, event));
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
function text(element) {
|
|
1430
|
-
var output = null;
|
|
1431
|
-
if (element) {
|
|
1432
|
-
// Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
|
|
1433
|
-
var t = element.textContent || element.value || element.alt;
|
|
1434
|
-
if (t) {
|
|
1435
|
-
// Trim any spaces at the beginning or at the end of string
|
|
1436
|
-
// Also, replace multiple occurrence of space characters with a single white space
|
|
1437
|
-
// Finally, send only first few characters as specified by the Setting
|
|
1438
|
-
output = t.trim().replace(/\s+/g, " " /* Constant.Space */).substr(0, 25 /* Setting.ClickText */);
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
return output;
|
|
1442
1231
|
}
|
|
1443
|
-
function
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1232
|
+
function getPreviousId(node) {
|
|
1233
|
+
var id = null;
|
|
1234
|
+
// Some nodes may not have an ID by design since Clarity skips over tags like SCRIPT, NOSCRIPT, META, COMMENTS, etc..
|
|
1235
|
+
// In that case, we keep going back and check for their sibling until we find a sibling with ID or no more sibling nodes are left.
|
|
1236
|
+
while (id === null && node.previousSibling) {
|
|
1237
|
+
id = getId(node.previousSibling);
|
|
1238
|
+
node = node.previousSibling;
|
|
1449
1239
|
}
|
|
1450
|
-
return
|
|
1240
|
+
return id;
|
|
1451
1241
|
}
|
|
1452
|
-
function
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
// floors the value (e.g. 162px). This keeps consistent behavior across browsers.
|
|
1463
|
-
box = {
|
|
1464
|
-
x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
|
|
1465
|
-
y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
|
|
1466
|
-
w: Math.floor(rect.width),
|
|
1467
|
-
h: Math.floor(rect.height)
|
|
1468
|
-
};
|
|
1469
|
-
}
|
|
1242
|
+
function track$5(id, source, changed, parentChanged) {
|
|
1243
|
+
if (changed === void 0) { changed = true; }
|
|
1244
|
+
if (parentChanged === void 0) { parentChanged = false; }
|
|
1245
|
+
// Keep track of the order in which mutations happened, they may not be sequential
|
|
1246
|
+
// Edge case: If an element is added later on, and pre-discovered element is moved as a child.
|
|
1247
|
+
// In that case, we need to reorder the pre-discovered element in the update list to keep visualization consistent.
|
|
1248
|
+
var uIndex = updateMap.indexOf(id);
|
|
1249
|
+
if (uIndex >= 0 && source === 1 /* Source.ChildListAdd */ && parentChanged) {
|
|
1250
|
+
updateMap.splice(uIndex, 1);
|
|
1251
|
+
updateMap.push(id);
|
|
1470
1252
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
function context(a) {
|
|
1474
|
-
if (a && a.hasAttribute("target" /* Constant.Target */)) {
|
|
1475
|
-
switch (a.getAttribute("target" /* Constant.Target */)) {
|
|
1476
|
-
case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
|
|
1477
|
-
case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
|
|
1478
|
-
case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
|
|
1479
|
-
}
|
|
1253
|
+
else if (uIndex === -1 && changed) {
|
|
1254
|
+
updateMap.push(id);
|
|
1480
1255
|
}
|
|
1481
|
-
return 0 /* BrowsingContext.Self */;
|
|
1482
|
-
}
|
|
1483
|
-
function reset$h() {
|
|
1484
|
-
state$7 = [];
|
|
1485
|
-
}
|
|
1486
|
-
function stop$s() {
|
|
1487
|
-
reset$h();
|
|
1488
1256
|
}
|
|
1489
1257
|
|
|
1490
|
-
var
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1258
|
+
var dom = /*#__PURE__*/Object.freeze({
|
|
1259
|
+
__proto__: null,
|
|
1260
|
+
add: add,
|
|
1261
|
+
get: get,
|
|
1262
|
+
getId: getId,
|
|
1263
|
+
getNode: getNode,
|
|
1264
|
+
getValue: getValue,
|
|
1265
|
+
has: has,
|
|
1266
|
+
hashText: hashText,
|
|
1267
|
+
iframe: iframe,
|
|
1268
|
+
lookup: lookup,
|
|
1269
|
+
parse: parse$1,
|
|
1270
|
+
sameorigin: sameorigin,
|
|
1271
|
+
start: start$x,
|
|
1272
|
+
stop: stop$u,
|
|
1273
|
+
update: update$1,
|
|
1274
|
+
updates: updates$2
|
|
1275
|
+
});
|
|
1276
|
+
|
|
1277
|
+
// Track the start time to be able to compute duration at the end of the task
|
|
1278
|
+
var idleTimeout = 5000;
|
|
1279
|
+
var tracker = {};
|
|
1280
|
+
var queuedTasks = [];
|
|
1281
|
+
var activeTask = null;
|
|
1282
|
+
var pauseTask = null;
|
|
1283
|
+
var resumeResolve = null;
|
|
1284
|
+
function pause$1() {
|
|
1285
|
+
if (pauseTask === null) {
|
|
1286
|
+
pauseTask = new Promise(function (resolve) {
|
|
1287
|
+
resumeResolve = resolve;
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1498
1290
|
}
|
|
1499
|
-
function
|
|
1500
|
-
|
|
1501
|
-
|
|
1291
|
+
function resume$1() {
|
|
1292
|
+
if (pauseTask) {
|
|
1293
|
+
resumeResolve();
|
|
1294
|
+
pauseTask = null;
|
|
1295
|
+
if (activeTask === null) {
|
|
1296
|
+
run();
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1502
1299
|
}
|
|
1503
|
-
function reset$
|
|
1504
|
-
|
|
1300
|
+
function reset$j() {
|
|
1301
|
+
tracker = {};
|
|
1302
|
+
queuedTasks = [];
|
|
1303
|
+
activeTask = null;
|
|
1304
|
+
pauseTask = null;
|
|
1505
1305
|
}
|
|
1506
|
-
function
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1306
|
+
function schedule$1(task, priority) {
|
|
1307
|
+
if (priority === void 0) { priority = 0 /* Priority.Normal */; }
|
|
1308
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1309
|
+
var _i, queuedTasks_1, q, promise;
|
|
1310
|
+
return __generator(this, function (_a) {
|
|
1311
|
+
// If this task is already scheduled, skip it
|
|
1312
|
+
for (_i = 0, queuedTasks_1 = queuedTasks; _i < queuedTasks_1.length; _i++) {
|
|
1313
|
+
q = queuedTasks_1[_i];
|
|
1314
|
+
if (q.task === task) {
|
|
1315
|
+
return [2 /*return*/];
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
promise = new Promise(function (resolve) {
|
|
1319
|
+
var insert = priority === 1 /* Priority.High */ ? "unshift" : "push";
|
|
1320
|
+
// Queue this task for asynchronous execution later
|
|
1321
|
+
// We also store a unique page identifier (id) along with the task to ensure
|
|
1322
|
+
// ensure that we do not accidentally execute this task in context of a different page
|
|
1323
|
+
queuedTasks[insert]({ task: task, resolve: resolve, id: id() });
|
|
1324
|
+
});
|
|
1325
|
+
// If there is no active task running, and Clarity is not in pause state,
|
|
1326
|
+
// invoke the first task in the queue synchronously. This ensures that we don't yield the thread during unload event
|
|
1327
|
+
if (activeTask === null && pauseTask === null) {
|
|
1328
|
+
run();
|
|
1329
|
+
}
|
|
1330
|
+
return [2 /*return*/, promise];
|
|
1331
|
+
});
|
|
1332
|
+
});
|
|
1514
1333
|
}
|
|
1515
|
-
function
|
|
1516
|
-
|
|
1334
|
+
function run() {
|
|
1335
|
+
var entry = queuedTasks.shift();
|
|
1336
|
+
if (entry) {
|
|
1337
|
+
activeTask = entry;
|
|
1338
|
+
entry.task().then(function () {
|
|
1339
|
+
// Bail out if the context in which this task was operating is different from the current page
|
|
1340
|
+
// An example scenario where task could span across pages is Single Page Applications (SPA)
|
|
1341
|
+
// A task that started on page #1, but completes on page #2
|
|
1342
|
+
if (entry.id !== id()) {
|
|
1343
|
+
return;
|
|
1344
|
+
}
|
|
1345
|
+
entry.resolve();
|
|
1346
|
+
activeTask = null; // Reset active task back to null now that the promise is resolved
|
|
1347
|
+
run();
|
|
1348
|
+
}).catch(function (error) {
|
|
1349
|
+
// If one of the scheduled tasks failed, log, recover and continue processing rest of the tasks
|
|
1350
|
+
if (entry.id !== id()) {
|
|
1351
|
+
return;
|
|
1352
|
+
}
|
|
1353
|
+
if (error) {
|
|
1354
|
+
log$1(0 /* Code.RunTask */, 1 /* Severity.Warning */, error.name, error.message, error.stack);
|
|
1355
|
+
}
|
|
1356
|
+
activeTask = null;
|
|
1357
|
+
run();
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1517
1360
|
}
|
|
1518
|
-
function
|
|
1519
|
-
var
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
switch (input.type) {
|
|
1524
|
-
case "radio":
|
|
1525
|
-
case "checkbox":
|
|
1526
|
-
v = input.checked ? "true" : "false";
|
|
1527
|
-
break;
|
|
1528
|
-
}
|
|
1529
|
-
var data = { target: input, value: v };
|
|
1530
|
-
// If last entry in the queue is for the same target node as the current one, remove it so we can later swap it with current data.
|
|
1531
|
-
if (state$5.length > 0 && (state$5[state$5.length - 1].data.target === data.target)) {
|
|
1532
|
-
state$5.pop();
|
|
1533
|
-
}
|
|
1534
|
-
state$5.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
|
|
1535
|
-
clearTimeout(timeout$5);
|
|
1536
|
-
timeout$5 = setTimeout(process$6, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
|
|
1361
|
+
function state$9(timer) {
|
|
1362
|
+
var id = key(timer);
|
|
1363
|
+
if (id in tracker) {
|
|
1364
|
+
var elapsed = performance.now() - tracker[id].start;
|
|
1365
|
+
return (elapsed > tracker[id].yield) ? 0 /* Task.Wait */ : 1 /* Task.Run */;
|
|
1537
1366
|
}
|
|
1367
|
+
// If this task is no longer being tracked, send stop message to the caller
|
|
1368
|
+
return 2 /* Task.Stop */;
|
|
1538
1369
|
}
|
|
1539
|
-
function
|
|
1540
|
-
|
|
1370
|
+
function start$w(timer) {
|
|
1371
|
+
tracker[key(timer)] = { start: performance.now(), calls: 0, yield: 30 /* Setting.LongTask */ };
|
|
1541
1372
|
}
|
|
1542
|
-
function
|
|
1543
|
-
|
|
1373
|
+
function restart$2(timer) {
|
|
1374
|
+
var id = key(timer);
|
|
1375
|
+
if (tracker && tracker[id]) {
|
|
1376
|
+
var c = tracker[id].calls;
|
|
1377
|
+
var y = tracker[id].yield;
|
|
1378
|
+
start$w(timer);
|
|
1379
|
+
tracker[id].calls = c + 1;
|
|
1380
|
+
tracker[id].yield = y;
|
|
1381
|
+
}
|
|
1544
1382
|
}
|
|
1545
|
-
function stop$
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1383
|
+
function stop$t(timer) {
|
|
1384
|
+
var end = performance.now();
|
|
1385
|
+
var id = key(timer);
|
|
1386
|
+
var duration = end - tracker[id].start;
|
|
1387
|
+
sum(timer.cost, duration);
|
|
1388
|
+
count$1(5 /* Metric.InvokeCount */);
|
|
1389
|
+
// For the first execution, which is synchronous, time is automatically counted towards TotalDuration.
|
|
1390
|
+
// However, for subsequent asynchronous runs, we need to manually update TotalDuration metric.
|
|
1391
|
+
if (tracker[id].calls > 0) {
|
|
1392
|
+
sum(4 /* Metric.TotalCost */, duration);
|
|
1393
|
+
}
|
|
1554
1394
|
}
|
|
1555
|
-
function
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1395
|
+
function suspend$1(timer) {
|
|
1396
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1397
|
+
var id, _a;
|
|
1398
|
+
return __generator(this, function (_b) {
|
|
1399
|
+
switch (_b.label) {
|
|
1400
|
+
case 0:
|
|
1401
|
+
id = key(timer);
|
|
1402
|
+
if (!(id in tracker)) return [3 /*break*/, 2];
|
|
1403
|
+
stop$t(timer);
|
|
1404
|
+
_a = tracker[id];
|
|
1405
|
+
return [4 /*yield*/, wait()];
|
|
1406
|
+
case 1:
|
|
1407
|
+
_a.yield = (_b.sent()).timeRemaining();
|
|
1408
|
+
restart$2(timer);
|
|
1409
|
+
_b.label = 2;
|
|
1410
|
+
case 2:
|
|
1411
|
+
// After we are done with suspending task, ensure that we are still operating in the right context
|
|
1412
|
+
// If the task is still being tracked, continue running the task, otherwise ask caller to stop execution
|
|
1413
|
+
return [2 /*return*/, id in tracker ? 1 /* Task.Run */ : 2 /* Task.Stop */];
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1416
|
+
});
|
|
1565
1417
|
}
|
|
1566
|
-
function
|
|
1567
|
-
|
|
1568
|
-
var d = frame ? frame.contentDocument.documentElement : document.documentElement;
|
|
1569
|
-
var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
|
|
1570
|
-
var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
|
|
1571
|
-
// In case of iframe, we adjust (x,y) to be relative to top parent's origin
|
|
1572
|
-
if (frame) {
|
|
1573
|
-
var distance = offset(frame);
|
|
1574
|
-
x = x ? x + Math.round(distance.x) : x;
|
|
1575
|
-
y = y ? y + Math.round(distance.y) : y;
|
|
1576
|
-
}
|
|
1577
|
-
// Check for null values before processing this event
|
|
1578
|
-
if (x !== null && y !== null) {
|
|
1579
|
-
handler$2({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
|
|
1580
|
-
}
|
|
1418
|
+
function key(timer) {
|
|
1419
|
+
return "".concat(timer.id, ".").concat(timer.cost);
|
|
1581
1420
|
}
|
|
1582
|
-
function
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
if (x !== null && y !== null) {
|
|
1596
|
-
handler$2({ time: t, event: event, data: { target: target(evt), x: x, y: y } });
|
|
1421
|
+
function wait() {
|
|
1422
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1423
|
+
return __generator(this, function (_a) {
|
|
1424
|
+
switch (_a.label) {
|
|
1425
|
+
case 0:
|
|
1426
|
+
if (!pauseTask) return [3 /*break*/, 2];
|
|
1427
|
+
return [4 /*yield*/, pauseTask];
|
|
1428
|
+
case 1:
|
|
1429
|
+
_a.sent();
|
|
1430
|
+
_a.label = 2;
|
|
1431
|
+
case 2: return [2 /*return*/, new Promise(function (resolve) {
|
|
1432
|
+
requestIdleCallback(resolve, { timeout: idleTimeout });
|
|
1433
|
+
})];
|
|
1597
1434
|
}
|
|
1435
|
+
});
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
// Use native implementation of requestIdleCallback if it exists.
|
|
1439
|
+
// Otherwise, fall back to a custom implementation using requestAnimationFrame & MessageChannel.
|
|
1440
|
+
// While it's not possible to build a perfect polyfill given the nature of this API, the following code attempts to get close.
|
|
1441
|
+
// Background context: requestAnimationFrame invokes the js code right before: style, layout and paint computation within the frame.
|
|
1442
|
+
// This means, that any code that runs as part of requestAnimationFrame will by default be blocking in nature. Not what we want.
|
|
1443
|
+
// For non-blocking behavior, We need to know when browser has finished painiting. This can be accomplished in two different ways (hacks):
|
|
1444
|
+
// (1) Use MessageChannel to pass the message, and browser will receive the message right after pain event has occured.
|
|
1445
|
+
// (2) Use setTimeout call within requestAnimationFrame. This also works, but there's a risk that browser may throttle setTimeout calls.
|
|
1446
|
+
// Given this information, we are currently using (1) from above. More information on (2) as well as some additional context is below:
|
|
1447
|
+
// https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Performance_best_practices_for_Firefox_fe_engineers
|
|
1448
|
+
function requestIdleCallbackPolyfill(callback, options) {
|
|
1449
|
+
var startTime = performance.now();
|
|
1450
|
+
var channel = new MessageChannel();
|
|
1451
|
+
var incoming = channel.port1;
|
|
1452
|
+
var outgoing = channel.port2;
|
|
1453
|
+
incoming.onmessage = function (event) {
|
|
1454
|
+
var currentTime = performance.now();
|
|
1455
|
+
var elapsed = currentTime - startTime;
|
|
1456
|
+
var duration = currentTime - event.data;
|
|
1457
|
+
if (duration > 30 /* Setting.LongTask */ && elapsed < options.timeout) {
|
|
1458
|
+
requestAnimationFrame(function () { outgoing.postMessage(currentTime); });
|
|
1598
1459
|
}
|
|
1599
|
-
|
|
1460
|
+
else {
|
|
1461
|
+
var didTimeout_1 = elapsed > options.timeout;
|
|
1462
|
+
callback({
|
|
1463
|
+
didTimeout: didTimeout_1,
|
|
1464
|
+
timeRemaining: function () { return didTimeout_1 ? 30 /* Setting.LongTask */ : Math.max(0, 30 /* Setting.LongTask */ - duration); }
|
|
1465
|
+
});
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1468
|
+
requestAnimationFrame(function () { outgoing.postMessage(performance.now()); });
|
|
1600
1469
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1470
|
+
var requestIdleCallback = window["requestIdleCallback"] || requestIdleCallbackPolyfill;
|
|
1471
|
+
|
|
1472
|
+
// Following code takes an array of tokens and transforms it to optimize for repeating tokens and make it efficient to send over the wire
|
|
1473
|
+
// The way it works is that it iterate over all tokens and checks if the current token was already seen in the tokens array so far
|
|
1474
|
+
// If so, it replaces the token with its reference (index). This helps us save bytes by not repeating the same value twice.
|
|
1475
|
+
// E.g. If tokens array is: ["hello", "world", "coding", "language", "world", "language", "example"]
|
|
1476
|
+
// Then the resulting tokens array after following code execution would be: ["hello", "world", "coding", "language", [1, 3], "example"]
|
|
1477
|
+
// Where [1,3] points to tokens[1] => "world" and tokens[3] => "language"
|
|
1478
|
+
function tokenize (tokens) {
|
|
1479
|
+
var output = [];
|
|
1480
|
+
var lookup = {};
|
|
1481
|
+
var pointer = 0;
|
|
1482
|
+
var reference = null;
|
|
1483
|
+
for (var i = 0; i < tokens.length; i++) {
|
|
1484
|
+
// Only optimize for string values
|
|
1485
|
+
if (typeof tokens[i] === "string" /* Constant.String */) {
|
|
1486
|
+
var token = tokens[i];
|
|
1487
|
+
var index = lookup[token] || -1;
|
|
1488
|
+
if (index >= 0) {
|
|
1489
|
+
if (reference) {
|
|
1490
|
+
reference.push(index);
|
|
1491
|
+
}
|
|
1492
|
+
else {
|
|
1493
|
+
reference = [index];
|
|
1494
|
+
output.push(reference);
|
|
1495
|
+
pointer++;
|
|
1496
|
+
}
|
|
1610
1497
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
}
|
|
1624
|
-
function reset$e() {
|
|
1625
|
-
state$4 = [];
|
|
1626
|
-
}
|
|
1627
|
-
function similar$1(last, current) {
|
|
1628
|
-
var dx = last.data.x - current.data.x;
|
|
1629
|
-
var dy = last.data.y - current.data.y;
|
|
1630
|
-
var distance = Math.sqrt(dx * dx + dy * dy);
|
|
1631
|
-
var gap = current.time - last.time;
|
|
1632
|
-
var match = current.data.target === last.data.target;
|
|
1633
|
-
return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
|
|
1634
|
-
}
|
|
1635
|
-
function stop$p() {
|
|
1636
|
-
clearTimeout(timeout$4);
|
|
1637
|
-
// Send out any pending pointer events in the pipeline
|
|
1638
|
-
if (state$4.length > 0) {
|
|
1639
|
-
process$5(state$4[state$4.length - 1].event);
|
|
1498
|
+
else {
|
|
1499
|
+
reference = null;
|
|
1500
|
+
output.push(token);
|
|
1501
|
+
lookup[token] = pointer++;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
else {
|
|
1505
|
+
// If the value is anything other than string, append it as it is to the output array
|
|
1506
|
+
// And, also increment the pointer to stay in sync with output array
|
|
1507
|
+
reference = null;
|
|
1508
|
+
output.push(tokens[i]);
|
|
1509
|
+
pointer++;
|
|
1510
|
+
}
|
|
1640
1511
|
}
|
|
1512
|
+
return output;
|
|
1641
1513
|
}
|
|
1642
1514
|
|
|
1643
|
-
var data$
|
|
1644
|
-
function
|
|
1645
|
-
|
|
1646
|
-
recompute$5();
|
|
1515
|
+
var data$c;
|
|
1516
|
+
function reset$i() {
|
|
1517
|
+
data$c = null;
|
|
1647
1518
|
}
|
|
1648
|
-
function
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
// Therefore, when possible, use documentElement's clientWidth property.
|
|
1652
|
-
data$b = {
|
|
1653
|
-
width: de && "clientWidth" in de ? Math.min(de.clientWidth, window.innerWidth) : window.innerWidth,
|
|
1654
|
-
height: de && "clientHeight" in de ? Math.min(de.clientHeight, window.innerHeight) : window.innerHeight,
|
|
1655
|
-
};
|
|
1656
|
-
encode$3(11 /* Event.Resize */);
|
|
1519
|
+
function start$v() {
|
|
1520
|
+
reset$i();
|
|
1521
|
+
compute$7();
|
|
1657
1522
|
}
|
|
1658
|
-
function
|
|
1659
|
-
|
|
1523
|
+
function compute$7() {
|
|
1524
|
+
var body = document.body;
|
|
1525
|
+
var d = document.documentElement;
|
|
1526
|
+
var bodyClientWidth = body ? body.clientWidth : null;
|
|
1527
|
+
var bodyScrollWidth = body ? body.scrollWidth : null;
|
|
1528
|
+
var bodyOffsetWidth = body ? body.offsetWidth : null;
|
|
1529
|
+
var documentClientWidth = d ? d.clientWidth : null;
|
|
1530
|
+
var documentScrollWidth = d ? d.scrollWidth : null;
|
|
1531
|
+
var documentOffsetWidth = d ? d.offsetWidth : null;
|
|
1532
|
+
var width = Math.max(bodyClientWidth, bodyScrollWidth, bodyOffsetWidth, documentClientWidth, documentScrollWidth, documentOffsetWidth);
|
|
1533
|
+
var bodyClientHeight = body ? body.clientHeight : null;
|
|
1534
|
+
var bodyScrollHeight = body ? body.scrollHeight : null;
|
|
1535
|
+
var bodyOffsetHeight = body ? body.offsetHeight : null;
|
|
1536
|
+
var documentClientHeight = d ? d.clientHeight : null;
|
|
1537
|
+
var documentScrollHeight = d ? d.scrollHeight : null;
|
|
1538
|
+
var documentOffsetHeight = d ? d.offsetHeight : null;
|
|
1539
|
+
var height = Math.max(bodyClientHeight, bodyScrollHeight, bodyOffsetHeight, documentClientHeight, documentScrollHeight, documentOffsetHeight);
|
|
1540
|
+
// Check that width or height has changed from before, and also that width & height are not null values
|
|
1541
|
+
if ((data$c === null || width !== data$c.width || height !== data$c.height) && width !== null && height !== null) {
|
|
1542
|
+
data$c = { width: width, height: height };
|
|
1543
|
+
encode$4(8 /* Event.Document */);
|
|
1544
|
+
}
|
|
1660
1545
|
}
|
|
1661
|
-
function
|
|
1662
|
-
reset$
|
|
1546
|
+
function end() {
|
|
1547
|
+
reset$i();
|
|
1663
1548
|
}
|
|
1664
1549
|
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1550
|
+
function encode$4 (type, timer, ts) {
|
|
1551
|
+
if (timer === void 0) { timer = null; }
|
|
1552
|
+
if (ts === void 0) { ts = null; }
|
|
1553
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1554
|
+
var eventTime, tokens, _a, d, _i, _b, r, values, _c, values_1, value, state, data, active, suspend, privacy, mangle, keys, _d, keys_1, key, box, factor, attr;
|
|
1555
|
+
return __generator(this, function (_e) {
|
|
1556
|
+
switch (_e.label) {
|
|
1557
|
+
case 0:
|
|
1558
|
+
eventTime = ts || time();
|
|
1559
|
+
tokens = [eventTime, type];
|
|
1560
|
+
_a = type;
|
|
1561
|
+
switch (_a) {
|
|
1562
|
+
case 8 /* Event.Document */: return [3 /*break*/, 1];
|
|
1563
|
+
case 7 /* Event.Region */: return [3 /*break*/, 2];
|
|
1564
|
+
case 5 /* Event.Discover */: return [3 /*break*/, 3];
|
|
1565
|
+
case 6 /* Event.Mutation */: return [3 /*break*/, 3];
|
|
1566
|
+
}
|
|
1567
|
+
return [3 /*break*/, 10];
|
|
1568
|
+
case 1:
|
|
1569
|
+
d = data$c;
|
|
1570
|
+
tokens.push(d.width);
|
|
1571
|
+
tokens.push(d.height);
|
|
1572
|
+
track$7(type, d.width, d.height);
|
|
1573
|
+
queue(tokens);
|
|
1574
|
+
return [3 /*break*/, 10];
|
|
1575
|
+
case 2:
|
|
1576
|
+
for (_i = 0, _b = state$8; _i < _b.length; _i++) {
|
|
1577
|
+
r = _b[_i];
|
|
1578
|
+
tokens = [r.time, 7 /* Event.Region */];
|
|
1579
|
+
tokens.push(r.data.id);
|
|
1580
|
+
tokens.push(r.data.interaction);
|
|
1581
|
+
tokens.push(r.data.visibility);
|
|
1582
|
+
tokens.push(r.data.name);
|
|
1583
|
+
queue(tokens);
|
|
1584
|
+
}
|
|
1585
|
+
reset$h();
|
|
1586
|
+
return [3 /*break*/, 10];
|
|
1587
|
+
case 3:
|
|
1588
|
+
// Check if we are operating within the context of the current page
|
|
1589
|
+
if (state$9(timer) === 2 /* Task.Stop */) {
|
|
1590
|
+
return [3 /*break*/, 10];
|
|
1591
|
+
}
|
|
1592
|
+
values = updates$2();
|
|
1593
|
+
if (!(values.length > 0)) return [3 /*break*/, 9];
|
|
1594
|
+
_c = 0, values_1 = values;
|
|
1595
|
+
_e.label = 4;
|
|
1596
|
+
case 4:
|
|
1597
|
+
if (!(_c < values_1.length)) return [3 /*break*/, 8];
|
|
1598
|
+
value = values_1[_c];
|
|
1599
|
+
state = state$9(timer);
|
|
1600
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 6];
|
|
1601
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
1602
|
+
case 5:
|
|
1603
|
+
state = _e.sent();
|
|
1604
|
+
_e.label = 6;
|
|
1605
|
+
case 6:
|
|
1606
|
+
if (state === 2 /* Task.Stop */) {
|
|
1607
|
+
return [3 /*break*/, 8];
|
|
1608
|
+
}
|
|
1609
|
+
data = value.data;
|
|
1610
|
+
active = value.metadata.active;
|
|
1611
|
+
suspend = value.metadata.suspend;
|
|
1612
|
+
privacy = value.metadata.privacy;
|
|
1613
|
+
mangle = shouldMangle(value);
|
|
1614
|
+
keys = active ? ["tag", "attributes", "value"] : ["tag"];
|
|
1615
|
+
for (_d = 0, keys_1 = keys; _d < keys_1.length; _d++) {
|
|
1616
|
+
key = keys_1[_d];
|
|
1617
|
+
if (data[key]) {
|
|
1618
|
+
switch (key) {
|
|
1619
|
+
case "tag":
|
|
1620
|
+
box = size(value);
|
|
1621
|
+
factor = mangle ? -1 : 1;
|
|
1622
|
+
tokens.push(value.id * factor);
|
|
1623
|
+
if (value.parent && active) {
|
|
1624
|
+
tokens.push(value.parent);
|
|
1625
|
+
}
|
|
1626
|
+
if (value.previous && active) {
|
|
1627
|
+
tokens.push(value.previous);
|
|
1628
|
+
}
|
|
1629
|
+
tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
|
|
1630
|
+
if (box && box.length === 2) {
|
|
1631
|
+
tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
|
|
1632
|
+
}
|
|
1633
|
+
break;
|
|
1634
|
+
case "attributes":
|
|
1635
|
+
for (attr in data[key]) {
|
|
1636
|
+
if (data[key][attr] !== undefined) {
|
|
1637
|
+
tokens.push(attribute(attr, data[key][attr], privacy));
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
break;
|
|
1641
|
+
case "value":
|
|
1642
|
+
check$4(value.metadata.fraud, value.id, data[key]);
|
|
1643
|
+
tokens.push(text$1(data[key], data.tag, privacy, mangle));
|
|
1644
|
+
break;
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
_e.label = 7;
|
|
1649
|
+
case 7:
|
|
1650
|
+
_c++;
|
|
1651
|
+
return [3 /*break*/, 4];
|
|
1652
|
+
case 8:
|
|
1653
|
+
if (type === 6 /* Event.Mutation */) {
|
|
1654
|
+
activity(eventTime);
|
|
1655
|
+
}
|
|
1656
|
+
queue(tokenize(tokens), !config$1.lean);
|
|
1657
|
+
_e.label = 9;
|
|
1658
|
+
case 9: return [3 /*break*/, 10];
|
|
1659
|
+
case 10: return [2 /*return*/];
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1662
|
+
});
|
|
1705
1663
|
}
|
|
1706
|
-
function
|
|
1707
|
-
|
|
1664
|
+
function shouldMangle(value) {
|
|
1665
|
+
var privacy = value.metadata.privacy;
|
|
1666
|
+
return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
|
|
1708
1667
|
}
|
|
1709
|
-
function
|
|
1710
|
-
|
|
1668
|
+
function size(value) {
|
|
1669
|
+
if (value.metadata.size !== null && value.metadata.size.length === 0) {
|
|
1670
|
+
var img = getNode(value.id);
|
|
1671
|
+
if (img) {
|
|
1672
|
+
return [Math.floor(img.offsetWidth * 100 /* Setting.BoxPrecision */), Math.floor(img.offsetHeight * 100 /* Setting.BoxPrecision */)];
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
return value.metadata.size;
|
|
1711
1676
|
}
|
|
1712
|
-
function
|
|
1713
|
-
|
|
1714
|
-
var dy = last.data.y - current.data.y;
|
|
1715
|
-
return (dx * dx + dy * dy < 20 /* Setting.Distance */ * 20 /* Setting.Distance */) && (current.time - last.time < 25 /* Setting.Interval */);
|
|
1677
|
+
function str$1(input) {
|
|
1678
|
+
return input.toString(36);
|
|
1716
1679
|
}
|
|
1717
|
-
function
|
|
1718
|
-
|
|
1719
|
-
state$3 = [];
|
|
1680
|
+
function attribute(key, value, privacy) {
|
|
1681
|
+
return "".concat(key, "=").concat(text$1(value, key, privacy));
|
|
1720
1682
|
}
|
|
1721
1683
|
|
|
1722
|
-
var
|
|
1723
|
-
var
|
|
1724
|
-
var
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
function
|
|
1729
|
-
|
|
1730
|
-
|
|
1684
|
+
var state$8 = [];
|
|
1685
|
+
var regionMap = null; // Maps region nodes => region name
|
|
1686
|
+
var regions = {};
|
|
1687
|
+
var queue$2 = [];
|
|
1688
|
+
var watch = false;
|
|
1689
|
+
var observer$1 = null;
|
|
1690
|
+
function start$u() {
|
|
1691
|
+
reset$h();
|
|
1692
|
+
observer$1 = null;
|
|
1693
|
+
regionMap = new WeakMap();
|
|
1694
|
+
regions = {};
|
|
1695
|
+
queue$2 = [];
|
|
1696
|
+
watch = window["IntersectionObserver"] ? true : false;
|
|
1731
1697
|
}
|
|
1732
|
-
function
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
return;
|
|
1746
|
-
}
|
|
1747
|
-
var startNode = data$a.start ? data$a.start : null;
|
|
1748
|
-
if (previous !== null && data$a.start !== null && startNode !== current.anchorNode) {
|
|
1749
|
-
clearTimeout(timeout$2);
|
|
1750
|
-
process$3(21 /* Event.Selection */);
|
|
1698
|
+
function observe$c(node, name) {
|
|
1699
|
+
if (regionMap.has(node) === false) {
|
|
1700
|
+
regionMap.set(node, name);
|
|
1701
|
+
observer$1 = observer$1 === null && watch ? new IntersectionObserver(handler$3, {
|
|
1702
|
+
// Get notified as intersection continues to change
|
|
1703
|
+
// This allows us to process regions that get partially hidden during the lifetime of the page
|
|
1704
|
+
// See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
|
|
1705
|
+
// By default, intersection observers only fire an event when even a single pixel is visible and not thereafter.
|
|
1706
|
+
threshold: [0, 0.2, 0.4, 0.6, 0.8, 1]
|
|
1707
|
+
}) : observer$1;
|
|
1708
|
+
if (observer$1 && node && node.nodeType === Node.ELEMENT_NODE) {
|
|
1709
|
+
observer$1.observe(node);
|
|
1710
|
+
}
|
|
1751
1711
|
}
|
|
1752
|
-
data$a = {
|
|
1753
|
-
start: current.anchorNode,
|
|
1754
|
-
startOffset: current.anchorOffset,
|
|
1755
|
-
end: current.focusNode,
|
|
1756
|
-
endOffset: current.focusOffset
|
|
1757
|
-
};
|
|
1758
|
-
previous = current;
|
|
1759
|
-
clearTimeout(timeout$2);
|
|
1760
|
-
timeout$2 = setTimeout(process$3, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
|
|
1761
|
-
}
|
|
1762
|
-
function process$3(event) {
|
|
1763
|
-
schedule$1(encode$3.bind(this, event));
|
|
1764
|
-
}
|
|
1765
|
-
function reset$b() {
|
|
1766
|
-
previous = null;
|
|
1767
|
-
data$a = { start: 0, startOffset: 0, end: 0, endOffset: 0 };
|
|
1768
1712
|
}
|
|
1769
|
-
function
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
var state$2 = [];
|
|
1775
|
-
function start$n() {
|
|
1776
|
-
reset$a();
|
|
1713
|
+
function exists(node) {
|
|
1714
|
+
// Check if regionMap is not null before looking up a node
|
|
1715
|
+
// Since, dom module stops after region module, it's possible that we may set regionMap to be null
|
|
1716
|
+
// and still attempt to call exists on a late coming DOM mutation (or addition), effectively causing a script error
|
|
1717
|
+
return regionMap && regionMap.has(node);
|
|
1777
1718
|
}
|
|
1778
|
-
function
|
|
1779
|
-
|
|
1719
|
+
function track$4(id, event) {
|
|
1720
|
+
var node = getNode(id);
|
|
1721
|
+
var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
|
|
1722
|
+
// Determine the interaction state based on incoming event
|
|
1723
|
+
var interaction = 16 /* InteractionState.None */;
|
|
1724
|
+
switch (event) {
|
|
1725
|
+
case 9 /* Event.Click */:
|
|
1726
|
+
interaction = 20 /* InteractionState.Clicked */;
|
|
1727
|
+
break;
|
|
1728
|
+
case 27 /* Event.Input */:
|
|
1729
|
+
interaction = 30 /* InteractionState.Input */;
|
|
1730
|
+
break;
|
|
1731
|
+
}
|
|
1732
|
+
// Process updates to this region, if applicable
|
|
1733
|
+
process$6(node, data, interaction, data.visibility);
|
|
1780
1734
|
}
|
|
1781
|
-
function
|
|
1782
|
-
|
|
1783
|
-
|
|
1735
|
+
function compute$6() {
|
|
1736
|
+
// Process any regions where we couldn't resolve an "id" for at the time of last intersection observer event
|
|
1737
|
+
// This could happen in cases where elements are not yet processed by Clarity's virtual DOM but browser reports a change, regardless.
|
|
1738
|
+
// For those cases we add them to the queue and re-process them below
|
|
1739
|
+
var q = [];
|
|
1740
|
+
for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
|
|
1741
|
+
var r = queue_1[_i];
|
|
1742
|
+
var id = getId(r.node);
|
|
1743
|
+
if (!(id in regions)) {
|
|
1744
|
+
if (id) {
|
|
1745
|
+
r.data.id = id;
|
|
1746
|
+
regions[id] = r.data;
|
|
1747
|
+
state$8.push(clone$1(r.data));
|
|
1748
|
+
}
|
|
1749
|
+
else {
|
|
1750
|
+
q.push(r);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
queue$2 = q;
|
|
1755
|
+
// Schedule encode only when we have at least one valid data entry
|
|
1756
|
+
if (state$8.length > 0) {
|
|
1757
|
+
encode$4(7 /* Event.Region */);
|
|
1758
|
+
}
|
|
1784
1759
|
}
|
|
1785
|
-
function
|
|
1786
|
-
|
|
1760
|
+
function handler$3(entries) {
|
|
1761
|
+
for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
|
|
1762
|
+
var entry = entries_1[_i];
|
|
1763
|
+
var target = entry.target;
|
|
1764
|
+
var rect = entry.boundingClientRect;
|
|
1765
|
+
var overlap = entry.intersectionRect;
|
|
1766
|
+
var viewport = entry.rootBounds;
|
|
1767
|
+
// Only capture regions that have non-zero width or height to avoid tracking and sending regions
|
|
1768
|
+
// that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
|
|
1769
|
+
// like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
|
|
1770
|
+
// Also, if these regions ever become non-zero width or height (through AJAX, user action or orientation change) - we will automatically start monitoring them from that point onwards
|
|
1771
|
+
if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
|
|
1772
|
+
var id = target ? getId(target) : null;
|
|
1773
|
+
var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
|
|
1774
|
+
// For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
|
|
1775
|
+
// However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
|
|
1776
|
+
var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
|
|
1777
|
+
var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
|
|
1778
|
+
// If an element is either visible or was visible and has been scrolled to the end
|
|
1779
|
+
// i.e. Scrolled to end is determined by if the starting position of the element + the window height is more than the total element height.
|
|
1780
|
+
// starting position is relative to the viewport - so Intersection observer returns a negative value for rect.top to indicate that the element top is above the viewport
|
|
1781
|
+
var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
|
|
1782
|
+
// Process updates to this region, if applicable
|
|
1783
|
+
process$6(target, data, data.interaction, (scrolledToEnd ?
|
|
1784
|
+
13 /* RegionVisibility.ScrolledToEnd */ :
|
|
1785
|
+
(visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
|
|
1786
|
+
// Stop observing this element now that we have already received scrolled signal
|
|
1787
|
+
if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
|
|
1788
|
+
observer$1.unobserve(target);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
if (state$8.length > 0) {
|
|
1793
|
+
encode$4(7 /* Event.Region */);
|
|
1794
|
+
}
|
|
1787
1795
|
}
|
|
1788
|
-
function
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1796
|
+
function process$6(n, d, s, v) {
|
|
1797
|
+
// Check if received a state that supersedes existing state
|
|
1798
|
+
var updated = s > d.interaction || v > d.visibility;
|
|
1799
|
+
d.interaction = s > d.interaction ? s : d.interaction;
|
|
1800
|
+
d.visibility = v > d.visibility ? v : d.visibility;
|
|
1801
|
+
// If the corresponding node is already discovered, update the internal state
|
|
1802
|
+
// Otherwise, track it in a queue to reprocess later.
|
|
1803
|
+
if (d.id) {
|
|
1804
|
+
if ((d.id in regions && updated) || !(d.id in regions)) {
|
|
1805
|
+
regions[d.id] = d;
|
|
1806
|
+
state$8.push(clone$1(d));
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
else {
|
|
1810
|
+
queue$2.push({ node: n, data: d });
|
|
1811
|
+
}
|
|
1795
1812
|
}
|
|
1796
|
-
function
|
|
1797
|
-
data
|
|
1798
|
-
encode$3(26 /* Event.Unload */, time(evt));
|
|
1799
|
-
stop();
|
|
1813
|
+
function clone$1(r) {
|
|
1814
|
+
return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
|
|
1800
1815
|
}
|
|
1801
|
-
function reset$
|
|
1802
|
-
|
|
1816
|
+
function reset$h() {
|
|
1817
|
+
state$8 = [];
|
|
1803
1818
|
}
|
|
1804
|
-
function stop$
|
|
1805
|
-
reset$
|
|
1819
|
+
function stop$s() {
|
|
1820
|
+
reset$h();
|
|
1821
|
+
regionMap = null;
|
|
1822
|
+
regions = {};
|
|
1823
|
+
queue$2 = [];
|
|
1824
|
+
if (observer$1) {
|
|
1825
|
+
observer$1.disconnect();
|
|
1826
|
+
observer$1 = null;
|
|
1827
|
+
}
|
|
1828
|
+
watch = false;
|
|
1806
1829
|
}
|
|
1807
1830
|
|
|
1808
|
-
var
|
|
1809
|
-
function start$
|
|
1810
|
-
|
|
1811
|
-
recompute();
|
|
1831
|
+
var state$7 = [];
|
|
1832
|
+
function start$t() {
|
|
1833
|
+
reset$g();
|
|
1812
1834
|
}
|
|
1813
|
-
function
|
|
1814
|
-
|
|
1815
|
-
data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
|
|
1816
|
-
encode$3(28 /* Event.Visibility */, time(evt));
|
|
1835
|
+
function observe$b(root) {
|
|
1836
|
+
bind(root, "change", recompute$8, true);
|
|
1817
1837
|
}
|
|
1818
|
-
function
|
|
1819
|
-
|
|
1838
|
+
function recompute$8(evt) {
|
|
1839
|
+
var element = target(evt);
|
|
1840
|
+
if (element) {
|
|
1841
|
+
var value = element.value;
|
|
1842
|
+
var checksum = value && value.length >= 5 /* Setting.WordLength */ && config$1.fraud ? hash(value, 24 /* Setting.ChecksumPrecision */) : "" /* Constant.Empty */;
|
|
1843
|
+
state$7.push({ time: time(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
|
|
1844
|
+
schedule$1(encode$3.bind(this, 42 /* Event.Change */));
|
|
1845
|
+
}
|
|
1820
1846
|
}
|
|
1821
|
-
function
|
|
1822
|
-
|
|
1847
|
+
function reset$g() {
|
|
1848
|
+
state$7 = [];
|
|
1849
|
+
}
|
|
1850
|
+
function stop$r() {
|
|
1851
|
+
reset$g();
|
|
1823
1852
|
}
|
|
1824
1853
|
|
|
1825
|
-
function
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
start$m();
|
|
1838
|
-
}
|
|
1839
|
-
function stop$i() {
|
|
1840
|
-
stop$e();
|
|
1841
|
-
stop$s();
|
|
1842
|
-
stop$r();
|
|
1843
|
-
stop$p();
|
|
1844
|
-
stop$q();
|
|
1845
|
-
stop$o();
|
|
1846
|
-
stop$j();
|
|
1847
|
-
stop$n();
|
|
1848
|
-
stop$m();
|
|
1849
|
-
stop$t();
|
|
1850
|
-
stop$l();
|
|
1851
|
-
stop$k();
|
|
1852
|
-
}
|
|
1853
|
-
function observe$4(root) {
|
|
1854
|
-
observe$7(root);
|
|
1855
|
-
// Only monitor following interactions if the root node is a document
|
|
1856
|
-
// In case of shadow DOM, following events automatically bubble up to the parent document.
|
|
1857
|
-
if (root.nodeType === Node.DOCUMENT_NODE) {
|
|
1858
|
-
observe$b(root);
|
|
1859
|
-
observe$a(root);
|
|
1860
|
-
observe$8(root);
|
|
1861
|
-
observe$9(root);
|
|
1862
|
-
observe$6(root);
|
|
1863
|
-
observe$c(root);
|
|
1864
|
-
observe$5(root);
|
|
1854
|
+
function offset (element) {
|
|
1855
|
+
var output = { x: 0, y: 0 };
|
|
1856
|
+
// Walk up the chain to ensure we compute offset distance correctly
|
|
1857
|
+
// In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
|
|
1858
|
+
if (element && element.offsetParent) {
|
|
1859
|
+
do {
|
|
1860
|
+
var parent_1 = element.offsetParent;
|
|
1861
|
+
var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
|
|
1862
|
+
output.x += element.offsetLeft;
|
|
1863
|
+
output.y += element.offsetTop;
|
|
1864
|
+
element = frame ? frame : parent_1;
|
|
1865
|
+
} while (element);
|
|
1865
1866
|
}
|
|
1867
|
+
return output;
|
|
1866
1868
|
}
|
|
1867
1869
|
|
|
1868
|
-
var
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
observe: observe$4
|
|
1873
|
-
});
|
|
1874
|
-
|
|
1875
|
-
var digitsRegex = /[^0-9\.]/g;
|
|
1876
|
-
/* JSON+LD (Linked Data) Recursive Parser */
|
|
1877
|
-
function ld(json) {
|
|
1878
|
-
for (var _i = 0, _a = Object.keys(json); _i < _a.length; _i++) {
|
|
1879
|
-
var key = _a[_i];
|
|
1880
|
-
var value = json[key];
|
|
1881
|
-
if (key === "@type" /* JsonLD.Type */ && typeof value === "string") {
|
|
1882
|
-
value = value.toLowerCase();
|
|
1883
|
-
/* Normalizations */
|
|
1884
|
-
value = value.indexOf("article" /* JsonLD.Article */) >= 0 || value.indexOf("posting" /* JsonLD.Posting */) >= 0 ? "article" /* JsonLD.Article */ : value;
|
|
1885
|
-
switch (value) {
|
|
1886
|
-
case "article" /* JsonLD.Article */:
|
|
1887
|
-
case "recipe" /* JsonLD.Recipe */:
|
|
1888
|
-
log(5 /* Dimension.SchemaType */, json[key]);
|
|
1889
|
-
log(8 /* Dimension.AuthorName */, json["creator" /* JsonLD.Creator */]);
|
|
1890
|
-
log(18 /* Dimension.Headline */, json["headline" /* JsonLD.Headline */]);
|
|
1891
|
-
break;
|
|
1892
|
-
case "product" /* JsonLD.Product */:
|
|
1893
|
-
log(5 /* Dimension.SchemaType */, json[key]);
|
|
1894
|
-
log(10 /* Dimension.ProductName */, json["name" /* JsonLD.Name */]);
|
|
1895
|
-
log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
|
|
1896
|
-
if (json["brand" /* JsonLD.Brand */]) {
|
|
1897
|
-
log(6 /* Dimension.ProductBrand */, json["brand" /* JsonLD.Brand */]["name" /* JsonLD.Name */]);
|
|
1898
|
-
}
|
|
1899
|
-
break;
|
|
1900
|
-
case "aggregaterating" /* JsonLD.AggregateRating */:
|
|
1901
|
-
if (json["ratingValue" /* JsonLD.RatingValue */]) {
|
|
1902
|
-
max(11 /* Metric.RatingValue */, num$1(json["ratingValue" /* JsonLD.RatingValue */], 100 /* Setting.RatingScale */));
|
|
1903
|
-
max(18 /* Metric.BestRating */, num$1(json["bestRating" /* JsonLD.BestRating */]));
|
|
1904
|
-
max(19 /* Metric.WorstRating */, num$1(json["worstRating" /* JsonLD.WorstRating */]));
|
|
1905
|
-
}
|
|
1906
|
-
max(12 /* Metric.RatingCount */, num$1(json["ratingCount" /* JsonLD.RatingCount */]));
|
|
1907
|
-
max(17 /* Metric.ReviewCount */, num$1(json["reviewCount" /* JsonLD.ReviewCount */]));
|
|
1908
|
-
break;
|
|
1909
|
-
case "person" /* JsonLD.Author */:
|
|
1910
|
-
log(8 /* Dimension.AuthorName */, json["name" /* JsonLD.Name */]);
|
|
1911
|
-
break;
|
|
1912
|
-
case "offer" /* JsonLD.Offer */:
|
|
1913
|
-
log(7 /* Dimension.ProductAvailability */, json["availability" /* JsonLD.Availability */]);
|
|
1914
|
-
log(14 /* Dimension.ProductCondition */, json["itemCondition" /* JsonLD.ItemCondition */]);
|
|
1915
|
-
log(13 /* Dimension.ProductCurrency */, json["priceCurrency" /* JsonLD.PriceCurrency */]);
|
|
1916
|
-
log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
|
|
1917
|
-
max(13 /* Metric.ProductPrice */, num$1(json["price" /* JsonLD.Price */]));
|
|
1918
|
-
break;
|
|
1919
|
-
case "brand" /* JsonLD.Brand */:
|
|
1920
|
-
log(6 /* Dimension.ProductBrand */, json["name" /* JsonLD.Name */]);
|
|
1921
|
-
break;
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
// Continue parsing nested objects
|
|
1925
|
-
if (value !== null && typeof (value) === "object" /* Constant.Object */) {
|
|
1926
|
-
ld(value);
|
|
1927
|
-
}
|
|
1928
|
-
}
|
|
1870
|
+
var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
|
|
1871
|
+
var state$6 = [];
|
|
1872
|
+
function start$s() {
|
|
1873
|
+
reset$f();
|
|
1929
1874
|
}
|
|
1930
|
-
function
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1875
|
+
function observe$a(root) {
|
|
1876
|
+
bind(root, "click", handler$2.bind(this, 9 /* Event.Click */, root), true);
|
|
1877
|
+
}
|
|
1878
|
+
function handler$2(event, root, evt) {
|
|
1879
|
+
var frame = iframe(root);
|
|
1880
|
+
var d = frame ? frame.contentDocument.documentElement : document.documentElement;
|
|
1881
|
+
var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
|
|
1882
|
+
var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
|
|
1883
|
+
// In case of iframe, we adjust (x,y) to be relative to top parent's origin
|
|
1884
|
+
if (frame) {
|
|
1885
|
+
var distance = offset(frame);
|
|
1886
|
+
x = x ? x + Math.round(distance.x) : x;
|
|
1887
|
+
y = y ? y + Math.round(distance.y) : y;
|
|
1937
1888
|
}
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
var
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
//
|
|
1947
|
-
if (
|
|
1948
|
-
|
|
1889
|
+
var t = target(evt);
|
|
1890
|
+
// Find nearest anchor tag (<a/>) parent if current target node is part of one
|
|
1891
|
+
// If present, we use the returned link element to populate text and link properties below
|
|
1892
|
+
var a = link(t);
|
|
1893
|
+
// Get layout rectangle for the target element
|
|
1894
|
+
var l = layout$1(t);
|
|
1895
|
+
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
|
|
1896
|
+
// This property helps differentiate between a keyboard navigation vs. pointer click
|
|
1897
|
+
// In case of a keyboard navigation, we use center of target element as (x,y)
|
|
1898
|
+
if (evt.detail === 0 && l) {
|
|
1899
|
+
x = Math.round(l.x + (l.w / 2));
|
|
1900
|
+
y = Math.round(l.y + (l.h / 2));
|
|
1949
1901
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
case Node.DOCUMENT_NODE:
|
|
1971
|
-
// We check for regions in the beginning when discovering document and
|
|
1972
|
-
// later whenever there are new additions or modifications to DOM (mutations)
|
|
1973
|
-
if (node === document)
|
|
1974
|
-
parse$1(document);
|
|
1975
|
-
observe$3(node);
|
|
1976
|
-
break;
|
|
1977
|
-
case Node.DOCUMENT_FRAGMENT_NODE:
|
|
1978
|
-
var shadowRoot = node;
|
|
1979
|
-
if (shadowRoot.host) {
|
|
1980
|
-
parse$1(shadowRoot);
|
|
1981
|
-
var type = typeof (shadowRoot.constructor);
|
|
1982
|
-
if (type === "function" /* Constant.Function */ && shadowRoot.constructor.toString().indexOf("[native code]" /* Constant.NativeCode */) >= 0) {
|
|
1983
|
-
observe$3(shadowRoot);
|
|
1984
|
-
// See: https://wicg.github.io/construct-stylesheets/ for more details on adoptedStyleSheets.
|
|
1985
|
-
// At the moment, we are only able to capture "open" shadow DOM nodes. If they are closed, they are not accessible.
|
|
1986
|
-
// In future we may decide to proxy "attachShadow" call to gain access, but at the moment, we don't want to
|
|
1987
|
-
// cause any unintended side effect to the page. We will re-evaluate after we gather more real world data on this.
|
|
1988
|
-
var style = "" /* Constant.Empty */;
|
|
1989
|
-
var adoptedStyleSheets = "adoptedStyleSheets" in shadowRoot ? shadowRoot["adoptedStyleSheets"] : [];
|
|
1990
|
-
for (var _i = 0, adoptedStyleSheets_1 = adoptedStyleSheets; _i < adoptedStyleSheets_1.length; _i++) {
|
|
1991
|
-
var styleSheet = adoptedStyleSheets_1[_i];
|
|
1992
|
-
style += getCssRules(styleSheet);
|
|
1993
|
-
}
|
|
1994
|
-
var fragementData = { tag: "*S" /* Constant.ShadowDomTag */, attributes: { style: style } };
|
|
1995
|
-
dom[call](node, shadowRoot.host, fragementData, source);
|
|
1996
|
-
}
|
|
1997
|
-
else {
|
|
1998
|
-
// If the browser doesn't support shadow DOM natively, we detect that, and send appropriate tag back.
|
|
1999
|
-
// The differentiation is important because we don't have to observe pollyfill shadow DOM nodes,
|
|
2000
|
-
// the same way we observe real shadow DOM nodes (encapsulation provided by the browser).
|
|
2001
|
-
dom[call](node, shadowRoot.host, { tag: "*P" /* Constant.PolyfillShadowDomTag */, attributes: {} }, source);
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
break;
|
|
2005
|
-
case Node.TEXT_NODE:
|
|
2006
|
-
// In IE11 TEXT_NODE doesn't expose a valid parentElement property. Instead we need to lookup parentNode property.
|
|
2007
|
-
parent = parent ? parent : node.parentNode;
|
|
2008
|
-
// Account for this text node only if we are tracking the parent node
|
|
2009
|
-
// We do not wish to track text nodes for ignored parent nodes, like script tags
|
|
2010
|
-
// Also, we do not track text nodes for STYLE tags
|
|
2011
|
-
// The only exception is when we receive a mutation to remove the text node, in that case
|
|
2012
|
-
// parent will be null, but we can still process the node by checking it's an update call.
|
|
2013
|
-
if (call === "update" || (parent && has(parent) && parent.tagName !== "STYLE")) {
|
|
2014
|
-
var textData = { tag: "*T" /* Constant.TextTag */, value: node.nodeValue };
|
|
2015
|
-
dom[call](node, parent, textData, source);
|
|
2016
|
-
}
|
|
2017
|
-
break;
|
|
2018
|
-
case Node.ELEMENT_NODE:
|
|
2019
|
-
var element = node;
|
|
2020
|
-
var tag = element.tagName;
|
|
2021
|
-
var attributes = getAttributes(element);
|
|
2022
|
-
// In some cases, external libraries like vue-fragment, can modify parentNode property to not be in sync with the DOM
|
|
2023
|
-
// For correctness, we first look at parentElement and if it not present then fall back to using parentNode
|
|
2024
|
-
parent = node.parentElement ? node.parentElement : (node.parentNode ? node.parentNode : null);
|
|
2025
|
-
// If we encounter a node that is part of SVG namespace, prefix the tag with SVG_PREFIX
|
|
2026
|
-
if (element.namespaceURI === "http://www.w3.org/2000/svg" /* Constant.SvgNamespace */) {
|
|
2027
|
-
tag = "svg:" /* Constant.SvgPrefix */ + tag;
|
|
2028
|
-
}
|
|
2029
|
-
switch (tag) {
|
|
2030
|
-
case "HTML":
|
|
2031
|
-
parent = insideFrame && parent ? iframe(parent) : null;
|
|
2032
|
-
var htmlPrefix = insideFrame ? "iframe:" /* Constant.IFramePrefix */ : "" /* Constant.Empty */;
|
|
2033
|
-
var htmlData = { tag: htmlPrefix + tag, attributes: attributes };
|
|
2034
|
-
dom[call](node, parent, htmlData, source);
|
|
2035
|
-
break;
|
|
2036
|
-
case "SCRIPT":
|
|
2037
|
-
if ("type" /* Constant.Type */ in attributes && attributes["type" /* Constant.Type */] === "application/ld+json" /* Constant.JsonLD */) {
|
|
2038
|
-
try {
|
|
2039
|
-
ld(JSON.parse(element.text.replace(newlineRegex, "" /* Constant.Empty */)));
|
|
2040
|
-
}
|
|
2041
|
-
catch ( /* do nothing */_b) { /* do nothing */ }
|
|
2042
|
-
}
|
|
2043
|
-
break;
|
|
2044
|
-
case "NOSCRIPT":
|
|
2045
|
-
break;
|
|
2046
|
-
case "META":
|
|
2047
|
-
var key = ("property" /* Constant.Property */ in attributes ?
|
|
2048
|
-
"property" /* Constant.Property */ :
|
|
2049
|
-
("name" /* Constant.Name */ in attributes ? "name" /* Constant.Name */ : null));
|
|
2050
|
-
if (key && "content" /* Constant.Content */ in attributes) {
|
|
2051
|
-
var content = attributes["content" /* Constant.Content */];
|
|
2052
|
-
switch (attributes[key]) {
|
|
2053
|
-
case "og:title" /* Constant.ogTitle */:
|
|
2054
|
-
log(20 /* Dimension.MetaTitle */, content);
|
|
2055
|
-
break;
|
|
2056
|
-
case "og:type" /* Constant.ogType */:
|
|
2057
|
-
log(19 /* Dimension.MetaType */, content);
|
|
2058
|
-
break;
|
|
2059
|
-
case "generator" /* Constant.Generator */:
|
|
2060
|
-
log(21 /* Dimension.Generator */, content);
|
|
2061
|
-
break;
|
|
2062
|
-
}
|
|
2063
|
-
}
|
|
2064
|
-
break;
|
|
2065
|
-
case "HEAD":
|
|
2066
|
-
var head = { tag: tag, attributes: attributes };
|
|
2067
|
-
var l = insideFrame && ((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.location) ? node.ownerDocument.location : location;
|
|
2068
|
-
head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.hostname + l.pathname;
|
|
2069
|
-
dom[call](node, parent, head, source);
|
|
2070
|
-
break;
|
|
2071
|
-
case "BASE":
|
|
2072
|
-
// Override the auto detected base path to explicit value specified in this tag
|
|
2073
|
-
var baseHead = get(node.parentElement);
|
|
2074
|
-
if (baseHead) {
|
|
2075
|
-
// We create "a" element so we can generate protocol and hostname for relative paths like "/path/"
|
|
2076
|
-
var a = document.createElement("a");
|
|
2077
|
-
a.href = attributes["href"];
|
|
2078
|
-
baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.hostname + a.pathname;
|
|
2079
|
-
}
|
|
2080
|
-
break;
|
|
2081
|
-
case "STYLE":
|
|
2082
|
-
var styleData = { tag: tag, attributes: attributes, value: getStyleValue(element) };
|
|
2083
|
-
dom[call](node, parent, styleData, source);
|
|
2084
|
-
break;
|
|
2085
|
-
case "IFRAME":
|
|
2086
|
-
var iframe$1 = node;
|
|
2087
|
-
var frameData = { tag: tag, attributes: attributes };
|
|
2088
|
-
if (sameorigin(iframe$1)) {
|
|
2089
|
-
monitor(iframe$1);
|
|
2090
|
-
frameData.attributes["*O" /* Constant.SameOrigin */] = "true";
|
|
2091
|
-
if (iframe$1.contentDocument && iframe$1.contentWindow && iframe$1.contentDocument.readyState !== "loading") {
|
|
2092
|
-
child = iframe$1.contentDocument;
|
|
2093
|
-
}
|
|
2094
|
-
}
|
|
2095
|
-
dom[call](node, parent, frameData, source);
|
|
2096
|
-
break;
|
|
2097
|
-
default:
|
|
2098
|
-
var data = { tag: tag, attributes: attributes };
|
|
2099
|
-
if (element.shadowRoot) {
|
|
2100
|
-
child = element.shadowRoot;
|
|
2101
|
-
}
|
|
2102
|
-
dom[call](node, parent, data, source);
|
|
2103
|
-
break;
|
|
1902
|
+
var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1903
|
+
var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1904
|
+
// Check for null values before processing this event
|
|
1905
|
+
if (x !== null && y !== null) {
|
|
1906
|
+
state$6.push({
|
|
1907
|
+
time: time(evt),
|
|
1908
|
+
event: event,
|
|
1909
|
+
data: {
|
|
1910
|
+
target: t,
|
|
1911
|
+
x: x,
|
|
1912
|
+
y: y,
|
|
1913
|
+
eX: eX,
|
|
1914
|
+
eY: eY,
|
|
1915
|
+
button: evt.button,
|
|
1916
|
+
reaction: reaction(t),
|
|
1917
|
+
context: context(a),
|
|
1918
|
+
text: text(t),
|
|
1919
|
+
link: a ? a.href : null,
|
|
1920
|
+
hash: null,
|
|
1921
|
+
trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
|
|
2104
1922
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
return child;
|
|
2108
|
-
}
|
|
2109
|
-
function observe$3(root) {
|
|
2110
|
-
if (has(root)) {
|
|
2111
|
-
return;
|
|
1923
|
+
});
|
|
1924
|
+
schedule$1(encode$3.bind(this, event));
|
|
2112
1925
|
}
|
|
2113
|
-
observe$2(root); // Observe mutations for this root node
|
|
2114
|
-
observe$4(root); // Observe interactions for this root node
|
|
2115
1926
|
}
|
|
2116
|
-
function
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
1927
|
+
function text(element) {
|
|
1928
|
+
var output = null;
|
|
1929
|
+
if (element) {
|
|
1930
|
+
// Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
|
|
1931
|
+
var t = element.textContent || element.value || element.alt;
|
|
1932
|
+
if (t) {
|
|
1933
|
+
// Trim any spaces at the beginning or at the end of string
|
|
1934
|
+
// Also, replace multiple occurrence of space characters with a single white space
|
|
1935
|
+
// Finally, send only first few characters as specified by the Setting
|
|
1936
|
+
output = t.trim().replace(/\s+/g, " " /* Constant.Space */).substr(0, 25 /* Setting.ClickText */);
|
|
1937
|
+
}
|
|
2123
1938
|
}
|
|
2124
|
-
return
|
|
1939
|
+
return output;
|
|
2125
1940
|
}
|
|
2126
|
-
function
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
cssRules = sheet ? sheet.cssRules : [];
|
|
2132
|
-
}
|
|
2133
|
-
catch (e) {
|
|
2134
|
-
log$1(1 /* Code.CssRules */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
2135
|
-
if (e && e.name !== "SecurityError") {
|
|
2136
|
-
throw e;
|
|
1941
|
+
function reaction(element) {
|
|
1942
|
+
if (element.nodeType === Node.ELEMENT_NODE) {
|
|
1943
|
+
var tag = element.tagName.toLowerCase();
|
|
1944
|
+
if (UserInputTags.indexOf(tag) >= 0) {
|
|
1945
|
+
return 0 /* BooleanFlag.False */;
|
|
2137
1946
|
}
|
|
2138
1947
|
}
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
1948
|
+
return 1 /* BooleanFlag.True */;
|
|
1949
|
+
}
|
|
1950
|
+
function layout$1(element) {
|
|
1951
|
+
var box = null;
|
|
1952
|
+
var de = document.documentElement;
|
|
1953
|
+
if (typeof element.getBoundingClientRect === "function") {
|
|
1954
|
+
// getBoundingClientRect returns rectangle relative positioning to viewport
|
|
1955
|
+
var rect = element.getBoundingClientRect();
|
|
1956
|
+
if (rect && rect.width > 0 && rect.height > 0) {
|
|
1957
|
+
// Add viewport's scroll position to rectangle to get position relative to document origin
|
|
1958
|
+
// Also: using Math.floor() instead of Math.round() because in Edge,
|
|
1959
|
+
// getBoundingClientRect returns partial pixel values (e.g. 162.5px) and Chrome already
|
|
1960
|
+
// floors the value (e.g. 162px). This keeps consistent behavior across browsers.
|
|
1961
|
+
box = {
|
|
1962
|
+
x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
|
|
1963
|
+
y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
|
|
1964
|
+
w: Math.floor(rect.width),
|
|
1965
|
+
h: Math.floor(rect.height)
|
|
1966
|
+
};
|
|
2142
1967
|
}
|
|
2143
1968
|
}
|
|
2144
|
-
return
|
|
1969
|
+
return box;
|
|
2145
1970
|
}
|
|
2146
|
-
function
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
if (IGNORE_ATTRIBUTES.indexOf(name_1) < 0) {
|
|
2153
|
-
output[name_1] = attributes[i].value;
|
|
2154
|
-
}
|
|
1971
|
+
function context(a) {
|
|
1972
|
+
if (a && a.hasAttribute("target" /* Constant.Target */)) {
|
|
1973
|
+
switch (a.getAttribute("target" /* Constant.Target */)) {
|
|
1974
|
+
case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
|
|
1975
|
+
case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
|
|
1976
|
+
case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
|
|
2155
1977
|
}
|
|
2156
1978
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
1979
|
+
return 0 /* BrowsingContext.Self */;
|
|
1980
|
+
}
|
|
1981
|
+
function reset$f() {
|
|
1982
|
+
state$6 = [];
|
|
1983
|
+
}
|
|
1984
|
+
function stop$q() {
|
|
1985
|
+
reset$f();
|
|
2162
1986
|
}
|
|
2163
1987
|
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
return [4 /*yield*/, suspend$1(timer)];
|
|
2183
|
-
case 2:
|
|
2184
|
-
state = _a.sent();
|
|
2185
|
-
_a.label = 3;
|
|
2186
|
-
case 3:
|
|
2187
|
-
if (state === 2 /* Task.Stop */) {
|
|
2188
|
-
return [3 /*break*/, 4];
|
|
2189
|
-
}
|
|
2190
|
-
subnode = processNode(node, source);
|
|
2191
|
-
if (subnode) {
|
|
2192
|
-
queue.push(subnode);
|
|
2193
|
-
}
|
|
2194
|
-
return [3 /*break*/, 1];
|
|
2195
|
-
case 4: return [2 /*return*/];
|
|
2196
|
-
}
|
|
2197
|
-
});
|
|
2198
|
-
});
|
|
1988
|
+
var state$5 = [];
|
|
1989
|
+
function start$r() {
|
|
1990
|
+
reset$e();
|
|
1991
|
+
}
|
|
1992
|
+
function observe$9(root) {
|
|
1993
|
+
bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
|
|
1994
|
+
bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
|
|
1995
|
+
bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
|
|
1996
|
+
}
|
|
1997
|
+
function recompute$7(action, evt) {
|
|
1998
|
+
state$5.push({ time: time(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
|
|
1999
|
+
schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
|
|
2000
|
+
}
|
|
2001
|
+
function reset$e() {
|
|
2002
|
+
state$5 = [];
|
|
2003
|
+
}
|
|
2004
|
+
function stop$p() {
|
|
2005
|
+
reset$e();
|
|
2199
2006
|
}
|
|
2200
2007
|
|
|
2201
|
-
var
|
|
2202
|
-
var
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
// need to override the insertRule API and listen for changes manually.
|
|
2220
|
-
if (insertRule === null) {
|
|
2221
|
-
insertRule = CSSStyleSheet.prototype.insertRule;
|
|
2222
|
-
CSSStyleSheet.prototype.insertRule = function () {
|
|
2223
|
-
if (active()) {
|
|
2224
|
-
schedule(this.ownerNode);
|
|
2225
|
-
}
|
|
2226
|
-
return insertRule.apply(this, arguments);
|
|
2227
|
-
};
|
|
2228
|
-
}
|
|
2229
|
-
if (deleteRule === null) {
|
|
2230
|
-
deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
2231
|
-
CSSStyleSheet.prototype.deleteRule = function () {
|
|
2232
|
-
if (active()) {
|
|
2233
|
-
schedule(this.ownerNode);
|
|
2234
|
-
}
|
|
2235
|
-
return deleteRule.apply(this, arguments);
|
|
2236
|
-
};
|
|
2237
|
-
}
|
|
2238
|
-
// Add a hook to attachShadow API calls
|
|
2239
|
-
// In case we are unable to add a hook and browser throws an exception,
|
|
2240
|
-
// reset attachShadow variable and resume processing like before
|
|
2241
|
-
if (attachShadow === null) {
|
|
2242
|
-
attachShadow = Element.prototype.attachShadow;
|
|
2243
|
-
try {
|
|
2244
|
-
Element.prototype.attachShadow = function () {
|
|
2245
|
-
if (active()) {
|
|
2246
|
-
return schedule(attachShadow.apply(this, arguments));
|
|
2247
|
-
}
|
|
2248
|
-
else {
|
|
2249
|
-
return attachShadow.apply(this, arguments);
|
|
2250
|
-
}
|
|
2251
|
-
};
|
|
2008
|
+
var timeout$5 = null;
|
|
2009
|
+
var state$4 = [];
|
|
2010
|
+
function start$q() {
|
|
2011
|
+
reset$d();
|
|
2012
|
+
}
|
|
2013
|
+
function observe$8(root) {
|
|
2014
|
+
bind(root, "input", recompute$6, true);
|
|
2015
|
+
}
|
|
2016
|
+
function recompute$6(evt) {
|
|
2017
|
+
var input = target(evt);
|
|
2018
|
+
var value = get(input);
|
|
2019
|
+
if (input && input.type && value) {
|
|
2020
|
+
var v = input.value;
|
|
2021
|
+
switch (input.type) {
|
|
2022
|
+
case "radio":
|
|
2023
|
+
case "checkbox":
|
|
2024
|
+
v = input.checked ? "true" : "false";
|
|
2025
|
+
break;
|
|
2252
2026
|
}
|
|
2253
|
-
|
|
2254
|
-
|
|
2027
|
+
var data = { target: input, value: v };
|
|
2028
|
+
// If last entry in the queue is for the same target node as the current one, remove it so we can later swap it with current data.
|
|
2029
|
+
if (state$4.length > 0 && (state$4[state$4.length - 1].data.target === data.target)) {
|
|
2030
|
+
state$4.pop();
|
|
2255
2031
|
}
|
|
2032
|
+
state$4.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
|
|
2033
|
+
clearTimeout(timeout$5);
|
|
2034
|
+
timeout$5 = setTimeout(process$5, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
|
|
2256
2035
|
}
|
|
2257
2036
|
}
|
|
2258
|
-
function
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2037
|
+
function process$5(event) {
|
|
2038
|
+
schedule$1(encode$3.bind(this, event));
|
|
2039
|
+
}
|
|
2040
|
+
function reset$d() {
|
|
2041
|
+
state$4 = [];
|
|
2042
|
+
}
|
|
2043
|
+
function stop$o() {
|
|
2044
|
+
clearTimeout(timeout$5);
|
|
2045
|
+
reset$d();
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
var state$3 = [];
|
|
2049
|
+
var timeout$4 = null;
|
|
2050
|
+
function start$p() {
|
|
2051
|
+
reset$c();
|
|
2052
|
+
}
|
|
2053
|
+
function observe$7(root) {
|
|
2054
|
+
bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
|
|
2055
|
+
bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
|
|
2056
|
+
bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
|
|
2057
|
+
bind(root, "wheel", mouse.bind(this, 15 /* Event.MouseWheel */, root), true);
|
|
2058
|
+
bind(root, "dblclick", mouse.bind(this, 16 /* Event.DoubleClick */, root), true);
|
|
2059
|
+
bind(root, "touchstart", touch.bind(this, 17 /* Event.TouchStart */, root), true);
|
|
2060
|
+
bind(root, "touchend", touch.bind(this, 18 /* Event.TouchEnd */, root), true);
|
|
2061
|
+
bind(root, "touchmove", touch.bind(this, 19 /* Event.TouchMove */, root), true);
|
|
2062
|
+
bind(root, "touchcancel", touch.bind(this, 20 /* Event.TouchCancel */, root), true);
|
|
2063
|
+
}
|
|
2064
|
+
function mouse(event, root, evt) {
|
|
2065
|
+
var frame = iframe(root);
|
|
2066
|
+
var d = frame ? frame.contentDocument.documentElement : document.documentElement;
|
|
2067
|
+
var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
|
|
2068
|
+
var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
|
|
2069
|
+
// In case of iframe, we adjust (x,y) to be relative to top parent's origin
|
|
2070
|
+
if (frame) {
|
|
2071
|
+
var distance = offset(frame);
|
|
2072
|
+
x = x ? x + Math.round(distance.x) : x;
|
|
2073
|
+
y = y ? y + Math.round(distance.y) : y;
|
|
2270
2074
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2075
|
+
// Check for null values before processing this event
|
|
2076
|
+
if (x !== null && y !== null) {
|
|
2077
|
+
handler$1({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
|
|
2273
2078
|
}
|
|
2274
2079
|
}
|
|
2275
|
-
function
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2080
|
+
function touch(event, root, evt) {
|
|
2081
|
+
var frame = iframe(root);
|
|
2082
|
+
var d = frame ? frame.contentDocument.documentElement : document.documentElement;
|
|
2083
|
+
var touches = evt.changedTouches;
|
|
2084
|
+
var t = time(evt);
|
|
2085
|
+
if (touches) {
|
|
2086
|
+
for (var i = 0; i < touches.length; i++) {
|
|
2087
|
+
var entry = touches[i];
|
|
2088
|
+
var x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
|
|
2089
|
+
var y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
|
|
2090
|
+
x = x && frame ? x + Math.round(frame.offsetLeft) : x;
|
|
2091
|
+
y = y && frame ? y + Math.round(frame.offsetTop) : y;
|
|
2092
|
+
// Check for null values before processing this event
|
|
2093
|
+
if (x !== null && y !== null) {
|
|
2094
|
+
handler$1({ time: t, event: event, data: { target: target(evt), x: x, y: y } });
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2281
2097
|
}
|
|
2282
2098
|
}
|
|
2283
|
-
function
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2099
|
+
function handler$1(current) {
|
|
2100
|
+
switch (current.event) {
|
|
2101
|
+
case 12 /* Event.MouseMove */:
|
|
2102
|
+
case 15 /* Event.MouseWheel */:
|
|
2103
|
+
case 19 /* Event.TouchMove */:
|
|
2104
|
+
var length_1 = state$3.length;
|
|
2105
|
+
var last = length_1 > 1 ? state$3[length_1 - 2] : null;
|
|
2106
|
+
if (last && similar$1(last, current)) {
|
|
2107
|
+
state$3.pop();
|
|
2108
|
+
}
|
|
2109
|
+
state$3.push(current);
|
|
2110
|
+
clearTimeout(timeout$4);
|
|
2111
|
+
timeout$4 = setTimeout(process$4, 500 /* Setting.LookAhead */, current.event);
|
|
2112
|
+
break;
|
|
2113
|
+
default:
|
|
2114
|
+
state$3.push(current);
|
|
2115
|
+
process$4(current.event);
|
|
2116
|
+
break;
|
|
2289
2117
|
}
|
|
2290
|
-
observers = [];
|
|
2291
|
-
history$4 = {};
|
|
2292
|
-
mutations = [];
|
|
2293
|
-
queue$2 = [];
|
|
2294
|
-
activePeriod = 0;
|
|
2295
|
-
timeout$1 = null;
|
|
2296
2118
|
}
|
|
2297
|
-
function
|
|
2298
|
-
|
|
2119
|
+
function process$4(event) {
|
|
2120
|
+
schedule$1(encode$3.bind(this, event));
|
|
2299
2121
|
}
|
|
2300
|
-
function
|
|
2301
|
-
|
|
2302
|
-
var now = time();
|
|
2303
|
-
track$6(6 /* Event.Mutation */, now);
|
|
2304
|
-
mutations.push({ time: now, mutations: m });
|
|
2305
|
-
schedule$1(process$2, 1 /* Priority.High */).then(function () {
|
|
2306
|
-
setTimeout(compute$7);
|
|
2307
|
-
measure(compute$6)();
|
|
2308
|
-
});
|
|
2122
|
+
function reset$c() {
|
|
2123
|
+
state$3 = [];
|
|
2309
2124
|
}
|
|
2310
|
-
function
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
start$x(timer);
|
|
2318
|
-
_b.label = 1;
|
|
2319
|
-
case 1:
|
|
2320
|
-
if (!(mutations.length > 0)) return [3 /*break*/, 8];
|
|
2321
|
-
record = mutations.shift();
|
|
2322
|
-
instance = time();
|
|
2323
|
-
_i = 0, _a = record.mutations;
|
|
2324
|
-
_b.label = 2;
|
|
2325
|
-
case 2:
|
|
2326
|
-
if (!(_i < _a.length)) return [3 /*break*/, 6];
|
|
2327
|
-
mutation = _a[_i];
|
|
2328
|
-
state = state$9(timer);
|
|
2329
|
-
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
|
|
2330
|
-
return [4 /*yield*/, suspend$1(timer)];
|
|
2331
|
-
case 3:
|
|
2332
|
-
state = _b.sent();
|
|
2333
|
-
_b.label = 4;
|
|
2334
|
-
case 4:
|
|
2335
|
-
if (state === 2 /* Task.Stop */) {
|
|
2336
|
-
return [3 /*break*/, 6];
|
|
2337
|
-
}
|
|
2338
|
-
target = mutation.target;
|
|
2339
|
-
type = track$5(mutation, timer, instance);
|
|
2340
|
-
if (type && target && target.ownerDocument) {
|
|
2341
|
-
parse$1(target.ownerDocument);
|
|
2342
|
-
}
|
|
2343
|
-
if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
|
|
2344
|
-
parse$1(target);
|
|
2345
|
-
}
|
|
2346
|
-
switch (type) {
|
|
2347
|
-
case "attributes" /* Constant.Attributes */:
|
|
2348
|
-
processNode(target, 3 /* Source.Attributes */);
|
|
2349
|
-
break;
|
|
2350
|
-
case "characterData" /* Constant.CharacterData */:
|
|
2351
|
-
processNode(target, 4 /* Source.CharacterData */);
|
|
2352
|
-
break;
|
|
2353
|
-
case "childList" /* Constant.ChildList */:
|
|
2354
|
-
processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer);
|
|
2355
|
-
processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer);
|
|
2356
|
-
break;
|
|
2357
|
-
case "suspend" /* Constant.Suspend */:
|
|
2358
|
-
value = get(target);
|
|
2359
|
-
if (value) {
|
|
2360
|
-
value.metadata.suspend = true;
|
|
2361
|
-
}
|
|
2362
|
-
break;
|
|
2363
|
-
}
|
|
2364
|
-
_b.label = 5;
|
|
2365
|
-
case 5:
|
|
2366
|
-
_i++;
|
|
2367
|
-
return [3 /*break*/, 2];
|
|
2368
|
-
case 6: return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
|
|
2369
|
-
case 7:
|
|
2370
|
-
_b.sent();
|
|
2371
|
-
return [3 /*break*/, 1];
|
|
2372
|
-
case 8:
|
|
2373
|
-
stop$u(timer);
|
|
2374
|
-
return [2 /*return*/];
|
|
2375
|
-
}
|
|
2376
|
-
});
|
|
2377
|
-
});
|
|
2125
|
+
function similar$1(last, current) {
|
|
2126
|
+
var dx = last.data.x - current.data.x;
|
|
2127
|
+
var dy = last.data.y - current.data.y;
|
|
2128
|
+
var distance = Math.sqrt(dx * dx + dy * dy);
|
|
2129
|
+
var gap = current.time - last.time;
|
|
2130
|
+
var match = current.data.target === last.data.target;
|
|
2131
|
+
return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
|
|
2378
2132
|
}
|
|
2379
|
-
function
|
|
2380
|
-
|
|
2381
|
-
//
|
|
2382
|
-
if (
|
|
2383
|
-
|
|
2384
|
-
var target = get(m.target);
|
|
2385
|
-
var element = target && target.selector ? target.selector.join() : m.target.nodeName;
|
|
2386
|
-
var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
|
|
2387
|
-
// We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
|
|
2388
|
-
// repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
|
|
2389
|
-
// In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
|
|
2390
|
-
var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
|
|
2391
|
-
// Initialize an entry if it doesn't already exist
|
|
2392
|
-
history$4[key] = key in history$4 ? history$4[key] : [0, instance];
|
|
2393
|
-
var h = history$4[key];
|
|
2394
|
-
// Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
|
|
2395
|
-
if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
|
|
2396
|
-
processNodeList(h[2], 2 /* Source.ChildListRemove */, timer);
|
|
2397
|
-
}
|
|
2398
|
-
// Update the counter
|
|
2399
|
-
h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
|
|
2400
|
-
h[1] = instance;
|
|
2401
|
-
// Return updated mutation type based on if we have already hit the threshold or not
|
|
2402
|
-
if (h[0] === 10 /* Setting.MutationSuspendThreshold */) {
|
|
2403
|
-
// Store a reference to removedNodes so we can process them later
|
|
2404
|
-
// when we resume mutations again on user interactions
|
|
2405
|
-
h[2] = m.removedNodes;
|
|
2406
|
-
return "suspend" /* Constant.Suspend */;
|
|
2407
|
-
}
|
|
2408
|
-
else if (h[0] > 10 /* Setting.MutationSuspendThreshold */) {
|
|
2409
|
-
return "" /* Constant.Empty */;
|
|
2410
|
-
}
|
|
2133
|
+
function stop$n() {
|
|
2134
|
+
clearTimeout(timeout$4);
|
|
2135
|
+
// Send out any pending pointer events in the pipeline
|
|
2136
|
+
if (state$3.length > 0) {
|
|
2137
|
+
process$4(state$3[state$3.length - 1].event);
|
|
2411
2138
|
}
|
|
2412
|
-
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
var data$b;
|
|
2142
|
+
function start$o() {
|
|
2143
|
+
bind(window, "resize", recompute$5);
|
|
2144
|
+
recompute$5();
|
|
2413
2145
|
}
|
|
2414
|
-
function
|
|
2415
|
-
var
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2146
|
+
function recompute$5() {
|
|
2147
|
+
var de = document.documentElement;
|
|
2148
|
+
// window.innerWidth includes width of the scrollbar and is not a true representation of the viewport width.
|
|
2149
|
+
// Therefore, when possible, use documentElement's clientWidth property.
|
|
2150
|
+
data$b = {
|
|
2151
|
+
width: de && "clientWidth" in de ? Math.min(de.clientWidth, window.innerWidth) : window.innerWidth,
|
|
2152
|
+
height: de && "clientHeight" in de ? Math.min(de.clientHeight, window.innerHeight) : window.innerHeight,
|
|
2153
|
+
};
|
|
2154
|
+
encode$3(11 /* Event.Resize */);
|
|
2420
2155
|
}
|
|
2421
|
-
function
|
|
2422
|
-
|
|
2423
|
-
var length, i, state;
|
|
2424
|
-
return __generator(this, function (_a) {
|
|
2425
|
-
switch (_a.label) {
|
|
2426
|
-
case 0:
|
|
2427
|
-
length = list ? list.length : 0;
|
|
2428
|
-
i = 0;
|
|
2429
|
-
_a.label = 1;
|
|
2430
|
-
case 1:
|
|
2431
|
-
if (!(i < length)) return [3 /*break*/, 6];
|
|
2432
|
-
if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
|
|
2433
|
-
traverse(list[i], timer, source);
|
|
2434
|
-
return [3 /*break*/, 5];
|
|
2435
|
-
case 2:
|
|
2436
|
-
state = state$9(timer);
|
|
2437
|
-
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
|
|
2438
|
-
return [4 /*yield*/, suspend$1(timer)];
|
|
2439
|
-
case 3:
|
|
2440
|
-
state = _a.sent();
|
|
2441
|
-
_a.label = 4;
|
|
2442
|
-
case 4:
|
|
2443
|
-
if (state === 2 /* Task.Stop */) {
|
|
2444
|
-
return [3 /*break*/, 6];
|
|
2445
|
-
}
|
|
2446
|
-
processNode(list[i], source);
|
|
2447
|
-
_a.label = 5;
|
|
2448
|
-
case 5:
|
|
2449
|
-
i++;
|
|
2450
|
-
return [3 /*break*/, 1];
|
|
2451
|
-
case 6: return [2 /*return*/];
|
|
2452
|
-
}
|
|
2453
|
-
});
|
|
2454
|
-
});
|
|
2156
|
+
function reset$b() {
|
|
2157
|
+
data$b = null;
|
|
2455
2158
|
}
|
|
2456
|
-
function
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2159
|
+
function stop$m() {
|
|
2160
|
+
reset$b();
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
var state$2 = [];
|
|
2164
|
+
var timeout$3 = null;
|
|
2165
|
+
function start$n() {
|
|
2166
|
+
state$2 = [];
|
|
2167
|
+
recompute$4();
|
|
2168
|
+
}
|
|
2169
|
+
function observe$6(root) {
|
|
2170
|
+
var frame = iframe(root);
|
|
2171
|
+
var node = frame ? frame.contentWindow : (root === document ? window : root);
|
|
2172
|
+
bind(node, "scroll", recompute$4, true);
|
|
2173
|
+
}
|
|
2174
|
+
function recompute$4(event) {
|
|
2175
|
+
if (event === void 0) { event = null; }
|
|
2176
|
+
var w = window;
|
|
2177
|
+
var de = document.documentElement;
|
|
2178
|
+
var element = event ? target(event) : de;
|
|
2179
|
+
// If the target is a Document node, then identify corresponding documentElement and window for this document
|
|
2180
|
+
if (element && element.nodeType === Node.DOCUMENT_NODE) {
|
|
2181
|
+
var frame = iframe(element);
|
|
2182
|
+
w = frame ? frame.contentWindow : w;
|
|
2183
|
+
element = de = element.documentElement;
|
|
2461
2184
|
}
|
|
2462
|
-
//
|
|
2463
|
-
//
|
|
2464
|
-
// And
|
|
2465
|
-
|
|
2466
|
-
|
|
2185
|
+
// Edge doesn't support scrollTop position on document.documentElement.
|
|
2186
|
+
// For cross browser compatibility, looking up pageYOffset on window if the scroll is on document.
|
|
2187
|
+
// And, if for some reason that is not available, fall back to looking up scrollTop on document.documentElement.
|
|
2188
|
+
var x = element === de && "pageXOffset" in w ? Math.round(w.pageXOffset) : Math.round(element.scrollLeft);
|
|
2189
|
+
var y = element === de && "pageYOffset" in w ? Math.round(w.pageYOffset) : Math.round(element.scrollTop);
|
|
2190
|
+
var current = { time: time(event), event: 10 /* Event.Scroll */, data: { target: element, x: x, y: y } };
|
|
2191
|
+
// We don't send any scroll events if this is the first event and the current position is top (0,0)
|
|
2192
|
+
if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
|
|
2193
|
+
return;
|
|
2467
2194
|
}
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
|
|
2473
|
-
var node = queue_1[_i];
|
|
2474
|
-
// Generate a mutation for this node only if it still exists
|
|
2475
|
-
if (node) {
|
|
2476
|
-
var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
|
2477
|
-
// Skip re-processing shadowRoot if it was already discovered
|
|
2478
|
-
if (shadowRoot && has(node)) {
|
|
2479
|
-
continue;
|
|
2480
|
-
}
|
|
2481
|
-
generate(node, shadowRoot || fragment ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
|
|
2482
|
-
}
|
|
2195
|
+
var length = state$2.length;
|
|
2196
|
+
var last = length > 1 ? state$2[length - 2] : null;
|
|
2197
|
+
if (last && similar(last, current)) {
|
|
2198
|
+
state$2.pop();
|
|
2483
2199
|
}
|
|
2484
|
-
|
|
2200
|
+
state$2.push(current);
|
|
2201
|
+
clearTimeout(timeout$3);
|
|
2202
|
+
timeout$3 = setTimeout(process$3, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
|
|
2485
2203
|
}
|
|
2486
|
-
function
|
|
2487
|
-
|
|
2488
|
-
addedNodes: [target],
|
|
2489
|
-
attributeName: null,
|
|
2490
|
-
attributeNamespace: null,
|
|
2491
|
-
nextSibling: null,
|
|
2492
|
-
oldValue: null,
|
|
2493
|
-
previousSibling: null,
|
|
2494
|
-
removedNodes: [],
|
|
2495
|
-
target: target,
|
|
2496
|
-
type: type
|
|
2497
|
-
}]);
|
|
2498
|
-
}
|
|
2499
|
-
|
|
2500
|
-
var index = 1;
|
|
2501
|
-
var nodes = [];
|
|
2502
|
-
var values = [];
|
|
2503
|
-
var updateMap = [];
|
|
2504
|
-
var hashMap = {};
|
|
2505
|
-
var override = [];
|
|
2506
|
-
var unmask = [];
|
|
2507
|
-
var updatedFragments = {};
|
|
2508
|
-
var maskText = [];
|
|
2509
|
-
var maskExclude = [];
|
|
2510
|
-
var maskDisable = [];
|
|
2511
|
-
var maskTags = [];
|
|
2512
|
-
// The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
|
|
2513
|
-
var idMap = null; // Maps node => id.
|
|
2514
|
-
var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
|
|
2515
|
-
var privacyMap = null; // Maps node => Privacy (enum)
|
|
2516
|
-
var fraudMap = null; // Maps node => FraudId (number)
|
|
2517
|
-
function start$i() {
|
|
2518
|
-
reset$7();
|
|
2519
|
-
parse$1(document, true);
|
|
2204
|
+
function reset$a() {
|
|
2205
|
+
state$2 = [];
|
|
2520
2206
|
}
|
|
2521
|
-
function
|
|
2522
|
-
|
|
2207
|
+
function process$3(event) {
|
|
2208
|
+
schedule$1(encode$3.bind(this, event));
|
|
2523
2209
|
}
|
|
2524
|
-
function
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
updateMap = [];
|
|
2529
|
-
hashMap = {};
|
|
2530
|
-
override = [];
|
|
2531
|
-
unmask = [];
|
|
2532
|
-
maskText = "address,password,contact" /* Mask.Text */.split("," /* Constant.Comma */);
|
|
2533
|
-
maskExclude = "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.split("," /* Constant.Comma */);
|
|
2534
|
-
maskDisable = "radio,checkbox,range,button,reset,submit" /* Mask.Disable */.split("," /* Constant.Comma */);
|
|
2535
|
-
maskTags = "INPUT,SELECT,TEXTAREA" /* Mask.Tags */.split("," /* Constant.Comma */);
|
|
2536
|
-
idMap = new WeakMap();
|
|
2537
|
-
iframeMap = new WeakMap();
|
|
2538
|
-
privacyMap = new WeakMap();
|
|
2539
|
-
fraudMap = new WeakMap();
|
|
2540
|
-
reset$l();
|
|
2210
|
+
function similar(last, current) {
|
|
2211
|
+
var dx = last.data.x - current.data.x;
|
|
2212
|
+
var dy = last.data.y - current.data.y;
|
|
2213
|
+
return (dx * dx + dy * dy < 20 /* Setting.Distance */ * 20 /* Setting.Distance */) && (current.time - last.time < 25 /* Setting.Interval */);
|
|
2541
2214
|
}
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2215
|
+
function stop$l() {
|
|
2216
|
+
clearTimeout(timeout$3);
|
|
2217
|
+
state$2 = [];
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
var data$a = null;
|
|
2221
|
+
var previous = null;
|
|
2222
|
+
var timeout$2 = null;
|
|
2223
|
+
function start$m() {
|
|
2224
|
+
reset$9();
|
|
2225
|
+
}
|
|
2226
|
+
function observe$5(root) {
|
|
2227
|
+
bind(root, "selectstart", recompute$3.bind(this, root), true);
|
|
2228
|
+
bind(root, "selectionchange", recompute$3.bind(this, root), true);
|
|
2229
|
+
}
|
|
2230
|
+
function recompute$3(root) {
|
|
2231
|
+
var doc = root.nodeType === Node.DOCUMENT_NODE ? root : document;
|
|
2232
|
+
var current = doc.getSelection();
|
|
2233
|
+
// Bail out if we don't have a valid selection
|
|
2234
|
+
if (current === null) {
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
2237
|
+
// Bail out if we got a valid selection but not valid nodes
|
|
2238
|
+
// In Edge, selectionchange gets fired even on interactions like right clicks and
|
|
2239
|
+
// can result in null anchorNode and focusNode if there was no previous selection on page
|
|
2240
|
+
// Also, ignore any selections that start and end at the exact same point
|
|
2241
|
+
if ((current.anchorNode === null && current.focusNode === null) ||
|
|
2242
|
+
(current.anchorNode === current.focusNode && current.anchorOffset === current.focusOffset)) {
|
|
2243
|
+
return;
|
|
2244
|
+
}
|
|
2245
|
+
var startNode = data$a.start ? data$a.start : null;
|
|
2246
|
+
if (previous !== null && data$a.start !== null && startNode !== current.anchorNode) {
|
|
2247
|
+
clearTimeout(timeout$2);
|
|
2248
|
+
process$2(21 /* Event.Selection */);
|
|
2249
|
+
}
|
|
2250
|
+
data$a = {
|
|
2251
|
+
start: current.anchorNode,
|
|
2252
|
+
startOffset: current.anchorOffset,
|
|
2253
|
+
end: current.focusNode,
|
|
2254
|
+
endOffset: current.focusOffset
|
|
2255
|
+
};
|
|
2256
|
+
previous = current;
|
|
2257
|
+
clearTimeout(timeout$2);
|
|
2258
|
+
timeout$2 = setTimeout(process$2, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
|
|
2259
|
+
}
|
|
2260
|
+
function process$2(event) {
|
|
2261
|
+
schedule$1(encode$3.bind(this, event));
|
|
2262
|
+
}
|
|
2263
|
+
function reset$9() {
|
|
2264
|
+
previous = null;
|
|
2265
|
+
data$a = { start: 0, startOffset: 0, end: 0, endOffset: 0 };
|
|
2266
|
+
}
|
|
2267
|
+
function stop$k() {
|
|
2268
|
+
reset$9();
|
|
2269
|
+
clearTimeout(timeout$2);
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
var state$1 = [];
|
|
2273
|
+
function start$l() {
|
|
2274
|
+
reset$8();
|
|
2275
|
+
}
|
|
2276
|
+
function observe$4(root) {
|
|
2277
|
+
bind(root, "submit", recompute$2, true);
|
|
2278
|
+
}
|
|
2279
|
+
function recompute$2(evt) {
|
|
2280
|
+
state$1.push({ time: time(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
|
|
2281
|
+
schedule$1(encode$3.bind(this, 39 /* Event.Submit */));
|
|
2282
|
+
}
|
|
2283
|
+
function reset$8() {
|
|
2284
|
+
state$1 = [];
|
|
2285
|
+
}
|
|
2286
|
+
function stop$j() {
|
|
2287
|
+
reset$8();
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
var data$9;
|
|
2291
|
+
function start$k() {
|
|
2292
|
+
bind(window, "pagehide", recompute$1);
|
|
2293
|
+
}
|
|
2294
|
+
function recompute$1(evt) {
|
|
2295
|
+
data$9 = { name: evt.type };
|
|
2296
|
+
encode$3(26 /* Event.Unload */, time(evt));
|
|
2297
|
+
stop();
|
|
2298
|
+
}
|
|
2299
|
+
function reset$7() {
|
|
2300
|
+
data$9 = null;
|
|
2301
|
+
}
|
|
2302
|
+
function stop$i() {
|
|
2303
|
+
reset$7();
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
var data$8;
|
|
2307
|
+
function start$j() {
|
|
2308
|
+
bind(document, "visibilitychange", recompute);
|
|
2309
|
+
recompute();
|
|
2310
|
+
}
|
|
2311
|
+
function recompute(evt) {
|
|
2312
|
+
if (evt === void 0) { evt = null; }
|
|
2313
|
+
data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
|
|
2314
|
+
encode$3(28 /* Event.Visibility */, time(evt));
|
|
2315
|
+
}
|
|
2316
|
+
function reset$6() {
|
|
2317
|
+
data$8 = null;
|
|
2318
|
+
}
|
|
2319
|
+
function stop$h() {
|
|
2320
|
+
reset$6();
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
function start$i() {
|
|
2324
|
+
start$g();
|
|
2325
|
+
start$s();
|
|
2326
|
+
start$r();
|
|
2327
|
+
start$p();
|
|
2328
|
+
start$q();
|
|
2329
|
+
start$o();
|
|
2330
|
+
start$j();
|
|
2331
|
+
start$n();
|
|
2332
|
+
start$m();
|
|
2333
|
+
start$t();
|
|
2334
|
+
start$l();
|
|
2335
|
+
start$k();
|
|
2336
|
+
}
|
|
2337
|
+
function stop$g() {
|
|
2338
|
+
stop$e();
|
|
2339
|
+
stop$q();
|
|
2340
|
+
stop$p();
|
|
2341
|
+
stop$n();
|
|
2342
|
+
stop$o();
|
|
2343
|
+
stop$m();
|
|
2344
|
+
stop$h();
|
|
2345
|
+
stop$l();
|
|
2346
|
+
stop$k();
|
|
2347
|
+
stop$r();
|
|
2348
|
+
stop$j();
|
|
2349
|
+
stop$i();
|
|
2350
|
+
}
|
|
2351
|
+
function observe$3(root) {
|
|
2352
|
+
observe$6(root);
|
|
2353
|
+
// Only monitor following interactions if the root node is a document
|
|
2354
|
+
// In case of shadow DOM, following events automatically bubble up to the parent document.
|
|
2355
|
+
if (root.nodeType === Node.DOCUMENT_NODE) {
|
|
2356
|
+
observe$a(root);
|
|
2357
|
+
observe$9(root);
|
|
2358
|
+
observe$7(root);
|
|
2359
|
+
observe$8(root);
|
|
2360
|
+
observe$5(root);
|
|
2361
|
+
observe$b(root);
|
|
2362
|
+
observe$4(root);
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
var interaction = /*#__PURE__*/Object.freeze({
|
|
2367
|
+
__proto__: null,
|
|
2368
|
+
observe: observe$3,
|
|
2369
|
+
start: start$i,
|
|
2370
|
+
stop: stop$g
|
|
2371
|
+
});
|
|
2372
|
+
|
|
2373
|
+
var digitsRegex = /[^0-9\.]/g;
|
|
2374
|
+
/* JSON+LD (Linked Data) Recursive Parser */
|
|
2375
|
+
function ld(json) {
|
|
2376
|
+
for (var _i = 0, _a = Object.keys(json); _i < _a.length; _i++) {
|
|
2377
|
+
var key = _a[_i];
|
|
2378
|
+
var value = json[key];
|
|
2379
|
+
if (key === "@type" /* JsonLD.Type */ && typeof value === "string") {
|
|
2380
|
+
value = value.toLowerCase();
|
|
2381
|
+
/* Normalizations */
|
|
2382
|
+
value = value.indexOf("article" /* JsonLD.Article */) >= 0 || value.indexOf("posting" /* JsonLD.Posting */) >= 0 ? "article" /* JsonLD.Article */ : value;
|
|
2383
|
+
switch (value) {
|
|
2384
|
+
case "article" /* JsonLD.Article */:
|
|
2385
|
+
case "recipe" /* JsonLD.Recipe */:
|
|
2386
|
+
log(5 /* Dimension.SchemaType */, json[key]);
|
|
2387
|
+
log(8 /* Dimension.AuthorName */, json["creator" /* JsonLD.Creator */]);
|
|
2388
|
+
log(18 /* Dimension.Headline */, json["headline" /* JsonLD.Headline */]);
|
|
2389
|
+
break;
|
|
2390
|
+
case "product" /* JsonLD.Product */:
|
|
2391
|
+
log(5 /* Dimension.SchemaType */, json[key]);
|
|
2392
|
+
log(10 /* Dimension.ProductName */, json["name" /* JsonLD.Name */]);
|
|
2393
|
+
log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
|
|
2394
|
+
if (json["brand" /* JsonLD.Brand */]) {
|
|
2395
|
+
log(6 /* Dimension.ProductBrand */, json["brand" /* JsonLD.Brand */]["name" /* JsonLD.Name */]);
|
|
2396
|
+
}
|
|
2397
|
+
break;
|
|
2398
|
+
case "aggregaterating" /* JsonLD.AggregateRating */:
|
|
2399
|
+
if (json["ratingValue" /* JsonLD.RatingValue */]) {
|
|
2400
|
+
max(11 /* Metric.RatingValue */, num$1(json["ratingValue" /* JsonLD.RatingValue */], 100 /* Setting.RatingScale */));
|
|
2401
|
+
max(18 /* Metric.BestRating */, num$1(json["bestRating" /* JsonLD.BestRating */]));
|
|
2402
|
+
max(19 /* Metric.WorstRating */, num$1(json["worstRating" /* JsonLD.WorstRating */]));
|
|
2403
|
+
}
|
|
2404
|
+
max(12 /* Metric.RatingCount */, num$1(json["ratingCount" /* JsonLD.RatingCount */]));
|
|
2405
|
+
max(17 /* Metric.ReviewCount */, num$1(json["reviewCount" /* JsonLD.ReviewCount */]));
|
|
2406
|
+
break;
|
|
2407
|
+
case "person" /* JsonLD.Author */:
|
|
2408
|
+
log(8 /* Dimension.AuthorName */, json["name" /* JsonLD.Name */]);
|
|
2409
|
+
break;
|
|
2410
|
+
case "offer" /* JsonLD.Offer */:
|
|
2411
|
+
log(7 /* Dimension.ProductAvailability */, json["availability" /* JsonLD.Availability */]);
|
|
2412
|
+
log(14 /* Dimension.ProductCondition */, json["itemCondition" /* JsonLD.ItemCondition */]);
|
|
2413
|
+
log(13 /* Dimension.ProductCurrency */, json["priceCurrency" /* JsonLD.PriceCurrency */]);
|
|
2414
|
+
log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
|
|
2415
|
+
max(13 /* Metric.ProductPrice */, num$1(json["price" /* JsonLD.Price */]));
|
|
2416
|
+
break;
|
|
2417
|
+
case "brand" /* JsonLD.Brand */:
|
|
2418
|
+
log(6 /* Dimension.ProductBrand */, json["name" /* JsonLD.Name */]);
|
|
2419
|
+
break;
|
|
2420
|
+
}
|
|
2552
2421
|
}
|
|
2553
|
-
//
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "".concat(x[0])); }); }); // Regions
|
|
2557
|
-
config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
|
|
2558
|
-
config$1.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
|
|
2559
|
-
unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
|
|
2422
|
+
// Continue parsing nested objects
|
|
2423
|
+
if (value !== null && typeof (value) === "object" /* Constant.Object */) {
|
|
2424
|
+
ld(value);
|
|
2560
2425
|
}
|
|
2561
2426
|
}
|
|
2562
|
-
|
|
2563
|
-
|
|
2427
|
+
}
|
|
2428
|
+
function num$1(input, scale) {
|
|
2429
|
+
if (scale === void 0) { scale = 1; }
|
|
2430
|
+
if (input !== null) {
|
|
2431
|
+
switch (typeof input) {
|
|
2432
|
+
case "number" /* Constant.Number */: return Math.round(input * scale);
|
|
2433
|
+
case "string" /* Constant.String */: return Math.round(parseFloat(input.replace(digitsRegex, "" /* Constant.Empty */)) * scale);
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
return null;
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror", "data-drupal-form-submit-last"];
|
|
2440
|
+
var newlineRegex = /[\r\n]+/g;
|
|
2441
|
+
function processNode (node, source) {
|
|
2442
|
+
var _a;
|
|
2443
|
+
var child = null;
|
|
2444
|
+
// Do not track this change if we are attempting to remove a node before discovering it
|
|
2445
|
+
if (source === 2 /* Source.ChildListRemove */ && has(node) === false) {
|
|
2446
|
+
return child;
|
|
2447
|
+
}
|
|
2448
|
+
// Special handling for text nodes that belong to style nodes
|
|
2449
|
+
if (source !== 0 /* Source.Discover */ &&
|
|
2450
|
+
node.nodeType === Node.TEXT_NODE &&
|
|
2451
|
+
node.parentElement &&
|
|
2452
|
+
node.parentElement.tagName === "STYLE") {
|
|
2453
|
+
node = node.parentNode;
|
|
2454
|
+
}
|
|
2455
|
+
var add = has(node) === false;
|
|
2456
|
+
var call = add ? "add" : "update";
|
|
2457
|
+
var parent = node.parentElement ? node.parentElement : null;
|
|
2458
|
+
var insideFrame = node.ownerDocument !== document;
|
|
2459
|
+
switch (node.nodeType) {
|
|
2460
|
+
case Node.DOCUMENT_TYPE_NODE:
|
|
2461
|
+
parent = insideFrame && node.parentNode ? iframe(node.parentNode) : parent;
|
|
2462
|
+
var docTypePrefix = insideFrame ? "iframe:" /* Constant.IFramePrefix */ : "" /* Constant.Empty */;
|
|
2463
|
+
var doctype = node;
|
|
2464
|
+
var docAttributes = { name: doctype.name, publicId: doctype.publicId, systemId: doctype.systemId };
|
|
2465
|
+
var docData = { tag: docTypePrefix + "*D" /* Constant.DocumentTag */, attributes: docAttributes };
|
|
2466
|
+
dom[call](node, parent, docData, source);
|
|
2467
|
+
break;
|
|
2468
|
+
case Node.DOCUMENT_NODE:
|
|
2469
|
+
// We check for regions in the beginning when discovering document and
|
|
2470
|
+
// later whenever there are new additions or modifications to DOM (mutations)
|
|
2471
|
+
if (node === document)
|
|
2472
|
+
parse$1(document);
|
|
2473
|
+
observe$2(node);
|
|
2474
|
+
break;
|
|
2475
|
+
case Node.DOCUMENT_FRAGMENT_NODE:
|
|
2476
|
+
var shadowRoot = node;
|
|
2477
|
+
if (shadowRoot.host) {
|
|
2478
|
+
parse$1(shadowRoot);
|
|
2479
|
+
var type = typeof (shadowRoot.constructor);
|
|
2480
|
+
if (type === "function" /* Constant.Function */ && shadowRoot.constructor.toString().indexOf("[native code]" /* Constant.NativeCode */) >= 0) {
|
|
2481
|
+
observe$2(shadowRoot);
|
|
2482
|
+
// See: https://wicg.github.io/construct-stylesheets/ for more details on adoptedStyleSheets.
|
|
2483
|
+
// At the moment, we are only able to capture "open" shadow DOM nodes. If they are closed, they are not accessible.
|
|
2484
|
+
// In future we may decide to proxy "attachShadow" call to gain access, but at the moment, we don't want to
|
|
2485
|
+
// cause any unintended side effect to the page. We will re-evaluate after we gather more real world data on this.
|
|
2486
|
+
var style = "" /* Constant.Empty */;
|
|
2487
|
+
var adoptedStyleSheets = "adoptedStyleSheets" in shadowRoot ? shadowRoot["adoptedStyleSheets"] : [];
|
|
2488
|
+
for (var _i = 0, adoptedStyleSheets_1 = adoptedStyleSheets; _i < adoptedStyleSheets_1.length; _i++) {
|
|
2489
|
+
var styleSheet = adoptedStyleSheets_1[_i];
|
|
2490
|
+
style += getCssRules(styleSheet);
|
|
2491
|
+
}
|
|
2492
|
+
var fragementData = { tag: "*S" /* Constant.ShadowDomTag */, attributes: { style: style } };
|
|
2493
|
+
dom[call](node, shadowRoot.host, fragementData, source);
|
|
2494
|
+
}
|
|
2495
|
+
else {
|
|
2496
|
+
// If the browser doesn't support shadow DOM natively, we detect that, and send appropriate tag back.
|
|
2497
|
+
// The differentiation is important because we don't have to observe pollyfill shadow DOM nodes,
|
|
2498
|
+
// the same way we observe real shadow DOM nodes (encapsulation provided by the browser).
|
|
2499
|
+
dom[call](node, shadowRoot.host, { tag: "*P" /* Constant.PolyfillShadowDomTag */, attributes: {} }, source);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
break;
|
|
2503
|
+
case Node.TEXT_NODE:
|
|
2504
|
+
// In IE11 TEXT_NODE doesn't expose a valid parentElement property. Instead we need to lookup parentNode property.
|
|
2505
|
+
parent = parent ? parent : node.parentNode;
|
|
2506
|
+
// Account for this text node only if we are tracking the parent node
|
|
2507
|
+
// We do not wish to track text nodes for ignored parent nodes, like script tags
|
|
2508
|
+
// Also, we do not track text nodes for STYLE tags
|
|
2509
|
+
// The only exception is when we receive a mutation to remove the text node, in that case
|
|
2510
|
+
// parent will be null, but we can still process the node by checking it's an update call.
|
|
2511
|
+
if (call === "update" || (parent && has(parent) && parent.tagName !== "STYLE")) {
|
|
2512
|
+
var textData = { tag: "*T" /* Constant.TextTag */, value: node.nodeValue };
|
|
2513
|
+
dom[call](node, parent, textData, source);
|
|
2514
|
+
}
|
|
2515
|
+
break;
|
|
2516
|
+
case Node.ELEMENT_NODE:
|
|
2517
|
+
var element = node;
|
|
2518
|
+
var tag = element.tagName;
|
|
2519
|
+
var attributes = getAttributes(element);
|
|
2520
|
+
// In some cases, external libraries like vue-fragment, can modify parentNode property to not be in sync with the DOM
|
|
2521
|
+
// For correctness, we first look at parentElement and if it not present then fall back to using parentNode
|
|
2522
|
+
parent = node.parentElement ? node.parentElement : (node.parentNode ? node.parentNode : null);
|
|
2523
|
+
// If we encounter a node that is part of SVG namespace, prefix the tag with SVG_PREFIX
|
|
2524
|
+
if (element.namespaceURI === "http://www.w3.org/2000/svg" /* Constant.SvgNamespace */) {
|
|
2525
|
+
tag = "svg:" /* Constant.SvgPrefix */ + tag;
|
|
2526
|
+
}
|
|
2527
|
+
switch (tag) {
|
|
2528
|
+
case "HTML":
|
|
2529
|
+
parent = insideFrame && parent ? iframe(parent) : null;
|
|
2530
|
+
var htmlPrefix = insideFrame ? "iframe:" /* Constant.IFramePrefix */ : "" /* Constant.Empty */;
|
|
2531
|
+
var htmlData = { tag: htmlPrefix + tag, attributes: attributes };
|
|
2532
|
+
dom[call](node, parent, htmlData, source);
|
|
2533
|
+
break;
|
|
2534
|
+
case "SCRIPT":
|
|
2535
|
+
if ("type" /* Constant.Type */ in attributes && attributes["type" /* Constant.Type */] === "application/ld+json" /* Constant.JsonLD */) {
|
|
2536
|
+
try {
|
|
2537
|
+
ld(JSON.parse(element.text.replace(newlineRegex, "" /* Constant.Empty */)));
|
|
2538
|
+
}
|
|
2539
|
+
catch ( /* do nothing */_b) { /* do nothing */ }
|
|
2540
|
+
}
|
|
2541
|
+
break;
|
|
2542
|
+
case "NOSCRIPT":
|
|
2543
|
+
break;
|
|
2544
|
+
case "META":
|
|
2545
|
+
var key = ("property" /* Constant.Property */ in attributes ?
|
|
2546
|
+
"property" /* Constant.Property */ :
|
|
2547
|
+
("name" /* Constant.Name */ in attributes ? "name" /* Constant.Name */ : null));
|
|
2548
|
+
if (key && "content" /* Constant.Content */ in attributes) {
|
|
2549
|
+
var content = attributes["content" /* Constant.Content */];
|
|
2550
|
+
switch (attributes[key]) {
|
|
2551
|
+
case "og:title" /* Constant.ogTitle */:
|
|
2552
|
+
log(20 /* Dimension.MetaTitle */, content);
|
|
2553
|
+
break;
|
|
2554
|
+
case "og:type" /* Constant.ogType */:
|
|
2555
|
+
log(19 /* Dimension.MetaType */, content);
|
|
2556
|
+
break;
|
|
2557
|
+
case "generator" /* Constant.Generator */:
|
|
2558
|
+
log(21 /* Dimension.Generator */, content);
|
|
2559
|
+
break;
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
break;
|
|
2563
|
+
case "HEAD":
|
|
2564
|
+
var head = { tag: tag, attributes: attributes };
|
|
2565
|
+
var l = insideFrame && ((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.location) ? node.ownerDocument.location : location;
|
|
2566
|
+
head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.hostname + l.pathname;
|
|
2567
|
+
dom[call](node, parent, head, source);
|
|
2568
|
+
break;
|
|
2569
|
+
case "BASE":
|
|
2570
|
+
// Override the auto detected base path to explicit value specified in this tag
|
|
2571
|
+
var baseHead = get(node.parentElement);
|
|
2572
|
+
if (baseHead) {
|
|
2573
|
+
// We create "a" element so we can generate protocol and hostname for relative paths like "/path/"
|
|
2574
|
+
var a = document.createElement("a");
|
|
2575
|
+
a.href = attributes["href"];
|
|
2576
|
+
baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.hostname + a.pathname;
|
|
2577
|
+
}
|
|
2578
|
+
break;
|
|
2579
|
+
case "STYLE":
|
|
2580
|
+
var styleData = { tag: tag, attributes: attributes, value: getStyleValue(element) };
|
|
2581
|
+
dom[call](node, parent, styleData, source);
|
|
2582
|
+
break;
|
|
2583
|
+
case "IFRAME":
|
|
2584
|
+
var iframe$1 = node;
|
|
2585
|
+
var frameData = { tag: tag, attributes: attributes };
|
|
2586
|
+
if (sameorigin(iframe$1)) {
|
|
2587
|
+
monitor(iframe$1);
|
|
2588
|
+
frameData.attributes["*O" /* Constant.SameOrigin */] = "true";
|
|
2589
|
+
if (iframe$1.contentDocument && iframe$1.contentWindow && iframe$1.contentDocument.readyState !== "loading") {
|
|
2590
|
+
child = iframe$1.contentDocument;
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
dom[call](node, parent, frameData, source);
|
|
2594
|
+
break;
|
|
2595
|
+
default:
|
|
2596
|
+
var data = { tag: tag, attributes: attributes };
|
|
2597
|
+
if (element.shadowRoot) {
|
|
2598
|
+
child = element.shadowRoot;
|
|
2599
|
+
}
|
|
2600
|
+
dom[call](node, parent, data, source);
|
|
2601
|
+
break;
|
|
2602
|
+
}
|
|
2603
|
+
break;
|
|
2564
2604
|
}
|
|
2605
|
+
return child;
|
|
2565
2606
|
}
|
|
2566
|
-
function
|
|
2567
|
-
if (
|
|
2568
|
-
|
|
2569
|
-
return null;
|
|
2570
|
-
}
|
|
2571
|
-
var id = idMap.get(node);
|
|
2572
|
-
if (!id && autogen) {
|
|
2573
|
-
id = index++;
|
|
2574
|
-
idMap.set(node, id);
|
|
2607
|
+
function observe$2(root) {
|
|
2608
|
+
if (has(root)) {
|
|
2609
|
+
return;
|
|
2575
2610
|
}
|
|
2576
|
-
|
|
2611
|
+
observe$1(root); // Observe mutations for this root node
|
|
2612
|
+
observe$3(root); // Observe interactions for this root node
|
|
2577
2613
|
}
|
|
2578
|
-
function
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
var
|
|
2582
|
-
var
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
var fraudId = fraudMap.has(node) ? fraudMap.get(node) : null;
|
|
2586
|
-
var privacyId = config$1.content ? 1 /* Privacy.Sensitive */ : 3 /* Privacy.TextImage */;
|
|
2587
|
-
if (parentId >= 0 && values[parentId]) {
|
|
2588
|
-
parentValue = values[parentId];
|
|
2589
|
-
parentValue.children.push(id);
|
|
2590
|
-
regionId = regionId === null ? parentValue.region : regionId;
|
|
2591
|
-
fragmentId = parentValue.fragment;
|
|
2592
|
-
fraudId = fraudId === null ? parentValue.metadata.fraud : fraudId;
|
|
2593
|
-
privacyId = parentValue.metadata.privacy;
|
|
2594
|
-
}
|
|
2595
|
-
// If there's an explicit region attribute set on the element, use it to mark a region on the page
|
|
2596
|
-
if (data.attributes && "data-clarity-region" /* Constant.RegionData */ in data.attributes) {
|
|
2597
|
-
observe$1(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
|
|
2598
|
-
regionId = id;
|
|
2614
|
+
function getStyleValue(style) {
|
|
2615
|
+
// Call trim on the text content to ensure we do not process white spaces ( , \n, \r\n, \t, etc.)
|
|
2616
|
+
// Also, check if stylesheet has any data-* attribute, if so process rules instead of looking up text
|
|
2617
|
+
var value = style.textContent ? style.textContent.trim() : "" /* Constant.Empty */;
|
|
2618
|
+
var dataset = style.dataset ? Object.keys(style.dataset).length : 0;
|
|
2619
|
+
if (value.length === 0 || dataset > 0) {
|
|
2620
|
+
value = getCssRules(style.sheet);
|
|
2599
2621
|
}
|
|
2600
|
-
|
|
2601
|
-
values[id] = {
|
|
2602
|
-
id: id,
|
|
2603
|
-
parent: parentId,
|
|
2604
|
-
previous: previousId,
|
|
2605
|
-
children: [],
|
|
2606
|
-
data: data,
|
|
2607
|
-
selector: null,
|
|
2608
|
-
hash: null,
|
|
2609
|
-
region: regionId,
|
|
2610
|
-
metadata: { active: true, suspend: false, privacy: privacyId, position: null, fraud: fraudId, size: null },
|
|
2611
|
-
fragment: fragmentId,
|
|
2612
|
-
};
|
|
2613
|
-
privacy(node, values[id], parentValue);
|
|
2614
|
-
updateSelector(values[id]);
|
|
2615
|
-
size(values[id]);
|
|
2616
|
-
track$4(id, source, values[id].fragment);
|
|
2622
|
+
return value;
|
|
2617
2623
|
}
|
|
2618
|
-
function
|
|
2619
|
-
var
|
|
2620
|
-
var
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
changed = true;
|
|
2630
|
-
value.previous = previousId;
|
|
2631
|
-
}
|
|
2632
|
-
// Handle case where parent might have been updated
|
|
2633
|
-
if (value.parent !== parentId) {
|
|
2634
|
-
changed = true;
|
|
2635
|
-
var oldParentId = value.parent;
|
|
2636
|
-
value.parent = parentId;
|
|
2637
|
-
// Move this node to the right location under new parent
|
|
2638
|
-
if (parentId !== null && parentId >= 0) {
|
|
2639
|
-
var childIndex = previousId === null ? 0 : values[parentId].children.indexOf(previousId) + 1;
|
|
2640
|
-
values[parentId].children.splice(childIndex, 0, id);
|
|
2641
|
-
// Update region after the move
|
|
2642
|
-
value.region = exists(node) ? id : values[parentId].region;
|
|
2643
|
-
}
|
|
2644
|
-
else {
|
|
2645
|
-
// Mark this element as deleted if the parent has been updated to null
|
|
2646
|
-
remove(id, source);
|
|
2647
|
-
}
|
|
2648
|
-
// Remove reference to this node from the old parent
|
|
2649
|
-
if (oldParentId !== null && oldParentId >= 0) {
|
|
2650
|
-
var nodeIndex = values[oldParentId].children.indexOf(id);
|
|
2651
|
-
if (nodeIndex >= 0) {
|
|
2652
|
-
values[oldParentId].children.splice(nodeIndex, 1);
|
|
2653
|
-
}
|
|
2654
|
-
}
|
|
2655
|
-
parentChanged = true;
|
|
2656
|
-
}
|
|
2657
|
-
// Update data
|
|
2658
|
-
for (var key in data) {
|
|
2659
|
-
if (diff(value["data"], data, key)) {
|
|
2660
|
-
changed = true;
|
|
2661
|
-
value["data"][key] = data[key];
|
|
2662
|
-
}
|
|
2624
|
+
function getCssRules(sheet) {
|
|
2625
|
+
var value = "" /* Constant.Empty */;
|
|
2626
|
+
var cssRules = null;
|
|
2627
|
+
// Firefox throws a SecurityError when trying to access cssRules of a stylesheet from a different domain
|
|
2628
|
+
try {
|
|
2629
|
+
cssRules = sheet ? sheet.cssRules : [];
|
|
2630
|
+
}
|
|
2631
|
+
catch (e) {
|
|
2632
|
+
log$1(1 /* Code.CssRules */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
2633
|
+
if (e && e.name !== "SecurityError") {
|
|
2634
|
+
throw e;
|
|
2663
2635
|
}
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2636
|
+
}
|
|
2637
|
+
if (cssRules !== null) {
|
|
2638
|
+
for (var i = 0; i < cssRules.length; i++) {
|
|
2639
|
+
value += cssRules[i].cssText;
|
|
2667
2640
|
}
|
|
2668
|
-
// Update selector
|
|
2669
|
-
updateSelector(value);
|
|
2670
|
-
track$4(id, source, values[id].fragment, changed, parentChanged);
|
|
2671
2641
|
}
|
|
2642
|
+
return value;
|
|
2672
2643
|
}
|
|
2673
|
-
function
|
|
2674
|
-
var output =
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
var doc = frame.contentDocument;
|
|
2682
|
-
if (doc) {
|
|
2683
|
-
iframeMap.set(frame.contentDocument, frame);
|
|
2684
|
-
output = true;
|
|
2644
|
+
function getAttributes(element) {
|
|
2645
|
+
var output = {};
|
|
2646
|
+
var attributes = element.attributes;
|
|
2647
|
+
if (attributes && attributes.length > 0) {
|
|
2648
|
+
for (var i = 0; i < attributes.length; i++) {
|
|
2649
|
+
var name_1 = attributes[i].name;
|
|
2650
|
+
if (IGNORE_ATTRIBUTES.indexOf(name_1) < 0) {
|
|
2651
|
+
output[name_1] = attributes[i].value;
|
|
2685
2652
|
}
|
|
2686
2653
|
}
|
|
2687
|
-
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
2688
2654
|
}
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
|
|
2693
|
-
return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
|
|
2694
|
-
}
|
|
2695
|
-
function privacy(node, value, parent) {
|
|
2696
|
-
var data = value.data;
|
|
2697
|
-
var metadata = value.metadata;
|
|
2698
|
-
var current = metadata.privacy;
|
|
2699
|
-
var attributes = data.attributes || {};
|
|
2700
|
-
var tag = data.tag.toUpperCase();
|
|
2701
|
-
switch (true) {
|
|
2702
|
-
case maskTags.indexOf(tag) >= 0:
|
|
2703
|
-
var type = attributes["type" /* Constant.Type */];
|
|
2704
|
-
var meta_1 = "" /* Constant.Empty */;
|
|
2705
|
-
Object.keys(attributes).forEach(function (x) { return meta_1 += attributes[x].toLowerCase(); });
|
|
2706
|
-
var exclude = maskExclude.some(function (x) { return meta_1.indexOf(x) >= 0; });
|
|
2707
|
-
// Regardless of privacy mode, always mask off user input from input boxes or drop downs with two exceptions:
|
|
2708
|
-
// (1) The node is detected to be one of the excluded fields, in which case we drop everything
|
|
2709
|
-
// (2) The node's type is one of the allowed types (like checkboxes)
|
|
2710
|
-
metadata.privacy = tag === "INPUT" /* Constant.InputTag */ && maskDisable.indexOf(type) >= 0 ? current : (exclude ? 4 /* Privacy.Exclude */ : 2 /* Privacy.Text */);
|
|
2711
|
-
break;
|
|
2712
|
-
case "data-clarity-mask" /* Constant.MaskData */ in attributes:
|
|
2713
|
-
metadata.privacy = 3 /* Privacy.TextImage */;
|
|
2714
|
-
break;
|
|
2715
|
-
case "data-clarity-unmask" /* Constant.UnmaskData */ in attributes:
|
|
2716
|
-
metadata.privacy = 0 /* Privacy.None */;
|
|
2717
|
-
break;
|
|
2718
|
-
case privacyMap.has(node):
|
|
2719
|
-
// If this node was explicitly configured to contain sensitive content, honor that privacy setting
|
|
2720
|
-
metadata.privacy = privacyMap.get(node);
|
|
2721
|
-
break;
|
|
2722
|
-
case fraudMap.has(node):
|
|
2723
|
-
// If this node was explicitly configured to be evaluated for fraud, then also mask content
|
|
2724
|
-
metadata.privacy = 2 /* Privacy.Text */;
|
|
2725
|
-
break;
|
|
2726
|
-
case tag === "*T" /* Constant.TextTag */:
|
|
2727
|
-
// If it's a text node belonging to a STYLE or TITLE tag or one of scrub exceptions, then capture content
|
|
2728
|
-
var pTag = parent && parent.data ? parent.data.tag : "" /* Constant.Empty */;
|
|
2729
|
-
var pSelector_1 = parent && parent.selector ? parent.selector[1 /* Selector.Default */] : "" /* Constant.Empty */;
|
|
2730
|
-
var tags = ["STYLE" /* Constant.StyleTag */, "TITLE" /* Constant.TitleTag */, "svg:style" /* Constant.SvgStyle */];
|
|
2731
|
-
metadata.privacy = tags.includes(pTag) || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* Privacy.None */ : current;
|
|
2732
|
-
break;
|
|
2733
|
-
case current === 1 /* Privacy.Sensitive */:
|
|
2734
|
-
// In a mode where we mask sensitive information by default, look through class names to aggressively mask content
|
|
2735
|
-
metadata.privacy = inspect(attributes["class" /* Constant.Class */], maskText, metadata);
|
|
2736
|
-
break;
|
|
2655
|
+
// For INPUT tags read the dynamic "value" property if an explicit "value" attribute is not set
|
|
2656
|
+
if (element.tagName === "INPUT" /* Constant.InputTag */ && !("value" /* Constant.Value */ in output) && element.value) {
|
|
2657
|
+
output["value" /* Constant.Value */] = element.value;
|
|
2737
2658
|
}
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2659
|
+
return output;
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
function traverse (root, timer, source) {
|
|
2663
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2664
|
+
var queue, node, next, state, subnode;
|
|
2665
|
+
return __generator(this, function (_a) {
|
|
2666
|
+
switch (_a.label) {
|
|
2667
|
+
case 0:
|
|
2668
|
+
queue = [root];
|
|
2669
|
+
_a.label = 1;
|
|
2670
|
+
case 1:
|
|
2671
|
+
if (!(queue.length > 0)) return [3 /*break*/, 4];
|
|
2672
|
+
node = queue.shift();
|
|
2673
|
+
next = node.firstChild;
|
|
2674
|
+
while (next) {
|
|
2675
|
+
queue.push(next);
|
|
2676
|
+
next = next.nextSibling;
|
|
2677
|
+
}
|
|
2678
|
+
state = state$9(timer);
|
|
2679
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
|
|
2680
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
2681
|
+
case 2:
|
|
2682
|
+
state = _a.sent();
|
|
2683
|
+
_a.label = 3;
|
|
2684
|
+
case 3:
|
|
2685
|
+
if (state === 2 /* Task.Stop */) {
|
|
2686
|
+
return [3 /*break*/, 4];
|
|
2687
|
+
}
|
|
2688
|
+
subnode = processNode(node, source);
|
|
2689
|
+
if (subnode) {
|
|
2690
|
+
queue.push(subnode);
|
|
2691
|
+
}
|
|
2692
|
+
return [3 /*break*/, 1];
|
|
2693
|
+
case 4: return [2 /*return*/];
|
|
2694
|
+
}
|
|
2695
|
+
});
|
|
2696
|
+
});
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
var observers = [];
|
|
2700
|
+
var mutations = [];
|
|
2701
|
+
var insertRule = null;
|
|
2702
|
+
var deleteRule = null;
|
|
2703
|
+
var attachShadow = null;
|
|
2704
|
+
var queue$1 = [];
|
|
2705
|
+
var timeout$1 = null;
|
|
2706
|
+
var activePeriod = null;
|
|
2707
|
+
var history$4 = {};
|
|
2708
|
+
function start$h() {
|
|
2709
|
+
observers = [];
|
|
2710
|
+
queue$1 = [];
|
|
2711
|
+
timeout$1 = null;
|
|
2712
|
+
activePeriod = 0;
|
|
2713
|
+
history$4 = {};
|
|
2714
|
+
// Some popular open source libraries, like styled-components, optimize performance
|
|
2715
|
+
// by injecting CSS using insertRule API vs. appending text node. A side effect of
|
|
2716
|
+
// using javascript API is that it doesn't trigger DOM mutation and therefore we
|
|
2717
|
+
// need to override the insertRule API and listen for changes manually.
|
|
2718
|
+
if (insertRule === null) {
|
|
2719
|
+
insertRule = CSSStyleSheet.prototype.insertRule;
|
|
2720
|
+
CSSStyleSheet.prototype.insertRule = function () {
|
|
2721
|
+
if (active()) {
|
|
2722
|
+
schedule(this.ownerNode);
|
|
2723
|
+
}
|
|
2724
|
+
return insertRule.apply(this, arguments);
|
|
2725
|
+
};
|
|
2742
2726
|
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
function
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
if (a[field][key] !== b[field][key]) {
|
|
2749
|
-
return true;
|
|
2727
|
+
if (deleteRule === null) {
|
|
2728
|
+
deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
2729
|
+
CSSStyleSheet.prototype.deleteRule = function () {
|
|
2730
|
+
if (active()) {
|
|
2731
|
+
schedule(this.ownerNode);
|
|
2750
2732
|
}
|
|
2733
|
+
return deleteRule.apply(this, arguments);
|
|
2734
|
+
};
|
|
2735
|
+
}
|
|
2736
|
+
// Add a hook to attachShadow API calls
|
|
2737
|
+
// In case we are unable to add a hook and browser throws an exception,
|
|
2738
|
+
// reset attachShadow variable and resume processing like before
|
|
2739
|
+
if (attachShadow === null) {
|
|
2740
|
+
attachShadow = Element.prototype.attachShadow;
|
|
2741
|
+
try {
|
|
2742
|
+
Element.prototype.attachShadow = function () {
|
|
2743
|
+
if (active()) {
|
|
2744
|
+
return schedule(attachShadow.apply(this, arguments));
|
|
2745
|
+
}
|
|
2746
|
+
else {
|
|
2747
|
+
return attachShadow.apply(this, arguments);
|
|
2748
|
+
}
|
|
2749
|
+
};
|
|
2751
2750
|
}
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
return true;
|
|
2755
|
-
}
|
|
2751
|
+
catch (_a) {
|
|
2752
|
+
attachShadow = null;
|
|
2756
2753
|
}
|
|
2757
|
-
return false;
|
|
2758
2754
|
}
|
|
2759
|
-
return a[field] !== b[field];
|
|
2760
2755
|
}
|
|
2761
|
-
function
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2756
|
+
function observe$1(node) {
|
|
2757
|
+
// Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
|
|
2758
|
+
// In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
|
|
2759
|
+
// For this reason, we need to wire up mutations every time we see a new shadow dom.
|
|
2760
|
+
// Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
|
|
2761
|
+
try {
|
|
2762
|
+
var m = api("MutationObserver" /* Constant.MutationObserver */);
|
|
2763
|
+
var observer = m in window ? new window[m](measure(handle$1)) : null;
|
|
2764
|
+
if (observer) {
|
|
2765
|
+
observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
|
|
2766
|
+
observers.push(observer);
|
|
2769
2767
|
}
|
|
2770
2768
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
function updateSelector(value) {
|
|
2774
|
-
var parent = value.parent && value.parent in values ? values[value.parent] : null;
|
|
2775
|
-
var prefix = parent ? parent.selector : null;
|
|
2776
|
-
var d = value.data;
|
|
2777
|
-
var p = position(parent, value);
|
|
2778
|
-
var s = { id: value.id, tag: d.tag, prefix: prefix, position: p, attributes: d.attributes };
|
|
2779
|
-
value.selector = [get$1(s, 0 /* Selector.Alpha */), get$1(s, 1 /* Selector.Beta */)];
|
|
2780
|
-
value.hash = value.selector.map(function (x) { return x ? hash(x) : null; });
|
|
2781
|
-
value.hash.forEach(function (h) { return hashMap[h] = value.id; });
|
|
2782
|
-
// Match fragment configuration against both alpha and beta hash
|
|
2783
|
-
if (value.hash.some(function (h) { return fragments.indexOf(h) !== -1; })) {
|
|
2784
|
-
value.fragment = value.id;
|
|
2785
|
-
}
|
|
2786
|
-
}
|
|
2787
|
-
function hashText(hash) {
|
|
2788
|
-
var id = lookup(hash);
|
|
2789
|
-
var node = getNode(id);
|
|
2790
|
-
return node !== null && node.textContent !== null ? node.textContent.substr(0, 25 /* Setting.ClickText */) : '';
|
|
2791
|
-
}
|
|
2792
|
-
function getNode(id) {
|
|
2793
|
-
if (id in nodes) {
|
|
2794
|
-
return nodes[id];
|
|
2769
|
+
catch (e) {
|
|
2770
|
+
log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
|
|
2795
2771
|
}
|
|
2796
|
-
return null;
|
|
2797
2772
|
}
|
|
2798
|
-
function
|
|
2799
|
-
|
|
2800
|
-
|
|
2773
|
+
function monitor(frame) {
|
|
2774
|
+
// Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
|
|
2775
|
+
// This includes cases where iframe location is updated without explicitly updating src attribute
|
|
2776
|
+
// E.g. iframe.contentWindow.location.href = "new-location";
|
|
2777
|
+
if (has(frame) === false) {
|
|
2778
|
+
bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
|
|
2801
2779
|
}
|
|
2802
|
-
return null;
|
|
2803
|
-
}
|
|
2804
|
-
function get(node) {
|
|
2805
|
-
var id = getId(node);
|
|
2806
|
-
return id in values ? values[id] : null;
|
|
2807
|
-
}
|
|
2808
|
-
function lookup(hash) {
|
|
2809
|
-
return hash in hashMap ? hashMap[hash] : null;
|
|
2810
|
-
}
|
|
2811
|
-
function has(node) {
|
|
2812
|
-
return getId(node) in nodes;
|
|
2813
2780
|
}
|
|
2814
|
-
function
|
|
2815
|
-
var
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
output.push(values[id]);
|
|
2781
|
+
function stop$f() {
|
|
2782
|
+
for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) {
|
|
2783
|
+
var observer = observers_1[_i];
|
|
2784
|
+
if (observer) {
|
|
2785
|
+
observer.disconnect();
|
|
2820
2786
|
}
|
|
2821
2787
|
}
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
}
|
|
2829
|
-
function remove(id, source) {
|
|
2830
|
-
if (id in values) {
|
|
2831
|
-
var value = values[id];
|
|
2832
|
-
value.metadata.active = false;
|
|
2833
|
-
value.parent = null;
|
|
2834
|
-
track$4(id, source);
|
|
2835
|
-
}
|
|
2836
|
-
}
|
|
2837
|
-
function size(value) {
|
|
2838
|
-
// If this element is a image node, and is masked, then track box model for the current element
|
|
2839
|
-
if (value.data.tag === "IMG" /* Constant.ImageTag */ && value.metadata.privacy === 3 /* Privacy.TextImage */) {
|
|
2840
|
-
value.metadata.size = [];
|
|
2841
|
-
}
|
|
2788
|
+
observers = [];
|
|
2789
|
+
history$4 = {};
|
|
2790
|
+
mutations = [];
|
|
2791
|
+
queue$1 = [];
|
|
2792
|
+
activePeriod = 0;
|
|
2793
|
+
timeout$1 = null;
|
|
2842
2794
|
}
|
|
2843
|
-
function
|
|
2844
|
-
|
|
2845
|
-
// Some nodes may not have an ID by design since Clarity skips over tags like SCRIPT, NOSCRIPT, META, COMMENTS, etc..
|
|
2846
|
-
// In that case, we keep going back and check for their sibling until we find a sibling with ID or no more sibling nodes are left.
|
|
2847
|
-
while (id === null && node.previousSibling) {
|
|
2848
|
-
id = getId(node.previousSibling);
|
|
2849
|
-
node = node.previousSibling;
|
|
2850
|
-
}
|
|
2851
|
-
return id;
|
|
2795
|
+
function active$2() {
|
|
2796
|
+
activePeriod = time() + 3000 /* Setting.MutationActivePeriod */;
|
|
2852
2797
|
}
|
|
2853
|
-
function
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
schedule(node, true);
|
|
2863
|
-
value.hash.forEach(function (h) {
|
|
2864
|
-
if (fragments.indexOf(h) !== -1) {
|
|
2865
|
-
updatedFragments[fragment] = h;
|
|
2866
|
-
}
|
|
2867
|
-
});
|
|
2868
|
-
}
|
|
2869
|
-
}
|
|
2870
|
-
// Keep track of the order in which mutations happened, they may not be sequential
|
|
2871
|
-
// Edge case: If an element is added later on, and pre-discovered element is moved as a child.
|
|
2872
|
-
// In that case, we need to reorder the pre-discovered element in the update list to keep visualization consistent.
|
|
2873
|
-
var uIndex = updateMap.indexOf(id);
|
|
2874
|
-
if (uIndex >= 0 && source === 1 /* Source.ChildListAdd */ && parentChanged) {
|
|
2875
|
-
updateMap.splice(uIndex, 1);
|
|
2876
|
-
updateMap.push(id);
|
|
2877
|
-
}
|
|
2878
|
-
else if (uIndex === -1 && changed) {
|
|
2879
|
-
updateMap.push(id);
|
|
2880
|
-
}
|
|
2881
|
-
}
|
|
2882
|
-
|
|
2883
|
-
var state$1 = [];
|
|
2884
|
-
var regionMap = null; // Maps region nodes => region name
|
|
2885
|
-
var regions = {};
|
|
2886
|
-
var queue$1 = [];
|
|
2887
|
-
var watch = false;
|
|
2888
|
-
var observer$1 = null;
|
|
2889
|
-
function start$h() {
|
|
2890
|
-
reset$6();
|
|
2891
|
-
observer$1 = null;
|
|
2892
|
-
regionMap = new WeakMap();
|
|
2893
|
-
regions = {};
|
|
2894
|
-
queue$1 = [];
|
|
2895
|
-
watch = window["IntersectionObserver"] ? true : false;
|
|
2798
|
+
function handle$1(m) {
|
|
2799
|
+
// Queue up mutation records for asynchronous processing
|
|
2800
|
+
var now = time();
|
|
2801
|
+
track$6(6 /* Event.Mutation */, now);
|
|
2802
|
+
mutations.push({ time: now, mutations: m });
|
|
2803
|
+
schedule$1(process$1, 1 /* Priority.High */).then(function () {
|
|
2804
|
+
setTimeout(compute$7);
|
|
2805
|
+
measure(compute$6)();
|
|
2806
|
+
});
|
|
2896
2807
|
}
|
|
2897
|
-
function
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2808
|
+
function process$1() {
|
|
2809
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2810
|
+
var timer, record, instance, _i, _a, mutation, state, target, type, value;
|
|
2811
|
+
return __generator(this, function (_b) {
|
|
2812
|
+
switch (_b.label) {
|
|
2813
|
+
case 0:
|
|
2814
|
+
timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
|
|
2815
|
+
start$w(timer);
|
|
2816
|
+
_b.label = 1;
|
|
2817
|
+
case 1:
|
|
2818
|
+
if (!(mutations.length > 0)) return [3 /*break*/, 8];
|
|
2819
|
+
record = mutations.shift();
|
|
2820
|
+
instance = time();
|
|
2821
|
+
_i = 0, _a = record.mutations;
|
|
2822
|
+
_b.label = 2;
|
|
2823
|
+
case 2:
|
|
2824
|
+
if (!(_i < _a.length)) return [3 /*break*/, 6];
|
|
2825
|
+
mutation = _a[_i];
|
|
2826
|
+
state = state$9(timer);
|
|
2827
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
|
|
2828
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
2829
|
+
case 3:
|
|
2830
|
+
state = _b.sent();
|
|
2831
|
+
_b.label = 4;
|
|
2832
|
+
case 4:
|
|
2833
|
+
if (state === 2 /* Task.Stop */) {
|
|
2834
|
+
return [3 /*break*/, 6];
|
|
2835
|
+
}
|
|
2836
|
+
target = mutation.target;
|
|
2837
|
+
type = track$3(mutation, timer, instance);
|
|
2838
|
+
if (type && target && target.ownerDocument) {
|
|
2839
|
+
parse$1(target.ownerDocument);
|
|
2840
|
+
}
|
|
2841
|
+
if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
|
|
2842
|
+
parse$1(target);
|
|
2843
|
+
}
|
|
2844
|
+
switch (type) {
|
|
2845
|
+
case "attributes" /* Constant.Attributes */:
|
|
2846
|
+
processNode(target, 3 /* Source.Attributes */);
|
|
2847
|
+
break;
|
|
2848
|
+
case "characterData" /* Constant.CharacterData */:
|
|
2849
|
+
processNode(target, 4 /* Source.CharacterData */);
|
|
2850
|
+
break;
|
|
2851
|
+
case "childList" /* Constant.ChildList */:
|
|
2852
|
+
processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer);
|
|
2853
|
+
processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer);
|
|
2854
|
+
break;
|
|
2855
|
+
case "suspend" /* Constant.Suspend */:
|
|
2856
|
+
value = get(target);
|
|
2857
|
+
if (value) {
|
|
2858
|
+
value.metadata.suspend = true;
|
|
2859
|
+
}
|
|
2860
|
+
break;
|
|
2861
|
+
}
|
|
2862
|
+
_b.label = 5;
|
|
2863
|
+
case 5:
|
|
2864
|
+
_i++;
|
|
2865
|
+
return [3 /*break*/, 2];
|
|
2866
|
+
case 6: return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
|
|
2867
|
+
case 7:
|
|
2868
|
+
_b.sent();
|
|
2869
|
+
return [3 /*break*/, 1];
|
|
2870
|
+
case 8:
|
|
2871
|
+
stop$t(timer);
|
|
2872
|
+
return [2 /*return*/];
|
|
2873
|
+
}
|
|
2874
|
+
});
|
|
2875
|
+
});
|
|
2876
|
+
}
|
|
2877
|
+
function track$3(m, timer, instance) {
|
|
2878
|
+
var value = m.target ? get(m.target.parentNode) : null;
|
|
2879
|
+
// Check if the parent is already discovered and that the parent is not the document root
|
|
2880
|
+
if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
|
|
2881
|
+
var inactive = time() > activePeriod;
|
|
2882
|
+
var target = get(m.target);
|
|
2883
|
+
var element = target && target.selector ? target.selector.join() : m.target.nodeName;
|
|
2884
|
+
var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
|
|
2885
|
+
// We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
|
|
2886
|
+
// repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
|
|
2887
|
+
// In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
|
|
2888
|
+
var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
|
|
2889
|
+
// Initialize an entry if it doesn't already exist
|
|
2890
|
+
history$4[key] = key in history$4 ? history$4[key] : [0, instance];
|
|
2891
|
+
var h = history$4[key];
|
|
2892
|
+
// Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
|
|
2893
|
+
if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
|
|
2894
|
+
processNodeList(h[2], 2 /* Source.ChildListRemove */, timer);
|
|
2895
|
+
}
|
|
2896
|
+
// Update the counter
|
|
2897
|
+
h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
|
|
2898
|
+
h[1] = instance;
|
|
2899
|
+
// Return updated mutation type based on if we have already hit the threshold or not
|
|
2900
|
+
if (h[0] === 10 /* Setting.MutationSuspendThreshold */) {
|
|
2901
|
+
// Store a reference to removedNodes so we can process them later
|
|
2902
|
+
// when we resume mutations again on user interactions
|
|
2903
|
+
h[2] = m.removedNodes;
|
|
2904
|
+
return "suspend" /* Constant.Suspend */;
|
|
2905
|
+
}
|
|
2906
|
+
else if (h[0] > 10 /* Setting.MutationSuspendThreshold */) {
|
|
2907
|
+
return "" /* Constant.Empty */;
|
|
2909
2908
|
}
|
|
2910
2909
|
}
|
|
2910
|
+
return m.type;
|
|
2911
2911
|
}
|
|
2912
|
-
function
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
return regionMap && regionMap.has(node);
|
|
2917
|
-
}
|
|
2918
|
-
function track$3(id, event) {
|
|
2919
|
-
var node = getNode(id);
|
|
2920
|
-
var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
|
|
2921
|
-
// Determine the interaction state based on incoming event
|
|
2922
|
-
var interaction = 16 /* InteractionState.None */;
|
|
2923
|
-
switch (event) {
|
|
2924
|
-
case 9 /* Event.Click */:
|
|
2925
|
-
interaction = 20 /* InteractionState.Clicked */;
|
|
2926
|
-
break;
|
|
2927
|
-
case 27 /* Event.Input */:
|
|
2928
|
-
interaction = 30 /* InteractionState.Input */;
|
|
2929
|
-
break;
|
|
2912
|
+
function names(nodes) {
|
|
2913
|
+
var output = [];
|
|
2914
|
+
for (var i = 0; nodes && i < nodes.length; i++) {
|
|
2915
|
+
output.push(nodes[i].nodeName);
|
|
2930
2916
|
}
|
|
2931
|
-
|
|
2932
|
-
process$1(node, data, interaction, data.visibility);
|
|
2917
|
+
return output.join();
|
|
2933
2918
|
}
|
|
2934
|
-
function
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2919
|
+
function processNodeList(list, source, timer) {
|
|
2920
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2921
|
+
var length, i, state;
|
|
2922
|
+
return __generator(this, function (_a) {
|
|
2923
|
+
switch (_a.label) {
|
|
2924
|
+
case 0:
|
|
2925
|
+
length = list ? list.length : 0;
|
|
2926
|
+
i = 0;
|
|
2927
|
+
_a.label = 1;
|
|
2928
|
+
case 1:
|
|
2929
|
+
if (!(i < length)) return [3 /*break*/, 6];
|
|
2930
|
+
if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
|
|
2931
|
+
traverse(list[i], timer, source);
|
|
2932
|
+
return [3 /*break*/, 5];
|
|
2933
|
+
case 2:
|
|
2934
|
+
state = state$9(timer);
|
|
2935
|
+
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
|
|
2936
|
+
return [4 /*yield*/, suspend$1(timer)];
|
|
2937
|
+
case 3:
|
|
2938
|
+
state = _a.sent();
|
|
2939
|
+
_a.label = 4;
|
|
2940
|
+
case 4:
|
|
2941
|
+
if (state === 2 /* Task.Stop */) {
|
|
2942
|
+
return [3 /*break*/, 6];
|
|
2943
|
+
}
|
|
2944
|
+
processNode(list[i], source);
|
|
2945
|
+
_a.label = 5;
|
|
2946
|
+
case 5:
|
|
2947
|
+
i++;
|
|
2948
|
+
return [3 /*break*/, 1];
|
|
2949
|
+
case 6: return [2 /*return*/];
|
|
2950
2950
|
}
|
|
2951
|
-
}
|
|
2952
|
-
}
|
|
2953
|
-
queue$1 = q;
|
|
2954
|
-
// Schedule encode only when we have at least one valid data entry
|
|
2955
|
-
if (state$1.length > 0) {
|
|
2956
|
-
encode$4(7 /* Event.Region */);
|
|
2957
|
-
}
|
|
2951
|
+
});
|
|
2952
|
+
});
|
|
2958
2953
|
}
|
|
2959
|
-
function
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
var rect = entry.boundingClientRect;
|
|
2964
|
-
var overlap = entry.intersectionRect;
|
|
2965
|
-
var viewport = entry.rootBounds;
|
|
2966
|
-
// Only capture regions that have non-zero width or height to avoid tracking and sending regions
|
|
2967
|
-
// that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
|
|
2968
|
-
// like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
|
|
2969
|
-
// Also, if these regions ever become non-zero width or height (through AJAX, user action or orientation change) - we will automatically start monitoring them from that point onwards
|
|
2970
|
-
if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
|
|
2971
|
-
var id = target ? getId(target) : null;
|
|
2972
|
-
var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
|
|
2973
|
-
// For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
|
|
2974
|
-
// However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
|
|
2975
|
-
var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
|
|
2976
|
-
var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
|
|
2977
|
-
// If an element is either visible or was visible and has been scrolled to the end
|
|
2978
|
-
// i.e. Scrolled to end is determined by if the starting position of the element + the window height is more than the total element height.
|
|
2979
|
-
// starting position is relative to the viewport - so Intersection observer returns a negative value for rect.top to indicate that the element top is above the viewport
|
|
2980
|
-
var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
|
|
2981
|
-
// Process updates to this region, if applicable
|
|
2982
|
-
process$1(target, data, data.interaction, (scrolledToEnd ?
|
|
2983
|
-
13 /* RegionVisibility.ScrolledToEnd */ :
|
|
2984
|
-
(visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
|
|
2985
|
-
// Stop observing this element now that we have already received scrolled signal
|
|
2986
|
-
if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
|
|
2987
|
-
observer$1.unobserve(target);
|
|
2988
|
-
}
|
|
2989
|
-
}
|
|
2954
|
+
function schedule(node) {
|
|
2955
|
+
// Only schedule manual trigger for this node if it's not already in the queue
|
|
2956
|
+
if (queue$1.indexOf(node) < 0) {
|
|
2957
|
+
queue$1.push(node);
|
|
2990
2958
|
}
|
|
2991
|
-
|
|
2992
|
-
|
|
2959
|
+
// Cancel any previous trigger before scheduling a new one.
|
|
2960
|
+
// It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
|
|
2961
|
+
// And in those cases we do not wish to monitor changes multiple times for the same node.
|
|
2962
|
+
if (timeout$1) {
|
|
2963
|
+
clearTimeout(timeout$1);
|
|
2993
2964
|
}
|
|
2965
|
+
timeout$1 = setTimeout(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
|
|
2966
|
+
return node;
|
|
2994
2967
|
}
|
|
2995
|
-
function
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
2968
|
+
function trigger$2() {
|
|
2969
|
+
for (var _i = 0, queue_1 = queue$1; _i < queue_1.length; _i++) {
|
|
2970
|
+
var node = queue_1[_i];
|
|
2971
|
+
// Generate a mutation for this node only if it still exists
|
|
2972
|
+
if (node) {
|
|
2973
|
+
var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
|
2974
|
+
// Skip re-processing shadowRoot if it was already discovered
|
|
2975
|
+
if (shadowRoot && has(node)) {
|
|
2976
|
+
continue;
|
|
2977
|
+
}
|
|
2978
|
+
generate(node, shadowRoot ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
|
|
3006
2979
|
}
|
|
3007
2980
|
}
|
|
3008
|
-
else {
|
|
3009
|
-
queue$1.push({ node: n, data: d });
|
|
3010
|
-
}
|
|
3011
|
-
}
|
|
3012
|
-
function clone$1(r) {
|
|
3013
|
-
return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
|
|
3014
|
-
}
|
|
3015
|
-
function reset$6() {
|
|
3016
|
-
state$1 = [];
|
|
3017
|
-
}
|
|
3018
|
-
function stop$f() {
|
|
3019
|
-
reset$6();
|
|
3020
|
-
regionMap = null;
|
|
3021
|
-
regions = {};
|
|
3022
2981
|
queue$1 = [];
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
2982
|
+
}
|
|
2983
|
+
function generate(target, type) {
|
|
2984
|
+
measure(handle$1)([{
|
|
2985
|
+
addedNodes: [target],
|
|
2986
|
+
attributeName: null,
|
|
2987
|
+
attributeNamespace: null,
|
|
2988
|
+
nextSibling: null,
|
|
2989
|
+
oldValue: null,
|
|
2990
|
+
previousSibling: null,
|
|
2991
|
+
removedNodes: [],
|
|
2992
|
+
target: target,
|
|
2993
|
+
type: type
|
|
2994
|
+
}]);
|
|
3028
2995
|
}
|
|
3029
2996
|
|
|
3030
2997
|
function target(evt) {
|
|
@@ -3057,7 +3024,7 @@ function metadata$2(node, event, text) {
|
|
|
3057
3024
|
output.hash = value.hash;
|
|
3058
3025
|
output.privacy = metadata_1.privacy;
|
|
3059
3026
|
if (value.region) {
|
|
3060
|
-
track$
|
|
3027
|
+
track$4(value.region, event);
|
|
3061
3028
|
}
|
|
3062
3029
|
if (metadata_1.fraud) {
|
|
3063
3030
|
check$4(metadata_1.fraud, value.id, text || value.data.value);
|
|
@@ -3084,7 +3051,7 @@ function encode$3 (type, ts) {
|
|
|
3084
3051
|
case 18 /* Event.TouchEnd */:
|
|
3085
3052
|
case 19 /* Event.TouchMove */:
|
|
3086
3053
|
case 20 /* Event.TouchCancel */:
|
|
3087
|
-
for (_i = 0, _a = state$
|
|
3054
|
+
for (_i = 0, _a = state$3; _i < _a.length; _i++) {
|
|
3088
3055
|
entry = _a[_i];
|
|
3089
3056
|
pTarget = metadata$2(entry.data.target, entry.event);
|
|
3090
3057
|
if (pTarget.id > 0) {
|
|
@@ -3096,10 +3063,10 @@ function encode$3 (type, ts) {
|
|
|
3096
3063
|
track$7(entry.event, entry.data.x, entry.data.y);
|
|
3097
3064
|
}
|
|
3098
3065
|
}
|
|
3099
|
-
reset$
|
|
3066
|
+
reset$c();
|
|
3100
3067
|
break;
|
|
3101
3068
|
case 9 /* Event.Click */:
|
|
3102
|
-
for (_b = 0, _c = state$
|
|
3069
|
+
for (_b = 0, _c = state$6; _b < _c.length; _b++) {
|
|
3103
3070
|
entry = _c[_b];
|
|
3104
3071
|
cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
|
|
3105
3072
|
tokens = [entry.time, entry.event];
|
|
@@ -3119,10 +3086,10 @@ function encode$3 (type, ts) {
|
|
|
3119
3086
|
queue(tokens);
|
|
3120
3087
|
track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
|
|
3121
3088
|
}
|
|
3122
|
-
reset$
|
|
3089
|
+
reset$f();
|
|
3123
3090
|
break;
|
|
3124
3091
|
case 38 /* Event.Clipboard */:
|
|
3125
|
-
for (_d = 0, _e = state$
|
|
3092
|
+
for (_d = 0, _e = state$5; _d < _e.length; _d++) {
|
|
3126
3093
|
entry = _e[_d];
|
|
3127
3094
|
tokens = [entry.time, entry.event];
|
|
3128
3095
|
target = metadata$2(entry.data.target, entry.event);
|
|
@@ -3132,24 +3099,24 @@ function encode$3 (type, ts) {
|
|
|
3132
3099
|
queue(tokens);
|
|
3133
3100
|
}
|
|
3134
3101
|
}
|
|
3135
|
-
reset$
|
|
3102
|
+
reset$e();
|
|
3136
3103
|
break;
|
|
3137
3104
|
case 11 /* Event.Resize */:
|
|
3138
3105
|
r = data$b;
|
|
3139
3106
|
tokens.push(r.width);
|
|
3140
3107
|
tokens.push(r.height);
|
|
3141
3108
|
track$7(type, r.width, r.height);
|
|
3142
|
-
reset$
|
|
3109
|
+
reset$b();
|
|
3143
3110
|
queue(tokens);
|
|
3144
3111
|
break;
|
|
3145
3112
|
case 26 /* Event.Unload */:
|
|
3146
3113
|
u = data$9;
|
|
3147
3114
|
tokens.push(u.name);
|
|
3148
|
-
reset$
|
|
3115
|
+
reset$7();
|
|
3149
3116
|
queue(tokens);
|
|
3150
3117
|
break;
|
|
3151
3118
|
case 27 /* Event.Input */:
|
|
3152
|
-
for (_f = 0, _g = state$
|
|
3119
|
+
for (_f = 0, _g = state$4; _f < _g.length; _f++) {
|
|
3153
3120
|
entry = _g[_f];
|
|
3154
3121
|
iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
|
|
3155
3122
|
tokens = [entry.time, entry.event];
|
|
@@ -3157,7 +3124,7 @@ function encode$3 (type, ts) {
|
|
|
3157
3124
|
tokens.push(text$1(entry.data.value, "input", iTarget.privacy));
|
|
3158
3125
|
queue(tokens);
|
|
3159
3126
|
}
|
|
3160
|
-
reset$
|
|
3127
|
+
reset$d();
|
|
3161
3128
|
break;
|
|
3162
3129
|
case 21 /* Event.Selection */:
|
|
3163
3130
|
s = data$a;
|
|
@@ -3168,12 +3135,12 @@ function encode$3 (type, ts) {
|
|
|
3168
3135
|
tokens.push(s.startOffset);
|
|
3169
3136
|
tokens.push(endTarget.id);
|
|
3170
3137
|
tokens.push(s.endOffset);
|
|
3171
|
-
reset$
|
|
3138
|
+
reset$9();
|
|
3172
3139
|
queue(tokens);
|
|
3173
3140
|
}
|
|
3174
3141
|
break;
|
|
3175
3142
|
case 10 /* Event.Scroll */:
|
|
3176
|
-
for (_h = 0, _j = state$
|
|
3143
|
+
for (_h = 0, _j = state$2; _h < _j.length; _h++) {
|
|
3177
3144
|
entry = _j[_h];
|
|
3178
3145
|
sTarget = metadata$2(entry.data.target, entry.event);
|
|
3179
3146
|
if (sTarget.id > 0) {
|
|
@@ -3185,10 +3152,10 @@ function encode$3 (type, ts) {
|
|
|
3185
3152
|
track$7(entry.event, entry.data.x, entry.data.y);
|
|
3186
3153
|
}
|
|
3187
3154
|
}
|
|
3188
|
-
reset$
|
|
3155
|
+
reset$a();
|
|
3189
3156
|
break;
|
|
3190
3157
|
case 42 /* Event.Change */:
|
|
3191
|
-
for (_k = 0, _l = state$
|
|
3158
|
+
for (_k = 0, _l = state$7; _k < _l.length; _k++) {
|
|
3192
3159
|
entry = _l[_k];
|
|
3193
3160
|
tokens = [entry.time, entry.event];
|
|
3194
3161
|
target = metadata$2(entry.data.target, entry.event);
|
|
@@ -3201,10 +3168,10 @@ function encode$3 (type, ts) {
|
|
|
3201
3168
|
queue(tokens);
|
|
3202
3169
|
}
|
|
3203
3170
|
}
|
|
3204
|
-
reset$
|
|
3171
|
+
reset$g();
|
|
3205
3172
|
break;
|
|
3206
3173
|
case 39 /* Event.Submit */:
|
|
3207
|
-
for (_m = 0, _o = state$
|
|
3174
|
+
for (_m = 0, _o = state$1; _m < _o.length; _m++) {
|
|
3208
3175
|
entry = _o[_m];
|
|
3209
3176
|
tokens = [entry.time, entry.event];
|
|
3210
3177
|
target = metadata$2(entry.data.target, entry.event);
|
|
@@ -3213,7 +3180,7 @@ function encode$3 (type, ts) {
|
|
|
3213
3180
|
queue(tokens);
|
|
3214
3181
|
}
|
|
3215
3182
|
}
|
|
3216
|
-
reset$
|
|
3183
|
+
reset$8();
|
|
3217
3184
|
break;
|
|
3218
3185
|
case 22 /* Event.Timeline */:
|
|
3219
3186
|
for (_p = 0, _q = updates$1; _p < _q.length; _p++) {
|
|
@@ -3234,7 +3201,7 @@ function encode$3 (type, ts) {
|
|
|
3234
3201
|
tokens.push(v.visible);
|
|
3235
3202
|
queue(tokens);
|
|
3236
3203
|
visibility(t, v.visible);
|
|
3237
|
-
reset$
|
|
3204
|
+
reset$6();
|
|
3238
3205
|
break;
|
|
3239
3206
|
}
|
|
3240
3207
|
return [2 /*return*/];
|
|
@@ -3535,22 +3502,31 @@ function delay() {
|
|
|
3535
3502
|
return typeof config$1.upload === "string" /* Constant.String */ ? Math.max(Math.min(gap, 30000 /* Setting.MaxUploadDelay */), 100 /* Setting.MinUploadDelay */) : config$1.delay;
|
|
3536
3503
|
}
|
|
3537
3504
|
function response(payload) {
|
|
3538
|
-
var
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3505
|
+
var lines = payload && payload.length > 0 ? payload.split("\n") : [];
|
|
3506
|
+
for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
|
|
3507
|
+
var line = lines_1[_i];
|
|
3508
|
+
var parts = line && line.length > 0 ? line.split(/ (.*)/) : ["" /* Constant.Empty */];
|
|
3509
|
+
switch (parts[0]) {
|
|
3510
|
+
case "END" /* Constant.End */:
|
|
3511
|
+
// Clear out session storage and end the session so we can start fresh the next time
|
|
3512
|
+
trigger(6 /* Check.Server */);
|
|
3513
|
+
break;
|
|
3514
|
+
case "UPGRADE" /* Constant.Upgrade */:
|
|
3515
|
+
// Upgrade current session to send back playback information
|
|
3516
|
+
upgrade("Auto" /* Constant.Auto */);
|
|
3517
|
+
break;
|
|
3518
|
+
case "ACTION" /* Constant.Action */:
|
|
3519
|
+
// Invoke action callback, if configured and has a valid value
|
|
3520
|
+
if (config$1.action && parts.length > 1) {
|
|
3521
|
+
config$1.action(parts[1]);
|
|
3522
|
+
}
|
|
3523
|
+
break;
|
|
3524
|
+
case "EXTRACT" /* Constant.Extract */:
|
|
3525
|
+
if (parts.length > 1) {
|
|
3526
|
+
trigger$1(parts[1]);
|
|
3527
|
+
}
|
|
3528
|
+
break;
|
|
3529
|
+
}
|
|
3554
3530
|
}
|
|
3555
3531
|
}
|
|
3556
3532
|
|
|
@@ -3655,30 +3631,27 @@ var data$5 = {};
|
|
|
3655
3631
|
var keys = [];
|
|
3656
3632
|
var variables = {};
|
|
3657
3633
|
var selectors = {};
|
|
3658
|
-
var fragments = [];
|
|
3659
3634
|
function start$c() {
|
|
3635
|
+
reset$4();
|
|
3636
|
+
}
|
|
3637
|
+
function trigger$1(input) {
|
|
3660
3638
|
try {
|
|
3661
|
-
var
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
}
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
var
|
|
3639
|
+
var parts = input && input.length > 0 ? input.split(/ (.*)/) : ["" /* Constant.Empty */];
|
|
3640
|
+
var key = parseInt(parts[0]);
|
|
3641
|
+
var values = parts.length > 1 ? JSON.parse(parts[1]) : {};
|
|
3642
|
+
variables[key] = {};
|
|
3643
|
+
selectors[key] = {};
|
|
3644
|
+
for (var v in values) {
|
|
3645
|
+
var id = parseInt(v);
|
|
3646
|
+
var value = values[v];
|
|
3647
|
+
var source = value.startsWith("~" /* Constant.Tilde */) ? 0 /* ExtractSource.Javascript */ : 2 /* ExtractSource.Text */;
|
|
3668
3648
|
switch (source) {
|
|
3669
3649
|
case 0 /* ExtractSource.Javascript */:
|
|
3670
|
-
var variable =
|
|
3671
|
-
variables[key] = parse(variable);
|
|
3672
|
-
break;
|
|
3673
|
-
case 1 /* ExtractSource.Cookie */:
|
|
3674
|
-
/*Todo: Add cookie extract logic*/
|
|
3650
|
+
var variable = value.substring(1, value.length);
|
|
3651
|
+
variables[key][id] = parse(variable);
|
|
3675
3652
|
break;
|
|
3676
3653
|
case 2 /* ExtractSource.Text */:
|
|
3677
|
-
|
|
3678
|
-
selectors[key] = match_1;
|
|
3679
|
-
break;
|
|
3680
|
-
case 3 /* ExtractSource.Fragment */:
|
|
3681
|
-
fragments = e[i + 2];
|
|
3654
|
+
selectors[key][id] = value;
|
|
3682
3655
|
break;
|
|
3683
3656
|
}
|
|
3684
3657
|
}
|
|
@@ -3693,15 +3666,25 @@ function clone(v) {
|
|
|
3693
3666
|
function compute$4() {
|
|
3694
3667
|
try {
|
|
3695
3668
|
for (var v in variables) {
|
|
3696
|
-
var
|
|
3697
|
-
if (
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3669
|
+
var key = parseInt(v);
|
|
3670
|
+
if (!(key in keys)) {
|
|
3671
|
+
var variableData = variables[key];
|
|
3672
|
+
for (var v_1 in variableData) {
|
|
3673
|
+
var variableKey = parseInt(v_1);
|
|
3674
|
+
var value = str(evaluate(clone(variableData[variableKey])));
|
|
3675
|
+
if (value) {
|
|
3676
|
+
update(key, variableKey, value);
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
var selectorData = selectors[key];
|
|
3680
|
+
for (var s in selectorData) {
|
|
3681
|
+
var selectorKey = parseInt(s);
|
|
3682
|
+
var nodes = document.querySelectorAll(selectorData[selectorKey]);
|
|
3683
|
+
if (nodes) {
|
|
3684
|
+
var text = Array.from(nodes).map(function (e) { return e.innerText; });
|
|
3685
|
+
update(key, selectorKey, text.join("<SEP>" /* Constant.Seperator */).substring(0, 10000 /* Setting.ExtractLimit */));
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3705
3688
|
}
|
|
3706
3689
|
}
|
|
3707
3690
|
}
|
|
@@ -3711,20 +3694,20 @@ function compute$4() {
|
|
|
3711
3694
|
encode$1(40 /* Event.Extract */);
|
|
3712
3695
|
}
|
|
3713
3696
|
function reset$4() {
|
|
3697
|
+
data$5 = {};
|
|
3714
3698
|
keys = [];
|
|
3699
|
+
variables = {};
|
|
3700
|
+
selectors = {};
|
|
3715
3701
|
}
|
|
3716
|
-
function update(key,
|
|
3717
|
-
if (
|
|
3718
|
-
|
|
3719
|
-
data$5[key] = value;
|
|
3702
|
+
function update(key, subkey, value) {
|
|
3703
|
+
if (!(key in data$5)) {
|
|
3704
|
+
data$5[key] = [];
|
|
3720
3705
|
keys.push(key);
|
|
3721
3706
|
}
|
|
3707
|
+
data$5[key].push([subkey, value]);
|
|
3722
3708
|
}
|
|
3723
3709
|
function stop$b() {
|
|
3724
|
-
|
|
3725
|
-
keys = [];
|
|
3726
|
-
variables = {};
|
|
3727
|
-
selectors = {};
|
|
3710
|
+
reset$4();
|
|
3728
3711
|
}
|
|
3729
3712
|
function parse(variable) {
|
|
3730
3713
|
var syntax = [];
|
|
@@ -3889,7 +3872,7 @@ function encode$1 (event) {
|
|
|
3889
3872
|
for (var _d = 0, extractKeys_1 = extractKeys; _d < extractKeys_1.length; _d++) {
|
|
3890
3873
|
var e = extractKeys_1[_d];
|
|
3891
3874
|
tokens.push(e);
|
|
3892
|
-
tokens.push(data$5[e]);
|
|
3875
|
+
tokens.push([].concat.apply([], data$5[e]));
|
|
3893
3876
|
}
|
|
3894
3877
|
reset$4();
|
|
3895
3878
|
queue(tokens, false);
|
|
@@ -4390,7 +4373,7 @@ var status = false;
|
|
|
4390
4373
|
function start$6() {
|
|
4391
4374
|
status = true;
|
|
4392
4375
|
start$G();
|
|
4393
|
-
reset$
|
|
4376
|
+
reset$j();
|
|
4394
4377
|
reset$1();
|
|
4395
4378
|
reset$2();
|
|
4396
4379
|
start$7();
|
|
@@ -4399,7 +4382,7 @@ function stop$5() {
|
|
|
4399
4382
|
stop$6();
|
|
4400
4383
|
reset$2();
|
|
4401
4384
|
reset$1();
|
|
4402
|
-
reset$
|
|
4385
|
+
reset$j();
|
|
4403
4386
|
stop$C();
|
|
4404
4387
|
status = false;
|
|
4405
4388
|
}
|
|
@@ -4482,14 +4465,14 @@ function discover() {
|
|
|
4482
4465
|
case 0:
|
|
4483
4466
|
ts = time();
|
|
4484
4467
|
timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
|
|
4485
|
-
start$
|
|
4468
|
+
start$w(timer);
|
|
4486
4469
|
return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */)];
|
|
4487
4470
|
case 1:
|
|
4488
4471
|
_a.sent();
|
|
4489
4472
|
return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
|
|
4490
4473
|
case 2:
|
|
4491
4474
|
_a.sent();
|
|
4492
|
-
stop$
|
|
4475
|
+
stop$t(timer);
|
|
4493
4476
|
return [2 /*return*/];
|
|
4494
4477
|
}
|
|
4495
4478
|
});
|
|
@@ -4499,24 +4482,24 @@ function discover() {
|
|
|
4499
4482
|
function start$3() {
|
|
4500
4483
|
// The order below is important
|
|
4501
4484
|
// and is determined by interdependencies of modules
|
|
4502
|
-
start$
|
|
4485
|
+
start$v();
|
|
4486
|
+
start$u();
|
|
4487
|
+
start$x();
|
|
4503
4488
|
start$h();
|
|
4504
|
-
start$i();
|
|
4505
|
-
start$j();
|
|
4506
4489
|
start$4();
|
|
4507
4490
|
}
|
|
4508
4491
|
function stop$3() {
|
|
4492
|
+
stop$s();
|
|
4493
|
+
stop$u();
|
|
4509
4494
|
stop$f();
|
|
4510
|
-
stop$g();
|
|
4511
|
-
stop$h();
|
|
4512
4495
|
end();
|
|
4513
4496
|
}
|
|
4514
4497
|
|
|
4515
4498
|
var layout = /*#__PURE__*/Object.freeze({
|
|
4516
4499
|
__proto__: null,
|
|
4500
|
+
hashText: hashText,
|
|
4517
4501
|
start: start$3,
|
|
4518
|
-
stop: stop$3
|
|
4519
|
-
hashText: hashText
|
|
4502
|
+
stop: stop$3
|
|
4520
4503
|
});
|
|
4521
4504
|
|
|
4522
4505
|
function encode (type) {
|
|
@@ -4668,11 +4651,6 @@ function process(entries) {
|
|
|
4668
4651
|
break;
|
|
4669
4652
|
}
|
|
4670
4653
|
}
|
|
4671
|
-
if (performance && "memory" /* Constant.Memory */ in performance && performance["memory" /* Constant.Memory */].usedJSHeapSize) {
|
|
4672
|
-
// Track consumed memory (MBs) where "memory" API is available
|
|
4673
|
-
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory
|
|
4674
|
-
max(30 /* Metric.UsedMemory */, Math.abs(performance["memory" /* Constant.Memory */].usedJSHeapSize / 1048576 /* Setting.MegaByte */));
|
|
4675
|
-
}
|
|
4676
4654
|
}
|
|
4677
4655
|
function stop$2() {
|
|
4678
4656
|
if (observer) {
|