clarity-js 0.7.67 → 0.7.69
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.extended.js +1 -1
- package/build/clarity.insight.js +1 -1
- package/build/clarity.js +87 -28
- package/build/clarity.min.js +1 -1
- package/build/clarity.module.js +87 -28
- package/build/clarity.performance.js +1 -1
- package/package.json +1 -1
- package/src/core/event.ts +14 -10
- package/src/core/time.ts +2 -2
- package/src/core/version.ts +1 -1
- package/src/data/baseline.ts +32 -0
- package/src/data/encode.ts +6 -0
- package/src/data/metadata.ts +1 -1
- package/src/interaction/click.ts +12 -6
- package/src/interaction/encode.ts +2 -0
- package/src/interaction/timeline.ts +1 -1
- package/src/interaction/unload.ts +3 -3
- package/src/layout/mutation.ts +158 -94
- package/src/layout/style.ts +8 -7
- package/types/core.d.ts +4 -1
- package/types/data.d.ts +6 -0
- package/types/interaction.d.ts +8 -0
package/build/clarity.js
CHANGED
|
@@ -169,7 +169,7 @@ function stop$F() {
|
|
|
169
169
|
startTime = 0;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
var version$1 = "0.7.
|
|
172
|
+
var version$1 = "0.7.69";
|
|
173
173
|
|
|
174
174
|
// tslint:disable: no-bitwise
|
|
175
175
|
function hash (input, precision) {
|
|
@@ -411,6 +411,12 @@ function reset$s() {
|
|
|
411
411
|
downX: buffer.downX,
|
|
412
412
|
downY: buffer.downY,
|
|
413
413
|
downTime: buffer.downTime,
|
|
414
|
+
upX: buffer.upX,
|
|
415
|
+
upY: buffer.upY,
|
|
416
|
+
upTime: buffer.upTime,
|
|
417
|
+
pointerPrevX: buffer.pointerPrevX,
|
|
418
|
+
pointerPrevY: buffer.pointerPrevY,
|
|
419
|
+
pointerPrevTime: buffer.pointerPrevTime,
|
|
414
420
|
}
|
|
415
421
|
};
|
|
416
422
|
}
|
|
@@ -433,6 +439,12 @@ function reset$s() {
|
|
|
433
439
|
downX: 0,
|
|
434
440
|
downY: 0,
|
|
435
441
|
downTime: 0,
|
|
442
|
+
upX: 0,
|
|
443
|
+
upY: 0,
|
|
444
|
+
upTime: 0,
|
|
445
|
+
pointerPrevX: 0,
|
|
446
|
+
pointerPrevY: 0,
|
|
447
|
+
pointerPrevTime: 0,
|
|
436
448
|
};
|
|
437
449
|
}
|
|
438
450
|
function track$8(event, x, y, time) {
|
|
@@ -454,6 +466,9 @@ function track$8(event, x, y, time) {
|
|
|
454
466
|
buffer.moveX = x;
|
|
455
467
|
buffer.moveY = y;
|
|
456
468
|
buffer.moveTime = time;
|
|
469
|
+
buffer.pointerPrevX = buffer.pointerX;
|
|
470
|
+
buffer.pointerPrevY = buffer.pointerY;
|
|
471
|
+
buffer.pointerPrevTime = buffer.pointerTime;
|
|
457
472
|
buffer.pointerX = x;
|
|
458
473
|
buffer.pointerY = y;
|
|
459
474
|
buffer.pointerTime = time;
|
|
@@ -462,11 +477,28 @@ function track$8(event, x, y, time) {
|
|
|
462
477
|
buffer.downX = x;
|
|
463
478
|
buffer.downY = y;
|
|
464
479
|
buffer.downTime = time;
|
|
480
|
+
buffer.pointerPrevX = buffer.pointerX;
|
|
481
|
+
buffer.pointerPrevY = buffer.pointerY;
|
|
482
|
+
buffer.pointerPrevTime = buffer.pointerTime;
|
|
483
|
+
buffer.pointerX = x;
|
|
484
|
+
buffer.pointerY = y;
|
|
485
|
+
buffer.pointerTime = time;
|
|
486
|
+
break;
|
|
487
|
+
case 14 /* Event.MouseUp */:
|
|
488
|
+
buffer.upX = x;
|
|
489
|
+
buffer.upY = y;
|
|
490
|
+
buffer.upTime = time;
|
|
491
|
+
buffer.pointerPrevX = buffer.pointerX;
|
|
492
|
+
buffer.pointerPrevY = buffer.pointerY;
|
|
493
|
+
buffer.pointerPrevTime = buffer.pointerTime;
|
|
465
494
|
buffer.pointerX = x;
|
|
466
495
|
buffer.pointerY = y;
|
|
467
496
|
buffer.pointerTime = time;
|
|
468
497
|
break;
|
|
469
498
|
default:
|
|
499
|
+
buffer.pointerPrevX = buffer.pointerX;
|
|
500
|
+
buffer.pointerPrevY = buffer.pointerY;
|
|
501
|
+
buffer.pointerPrevTime = buffer.pointerTime;
|
|
470
502
|
buffer.pointerX = x;
|
|
471
503
|
buffer.pointerY = y;
|
|
472
504
|
buffer.pointerTime = time;
|
|
@@ -1851,6 +1883,7 @@ function handler$3(event, root, evt) {
|
|
|
1851
1883
|
var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
|
|
1852
1884
|
// Check for null values before processing this event
|
|
1853
1885
|
if (x !== null && y !== null) {
|
|
1886
|
+
var textInfo = text(t);
|
|
1854
1887
|
state$8.push({
|
|
1855
1888
|
time: time(evt),
|
|
1856
1889
|
event: event,
|
|
@@ -1863,10 +1896,11 @@ function handler$3(event, root, evt) {
|
|
|
1863
1896
|
button: evt.button,
|
|
1864
1897
|
reaction: reaction(t),
|
|
1865
1898
|
context: context(a),
|
|
1866
|
-
text: text
|
|
1899
|
+
text: textInfo.text,
|
|
1867
1900
|
link: a ? a.href : null,
|
|
1868
1901
|
hash: null,
|
|
1869
|
-
trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False
|
|
1902
|
+
trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */,
|
|
1903
|
+
isFullText: textInfo.isFullText,
|
|
1870
1904
|
}
|
|
1871
1905
|
});
|
|
1872
1906
|
schedule$1(encode$3.bind(this, event));
|
|
@@ -1886,17 +1920,20 @@ function link(node) {
|
|
|
1886
1920
|
}
|
|
1887
1921
|
function text(element) {
|
|
1888
1922
|
var output = null;
|
|
1923
|
+
var isFullText = false;
|
|
1889
1924
|
if (element) {
|
|
1890
1925
|
// Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
|
|
1891
1926
|
var t = element.textContent || String(element.value || '') || element.alt;
|
|
1892
1927
|
if (t) {
|
|
1893
1928
|
// Replace multiple occurrence of space characters with a single white space
|
|
1894
1929
|
// Also, trim any spaces at the beginning or at the end of string
|
|
1930
|
+
var trimmedText = t.replace(/\s+/g, " " /* Constant.Space */).trim();
|
|
1895
1931
|
// Finally, send only first few characters as specified by the Setting
|
|
1896
|
-
output =
|
|
1932
|
+
output = trimmedText.substring(0, 25 /* Setting.ClickText */);
|
|
1933
|
+
isFullText = output.length === trimmedText.length;
|
|
1897
1934
|
}
|
|
1898
1935
|
}
|
|
1899
|
-
return output;
|
|
1936
|
+
return { text: output, isFullText: isFullText ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */ };
|
|
1900
1937
|
}
|
|
1901
1938
|
function reaction(element) {
|
|
1902
1939
|
if (element.nodeType === Node.ELEMENT_NODE) {
|
|
@@ -2348,7 +2385,7 @@ function start$n() {
|
|
|
2348
2385
|
}
|
|
2349
2386
|
function recompute$1(evt) {
|
|
2350
2387
|
recompute$1.dn = 17 /* FunctionNames.UnloadRecompute */;
|
|
2351
|
-
data$9 = { name: evt.type };
|
|
2388
|
+
data$9 = { name: evt.type, persisted: evt.persisted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */ };
|
|
2352
2389
|
encode$3(26 /* Event.Unload */, time(evt));
|
|
2353
2390
|
stop();
|
|
2354
2391
|
}
|
|
@@ -2479,6 +2516,8 @@ var throttleDelay = null;
|
|
|
2479
2516
|
var activePeriod = null;
|
|
2480
2517
|
var history$4 = {};
|
|
2481
2518
|
var criticalPeriod = null;
|
|
2519
|
+
// We ignore mutations if these attributes are updated
|
|
2520
|
+
var IGNORED_ATTRIBUTES = ["data-google-query-id", "data-load-complete", "data-google-container-id"];
|
|
2482
2521
|
function start$k() {
|
|
2483
2522
|
start$k.dn = 21 /* FunctionNames.MutationStart */;
|
|
2484
2523
|
observers = [];
|
|
@@ -2629,7 +2668,9 @@ function processMutation(timer, mutation, instance, timestamp) {
|
|
|
2629
2668
|
}
|
|
2630
2669
|
switch (type) {
|
|
2631
2670
|
case "attributes" /* Constant.Attributes */:
|
|
2632
|
-
|
|
2671
|
+
if (IGNORED_ATTRIBUTES.indexOf(mutation.attributeName) < 0) {
|
|
2672
|
+
processNode(target, 3 /* Source.Attributes */, timestamp);
|
|
2673
|
+
}
|
|
2633
2674
|
break;
|
|
2634
2675
|
case "characterData" /* Constant.CharacterData */:
|
|
2635
2676
|
processNode(target, 4 /* Source.CharacterData */, timestamp);
|
|
@@ -2734,8 +2775,7 @@ function track$5(m, timer, instance, timestamp) {
|
|
|
2734
2775
|
var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
|
|
2735
2776
|
// Check if its a low priority (e.g., ads related) element mutation happening during critical period
|
|
2736
2777
|
// If the discard list is empty, we discard all mutations during critical period
|
|
2737
|
-
var lowPriMutation = config$2.throttleMutations && critical &&
|
|
2738
|
-
(config$2.discard.length === 0 || config$2.discard.some(function (key) { return element_1.includes(key); }));
|
|
2778
|
+
var lowPriMutation = config$2.throttleMutations && critical && (config$2.discard.length === 0 || config$2.discard.some(function (key) { return element_1.includes(key); }));
|
|
2739
2779
|
// We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
|
|
2740
2780
|
// repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
|
|
2741
2781
|
// In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
|
|
@@ -2816,7 +2856,9 @@ function processThrottledMutations() {
|
|
|
2816
2856
|
if (throttleDelay) {
|
|
2817
2857
|
clearTimeout(throttleDelay);
|
|
2818
2858
|
}
|
|
2819
|
-
throttleDelay = setTimeout(function () {
|
|
2859
|
+
throttleDelay = setTimeout(function () {
|
|
2860
|
+
schedule$1(process$2, 1 /* Priority.High */);
|
|
2861
|
+
}, 33 /* Setting.LookAhead */);
|
|
2820
2862
|
}
|
|
2821
2863
|
function schedule(node) {
|
|
2822
2864
|
// Only schedule manual trigger for this node if it's not already in the queue
|
|
@@ -2829,7 +2871,9 @@ function schedule(node) {
|
|
|
2829
2871
|
if (timeout$1) {
|
|
2830
2872
|
clearTimeout(timeout$1);
|
|
2831
2873
|
}
|
|
2832
|
-
timeout$1 = setTimeout(function () {
|
|
2874
|
+
timeout$1 = setTimeout(function () {
|
|
2875
|
+
trigger$2();
|
|
2876
|
+
}, 33 /* Setting.LookAhead */);
|
|
2833
2877
|
return node;
|
|
2834
2878
|
}
|
|
2835
2879
|
function trigger$2() {
|
|
@@ -2849,7 +2893,8 @@ function trigger$2() {
|
|
|
2849
2893
|
}
|
|
2850
2894
|
function generate(target, type) {
|
|
2851
2895
|
generate.dn = 23 /* FunctionNames.MutationGenerate */;
|
|
2852
|
-
measure(handle$1)([
|
|
2896
|
+
measure(handle$1)([
|
|
2897
|
+
{
|
|
2853
2898
|
addedNodes: [target],
|
|
2854
2899
|
attributeName: null,
|
|
2855
2900
|
attributeNamespace: null,
|
|
@@ -2858,8 +2903,9 @@ function generate(target, type) {
|
|
|
2858
2903
|
previousSibling: null,
|
|
2859
2904
|
removedNodes: [],
|
|
2860
2905
|
target: target,
|
|
2861
|
-
type: type
|
|
2862
|
-
}
|
|
2906
|
+
type: type,
|
|
2907
|
+
},
|
|
2908
|
+
]);
|
|
2863
2909
|
}
|
|
2864
2910
|
|
|
2865
2911
|
var digitsRegex = /[^0-9\.]/g;
|
|
@@ -3185,10 +3231,10 @@ var sheetAdoptionState = [];
|
|
|
3185
3231
|
var replace = null;
|
|
3186
3232
|
var replaceSync = null;
|
|
3187
3233
|
var styleSheetId = 'claritySheetId';
|
|
3188
|
-
var styleSheetPageNum = 'claritySheetNum';
|
|
3189
3234
|
var styleSheetMap = {};
|
|
3190
3235
|
var styleTimeMap = {};
|
|
3191
3236
|
var documentNodes = [];
|
|
3237
|
+
var createdSheetIds = [];
|
|
3192
3238
|
function start$j() {
|
|
3193
3239
|
if (window['CSSStyleSheet'] && CSSStyleSheet.prototype) {
|
|
3194
3240
|
if (replace === null) {
|
|
@@ -3199,7 +3245,7 @@ function start$j() {
|
|
|
3199
3245
|
// if we haven't seen this stylesheet on this page yet, wait until the checkDocumentStyles has found it
|
|
3200
3246
|
// and attached the sheet to a document. This way the timestamp of the style sheet creation will align
|
|
3201
3247
|
// to when it is used in the document rather than potentially being misaligned during the traverse process.
|
|
3202
|
-
if (this[
|
|
3248
|
+
if (createdSheetIds.indexOf(this[styleSheetId]) > -1) {
|
|
3203
3249
|
trackStyleChange(time(), this[styleSheetId], 1 /* StyleSheetOperation.Replace */, arguments[0]);
|
|
3204
3250
|
}
|
|
3205
3251
|
}
|
|
@@ -3214,7 +3260,7 @@ function start$j() {
|
|
|
3214
3260
|
// if we haven't seen this stylesheet on this page yet, wait until the checkDocumentStyles has found it
|
|
3215
3261
|
// and attached the sheet to a document. This way the timestamp of the style sheet creation will align
|
|
3216
3262
|
// to when it is used in the document rather than potentially being misaligned during the traverse process.
|
|
3217
|
-
if (this[
|
|
3263
|
+
if (createdSheetIds.indexOf(this[styleSheetId]) > -1) {
|
|
3218
3264
|
trackStyleChange(time(), this[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, arguments[0]);
|
|
3219
3265
|
}
|
|
3220
3266
|
}
|
|
@@ -3236,14 +3282,13 @@ function checkDocumentStyles(documentNode, timestamp) {
|
|
|
3236
3282
|
var currentStyleSheets = [];
|
|
3237
3283
|
for (var _i = 0, _a = documentNode.adoptedStyleSheets; _i < _a.length; _i++) {
|
|
3238
3284
|
var styleSheet = _a[_i];
|
|
3239
|
-
var pageNum = data$2.pageNum;
|
|
3240
3285
|
// If we haven't seen this style sheet on this page yet, we create a reference to it for the visualizer.
|
|
3241
3286
|
// For SPA or times in which Clarity restarts on a given page, our visualizer would lose context
|
|
3242
3287
|
// on the previously created style sheet for page N-1.
|
|
3243
3288
|
// Then we synthetically call replaceSync with its contents to bootstrap it
|
|
3244
|
-
if (styleSheet[
|
|
3245
|
-
styleSheet[styleSheetPageNum] = pageNum;
|
|
3289
|
+
if (!styleSheet[styleSheetId] || createdSheetIds.indexOf(styleSheet[styleSheetId]) === -1) {
|
|
3246
3290
|
styleSheet[styleSheetId] = shortid();
|
|
3291
|
+
createdSheetIds.push(styleSheet[styleSheetId]);
|
|
3247
3292
|
trackStyleChange(timestamp, styleSheet[styleSheetId], 0 /* StyleSheetOperation.Create */);
|
|
3248
3293
|
trackStyleChange(timestamp, styleSheet[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, getCssRules(styleSheet));
|
|
3249
3294
|
}
|
|
@@ -3276,6 +3321,7 @@ function stop$h() {
|
|
|
3276
3321
|
styleSheetMap = {};
|
|
3277
3322
|
styleTimeMap = {};
|
|
3278
3323
|
documentNodes = [];
|
|
3324
|
+
createdSheetIds = [];
|
|
3279
3325
|
reset$8();
|
|
3280
3326
|
}
|
|
3281
3327
|
function trackStyleChange(time, id, operation, cssRules) {
|
|
@@ -3825,6 +3871,7 @@ function encode$3 (type, ts) {
|
|
|
3825
3871
|
tokens.push(url$1(entry.data.link));
|
|
3826
3872
|
tokens.push(cHash);
|
|
3827
3873
|
tokens.push(entry.data.trust);
|
|
3874
|
+
tokens.push(entry.data.isFullText);
|
|
3828
3875
|
queue(tokens);
|
|
3829
3876
|
track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
|
|
3830
3877
|
}
|
|
@@ -3854,6 +3901,7 @@ function encode$3 (type, ts) {
|
|
|
3854
3901
|
case 26 /* Event.Unload */:
|
|
3855
3902
|
u = data$9;
|
|
3856
3903
|
tokens.push(u.name);
|
|
3904
|
+
tokens.push(u.persisted);
|
|
3857
3905
|
reset$a();
|
|
3858
3906
|
queue(tokens);
|
|
3859
3907
|
break;
|
|
@@ -3984,7 +4032,7 @@ function track$2(time, event, hash, x, y, reaction, context) {
|
|
|
3984
4032
|
// Since timeline only keeps the data for configured time, we still want to continue tracking these values
|
|
3985
4033
|
// as part of the baseline. For instance, in a scenario where last scroll happened 5s ago.
|
|
3986
4034
|
// We would still need to capture the last scroll position as part of the baseline event, even when timeline will be empty.
|
|
3987
|
-
track$8(event, x, y);
|
|
4035
|
+
track$8(event, x, y, time);
|
|
3988
4036
|
}
|
|
3989
4037
|
function compute$5() {
|
|
3990
4038
|
var temp = [];
|
|
@@ -4596,6 +4644,12 @@ function encode$1 (event) {
|
|
|
4596
4644
|
tokens.push(b.data.downX);
|
|
4597
4645
|
tokens.push(b.data.downY);
|
|
4598
4646
|
tokens.push(b.data.downTime);
|
|
4647
|
+
tokens.push(b.data.upX);
|
|
4648
|
+
tokens.push(b.data.upY);
|
|
4649
|
+
tokens.push(b.data.upTime);
|
|
4650
|
+
tokens.push(b.data.pointerPrevX);
|
|
4651
|
+
tokens.push(b.data.pointerPrevY);
|
|
4652
|
+
tokens.push(b.data.pointerPrevTime);
|
|
4599
4653
|
queue(tokens, false);
|
|
4600
4654
|
}
|
|
4601
4655
|
reset$s();
|
|
@@ -4927,7 +4981,7 @@ function callback() {
|
|
|
4927
4981
|
processCallback(upgrade);
|
|
4928
4982
|
}
|
|
4929
4983
|
function save() {
|
|
4930
|
-
if (!data$2)
|
|
4984
|
+
if (!data$2 || !config$2.track)
|
|
4931
4985
|
return;
|
|
4932
4986
|
var ts = Math.round(Date.now());
|
|
4933
4987
|
var upload = config$2.upload && typeof config$2.upload === "string" /* Constant.String */ ? config$2.upload.replace("https://" /* Constant.HTTPS */, "" /* Constant.Empty */) : "" /* Constant.Empty */;
|
|
@@ -5224,16 +5278,19 @@ function measure (method) {
|
|
|
5224
5278
|
}
|
|
5225
5279
|
|
|
5226
5280
|
var bindings = [];
|
|
5227
|
-
function bind(target, event, listener, capture) {
|
|
5281
|
+
function bind(target, event, listener, capture, passive) {
|
|
5228
5282
|
if (capture === void 0) { capture = false; }
|
|
5283
|
+
if (passive === void 0) { passive = true; }
|
|
5229
5284
|
listener = measure(listener);
|
|
5230
5285
|
// Wrapping following lines inside try / catch to cover edge cases where we might try to access an inaccessible element.
|
|
5231
5286
|
// E.g. Iframe may start off as same-origin but later turn into cross-origin, and the following lines will throw an exception.
|
|
5232
5287
|
try {
|
|
5233
|
-
target[api("addEventListener" /* Constant.AddEventListener */)](event, listener, capture);
|
|
5234
|
-
bindings.push({ event: event, target: target, listener: listener, capture: capture });
|
|
5288
|
+
target[api("addEventListener" /* Constant.AddEventListener */)](event, listener, { capture: capture, passive: passive });
|
|
5289
|
+
bindings.push({ event: event, target: target, listener: listener, options: { capture: capture, passive: passive } });
|
|
5290
|
+
}
|
|
5291
|
+
catch (_a) {
|
|
5292
|
+
/* do nothing */
|
|
5235
5293
|
}
|
|
5236
|
-
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
5237
5294
|
}
|
|
5238
5295
|
function reset$1() {
|
|
5239
5296
|
// Walk through existing list of bindings and remove them all
|
|
@@ -5241,9 +5298,11 @@ function reset$1() {
|
|
|
5241
5298
|
var binding = bindings_1[_i];
|
|
5242
5299
|
// Wrapping inside try / catch to avoid situations where the element may be destroyed before we get a chance to unbind
|
|
5243
5300
|
try {
|
|
5244
|
-
binding.target[api("removeEventListener" /* Constant.RemoveEventListener */)](binding.event, binding.listener, binding.capture);
|
|
5301
|
+
binding.target[api("removeEventListener" /* Constant.RemoveEventListener */)](binding.event, binding.listener, { capture: binding.options.capture, passive: binding.options.passive });
|
|
5302
|
+
}
|
|
5303
|
+
catch (_a) {
|
|
5304
|
+
/* do nothing */
|
|
5245
5305
|
}
|
|
5246
|
-
catch ( /* do nothing */_a) { /* do nothing */ }
|
|
5247
5306
|
}
|
|
5248
5307
|
bindings = [];
|
|
5249
5308
|
}
|