@amplitude/plugin-autocapture-browser 1.0.0-beta.2 → 1.0.0-beta.3

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.
Files changed (72) hide show
  1. package/lib/cjs/autocapture/track-action-click.d.ts +13 -0
  2. package/lib/cjs/autocapture/track-action-click.d.ts.map +1 -0
  3. package/lib/cjs/autocapture/track-action-click.js +43 -0
  4. package/lib/cjs/autocapture/track-action-click.js.map +1 -0
  5. package/lib/cjs/autocapture/track-change.d.ts +11 -0
  6. package/lib/cjs/autocapture/track-change.d.ts.map +1 -0
  7. package/lib/cjs/autocapture/track-change.js +19 -0
  8. package/lib/cjs/autocapture/track-change.js.map +1 -0
  9. package/lib/cjs/autocapture/track-click.d.ts +10 -0
  10. package/lib/cjs/autocapture/track-click.d.ts.map +1 -0
  11. package/lib/cjs/autocapture/track-click.js +53 -0
  12. package/lib/cjs/autocapture/track-click.js.map +1 -0
  13. package/lib/cjs/autocapture-plugin.d.ts +66 -0
  14. package/lib/cjs/autocapture-plugin.d.ts.map +1 -1
  15. package/lib/cjs/autocapture-plugin.js +122 -130
  16. package/lib/cjs/autocapture-plugin.js.map +1 -1
  17. package/lib/cjs/helpers.d.ts +5 -0
  18. package/lib/cjs/helpers.d.ts.map +1 -1
  19. package/lib/cjs/helpers.js +63 -3
  20. package/lib/cjs/helpers.js.map +1 -1
  21. package/lib/cjs/libs/messenger.d.ts +3 -1
  22. package/lib/cjs/libs/messenger.d.ts.map +1 -1
  23. package/lib/cjs/libs/messenger.js +3 -1
  24. package/lib/cjs/libs/messenger.js.map +1 -1
  25. package/lib/cjs/version.d.ts +1 -1
  26. package/lib/cjs/version.js +1 -1
  27. package/lib/cjs/version.js.map +1 -1
  28. package/lib/esm/autocapture/track-action-click.d.ts +13 -0
  29. package/lib/esm/autocapture/track-action-click.d.ts.map +1 -0
  30. package/lib/esm/autocapture/track-action-click.js +40 -0
  31. package/lib/esm/autocapture/track-action-click.js.map +1 -0
  32. package/lib/esm/autocapture/track-change.d.ts +11 -0
  33. package/lib/esm/autocapture/track-change.d.ts.map +1 -0
  34. package/lib/esm/autocapture/track-change.js +16 -0
  35. package/lib/esm/autocapture/track-change.js.map +1 -0
  36. package/lib/esm/autocapture/track-click.d.ts +10 -0
  37. package/lib/esm/autocapture/track-click.d.ts.map +1 -0
  38. package/lib/esm/autocapture/track-click.js +50 -0
  39. package/lib/esm/autocapture/track-click.js.map +1 -0
  40. package/lib/esm/autocapture-plugin.d.ts +66 -0
  41. package/lib/esm/autocapture-plugin.d.ts.map +1 -1
  42. package/lib/esm/autocapture-plugin.js +122 -131
  43. package/lib/esm/autocapture-plugin.js.map +1 -1
  44. package/lib/esm/helpers.d.ts +5 -0
  45. package/lib/esm/helpers.d.ts.map +1 -1
  46. package/lib/esm/helpers.js +60 -2
  47. package/lib/esm/helpers.js.map +1 -1
  48. package/lib/esm/libs/messenger.d.ts +3 -1
  49. package/lib/esm/libs/messenger.d.ts.map +1 -1
  50. package/lib/esm/libs/messenger.js +3 -1
  51. package/lib/esm/libs/messenger.js.map +1 -1
  52. package/lib/esm/version.d.ts +1 -1
  53. package/lib/esm/version.js +1 -1
  54. package/lib/esm/version.js.map +1 -1
  55. package/lib/scripts/amplitude-min.js +1 -1
  56. package/lib/scripts/amplitude-min.js.gz +0 -0
  57. package/lib/scripts/amplitude-min.umd.js +1 -1
  58. package/lib/scripts/amplitude-min.umd.js.gz +0 -0
  59. package/lib/scripts/autocapture/track-action-click.d.ts +13 -0
  60. package/lib/scripts/autocapture/track-action-click.d.ts.map +1 -0
  61. package/lib/scripts/autocapture/track-change.d.ts +11 -0
  62. package/lib/scripts/autocapture/track-change.d.ts.map +1 -0
  63. package/lib/scripts/autocapture/track-click.d.ts +10 -0
  64. package/lib/scripts/autocapture/track-click.d.ts.map +1 -0
  65. package/lib/scripts/autocapture-plugin.d.ts +66 -0
  66. package/lib/scripts/autocapture-plugin.d.ts.map +1 -1
  67. package/lib/scripts/helpers.d.ts +5 -0
  68. package/lib/scripts/helpers.d.ts.map +1 -1
  69. package/lib/scripts/libs/messenger.d.ts +3 -1
  70. package/lib/scripts/libs/messenger.d.ts.map +1 -1
  71. package/lib/scripts/version.d.ts +1 -1
  72. package/package.json +3 -2
