@amplitude/plugin-autocapture-browser 1.10.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/autocapture/track-rage-click.d.ts.map +1 -1
- package/lib/cjs/autocapture/track-rage-click.js +77 -29
- package/lib/cjs/autocapture/track-rage-click.js.map +1 -1
- package/lib/cjs/autocapture-plugin.d.ts.map +1 -1
- package/lib/cjs/autocapture-plugin.js +11 -8
- package/lib/cjs/autocapture-plugin.js.map +1 -1
- package/lib/cjs/constants.d.ts +1 -0
- package/lib/cjs/constants.d.ts.map +1 -1
- package/lib/cjs/constants.js +2 -1
- package/lib/cjs/constants.js.map +1 -1
- package/lib/cjs/data-extractor.d.ts +19 -0
- package/lib/cjs/data-extractor.d.ts.map +1 -0
- package/lib/cjs/data-extractor.js +230 -0
- package/lib/cjs/data-extractor.js.map +1 -0
- package/lib/cjs/frustration-plugin.d.ts.map +1 -1
- package/lib/cjs/frustration-plugin.js +10 -4
- package/lib/cjs/frustration-plugin.js.map +1 -1
- package/lib/cjs/helpers.d.ts +0 -10
- package/lib/cjs/helpers.d.ts.map +1 -1
- package/lib/cjs/helpers.js +1 -154
- package/lib/cjs/helpers.js.map +1 -1
- package/lib/cjs/libs/messenger.d.ts +3 -1
- package/lib/cjs/libs/messenger.d.ts.map +1 -1
- package/lib/cjs/libs/messenger.js +4 -4
- package/lib/cjs/libs/messenger.js.map +1 -1
- package/lib/cjs/pageActions/actions.d.ts +3 -3
- package/lib/cjs/pageActions/actions.d.ts.map +1 -1
- package/lib/cjs/pageActions/actions.js +3 -23
- package/lib/cjs/pageActions/actions.js.map +1 -1
- package/lib/cjs/pageActions/triggers.d.ts +4 -2
- package/lib/cjs/pageActions/triggers.d.ts.map +1 -1
- package/lib/cjs/pageActions/triggers.js +5 -4
- package/lib/cjs/pageActions/triggers.js.map +1 -1
- package/lib/cjs/version.d.ts +1 -1
- package/lib/cjs/version.js +1 -1
- package/lib/cjs/version.js.map +1 -1
- package/lib/esm/autocapture/track-rage-click.d.ts.map +1 -1
- package/lib/esm/autocapture/track-rage-click.js +78 -30
- package/lib/esm/autocapture/track-rage-click.js.map +1 -1
- package/lib/esm/autocapture-plugin.d.ts.map +1 -1
- package/lib/esm/autocapture-plugin.js +12 -9
- package/lib/esm/autocapture-plugin.js.map +1 -1
- package/lib/esm/constants.d.ts +1 -0
- package/lib/esm/constants.d.ts.map +1 -1
- package/lib/esm/constants.js +1 -0
- package/lib/esm/constants.js.map +1 -1
- package/lib/esm/data-extractor.d.ts +19 -0
- package/lib/esm/data-extractor.d.ts.map +1 -0
- package/lib/esm/data-extractor.js +227 -0
- package/lib/esm/data-extractor.js.map +1 -0
- package/lib/esm/frustration-plugin.d.ts.map +1 -1
- package/lib/esm/frustration-plugin.js +11 -5
- package/lib/esm/frustration-plugin.js.map +1 -1
- package/lib/esm/helpers.d.ts +0 -10
- package/lib/esm/helpers.d.ts.map +1 -1
- package/lib/esm/helpers.js +0 -146
- package/lib/esm/helpers.js.map +1 -1
- package/lib/esm/libs/messenger.d.ts +3 -1
- package/lib/esm/libs/messenger.d.ts.map +1 -1
- package/lib/esm/libs/messenger.js +5 -5
- package/lib/esm/libs/messenger.js.map +1 -1
- package/lib/esm/pageActions/actions.d.ts +3 -3
- package/lib/esm/pageActions/actions.d.ts.map +1 -1
- package/lib/esm/pageActions/actions.js +2 -21
- package/lib/esm/pageActions/actions.js.map +1 -1
- package/lib/esm/pageActions/triggers.d.ts +4 -2
- package/lib/esm/pageActions/triggers.d.ts.map +1 -1
- package/lib/esm/pageActions/triggers.js +5 -4
- package/lib/esm/pageActions/triggers.js.map +1 -1
- package/lib/esm/version.d.ts +1 -1
- package/lib/esm/version.js +1 -1
- package/lib/esm/version.js.map +1 -1
- package/lib/scripts/amplitude-min.js +1 -1
- package/lib/scripts/amplitude-min.js.gz +0 -0
- package/lib/scripts/amplitude-min.js.map +1 -1
- package/lib/scripts/amplitude-min.umd.js +1 -1
- package/lib/scripts/amplitude-min.umd.js.gz +0 -0
- package/lib/scripts/autocapture/track-rage-click.d.ts.map +1 -1
- package/lib/scripts/autocapture-plugin.d.ts.map +1 -1
- package/lib/scripts/constants.d.ts +1 -0
- package/lib/scripts/constants.d.ts.map +1 -1
- package/lib/scripts/data-extractor.d.ts +19 -0
- package/lib/scripts/data-extractor.d.ts.map +1 -0
- package/lib/scripts/frustration-plugin.d.ts.map +1 -1
- package/lib/scripts/helpers.d.ts +0 -10
- package/lib/scripts/helpers.d.ts.map +1 -1
- package/lib/scripts/libs/messenger.d.ts +3 -1
- package/lib/scripts/libs/messenger.d.ts.map +1 -1
- package/lib/scripts/pageActions/actions.d.ts +3 -3
- package/lib/scripts/pageActions/actions.d.ts.map +1 -1
- package/lib/scripts/pageActions/triggers.d.ts +4 -2
- package/lib/scripts/pageActions/triggers.d.ts.map +1 -1
- package/lib/scripts/version.d.ts +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataExtractor = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var constants = tslib_1.__importStar(require("./constants"));
|
|
6
|
+
var helpers_1 = require("./helpers");
|
|
7
|
+
var hierarchy_1 = require("./hierarchy");
|
|
8
|
+
var actions_1 = require("./pageActions/actions");
|
|
9
|
+
var CC_REGEX = /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;
|
|
10
|
+
var SSN_REGEX = /(^\d{3}-?\d{2}-?\d{4}$)/;
|
|
11
|
+
var EMAIL_REGEX = /[^\s@]+@[^\s@.]+\.[^\s@]+/;
|
|
12
|
+
var DataExtractor = /** @class */ (function () {
|
|
13
|
+
function DataExtractor(options) {
|
|
14
|
+
var e_1, _a;
|
|
15
|
+
var _this = this;
|
|
16
|
+
var _b;
|
|
17
|
+
this.isNonSensitiveString = function (text) {
|
|
18
|
+
var e_2, _a;
|
|
19
|
+
if (typeof text !== 'string') {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
// Check for credit card number
|
|
23
|
+
if (CC_REGEX.test((text || '').replace(/[- ]/g, ''))) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// Check for social security number or email
|
|
27
|
+
if (SSN_REGEX.test(text) || EMAIL_REGEX.test(text)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
// Check for additional mask text patterns
|
|
32
|
+
for (var _b = tslib_1.__values(_this.additionalMaskTextPatterns), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
33
|
+
var pattern = _c.value;
|
|
34
|
+
try {
|
|
35
|
+
if (pattern.test(text)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (_d) {
|
|
40
|
+
// ignore invalid pattern
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
45
|
+
finally {
|
|
46
|
+
try {
|
|
47
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
48
|
+
}
|
|
49
|
+
finally { if (e_2) throw e_2.error; }
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
this.getNearestLabel = function (element) {
|
|
54
|
+
var parent = element.parentElement;
|
|
55
|
+
if (!parent) {
|
|
56
|
+
return '';
|
|
57
|
+
}
|
|
58
|
+
var labelElement;
|
|
59
|
+
try {
|
|
60
|
+
labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');
|
|
61
|
+
}
|
|
62
|
+
catch (_a) {
|
|
63
|
+
/* istanbul ignore next */
|
|
64
|
+
labelElement = null;
|
|
65
|
+
}
|
|
66
|
+
if (labelElement) {
|
|
67
|
+
/* istanbul ignore next */
|
|
68
|
+
var labelText = labelElement.textContent || '';
|
|
69
|
+
return _this.isNonSensitiveString(labelText) ? labelText : '';
|
|
70
|
+
}
|
|
71
|
+
return _this.getNearestLabel(parent);
|
|
72
|
+
};
|
|
73
|
+
// Returns the Amplitude event properties for the given element.
|
|
74
|
+
this.getEventProperties = function (actionType, element, dataAttributePrefix) {
|
|
75
|
+
var _a;
|
|
76
|
+
var _b, _c;
|
|
77
|
+
/* istanbul ignore next */
|
|
78
|
+
var tag = (_c = (_b = element === null || element === void 0 ? void 0 : element.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
79
|
+
/* istanbul ignore next */
|
|
80
|
+
var rect = typeof element.getBoundingClientRect === 'function' ? element.getBoundingClientRect() : { left: null, top: null };
|
|
81
|
+
var ariaLabel = element.getAttribute('aria-label');
|
|
82
|
+
var attributes = (0, helpers_1.getAttributesWithPrefix)(element, dataAttributePrefix);
|
|
83
|
+
var nearestLabel = _this.getNearestLabel(element);
|
|
84
|
+
/* istanbul ignore next */
|
|
85
|
+
var properties = (_a = {},
|
|
86
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ID] = element.getAttribute('id') || '',
|
|
87
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS] = element.getAttribute('class'),
|
|
88
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY] = (0, hierarchy_1.getHierarchy)(element),
|
|
89
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG] = tag,
|
|
90
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT] = _this.getText(element),
|
|
91
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT] = rect.left == null ? null : Math.round(rect.left),
|
|
92
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP] = rect.top == null ? null : Math.round(rect.top),
|
|
93
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL] = ariaLabel,
|
|
94
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES] = attributes,
|
|
95
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL] = nearestLabel,
|
|
96
|
+
_a[constants.AMPLITUDE_EVENT_PROP_PAGE_URL] = window.location.href.split('?')[0],
|
|
97
|
+
_a[constants.AMPLITUDE_EVENT_PROP_PAGE_TITLE] = (typeof document !== 'undefined' && document.title) || '',
|
|
98
|
+
_a[constants.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT] = window.innerHeight,
|
|
99
|
+
_a[constants.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH] = window.innerWidth,
|
|
100
|
+
_a);
|
|
101
|
+
if (tag === 'a' && actionType === 'click' && element instanceof HTMLAnchorElement) {
|
|
102
|
+
properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HREF] = element.href;
|
|
103
|
+
}
|
|
104
|
+
return (0, helpers_1.removeEmptyProperties)(properties);
|
|
105
|
+
};
|
|
106
|
+
this.addAdditionalEventProperties = function (event, type, selectorAllowlist, dataAttributePrefix,
|
|
107
|
+
// capture the event if the cursor is a "pointer" when this element is clicked on
|
|
108
|
+
// reason: a "pointer" cursor indicates that an element should be interactable
|
|
109
|
+
// regardless of the element's tag name
|
|
110
|
+
isCapturingCursorPointer) {
|
|
111
|
+
if (isCapturingCursorPointer === void 0) { isCapturingCursorPointer = false; }
|
|
112
|
+
var baseEvent = {
|
|
113
|
+
event: event,
|
|
114
|
+
timestamp: Date.now(),
|
|
115
|
+
type: type,
|
|
116
|
+
};
|
|
117
|
+
if ((0, helpers_1.isElementBasedEvent)(baseEvent) && baseEvent.event.target !== null) {
|
|
118
|
+
if (isCapturingCursorPointer) {
|
|
119
|
+
var isCursorPointer = (0, helpers_1.isElementPointerCursor)(baseEvent.event.target, baseEvent.type);
|
|
120
|
+
if (isCursorPointer) {
|
|
121
|
+
baseEvent.closestTrackedAncestor = baseEvent.event.target;
|
|
122
|
+
baseEvent.targetElementProperties = _this.getEventProperties(baseEvent.type, baseEvent.closestTrackedAncestor, dataAttributePrefix);
|
|
123
|
+
return baseEvent;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Retrieve additional event properties from the target element
|
|
127
|
+
var closestTrackedAncestor = (0, helpers_1.getClosestElement)(baseEvent.event.target, selectorAllowlist);
|
|
128
|
+
if (closestTrackedAncestor) {
|
|
129
|
+
baseEvent.closestTrackedAncestor = closestTrackedAncestor;
|
|
130
|
+
baseEvent.targetElementProperties = _this.getEventProperties(baseEvent.type, closestTrackedAncestor, dataAttributePrefix);
|
|
131
|
+
}
|
|
132
|
+
return baseEvent;
|
|
133
|
+
}
|
|
134
|
+
return baseEvent;
|
|
135
|
+
};
|
|
136
|
+
this.extractDataFromDataSource = function (dataSource, contextElement) {
|
|
137
|
+
// Extract from DOM Element
|
|
138
|
+
if (dataSource.sourceType === 'DOM_ELEMENT') {
|
|
139
|
+
var sourceElement = (0, actions_1.getDataSource)(dataSource, contextElement);
|
|
140
|
+
if (!sourceElement) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
if (dataSource.elementExtractType === 'TEXT') {
|
|
144
|
+
return _this.getText(sourceElement);
|
|
145
|
+
}
|
|
146
|
+
else if (dataSource.elementExtractType === 'ATTRIBUTE' && dataSource.attribute) {
|
|
147
|
+
return sourceElement.getAttribute(dataSource.attribute);
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
// TODO: Extract from other source types
|
|
152
|
+
return undefined;
|
|
153
|
+
};
|
|
154
|
+
this.combineText = function (element) {
|
|
155
|
+
var text = '';
|
|
156
|
+
if ((0, helpers_1.isNonSensitiveElement)(element) && element.childNodes && element.childNodes.length) {
|
|
157
|
+
element.childNodes.forEach(function (child) {
|
|
158
|
+
var childText = '';
|
|
159
|
+
if ((0, helpers_1.isTextNode)(child)) {
|
|
160
|
+
if (child.textContent) {
|
|
161
|
+
childText = child.textContent;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
childText = _this.combineText(child);
|
|
166
|
+
}
|
|
167
|
+
text += childText
|
|
168
|
+
.split(/(\s+)/)
|
|
169
|
+
.filter(_this.isNonSensitiveString)
|
|
170
|
+
.join('')
|
|
171
|
+
.replace(/[\r\n]/g, ' ')
|
|
172
|
+
.replace(/[ ]+/g, ' ')
|
|
173
|
+
.substring(0, 255);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return text;
|
|
177
|
+
};
|
|
178
|
+
this.getText = function (element) {
|
|
179
|
+
return _this.combineText(element).trim();
|
|
180
|
+
};
|
|
181
|
+
// Returns the element properties for the given element in Visual Labeling.
|
|
182
|
+
this.getEventTagProps = function (element) {
|
|
183
|
+
var _a;
|
|
184
|
+
var _b, _c;
|
|
185
|
+
if (!element) {
|
|
186
|
+
return {};
|
|
187
|
+
}
|
|
188
|
+
/* istanbul ignore next */
|
|
189
|
+
var tag = (_c = (_b = element === null || element === void 0 ? void 0 : element.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
190
|
+
var properties = (_a = {},
|
|
191
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG] = tag,
|
|
192
|
+
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT] = _this.getText(element),
|
|
193
|
+
_a[constants.AMPLITUDE_EVENT_PROP_PAGE_URL] = window.location.href.split('?')[0],
|
|
194
|
+
_a);
|
|
195
|
+
return (0, helpers_1.removeEmptyProperties)(properties);
|
|
196
|
+
};
|
|
197
|
+
var rawPatterns = (_b = options.maskTextRegex) !== null && _b !== void 0 ? _b : [];
|
|
198
|
+
var compiled = [];
|
|
199
|
+
try {
|
|
200
|
+
for (var rawPatterns_1 = tslib_1.__values(rawPatterns), rawPatterns_1_1 = rawPatterns_1.next(); !rawPatterns_1_1.done; rawPatterns_1_1 = rawPatterns_1.next()) {
|
|
201
|
+
var entry = rawPatterns_1_1.value;
|
|
202
|
+
if (compiled.length >= constants.MAX_MASK_TEXT_PATTERNS) {
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
if (entry instanceof RegExp) {
|
|
206
|
+
compiled.push(entry);
|
|
207
|
+
}
|
|
208
|
+
else if ('pattern' in entry && typeof entry.pattern === 'string') {
|
|
209
|
+
try {
|
|
210
|
+
compiled.push(new RegExp(entry.pattern));
|
|
211
|
+
}
|
|
212
|
+
catch (_c) {
|
|
213
|
+
// ignore invalid pattern strings
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
219
|
+
finally {
|
|
220
|
+
try {
|
|
221
|
+
if (rawPatterns_1_1 && !rawPatterns_1_1.done && (_a = rawPatterns_1.return)) _a.call(rawPatterns_1);
|
|
222
|
+
}
|
|
223
|
+
finally { if (e_1) throw e_1.error; }
|
|
224
|
+
}
|
|
225
|
+
this.additionalMaskTextPatterns = compiled;
|
|
226
|
+
}
|
|
227
|
+
return DataExtractor;
|
|
228
|
+
}());
|
|
229
|
+
exports.DataExtractor = DataExtractor;
|
|
230
|
+
//# sourceMappingURL=data-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-extractor.js","sourceRoot":"","sources":["../../src/data-extractor.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport type { ElementInteractionsOptions, ActionType } from '@amplitude/analytics-core';\nimport type { DataSource } from '@amplitude/analytics-core/lib/esm/types/element-interactions';\nimport * as constants from './constants';\nimport {\n isTextNode,\n removeEmptyProperties,\n isNonSensitiveElement,\n getAttributesWithPrefix,\n isElementPointerCursor,\n getClosestElement,\n isElementBasedEvent,\n} from './helpers';\nimport type { BaseTimestampedEvent, ElementBasedTimestampedEvent, TimestampedEvent } from './helpers';\nimport { getHierarchy } from './hierarchy';\nimport type { JSONValue } from './helpers';\nimport { getDataSource } from './pageActions/actions';\n\nconst CC_REGEX =\n /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;\nconst SSN_REGEX = /(^\\d{3}-?\\d{2}-?\\d{4}$)/;\nconst EMAIL_REGEX = /[^\\s@]+@[^\\s@.]+\\.[^\\s@]+/;\n\nexport class DataExtractor {\n private readonly additionalMaskTextPatterns: RegExp[];\n\n constructor(options: ElementInteractionsOptions) {\n const rawPatterns = options.maskTextRegex ?? [];\n\n const compiled: RegExp[] = [];\n for (const entry of rawPatterns) {\n if (compiled.length >= constants.MAX_MASK_TEXT_PATTERNS) {\n break;\n }\n if (entry instanceof RegExp) {\n compiled.push(entry);\n } else if ('pattern' in entry && typeof entry.pattern === 'string') {\n try {\n compiled.push(new RegExp(entry.pattern));\n } catch {\n // ignore invalid pattern strings\n }\n }\n }\n this.additionalMaskTextPatterns = compiled;\n }\n\n isNonSensitiveString = (text: string | null): boolean => {\n if (typeof text !== 'string') {\n return true;\n }\n\n // Check for credit card number\n if (CC_REGEX.test((text || '').replace(/[- ]/g, ''))) {\n return false;\n }\n\n // Check for social security number or email\n if (SSN_REGEX.test(text) || EMAIL_REGEX.test(text)) {\n return false;\n }\n\n // Check for additional mask text patterns\n for (const pattern of this.additionalMaskTextPatterns) {\n try {\n if (pattern.test(text)) {\n return false;\n }\n } catch {\n // ignore invalid pattern\n }\n }\n\n return true;\n };\n\n getNearestLabel = (element: Element): string => {\n const parent = element.parentElement;\n if (!parent) {\n return '';\n }\n let labelElement: Element | null;\n try {\n labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');\n } catch {\n /* istanbul ignore next */\n labelElement = null;\n }\n if (labelElement) {\n /* istanbul ignore next */\n const labelText = labelElement.textContent || '';\n return this.isNonSensitiveString(labelText) ? labelText : '';\n }\n return this.getNearestLabel(parent);\n };\n\n // Returns the Amplitude event properties for the given element.\n getEventProperties = (actionType: ActionType, element: Element, dataAttributePrefix: string) => {\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n /* istanbul ignore next */\n const rect =\n typeof element.getBoundingClientRect === 'function' ? element.getBoundingClientRect() : { left: null, top: null };\n const ariaLabel = element.getAttribute('aria-label');\n const attributes = getAttributesWithPrefix(element, dataAttributePrefix);\n const nearestLabel = this.getNearestLabel(element);\n /* istanbul ignore next */\n const properties: Record<string, unknown> = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_ID]: element.getAttribute('id') || '',\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS]: element.getAttribute('class'),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY]: getHierarchy(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT]: rect.left == null ? null : Math.round(rect.left),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP]: rect.top == null ? null : Math.round(rect.top),\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL]: ariaLabel,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES]: attributes,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL]: nearestLabel,\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: window.location.href.split('?')[0],\n [constants.AMPLITUDE_EVENT_PROP_PAGE_TITLE]: (typeof document !== 'undefined' && document.title) || '',\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT]: window.innerHeight,\n [constants.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH]: window.innerWidth,\n };\n if (tag === 'a' && actionType === 'click' && element instanceof HTMLAnchorElement) {\n properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HREF] = element.href;\n }\n return removeEmptyProperties(properties);\n };\n\n addAdditionalEventProperties = <T>(\n event: T,\n type: TimestampedEvent<T>['type'],\n selectorAllowlist: string[],\n dataAttributePrefix: string,\n // capture the event if the cursor is a \"pointer\" when this element is clicked on\n // reason: a \"pointer\" cursor indicates that an element should be interactable\n // regardless of the element's tag name\n isCapturingCursorPointer = false,\n ): TimestampedEvent<T> | ElementBasedTimestampedEvent<T> => {\n const baseEvent: BaseTimestampedEvent<T> | ElementBasedTimestampedEvent<T> = {\n event,\n timestamp: Date.now(),\n type,\n };\n\n if (isElementBasedEvent(baseEvent) && baseEvent.event.target !== null) {\n if (isCapturingCursorPointer) {\n const isCursorPointer = isElementPointerCursor(baseEvent.event.target as Element, baseEvent.type);\n if (isCursorPointer) {\n baseEvent.closestTrackedAncestor = baseEvent.event.target as HTMLElement;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n baseEvent.closestTrackedAncestor,\n dataAttributePrefix,\n );\n return baseEvent;\n }\n }\n // Retrieve additional event properties from the target element\n const closestTrackedAncestor = getClosestElement(baseEvent.event.target as HTMLElement, selectorAllowlist);\n if (closestTrackedAncestor) {\n baseEvent.closestTrackedAncestor = closestTrackedAncestor;\n baseEvent.targetElementProperties = this.getEventProperties(\n baseEvent.type,\n closestTrackedAncestor,\n dataAttributePrefix,\n );\n }\n return baseEvent;\n }\n\n return baseEvent;\n };\n\n extractDataFromDataSource = (dataSource: DataSource, contextElement: HTMLElement) => {\n // Extract from DOM Element\n if (dataSource.sourceType === 'DOM_ELEMENT') {\n const sourceElement = getDataSource(dataSource, contextElement);\n if (!sourceElement) {\n return undefined;\n }\n\n if (dataSource.elementExtractType === 'TEXT') {\n return this.getText(sourceElement);\n } else if (dataSource.elementExtractType === 'ATTRIBUTE' && dataSource.attribute) {\n return sourceElement.getAttribute(dataSource.attribute);\n }\n return undefined;\n }\n\n // TODO: Extract from other source types\n return undefined;\n };\n\n combineText = (element: Element): string => {\n let text = '';\n if (isNonSensitiveElement(element) && element.childNodes && element.childNodes.length) {\n element.childNodes.forEach((child) => {\n let childText = '';\n if (isTextNode(child)) {\n if (child.textContent) {\n childText = child.textContent;\n }\n } else {\n childText = this.combineText(child as Element);\n }\n text += childText\n .split(/(\\s+)/)\n .filter(this.isNonSensitiveString)\n .join('')\n .replace(/[\\r\\n]/g, ' ')\n .replace(/[ ]+/g, ' ')\n .substring(0, 255);\n });\n }\n return text;\n };\n\n getText = (element: Element): string => {\n return this.combineText(element).trim();\n };\n\n // Returns the element properties for the given element in Visual Labeling.\n getEventTagProps = (element: Element): Record<string, JSONValue> => {\n if (!element) {\n return {};\n }\n /* istanbul ignore next */\n const tag = element?.tagName?.toLowerCase?.();\n\n const properties = {\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG]: tag,\n [constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT]: this.getText(element),\n [constants.AMPLITUDE_EVENT_PROP_PAGE_URL]: window.location.href.split('?')[0],\n };\n return removeEmptyProperties(properties) as Record<string, JSONValue>;\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frustration-plugin.d.ts","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,8BAA8B,EAI/B,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"frustration-plugin.d.ts","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,8BAA8B,EAI/B,MAAM,2BAA2B,CAAC;AAUnC,KAAK,uBAAuB,GAAG,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE9E,eAAO,MAAM,iBAAiB,aAAa,8BAA8B,KAAQ,uBA+GhF,CAAC"}
|
|
@@ -11,6 +11,7 @@ var track_dead_click_1 = require("./autocapture/track-dead-click");
|
|
|
11
11
|
var track_rage_click_1 = require("./autocapture/track-rage-click");
|
|
12
12
|
var autocapture_plugin_1 = require("./autocapture-plugin");
|
|
13
13
|
var observables_1 = require("./observables");
|
|
14
|
+
var data_extractor_1 = require("./data-extractor");
|
|
14
15
|
var frustrationPlugin = function (options) {
|
|
15
16
|
var _a, _b, _c, _d, _e;
|
|
16
17
|
if (options === void 0) { options = {}; }
|
|
@@ -20,6 +21,7 @@ var frustrationPlugin = function (options) {
|
|
|
20
21
|
var rageCssSelectors = (_b = (_a = options.rageClicks) === null || _a === void 0 ? void 0 : _a.cssSelectorAllowlist) !== null && _b !== void 0 ? _b : analytics_core_1.DEFAULT_RAGE_CLICK_ALLOWLIST;
|
|
21
22
|
var deadCssSelectors = (_d = (_c = options.deadClicks) === null || _c === void 0 ? void 0 : _c.cssSelectorAllowlist) !== null && _d !== void 0 ? _d : analytics_core_1.DEFAULT_DEAD_CLICK_ALLOWLIST;
|
|
22
23
|
var dataAttributePrefix = (_e = options.dataAttributePrefix) !== null && _e !== void 0 ? _e : analytics_core_1.DEFAULT_DATA_ATTRIBUTE_PREFIX;
|
|
24
|
+
var dataExtractor = new data_extractor_1.DataExtractor(options);
|
|
23
25
|
// combine the two selector lists to determine which clicked elements should be filtered
|
|
24
26
|
var combinedCssSelectors = tslib_1.__spreadArray([], tslib_1.__read(new Set(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(rageCssSelectors), false), tslib_1.__read(deadCssSelectors), false))), false);
|
|
25
27
|
// Create observables on events on the window
|
|
@@ -27,18 +29,20 @@ var frustrationPlugin = function (options) {
|
|
|
27
29
|
var _a;
|
|
28
30
|
// Create Observables from direct user events
|
|
29
31
|
var clickObservable = (0, observables_1.createClickObservable)('pointerdown').pipe((0, rxjs_1.map)(function (click) {
|
|
30
|
-
return
|
|
32
|
+
return dataExtractor.addAdditionalEventProperties(click, 'click', combinedCssSelectors, dataAttributePrefix, true);
|
|
31
33
|
}), (0, rxjs_1.share)());
|
|
32
34
|
// Create observable for URL changes
|
|
33
35
|
var navigateObservable;
|
|
34
36
|
/* istanbul ignore next */
|
|
35
37
|
if (window.navigation) {
|
|
36
38
|
navigateObservable = (0, rxjs_1.fromEvent)(window.navigation, 'navigate').pipe((0, rxjs_1.map)(function (navigate) {
|
|
37
|
-
return
|
|
39
|
+
return dataExtractor.addAdditionalEventProperties(navigate, 'navigate', combinedCssSelectors, dataAttributePrefix);
|
|
38
40
|
}), (0, rxjs_1.share)());
|
|
39
41
|
}
|
|
40
42
|
// Track DOM Mutations
|
|
41
|
-
var enrichedMutationObservable = (0, observables_1.createMutationObservable)().pipe((0, rxjs_1.map)(function (mutation) {
|
|
43
|
+
var enrichedMutationObservable = (0, observables_1.createMutationObservable)().pipe((0, rxjs_1.map)(function (mutation) {
|
|
44
|
+
return dataExtractor.addAdditionalEventProperties(mutation, 'mutation', combinedCssSelectors, dataAttributePrefix);
|
|
45
|
+
}), (0, rxjs_1.share)());
|
|
42
46
|
return _a = {},
|
|
43
47
|
_a[autocapture_plugin_1.ObservablesEnum.ClickObservable] = clickObservable,
|
|
44
48
|
_a[autocapture_plugin_1.ObservablesEnum.ChangeObservable] = new rxjs_1.Observable(),
|
|
@@ -66,7 +70,9 @@ var frustrationPlugin = function (options) {
|
|
|
66
70
|
deadClickSubscription = (0, track_dead_click_1.trackDeadClick)({
|
|
67
71
|
amplitude: amplitude,
|
|
68
72
|
allObservables: allObservables,
|
|
69
|
-
getEventProperties: function (actionType, element) {
|
|
73
|
+
getEventProperties: function (actionType, element) {
|
|
74
|
+
return dataExtractor.getEventProperties(actionType, element, dataAttributePrefix);
|
|
75
|
+
},
|
|
70
76
|
shouldTrackDeadClick: shouldTrackDeadClick,
|
|
71
77
|
});
|
|
72
78
|
subscriptions.push(deadClickSubscription);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frustration-plugin.js","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":";;;;AAAA,0CAA0C;AAC1C,4DAQmC;AACnC,6DAAyC;AACzC,6BAAuE;AACvE,
|
|
1
|
+
{"version":3,"file":"frustration-plugin.js","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n BrowserClient,\n BrowserConfig,\n EnrichmentPlugin,\n FrustrationInteractionsOptions,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n DEFAULT_RAGE_CLICK_ALLOWLIST,\n DEFAULT_DEAD_CLICK_ALLOWLIST,\n} from '@amplitude/analytics-core';\nimport * as constants from './constants';\nimport { fromEvent, map, Observable, Subscription, share } from 'rxjs';\nimport { createShouldTrackEvent, ElementBasedTimestampedEvent, NavigateEvent } from './helpers';\nimport { trackDeadClick } from './autocapture/track-dead-click';\nimport { trackRageClicks } from './autocapture/track-rage-click';\nimport { AllWindowObservables, ObservablesEnum } from './autocapture-plugin';\nimport { createClickObservable, createMutationObservable } from './observables';\nimport { DataExtractor } from './data-extractor';\n\ntype BrowserEnrichmentPlugin = EnrichmentPlugin<BrowserClient, BrowserConfig>;\n\nexport const frustrationPlugin = (options: FrustrationInteractionsOptions = {}): BrowserEnrichmentPlugin => {\n const name = constants.FRUSTRATION_PLUGIN_NAME;\n const type = 'enrichment';\n\n const subscriptions: Subscription[] = [];\n\n const rageCssSelectors = options.rageClicks?.cssSelectorAllowlist ?? DEFAULT_RAGE_CLICK_ALLOWLIST;\n const deadCssSelectors = options.deadClicks?.cssSelectorAllowlist ?? DEFAULT_DEAD_CLICK_ALLOWLIST;\n\n const dataAttributePrefix = options.dataAttributePrefix ?? DEFAULT_DATA_ATTRIBUTE_PREFIX;\n\n const dataExtractor = new DataExtractor(options);\n\n // combine the two selector lists to determine which clicked elements should be filtered\n const combinedCssSelectors = [...new Set([...rageCssSelectors, ...deadCssSelectors])];\n\n // Create observables on events on the window\n const createObservables = (): AllWindowObservables => {\n // Create Observables from direct user events\n const clickObservable = createClickObservable('pointerdown').pipe(\n map((click) => {\n return dataExtractor.addAdditionalEventProperties(\n click,\n 'click',\n combinedCssSelectors,\n dataAttributePrefix,\n true, // capture when cursor is pointer\n );\n }),\n share(),\n );\n\n // Create observable for URL changes\n let navigateObservable;\n /* istanbul ignore next */\n if (window.navigation) {\n navigateObservable = fromEvent<NavigateEvent>(window.navigation, 'navigate').pipe(\n map((navigate) =>\n dataExtractor.addAdditionalEventProperties(navigate, 'navigate', combinedCssSelectors, dataAttributePrefix),\n ),\n share(),\n );\n }\n\n // Track DOM Mutations\n const enrichedMutationObservable = createMutationObservable().pipe(\n map((mutation) =>\n dataExtractor.addAdditionalEventProperties(mutation, 'mutation', combinedCssSelectors, dataAttributePrefix),\n ),\n share(),\n );\n\n return {\n [ObservablesEnum.ClickObservable]: clickObservable as Observable<ElementBasedTimestampedEvent<MouseEvent>>,\n [ObservablesEnum.ChangeObservable]: new Observable<ElementBasedTimestampedEvent<Event>>(), // Empty observable since we don't need change events\n [ObservablesEnum.NavigateObservable]: navigateObservable,\n [ObservablesEnum.MutationObservable]: enrichedMutationObservable,\n };\n };\n\n const setup: BrowserEnrichmentPlugin['setup'] = async (config, amplitude) => {\n /* istanbul ignore if */\n if (typeof document === 'undefined') {\n return;\n }\n\n // Create should track event functions for the different allowlists\n const shouldTrackRageClick = createShouldTrackEvent(options, rageCssSelectors);\n const shouldTrackDeadClick = createShouldTrackEvent(options, deadCssSelectors);\n\n // Create observables for events on the window\n const allObservables = createObservables();\n\n // Create subscriptions\n const rageClickSubscription = trackRageClicks({\n allObservables,\n amplitude,\n shouldTrackRageClick,\n });\n subscriptions.push(rageClickSubscription);\n\n const deadClickSubscription = trackDeadClick({\n amplitude,\n allObservables,\n getEventProperties: (actionType, element) =>\n dataExtractor.getEventProperties(actionType, element, dataAttributePrefix),\n shouldTrackDeadClick,\n });\n subscriptions.push(deadClickSubscription);\n\n /* istanbul ignore next */\n config?.loggerProvider?.log(`${name} has been successfully added.`);\n };\n\n const execute: BrowserEnrichmentPlugin['execute'] = async (event) => {\n return event;\n };\n\n const teardown = async () => {\n for (const subscription of subscriptions) {\n subscription.unsubscribe();\n }\n };\n\n return {\n name,\n type,\n setup,\n execute,\n teardown,\n };\n};\n"]}
|
package/lib/cjs/helpers.d.ts
CHANGED
|
@@ -5,10 +5,8 @@ export type JSONValue = string | number | boolean | null | {
|
|
|
5
5
|
export type shouldTrackEvent = (actionType: ActionType, element: Element) => boolean;
|
|
6
6
|
export declare const isElementPointerCursor: (element: Element, actionType: ActionType) => boolean;
|
|
7
7
|
export declare const createShouldTrackEvent: (autocaptureOptions: ElementInteractionsOptions, allowlist: string[], isAlwaysCaptureCursorPointer?: boolean) => shouldTrackEvent;
|
|
8
|
-
export declare const isNonSensitiveString: (text: string | null) => boolean;
|
|
9
8
|
export declare const isTextNode: (node: Node) => boolean;
|
|
10
9
|
export declare const isNonSensitiveElement: (element: Element) => boolean;
|
|
11
|
-
export declare const getText: (element: Element) => string;
|
|
12
10
|
export declare const getAttributesWithPrefix: (element: Element, prefix: string) => {
|
|
13
11
|
[key: string]: string;
|
|
14
12
|
};
|
|
@@ -18,20 +16,12 @@ export declare const removeEmptyProperties: (properties: {
|
|
|
18
16
|
}) => {
|
|
19
17
|
[key: string]: unknown;
|
|
20
18
|
};
|
|
21
|
-
export declare const getNearestLabel: (element: Element) => string;
|
|
22
19
|
export declare const querySelectUniqueElements: (root: Element | Document, selectors: string[]) => Element[];
|
|
23
20
|
export declare const getClosestElement: (element: Element | null, selectors: string[]) => Element | null;
|
|
24
|
-
export declare const getEventTagProps: (element: Element) => {
|
|
25
|
-
[key: string]: unknown;
|
|
26
|
-
};
|
|
27
21
|
export declare const asyncLoadScript: (url: string) => Promise<unknown>;
|
|
28
22
|
export declare function generateUniqueId(): string;
|
|
29
23
|
export declare const filterOutNonTrackableEvents: (event: ElementBasedTimestampedEvent<ElementBasedEvent>) => boolean;
|
|
30
|
-
export declare const getEventProperties: (actionType: ActionType, element: Element, dataAttributePrefix: string) => {
|
|
31
|
-
[key: string]: unknown;
|
|
32
|
-
};
|
|
33
24
|
export type AutoCaptureOptionsWithDefaults = Required<Pick<ElementInteractionsOptions, 'debounceTime' | 'cssSelectorAllowlist' | 'actionClickAllowlist'>> & ElementInteractionsOptions;
|
|
34
|
-
export declare const addAdditionalEventProperties: <T>(event: T, type: "error" | "navigate" | "change" | "click" | "rage" | "mutation", selectorAllowlist: string[], dataAttributePrefix: string, isCapturingCursorPointer?: boolean) => TimestampedEvent<T>;
|
|
35
25
|
export type BaseTimestampedEvent<T> = {
|
|
36
26
|
event: T;
|
|
37
27
|
timestamp: number;
|
package/lib/cjs/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,UAAU,EAAuB,MAAM,2BAA2B,CAAC;AAExG,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAIzG,MAAM,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;AAErF,eAAO,MAAM,sBAAsB,YAAa,OAAO,cAAc,UAAU,KAAG,OAKjF,CAAC;AAEF,eAAO,MAAM,sBAAsB,uBACb,0BAA0B,aACnC,MAAM,EAAE,6CAElB,gBA2DF,CAAC;AAEF,eAAO,MAAM,UAAU,SAAU,IAAI,YAEpC,CAAC;AAEF,eAAO,MAAM,qBAAqB,YAAa,OAAO,YAOrD,CAAC;AAEF,eAAO,MAAM,uBAAuB,YAAa,OAAO,UAAU,MAAM;;CAWvE,CAAC;AAEF,eAAO,MAAM,OAAO,UAAW,OAAO,YAOrC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;CAQjC,CAAC;AAEF,eAAO,MAAM,yBAAyB,SAAU,OAAO,GAAG,QAAQ,aAAa,MAAM,EAAE,KAAG,OAAO,EAchG,CAAC;AAGF,eAAO,MAAM,iBAAiB,YAAa,OAAO,GAAG,IAAI,aAAa,MAAM,EAAE,KAAG,OAAO,GAAG,IAU1F,CAAC;AAEF,eAAO,MAAM,eAAe,QAAS,MAAM,qBA2B1C,CAAC;AAEF,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,eAAO,MAAM,2BAA2B,UAAW,6BAA6B,iBAAiB,CAAC,KAAG,OAQpG,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CACnD,IAAI,CAAC,0BAA0B,EAAE,cAAc,GAAG,sBAAsB,GAAG,sBAAsB,CAAC,CACnG,GACC,0BAA0B,CAAC;AAG7B,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;IACpC,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;CACvE,CAAC;AAGF,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,KAAK,CAAC;AACnD,MAAM,MAAM,4BAA4B,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC,GAAG;IACtE,KAAK,EAAE,UAAU,GAAG,KAAK,CAAC;IAC1B,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,sBAAsB,EAAE,OAAO,CAAC;IAChC,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAC/B,KAAK,EAAE,4BAA4B,CAAC,iBAAiB,CAAC,KACnD,4BAA4B,CAAC,iBAAiB,CAAC,CAAC;AAGrD,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC,GAAG,4BAA4B,CAAC,CAAC,CAAC,CAAC;AAG5F,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,4BAA4B,CAAC,CAAC,CAAC,CAE/G;AAED,MAAM,WAAW,aAAc,SAAQ,KAAK;IAC1C,QAAQ,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IACpE,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;QAE/B,QAAQ,IAAI,GAAG,CAAC;KACjB,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAEvC,MAAM,IAAI,IAAI,CAAC;CAChB"}
|
package/lib/cjs/helpers.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isElementBasedEvent = exports.
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
3
|
+
exports.isElementBasedEvent = exports.filterOutNonTrackableEvents = exports.generateUniqueId = exports.asyncLoadScript = exports.getClosestElement = exports.querySelectUniqueElements = exports.removeEmptyProperties = exports.isEmpty = exports.getAttributesWithPrefix = exports.isNonSensitiveElement = exports.isTextNode = exports.createShouldTrackEvent = exports.isElementPointerCursor = void 0;
|
|
5
4
|
/* eslint-disable no-restricted-globals */
|
|
6
|
-
var constants = tslib_1.__importStar(require("./constants"));
|
|
7
5
|
var analytics_core_1 = require("@amplitude/analytics-core");
|
|
8
|
-
var hierarchy_1 = require("./hierarchy");
|
|
9
6
|
var SENSITIVE_TAGS = ['input', 'select', 'textarea'];
|
|
10
7
|
var isElementPointerCursor = function (element, actionType) {
|
|
11
8
|
var _a;
|
|
@@ -71,27 +68,6 @@ isAlwaysCaptureCursorPointer) {
|
|
|
71
68
|
};
|
|
72
69
|
};
|
|
73
70
|
exports.createShouldTrackEvent = createShouldTrackEvent;
|
|
74
|
-
var isNonSensitiveString = function (text) {
|
|
75
|
-
if (text == null) {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
if (typeof text === 'string') {
|
|
79
|
-
var ccRegex = /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;
|
|
80
|
-
if (ccRegex.test((text || '').replace(/[- ]/g, ''))) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
var ssnRegex = /(^\d{3}-?\d{2}-?\d{4}$)/;
|
|
84
|
-
if (ssnRegex.test(text)) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
var emailRegex = /[^\s@]+@[^\s@.]+\.[^\s@]+/;
|
|
88
|
-
if (emailRegex.test(text)) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return true;
|
|
93
|
-
};
|
|
94
|
-
exports.isNonSensitiveString = isNonSensitiveString;
|
|
95
71
|
var isTextNode = function (node) {
|
|
96
72
|
return !!node && node.nodeType === 3;
|
|
97
73
|
};
|
|
@@ -104,32 +80,6 @@ var isNonSensitiveElement = function (element) {
|
|
|
104
80
|
return !SENSITIVE_TAGS.includes(tag) && !isContentEditable;
|
|
105
81
|
};
|
|
106
82
|
exports.isNonSensitiveElement = isNonSensitiveElement;
|
|
107
|
-
// Maybe this can be simplified with element.innerText, keep and manual concatenating for now, more research needed.
|
|
108
|
-
var getText = function (element) {
|
|
109
|
-
var text = '';
|
|
110
|
-
if ((0, exports.isNonSensitiveElement)(element) && element.childNodes && element.childNodes.length) {
|
|
111
|
-
element.childNodes.forEach(function (child) {
|
|
112
|
-
var childText = '';
|
|
113
|
-
if ((0, exports.isTextNode)(child)) {
|
|
114
|
-
if (child.textContent) {
|
|
115
|
-
childText = child.textContent;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
childText = (0, exports.getText)(child);
|
|
120
|
-
}
|
|
121
|
-
text += childText
|
|
122
|
-
.split(/(\s+)/)
|
|
123
|
-
.filter(exports.isNonSensitiveString)
|
|
124
|
-
.join('')
|
|
125
|
-
.replace(/[\r\n]/g, ' ')
|
|
126
|
-
.replace(/[ ]+/g, ' ')
|
|
127
|
-
.substring(0, 255);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
return text;
|
|
131
|
-
};
|
|
132
|
-
exports.getText = getText;
|
|
133
83
|
var getAttributesWithPrefix = function (element, prefix) {
|
|
134
84
|
return element.getAttributeNames().reduce(function (attributes, attributeName) {
|
|
135
85
|
if (attributeName.startsWith(prefix)) {
|
|
@@ -160,27 +110,6 @@ var removeEmptyProperties = function (properties) {
|
|
|
160
110
|
}, {});
|
|
161
111
|
};
|
|
162
112
|
exports.removeEmptyProperties = removeEmptyProperties;
|
|
163
|
-
var getNearestLabel = function (element) {
|
|
164
|
-
var parent = element.parentElement;
|
|
165
|
-
if (!parent) {
|
|
166
|
-
return '';
|
|
167
|
-
}
|
|
168
|
-
var labelElement;
|
|
169
|
-
try {
|
|
170
|
-
labelElement = parent.querySelector(':scope>span,h1,h2,h3,h4,h5,h6');
|
|
171
|
-
}
|
|
172
|
-
catch (error) {
|
|
173
|
-
/* istanbul ignore next */
|
|
174
|
-
labelElement = null;
|
|
175
|
-
}
|
|
176
|
-
if (labelElement) {
|
|
177
|
-
/* istanbul ignore next */
|
|
178
|
-
var labelText = labelElement.textContent || '';
|
|
179
|
-
return (0, exports.isNonSensitiveString)(labelText) ? labelText : '';
|
|
180
|
-
}
|
|
181
|
-
return (0, exports.getNearestLabel)(parent);
|
|
182
|
-
};
|
|
183
|
-
exports.getNearestLabel = getNearestLabel;
|
|
184
113
|
var querySelectUniqueElements = function (root, selectors) {
|
|
185
114
|
if (root && 'querySelectorAll' in root && typeof root.querySelectorAll === 'function') {
|
|
186
115
|
var elementSet = selectors.reduce(function (elements, selector) {
|
|
@@ -210,23 +139,6 @@ var getClosestElement = function (element, selectors) {
|
|
|
210
139
|
return (0, exports.getClosestElement)(element === null || element === void 0 ? void 0 : element.parentElement, selectors);
|
|
211
140
|
};
|
|
212
141
|
exports.getClosestElement = getClosestElement;
|
|
213
|
-
// Returns the element properties for the given element in Visual Labeling.
|
|
214
|
-
var getEventTagProps = function (element) {
|
|
215
|
-
var _a;
|
|
216
|
-
var _b, _c;
|
|
217
|
-
if (!element) {
|
|
218
|
-
return {};
|
|
219
|
-
}
|
|
220
|
-
/* istanbul ignore next */
|
|
221
|
-
var tag = (_c = (_b = element === null || element === void 0 ? void 0 : element.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
222
|
-
var properties = (_a = {},
|
|
223
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG] = tag,
|
|
224
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT] = (0, exports.getText)(element),
|
|
225
|
-
_a[constants.AMPLITUDE_EVENT_PROP_PAGE_URL] = window.location.href.split('?')[0],
|
|
226
|
-
_a);
|
|
227
|
-
return (0, exports.removeEmptyProperties)(properties);
|
|
228
|
-
};
|
|
229
|
-
exports.getEventTagProps = getEventTagProps;
|
|
230
142
|
var asyncLoadScript = function (url) {
|
|
231
143
|
return new Promise(function (resolve, reject) {
|
|
232
144
|
var _a;
|
|
@@ -267,71 +179,6 @@ var filterOutNonTrackableEvents = function (event) {
|
|
|
267
179
|
return true;
|
|
268
180
|
};
|
|
269
181
|
exports.filterOutNonTrackableEvents = filterOutNonTrackableEvents;
|
|
270
|
-
// Returns the Amplitude event properties for the given element.
|
|
271
|
-
var getEventProperties = function (actionType, element, dataAttributePrefix) {
|
|
272
|
-
var _a;
|
|
273
|
-
var _b, _c;
|
|
274
|
-
/* istanbul ignore next */
|
|
275
|
-
var tag = (_c = (_b = element === null || element === void 0 ? void 0 : element.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
276
|
-
/* istanbul ignore next */
|
|
277
|
-
var rect = typeof element.getBoundingClientRect === 'function' ? element.getBoundingClientRect() : { left: null, top: null };
|
|
278
|
-
var ariaLabel = element.getAttribute('aria-label');
|
|
279
|
-
var attributes = (0, exports.getAttributesWithPrefix)(element, dataAttributePrefix);
|
|
280
|
-
var nearestLabel = (0, exports.getNearestLabel)(element);
|
|
281
|
-
/* istanbul ignore next */
|
|
282
|
-
var properties = (_a = {},
|
|
283
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ID] = element.getAttribute('id') || '',
|
|
284
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS] = element.getAttribute('class'),
|
|
285
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY] = (0, hierarchy_1.getHierarchy)(element),
|
|
286
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TAG] = tag,
|
|
287
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT] = (0, exports.getText)(element),
|
|
288
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT] = rect.left == null ? null : Math.round(rect.left),
|
|
289
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP] = rect.top == null ? null : Math.round(rect.top),
|
|
290
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL] = ariaLabel,
|
|
291
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES] = attributes,
|
|
292
|
-
_a[constants.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL] = nearestLabel,
|
|
293
|
-
_a[constants.AMPLITUDE_EVENT_PROP_PAGE_URL] = window.location.href.split('?')[0],
|
|
294
|
-
_a[constants.AMPLITUDE_EVENT_PROP_PAGE_TITLE] = (typeof document !== 'undefined' && document.title) || '',
|
|
295
|
-
_a[constants.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT] = window.innerHeight,
|
|
296
|
-
_a[constants.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH] = window.innerWidth,
|
|
297
|
-
_a);
|
|
298
|
-
if (tag === 'a' && actionType === 'click' && element instanceof HTMLAnchorElement) {
|
|
299
|
-
properties[constants.AMPLITUDE_EVENT_PROP_ELEMENT_HREF] = element.href;
|
|
300
|
-
}
|
|
301
|
-
return (0, exports.removeEmptyProperties)(properties);
|
|
302
|
-
};
|
|
303
|
-
exports.getEventProperties = getEventProperties;
|
|
304
|
-
var addAdditionalEventProperties = function (event, type, selectorAllowlist, dataAttributePrefix,
|
|
305
|
-
// capture the event if the cursor is a "pointer" when this element is clicked on
|
|
306
|
-
// reason: a "pointer" cursor indicates that an element should be interactable
|
|
307
|
-
// regardless of the element's tag name
|
|
308
|
-
isCapturingCursorPointer) {
|
|
309
|
-
if (isCapturingCursorPointer === void 0) { isCapturingCursorPointer = false; }
|
|
310
|
-
var baseEvent = {
|
|
311
|
-
event: event,
|
|
312
|
-
timestamp: Date.now(),
|
|
313
|
-
type: type,
|
|
314
|
-
};
|
|
315
|
-
if (isElementBasedEvent(baseEvent) && baseEvent.event.target !== null) {
|
|
316
|
-
if (isCapturingCursorPointer) {
|
|
317
|
-
var isCursorPointer = (0, exports.isElementPointerCursor)(baseEvent.event.target, baseEvent.type);
|
|
318
|
-
if (isCursorPointer) {
|
|
319
|
-
baseEvent.closestTrackedAncestor = baseEvent.event.target;
|
|
320
|
-
baseEvent.targetElementProperties = (0, exports.getEventProperties)(baseEvent.type, baseEvent.closestTrackedAncestor, dataAttributePrefix);
|
|
321
|
-
return baseEvent;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
// Retrieve additional event properties from the target element
|
|
325
|
-
var closestTrackedAncestor = (0, exports.getClosestElement)(baseEvent.event.target, selectorAllowlist);
|
|
326
|
-
if (closestTrackedAncestor) {
|
|
327
|
-
baseEvent.closestTrackedAncestor = closestTrackedAncestor;
|
|
328
|
-
baseEvent.targetElementProperties = (0, exports.getEventProperties)(baseEvent.type, closestTrackedAncestor, dataAttributePrefix);
|
|
329
|
-
}
|
|
330
|
-
return baseEvent;
|
|
331
|
-
}
|
|
332
|
-
return baseEvent;
|
|
333
|
-
};
|
|
334
|
-
exports.addAdditionalEventProperties = addAdditionalEventProperties;
|
|
335
182
|
// Type predicate
|
|
336
183
|
function isElementBasedEvent(event) {
|
|
337
184
|
return event.type === 'click' || event.type === 'change';
|