clarity-js 0.7.3 → 0.7.5
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 -1
- package/build/clarity.js +1312 -1325
- package/build/clarity.min.js +1 -1
- package/build/clarity.module.js +1312 -1325
- package/package.json +1 -1
- package/src/core/config.ts +0 -1
- package/src/core/report.ts +1 -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 +26 -15
- package/src/layout/dom.ts +4 -35
- package/src/layout/mutation.ts +4 -4
- package/src/layout/node.ts +2 -2
- package/src/performance/observer.ts +1 -1
- package/types/core.d.ts +0 -2
- package/types/data.d.ts +8 -4
- package/types/layout.d.ts +0 -1
package/build/clarity.js
CHANGED
|
@@ -1,23 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var dom = /*#__PURE__*/Object.freeze({
|
|
4
|
-
__proto__: null,
|
|
5
|
-
get add () { return add; },
|
|
6
|
-
get get () { return get; },
|
|
7
|
-
get getId () { return getId; },
|
|
8
|
-
get getNode () { return getNode; },
|
|
9
|
-
get getValue () { return getValue; },
|
|
10
|
-
get has () { return has; },
|
|
11
|
-
get hashText () { return hashText; },
|
|
12
|
-
get iframe () { return iframe; },
|
|
13
|
-
get lookup () { return lookup; },
|
|
14
|
-
get parse () { return parse$1; },
|
|
15
|
-
get sameorigin () { return sameorigin; },
|
|
16
|
-
get start () { return start$i; },
|
|
17
|
-
get stop () { return stop$g; },
|
|
18
|
-
get update () { return update$1; },
|
|
19
|
-
get updates () { return updates$2; }
|
|
20
|
-
});
|
|
21
3
|
var upload$1 = /*#__PURE__*/Object.freeze({
|
|
22
4
|
__proto__: null,
|
|
23
5
|
get queue () { return queue; },
|
|
@@ -30,11 +12,11 @@ var extract = /*#__PURE__*/Object.freeze({
|
|
|
30
12
|
get clone () { return clone; },
|
|
31
13
|
get compute () { return compute$4; },
|
|
32
14
|
get data () { return data$5; },
|
|
33
|
-
get fragments () { return fragments; },
|
|
34
15
|
get keys () { return keys; },
|
|
35
16
|
get reset () { return reset$4; },
|
|
36
17
|
get start () { return start$c; },
|
|
37
18
|
get stop () { return stop$b; },
|
|
19
|
+
get trigger () { return trigger$1; },
|
|
38
20
|
get update () { return update; }
|
|
39
21
|
});
|
|
40
22
|
var limit = /*#__PURE__*/Object.freeze({
|
|
@@ -137,7 +119,6 @@ var config$1 = {
|
|
|
137
119
|
mask: [],
|
|
138
120
|
unmask: [],
|
|
139
121
|
regions: [],
|
|
140
|
-
extract: [],
|
|
141
122
|
cookies: [],
|
|
142
123
|
fraud: true,
|
|
143
124
|
checksum: [],
|
|
@@ -168,7 +149,7 @@ function stop$C() {
|
|
|
168
149
|
startTime = 0;
|
|
169
150
|
}
|
|
170
151
|
|
|
171
|
-
var version$1 = "0.7.
|
|
152
|
+
var version$1 = "0.7.5";
|
|
172
153
|
|
|
173
154
|
// tslint:disable: no-bitwise
|
|
174
155
|
function hash (input, precision) {
|
|
@@ -921,168 +902,540 @@ var selector = /*#__PURE__*/Object.freeze({
|
|
|
921
902
|
reset: reset$l
|
|
922
903
|
});
|
|
923
904
|
|
|
924
|
-
|
|
925
|
-
var
|
|
926
|
-
var
|
|
927
|
-
var
|
|
928
|
-
var
|
|
929
|
-
var
|
|
930
|
-
var
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
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);
|
|
937
924
|
}
|
|
938
|
-
function
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
925
|
+
function stop$u() {
|
|
926
|
+
reset$k();
|
|
927
|
+
}
|
|
928
|
+
function reset$k() {
|
|
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();
|
|
945
|
+
}
|
|
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
|
|
944
964
|
}
|
|
945
965
|
}
|
|
966
|
+
catch (e) {
|
|
967
|
+
log$1(5 /* Code.Selector */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
968
|
+
}
|
|
946
969
|
}
|
|
947
|
-
function
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
970
|
+
function getId(node, autogen) {
|
|
971
|
+
if (autogen === void 0) { autogen = false; }
|
|
972
|
+
if (node === null) {
|
|
973
|
+
return null;
|
|
974
|
+
}
|
|
975
|
+
var id = idMap.get(node);
|
|
976
|
+
if (!id && autogen) {
|
|
977
|
+
id = index++;
|
|
978
|
+
idMap.set(node, id);
|
|
979
|
+
}
|
|
980
|
+
return id ? id : null;
|
|
952
981
|
}
|
|
953
|
-
function
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
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 },
|
|
1013
|
+
};
|
|
1014
|
+
privacy(node, values[id], parentValue);
|
|
1015
|
+
updateSelector(values[id]);
|
|
1016
|
+
size$1(values[id]);
|
|
1017
|
+
track$5(id, source);
|
|
980
1018
|
}
|
|
981
|
-
function
|
|
982
|
-
var
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
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;
|
|
991
1044
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
}).catch(function (error) {
|
|
996
|
-
// If one of the scheduled tasks failed, log, recover and continue processing rest of the tasks
|
|
997
|
-
if (entry.id !== id()) {
|
|
998
|
-
return;
|
|
1045
|
+
else {
|
|
1046
|
+
// Mark this element as deleted if the parent has been updated to null
|
|
1047
|
+
remove(id, source);
|
|
999
1048
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
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
|
+
}
|
|
1002
1055
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1056
|
+
parentChanged = true;
|
|
1057
|
+
}
|
|
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);
|
|
1006
1068
|
}
|
|
1007
1069
|
}
|
|
1008
|
-
function
|
|
1009
|
-
var
|
|
1010
|
-
if (
|
|
1011
|
-
var
|
|
1012
|
-
|
|
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
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
1013
1085
|
}
|
|
1014
|
-
|
|
1015
|
-
return 2 /* Task.Stop */;
|
|
1086
|
+
return output;
|
|
1016
1087
|
}
|
|
1017
|
-
function
|
|
1018
|
-
|
|
1088
|
+
function iframe(node) {
|
|
1089
|
+
var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
|
|
1090
|
+
return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
|
|
1019
1091
|
}
|
|
1020
|
-
function
|
|
1021
|
-
var
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
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;
|
|
1028
1134
|
}
|
|
1029
1135
|
}
|
|
1030
|
-
function
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
var duration = end - tracker[id].start;
|
|
1034
|
-
sum(timer.cost, duration);
|
|
1035
|
-
count$1(5 /* Metric.InvokeCount */);
|
|
1036
|
-
// For the first execution, which is synchronous, time is automatically counted towards TotalDuration.
|
|
1037
|
-
// However, for subsequent asynchronous runs, we need to manually update TotalDuration metric.
|
|
1038
|
-
if (tracker[id].calls > 0) {
|
|
1039
|
-
sum(4 /* Metric.TotalCost */, duration);
|
|
1136
|
+
function inspect(input, lookup, metadata) {
|
|
1137
|
+
if (input && lookup.some(function (x) { return input.indexOf(x) >= 0; })) {
|
|
1138
|
+
return 2 /* Privacy.Text */;
|
|
1040
1139
|
}
|
|
1140
|
+
return metadata.privacy;
|
|
1041
1141
|
}
|
|
1042
|
-
function
|
|
1043
|
-
|
|
1044
|
-
var
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
case 0:
|
|
1048
|
-
id = key(timer);
|
|
1049
|
-
if (!(id in tracker)) return [3 /*break*/, 2];
|
|
1050
|
-
stop$u(timer);
|
|
1051
|
-
_a = tracker[id];
|
|
1052
|
-
return [4 /*yield*/, wait()];
|
|
1053
|
-
case 1:
|
|
1054
|
-
_a.yield = (_b.sent()).timeRemaining();
|
|
1055
|
-
restart$2(timer);
|
|
1056
|
-
_b.label = 2;
|
|
1057
|
-
case 2:
|
|
1058
|
-
// After we are done with suspending task, ensure that we are still operating in the right context
|
|
1059
|
-
// If the task is still being tracked, continue running the task, otherwise ask caller to stop execution
|
|
1060
|
-
return [2 /*return*/, id in tracker ? 1 /* Task.Run */ : 2 /* Task.Stop */];
|
|
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;
|
|
1061
1147
|
}
|
|
1148
|
+
}
|
|
1149
|
+
for (var key in b[field]) {
|
|
1150
|
+
if (b[field][key] !== a[field][key]) {
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
return a[field] !== b[field];
|
|
1157
|
+
}
|
|
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;
|
|
1169
|
+
}
|
|
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; });
|
|
1179
|
+
}
|
|
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 */) : '';
|
|
1184
|
+
}
|
|
1185
|
+
function getNode(id) {
|
|
1186
|
+
if (id in nodes) {
|
|
1187
|
+
return nodes[id];
|
|
1188
|
+
}
|
|
1189
|
+
return null;
|
|
1190
|
+
}
|
|
1191
|
+
function getValue(id) {
|
|
1192
|
+
if (id in values) {
|
|
1193
|
+
return values[id];
|
|
1194
|
+
}
|
|
1195
|
+
return null;
|
|
1196
|
+
}
|
|
1197
|
+
function get(node) {
|
|
1198
|
+
var id = getId(node);
|
|
1199
|
+
return id in values ? values[id] : null;
|
|
1200
|
+
}
|
|
1201
|
+
function lookup(hash) {
|
|
1202
|
+
return hash in hashMap ? hashMap[hash] : null;
|
|
1203
|
+
}
|
|
1204
|
+
function has(node) {
|
|
1205
|
+
return getId(node) in nodes;
|
|
1206
|
+
}
|
|
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
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
updateMap = [];
|
|
1216
|
+
return output;
|
|
1217
|
+
}
|
|
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);
|
|
1224
|
+
}
|
|
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 = [];
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
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;
|
|
1239
|
+
}
|
|
1240
|
+
return id;
|
|
1241
|
+
}
|
|
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);
|
|
1252
|
+
}
|
|
1253
|
+
else if (uIndex === -1 && changed) {
|
|
1254
|
+
updateMap.push(id);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
|
|
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;
|
|
1062
1288
|
});
|
|
1063
|
-
}
|
|
1289
|
+
}
|
|
1064
1290
|
}
|
|
1065
|
-
function
|
|
1066
|
-
|
|
1291
|
+
function resume$1() {
|
|
1292
|
+
if (pauseTask) {
|
|
1293
|
+
resumeResolve();
|
|
1294
|
+
pauseTask = null;
|
|
1295
|
+
if (activeTask === null) {
|
|
1296
|
+
run();
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1067
1299
|
}
|
|
1068
|
-
function
|
|
1300
|
+
function reset$j() {
|
|
1301
|
+
tracker = {};
|
|
1302
|
+
queuedTasks = [];
|
|
1303
|
+
activeTask = null;
|
|
1304
|
+
pauseTask = null;
|
|
1305
|
+
}
|
|
1306
|
+
function schedule$1(task, priority) {
|
|
1307
|
+
if (priority === void 0) { priority = 0 /* Priority.Normal */; }
|
|
1069
1308
|
return __awaiter(this, void 0, void 0, function () {
|
|
1309
|
+
var _i, queuedTasks_1, q, promise;
|
|
1070
1310
|
return __generator(this, function (_a) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
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();
|
|
1081
1329
|
}
|
|
1330
|
+
return [2 /*return*/, promise];
|
|
1082
1331
|
});
|
|
1083
1332
|
});
|
|
1084
1333
|
}
|
|
1085
|
-
|
|
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
|
+
}
|
|
1360
|
+
}
|
|
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 */;
|
|
1366
|
+
}
|
|
1367
|
+
// If this task is no longer being tracked, send stop message to the caller
|
|
1368
|
+
return 2 /* Task.Stop */;
|
|
1369
|
+
}
|
|
1370
|
+
function start$w(timer) {
|
|
1371
|
+
tracker[key(timer)] = { start: performance.now(), calls: 0, yield: 30 /* Setting.LongTask */ };
|
|
1372
|
+
}
|
|
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
|
+
}
|
|
1382
|
+
}
|
|
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
|
+
}
|
|
1394
|
+
}
|
|
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
|
+
});
|
|
1417
|
+
}
|
|
1418
|
+
function key(timer) {
|
|
1419
|
+
return "".concat(timer.id, ".").concat(timer.cost);
|
|
1420
|
+
}
|
|
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
|
+
})];
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
// Use native implementation of requestIdleCallback if it exists.
|
|
1086
1439
|
// Otherwise, fall back to a custom implementation using requestAnimationFrame & MessageChannel.
|
|
1087
1440
|
// While it's not possible to build a perfect polyfill given the nature of this API, the following code attempts to get close.
|
|
1088
1441
|
// Background context: requestAnimationFrame invokes the js code right before: style, layout and paint computation within the frame.
|
|
@@ -1159,6 +1512,41 @@ function tokenize (tokens) {
|
|
|
1159
1512
|
return output;
|
|
1160
1513
|
}
|
|
1161
1514
|
|
|
1515
|
+
var data$c;
|
|
1516
|
+
function reset$i() {
|
|
1517
|
+
data$c = null;
|
|
1518
|
+
}
|
|
1519
|
+
function start$v() {
|
|
1520
|
+
reset$i();
|
|
1521
|
+
compute$7();
|
|
1522
|
+
}
|
|
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
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
function end() {
|
|
1547
|
+
reset$i();
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1162
1550
|
function encode$4 (type, timer, ts) {
|
|
1163
1551
|
if (timer === void 0) { timer = null; }
|
|
1164
1552
|
if (ts === void 0) { ts = null; }
|
|
@@ -1185,7 +1573,7 @@ function encode$4 (type, timer, ts) {
|
|
|
1185
1573
|
queue(tokens);
|
|
1186
1574
|
return [3 /*break*/, 10];
|
|
1187
1575
|
case 2:
|
|
1188
|
-
for (_i = 0, _b = state$
|
|
1576
|
+
for (_i = 0, _b = state$8; _i < _b.length; _i++) {
|
|
1189
1577
|
r = _b[_i];
|
|
1190
1578
|
tokens = [r.time, 7 /* Event.Region */];
|
|
1191
1579
|
tokens.push(r.data.id);
|
|
@@ -1194,7 +1582,7 @@ function encode$4 (type, timer, ts) {
|
|
|
1194
1582
|
tokens.push(r.data.name);
|
|
1195
1583
|
queue(tokens);
|
|
1196
1584
|
}
|
|
1197
|
-
reset$
|
|
1585
|
+
reset$h();
|
|
1198
1586
|
return [3 /*break*/, 10];
|
|
1199
1587
|
case 3:
|
|
1200
1588
|
// Check if we are operating within the context of the current page
|
|
@@ -1229,7 +1617,7 @@ function encode$4 (type, timer, ts) {
|
|
|
1229
1617
|
if (data[key]) {
|
|
1230
1618
|
switch (key) {
|
|
1231
1619
|
case "tag":
|
|
1232
|
-
box = size
|
|
1620
|
+
box = size(value);
|
|
1233
1621
|
factor = mangle ? -1 : 1;
|
|
1234
1622
|
tokens.push(value.id * factor);
|
|
1235
1623
|
if (value.parent && active) {
|
|
@@ -1277,7 +1665,7 @@ function shouldMangle(value) {
|
|
|
1277
1665
|
var privacy = value.metadata.privacy;
|
|
1278
1666
|
return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
|
|
1279
1667
|
}
|
|
1280
|
-
function size
|
|
1668
|
+
function size(value) {
|
|
1281
1669
|
if (value.metadata.size !== null && value.metadata.size.length === 0) {
|
|
1282
1670
|
var img = getNode(value.id);
|
|
1283
1671
|
if (img) {
|
|
@@ -1293,95 +1681,207 @@ function attribute(key, value, privacy) {
|
|
|
1293
1681
|
return "".concat(key, "=").concat(text$1(value, key, privacy));
|
|
1294
1682
|
}
|
|
1295
1683
|
|
|
1296
|
-
var data$c;
|
|
1297
|
-
function reset$j() {
|
|
1298
|
-
data$c = null;
|
|
1299
|
-
}
|
|
1300
|
-
function start$w() {
|
|
1301
|
-
reset$j();
|
|
1302
|
-
compute$7();
|
|
1303
|
-
}
|
|
1304
|
-
function compute$7() {
|
|
1305
|
-
var body = document.body;
|
|
1306
|
-
var d = document.documentElement;
|
|
1307
|
-
var bodyClientWidth = body ? body.clientWidth : null;
|
|
1308
|
-
var bodyScrollWidth = body ? body.scrollWidth : null;
|
|
1309
|
-
var bodyOffsetWidth = body ? body.offsetWidth : null;
|
|
1310
|
-
var documentClientWidth = d ? d.clientWidth : null;
|
|
1311
|
-
var documentScrollWidth = d ? d.scrollWidth : null;
|
|
1312
|
-
var documentOffsetWidth = d ? d.offsetWidth : null;
|
|
1313
|
-
var width = Math.max(bodyClientWidth, bodyScrollWidth, bodyOffsetWidth, documentClientWidth, documentScrollWidth, documentOffsetWidth);
|
|
1314
|
-
var bodyClientHeight = body ? body.clientHeight : null;
|
|
1315
|
-
var bodyScrollHeight = body ? body.scrollHeight : null;
|
|
1316
|
-
var bodyOffsetHeight = body ? body.offsetHeight : null;
|
|
1317
|
-
var documentClientHeight = d ? d.clientHeight : null;
|
|
1318
|
-
var documentScrollHeight = d ? d.scrollHeight : null;
|
|
1319
|
-
var documentOffsetHeight = d ? d.offsetHeight : null;
|
|
1320
|
-
var height = Math.max(bodyClientHeight, bodyScrollHeight, bodyOffsetHeight, documentClientHeight, documentScrollHeight, documentOffsetHeight);
|
|
1321
|
-
// Check that width or height has changed from before, and also that width & height are not null values
|
|
1322
|
-
if ((data$c === null || width !== data$c.width || height !== data$c.height) && width !== null && height !== null) {
|
|
1323
|
-
data$c = { width: width, height: height };
|
|
1324
|
-
encode$4(8 /* Event.Document */);
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
function end() {
|
|
1328
|
-
reset$j();
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
1684
|
var state$8 = [];
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
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;
|
|
1337
1697
|
}
|
|
1338
|
-
function
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
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
|
+
}
|
|
1345
1711
|
}
|
|
1346
1712
|
}
|
|
1347
|
-
function
|
|
1348
|
-
|
|
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);
|
|
1349
1718
|
}
|
|
1350
|
-
function
|
|
1351
|
-
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
output.x += element.offsetLeft;
|
|
1363
|
-
output.y += element.offsetTop;
|
|
1364
|
-
element = frame ? frame : parent_1;
|
|
1365
|
-
} while (element);
|
|
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;
|
|
1366
1731
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
|
|
1371
|
-
var state$7 = [];
|
|
1372
|
-
function start$u() {
|
|
1373
|
-
reset$h();
|
|
1374
|
-
}
|
|
1375
|
-
function observe$b(root) {
|
|
1376
|
-
bind(root, "click", handler$3.bind(this, 9 /* Event.Click */, root), true);
|
|
1732
|
+
// Process updates to this region, if applicable
|
|
1733
|
+
process$6(node, data, interaction, data.visibility);
|
|
1377
1734
|
}
|
|
1378
|
-
function
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
var
|
|
1383
|
-
|
|
1384
|
-
|
|
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
|
+
}
|
|
1759
|
+
}
|
|
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
|
+
}
|
|
1795
|
+
}
|
|
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
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
function clone$1(r) {
|
|
1814
|
+
return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
|
|
1815
|
+
}
|
|
1816
|
+
function reset$h() {
|
|
1817
|
+
state$8 = [];
|
|
1818
|
+
}
|
|
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;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
var state$7 = [];
|
|
1832
|
+
function start$t() {
|
|
1833
|
+
reset$g();
|
|
1834
|
+
}
|
|
1835
|
+
function observe$b(root) {
|
|
1836
|
+
bind(root, "change", recompute$8, true);
|
|
1837
|
+
}
|
|
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
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
function reset$g() {
|
|
1848
|
+
state$7 = [];
|
|
1849
|
+
}
|
|
1850
|
+
function stop$r() {
|
|
1851
|
+
reset$g();
|
|
1852
|
+
}
|
|
1853
|
+
|
|
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);
|
|
1866
|
+
}
|
|
1867
|
+
return output;
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
|
|
1871
|
+
var state$6 = [];
|
|
1872
|
+
function start$s() {
|
|
1873
|
+
reset$f();
|
|
1874
|
+
}
|
|
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) {
|
|
1385
1885
|
var distance = offset(frame);
|
|
1386
1886
|
x = x ? x + Math.round(distance.x) : x;
|
|
1387
1887
|
y = y ? y + Math.round(distance.y) : y;
|
|
@@ -1403,7 +1903,7 @@ function handler$3(event, root, evt) {
|
|
|
1403
1903
|
var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1404
1904
|
// Check for null values before processing this event
|
|
1405
1905
|
if (x !== null && y !== null) {
|
|
1406
|
-
state$
|
|
1906
|
+
state$6.push({
|
|
1407
1907
|
time: time(evt),
|
|
1408
1908
|
event: event,
|
|
1409
1909
|
data: {
|
|
@@ -1478,39 +1978,39 @@ function context(a) {
|
|
|
1478
1978
|
}
|
|
1479
1979
|
return 0 /* BrowsingContext.Self */;
|
|
1480
1980
|
}
|
|
1481
|
-
function reset$
|
|
1482
|
-
state$
|
|
1981
|
+
function reset$f() {
|
|
1982
|
+
state$6 = [];
|
|
1483
1983
|
}
|
|
1484
|
-
function stop$
|
|
1485
|
-
reset$
|
|
1984
|
+
function stop$q() {
|
|
1985
|
+
reset$f();
|
|
1486
1986
|
}
|
|
1487
1987
|
|
|
1488
|
-
var state$
|
|
1489
|
-
function start$
|
|
1490
|
-
reset$
|
|
1988
|
+
var state$5 = [];
|
|
1989
|
+
function start$r() {
|
|
1990
|
+
reset$e();
|
|
1491
1991
|
}
|
|
1492
|
-
function observe$
|
|
1992
|
+
function observe$9(root) {
|
|
1493
1993
|
bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
|
|
1494
1994
|
bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
|
|
1495
1995
|
bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
|
|
1496
1996
|
}
|
|
1497
1997
|
function recompute$7(action, evt) {
|
|
1498
|
-
state$
|
|
1998
|
+
state$5.push({ time: time(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
|
|
1499
1999
|
schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
|
|
1500
2000
|
}
|
|
1501
|
-
function reset$
|
|
1502
|
-
state$
|
|
2001
|
+
function reset$e() {
|
|
2002
|
+
state$5 = [];
|
|
1503
2003
|
}
|
|
1504
|
-
function stop$
|
|
1505
|
-
reset$
|
|
2004
|
+
function stop$p() {
|
|
2005
|
+
reset$e();
|
|
1506
2006
|
}
|
|
1507
2007
|
|
|
1508
2008
|
var timeout$5 = null;
|
|
1509
|
-
var state$
|
|
1510
|
-
function start$
|
|
1511
|
-
reset$
|
|
2009
|
+
var state$4 = [];
|
|
2010
|
+
function start$q() {
|
|
2011
|
+
reset$d();
|
|
1512
2012
|
}
|
|
1513
|
-
function observe$
|
|
2013
|
+
function observe$8(root) {
|
|
1514
2014
|
bind(root, "input", recompute$6, true);
|
|
1515
2015
|
}
|
|
1516
2016
|
function recompute$6(evt) {
|
|
@@ -1526,31 +2026,31 @@ function recompute$6(evt) {
|
|
|
1526
2026
|
}
|
|
1527
2027
|
var data = { target: input, value: v };
|
|
1528
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.
|
|
1529
|
-
if (state$
|
|
1530
|
-
state$
|
|
2029
|
+
if (state$4.length > 0 && (state$4[state$4.length - 1].data.target === data.target)) {
|
|
2030
|
+
state$4.pop();
|
|
1531
2031
|
}
|
|
1532
|
-
state$
|
|
2032
|
+
state$4.push({ time: time(evt), event: 27 /* Event.Input */, data: data });
|
|
1533
2033
|
clearTimeout(timeout$5);
|
|
1534
|
-
timeout$5 = setTimeout(process$
|
|
2034
|
+
timeout$5 = setTimeout(process$5, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
|
|
1535
2035
|
}
|
|
1536
2036
|
}
|
|
1537
|
-
function process$
|
|
2037
|
+
function process$5(event) {
|
|
1538
2038
|
schedule$1(encode$3.bind(this, event));
|
|
1539
2039
|
}
|
|
1540
|
-
function reset$
|
|
1541
|
-
state$
|
|
2040
|
+
function reset$d() {
|
|
2041
|
+
state$4 = [];
|
|
1542
2042
|
}
|
|
1543
|
-
function stop$
|
|
2043
|
+
function stop$o() {
|
|
1544
2044
|
clearTimeout(timeout$5);
|
|
1545
|
-
reset$
|
|
2045
|
+
reset$d();
|
|
1546
2046
|
}
|
|
1547
2047
|
|
|
1548
|
-
var state$
|
|
2048
|
+
var state$3 = [];
|
|
1549
2049
|
var timeout$4 = null;
|
|
1550
|
-
function start$
|
|
1551
|
-
reset$
|
|
2050
|
+
function start$p() {
|
|
2051
|
+
reset$c();
|
|
1552
2052
|
}
|
|
1553
|
-
function observe$
|
|
2053
|
+
function observe$7(root) {
|
|
1554
2054
|
bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
|
|
1555
2055
|
bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
|
|
1556
2056
|
bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
|
|
@@ -1574,7 +2074,7 @@ function mouse(event, root, evt) {
|
|
|
1574
2074
|
}
|
|
1575
2075
|
// Check for null values before processing this event
|
|
1576
2076
|
if (x !== null && y !== null) {
|
|
1577
|
-
handler$
|
|
2077
|
+
handler$1({ time: time(evt), event: event, data: { target: target(evt), x: x, y: y } });
|
|
1578
2078
|
}
|
|
1579
2079
|
}
|
|
1580
2080
|
function touch(event, root, evt) {
|
|
@@ -1591,36 +2091,36 @@ function touch(event, root, evt) {
|
|
|
1591
2091
|
y = y && frame ? y + Math.round(frame.offsetTop) : y;
|
|
1592
2092
|
// Check for null values before processing this event
|
|
1593
2093
|
if (x !== null && y !== null) {
|
|
1594
|
-
handler$
|
|
2094
|
+
handler$1({ time: t, event: event, data: { target: target(evt), x: x, y: y } });
|
|
1595
2095
|
}
|
|
1596
2096
|
}
|
|
1597
2097
|
}
|
|
1598
2098
|
}
|
|
1599
|
-
function handler$
|
|
2099
|
+
function handler$1(current) {
|
|
1600
2100
|
switch (current.event) {
|
|
1601
2101
|
case 12 /* Event.MouseMove */:
|
|
1602
2102
|
case 15 /* Event.MouseWheel */:
|
|
1603
2103
|
case 19 /* Event.TouchMove */:
|
|
1604
|
-
var length_1 = state$
|
|
1605
|
-
var last = length_1 > 1 ? state$
|
|
2104
|
+
var length_1 = state$3.length;
|
|
2105
|
+
var last = length_1 > 1 ? state$3[length_1 - 2] : null;
|
|
1606
2106
|
if (last && similar$1(last, current)) {
|
|
1607
|
-
state$
|
|
2107
|
+
state$3.pop();
|
|
1608
2108
|
}
|
|
1609
|
-
state$
|
|
2109
|
+
state$3.push(current);
|
|
1610
2110
|
clearTimeout(timeout$4);
|
|
1611
|
-
timeout$4 = setTimeout(process$
|
|
2111
|
+
timeout$4 = setTimeout(process$4, 500 /* Setting.LookAhead */, current.event);
|
|
1612
2112
|
break;
|
|
1613
2113
|
default:
|
|
1614
|
-
state$
|
|
1615
|
-
process$
|
|
2114
|
+
state$3.push(current);
|
|
2115
|
+
process$4(current.event);
|
|
1616
2116
|
break;
|
|
1617
2117
|
}
|
|
1618
2118
|
}
|
|
1619
|
-
function process$
|
|
2119
|
+
function process$4(event) {
|
|
1620
2120
|
schedule$1(encode$3.bind(this, event));
|
|
1621
2121
|
}
|
|
1622
|
-
function reset$
|
|
1623
|
-
state$
|
|
2122
|
+
function reset$c() {
|
|
2123
|
+
state$3 = [];
|
|
1624
2124
|
}
|
|
1625
2125
|
function similar$1(last, current) {
|
|
1626
2126
|
var dx = last.data.x - current.data.x;
|
|
@@ -1630,16 +2130,16 @@ function similar$1(last, current) {
|
|
|
1630
2130
|
var match = current.data.target === last.data.target;
|
|
1631
2131
|
return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
|
|
1632
2132
|
}
|
|
1633
|
-
function stop$
|
|
2133
|
+
function stop$n() {
|
|
1634
2134
|
clearTimeout(timeout$4);
|
|
1635
2135
|
// Send out any pending pointer events in the pipeline
|
|
1636
|
-
if (state$
|
|
1637
|
-
process$
|
|
2136
|
+
if (state$3.length > 0) {
|
|
2137
|
+
process$4(state$3[state$3.length - 1].event);
|
|
1638
2138
|
}
|
|
1639
2139
|
}
|
|
1640
2140
|
|
|
1641
2141
|
var data$b;
|
|
1642
|
-
function start$
|
|
2142
|
+
function start$o() {
|
|
1643
2143
|
bind(window, "resize", recompute$5);
|
|
1644
2144
|
recompute$5();
|
|
1645
2145
|
}
|
|
@@ -1653,20 +2153,20 @@ function recompute$5() {
|
|
|
1653
2153
|
};
|
|
1654
2154
|
encode$3(11 /* Event.Resize */);
|
|
1655
2155
|
}
|
|
1656
|
-
function reset$
|
|
2156
|
+
function reset$b() {
|
|
1657
2157
|
data$b = null;
|
|
1658
2158
|
}
|
|
1659
|
-
function stop$
|
|
1660
|
-
reset$
|
|
2159
|
+
function stop$m() {
|
|
2160
|
+
reset$b();
|
|
1661
2161
|
}
|
|
1662
2162
|
|
|
1663
|
-
var state$
|
|
2163
|
+
var state$2 = [];
|
|
1664
2164
|
var timeout$3 = null;
|
|
1665
|
-
function start$
|
|
1666
|
-
state$
|
|
2165
|
+
function start$n() {
|
|
2166
|
+
state$2 = [];
|
|
1667
2167
|
recompute$4();
|
|
1668
2168
|
}
|
|
1669
|
-
function observe$
|
|
2169
|
+
function observe$6(root) {
|
|
1670
2170
|
var frame = iframe(root);
|
|
1671
2171
|
var node = frame ? frame.contentWindow : (root === document ? window : root);
|
|
1672
2172
|
bind(node, "scroll", recompute$4, true);
|
|
@@ -1692,19 +2192,19 @@ function recompute$4(event) {
|
|
|
1692
2192
|
if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
|
|
1693
2193
|
return;
|
|
1694
2194
|
}
|
|
1695
|
-
var length = state$
|
|
1696
|
-
var last = length > 1 ? state$
|
|
2195
|
+
var length = state$2.length;
|
|
2196
|
+
var last = length > 1 ? state$2[length - 2] : null;
|
|
1697
2197
|
if (last && similar(last, current)) {
|
|
1698
|
-
state$
|
|
2198
|
+
state$2.pop();
|
|
1699
2199
|
}
|
|
1700
|
-
state$
|
|
2200
|
+
state$2.push(current);
|
|
1701
2201
|
clearTimeout(timeout$3);
|
|
1702
|
-
timeout$3 = setTimeout(process$
|
|
2202
|
+
timeout$3 = setTimeout(process$3, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
|
|
1703
2203
|
}
|
|
1704
|
-
function reset$
|
|
1705
|
-
state$
|
|
2204
|
+
function reset$a() {
|
|
2205
|
+
state$2 = [];
|
|
1706
2206
|
}
|
|
1707
|
-
function process$
|
|
2207
|
+
function process$3(event) {
|
|
1708
2208
|
schedule$1(encode$3.bind(this, event));
|
|
1709
2209
|
}
|
|
1710
2210
|
function similar(last, current) {
|
|
@@ -1712,18 +2212,18 @@ function similar(last, current) {
|
|
|
1712
2212
|
var dy = last.data.y - current.data.y;
|
|
1713
2213
|
return (dx * dx + dy * dy < 20 /* Setting.Distance */ * 20 /* Setting.Distance */) && (current.time - last.time < 25 /* Setting.Interval */);
|
|
1714
2214
|
}
|
|
1715
|
-
function stop$
|
|
2215
|
+
function stop$l() {
|
|
1716
2216
|
clearTimeout(timeout$3);
|
|
1717
|
-
state$
|
|
2217
|
+
state$2 = [];
|
|
1718
2218
|
}
|
|
1719
2219
|
|
|
1720
2220
|
var data$a = null;
|
|
1721
2221
|
var previous = null;
|
|
1722
2222
|
var timeout$2 = null;
|
|
1723
|
-
function start$
|
|
1724
|
-
reset$
|
|
2223
|
+
function start$m() {
|
|
2224
|
+
reset$9();
|
|
1725
2225
|
}
|
|
1726
|
-
function observe$
|
|
2226
|
+
function observe$5(root) {
|
|
1727
2227
|
bind(root, "selectstart", recompute$3.bind(this, root), true);
|
|
1728
2228
|
bind(root, "selectionchange", recompute$3.bind(this, root), true);
|
|
1729
2229
|
}
|
|
@@ -1745,7 +2245,7 @@ function recompute$3(root) {
|
|
|
1745
2245
|
var startNode = data$a.start ? data$a.start : null;
|
|
1746
2246
|
if (previous !== null && data$a.start !== null && startNode !== current.anchorNode) {
|
|
1747
2247
|
clearTimeout(timeout$2);
|
|
1748
|
-
process$
|
|
2248
|
+
process$2(21 /* Event.Selection */);
|
|
1749
2249
|
}
|
|
1750
2250
|
data$a = {
|
|
1751
2251
|
start: current.anchorNode,
|
|
@@ -1755,40 +2255,40 @@ function recompute$3(root) {
|
|
|
1755
2255
|
};
|
|
1756
2256
|
previous = current;
|
|
1757
2257
|
clearTimeout(timeout$2);
|
|
1758
|
-
timeout$2 = setTimeout(process$
|
|
2258
|
+
timeout$2 = setTimeout(process$2, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
|
|
1759
2259
|
}
|
|
1760
|
-
function process$
|
|
2260
|
+
function process$2(event) {
|
|
1761
2261
|
schedule$1(encode$3.bind(this, event));
|
|
1762
2262
|
}
|
|
1763
|
-
function reset$
|
|
2263
|
+
function reset$9() {
|
|
1764
2264
|
previous = null;
|
|
1765
2265
|
data$a = { start: 0, startOffset: 0, end: 0, endOffset: 0 };
|
|
1766
2266
|
}
|
|
1767
|
-
function stop$
|
|
1768
|
-
reset$
|
|
2267
|
+
function stop$k() {
|
|
2268
|
+
reset$9();
|
|
1769
2269
|
clearTimeout(timeout$2);
|
|
1770
2270
|
}
|
|
1771
2271
|
|
|
1772
|
-
var state$
|
|
1773
|
-
function start$
|
|
1774
|
-
reset$
|
|
2272
|
+
var state$1 = [];
|
|
2273
|
+
function start$l() {
|
|
2274
|
+
reset$8();
|
|
1775
2275
|
}
|
|
1776
|
-
function observe$
|
|
2276
|
+
function observe$4(root) {
|
|
1777
2277
|
bind(root, "submit", recompute$2, true);
|
|
1778
2278
|
}
|
|
1779
2279
|
function recompute$2(evt) {
|
|
1780
|
-
state$
|
|
2280
|
+
state$1.push({ time: time(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
|
|
1781
2281
|
schedule$1(encode$3.bind(this, 39 /* Event.Submit */));
|
|
1782
2282
|
}
|
|
1783
|
-
function reset$
|
|
1784
|
-
state$
|
|
2283
|
+
function reset$8() {
|
|
2284
|
+
state$1 = [];
|
|
1785
2285
|
}
|
|
1786
|
-
function stop$
|
|
1787
|
-
reset$
|
|
2286
|
+
function stop$j() {
|
|
2287
|
+
reset$8();
|
|
1788
2288
|
}
|
|
1789
2289
|
|
|
1790
2290
|
var data$9;
|
|
1791
|
-
function start$
|
|
2291
|
+
function start$k() {
|
|
1792
2292
|
bind(window, "pagehide", recompute$1);
|
|
1793
2293
|
}
|
|
1794
2294
|
function recompute$1(evt) {
|
|
@@ -1796,15 +2296,15 @@ function recompute$1(evt) {
|
|
|
1796
2296
|
encode$3(26 /* Event.Unload */, time(evt));
|
|
1797
2297
|
stop();
|
|
1798
2298
|
}
|
|
1799
|
-
function reset$
|
|
2299
|
+
function reset$7() {
|
|
1800
2300
|
data$9 = null;
|
|
1801
2301
|
}
|
|
1802
|
-
function stop$
|
|
1803
|
-
reset$
|
|
2302
|
+
function stop$i() {
|
|
2303
|
+
reset$7();
|
|
1804
2304
|
}
|
|
1805
2305
|
|
|
1806
2306
|
var data$8;
|
|
1807
|
-
function start$
|
|
2307
|
+
function start$j() {
|
|
1808
2308
|
bind(document, "visibilitychange", recompute);
|
|
1809
2309
|
recompute();
|
|
1810
2310
|
}
|
|
@@ -1813,61 +2313,61 @@ function recompute(evt) {
|
|
|
1813
2313
|
data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
|
|
1814
2314
|
encode$3(28 /* Event.Visibility */, time(evt));
|
|
1815
2315
|
}
|
|
1816
|
-
function reset$
|
|
2316
|
+
function reset$6() {
|
|
1817
2317
|
data$8 = null;
|
|
1818
2318
|
}
|
|
1819
|
-
function stop$
|
|
1820
|
-
reset$
|
|
2319
|
+
function stop$h() {
|
|
2320
|
+
reset$6();
|
|
1821
2321
|
}
|
|
1822
2322
|
|
|
1823
|
-
function start$
|
|
2323
|
+
function start$i() {
|
|
1824
2324
|
start$g();
|
|
1825
|
-
start$u();
|
|
1826
|
-
start$t();
|
|
1827
|
-
start$r();
|
|
1828
2325
|
start$s();
|
|
1829
|
-
start$
|
|
1830
|
-
start$l();
|
|
2326
|
+
start$r();
|
|
1831
2327
|
start$p();
|
|
2328
|
+
start$q();
|
|
1832
2329
|
start$o();
|
|
1833
|
-
start$
|
|
2330
|
+
start$j();
|
|
1834
2331
|
start$n();
|
|
1835
2332
|
start$m();
|
|
2333
|
+
start$t();
|
|
2334
|
+
start$l();
|
|
2335
|
+
start$k();
|
|
1836
2336
|
}
|
|
1837
|
-
function stop$
|
|
2337
|
+
function stop$g() {
|
|
1838
2338
|
stop$e();
|
|
1839
|
-
stop$s();
|
|
1840
|
-
stop$r();
|
|
1841
|
-
stop$p();
|
|
1842
2339
|
stop$q();
|
|
1843
|
-
stop$
|
|
1844
|
-
stop$j();
|
|
2340
|
+
stop$p();
|
|
1845
2341
|
stop$n();
|
|
2342
|
+
stop$o();
|
|
1846
2343
|
stop$m();
|
|
1847
|
-
stop$
|
|
2344
|
+
stop$h();
|
|
1848
2345
|
stop$l();
|
|
1849
2346
|
stop$k();
|
|
2347
|
+
stop$r();
|
|
2348
|
+
stop$j();
|
|
2349
|
+
stop$i();
|
|
1850
2350
|
}
|
|
1851
|
-
function observe$
|
|
1852
|
-
observe$
|
|
2351
|
+
function observe$3(root) {
|
|
2352
|
+
observe$6(root);
|
|
1853
2353
|
// Only monitor following interactions if the root node is a document
|
|
1854
2354
|
// In case of shadow DOM, following events automatically bubble up to the parent document.
|
|
1855
2355
|
if (root.nodeType === Node.DOCUMENT_NODE) {
|
|
1856
|
-
observe$b(root);
|
|
1857
2356
|
observe$a(root);
|
|
1858
|
-
observe$8(root);
|
|
1859
2357
|
observe$9(root);
|
|
1860
|
-
observe$
|
|
1861
|
-
observe$
|
|
2358
|
+
observe$7(root);
|
|
2359
|
+
observe$8(root);
|
|
1862
2360
|
observe$5(root);
|
|
2361
|
+
observe$b(root);
|
|
2362
|
+
observe$4(root);
|
|
1863
2363
|
}
|
|
1864
2364
|
}
|
|
1865
2365
|
|
|
1866
2366
|
var interaction = /*#__PURE__*/Object.freeze({
|
|
1867
2367
|
__proto__: null,
|
|
1868
|
-
observe: observe$
|
|
1869
|
-
start: start$
|
|
1870
|
-
stop: stop$
|
|
2368
|
+
observe: observe$3,
|
|
2369
|
+
start: start$i,
|
|
2370
|
+
stop: stop$g
|
|
1871
2371
|
});
|
|
1872
2372
|
|
|
1873
2373
|
var digitsRegex = /[^0-9\.]/g;
|
|
@@ -1970,7 +2470,7 @@ function processNode (node, source) {
|
|
|
1970
2470
|
// later whenever there are new additions or modifications to DOM (mutations)
|
|
1971
2471
|
if (node === document)
|
|
1972
2472
|
parse$1(document);
|
|
1973
|
-
observe$
|
|
2473
|
+
observe$2(node);
|
|
1974
2474
|
break;
|
|
1975
2475
|
case Node.DOCUMENT_FRAGMENT_NODE:
|
|
1976
2476
|
var shadowRoot = node;
|
|
@@ -1978,7 +2478,7 @@ function processNode (node, source) {
|
|
|
1978
2478
|
parse$1(shadowRoot);
|
|
1979
2479
|
var type = typeof (shadowRoot.constructor);
|
|
1980
2480
|
if (type === "function" /* Constant.Function */ && shadowRoot.constructor.toString().indexOf("[native code]" /* Constant.NativeCode */) >= 0) {
|
|
1981
|
-
observe$
|
|
2481
|
+
observe$2(shadowRoot);
|
|
1982
2482
|
// See: https://wicg.github.io/construct-stylesheets/ for more details on adoptedStyleSheets.
|
|
1983
2483
|
// At the moment, we are only able to capture "open" shadow DOM nodes. If they are closed, they are not accessible.
|
|
1984
2484
|
// In future we may decide to proxy "attachShadow" call to gain access, but at the moment, we don't want to
|
|
@@ -2063,7 +2563,7 @@ function processNode (node, source) {
|
|
|
2063
2563
|
case "HEAD":
|
|
2064
2564
|
var head = { tag: tag, attributes: attributes };
|
|
2065
2565
|
var l = insideFrame && ((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.location) ? node.ownerDocument.location : location;
|
|
2066
|
-
head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.
|
|
2566
|
+
head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.host + l.pathname;
|
|
2067
2567
|
dom[call](node, parent, head, source);
|
|
2068
2568
|
break;
|
|
2069
2569
|
case "BASE":
|
|
@@ -2073,7 +2573,7 @@ function processNode (node, source) {
|
|
|
2073
2573
|
// We create "a" element so we can generate protocol and hostname for relative paths like "/path/"
|
|
2074
2574
|
var a = document.createElement("a");
|
|
2075
2575
|
a.href = attributes["href"];
|
|
2076
|
-
baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.
|
|
2576
|
+
baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.host + a.pathname;
|
|
2077
2577
|
}
|
|
2078
2578
|
break;
|
|
2079
2579
|
case "STYLE":
|
|
@@ -2098,931 +2598,400 @@ function processNode (node, source) {
|
|
|
2098
2598
|
child = element.shadowRoot;
|
|
2099
2599
|
}
|
|
2100
2600
|
dom[call](node, parent, data, source);
|
|
2101
|
-
break;
|
|
2102
|
-
}
|
|
2103
|
-
break;
|
|
2104
|
-
}
|
|
2105
|
-
return child;
|
|
2106
|
-
}
|
|
2107
|
-
function observe$3(root) {
|
|
2108
|
-
if (has(root)) {
|
|
2109
|
-
return;
|
|
2110
|
-
}
|
|
2111
|
-
observe$2(root); // Observe mutations for this root node
|
|
2112
|
-
observe$4(root); // Observe interactions for this root node
|
|
2113
|
-
}
|
|
2114
|
-
function getStyleValue(style) {
|
|
2115
|
-
// Call trim on the text content to ensure we do not process white spaces ( , \n, \r\n, \t, etc.)
|
|
2116
|
-
// Also, check if stylesheet has any data-* attribute, if so process rules instead of looking up text
|
|
2117
|
-
var value = style.textContent ? style.textContent.trim() : "" /* Constant.Empty */;
|
|
2118
|
-
var dataset = style.dataset ? Object.keys(style.dataset).length : 0;
|
|
2119
|
-
if (value.length === 0 || dataset > 0) {
|
|
2120
|
-
value = getCssRules(style.sheet);
|
|
2121
|
-
}
|
|
2122
|
-
return value;
|
|
2123
|
-
}
|
|
2124
|
-
function getCssRules(sheet) {
|
|
2125
|
-
var value = "" /* Constant.Empty */;
|
|
2126
|
-
var cssRules = null;
|
|
2127
|
-
// Firefox throws a SecurityError when trying to access cssRules of a stylesheet from a different domain
|
|
2128
|
-
try {
|
|
2129
|
-
cssRules = sheet ? sheet.cssRules : [];
|
|
2130
|
-
}
|
|
2131
|
-
catch (e) {
|
|
2132
|
-
log$1(1 /* Code.CssRules */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
2133
|
-
if (e && e.name !== "SecurityError") {
|
|
2134
|
-
throw e;
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
if (cssRules !== null) {
|
|
2138
|
-
for (var i = 0; i < cssRules.length; i++) {
|
|
2139
|
-
value += cssRules[i].cssText;
|
|
2140
|
-
}
|
|
2141
|
-
}
|
|
2142
|
-
return value;
|
|
2143
|
-
}
|
|
2144
|
-
function getAttributes(element) {
|
|
2145
|
-
var output = {};
|
|
2146
|
-
var attributes = element.attributes;
|
|
2147
|
-
if (attributes && attributes.length > 0) {
|
|
2148
|
-
for (var i = 0; i < attributes.length; i++) {
|
|
2149
|
-
var name_1 = attributes[i].name;
|
|
2150
|
-
if (IGNORE_ATTRIBUTES.indexOf(name_1) < 0) {
|
|
2151
|
-
output[name_1] = attributes[i].value;
|
|
2152
|
-
}
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
// For INPUT tags read the dynamic "value" property if an explicit "value" attribute is not set
|
|
2156
|
-
if (element.tagName === "INPUT" /* Constant.InputTag */ && !("value" /* Constant.Value */ in output) && element.value) {
|
|
2157
|
-
output["value" /* Constant.Value */] = element.value;
|
|
2158
|
-
}
|
|
2159
|
-
return output;
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2162
|
-
function traverse (root, timer, source) {
|
|
2163
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2164
|
-
var queue, node, next, state, subnode;
|
|
2165
|
-
return __generator(this, function (_a) {
|
|
2166
|
-
switch (_a.label) {
|
|
2167
|
-
case 0:
|
|
2168
|
-
queue = [root];
|
|
2169
|
-
_a.label = 1;
|
|
2170
|
-
case 1:
|
|
2171
|
-
if (!(queue.length > 0)) return [3 /*break*/, 4];
|
|
2172
|
-
node = queue.shift();
|
|
2173
|
-
next = node.firstChild;
|
|
2174
|
-
while (next) {
|
|
2175
|
-
queue.push(next);
|
|
2176
|
-
next = next.nextSibling;
|
|
2177
|
-
}
|
|
2178
|
-
state = state$9(timer);
|
|
2179
|
-
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
|
|
2180
|
-
return [4 /*yield*/, suspend$1(timer)];
|
|
2181
|
-
case 2:
|
|
2182
|
-
state = _a.sent();
|
|
2183
|
-
_a.label = 3;
|
|
2184
|
-
case 3:
|
|
2185
|
-
if (state === 2 /* Task.Stop */) {
|
|
2186
|
-
return [3 /*break*/, 4];
|
|
2187
|
-
}
|
|
2188
|
-
subnode = processNode(node, source);
|
|
2189
|
-
if (subnode) {
|
|
2190
|
-
queue.push(subnode);
|
|
2191
|
-
}
|
|
2192
|
-
return [3 /*break*/, 1];
|
|
2193
|
-
case 4: return [2 /*return*/];
|
|
2194
|
-
}
|
|
2195
|
-
});
|
|
2196
|
-
});
|
|
2197
|
-
}
|
|
2198
|
-
|
|
2199
|
-
var observers = [];
|
|
2200
|
-
var mutations = [];
|
|
2201
|
-
var insertRule = null;
|
|
2202
|
-
var deleteRule = null;
|
|
2203
|
-
var attachShadow = null;
|
|
2204
|
-
var queue$2 = [];
|
|
2205
|
-
var timeout$1 = null;
|
|
2206
|
-
var activePeriod = null;
|
|
2207
|
-
var history$4 = {};
|
|
2208
|
-
function start$j() {
|
|
2209
|
-
observers = [];
|
|
2210
|
-
queue$2 = [];
|
|
2211
|
-
timeout$1 = null;
|
|
2212
|
-
activePeriod = 0;
|
|
2213
|
-
history$4 = {};
|
|
2214
|
-
// Some popular open source libraries, like styled-components, optimize performance
|
|
2215
|
-
// by injecting CSS using insertRule API vs. appending text node. A side effect of
|
|
2216
|
-
// using javascript API is that it doesn't trigger DOM mutation and therefore we
|
|
2217
|
-
// need to override the insertRule API and listen for changes manually.
|
|
2218
|
-
if (insertRule === null) {
|
|
2219
|
-
insertRule = CSSStyleSheet.prototype.insertRule;
|
|
2220
|
-
CSSStyleSheet.prototype.insertRule = function () {
|
|
2221
|
-
if (active()) {
|
|
2222
|
-
schedule(this.ownerNode);
|
|
2223
|
-
}
|
|
2224
|
-
return insertRule.apply(this, arguments);
|
|
2225
|
-
};
|
|
2226
|
-
}
|
|
2227
|
-
if (deleteRule === null) {
|
|
2228
|
-
deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
2229
|
-
CSSStyleSheet.prototype.deleteRule = function () {
|
|
2230
|
-
if (active()) {
|
|
2231
|
-
schedule(this.ownerNode);
|
|
2232
|
-
}
|
|
2233
|
-
return deleteRule.apply(this, arguments);
|
|
2234
|
-
};
|
|
2235
|
-
}
|
|
2236
|
-
// Add a hook to attachShadow API calls
|
|
2237
|
-
// In case we are unable to add a hook and browser throws an exception,
|
|
2238
|
-
// reset attachShadow variable and resume processing like before
|
|
2239
|
-
if (attachShadow === null) {
|
|
2240
|
-
attachShadow = Element.prototype.attachShadow;
|
|
2241
|
-
try {
|
|
2242
|
-
Element.prototype.attachShadow = function () {
|
|
2243
|
-
if (active()) {
|
|
2244
|
-
return schedule(attachShadow.apply(this, arguments));
|
|
2245
|
-
}
|
|
2246
|
-
else {
|
|
2247
|
-
return attachShadow.apply(this, arguments);
|
|
2248
|
-
}
|
|
2249
|
-
};
|
|
2250
|
-
}
|
|
2251
|
-
catch (_a) {
|
|
2252
|
-
attachShadow = null;
|
|
2253
|
-
}
|
|
2254
|
-
}
|
|
2255
|
-
}
|
|
2256
|
-
function observe$2(node) {
|
|
2257
|
-
// Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
|
|
2258
|
-
// In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
|
|
2259
|
-
// For this reason, we need to wire up mutations every time we see a new shadow dom.
|
|
2260
|
-
// Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
|
|
2261
|
-
try {
|
|
2262
|
-
var m = api("MutationObserver" /* Constant.MutationObserver */);
|
|
2263
|
-
var observer = m in window ? new window[m](measure(handle$1)) : null;
|
|
2264
|
-
if (observer) {
|
|
2265
|
-
observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
|
|
2266
|
-
observers.push(observer);
|
|
2267
|
-
}
|
|
2268
|
-
}
|
|
2269
|
-
catch (e) {
|
|
2270
|
-
log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
function monitor(frame) {
|
|
2274
|
-
// Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
|
|
2275
|
-
// This includes cases where iframe location is updated without explicitly updating src attribute
|
|
2276
|
-
// E.g. iframe.contentWindow.location.href = "new-location";
|
|
2277
|
-
if (has(frame) === false) {
|
|
2278
|
-
bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
function stop$h() {
|
|
2282
|
-
for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) {
|
|
2283
|
-
var observer = observers_1[_i];
|
|
2284
|
-
if (observer) {
|
|
2285
|
-
observer.disconnect();
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
observers = [];
|
|
2289
|
-
history$4 = {};
|
|
2290
|
-
mutations = [];
|
|
2291
|
-
queue$2 = [];
|
|
2292
|
-
activePeriod = 0;
|
|
2293
|
-
timeout$1 = null;
|
|
2294
|
-
}
|
|
2295
|
-
function active$2() {
|
|
2296
|
-
activePeriod = time() + 3000 /* Setting.MutationActivePeriod */;
|
|
2297
|
-
}
|
|
2298
|
-
function handle$1(m) {
|
|
2299
|
-
// Queue up mutation records for asynchronous processing
|
|
2300
|
-
var now = time();
|
|
2301
|
-
track$6(6 /* Event.Mutation */, now);
|
|
2302
|
-
mutations.push({ time: now, mutations: m });
|
|
2303
|
-
schedule$1(process$2, 1 /* Priority.High */).then(function () {
|
|
2304
|
-
setTimeout(compute$7);
|
|
2305
|
-
measure(compute$6)();
|
|
2306
|
-
});
|
|
2307
|
-
}
|
|
2308
|
-
function process$2() {
|
|
2309
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2310
|
-
var timer, record, instance, _i, _a, mutation, state, target, type, value;
|
|
2311
|
-
return __generator(this, function (_b) {
|
|
2312
|
-
switch (_b.label) {
|
|
2313
|
-
case 0:
|
|
2314
|
-
timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
|
|
2315
|
-
start$x(timer);
|
|
2316
|
-
_b.label = 1;
|
|
2317
|
-
case 1:
|
|
2318
|
-
if (!(mutations.length > 0)) return [3 /*break*/, 8];
|
|
2319
|
-
record = mutations.shift();
|
|
2320
|
-
instance = time();
|
|
2321
|
-
_i = 0, _a = record.mutations;
|
|
2322
|
-
_b.label = 2;
|
|
2323
|
-
case 2:
|
|
2324
|
-
if (!(_i < _a.length)) return [3 /*break*/, 6];
|
|
2325
|
-
mutation = _a[_i];
|
|
2326
|
-
state = state$9(timer);
|
|
2327
|
-
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
|
|
2328
|
-
return [4 /*yield*/, suspend$1(timer)];
|
|
2329
|
-
case 3:
|
|
2330
|
-
state = _b.sent();
|
|
2331
|
-
_b.label = 4;
|
|
2332
|
-
case 4:
|
|
2333
|
-
if (state === 2 /* Task.Stop */) {
|
|
2334
|
-
return [3 /*break*/, 6];
|
|
2335
|
-
}
|
|
2336
|
-
target = mutation.target;
|
|
2337
|
-
type = track$5(mutation, timer, instance);
|
|
2338
|
-
if (type && target && target.ownerDocument) {
|
|
2339
|
-
parse$1(target.ownerDocument);
|
|
2340
|
-
}
|
|
2341
|
-
if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
|
|
2342
|
-
parse$1(target);
|
|
2343
|
-
}
|
|
2344
|
-
switch (type) {
|
|
2345
|
-
case "attributes" /* Constant.Attributes */:
|
|
2346
|
-
processNode(target, 3 /* Source.Attributes */);
|
|
2347
|
-
break;
|
|
2348
|
-
case "characterData" /* Constant.CharacterData */:
|
|
2349
|
-
processNode(target, 4 /* Source.CharacterData */);
|
|
2350
|
-
break;
|
|
2351
|
-
case "childList" /* Constant.ChildList */:
|
|
2352
|
-
processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer);
|
|
2353
|
-
processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer);
|
|
2354
|
-
break;
|
|
2355
|
-
case "suspend" /* Constant.Suspend */:
|
|
2356
|
-
value = get(target);
|
|
2357
|
-
if (value) {
|
|
2358
|
-
value.metadata.suspend = true;
|
|
2359
|
-
}
|
|
2360
|
-
break;
|
|
2361
|
-
}
|
|
2362
|
-
_b.label = 5;
|
|
2363
|
-
case 5:
|
|
2364
|
-
_i++;
|
|
2365
|
-
return [3 /*break*/, 2];
|
|
2366
|
-
case 6: return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
|
|
2367
|
-
case 7:
|
|
2368
|
-
_b.sent();
|
|
2369
|
-
return [3 /*break*/, 1];
|
|
2370
|
-
case 8:
|
|
2371
|
-
stop$u(timer);
|
|
2372
|
-
return [2 /*return*/];
|
|
2373
|
-
}
|
|
2374
|
-
});
|
|
2375
|
-
});
|
|
2376
|
-
}
|
|
2377
|
-
function track$5(m, timer, instance) {
|
|
2378
|
-
var value = m.target ? get(m.target.parentNode) : null;
|
|
2379
|
-
// Check if the parent is already discovered and that the parent is not the document root
|
|
2380
|
-
if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
|
|
2381
|
-
var inactive = time() > activePeriod;
|
|
2382
|
-
var target = get(m.target);
|
|
2383
|
-
var element = target && target.selector ? target.selector.join() : m.target.nodeName;
|
|
2384
|
-
var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
|
|
2385
|
-
// We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
|
|
2386
|
-
// repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
|
|
2387
|
-
// In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
|
|
2388
|
-
var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
|
|
2389
|
-
// Initialize an entry if it doesn't already exist
|
|
2390
|
-
history$4[key] = key in history$4 ? history$4[key] : [0, instance];
|
|
2391
|
-
var h = history$4[key];
|
|
2392
|
-
// Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
|
|
2393
|
-
if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
|
|
2394
|
-
processNodeList(h[2], 2 /* Source.ChildListRemove */, timer);
|
|
2395
|
-
}
|
|
2396
|
-
// Update the counter
|
|
2397
|
-
h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
|
|
2398
|
-
h[1] = instance;
|
|
2399
|
-
// Return updated mutation type based on if we have already hit the threshold or not
|
|
2400
|
-
if (h[0] === 10 /* Setting.MutationSuspendThreshold */) {
|
|
2401
|
-
// Store a reference to removedNodes so we can process them later
|
|
2402
|
-
// when we resume mutations again on user interactions
|
|
2403
|
-
h[2] = m.removedNodes;
|
|
2404
|
-
return "suspend" /* Constant.Suspend */;
|
|
2405
|
-
}
|
|
2406
|
-
else if (h[0] > 10 /* Setting.MutationSuspendThreshold */) {
|
|
2407
|
-
return "" /* Constant.Empty */;
|
|
2408
|
-
}
|
|
2409
|
-
}
|
|
2410
|
-
return m.type;
|
|
2411
|
-
}
|
|
2412
|
-
function names(nodes) {
|
|
2413
|
-
var output = [];
|
|
2414
|
-
for (var i = 0; nodes && i < nodes.length; i++) {
|
|
2415
|
-
output.push(nodes[i].nodeName);
|
|
2416
|
-
}
|
|
2417
|
-
return output.join();
|
|
2418
|
-
}
|
|
2419
|
-
function processNodeList(list, source, timer) {
|
|
2420
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2421
|
-
var length, i, state;
|
|
2422
|
-
return __generator(this, function (_a) {
|
|
2423
|
-
switch (_a.label) {
|
|
2424
|
-
case 0:
|
|
2425
|
-
length = list ? list.length : 0;
|
|
2426
|
-
i = 0;
|
|
2427
|
-
_a.label = 1;
|
|
2428
|
-
case 1:
|
|
2429
|
-
if (!(i < length)) return [3 /*break*/, 6];
|
|
2430
|
-
if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
|
|
2431
|
-
traverse(list[i], timer, source);
|
|
2432
|
-
return [3 /*break*/, 5];
|
|
2433
|
-
case 2:
|
|
2434
|
-
state = state$9(timer);
|
|
2435
|
-
if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
|
|
2436
|
-
return [4 /*yield*/, suspend$1(timer)];
|
|
2437
|
-
case 3:
|
|
2438
|
-
state = _a.sent();
|
|
2439
|
-
_a.label = 4;
|
|
2440
|
-
case 4:
|
|
2441
|
-
if (state === 2 /* Task.Stop */) {
|
|
2442
|
-
return [3 /*break*/, 6];
|
|
2443
|
-
}
|
|
2444
|
-
processNode(list[i], source);
|
|
2445
|
-
_a.label = 5;
|
|
2446
|
-
case 5:
|
|
2447
|
-
i++;
|
|
2448
|
-
return [3 /*break*/, 1];
|
|
2449
|
-
case 6: return [2 /*return*/];
|
|
2450
|
-
}
|
|
2451
|
-
});
|
|
2452
|
-
});
|
|
2453
|
-
}
|
|
2454
|
-
function schedule(node, fragment) {
|
|
2455
|
-
if (fragment === void 0) { fragment = false; }
|
|
2456
|
-
// Only schedule manual trigger for this node if it's not already in the queue
|
|
2457
|
-
if (queue$2.indexOf(node) < 0) {
|
|
2458
|
-
queue$2.push(node);
|
|
2459
|
-
}
|
|
2460
|
-
// Cancel any previous trigger before scheduling a new one.
|
|
2461
|
-
// It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
|
|
2462
|
-
// And in those cases we do not wish to monitor changes multiple times for the same node.
|
|
2463
|
-
if (timeout$1) {
|
|
2464
|
-
clearTimeout(timeout$1);
|
|
2465
|
-
}
|
|
2466
|
-
timeout$1 = setTimeout(function () { trigger$1(fragment); }, 33 /* Setting.LookAhead */);
|
|
2467
|
-
return node;
|
|
2468
|
-
}
|
|
2469
|
-
function trigger$1(fragment) {
|
|
2470
|
-
for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
|
|
2471
|
-
var node = queue_1[_i];
|
|
2472
|
-
// Generate a mutation for this node only if it still exists
|
|
2473
|
-
if (node) {
|
|
2474
|
-
var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
|
|
2475
|
-
// Skip re-processing shadowRoot if it was already discovered
|
|
2476
|
-
if (shadowRoot && has(node)) {
|
|
2477
|
-
continue;
|
|
2478
|
-
}
|
|
2479
|
-
generate(node, shadowRoot || fragment ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
|
|
2480
|
-
}
|
|
2481
|
-
}
|
|
2482
|
-
queue$2 = [];
|
|
2483
|
-
}
|
|
2484
|
-
function generate(target, type) {
|
|
2485
|
-
measure(handle$1)([{
|
|
2486
|
-
addedNodes: [target],
|
|
2487
|
-
attributeName: null,
|
|
2488
|
-
attributeNamespace: null,
|
|
2489
|
-
nextSibling: null,
|
|
2490
|
-
oldValue: null,
|
|
2491
|
-
previousSibling: null,
|
|
2492
|
-
removedNodes: [],
|
|
2493
|
-
target: target,
|
|
2494
|
-
type: type
|
|
2495
|
-
}]);
|
|
2496
|
-
}
|
|
2497
|
-
|
|
2498
|
-
var index = 1;
|
|
2499
|
-
var nodes = [];
|
|
2500
|
-
var values = [];
|
|
2501
|
-
var updateMap = [];
|
|
2502
|
-
var hashMap = {};
|
|
2503
|
-
var override = [];
|
|
2504
|
-
var unmask = [];
|
|
2505
|
-
var updatedFragments = {};
|
|
2506
|
-
var maskText = [];
|
|
2507
|
-
var maskExclude = [];
|
|
2508
|
-
var maskDisable = [];
|
|
2509
|
-
var maskTags = [];
|
|
2510
|
-
// The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
|
|
2511
|
-
var idMap = null; // Maps node => id.
|
|
2512
|
-
var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
|
|
2513
|
-
var privacyMap = null; // Maps node => Privacy (enum)
|
|
2514
|
-
var fraudMap = null; // Maps node => FraudId (number)
|
|
2515
|
-
function start$i() {
|
|
2516
|
-
reset$7();
|
|
2517
|
-
parse$1(document, true);
|
|
2518
|
-
}
|
|
2519
|
-
function stop$g() {
|
|
2520
|
-
reset$7();
|
|
2521
|
-
}
|
|
2522
|
-
function reset$7() {
|
|
2523
|
-
index = 1;
|
|
2524
|
-
nodes = [];
|
|
2525
|
-
values = [];
|
|
2526
|
-
updateMap = [];
|
|
2527
|
-
hashMap = {};
|
|
2528
|
-
override = [];
|
|
2529
|
-
unmask = [];
|
|
2530
|
-
maskText = "address,password,contact" /* Mask.Text */.split("," /* Constant.Comma */);
|
|
2531
|
-
maskExclude = "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.split("," /* Constant.Comma */);
|
|
2532
|
-
maskDisable = "radio,checkbox,range,button,reset,submit" /* Mask.Disable */.split("," /* Constant.Comma */);
|
|
2533
|
-
maskTags = "INPUT,SELECT,TEXTAREA" /* Mask.Tags */.split("," /* Constant.Comma */);
|
|
2534
|
-
idMap = new WeakMap();
|
|
2535
|
-
iframeMap = new WeakMap();
|
|
2536
|
-
privacyMap = new WeakMap();
|
|
2537
|
-
fraudMap = new WeakMap();
|
|
2538
|
-
reset$l();
|
|
2539
|
-
}
|
|
2540
|
-
// We parse new root nodes for any regions or masked nodes in the beginning (document) and
|
|
2541
|
-
// later whenever there are new additions or modifications to DOM (mutations)
|
|
2542
|
-
function parse$1(root, init) {
|
|
2543
|
-
if (init === void 0) { init = false; }
|
|
2544
|
-
// Wrap selectors in a try / catch block.
|
|
2545
|
-
// It's possible for script to receive invalid selectors, e.g. "'#id'" with extra quotes, and cause the code below to fail
|
|
2546
|
-
try {
|
|
2547
|
-
// Parse unmask configuration into separate query selectors and override tokens as part of initialization
|
|
2548
|
-
if (init) {
|
|
2549
|
-
config$1.unmask.forEach(function (x) { return x.indexOf("!" /* Constant.Bang */) < 0 ? unmask.push(x) : override.push(x.substr(1)); });
|
|
2550
|
-
}
|
|
2551
|
-
// Since mutations may happen on leaf nodes too, e.g. text nodes, which may not support all selector APIs.
|
|
2552
|
-
// We ensure that the root note supports querySelectorAll API before executing the code below to identify new regions.
|
|
2553
|
-
if ("querySelectorAll" in root) {
|
|
2554
|
-
config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "".concat(x[0])); }); }); // Regions
|
|
2555
|
-
config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
|
|
2556
|
-
config$1.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
|
|
2557
|
-
unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
|
|
2558
|
-
}
|
|
2559
|
-
}
|
|
2560
|
-
catch (e) {
|
|
2561
|
-
log$1(5 /* Code.Selector */, 1 /* Severity.Warning */, e ? e.name : null);
|
|
2601
|
+
break;
|
|
2602
|
+
}
|
|
2603
|
+
break;
|
|
2562
2604
|
}
|
|
2605
|
+
return child;
|
|
2563
2606
|
}
|
|
2564
|
-
function
|
|
2565
|
-
if (
|
|
2566
|
-
|
|
2567
|
-
return null;
|
|
2568
|
-
}
|
|
2569
|
-
var id = idMap.get(node);
|
|
2570
|
-
if (!id && autogen) {
|
|
2571
|
-
id = index++;
|
|
2572
|
-
idMap.set(node, id);
|
|
2607
|
+
function observe$2(root) {
|
|
2608
|
+
if (has(root)) {
|
|
2609
|
+
return;
|
|
2573
2610
|
}
|
|
2574
|
-
|
|
2611
|
+
observe$1(root); // Observe mutations for this root node
|
|
2612
|
+
observe$3(root); // Observe interactions for this root node
|
|
2575
2613
|
}
|
|
2576
|
-
function
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
var
|
|
2580
|
-
var
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
var fraudId = fraudMap.has(node) ? fraudMap.get(node) : null;
|
|
2584
|
-
var privacyId = config$1.content ? 1 /* Privacy.Sensitive */ : 3 /* Privacy.TextImage */;
|
|
2585
|
-
if (parentId >= 0 && values[parentId]) {
|
|
2586
|
-
parentValue = values[parentId];
|
|
2587
|
-
parentValue.children.push(id);
|
|
2588
|
-
regionId = regionId === null ? parentValue.region : regionId;
|
|
2589
|
-
fragmentId = parentValue.fragment;
|
|
2590
|
-
fraudId = fraudId === null ? parentValue.metadata.fraud : fraudId;
|
|
2591
|
-
privacyId = parentValue.metadata.privacy;
|
|
2592
|
-
}
|
|
2593
|
-
// If there's an explicit region attribute set on the element, use it to mark a region on the page
|
|
2594
|
-
if (data.attributes && "data-clarity-region" /* Constant.RegionData */ in data.attributes) {
|
|
2595
|
-
observe$1(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
|
|
2596
|
-
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);
|
|
2597
2621
|
}
|
|
2598
|
-
|
|
2599
|
-
values[id] = {
|
|
2600
|
-
id: id,
|
|
2601
|
-
parent: parentId,
|
|
2602
|
-
previous: previousId,
|
|
2603
|
-
children: [],
|
|
2604
|
-
data: data,
|
|
2605
|
-
selector: null,
|
|
2606
|
-
hash: null,
|
|
2607
|
-
region: regionId,
|
|
2608
|
-
metadata: { active: true, suspend: false, privacy: privacyId, position: null, fraud: fraudId, size: null },
|
|
2609
|
-
fragment: fragmentId,
|
|
2610
|
-
};
|
|
2611
|
-
privacy(node, values[id], parentValue);
|
|
2612
|
-
updateSelector(values[id]);
|
|
2613
|
-
size(values[id]);
|
|
2614
|
-
track$4(id, source, values[id].fragment);
|
|
2622
|
+
return value;
|
|
2615
2623
|
}
|
|
2616
|
-
function
|
|
2617
|
-
var
|
|
2618
|
-
var
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
changed = true;
|
|
2628
|
-
value.previous = previousId;
|
|
2629
|
-
}
|
|
2630
|
-
// Handle case where parent might have been updated
|
|
2631
|
-
if (value.parent !== parentId) {
|
|
2632
|
-
changed = true;
|
|
2633
|
-
var oldParentId = value.parent;
|
|
2634
|
-
value.parent = parentId;
|
|
2635
|
-
// Move this node to the right location under new parent
|
|
2636
|
-
if (parentId !== null && parentId >= 0) {
|
|
2637
|
-
var childIndex = previousId === null ? 0 : values[parentId].children.indexOf(previousId) + 1;
|
|
2638
|
-
values[parentId].children.splice(childIndex, 0, id);
|
|
2639
|
-
// Update region after the move
|
|
2640
|
-
value.region = exists(node) ? id : values[parentId].region;
|
|
2641
|
-
}
|
|
2642
|
-
else {
|
|
2643
|
-
// Mark this element as deleted if the parent has been updated to null
|
|
2644
|
-
remove(id, source);
|
|
2645
|
-
}
|
|
2646
|
-
// Remove reference to this node from the old parent
|
|
2647
|
-
if (oldParentId !== null && oldParentId >= 0) {
|
|
2648
|
-
var nodeIndex = values[oldParentId].children.indexOf(id);
|
|
2649
|
-
if (nodeIndex >= 0) {
|
|
2650
|
-
values[oldParentId].children.splice(nodeIndex, 1);
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
parentChanged = true;
|
|
2654
|
-
}
|
|
2655
|
-
// Update data
|
|
2656
|
-
for (var key in data) {
|
|
2657
|
-
if (diff(value["data"], data, key)) {
|
|
2658
|
-
changed = true;
|
|
2659
|
-
value["data"][key] = data[key];
|
|
2660
|
-
}
|
|
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;
|
|
2661
2635
|
}
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2636
|
+
}
|
|
2637
|
+
if (cssRules !== null) {
|
|
2638
|
+
for (var i = 0; i < cssRules.length; i++) {
|
|
2639
|
+
value += cssRules[i].cssText;
|
|
2665
2640
|
}
|
|
2666
|
-
// Update selector
|
|
2667
|
-
updateSelector(value);
|
|
2668
|
-
track$4(id, source, values[id].fragment, changed, parentChanged);
|
|
2669
2641
|
}
|
|
2642
|
+
return value;
|
|
2670
2643
|
}
|
|
2671
|
-
function
|
|
2672
|
-
var output =
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
var doc = frame.contentDocument;
|
|
2680
|
-
if (doc) {
|
|
2681
|
-
iframeMap.set(frame.contentDocument, frame);
|
|
2682
|
-
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;
|
|
2683
2652
|
}
|
|
2684
2653
|
}
|
|
2685
|
-
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
2686
2654
|
}
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
|
|
2691
|
-
return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
|
|
2692
|
-
}
|
|
2693
|
-
function privacy(node, value, parent) {
|
|
2694
|
-
var data = value.data;
|
|
2695
|
-
var metadata = value.metadata;
|
|
2696
|
-
var current = metadata.privacy;
|
|
2697
|
-
var attributes = data.attributes || {};
|
|
2698
|
-
var tag = data.tag.toUpperCase();
|
|
2699
|
-
switch (true) {
|
|
2700
|
-
case maskTags.indexOf(tag) >= 0:
|
|
2701
|
-
var type = attributes["type" /* Constant.Type */];
|
|
2702
|
-
var meta_1 = "" /* Constant.Empty */;
|
|
2703
|
-
Object.keys(attributes).forEach(function (x) { return meta_1 += attributes[x].toLowerCase(); });
|
|
2704
|
-
var exclude = maskExclude.some(function (x) { return meta_1.indexOf(x) >= 0; });
|
|
2705
|
-
// Regardless of privacy mode, always mask off user input from input boxes or drop downs with two exceptions:
|
|
2706
|
-
// (1) The node is detected to be one of the excluded fields, in which case we drop everything
|
|
2707
|
-
// (2) The node's type is one of the allowed types (like checkboxes)
|
|
2708
|
-
metadata.privacy = tag === "INPUT" /* Constant.InputTag */ && maskDisable.indexOf(type) >= 0 ? current : (exclude ? 4 /* Privacy.Exclude */ : 2 /* Privacy.Text */);
|
|
2709
|
-
break;
|
|
2710
|
-
case "data-clarity-mask" /* Constant.MaskData */ in attributes:
|
|
2711
|
-
metadata.privacy = 3 /* Privacy.TextImage */;
|
|
2712
|
-
break;
|
|
2713
|
-
case "data-clarity-unmask" /* Constant.UnmaskData */ in attributes:
|
|
2714
|
-
metadata.privacy = 0 /* Privacy.None */;
|
|
2715
|
-
break;
|
|
2716
|
-
case privacyMap.has(node):
|
|
2717
|
-
// If this node was explicitly configured to contain sensitive content, honor that privacy setting
|
|
2718
|
-
metadata.privacy = privacyMap.get(node);
|
|
2719
|
-
break;
|
|
2720
|
-
case fraudMap.has(node):
|
|
2721
|
-
// If this node was explicitly configured to be evaluated for fraud, then also mask content
|
|
2722
|
-
metadata.privacy = 2 /* Privacy.Text */;
|
|
2723
|
-
break;
|
|
2724
|
-
case tag === "*T" /* Constant.TextTag */:
|
|
2725
|
-
// If it's a text node belonging to a STYLE or TITLE tag or one of scrub exceptions, then capture content
|
|
2726
|
-
var pTag = parent && parent.data ? parent.data.tag : "" /* Constant.Empty */;
|
|
2727
|
-
var pSelector_1 = parent && parent.selector ? parent.selector[1 /* Selector.Default */] : "" /* Constant.Empty */;
|
|
2728
|
-
var tags = ["STYLE" /* Constant.StyleTag */, "TITLE" /* Constant.TitleTag */, "svg:style" /* Constant.SvgStyle */];
|
|
2729
|
-
metadata.privacy = tags.includes(pTag) || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* Privacy.None */ : current;
|
|
2730
|
-
break;
|
|
2731
|
-
case current === 1 /* Privacy.Sensitive */:
|
|
2732
|
-
// In a mode where we mask sensitive information by default, look through class names to aggressively mask content
|
|
2733
|
-
metadata.privacy = inspect(attributes["class" /* Constant.Class */], maskText, metadata);
|
|
2734
|
-
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;
|
|
2735
2658
|
}
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
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
|
+
};
|
|
2740
2726
|
}
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
function
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
if (a[field][key] !== b[field][key]) {
|
|
2747
|
-
return true;
|
|
2727
|
+
if (deleteRule === null) {
|
|
2728
|
+
deleteRule = CSSStyleSheet.prototype.deleteRule;
|
|
2729
|
+
CSSStyleSheet.prototype.deleteRule = function () {
|
|
2730
|
+
if (active()) {
|
|
2731
|
+
schedule(this.ownerNode);
|
|
2748
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
|
+
};
|
|
2749
2750
|
}
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
return true;
|
|
2753
|
-
}
|
|
2751
|
+
catch (_a) {
|
|
2752
|
+
attachShadow = null;
|
|
2754
2753
|
}
|
|
2755
|
-
return false;
|
|
2756
2754
|
}
|
|
2757
|
-
return a[field] !== b[field];
|
|
2758
2755
|
}
|
|
2759
|
-
function
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
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);
|
|
2767
2767
|
}
|
|
2768
2768
|
}
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
function updateSelector(value) {
|
|
2772
|
-
var parent = value.parent && value.parent in values ? values[value.parent] : null;
|
|
2773
|
-
var prefix = parent ? parent.selector : null;
|
|
2774
|
-
var d = value.data;
|
|
2775
|
-
var p = position(parent, value);
|
|
2776
|
-
var s = { id: value.id, tag: d.tag, prefix: prefix, position: p, attributes: d.attributes };
|
|
2777
|
-
value.selector = [get$1(s, 0 /* Selector.Alpha */), get$1(s, 1 /* Selector.Beta */)];
|
|
2778
|
-
value.hash = value.selector.map(function (x) { return x ? hash(x) : null; });
|
|
2779
|
-
value.hash.forEach(function (h) { return hashMap[h] = value.id; });
|
|
2780
|
-
// Match fragment configuration against both alpha and beta hash
|
|
2781
|
-
if (value.hash.some(function (h) { return fragments.indexOf(h) !== -1; })) {
|
|
2782
|
-
value.fragment = value.id;
|
|
2783
|
-
}
|
|
2784
|
-
}
|
|
2785
|
-
function hashText(hash) {
|
|
2786
|
-
var id = lookup(hash);
|
|
2787
|
-
var node = getNode(id);
|
|
2788
|
-
return node !== null && node.textContent !== null ? node.textContent.substr(0, 25 /* Setting.ClickText */) : '';
|
|
2789
|
-
}
|
|
2790
|
-
function getNode(id) {
|
|
2791
|
-
if (id in nodes) {
|
|
2792
|
-
return nodes[id];
|
|
2769
|
+
catch (e) {
|
|
2770
|
+
log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
|
|
2793
2771
|
}
|
|
2794
|
-
return null;
|
|
2795
2772
|
}
|
|
2796
|
-
function
|
|
2797
|
-
|
|
2798
|
-
|
|
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);
|
|
2799
2779
|
}
|
|
2800
|
-
return null;
|
|
2801
2780
|
}
|
|
2802
|
-
function
|
|
2803
|
-
var
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
return hash in hashMap ? hashMap[hash] : null;
|
|
2808
|
-
}
|
|
2809
|
-
function has(node) {
|
|
2810
|
-
return getId(node) in nodes;
|
|
2811
|
-
}
|
|
2812
|
-
function updates$2() {
|
|
2813
|
-
var output = [];
|
|
2814
|
-
for (var _i = 0, updateMap_1 = updateMap; _i < updateMap_1.length; _i++) {
|
|
2815
|
-
var id = updateMap_1[_i];
|
|
2816
|
-
if (id in values) {
|
|
2817
|
-
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();
|
|
2818
2786
|
}
|
|
2819
2787
|
}
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
}
|
|
2827
|
-
function remove(id, source) {
|
|
2828
|
-
if (id in values) {
|
|
2829
|
-
var value = values[id];
|
|
2830
|
-
value.metadata.active = false;
|
|
2831
|
-
value.parent = null;
|
|
2832
|
-
track$4(id, source);
|
|
2833
|
-
}
|
|
2834
|
-
}
|
|
2835
|
-
function size(value) {
|
|
2836
|
-
// If this element is a image node, and is masked, then track box model for the current element
|
|
2837
|
-
if (value.data.tag === "IMG" /* Constant.ImageTag */ && value.metadata.privacy === 3 /* Privacy.TextImage */) {
|
|
2838
|
-
value.metadata.size = [];
|
|
2839
|
-
}
|
|
2788
|
+
observers = [];
|
|
2789
|
+
history$4 = {};
|
|
2790
|
+
mutations = [];
|
|
2791
|
+
queue$1 = [];
|
|
2792
|
+
activePeriod = 0;
|
|
2793
|
+
timeout$1 = null;
|
|
2840
2794
|
}
|
|
2841
|
-
function
|
|
2842
|
-
|
|
2843
|
-
// Some nodes may not have an ID by design since Clarity skips over tags like SCRIPT, NOSCRIPT, META, COMMENTS, etc..
|
|
2844
|
-
// 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.
|
|
2845
|
-
while (id === null && node.previousSibling) {
|
|
2846
|
-
id = getId(node.previousSibling);
|
|
2847
|
-
node = node.previousSibling;
|
|
2848
|
-
}
|
|
2849
|
-
return id;
|
|
2795
|
+
function active$2() {
|
|
2796
|
+
activePeriod = time() + 3000 /* Setting.MutationActivePeriod */;
|
|
2850
2797
|
}
|
|
2851
|
-
function
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
schedule(node, true);
|
|
2861
|
-
value.hash.forEach(function (h) {
|
|
2862
|
-
if (fragments.indexOf(h) !== -1) {
|
|
2863
|
-
updatedFragments[fragment] = h;
|
|
2864
|
-
}
|
|
2865
|
-
});
|
|
2866
|
-
}
|
|
2867
|
-
}
|
|
2868
|
-
// Keep track of the order in which mutations happened, they may not be sequential
|
|
2869
|
-
// Edge case: If an element is added later on, and pre-discovered element is moved as a child.
|
|
2870
|
-
// In that case, we need to reorder the pre-discovered element in the update list to keep visualization consistent.
|
|
2871
|
-
var uIndex = updateMap.indexOf(id);
|
|
2872
|
-
if (uIndex >= 0 && source === 1 /* Source.ChildListAdd */ && parentChanged) {
|
|
2873
|
-
updateMap.splice(uIndex, 1);
|
|
2874
|
-
updateMap.push(id);
|
|
2875
|
-
}
|
|
2876
|
-
else if (uIndex === -1 && changed) {
|
|
2877
|
-
updateMap.push(id);
|
|
2878
|
-
}
|
|
2879
|
-
}
|
|
2880
|
-
|
|
2881
|
-
var state$1 = [];
|
|
2882
|
-
var regionMap = null; // Maps region nodes => region name
|
|
2883
|
-
var regions = {};
|
|
2884
|
-
var queue$1 = [];
|
|
2885
|
-
var watch = false;
|
|
2886
|
-
var observer$1 = null;
|
|
2887
|
-
function start$h() {
|
|
2888
|
-
reset$6();
|
|
2889
|
-
observer$1 = null;
|
|
2890
|
-
regionMap = new WeakMap();
|
|
2891
|
-
regions = {};
|
|
2892
|
-
queue$1 = [];
|
|
2893
|
-
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
|
+
});
|
|
2894
2807
|
}
|
|
2895
|
-
function
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
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 */;
|
|
2907
2908
|
}
|
|
2908
2909
|
}
|
|
2910
|
+
return m.type;
|
|
2909
2911
|
}
|
|
2910
|
-
function
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
return regionMap && regionMap.has(node);
|
|
2915
|
-
}
|
|
2916
|
-
function track$3(id, event) {
|
|
2917
|
-
var node = getNode(id);
|
|
2918
|
-
var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
|
|
2919
|
-
// Determine the interaction state based on incoming event
|
|
2920
|
-
var interaction = 16 /* InteractionState.None */;
|
|
2921
|
-
switch (event) {
|
|
2922
|
-
case 9 /* Event.Click */:
|
|
2923
|
-
interaction = 20 /* InteractionState.Clicked */;
|
|
2924
|
-
break;
|
|
2925
|
-
case 27 /* Event.Input */:
|
|
2926
|
-
interaction = 30 /* InteractionState.Input */;
|
|
2927
|
-
break;
|
|
2912
|
+
function names(nodes) {
|
|
2913
|
+
var output = [];
|
|
2914
|
+
for (var i = 0; nodes && i < nodes.length; i++) {
|
|
2915
|
+
output.push(nodes[i].nodeName);
|
|
2928
2916
|
}
|
|
2929
|
-
|
|
2930
|
-
process$1(node, data, interaction, data.visibility);
|
|
2917
|
+
return output.join();
|
|
2931
2918
|
}
|
|
2932
|
-
function
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
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*/];
|
|
2948
2950
|
}
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
queue$1 = q;
|
|
2952
|
-
// Schedule encode only when we have at least one valid data entry
|
|
2953
|
-
if (state$1.length > 0) {
|
|
2954
|
-
encode$4(7 /* Event.Region */);
|
|
2955
|
-
}
|
|
2951
|
+
});
|
|
2952
|
+
});
|
|
2956
2953
|
}
|
|
2957
|
-
function
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
var rect = entry.boundingClientRect;
|
|
2962
|
-
var overlap = entry.intersectionRect;
|
|
2963
|
-
var viewport = entry.rootBounds;
|
|
2964
|
-
// Only capture regions that have non-zero width or height to avoid tracking and sending regions
|
|
2965
|
-
// that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
|
|
2966
|
-
// like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
|
|
2967
|
-
// 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
|
|
2968
|
-
if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
|
|
2969
|
-
var id = target ? getId(target) : null;
|
|
2970
|
-
var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
|
|
2971
|
-
// For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
|
|
2972
|
-
// However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
|
|
2973
|
-
var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
|
|
2974
|
-
var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
|
|
2975
|
-
// If an element is either visible or was visible and has been scrolled to the end
|
|
2976
|
-
// 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.
|
|
2977
|
-
// 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
|
|
2978
|
-
var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
|
|
2979
|
-
// Process updates to this region, if applicable
|
|
2980
|
-
process$1(target, data, data.interaction, (scrolledToEnd ?
|
|
2981
|
-
13 /* RegionVisibility.ScrolledToEnd */ :
|
|
2982
|
-
(visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
|
|
2983
|
-
// Stop observing this element now that we have already received scrolled signal
|
|
2984
|
-
if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
|
|
2985
|
-
observer$1.unobserve(target);
|
|
2986
|
-
}
|
|
2987
|
-
}
|
|
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);
|
|
2988
2958
|
}
|
|
2989
|
-
|
|
2990
|
-
|
|
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);
|
|
2991
2964
|
}
|
|
2965
|
+
timeout$1 = setTimeout(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
|
|
2966
|
+
return node;
|
|
2992
2967
|
}
|
|
2993
|
-
function
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
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 */);
|
|
3004
2979
|
}
|
|
3005
2980
|
}
|
|
3006
|
-
else {
|
|
3007
|
-
queue$1.push({ node: n, data: d });
|
|
3008
|
-
}
|
|
3009
|
-
}
|
|
3010
|
-
function clone$1(r) {
|
|
3011
|
-
return { time: time(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
|
|
3012
|
-
}
|
|
3013
|
-
function reset$6() {
|
|
3014
|
-
state$1 = [];
|
|
3015
|
-
}
|
|
3016
|
-
function stop$f() {
|
|
3017
|
-
reset$6();
|
|
3018
|
-
regionMap = null;
|
|
3019
|
-
regions = {};
|
|
3020
2981
|
queue$1 = [];
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
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
|
+
}]);
|
|
3026
2995
|
}
|
|
3027
2996
|
|
|
3028
2997
|
function target(evt) {
|
|
@@ -3055,7 +3024,7 @@ function metadata$2(node, event, text) {
|
|
|
3055
3024
|
output.hash = value.hash;
|
|
3056
3025
|
output.privacy = metadata_1.privacy;
|
|
3057
3026
|
if (value.region) {
|
|
3058
|
-
track$
|
|
3027
|
+
track$4(value.region, event);
|
|
3059
3028
|
}
|
|
3060
3029
|
if (metadata_1.fraud) {
|
|
3061
3030
|
check$4(metadata_1.fraud, value.id, text || value.data.value);
|
|
@@ -3082,7 +3051,7 @@ function encode$3 (type, ts) {
|
|
|
3082
3051
|
case 18 /* Event.TouchEnd */:
|
|
3083
3052
|
case 19 /* Event.TouchMove */:
|
|
3084
3053
|
case 20 /* Event.TouchCancel */:
|
|
3085
|
-
for (_i = 0, _a = state$
|
|
3054
|
+
for (_i = 0, _a = state$3; _i < _a.length; _i++) {
|
|
3086
3055
|
entry = _a[_i];
|
|
3087
3056
|
pTarget = metadata$2(entry.data.target, entry.event);
|
|
3088
3057
|
if (pTarget.id > 0) {
|
|
@@ -3094,10 +3063,10 @@ function encode$3 (type, ts) {
|
|
|
3094
3063
|
track$7(entry.event, entry.data.x, entry.data.y);
|
|
3095
3064
|
}
|
|
3096
3065
|
}
|
|
3097
|
-
reset$
|
|
3066
|
+
reset$c();
|
|
3098
3067
|
break;
|
|
3099
3068
|
case 9 /* Event.Click */:
|
|
3100
|
-
for (_b = 0, _c = state$
|
|
3069
|
+
for (_b = 0, _c = state$6; _b < _c.length; _b++) {
|
|
3101
3070
|
entry = _c[_b];
|
|
3102
3071
|
cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
|
|
3103
3072
|
tokens = [entry.time, entry.event];
|
|
@@ -3117,10 +3086,10 @@ function encode$3 (type, ts) {
|
|
|
3117
3086
|
queue(tokens);
|
|
3118
3087
|
track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
|
|
3119
3088
|
}
|
|
3120
|
-
reset$
|
|
3089
|
+
reset$f();
|
|
3121
3090
|
break;
|
|
3122
3091
|
case 38 /* Event.Clipboard */:
|
|
3123
|
-
for (_d = 0, _e = state$
|
|
3092
|
+
for (_d = 0, _e = state$5; _d < _e.length; _d++) {
|
|
3124
3093
|
entry = _e[_d];
|
|
3125
3094
|
tokens = [entry.time, entry.event];
|
|
3126
3095
|
target = metadata$2(entry.data.target, entry.event);
|
|
@@ -3130,24 +3099,24 @@ function encode$3 (type, ts) {
|
|
|
3130
3099
|
queue(tokens);
|
|
3131
3100
|
}
|
|
3132
3101
|
}
|
|
3133
|
-
reset$
|
|
3102
|
+
reset$e();
|
|
3134
3103
|
break;
|
|
3135
3104
|
case 11 /* Event.Resize */:
|
|
3136
3105
|
r = data$b;
|
|
3137
3106
|
tokens.push(r.width);
|
|
3138
3107
|
tokens.push(r.height);
|
|
3139
3108
|
track$7(type, r.width, r.height);
|
|
3140
|
-
reset$
|
|
3109
|
+
reset$b();
|
|
3141
3110
|
queue(tokens);
|
|
3142
3111
|
break;
|
|
3143
3112
|
case 26 /* Event.Unload */:
|
|
3144
3113
|
u = data$9;
|
|
3145
3114
|
tokens.push(u.name);
|
|
3146
|
-
reset$
|
|
3115
|
+
reset$7();
|
|
3147
3116
|
queue(tokens);
|
|
3148
3117
|
break;
|
|
3149
3118
|
case 27 /* Event.Input */:
|
|
3150
|
-
for (_f = 0, _g = state$
|
|
3119
|
+
for (_f = 0, _g = state$4; _f < _g.length; _f++) {
|
|
3151
3120
|
entry = _g[_f];
|
|
3152
3121
|
iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
|
|
3153
3122
|
tokens = [entry.time, entry.event];
|
|
@@ -3155,7 +3124,7 @@ function encode$3 (type, ts) {
|
|
|
3155
3124
|
tokens.push(text$1(entry.data.value, "input", iTarget.privacy));
|
|
3156
3125
|
queue(tokens);
|
|
3157
3126
|
}
|
|
3158
|
-
reset$
|
|
3127
|
+
reset$d();
|
|
3159
3128
|
break;
|
|
3160
3129
|
case 21 /* Event.Selection */:
|
|
3161
3130
|
s = data$a;
|
|
@@ -3166,12 +3135,12 @@ function encode$3 (type, ts) {
|
|
|
3166
3135
|
tokens.push(s.startOffset);
|
|
3167
3136
|
tokens.push(endTarget.id);
|
|
3168
3137
|
tokens.push(s.endOffset);
|
|
3169
|
-
reset$
|
|
3138
|
+
reset$9();
|
|
3170
3139
|
queue(tokens);
|
|
3171
3140
|
}
|
|
3172
3141
|
break;
|
|
3173
3142
|
case 10 /* Event.Scroll */:
|
|
3174
|
-
for (_h = 0, _j = state$
|
|
3143
|
+
for (_h = 0, _j = state$2; _h < _j.length; _h++) {
|
|
3175
3144
|
entry = _j[_h];
|
|
3176
3145
|
sTarget = metadata$2(entry.data.target, entry.event);
|
|
3177
3146
|
if (sTarget.id > 0) {
|
|
@@ -3183,10 +3152,10 @@ function encode$3 (type, ts) {
|
|
|
3183
3152
|
track$7(entry.event, entry.data.x, entry.data.y);
|
|
3184
3153
|
}
|
|
3185
3154
|
}
|
|
3186
|
-
reset$
|
|
3155
|
+
reset$a();
|
|
3187
3156
|
break;
|
|
3188
3157
|
case 42 /* Event.Change */:
|
|
3189
|
-
for (_k = 0, _l = state$
|
|
3158
|
+
for (_k = 0, _l = state$7; _k < _l.length; _k++) {
|
|
3190
3159
|
entry = _l[_k];
|
|
3191
3160
|
tokens = [entry.time, entry.event];
|
|
3192
3161
|
target = metadata$2(entry.data.target, entry.event);
|
|
@@ -3199,10 +3168,10 @@ function encode$3 (type, ts) {
|
|
|
3199
3168
|
queue(tokens);
|
|
3200
3169
|
}
|
|
3201
3170
|
}
|
|
3202
|
-
reset$
|
|
3171
|
+
reset$g();
|
|
3203
3172
|
break;
|
|
3204
3173
|
case 39 /* Event.Submit */:
|
|
3205
|
-
for (_m = 0, _o = state$
|
|
3174
|
+
for (_m = 0, _o = state$1; _m < _o.length; _m++) {
|
|
3206
3175
|
entry = _o[_m];
|
|
3207
3176
|
tokens = [entry.time, entry.event];
|
|
3208
3177
|
target = metadata$2(entry.data.target, entry.event);
|
|
@@ -3211,7 +3180,7 @@ function encode$3 (type, ts) {
|
|
|
3211
3180
|
queue(tokens);
|
|
3212
3181
|
}
|
|
3213
3182
|
}
|
|
3214
|
-
reset$
|
|
3183
|
+
reset$8();
|
|
3215
3184
|
break;
|
|
3216
3185
|
case 22 /* Event.Timeline */:
|
|
3217
3186
|
for (_p = 0, _q = updates$1; _p < _q.length; _p++) {
|
|
@@ -3232,7 +3201,7 @@ function encode$3 (type, ts) {
|
|
|
3232
3201
|
tokens.push(v.visible);
|
|
3233
3202
|
queue(tokens);
|
|
3234
3203
|
visibility(t, v.visible);
|
|
3235
|
-
reset$
|
|
3204
|
+
reset$6();
|
|
3236
3205
|
break;
|
|
3237
3206
|
}
|
|
3238
3207
|
return [2 /*return*/];
|
|
@@ -3416,7 +3385,7 @@ function send(payload, zipped, sequence, beacon) {
|
|
|
3416
3385
|
if (beacon === void 0) { beacon = false; }
|
|
3417
3386
|
// Upload data if a valid URL is defined in the config
|
|
3418
3387
|
if (typeof config$1.upload === "string" /* Constant.String */) {
|
|
3419
|
-
var
|
|
3388
|
+
var url_1 = config$1.upload;
|
|
3420
3389
|
var dispatched = false;
|
|
3421
3390
|
// If it's the last payload, attempt to upload using sendBeacon first.
|
|
3422
3391
|
// The advantage to using sendBeacon is that browser can decide to upload asynchronously, improving chances of success
|
|
@@ -3425,7 +3394,7 @@ function send(payload, zipped, sequence, beacon) {
|
|
|
3425
3394
|
if (beacon && "sendBeacon" in navigator) {
|
|
3426
3395
|
try {
|
|
3427
3396
|
// Navigator needs to be bound to sendBeacon before it is used to avoid errors in some browsers
|
|
3428
|
-
dispatched = navigator.sendBeacon.bind(navigator)(
|
|
3397
|
+
dispatched = navigator.sendBeacon.bind(navigator)(url_1, payload);
|
|
3429
3398
|
if (dispatched) {
|
|
3430
3399
|
done(sequence);
|
|
3431
3400
|
}
|
|
@@ -3447,7 +3416,9 @@ function send(payload, zipped, sequence, beacon) {
|
|
|
3447
3416
|
transit[sequence] = { data: payload, attempts: 1 };
|
|
3448
3417
|
}
|
|
3449
3418
|
var xhr_1 = new XMLHttpRequest();
|
|
3450
|
-
xhr_1.open("POST",
|
|
3419
|
+
xhr_1.open("POST", url_1, true);
|
|
3420
|
+
xhr_1.timeout = 15000 /* Setting.UploadTimeout */;
|
|
3421
|
+
xhr_1.ontimeout = function () { report(new Error("".concat("Timeout" /* Constant.Timeout */, " : ").concat(url_1))); };
|
|
3451
3422
|
if (sequence !== null) {
|
|
3452
3423
|
xhr_1.onreadystatechange = function () { measure(check$3)(xhr_1, sequence); };
|
|
3453
3424
|
}
|
|
@@ -3533,22 +3504,31 @@ function delay() {
|
|
|
3533
3504
|
return typeof config$1.upload === "string" /* Constant.String */ ? Math.max(Math.min(gap, 30000 /* Setting.MaxUploadDelay */), 100 /* Setting.MinUploadDelay */) : config$1.delay;
|
|
3534
3505
|
}
|
|
3535
3506
|
function response(payload) {
|
|
3536
|
-
var
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3507
|
+
var lines = payload && payload.length > 0 ? payload.split("\n") : [];
|
|
3508
|
+
for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
|
|
3509
|
+
var line = lines_1[_i];
|
|
3510
|
+
var parts = line && line.length > 0 ? line.split(/ (.*)/) : ["" /* Constant.Empty */];
|
|
3511
|
+
switch (parts[0]) {
|
|
3512
|
+
case "END" /* Constant.End */:
|
|
3513
|
+
// Clear out session storage and end the session so we can start fresh the next time
|
|
3514
|
+
trigger(6 /* Check.Server */);
|
|
3515
|
+
break;
|
|
3516
|
+
case "UPGRADE" /* Constant.Upgrade */:
|
|
3517
|
+
// Upgrade current session to send back playback information
|
|
3518
|
+
upgrade("Auto" /* Constant.Auto */);
|
|
3519
|
+
break;
|
|
3520
|
+
case "ACTION" /* Constant.Action */:
|
|
3521
|
+
// Invoke action callback, if configured and has a valid value
|
|
3522
|
+
if (config$1.action && parts.length > 1) {
|
|
3523
|
+
config$1.action(parts[1]);
|
|
3524
|
+
}
|
|
3525
|
+
break;
|
|
3526
|
+
case "EXTRACT" /* Constant.Extract */:
|
|
3527
|
+
if (parts.length > 1) {
|
|
3528
|
+
trigger$1(parts[1]);
|
|
3529
|
+
}
|
|
3530
|
+
break;
|
|
3531
|
+
}
|
|
3552
3532
|
}
|
|
3553
3533
|
}
|
|
3554
3534
|
|
|
@@ -3653,30 +3633,27 @@ var data$5 = {};
|
|
|
3653
3633
|
var keys = [];
|
|
3654
3634
|
var variables = {};
|
|
3655
3635
|
var selectors = {};
|
|
3656
|
-
var fragments = [];
|
|
3657
3636
|
function start$c() {
|
|
3637
|
+
reset$4();
|
|
3638
|
+
}
|
|
3639
|
+
function trigger$1(input) {
|
|
3658
3640
|
try {
|
|
3659
|
-
var
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
}
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
var
|
|
3641
|
+
var parts = input && input.length > 0 ? input.split(/ (.*)/) : ["" /* Constant.Empty */];
|
|
3642
|
+
var key = parseInt(parts[0]);
|
|
3643
|
+
var values = parts.length > 1 ? JSON.parse(parts[1]) : {};
|
|
3644
|
+
variables[key] = {};
|
|
3645
|
+
selectors[key] = {};
|
|
3646
|
+
for (var v in values) {
|
|
3647
|
+
var id = parseInt(v);
|
|
3648
|
+
var value = values[v];
|
|
3649
|
+
var source = value.startsWith("~" /* Constant.Tilde */) ? 0 /* ExtractSource.Javascript */ : 2 /* ExtractSource.Text */;
|
|
3666
3650
|
switch (source) {
|
|
3667
3651
|
case 0 /* ExtractSource.Javascript */:
|
|
3668
|
-
var variable =
|
|
3669
|
-
variables[key] = parse(variable);
|
|
3670
|
-
break;
|
|
3671
|
-
case 1 /* ExtractSource.Cookie */:
|
|
3672
|
-
/*Todo: Add cookie extract logic*/
|
|
3652
|
+
var variable = value.substring(1, value.length);
|
|
3653
|
+
variables[key][id] = parse(variable);
|
|
3673
3654
|
break;
|
|
3674
3655
|
case 2 /* ExtractSource.Text */:
|
|
3675
|
-
|
|
3676
|
-
selectors[key] = match_1;
|
|
3677
|
-
break;
|
|
3678
|
-
case 3 /* ExtractSource.Fragment */:
|
|
3679
|
-
fragments = e[i + 2];
|
|
3656
|
+
selectors[key][id] = value;
|
|
3680
3657
|
break;
|
|
3681
3658
|
}
|
|
3682
3659
|
}
|
|
@@ -3691,15 +3668,25 @@ function clone(v) {
|
|
|
3691
3668
|
function compute$4() {
|
|
3692
3669
|
try {
|
|
3693
3670
|
for (var v in variables) {
|
|
3694
|
-
var
|
|
3695
|
-
if (
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3671
|
+
var key = parseInt(v);
|
|
3672
|
+
if (!(key in keys)) {
|
|
3673
|
+
var variableData = variables[key];
|
|
3674
|
+
for (var v_1 in variableData) {
|
|
3675
|
+
var variableKey = parseInt(v_1);
|
|
3676
|
+
var value = str(evaluate(clone(variableData[variableKey])));
|
|
3677
|
+
if (value) {
|
|
3678
|
+
update(key, variableKey, value);
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
var selectorData = selectors[key];
|
|
3682
|
+
for (var s in selectorData) {
|
|
3683
|
+
var selectorKey = parseInt(s);
|
|
3684
|
+
var nodes = document.querySelectorAll(selectorData[selectorKey]);
|
|
3685
|
+
if (nodes) {
|
|
3686
|
+
var text = Array.from(nodes).map(function (e) { return e.innerText; });
|
|
3687
|
+
update(key, selectorKey, text.join("<SEP>" /* Constant.Seperator */).substring(0, 10000 /* Setting.ExtractLimit */));
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3703
3690
|
}
|
|
3704
3691
|
}
|
|
3705
3692
|
}
|
|
@@ -3709,20 +3696,20 @@ function compute$4() {
|
|
|
3709
3696
|
encode$1(40 /* Event.Extract */);
|
|
3710
3697
|
}
|
|
3711
3698
|
function reset$4() {
|
|
3699
|
+
data$5 = {};
|
|
3712
3700
|
keys = [];
|
|
3701
|
+
variables = {};
|
|
3702
|
+
selectors = {};
|
|
3713
3703
|
}
|
|
3714
|
-
function update(key,
|
|
3715
|
-
if (
|
|
3716
|
-
|
|
3717
|
-
data$5[key] = value;
|
|
3704
|
+
function update(key, subkey, value) {
|
|
3705
|
+
if (!(key in data$5)) {
|
|
3706
|
+
data$5[key] = [];
|
|
3718
3707
|
keys.push(key);
|
|
3719
3708
|
}
|
|
3709
|
+
data$5[key].push([subkey, value]);
|
|
3720
3710
|
}
|
|
3721
3711
|
function stop$b() {
|
|
3722
|
-
|
|
3723
|
-
keys = [];
|
|
3724
|
-
variables = {};
|
|
3725
|
-
selectors = {};
|
|
3712
|
+
reset$4();
|
|
3726
3713
|
}
|
|
3727
3714
|
function parse(variable) {
|
|
3728
3715
|
var syntax = [];
|
|
@@ -3887,7 +3874,7 @@ function encode$1 (event) {
|
|
|
3887
3874
|
for (var _d = 0, extractKeys_1 = extractKeys; _d < extractKeys_1.length; _d++) {
|
|
3888
3875
|
var e = extractKeys_1[_d];
|
|
3889
3876
|
tokens.push(e);
|
|
3890
|
-
tokens.push(data$5[e]);
|
|
3877
|
+
tokens.push([].concat.apply([], data$5[e]));
|
|
3891
3878
|
}
|
|
3892
3879
|
reset$4();
|
|
3893
3880
|
queue(tokens, false);
|
|
@@ -4276,7 +4263,7 @@ function report(e) {
|
|
|
4276
4263
|
// Using POST request instead of a GET request (img-src) to not violate existing CSP rules
|
|
4277
4264
|
// Since, Clarity already uses XHR to upload data, we stick with similar POST mechanism for reporting too
|
|
4278
4265
|
var xhr = new XMLHttpRequest();
|
|
4279
|
-
xhr.open("POST", url);
|
|
4266
|
+
xhr.open("POST", url, true);
|
|
4280
4267
|
xhr.send(JSON.stringify(payload));
|
|
4281
4268
|
history$1.push(e.message);
|
|
4282
4269
|
}
|
|
@@ -4388,7 +4375,7 @@ var status = false;
|
|
|
4388
4375
|
function start$6() {
|
|
4389
4376
|
status = true;
|
|
4390
4377
|
start$G();
|
|
4391
|
-
reset$
|
|
4378
|
+
reset$j();
|
|
4392
4379
|
reset$1();
|
|
4393
4380
|
reset$2();
|
|
4394
4381
|
start$7();
|
|
@@ -4397,7 +4384,7 @@ function stop$5() {
|
|
|
4397
4384
|
stop$6();
|
|
4398
4385
|
reset$2();
|
|
4399
4386
|
reset$1();
|
|
4400
|
-
reset$
|
|
4387
|
+
reset$j();
|
|
4401
4388
|
stop$C();
|
|
4402
4389
|
status = false;
|
|
4403
4390
|
}
|
|
@@ -4480,14 +4467,14 @@ function discover() {
|
|
|
4480
4467
|
case 0:
|
|
4481
4468
|
ts = time();
|
|
4482
4469
|
timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
|
|
4483
|
-
start$
|
|
4470
|
+
start$w(timer);
|
|
4484
4471
|
return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */)];
|
|
4485
4472
|
case 1:
|
|
4486
4473
|
_a.sent();
|
|
4487
4474
|
return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
|
|
4488
4475
|
case 2:
|
|
4489
4476
|
_a.sent();
|
|
4490
|
-
stop$
|
|
4477
|
+
stop$t(timer);
|
|
4491
4478
|
return [2 /*return*/];
|
|
4492
4479
|
}
|
|
4493
4480
|
});
|
|
@@ -4497,16 +4484,16 @@ function discover() {
|
|
|
4497
4484
|
function start$3() {
|
|
4498
4485
|
// The order below is important
|
|
4499
4486
|
// and is determined by interdependencies of modules
|
|
4500
|
-
start$
|
|
4487
|
+
start$v();
|
|
4488
|
+
start$u();
|
|
4489
|
+
start$x();
|
|
4501
4490
|
start$h();
|
|
4502
|
-
start$i();
|
|
4503
|
-
start$j();
|
|
4504
4491
|
start$4();
|
|
4505
4492
|
}
|
|
4506
4493
|
function stop$3() {
|
|
4494
|
+
stop$s();
|
|
4495
|
+
stop$u();
|
|
4507
4496
|
stop$f();
|
|
4508
|
-
stop$g();
|
|
4509
|
-
stop$h();
|
|
4510
4497
|
end();
|
|
4511
4498
|
}
|
|
4512
4499
|
|
|
@@ -4676,7 +4663,7 @@ function stop$2() {
|
|
|
4676
4663
|
function host(url) {
|
|
4677
4664
|
var a = document.createElement("a");
|
|
4678
4665
|
a.href = url;
|
|
4679
|
-
return a.
|
|
4666
|
+
return a.host;
|
|
4680
4667
|
}
|
|
4681
4668
|
|
|
4682
4669
|
function start$1() {
|