@@ -0,0 +1,13 @@
1
+ import { AllWindowObservables, AutoCaptureOptionsWithDefaults } from 'src/autocapture-plugin';
2
+ import { ActionType } from 'src/typings/autocapture';
3
+ import { BrowserClient } from '@amplitude/analytics-types';
4
+ import { shouldTrackEvent } from '../helpers';
5
+ export declare function trackActionClick({ amplitude, allObservables, options, getEventProperties, shouldTrackEvent, shouldTrackActionClick, }: {
6
+ amplitude: BrowserClient;
7
+ allObservables: AllWindowObservables;
8
+ options: AutoCaptureOptionsWithDefaults;
9
+ getEventProperties: (actionType: ActionType, element: Element) => Record<string, any>;
10
+ shouldTrackActionClick: shouldTrackEvent;
11
+ shouldTrackEvent: shouldTrackEvent;
12
+ }): import("rxjs").Subscription;
13
+ //# sourceMappingURL=track-action-click.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-action-click.d.ts","sourceRoot":"","sources":["../../../src/autocapture/track-action-click.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAG/B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAkD,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9F,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,cAAc,EACd,OAAO,EACP,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,GACvB,EAAE;IACD,SAAS,EAAE,aAAa,CAAC;IACzB,cAAc,EAAE,oBAAoB,CAAC;IACrC,OAAO,EAAE,8BAA8B,CAAC;IACxC,kBAAkB,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtF,sBAAsB,EAAE,gBAAgB,CAAC;IACzC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,+BAoDA"}
@@ -0,0 +1,43 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.trackActionClick = void 0;
3
+ var tslib_1 = require("tslib");
4
+ var rxjs_1 = require("rxjs");
5
+ var helpers_1 = require("../helpers");
6
+ var constants_1 = require("../constants");
7
+ function trackActionClick(_a) {
8
+ var amplitude = _a.amplitude, allObservables = _a.allObservables, options = _a.options, getEventProperties = _a.getEventProperties, shouldTrackEvent = _a.shouldTrackEvent, shouldTrackActionClick = _a.shouldTrackActionClick;
9
+ var clickObservable = allObservables.clickObservable, mutationObservable = allObservables.mutationObservable, navigateObservable = allObservables.navigateObservable;
10
+ var filteredClickObservable = clickObservable.pipe((0, rxjs_1.filter)(function (click) {
11
+ // Filter out regularly tracked click events that are already handled in trackClicks
12
+ return !shouldTrackEvent('click', click.closestTrackedAncestor);
13
+ }), (0, rxjs_1.map)(function (click) {
14
+ // overwrite the closestTrackedAncestor with the closest element that is on the actionClickAllowlist
15
+ var closestActionClickEl = (0, helpers_1.getClosestElement)(click.event.target, options.actionClickAllowlist);
16
+ click.closestTrackedAncestor = closestActionClickEl;
17
+ // overwrite the targetElementProperties with the properties of the closestActionClickEl
18
+ if (click.closestTrackedAncestor !== null) {
19
+ click.targetElementProperties = getEventProperties(click.type, click.closestTrackedAncestor);
20
+ }
21
+ return click;
22
+ }), (0, rxjs_1.filter)(helpers_1.filterOutNonTrackableEvents), (0, rxjs_1.filter)(function (clickEvent) {
23
+ // Only track change on elements that should be tracked
24
+ return shouldTrackActionClick('click', clickEvent.closestTrackedAncestor);
25
+ }));
26
+ var changeObservables = [mutationObservable];
27
+ /* istanbul ignore next */
28
+ if (navigateObservable) {
29
+ changeObservables.push(navigateObservable);
30
+ }
31
+ var mutationOrNavigate = rxjs_1.merge.apply(void 0, tslib_1.__spreadArray([], tslib_1.__read(changeObservables), false));
32
+ var actionClicks = filteredClickObservable.pipe(
33
+ // If a mutation occurs within 0.5 seconds of a click event (timeout({ first: 500 })), it emits the original first click event.
34
+ (0, rxjs_1.switchMap)(function (click) {
35
+ return mutationOrNavigate.pipe((0, rxjs_1.timeout)({ first: 500, with: function () { return rxjs_1.EMPTY; } }), (0, rxjs_1.map)(function () { return click; }));
36
+ }));
37
+ return actionClicks.subscribe(function (actionClick) {
38
+ /* istanbul ignore next */
39
+ amplitude === null || amplitude === void 0 ? void 0 : amplitude.track(constants_1.AMPLITUDE_ELEMENT_CLICKED_EVENT, getEventProperties('click', actionClick.closestTrackedAncestor));
40
+ });
41
+ }
42
+ exports.trackActionClick = trackActionClick;
43
+ //# sourceMappingURL=track-action-click.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-action-click.js","sourceRoot":"","sources":["../../../src/autocapture/track-action-click.ts"],"names":[],"mappings":";;;AAMA,6BAAqE;AAGrE,sCAA8F;AAC9F,0CAA+D;AAE/D,SAAgB,gBAAgB,CAAC,EAchC;QAbC,SAAS,eAAA,EACT,cAAc,oBAAA,EACd,OAAO,aAAA,EACP,kBAAkB,wBAAA,EAClB,gBAAgB,sBAAA,EAChB,sBAAsB,4BAAA;IASd,IAAA,eAAe,GAA6C,cAAc,gBAA3D,EAAE,kBAAkB,GAAyB,cAAc,mBAAvC,EAAE,kBAAkB,GAAK,cAAc,mBAAnB,CAAoB;IAEnF,IAAM,uBAAuB,GAAG,eAAe,CAAC,IAAI,CAClD,IAAA,aAAM,EAAC,UAAC,KAAK;QACX,oFAAoF;QACpF,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAClE,CAAC,CAAC,EACF,IAAA,UAAG,EAAC,UAAC,KAAK;QACR,oGAAoG;QACpG,IAAM,oBAAoB,GAAG,IAAA,2BAAiB,EAAC,KAAK,CAAC,KAAK,CAAC,MAAiB,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC5G,KAAK,CAAC,sBAAsB,GAAG,oBAA+B,CAAC;QAE/D,wFAAwF;QACxF,IAAI,KAAK,CAAC,sBAAsB,KAAK,IAAI,EAAE;YACzC,KAAK,CAAC,uBAAuB,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;SAC9F;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,EACF,IAAA,aAAM,EAAC,qCAA2B,CAAC,EACnC,IAAA,aAAM,EAAC,UAAC,UAAU;QAChB,uDAAuD;QACvD,OAAO,sBAAsB,CAAC,OAAO,EAAE,UAAU,CAAC,sBAAsB,CAAC,CAAC;IAC5E,CAAC,CAAC,CACH,CAAC;IAEF,IAAM,iBAAiB,GAEnB,CAAC,kBAAkB,CAAC,CAAC;IACzB,0BAA0B;IAC1B,IAAI,kBAAkB,EAAE;QACtB,iBAAiB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;KAC5C;IACD,IAAM,kBAAkB,GAAG,YAAK,wDAAI,iBAAiB,UAAC,CAAC;IAEvD,IAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI;IAC/C,+HAA+H;IAC/H,IAAA,gBAAS,EAAC,UAAC,KAAK;QACd,OAAA,kBAAkB,CAAC,IAAI,CACrB,IAAA,cAAO,EAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAM,OAAA,YAAK,EAAL,CAAK,EAAE,CAAC,EAC1C,IAAA,UAAG,EAAC,cAAM,OAAA,KAAK,EAAL,CAAK,CAAC,CACjB;IAHD,CAGC,CACF,CACF,CAAC;IAEF,OAAO,YAAY,CAAC,SAAS,CAAC,UAAC,WAAW;QACxC,0BAA0B;QAC1B,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,KAAK,CACd,2CAA+B,EAC/B,kBAAkB,CAAC,OAAO,EAAG,WAAwD,CAAC,sBAAsB,CAAC,CAC9G,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAlED,4CAkEC","sourcesContent":["import {\n AllWindowObservables,\n AutoCaptureOptionsWithDefaults,\n ElementBasedTimestampedEvent,\n ObservablesEnum,\n} from 'src/autocapture-plugin';\nimport { filter, map, switchMap, merge, timeout, EMPTY } from 'rxjs';\nimport { ActionType } from 'src/typings/autocapture';\nimport { BrowserClient } from '@amplitude/analytics-types';\nimport { filterOutNonTrackableEvents, getClosestElement, shouldTrackEvent } from '../helpers';\nimport { AMPLITUDE_ELEMENT_CLICKED_EVENT } from '../constants';\n\nexport function trackActionClick({\n amplitude,\n allObservables,\n options,\n getEventProperties,\n shouldTrackEvent,\n shouldTrackActionClick,\n}: {\n amplitude: BrowserClient;\n allObservables: AllWindowObservables;\n options: AutoCaptureOptionsWithDefaults;\n getEventProperties: (actionType: ActionType, element: Element) => Record<string, any>;\n shouldTrackActionClick: shouldTrackEvent;\n shouldTrackEvent: shouldTrackEvent;\n}) {\n const { clickObservable, mutationObservable, navigateObservable } = allObservables;\n\n const filteredClickObservable = clickObservable.pipe(\n filter((click) => {\n // Filter out regularly tracked click events that are already handled in trackClicks\n return !shouldTrackEvent('click', click.closestTrackedAncestor);\n }),\n map((click) => {\n // overwrite the closestTrackedAncestor with the closest element that is on the actionClickAllowlist\n const closestActionClickEl = getClosestElement(click.event.target as Element, options.actionClickAllowlist);\n click.closestTrackedAncestor = closestActionClickEl as Element;\n\n // overwrite the targetElementProperties with the properties of the closestActionClickEl\n if (click.closestTrackedAncestor !== null) {\n click.targetElementProperties = getEventProperties(click.type, click.closestTrackedAncestor);\n }\n return click;\n }),\n filter(filterOutNonTrackableEvents),\n filter((clickEvent) => {\n // Only track change on elements that should be tracked\n return shouldTrackActionClick('click', clickEvent.closestTrackedAncestor);\n }),\n );\n\n const changeObservables: Array<\n AllWindowObservables[ObservablesEnum.MutationObservable] | AllWindowObservables[ObservablesEnum.NavigateObservable]\n > = [mutationObservable];\n /* istanbul ignore next */\n if (navigateObservable) {\n changeObservables.push(navigateObservable);\n }\n const mutationOrNavigate = merge(...changeObservables);\n\n const actionClicks = filteredClickObservable.pipe(\n // If a mutation occurs within 0.5 seconds of a click event (timeout({ first: 500 })), it emits the original first click event.\n switchMap((click) =>\n mutationOrNavigate.pipe(\n timeout({ first: 500, with: () => EMPTY }),\n map(() => click),\n ),\n ),\n );\n\n return actionClicks.subscribe((actionClick) => {\n /* istanbul ignore next */\n amplitude?.track(\n AMPLITUDE_ELEMENT_CLICKED_EVENT,\n getEventProperties('click', (actionClick as ElementBasedTimestampedEvent<MouseEvent>).closestTrackedAncestor),\n );\n });\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { AllWindowObservables } from 'src/autocapture-plugin';
2
+ import { ActionType } from 'src/typings/autocapture';
3
+ import { BrowserClient } from '@amplitude/analytics-types';
4
+ import { shouldTrackEvent } from '../helpers';
5
+ export declare function trackChange({ amplitude, allObservables, getEventProperties, shouldTrackEvent, }: {
6
+ amplitude: BrowserClient;
7
+ allObservables: AllWindowObservables;
8
+ getEventProperties: (actionType: ActionType, element: Element) => Record<string, any>;
9
+ shouldTrackEvent: shouldTrackEvent;
10
+ }): import("rxjs").Subscription;
11
+ //# sourceMappingURL=track-change.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-change.d.ts","sourceRoot":"","sources":["../../../src/autocapture/track-change.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAA+B,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG3E,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,EAAE;IACD,SAAS,EAAE,aAAa,CAAC;IACzB,cAAc,EAAE,oBAAoB,CAAC;IACrC,kBAAkB,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtF,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,+BAeA"}
@@ -0,0 +1,19 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.trackChange = void 0;
3
+ var rxjs_1 = require("rxjs");
4
+ var helpers_1 = require("../helpers");
5
+ var constants_1 = require("../constants");
6
+ function trackChange(_a) {
7
+ var amplitude = _a.amplitude, allObservables = _a.allObservables, getEventProperties = _a.getEventProperties, shouldTrackEvent = _a.shouldTrackEvent;
8
+ var changeObservable = allObservables.changeObservable;
9
+ var filteredChangeObservable = changeObservable.pipe((0, rxjs_1.filter)(helpers_1.filterOutNonTrackableEvents), (0, rxjs_1.filter)(function (changeEvent) {
10
+ // Only track change on elements that should be tracked,
11
+ return shouldTrackEvent('change', changeEvent.closestTrackedAncestor);
12
+ }));
13
+ return filteredChangeObservable.subscribe(function (changeEvent) {
14
+ /* istanbul ignore next */
15
+ amplitude === null || amplitude === void 0 ? void 0 : amplitude.track(constants_1.AMPLITUDE_ELEMENT_CHANGED_EVENT, getEventProperties('change', changeEvent.closestTrackedAncestor));
16
+ });
17
+ }
18
+ exports.trackChange = trackChange;
19
+ //# sourceMappingURL=track-change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-change.js","sourceRoot":"","sources":["../../../src/autocapture/track-change.ts"],"names":[],"mappings":";;AACA,6BAA8B;AAG9B,sCAA2E;AAC3E,0CAA+D;AAE/D,SAAgB,WAAW,CAAC,EAU3B;QATC,SAAS,eAAA,EACT,cAAc,oBAAA,EACd,kBAAkB,wBAAA,EAClB,gBAAgB,sBAAA;IAOR,IAAA,gBAAgB,GAAK,cAAc,iBAAnB,CAAoB;IAE5C,IAAM,wBAAwB,GAAG,gBAAgB,CAAC,IAAI,CACpD,IAAA,aAAM,EAAC,qCAA2B,CAAC,EACnC,IAAA,aAAM,EAAC,UAAC,WAAW;QACjB,wDAAwD;QACxD,OAAO,gBAAgB,CAAC,QAAQ,EAAE,WAAW,CAAC,sBAAsB,CAAC,CAAC;IACxE,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,wBAAwB,CAAC,SAAS,CAAC,UAAC,WAAW;QACpD,0BAA0B;QAC1B,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,KAAK,CAAC,2CAA+B,EAAE,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACtH,CAAC,CAAC,CAAC;AACL,CAAC;AAzBD,kCAyBC","sourcesContent":["import { AllWindowObservables } from 'src/autocapture-plugin';\nimport { filter } from 'rxjs';\nimport { ActionType } from 'src/typings/autocapture';\nimport { BrowserClient } from '@amplitude/analytics-types';\nimport { filterOutNonTrackableEvents, shouldTrackEvent } from '../helpers';\nimport { AMPLITUDE_ELEMENT_CHANGED_EVENT } from '../constants';\n\nexport function trackChange({\n amplitude,\n allObservables,\n getEventProperties,\n shouldTrackEvent,\n}: {\n amplitude: BrowserClient;\n allObservables: AllWindowObservables;\n getEventProperties: (actionType: ActionType, element: Element) => Record<string, any>;\n shouldTrackEvent: shouldTrackEvent;\n}) {\n const { changeObservable } = allObservables;\n\n const filteredChangeObservable = changeObservable.pipe(\n filter(filterOutNonTrackableEvents),\n filter((changeEvent) => {\n // Only track change on elements that should be tracked,\n return shouldTrackEvent('change', changeEvent.closestTrackedAncestor);\n }),\n );\n\n return filteredChangeObservable.subscribe((changeEvent) => {\n /* istanbul ignore next */\n amplitude?.track(AMPLITUDE_ELEMENT_CHANGED_EVENT, getEventProperties('change', changeEvent.closestTrackedAncestor));\n });\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { AllWindowObservables, AutoCaptureOptionsWithDefaults } from 'src/autocapture-plugin';
2
+ import { BrowserClient } from '@amplitude/analytics-types';
3
+ import { shouldTrackEvent } from '../helpers';
4
+ export declare function trackClicks({ amplitude, allObservables, options, shouldTrackEvent, }: {
5
+ amplitude: BrowserClient;
6
+ allObservables: AllWindowObservables;
7
+ options: AutoCaptureOptionsWithDefaults;
8
+ shouldTrackEvent: shouldTrackEvent;
9
+ }): import("rxjs").Subscription;
10
+ //# sourceMappingURL=track-click.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-click.d.ts","sourceRoot":"","sources":["../../../src/autocapture/track-click.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAE9F,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAA+B,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAK3E,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,cAAc,EACd,OAAO,EACP,gBAAgB,GACjB,EAAE;IACD,SAAS,EAAE,aAAa,CAAC;IACzB,cAAc,EAAE,oBAAoB,CAAC;IACrC,OAAO,EAAE,8BAA8B,CAAC;IACxC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,+BAiDA"}
@@ -0,0 +1,53 @@
1
+ Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.trackClicks = void 0;
3
+ var tslib_1 = require("tslib");
4
+ var rxjs_1 = require("rxjs");
5
+ var helpers_1 = require("../helpers");
6
+ var constants_1 = require("../constants");
7
+ var RAGE_CLICK_THRESHOLD = 5;
8
+ function trackClicks(_a) {
9
+ var amplitude = _a.amplitude, allObservables = _a.allObservables, options = _a.options, shouldTrackEvent = _a.shouldTrackEvent;
10
+ var clickObservable = allObservables.clickObservable;
11
+ // Trigger if the target of the click event has changed and position is different
12
+ // Keeping track of position is important to avoid false positives when the user clicks on the same
13
+ // element where certain frameworks could replace the element instance between rerenders
14
+ var comparisonTrigger = clickObservable.pipe((0, rxjs_1.pairwise)(), (0, rxjs_1.filter)(function (_a) {
15
+ var _b = tslib_1.__read(_a, 2), prev = _b[0], current = _b[1];
16
+ var targetChanged = prev.event.target !== current.event.target;
17
+ /* istanbul ignore next */
18
+ var samePos = Math.abs(current.event.screenX - prev.event.screenX) <= 20 &&
19
+ Math.abs(current.event.screenY - prev.event.screenY) <= 20;
20
+ return targetChanged && !samePos;
21
+ }));
22
+ // Trigger if there is no click event within 1 second
23
+ var timeoutTrigger = clickObservable.pipe((0, rxjs_1.debounceTime)(options.debounceTime), (0, rxjs_1.map)(function () { return 'timeout'; }));
24
+ var triggers = (0, rxjs_1.merge)(comparisonTrigger, timeoutTrigger);
25
+ // Get buffers of clicks, if the buffer length is over 5, it is rage click
26
+ var bufferedClicks = clickObservable.pipe((0, rxjs_1.delay)(0), (0, rxjs_1.filter)(helpers_1.filterOutNonTrackableEvents), (0, rxjs_1.filter)(function (click) {
27
+ // Only track clicks on elements that should be tracked,
28
+ return shouldTrackEvent('click', click.closestTrackedAncestor);
29
+ }), (0, rxjs_1.buffer)(triggers));
30
+ return bufferedClicks.subscribe(function (clicks) {
31
+ var e_1, _a;
32
+ // TODO: update this when rage clicks are added
33
+ var clickType = clicks.length >= RAGE_CLICK_THRESHOLD ? constants_1.AMPLITUDE_ELEMENT_CLICKED_EVENT : constants_1.AMPLITUDE_ELEMENT_CLICKED_EVENT;
34
+ try {
35
+ for (var clicks_1 = tslib_1.__values(clicks), clicks_1_1 = clicks_1.next(); !clicks_1_1.done; clicks_1_1 = clicks_1.next()) {
36
+ var click = clicks_1_1.value;
37
+ /* istanbul ignore next */
38
+ amplitude === null || amplitude === void 0 ? void 0 : amplitude.track(clickType, click.targetElementProperties, {
39
+ time: click.timestamp,
40
+ });
41
+ }
42
+ }
43
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
44
+ finally {
45
+ try {
46
+ if (clicks_1_1 && !clicks_1_1.done && (_a = clicks_1.return)) _a.call(clicks_1);
47
+ }
48
+ finally { if (e_1) throw e_1.error; }
49
+ }
50
+ });
51
+ }
52
+ exports.trackClicks = trackClicks;
53
+ //# sourceMappingURL=track-click.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-click.js","sourceRoot":"","sources":["../../../src/autocapture/track-click.ts"],"names":[],"mappings":";;;AACA,6BAAiF;AAEjF,sCAA2E;AAC3E,0CAA+D;AAE/D,IAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,SAAgB,WAAW,CAAC,EAU3B;QATC,SAAS,eAAA,EACT,cAAc,oBAAA,EACd,OAAO,aAAA,EACP,gBAAgB,sBAAA;IAOR,IAAA,eAAe,GAAK,cAAc,gBAAnB,CAAoB;IAE3C,iFAAiF;IACjF,mGAAmG;IACnG,wFAAwF;IACxF,IAAM,iBAAiB,GAAG,eAAe,CAAC,IAAI,CAC5C,IAAA,eAAQ,GAAE,EACV,IAAA,aAAM,EAAC,UAAC,EAAe;YAAf,KAAA,qBAAe,EAAd,IAAI,QAAA,EAAE,OAAO,QAAA;QACpB,IAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QACjE,0BAA0B;QAC1B,IAAM,OAAO,GACX,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;YAC1D,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7D,OAAO,aAAa,IAAI,CAAC,OAAO,CAAC;IACnC,CAAC,CAAC,CACH,CAAC;IAEF,qDAAqD;IACrD,IAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CACzC,IAAA,mBAAY,EAAC,OAAO,CAAC,YAAY,CAAC,EAClC,IAAA,UAAG,EAAC,cAAM,OAAA,SAAkB,EAAlB,CAAkB,CAAC,CAC9B,CAAC;IAEF,IAAM,QAAQ,GAAG,IAAA,YAAK,EAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAE1D,0EAA0E;IAC1E,IAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CACzC,IAAA,YAAK,EAAC,CAAC,CAAC,EACR,IAAA,aAAM,EAAC,qCAA2B,CAAC,EACnC,IAAA,aAAM,EAAC,UAAC,KAAK;QACX,wDAAwD;QACxD,OAAO,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACjE,CAAC,CAAC,EACF,IAAA,aAAM,EAAC,QAAQ,CAAC,CACjB,CAAC;IAEF,OAAO,cAAc,CAAC,SAAS,CAAC,UAAC,MAAM;;QACrC,+CAA+C;QAC/C,IAAM,SAAS,GACb,MAAM,CAAC,MAAM,IAAI,oBAAoB,CAAC,CAAC,CAAC,2CAA+B,CAAC,CAAC,CAAC,2CAA+B,CAAC;;YAE5G,KAAoB,IAAA,WAAA,iBAAA,MAAM,CAAA,8BAAA,kDAAE;gBAAvB,IAAM,KAAK,mBAAA;gBACd,0BAA0B;gBAC1B,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,uBAAuB,EAAE;oBACzD,IAAI,EAAE,KAAK,CAAC,SAAS;iBACtB,CAAC,CAAC;aACJ;;;;;;;;;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AA3DD,kCA2DC","sourcesContent":["import { AllWindowObservables, AutoCaptureOptionsWithDefaults } from 'src/autocapture-plugin';\nimport { buffer, filter, map, debounceTime, merge, pairwise, delay } from 'rxjs';\nimport { BrowserClient } from '@amplitude/analytics-types';\nimport { filterOutNonTrackableEvents, shouldTrackEvent } from '../helpers';\nimport { AMPLITUDE_ELEMENT_CLICKED_EVENT } from '../constants';\n\nconst RAGE_CLICK_THRESHOLD = 5;\n\nexport function trackClicks({\n amplitude,\n allObservables,\n options,\n shouldTrackEvent,\n}: {\n amplitude: BrowserClient;\n allObservables: AllWindowObservables;\n options: AutoCaptureOptionsWithDefaults;\n shouldTrackEvent: shouldTrackEvent;\n}) {\n const { clickObservable } = allObservables;\n\n // Trigger if the target of the click event has changed and position is different\n // Keeping track of position is important to avoid false positives when the user clicks on the same\n // element where certain frameworks could replace the element instance between rerenders\n const comparisonTrigger = clickObservable.pipe(\n pairwise(),\n filter(([prev, current]) => {\n const targetChanged = prev.event.target !== current.event.target;\n /* istanbul ignore next */\n const samePos =\n Math.abs(current.event.screenX - prev.event.screenX) <= 20 &&\n Math.abs(current.event.screenY - prev.event.screenY) <= 20;\n return targetChanged && !samePos;\n }),\n );\n\n // Trigger if there is no click event within 1 second\n const timeoutTrigger = clickObservable.pipe(\n debounceTime(options.debounceTime),\n map(() => 'timeout' as const),\n );\n\n const triggers = merge(comparisonTrigger, timeoutTrigger);\n\n // Get buffers of clicks, if the buffer length is over 5, it is rage click\n const bufferedClicks = clickObservable.pipe(\n delay(0),\n filter(filterOutNonTrackableEvents),\n filter((click) => {\n // Only track clicks on elements that should be tracked,\n return shouldTrackEvent('click', click.closestTrackedAncestor);\n }),\n buffer(triggers),\n );\n\n return bufferedClicks.subscribe((clicks) => {\n // TODO: update this when rage clicks are added\n const clickType =\n clicks.length >= RAGE_CLICK_THRESHOLD ? AMPLITUDE_ELEMENT_CLICKED_EVENT : AMPLITUDE_ELEMENT_CLICKED_EVENT;\n\n for (const click of clicks) {\n /* istanbul ignore next */\n amplitude?.track(clickType, click.targetElementProperties, {\n time: click.timestamp,\n });\n }\n });\n}\n"]}
@@ -1,8 +1,38 @@
1
1
  import { BrowserClient, BrowserConfig, EnrichmentPlugin } from '@amplitude/analytics-types';
