@posthog/browser-common 0.9.8 → 0.9.10

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.
@@ -0,0 +1,13 @@
1
+ import type { AutocaptureConfig as DomAutocaptureConfig, RageclickConfig } from '@posthog/types';
2
+ export interface AutocaptureConfig extends DomAutocaptureConfig {
3
+ enabled: boolean;
4
+ rageclick: boolean | RageclickConfig;
5
+ maskAllElementAttributes: boolean;
6
+ maskAllText: boolean;
7
+ disableCaptureUrlHashes: boolean;
8
+ getCurrentUrl?: (defaultUrl: string) => string;
9
+ remoteRequestsDisabled: boolean;
10
+ }
11
+ export interface AutocaptureConfigSource {
12
+ refresh(config: AutocaptureConfig): void;
13
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.r = (exports1)=>{
5
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
6
+ value: 'Module'
7
+ });
8
+ Object.defineProperty(exports1, '__esModule', {
9
+ value: true
10
+ });
11
+ };
12
+ })();
13
+ var __webpack_exports__ = {};
14
+ __webpack_require__.r(__webpack_exports__);
15
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
16
+ Object.defineProperty(exports, '__esModule', {
17
+ value: true
18
+ });
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,63 @@
1
+ import type { Client } from './client';
2
+ import type { Extension } from './extension';
3
+ import type { ExtensionToken } from './token';
4
+ import RageClick from './rageclick';
5
+ import type { Properties } from '@posthog/types';
6
+ import type { RemoteConfigResult } from './types/remote-config';
7
+ import type { AutocaptureConfigSource } from './autocapture-config';
8
+ export declare function getAugmentPropertiesFromElement(elem: Element): Properties;
9
+ export declare function previousElementSibling(el: Element): Element | null;
10
+ export declare function getDefaultProperties(eventType: string): Properties;
11
+ export declare function getPropertiesFromElement(elem: Element, maskAllAttributes: boolean, maskText: boolean, elementAttributeIgnorelist: string[] | undefined, disableCaptureUrlHashes?: boolean): Properties;
12
+ export declare function autocapturePropertiesForElement(target: Element, { e, maskAllElementAttributes, maskAllText, elementAttributeIgnoreList, elementsChainAsString, disableCaptureUrlHashes, }: {
13
+ e: Event;
14
+ maskAllElementAttributes: boolean;
15
+ maskAllText: boolean;
16
+ elementAttributeIgnoreList?: string[] | undefined;
17
+ elementsChainAsString: boolean;
18
+ disableCaptureUrlHashes: boolean;
19
+ }): {
20
+ props: Properties;
21
+ explicitNoCapture?: boolean;
22
+ target?: Element;
23
+ };
24
+ export declare const AutocaptureExtension: ExtensionToken<Autocapture>;
25
+ export declare class Autocapture implements Extension {
26
+ private readonly _configSource;
27
+ readonly name: ExtensionToken<Autocapture>;
28
+ _initialized: boolean;
29
+ _isDisabledServerSide: boolean | null;
30
+ _hasReceivedConfigResponse: boolean;
31
+ _elementSelectors: Set<string> | null;
32
+ private _elementSelectorsByOwner;
33
+ rageclicks: RageClick;
34
+ _elementsChainAsString: boolean;
35
+ private _listenerWindow;
36
+ private _listenerDocument;
37
+ private _client;
38
+ private readonly _config;
39
+ private _remoteConfigSubscription;
40
+ private _domEventHandler;
41
+ private _copiedTextHandler;
42
+ private _disposed;
43
+ private _pointerDown;
44
+ private _pointerExpiry;
45
+ private _clearPointer;
46
+ private _isExcludedPointerTarget;
47
+ private _trackPointer;
48
+ private _recoverClickTarget;
49
+ constructor(_configSource: AutocaptureConfigSource);
50
+ setup(client: Client): void;
51
+ dispose(): void;
52
+ private _refreshConfig;
53
+ private _compileUrlPatterns;
54
+ _addDomEventHandlers(): void;
55
+ private _removeDomEventHandlers;
56
+ startIfEnabled(): void;
57
+ onRemoteConfig(result: RemoteConfigResult): void;
58
+ setElementSelectors(selectors: Set<string>, owner?: object): void;
59
+ getElementSelectors(element: Element | null, additionalElement?: Element): string[] | null;
60
+ get isEnabled(): boolean;
61
+ private _captureEvent;
62
+ isBrowserSupported(): boolean;
63
+ }
@@ -0,0 +1,533 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ Autocapture: ()=>Autocapture,
41
+ AutocaptureExtension: ()=>AutocaptureExtension,
42
+ autocapturePropertiesForElement: ()=>autocapturePropertiesForElement,
43
+ getAugmentPropertiesFromElement: ()=>getAugmentPropertiesFromElement,
44
+ getDefaultProperties: ()=>getDefaultProperties,
45
+ getPropertiesFromElement: ()=>getPropertiesFromElement,
46
+ previousElementSibling: ()=>previousElementSibling
47
+ });
48
+ const general_utils_js_namespaceObject = require("./utils/general-utils.js");
49
+ const autocapture_utils_js_namespaceObject = require("./utils/autocapture-utils.js");
50
+ const external_rageclick_js_namespaceObject = require("./rageclick.js");
51
+ var external_rageclick_js_default = /*#__PURE__*/ __webpack_require__.n(external_rageclick_js_namespaceObject);
52
+ const external_constants_js_namespaceObject = require("./constants.js");
53
+ const core_namespaceObject = require("@posthog/core");
54
+ const logger_js_namespaceObject = require("./utils/logger.js");
55
+ const convert_to_url_js_namespaceObject = require("./utils/convert-to-url.js");
56
+ const element_utils_js_namespaceObject = require("./utils/element-utils.js");
57
+ const getWindow = ()=>"u" < typeof window ? void 0 : window;
58
+ const getDocument = ()=>"u" < typeof document ? void 0 : document;
59
+ const COPY_AUTOCAPTURE_EVENT = '$copy_autocapture';
60
+ const logger = (0, logger_js_namespaceObject.createLogger)('[AutoCapture]');
61
+ function limitText(length, text) {
62
+ if (text.length > length) return text.slice(0, length) + '...';
63
+ return text;
64
+ }
65
+ function getAugmentPropertiesFromElement(elem) {
66
+ const shouldCaptureEl = (0, autocapture_utils_js_namespaceObject.shouldCaptureElement)(elem);
67
+ if (!shouldCaptureEl) return {};
68
+ const props = {};
69
+ (0, general_utils_js_namespaceObject.each)(elem.attributes, function(attr) {
70
+ if (attr.name && 0 === attr.name.indexOf('data-ph-capture-attribute')) {
71
+ const propertyKey = attr.name.replace('data-ph-capture-attribute-', '');
72
+ const propertyValue = attr.value;
73
+ if (propertyKey && propertyValue && (0, autocapture_utils_js_namespaceObject.shouldCaptureValue)(propertyValue)) props[propertyKey] = propertyValue;
74
+ }
75
+ });
76
+ return props;
77
+ }
78
+ function previousElementSibling(el) {
79
+ if (el.previousElementSibling) return el.previousElementSibling;
80
+ let _el = el;
81
+ do _el = _el.previousSibling;
82
+ while (_el && !(0, element_utils_js_namespaceObject.isElementNode)(_el));
83
+ return _el;
84
+ }
85
+ function getDefaultProperties(eventType) {
86
+ return {
87
+ $event_type: eventType,
88
+ $ce_version: 1
89
+ };
90
+ }
91
+ function getPropertiesFromElement(elem, maskAllAttributes, maskText, elementAttributeIgnorelist, disableCaptureUrlHashes = false) {
92
+ const tag_name = elem.tagName.toLowerCase();
93
+ const props = {
94
+ tag_name: tag_name
95
+ };
96
+ if (autocapture_utils_js_namespaceObject.autocaptureCompatibleElements.indexOf(tag_name) > -1 && !maskText) if ('a' === tag_name.toLowerCase() || 'button' === tag_name.toLowerCase()) props['$el_text'] = limitText(1024, (0, autocapture_utils_js_namespaceObject.getDirectAndNestedSpanText)(elem));
97
+ else props['$el_text'] = limitText(1024, (0, autocapture_utils_js_namespaceObject.getSafeText)(elem));
98
+ const classes = (0, autocapture_utils_js_namespaceObject.getClassNames)(elem);
99
+ if (!maskAllAttributes && !elementAttributeIgnorelist?.includes('class') && classes.length > 0) props['classes'] = classes.filter(function(c) {
100
+ return '' !== c;
101
+ });
102
+ (0, general_utils_js_namespaceObject.each)(elem.attributes, function(attr) {
103
+ if ((0, autocapture_utils_js_namespaceObject.isSensitiveElement)(elem) && -1 === [
104
+ 'name',
105
+ 'id',
106
+ 'class',
107
+ 'aria-label'
108
+ ].indexOf(attr.name)) return;
109
+ if (elementAttributeIgnorelist?.includes(attr.name)) return;
110
+ if (!maskAllAttributes && (0, autocapture_utils_js_namespaceObject.shouldCaptureValue)(attr.value) && !(0, autocapture_utils_js_namespaceObject.isAngularStyleAttr)(attr.name)) {
111
+ let value = attr.value;
112
+ if ('class' === attr.name) value = (0, autocapture_utils_js_namespaceObject.splitClassString)(value).join(' ');
113
+ props['attr__' + attr.name] = limitText(1024, 'href' === attr.name && disableCaptureUrlHashes ? (0, core_namespaceObject.stripUrlHash)(value) : value);
114
+ }
115
+ });
116
+ let nthChild = 1;
117
+ let nthOfType = 1;
118
+ let currentElem = elem;
119
+ while(currentElem = previousElementSibling(currentElem)){
120
+ nthChild++;
121
+ if (currentElem.tagName === elem.tagName) nthOfType++;
122
+ }
123
+ props['nth_child'] = nthChild;
124
+ props['nth_of_type'] = nthOfType;
125
+ return props;
126
+ }
127
+ function autocapturePropertiesForElement(target, { e, maskAllElementAttributes, maskAllText, elementAttributeIgnoreList, elementsChainAsString, disableCaptureUrlHashes }) {
128
+ if (!(0, element_utils_js_namespaceObject.isElementNode)(target)) return {
129
+ props: {}
130
+ };
131
+ const targetElementList = [
132
+ target
133
+ ];
134
+ const seen = new Set([
135
+ target
136
+ ]);
137
+ let curEl = target;
138
+ while(curEl.parentNode && !(0, element_utils_js_namespaceObject.isTag)(curEl, 'body')){
139
+ if (targetElementList.length >= autocapture_utils_js_namespaceObject.MAX_DOM_ANCESTOR_DEPTH) break;
140
+ if ((0, element_utils_js_namespaceObject.isShadowRoot)(curEl.parentNode)) {
141
+ const host = curEl.parentNode.host;
142
+ if (seen.has(host)) break;
143
+ seen.add(host);
144
+ targetElementList.push(host);
145
+ curEl = host;
146
+ continue;
147
+ }
148
+ if (!(0, element_utils_js_namespaceObject.isElementNode)(curEl.parentNode)) break;
149
+ if (seen.has(curEl.parentNode)) break;
150
+ seen.add(curEl.parentNode);
151
+ targetElementList.push(curEl.parentNode);
152
+ curEl = curEl.parentNode;
153
+ }
154
+ const controlIndex = 'click' === e.type && 'http://www.w3.org/2000/svg' === target.namespaceURI ? targetElementList.findIndex((el)=>(0, element_utils_js_namespaceObject.isTag)(el, 'button') || (0, element_utils_js_namespaceObject.isTag)(el, 'a')) : -1;
155
+ if (controlIndex > 0) maskAllText = maskAllText || targetElementList.slice(0, controlIndex + 1).some((el)=>!(0, autocapture_utils_js_namespaceObject.shouldCaptureElement)(el) || (0, autocapture_utils_js_namespaceObject.isSensitiveElement)(el));
156
+ const elementsJson = [];
157
+ const autocaptureAugmentProperties = {};
158
+ let href = false;
159
+ let explicitNoCapture = false;
160
+ (0, general_utils_js_namespaceObject.each)(targetElementList, (el)=>{
161
+ const shouldCaptureEl = (0, autocapture_utils_js_namespaceObject.shouldCaptureElement)(el);
162
+ if ((0, element_utils_js_namespaceObject.isTag)(el, 'a') && !maskAllElementAttributes && !elementAttributeIgnoreList?.includes('href')) {
163
+ const hrefAttr = el.getAttribute('href');
164
+ href = shouldCaptureEl && !!hrefAttr && (0, autocapture_utils_js_namespaceObject.shouldCaptureValue)(hrefAttr) ? disableCaptureUrlHashes ? (0, core_namespaceObject.stripUrlHash)(hrefAttr) : hrefAttr : false;
165
+ }
166
+ const classes = (0, autocapture_utils_js_namespaceObject.getClassNames)(el);
167
+ if ((0, core_namespaceObject.includes)(classes, 'ph-no-capture')) explicitNoCapture = true;
168
+ elementsJson.push(getPropertiesFromElement(el, maskAllElementAttributes, maskAllText, elementAttributeIgnoreList, disableCaptureUrlHashes));
169
+ const augmentProperties = getAugmentPropertiesFromElement(el);
170
+ (0, general_utils_js_namespaceObject.each)(augmentProperties, (value, key)=>{
171
+ if (!Object.prototype.hasOwnProperty.call(autocaptureAugmentProperties, key)) autocaptureAugmentProperties[key] = value;
172
+ });
173
+ });
174
+ if (explicitNoCapture) return {
175
+ props: {},
176
+ explicitNoCapture
177
+ };
178
+ if (controlIndex > 0) {
179
+ target = targetElementList[controlIndex];
180
+ elementsJson.splice(0, controlIndex);
181
+ }
182
+ if (!maskAllText) if ((0, element_utils_js_namespaceObject.isTag)(target, 'a') || (0, element_utils_js_namespaceObject.isTag)(target, 'button')) elementsJson[0]['$el_text'] = (0, autocapture_utils_js_namespaceObject.getDirectAndNestedSpanText)(target);
183
+ else elementsJson[0]['$el_text'] = (0, autocapture_utils_js_namespaceObject.getSafeText)(target);
184
+ let externalHref;
185
+ if (href) {
186
+ elementsJson[0]['attr__href'] = href;
187
+ const hrefHost = (0, convert_to_url_js_namespaceObject.convertToURL)(href)?.host;
188
+ const locationHost = getWindow()?.location?.host;
189
+ if (hrefHost && locationHost && hrefHost !== locationHost) externalHref = href;
190
+ }
191
+ const props = (0, general_utils_js_namespaceObject.extend)(getDefaultProperties(e.type), elementsChainAsString ? {} : {
192
+ $elements: elementsJson
193
+ }, {
194
+ $elements_chain: (0, autocapture_utils_js_namespaceObject.getElementsChainString)(elementsJson)
195
+ }, elementsJson[0]?.['$el_text'] ? {
196
+ $el_text: elementsJson[0]?.['$el_text']
197
+ } : {}, externalHref && 'click' === e.type ? {
198
+ $external_click_url: externalHref
199
+ } : {}, autocaptureAugmentProperties);
200
+ return {
201
+ props,
202
+ target
203
+ };
204
+ }
205
+ const AutocaptureExtension = 'autocapture';
206
+ class Autocapture {
207
+ _clearPointer() {
208
+ this._pointerDown = void 0;
209
+ clearTimeout(this._pointerExpiry);
210
+ this._pointerExpiry = void 0;
211
+ }
212
+ _isExcludedPointerTarget(target) {
213
+ if (!(0, autocapture_utils_js_namespaceObject.shouldCaptureElement)(target)) return true;
214
+ const ignorelist = this._refreshConfig().css_selector_ignorelist ?? autocapture_utils_js_namespaceObject.DEFAULT_AUTOCAPTURE_IGNORE_LIST;
215
+ const seen = new Set();
216
+ let el = target;
217
+ while(el){
218
+ if (seen.size >= autocapture_utils_js_namespaceObject.MAX_DOM_ANCESTOR_DEPTH || seen.has(el)) return true;
219
+ seen.add(el);
220
+ const current = el;
221
+ const classes = (0, autocapture_utils_js_namespaceObject.getClassNames)(current);
222
+ if ((0, core_namespaceObject.includes)(classes, 'ph-no-capture') || (0, core_namespaceObject.includes)(classes, 'ph-sensitive') || (0, autocapture_utils_js_namespaceObject.isSensitiveElement)(current) || ignorelist.some((selector)=>(0, autocapture_utils_js_namespaceObject.elementMatchesCSSSelector)(current, selector))) return true;
223
+ const parent = el.parentNode;
224
+ el = (0, element_utils_js_namespaceObject.isShadowRoot)(parent) ? parent.host : parent && (0, element_utils_js_namespaceObject.isElementNode)(parent) ? parent : null;
225
+ }
226
+ return false;
227
+ }
228
+ _trackPointer(e) {
229
+ if (!this.isEnabled || 'pointercancel' === e.type) return void this._clearPointer();
230
+ if ('pointerdown' === e.type) {
231
+ this._clearPointer();
232
+ const target = (0, autocapture_utils_js_namespaceObject.getEventTarget)(e);
233
+ if (e.isPrimary && 0 === e.button && !e.ctrlKey && target && (0, element_utils_js_namespaceObject.isElementNode)(target)) this._pointerDown = {
234
+ target,
235
+ excluded: this._isExcludedPointerTarget(target),
236
+ id: e.pointerId,
237
+ x: e.clientX,
238
+ y: e.clientY,
239
+ released: false,
240
+ distinctId: this._client?.distinctId
241
+ };
242
+ return;
243
+ }
244
+ const down = this._pointerDown;
245
+ if (!down) return;
246
+ if (e.pointerId !== down.id || Math.abs(e.clientX - down.x) > 5 || Math.abs(e.clientY - down.y) > 5) this._clearPointer();
247
+ else if ('pointerup' === e.type) {
248
+ down.released = true;
249
+ this._pointerExpiry = setTimeout(()=>this._clearPointer(), 0);
250
+ }
251
+ }
252
+ _recoverClickTarget(e) {
253
+ const down = this._pointerDown;
254
+ this._clearPointer();
255
+ const target = (0, autocapture_utils_js_namespaceObject.getEventTarget)(e);
256
+ if (down?.released && down.target.isConnected && down.distinctId === this._client?.distinctId && e.pointerId === down.id && (e.detail > 0 || 'touch' === e.pointerType || 'pen' === e.pointerType) && 0 === e.button && Math.abs(e.clientX - down.x) <= 5 && Math.abs(e.clientY - down.y) <= 5 && target && ((0, element_utils_js_namespaceObject.isTag)(target, 'html') || (0, element_utils_js_namespaceObject.isTag)(target, 'body'))) {
257
+ if (down.excluded) return null;
258
+ const ignorelist = this._refreshConfig().css_selector_ignorelist ?? autocapture_utils_js_namespaceObject.DEFAULT_AUTOCAPTURE_IGNORE_LIST;
259
+ const excludedRoot = [
260
+ target,
261
+ getDocument()?.documentElement,
262
+ getDocument()?.body
263
+ ].some((root)=>{
264
+ if (!root) return false;
265
+ const classes = (0, autocapture_utils_js_namespaceObject.getClassNames)(root);
266
+ return (0, core_namespaceObject.includes)(classes, 'ph-no-capture') || (0, core_namespaceObject.includes)(classes, 'ph-sensitive') || !(0, autocapture_utils_js_namespaceObject.shouldCaptureElement)(root) || (0, autocapture_utils_js_namespaceObject.isSensitiveElement)(root) || ignorelist.some((selector)=>(0, autocapture_utils_js_namespaceObject.elementMatchesCSSSelector)(root, selector));
267
+ });
268
+ if (excludedRoot) return null;
269
+ return down.target;
270
+ }
271
+ }
272
+ constructor(_configSource){
273
+ this._configSource = _configSource;
274
+ this.name = AutocaptureExtension;
275
+ this._initialized = false;
276
+ this._isDisabledServerSide = null;
277
+ this._hasReceivedConfigResponse = false;
278
+ this._elementSelectorsByOwner = new Map();
279
+ this._elementsChainAsString = false;
280
+ this._config = {
281
+ enabled: false,
282
+ rageclick: false,
283
+ maskAllElementAttributes: false,
284
+ maskAllText: false,
285
+ disableCaptureUrlHashes: false,
286
+ remoteRequestsDisabled: false
287
+ };
288
+ this._disposed = false;
289
+ this._configSource.refresh(this._config);
290
+ this.rageclicks = new (external_rageclick_js_default())(this._config.rageclick);
291
+ this._elementSelectors = null;
292
+ }
293
+ setup(client) {
294
+ this._compileUrlPatterns();
295
+ this._client = client;
296
+ const subscription = client.onRemoteConfig(this.onRemoteConfig.bind(this));
297
+ if (this._disposed) return void subscription.dispose();
298
+ this._remoteConfigSubscription = subscription;
299
+ this.startIfEnabled();
300
+ }
301
+ dispose() {
302
+ if (this._disposed) return;
303
+ this._disposed = true;
304
+ this._client = void 0;
305
+ this._remoteConfigSubscription?.dispose();
306
+ this._remoteConfigSubscription = void 0;
307
+ this._elementSelectorsByOwner.clear();
308
+ this._elementSelectors = null;
309
+ this._removeDomEventHandlers();
310
+ }
311
+ _refreshConfig() {
312
+ this._configSource.refresh(this._config);
313
+ return this._config;
314
+ }
315
+ _compileUrlPatterns() {
316
+ this._refreshConfig();
317
+ this._config.url_allowlist = this._config.url_allowlist?.map((url)=>new RegExp(url));
318
+ this._config.url_ignorelist = this._config.url_ignorelist?.map((url)=>new RegExp(url));
319
+ return this._config;
320
+ }
321
+ _addDomEventHandlers() {
322
+ const window1 = getWindow();
323
+ const document1 = getDocument();
324
+ if (!this.isBrowserSupported()) return void logger.info('Disabling Automatic Event Collection because this browser is not supported');
325
+ if (!window1 || !document1) return;
326
+ this._listenerWindow = window1;
327
+ this._listenerDocument = document1;
328
+ const handler = this._domEventHandler = (e)=>{
329
+ e = e || window1?.event;
330
+ try {
331
+ if ('blur' === e.type) return void this._clearPointer();
332
+ if (0 === e.type.indexOf('pointer')) return void this._trackPointer(e);
333
+ const target = 'click' === e.type ? this._recoverClickTarget(e) : void 0;
334
+ if ((0, core_namespaceObject.isNull)(target)) return;
335
+ this._captureEvent(e, '$autocapture', target);
336
+ } catch (error) {
337
+ logger.error('Failed to capture event', error);
338
+ }
339
+ };
340
+ (0, general_utils_js_namespaceObject.addEventListener)(window1, 'blur', handler);
341
+ (0, general_utils_js_namespaceObject.addEventListener)(document1, 'submit', handler, {
342
+ capture: true
343
+ });
344
+ (0, general_utils_js_namespaceObject.addEventListener)(document1, 'change', handler, {
345
+ capture: true
346
+ });
347
+ (0, general_utils_js_namespaceObject.addEventListener)(document1, 'click', handler, {
348
+ capture: true
349
+ });
350
+ (0, general_utils_js_namespaceObject.each)([
351
+ 'pointerdown',
352
+ 'pointermove',
353
+ 'pointerup',
354
+ 'pointercancel'
355
+ ], (type)=>{
356
+ (0, general_utils_js_namespaceObject.addEventListener)(document1, type, handler, {
357
+ capture: true
358
+ });
359
+ });
360
+ if (this._refreshConfig().capture_copied_text) {
361
+ const copiedTextHandler = this._copiedTextHandler = (e)=>{
362
+ e = e || window1?.event;
363
+ try {
364
+ this._captureEvent(e, COPY_AUTOCAPTURE_EVENT);
365
+ } catch (error) {
366
+ logger.error('Failed to capture clipboard event', error);
367
+ }
368
+ };
369
+ (0, general_utils_js_namespaceObject.addEventListener)(document1, 'copy', copiedTextHandler, {
370
+ capture: true
371
+ });
372
+ (0, general_utils_js_namespaceObject.addEventListener)(document1, 'cut', copiedTextHandler, {
373
+ capture: true
374
+ });
375
+ (0, general_utils_js_namespaceObject.addEventListener)(document1, 'paste', copiedTextHandler, {
376
+ capture: true
377
+ });
378
+ }
379
+ }
380
+ _removeDomEventHandlers() {
381
+ const window1 = this._listenerWindow;
382
+ const document1 = this._listenerDocument;
383
+ this._clearPointer();
384
+ if (this._domEventHandler) {
385
+ window1?.removeEventListener('blur', this._domEventHandler);
386
+ (0, general_utils_js_namespaceObject.each)([
387
+ 'pointerdown',
388
+ 'pointermove',
389
+ 'pointerup',
390
+ 'pointercancel'
391
+ ], (type)=>{
392
+ document1?.removeEventListener(type, this._domEventHandler, true);
393
+ });
394
+ document1?.removeEventListener('submit', this._domEventHandler, true);
395
+ document1?.removeEventListener('change', this._domEventHandler, true);
396
+ document1?.removeEventListener('click', this._domEventHandler, true);
397
+ this._domEventHandler = void 0;
398
+ }
399
+ if (this._copiedTextHandler) {
400
+ document1?.removeEventListener('copy', this._copiedTextHandler, true);
401
+ document1?.removeEventListener('cut', this._copiedTextHandler, true);
402
+ document1?.removeEventListener('paste', this._copiedTextHandler, true);
403
+ this._copiedTextHandler = void 0;
404
+ }
405
+ this._listenerWindow = void 0;
406
+ this._listenerDocument = void 0;
407
+ this._initialized = false;
408
+ }
409
+ startIfEnabled() {
410
+ if (!this.isEnabled) this._clearPointer();
411
+ if (!this._disposed && this._client && this.isEnabled && !this._initialized) {
412
+ this._addDomEventHandlers();
413
+ this._initialized = true;
414
+ }
415
+ }
416
+ onRemoteConfig(result) {
417
+ if (this._disposed) return;
418
+ this._hasReceivedConfigResponse = true;
419
+ if (!result.ok) return void this.startIfEnabled();
420
+ const response = result.config;
421
+ if (response.elementsChainAsString) this._elementsChainAsString = response.elementsChainAsString;
422
+ const optOut = response['autocapture_opt_out'];
423
+ if ((0, core_namespaceObject.isBoolean)(optOut)) {
424
+ this._client?.kv.set(external_constants_js_namespaceObject.AUTOCAPTURE_DISABLED_SERVER_SIDE, optOut);
425
+ this._isDisabledServerSide = optOut;
426
+ }
427
+ this.startIfEnabled();
428
+ }
429
+ setElementSelectors(selectors, owner = this) {
430
+ if (this._disposed) return;
431
+ if (selectors.size) this._elementSelectorsByOwner.set(owner, new Set(selectors));
432
+ else this._elementSelectorsByOwner.delete(owner);
433
+ const combined = new Set();
434
+ this._elementSelectorsByOwner.forEach((contribution)=>{
435
+ contribution.forEach((selector)=>combined.add(selector));
436
+ });
437
+ this._elementSelectors = combined;
438
+ }
439
+ getElementSelectors(element, additionalElement) {
440
+ const elementSelectors = [];
441
+ this._elementSelectors?.forEach((selector)=>{
442
+ const matchedElements = getDocument()?.querySelectorAll(selector);
443
+ matchedElements?.forEach((matchedElement)=>{
444
+ if ((element === matchedElement || additionalElement === matchedElement) && !(0, core_namespaceObject.includes)(elementSelectors, selector)) elementSelectors.push(selector);
445
+ });
446
+ });
447
+ return elementSelectors;
448
+ }
449
+ get isEnabled() {
450
+ if (this._disposed) return false;
451
+ const persistedServerDisabled = this._client?.kv.get(external_constants_js_namespaceObject.AUTOCAPTURE_DISABLED_SERVER_SIDE);
452
+ const memoryDisabled = this._isDisabledServerSide;
453
+ const config = this._refreshConfig();
454
+ if (!config.remoteRequestsDisabled && !this._hasReceivedConfigResponse) return false;
455
+ const clientConfigOnly = config.remoteRequestsDisabled && !this._hasReceivedConfigResponse;
456
+ if ((0, core_namespaceObject.isNull)(memoryDisabled) && !(0, core_namespaceObject.isBoolean)(persistedServerDisabled) && !clientConfigOnly) return false;
457
+ const disabledServer = this._isDisabledServerSide ?? !!persistedServerDisabled;
458
+ const disabledClient = !config.enabled;
459
+ return !disabledClient && !disabledServer;
460
+ }
461
+ _captureEvent(e, eventName = '$autocapture', targetOverride) {
462
+ if (!this.isEnabled) return void this._clearPointer();
463
+ let target = targetOverride || (0, autocapture_utils_js_namespaceObject.getEventTarget)(e);
464
+ if ((0, element_utils_js_namespaceObject.isTextNode)(target)) target = target.parentNode || null;
465
+ const config = this._compileUrlPatterns();
466
+ if ('$autocapture' === eventName && 'click' === e.type && e instanceof MouseEvent) {
467
+ if (!!config.rageclick && this.rageclicks?.isRageClick(e.clientX, e.clientY, e.timeStamp || new Date().getTime())) {
468
+ if ((0, autocapture_utils_js_namespaceObject.shouldCaptureRageclick)(target, config.rageclick)) this._captureEvent(e, '$rageclick', targetOverride);
469
+ }
470
+ }
471
+ const isClipboardAutocapture = eventName === COPY_AUTOCAPTURE_EVENT;
472
+ const eventConfig = isClipboardAutocapture ? {
473
+ ...config,
474
+ dom_event_allowlist: void 0
475
+ } : config;
476
+ if (target && (0, autocapture_utils_js_namespaceObject.shouldCaptureDomEvent)(target, e, eventConfig, isClipboardAutocapture, isClipboardAutocapture ? [
477
+ 'copy',
478
+ 'cut',
479
+ 'paste'
480
+ ] : void 0, {
481
+ config: {
482
+ get_current_url: config.getCurrentUrl
483
+ }
484
+ })) {
485
+ const { props, explicitNoCapture, target: attributedTarget } = autocapturePropertiesForElement(target, {
486
+ e,
487
+ maskAllElementAttributes: config.maskAllElementAttributes,
488
+ maskAllText: config.maskAllText,
489
+ elementAttributeIgnoreList: config.element_attribute_ignorelist,
490
+ elementsChainAsString: this._elementsChainAsString,
491
+ disableCaptureUrlHashes: config.disableCaptureUrlHashes
492
+ });
493
+ if (explicitNoCapture) return false;
494
+ const elementSelectors = this.getElementSelectors(target, attributedTarget);
495
+ if (elementSelectors && elementSelectors.length > 0) props['$element_selectors'] = elementSelectors;
496
+ if (eventName === COPY_AUTOCAPTURE_EVENT) {
497
+ const clipType = e.type || 'clipboard';
498
+ if ('paste' !== clipType) {
499
+ const selectedText = getWindow()?.getSelection()?.toString();
500
+ const selectedContent = (0, autocapture_utils_js_namespaceObject.makeSafeText)(selectedText);
501
+ if (!selectedContent) return false;
502
+ props['$selected_content'] = selectedContent;
503
+ props['$clipboard_text_length'] = selectedText?.length ?? 0;
504
+ }
505
+ props['$copy_type'] = clipType;
506
+ }
507
+ this._client?.capture(eventName, props);
508
+ return true;
509
+ }
510
+ }
511
+ isBrowserSupported() {
512
+ return (0, core_namespaceObject.isFunction)(getDocument()?.querySelectorAll);
513
+ }
514
+ }
515
+ exports.Autocapture = __webpack_exports__.Autocapture;
516
+ exports.AutocaptureExtension = __webpack_exports__.AutocaptureExtension;
517
+ exports.autocapturePropertiesForElement = __webpack_exports__.autocapturePropertiesForElement;
518
+ exports.getAugmentPropertiesFromElement = __webpack_exports__.getAugmentPropertiesFromElement;
519
+ exports.getDefaultProperties = __webpack_exports__.getDefaultProperties;
520
+ exports.getPropertiesFromElement = __webpack_exports__.getPropertiesFromElement;
521
+ exports.previousElementSibling = __webpack_exports__.previousElementSibling;
522
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
523
+ "Autocapture",
524
+ "AutocaptureExtension",
525
+ "autocapturePropertiesForElement",
526
+ "getAugmentPropertiesFromElement",
527
+ "getDefaultProperties",
528
+ "getPropertiesFromElement",
529
+ "previousElementSibling"
530
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
531
+ Object.defineProperty(exports, '__esModule', {
532
+ value: true
533
+ });