2
+ import { Observable } from 'rxjs';
2
3
  import { Messenger } from './libs/messenger';
3
4
  import { ActionType } from './typings/autocapture';
5
+ import { HasEventTargetAddRemove } from 'rxjs/internal/observable/fromEvent';
6
+ declare global {
7
+ interface Window {
8
+ navigation: HasEventTargetAddRemove<Event>;
9
+ }
10
+ }
11
+ interface NavigateEvent extends Event {
12
+ readonly navigationType: 'reload' | 'push' | 'replace' | 'traverse';
13
+ readonly destination: {
14
+ readonly url: string;
15
+ readonly key: string | null;
16
+ readonly id: string | null;
17
+ readonly index: number;
18
+ readonly sameDocument: boolean;
19
+ getState(): any;
20
+ };
21
+ readonly canIntercept: boolean;
22
+ readonly userInitiated: boolean;
23
+ readonly hashChange: boolean;
24
+ readonly signal: AbortSignal;
25
+ readonly formData: FormData | null;
26
+ readonly downloadRequest: string | null;
27
+ readonly info: any;
28
+ readonly hasUAVisualTransition: boolean;
29
+ /** @see https://github.com/WICG/navigation-api/pull/264 */
30
+ readonly sourceElement: Element | null;
31
+ scroll(): void;
32
+ }
4
33
  type BrowserEnrichmentPlugin = EnrichmentPlugin<BrowserClient, BrowserConfig>;
5
34
  export declare const DEFAULT_CSS_SELECTOR_ALLOWLIST: string[];
35
+ export declare const DEFAULT_ACTION_CLICK_ALLOWLIST: string[];
6
36
  export declare const DEFAULT_DATA_ATTRIBUTE_PREFIX = "data-amp-track-";
7
37
  export interface AutocaptureOptions {
8
38
  /**
@@ -38,7 +68,43 @@ export interface AutocaptureOptions {
38
68
  enabled?: boolean;
39
69
  messenger?: Messenger;
40
70
  };
71
+ /**
72
+ * Debounce time in milliseconds for tracking events.
73
+ * This is used to detect rage clicks.
74
+ */
75
+ debounceTime?: number;
76
+ /**
77
+ * CSS selector allowlist for tracking clicks that result in a DOM change/navigation on elements not already allowed by the cssSelectorAllowlist
78
+ */
79
+ actionClickAllowlist?: string[];
80
+ }
81
+ export type AutoCaptureOptionsWithDefaults = Required<Pick<AutocaptureOptions, 'debounceTime' | 'cssSelectorAllowlist' | 'actionClickAllowlist'>> & AutocaptureOptions;
82
+ export declare enum ObservablesEnum {
83
+ ClickObservable = "clickObservable",
84
+ ChangeObservable = "changeObservable",
85
+ NavigateObservable = "navigateObservable",
86
+ MutationObservable = "mutationObservable"
87
+ }
88
+ type BaseTimestampedEvent<T> = {
89
+ event: T;
90
+ timestamp: number;
91
+ type: 'rage' | 'click' | 'change' | 'error' | 'navigate' | 'mutation';
92
+ };
93
+ export type ElementBasedEvent = MouseEvent | Event;
94
+ export type ElementBasedTimestampedEvent<T> = BaseTimestampedEvent<T> & {
95
+ event: MouseEvent | Event;
96
+ type: 'click' | 'change';
97
+ closestTrackedAncestor: Element;
98
+ targetElementProperties: Record<string, any>;
99
+ };
100
+ export type TimestampedEvent<T> = BaseTimestampedEvent<T> | ElementBasedTimestampedEvent<T>;
101
+ export interface AllWindowObservables {
102
+ [ObservablesEnum.ClickObservable]: Observable<ElementBasedTimestampedEvent<MouseEvent>>;
103
+ [ObservablesEnum.ChangeObservable]: Observable<ElementBasedTimestampedEvent<Event>>;
104
+ [ObservablesEnum.NavigateObservable]: Observable<TimestampedEvent<NavigateEvent>> | undefined;
105
+ [ObservablesEnum.MutationObservable]: Observable<TimestampedEvent<MutationRecord[]>>;
41
106
  }
107
+ export declare function isElementBasedEvent<T>(event: BaseTimestampedEvent<T>): event is ElementBasedTimestampedEvent<T>;
42
108
  export declare const autocapturePlugin: (options?: AutocaptureOptions) => BrowserEnrichmentPlugin;
43
109
  export {};
44
110
  //# sourceMappingURL=autocapture-plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"autocapture-plugin.d.ts","sourceRoot":"","sources":["../../src/autocapture-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAU,MAAM,4BAA4B,CAAC;AAYpG,OAAO,EAAE,SAAS,EAAmB,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,KAAK,uBAAuB,GAAG,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE9E,eAAO,MAAM,8BAA8B,UAS1C,CAAC;AACF,eAAO,MAAM,6BAA6B,oBAAoB,CAAC;AAQ/D,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEvC;;;;;;;OAOG;IACH,wBAAwB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IAEjF;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,oBAAoB,CAAC,EAAE;QACrB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,SAAS,CAAC;KACvB,CAAC;CACH;AAED,eAAO,MAAM,iBAAiB,aAAa,kBAAkB,KAAQ,uBA2OpE,CAAC"}
1
+ {"version":3,"file":"autocapture-plugin.d.ts","sourceRoot":"","sources":["../../src/autocapture-plugin.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,15 @@
1
1
  var _this = this;
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.autocapturePlugin = exports.DEFAULT_DATA_ATTRIBUTE_PREFIX = exports.DEFAULT_CSS_SELECTOR_ALLOWLIST = void 0;
3
+ exports.autocapturePlugin = exports.isElementBasedEvent = exports.ObservablesEnum = exports.DEFAULT_DATA_ATTRIBUTE_PREFIX = exports.DEFAULT_ACTION_CLICK_ALLOWLIST = exports.DEFAULT_CSS_SELECTOR_ALLOWLIST = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var constants = tslib_1.__importStar(require("./constants"));
6
+ var rxjs_1 = require("rxjs");
6
7
  var helpers_1 = require("./helpers");
7
8
  var messenger_1 = require("./libs/messenger");
8
9
  var hierarchy_1 = require("./hierarchy");
10
+ var track_click_1 = require("./autocapture/track-click");
11
+ var track_change_1 = require("./autocapture/track-change");
12
+ var track_action_click_1 = require("./autocapture/track-action-click");
9
13
  exports.DEFAULT_CSS_SELECTOR_ALLOWLIST = [
10
14
  'a',
11
15
  'button',
@@ -16,84 +20,71 @@ exports.DEFAULT_CSS_SELECTOR_ALLOWLIST = [
16
20
  '[data-amp-default-track]',
17
21
  '.amp-default-track',
18
22
  ];
23
+ exports.DEFAULT_ACTION_CLICK_ALLOWLIST = ['div', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
19
24
  exports.DEFAULT_DATA_ATTRIBUTE_PREFIX = 'data-amp-track-';
25
+ var ObservablesEnum;
26
+ (function (ObservablesEnum) {
27
+ ObservablesEnum["ClickObservable"] = "clickObservable";
28
+ ObservablesEnum["ChangeObservable"] = "changeObservable";
29
+ // ErrorObservable = 'errorObservable',
30
+ ObservablesEnum["NavigateObservable"] = "navigateObservable";
31
+ ObservablesEnum["MutationObservable"] = "mutationObservable";
32
+ })(ObservablesEnum = exports.ObservablesEnum || (exports.ObservablesEnum = {}));
33
+ // Type predicate
34
+ function isElementBasedEvent(event) {
35
+ return event.type === 'click' || event.type === 'change';
36
+ }
37
+ exports.isElementBasedEvent = isElementBasedEvent;
20
38
  var autocapturePlugin = function (options) {
39
+ var _a, _b, _c;
21
40
  if (options === void 0) { options = {}; }
22
- var _a = options.cssSelectorAllowlist, cssSelectorAllowlist = _a === void 0 ? exports.DEFAULT_CSS_SELECTOR_ALLOWLIST : _a, pageUrlAllowlist = options.pageUrlAllowlist, shouldTrackEventResolver = options.shouldTrackEventResolver, _b = options.dataAttributePrefix, dataAttributePrefix = _b === void 0 ? exports.DEFAULT_DATA_ATTRIBUTE_PREFIX : _b, _c = options.visualTaggingOptions, visualTaggingOptions = _c === void 0 ? {
41
+ var _d = options.dataAttributePrefix, dataAttributePrefix = _d === void 0 ? exports.DEFAULT_DATA_ATTRIBUTE_PREFIX : _d, _e = options.visualTaggingOptions, visualTaggingOptions = _e === void 0 ? {
23
42
  enabled: true,
24
43
  messenger: new messenger_1.WindowMessenger(),
25
- } : _c;
44
+ } : _e;
45
+ options.cssSelectorAllowlist = (_a = options.cssSelectorAllowlist) !== null && _a !== void 0 ? _a : exports.DEFAULT_CSS_SELECTOR_ALLOWLIST;
46
+ options.actionClickAllowlist = (_b = options.actionClickAllowlist) !== null && _b !== void 0 ? _b : exports.DEFAULT_ACTION_CLICK_ALLOWLIST;
47
+ options.debounceTime = (_c = options.debounceTime) !== null && _c !== void 0 ? _c : 1000;
26
48
  var name = constants.PLUGIN_NAME;
27
49
  var type = 'enrichment';
28
- var observer;
29
- var eventListeners = [];
50
+ var subscriptions = [];
30
51
  var logger = undefined;
31
- var addEventListener = function (element, type, handler) {
32
- element.addEventListener(type, handler);
33
- eventListeners.push({
34
- element: element,
35
- type: type,
36
- handler: handler,
37
- });
38
- };
39
- var removeEventListeners = function () {
40
- eventListeners.forEach(function (_ref) {
41
- var element = _ref.element, type = _ref.type, handler = _ref.handler;
42
- /* istanbul ignore next */
43
- element === null || element === void 0 ? void 0 : element.removeEventListener(type, handler);
44
- });
45
- eventListeners = [];
46
- };
47
- var shouldTrackEvent = function (actionType, element) {
48
- var _a, _b, _c;
49
- /* istanbul ignore if */
50
- if (!element) {
51
- return false;
52
- }
53
- /* istanbul ignore next */
54
- var tag = (_b = (_a = element === null || element === void 0 ? void 0 : element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase) === null || _b === void 0 ? void 0 : _b.call(_a);
55
- // Text nodes have no tag
56
- if (!tag) {
57
- return false;
58
- }
59
- if (shouldTrackEventResolver) {
60
- return shouldTrackEventResolver(actionType, element);
61
- }
62
- if (!(0, helpers_1.isPageUrlAllowed)(window.location.href, pageUrlAllowlist)) {
63
- return false;
64
- }
52
+ // Create observables on events on the window
53
+ var createObservables = function () {
54
+ var _a;
55
+ // Create Observables from direct user events
56
+ var clickObservable = (0, rxjs_1.fromEvent)(document, 'click', { capture: true }).pipe((0, rxjs_1.map)(function (click) { return addAdditionalEventProperties(click, 'click'); }));
57
+ var changeObservable = (0, rxjs_1.fromEvent)(document, 'change', { capture: true }).pipe((0, rxjs_1.map)(function (change) { return addAdditionalEventProperties(change, 'change'); }));
58
+ // Create Observable from unhandled errors
59
+ // const errorObservable = fromEvent<ErrorEvent>(window, 'error').pipe(
60
+ // map((error) => addAdditionalEventProperties(error, 'error')),
61
+ // );
62
+ // Create observable for URL changes
63
+ var navigateObservable;
65
64
  /* istanbul ignore next */
66
- var elementType = (element === null || element === void 0 ? void 0 : element.type) || '';
67
- if (typeof elementType === 'string') {
68
- switch (elementType.toLowerCase()) {
69
- case 'hidden':
70
- return false;
71
- case 'password':
72
- return false;
73
- }
74
- }
75
- /* istanbul ignore if */
76
- if (cssSelectorAllowlist) {
77
- var hasMatchAnyAllowedSelector = cssSelectorAllowlist.some(function (selector) { var _a; return !!((_a = element === null || element === void 0 ? void 0 : element.matches) === null || _a === void 0 ? void 0 : _a.call(element, selector)); });
78
- if (!hasMatchAnyAllowedSelector) {
79
- return false;
80
- }
81
- }
82
- switch (tag) {
83
- case 'input':
84
- case 'select':
85
- case 'textarea':
86
- return actionType === 'change' || actionType === 'click';
87
- default: {
88
- /* istanbul ignore next */
89
- var computedStyle = (_c = window === null || window === void 0 ? void 0 : window.getComputedStyle) === null || _c === void 0 ? void 0 : _c.call(window, element);
90
- /* istanbul ignore next */
91
- if (computedStyle && computedStyle.getPropertyValue('cursor') === 'pointer' && actionType === 'click') {
92
- return true;
93
- }
94
- return actionType === 'click';
95
- }
65
+ if (window.navigation) {
66
+ navigateObservable = (0, rxjs_1.fromEvent)(window.navigation, 'navigate').pipe((0, rxjs_1.map)(function (navigate) { return addAdditionalEventProperties(navigate, 'navigate'); }));
96
67
  }
68
+ // Track DOM Mutations
69
+ var mutationObservable = new rxjs_1.Observable(function (observer) {
70
+ var mutationObserver = new MutationObserver(function (mutations) {
71
+ observer.next(mutations);
72
+ });
73
+ mutationObserver.observe(document.body, {
74
+ childList: true,
75
+ attributes: true,
76
+ characterData: true,
77
+ subtree: true,
78
+ });
79
+ return function () { return mutationObserver.disconnect(); };
80
+ }).pipe((0, rxjs_1.map)(function (mutation) { return addAdditionalEventProperties(mutation, 'mutation'); }));
81
+ return _a = {},
82
+ _a[ObservablesEnum.ClickObservable] = clickObservable,
83
+ _a[ObservablesEnum.ChangeObservable] = changeObservable,
84
+ // [ObservablesEnum.ErrorObservable]: errorObservable,
85
+ _a[ObservablesEnum.NavigateObservable] = navigateObservable,
86
+ _a[ObservablesEnum.MutationObservable] = mutationObservable,
87
+ _a;
97
88
  };
98
89
  // Returns the Amplitude event properties for the given element.
99
90
  var getEventProperties = function (actionType, element) {
@@ -130,8 +121,25 @@ var autocapturePlugin = function (options) {
130
121
  }
131
122
  return (0, helpers_1.removeEmptyProperties)(properties);
132
123
  };
124
+ var addAdditionalEventProperties = function (event, type) {
125
+ var baseEvent = {
126
+ event: event,
127
+ timestamp: Date.now(),
128
+ type: type,
129
+ };
130
+ if (isElementBasedEvent(baseEvent) && baseEvent.event.target !== null) {
131
+ // Retrieve additional event properties from the target element
132
+ var closestTrackedAncestor = (0, helpers_1.getClosestElement)(baseEvent.event.target, options.cssSelectorAllowlist);
133
+ if (closestTrackedAncestor) {
134
+ baseEvent.closestTrackedAncestor = closestTrackedAncestor;
135
+ baseEvent.targetElementProperties = getEventProperties(baseEvent.type, closestTrackedAncestor);
136
+ }
137
+ return baseEvent;
138
+ }
139
+ return baseEvent;
140
+ };
133
141
  var setup = function (config, amplitude) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
134
- var addListener, attachListeners;
142
+ var shouldTrackEvent, shouldTrackActionClick, allObservables, clickTrackingSubscription, changeSubscription, actionClickSubscription, allowlist, actionClickAllowlist;
135
143
  var _a, _b, _c;
136
144
  return tslib_1.__generator(this, function (_d) {
137
145
  if (!amplitude) {
@@ -144,67 +152,40 @@ var autocapturePlugin = function (options) {
144
152
  if (typeof document === 'undefined') {
145
153
  return [2 /*return*/];
146
154
  }
147
- addListener = function (el) {
148
- if (shouldTrackEvent('click', el)) {
149
- addEventListener(el, 'click', function (event) {
150
- // Limit to only the innermost element that matches the selectors, avoiding all propagated event after matching.
151
- /* istanbul ignore next */
152
- if ((event === null || event === void 0 ? void 0 : event.target) != (event === null || event === void 0 ? void 0 : event.currentTarget) &&
153
- (0, helpers_1.getClosestElement)(event === null || event === void 0 ? void 0 : event.target, cssSelectorAllowlist) != (event === null || event === void 0 ? void 0 : event.currentTarget)) {
154
- return;
155
- }
156
- /* istanbul ignore next */
157
- amplitude === null || amplitude === void 0 ? void 0 : amplitude.track(constants.AMPLITUDE_ELEMENT_CLICKED_EVENT, getEventProperties('click', el));
158
- });
159
- }
160
- if (shouldTrackEvent('change', el)) {
161
- addEventListener(el, 'change', function (event) {
162
- // Limit to only the innermost element that matches the selectors, avoiding all propagated event after matching.
163
- /* istanbul ignore next */
164
- if ((event === null || event === void 0 ? void 0 : event.target) != (event === null || event === void 0 ? void 0 : event.currentTarget) &&
165
- (0, helpers_1.getClosestElement)(event === null || event === void 0 ? void 0 : event.target, cssSelectorAllowlist) != (event === null || event === void 0 ? void 0 : event.currentTarget)) {
166
- return;
167
- }
168
- /* istanbul ignore next */
169
- amplitude === null || amplitude === void 0 ? void 0 : amplitude.track(constants.AMPLITUDE_ELEMENT_CHANGED_EVENT, getEventProperties('change', el));
170
- });
171
- }
172
- };
173
- if (typeof MutationObserver !== 'undefined') {
174
- observer = new MutationObserver(function (mutations) {
175
- mutations.forEach(function (mutation) {
176
- mutation.addedNodes.forEach(function (node) {
177
- addListener(node);
178
- if ('querySelectorAll' in node && typeof node.querySelectorAll === 'function') {
179
- (0, helpers_1.querySelectUniqueElements)(node, cssSelectorAllowlist).map(addListener);
180
- }
181
- });
182
- });
183
- });
184
- }
185
- attachListeners = function () {
186
- var allElements = (0, helpers_1.querySelectUniqueElements)(document.body, cssSelectorAllowlist);
187
- allElements.forEach(addListener);
188
- /* istanbul ignore next */
189
- observer === null || observer === void 0 ? void 0 : observer.observe(document.body, {
190
- subtree: true,
191
- childList: true,
192
- });
193
- };
194
- if (document.body) {
195
- attachListeners();
196
- }
197
- else {
198
- // This is to handle the case where the plugin is loaded before the body is available.
199
- // E.g., for non-reactive frameworks.
200
- window.addEventListener('load', attachListeners);
201
- }
155
+ shouldTrackEvent = (0, helpers_1.createShouldTrackEvent)(options, options.cssSelectorAllowlist);
156
+ shouldTrackActionClick = (0, helpers_1.createShouldTrackEvent)(options, options.actionClickAllowlist);
157
+ allObservables = createObservables();
158
+ clickTrackingSubscription = (0, track_click_1.trackClicks)({
159
+ allObservables: allObservables,
160
+ options: options,
161
+ amplitude: amplitude,
162
+ shouldTrackEvent: shouldTrackEvent,
163
+ });
164
+ subscriptions.push(clickTrackingSubscription);
165
+ changeSubscription = (0, track_change_1.trackChange)({
166
+ allObservables: allObservables,
167
+ getEventProperties: getEventProperties,
168
+ amplitude: amplitude,
169
+ shouldTrackEvent: shouldTrackEvent,
170
+ });
171
+ subscriptions.push(changeSubscription);
172
+ actionClickSubscription = (0, track_action_click_1.trackActionClick)({
173
+ allObservables: allObservables,
174
+ options: options,
175
+ getEventProperties: getEventProperties,
176
+ amplitude: amplitude,
177
+ shouldTrackEvent: shouldTrackEvent,
178
+ shouldTrackActionClick: shouldTrackActionClick,
179
+ });
180
+ subscriptions.push(actionClickSubscription);
202
181
  /* istanbul ignore next */
203
182
  (_b = config === null || config === void 0 ? void 0 : config.loggerProvider) === null || _b === void 0 ? void 0 : _b.log("".concat(name, " has been successfully added."));
204
183
  // Setup visual tagging selector
205
184
  if (window.opener && visualTaggingOptions.enabled) {
185
+ allowlist = options.cssSelectorAllowlist;
186
+ actionClickAllowlist = options.actionClickAllowlist;
206
187
  /* istanbul ignore next */
207
- (_c = visualTaggingOptions.messenger) === null || _c === void 0 ? void 0 : _c.setup(tslib_1.__assign(tslib_1.__assign({ logger: config === null || config === void 0 ? void 0 : config.loggerProvider }, ((config === null || config === void 0 ? void 0 : config.serverZone) && { endpoint: constants.AMPLITUDE_ORIGINS_MAP[config.serverZone] })), { isElementSelectable: shouldTrackEvent }));
188
+ (_c = visualTaggingOptions.messenger) === null || _c === void 0 ? void 0 : _c.setup(tslib_1.__assign(tslib_1.__assign({ logger: config === null || config === void 0 ? void 0 : config.loggerProvider }, ((config === null || config === void 0 ? void 0 : config.serverZone) && { endpoint: constants.AMPLITUDE_ORIGINS_MAP[config.serverZone] })), { isElementSelectable: (0, helpers_1.createShouldTrackEvent)(options, tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(allowlist), false), tslib_1.__read(actionClickAllowlist), false)), cssSelectorAllowlist: allowlist, actionClickAllowlist: actionClickAllowlist }));
208
189
  }
209
190
  return [2 /*return*/];
210
191
  });
@@ -215,11 +196,22 @@ var autocapturePlugin = function (options) {
215
196
  });
216
197
  }); };
217
198
  var teardown = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
218
- return tslib_1.__generator(this, function (_a) {
219
- if (observer) {
220
- observer.disconnect();
199
+ var subscriptions_1, subscriptions_1_1, subscription;
200
+ var e_1, _a;
201
+ return tslib_1.__generator(this, function (_b) {
202
+ try {
203
+ for (subscriptions_1 = tslib_1.__values(subscriptions), subscriptions_1_1 = subscriptions_1.next(); !subscriptions_1_1.done; subscriptions_1_1 = subscriptions_1.next()) {
204
+ subscription = subscriptions_1_1.value;
205
+ subscription.unsubscribe();
206
+ }
207
+ }
208
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
209
+ finally {
210
+ try {
211
+ if (subscriptions_1_1 && !subscriptions_1_1.done && (_a = subscriptions_1.return)) _a.call(subscriptions_1);
212
+ }
213
+ finally { if (e_1) throw e_1.error; }
221
214
  }
222
- removeEventListeners();
223
215
  return [2 /*return*/];
224
216
  });
225
217
  }); };