Skip to content

Commit c8c3191

Browse files
Paul Boocockpaulboocock
authored andcommitted
Allow forms and fields properties to be undefined on FormTrackingOptions (close snowplow#935)
1 parent a84e72d commit c8c3191

4 files changed

Lines changed: 30 additions & 44 deletions

File tree

libraries/browser-tracker-core/src/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ export function getFilterByClass(criterion?: FilterCriterion<HTMLElement> | null
489489
* or {denylist: [array of allowable strings]}
490490
* or {filter: function (elt) {return whether to track the element}
491491
*/
492-
export function getFilterByName<T extends { name: string }>(criterion: FilterCriterion<T>): (elt: T) => boolean {
492+
export function getFilterByName<T extends { name: string }>(criterion?: FilterCriterion<T>): (elt: T) => boolean {
493493
// If the criterion argument is not an object, add listeners to all elements
494494
if (criterion == null || typeof criterion !== 'object' || Array.isArray(criterion)) {
495495
return function () {

plugins/browser-plugin-form-tracking/src/helpers.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ import {
4343
buildFormSubmission,
4444
} from '@snowplow/tracker-core';
4545

46-
export interface FormTrackingOptions {
47-
forms: FilterCriterion<HTMLElement>;
48-
fields: FilterCriterion<TrackedHTMLElement> & { transform: transformFn };
46+
/** The form tracking configuration */
47+
export interface FormTrackingConfiguration {
48+
/** The options which can be configured for the form tracking events */
49+
options?: FormTrackingOptions;
50+
/** The dyanmic context which will be evaluated for each form event */
51+
context?: DynamicContext | null;
4952
}
5053

51-
export interface FormConfiguration {
52-
formFilter: (_: HTMLFormElement) => boolean;
53-
fieldFilter: (_: TrackedHTMLElement) => boolean;
54-
fieldTransform: transformFn;
54+
export interface FormTrackingOptions {
55+
forms?: FilterCriterion<HTMLElement>;
56+
fields?: FilterCriterion<TrackedHTMLElement> & { transform: transformFn };
5557
}
5658

5759
export interface TrackedHTMLElementTagNameMap {
@@ -75,17 +77,20 @@ export const innerElementTags: Array<keyof TrackedHTMLElementTagNameMap> = ['tex
7577

7678
const defaultTransformFn: transformFn = (x) => x;
7779

80+
interface FormConfiguration {
81+
formFilter: (_: HTMLFormElement) => boolean;
82+
fieldFilter: (_: TrackedHTMLElement) => boolean;
83+
fieldTransform: transformFn;
84+
}
85+
7886
/*
7987
* Add submission event listeners to all form elements
8088
* Add value change event listeners to all mutable inner form elements
8189
*/
82-
export function addFormListeners(
83-
tracker: BrowserTracker,
84-
formConfiguration?: FormTrackingOptions,
85-
context?: DynamicContext | null
86-
) {
87-
const trackingMarker = tracker.id + 'form',
88-
config = getConfigurationForOptions(formConfiguration);
90+
export function addFormListeners(tracker: BrowserTracker, configuration: FormTrackingConfiguration) {
91+
const { options, context } = configuration,
92+
trackingMarker = tracker.id + 'form',
93+
config = getConfigurationForOptions(options);
8994

9095
Array.prototype.slice.call(document.getElementsByTagName('form')).forEach(function (form) {
9196
if (config.formFilter(form) && !form[trackingMarker]) {
@@ -143,8 +148,8 @@ function getConfigurationForOptions(options?: FormTrackingOptions) {
143148
*
144149
* @param object criterion {transform: function (elt) {return the result of transform function applied to element}
145150
*/
146-
function getTransform(criterion: { transform: transformFn }): transformFn {
147-
if (Object.prototype.hasOwnProperty.call(criterion, 'transform')) {
151+
function getTransform(criterion?: { transform: transformFn }): transformFn {
152+
if (criterion && Object.prototype.hasOwnProperty.call(criterion, 'transform')) {
148153
return criterion.transform;
149154
}
150155

plugins/browser-plugin-form-tracking/src/index.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@
2929
*/
3030

3131
import { BrowserPlugin, BrowserTracker } from '@snowplow/browser-tracker-core';
32-
import { DynamicContext } from '@snowplow/tracker-core';
33-
import { FormTrackingOptions, addFormListeners } from './helpers';
32+
import { addFormListeners, FormTrackingConfiguration } from './helpers';
33+
34+
export { FormTrackingConfiguration } from './helpers';
3435

3536
const _trackers: Record<string, BrowserTracker> = {};
3637

@@ -45,14 +46,6 @@ export function FormTrackingPlugin(): BrowserPlugin {
4546
};
4647
}
4748

48-
/** The form tracking configuration */
49-
export interface FormTrackingConfiguration {
50-
/** The options which can be configured for the form tracking events */
51-
options?: FormTrackingOptions;
52-
/** The dyanmic context which will be evaluated for each form event */
53-
context?: DynamicContext | null;
54-
}
55-
5649
/**
5750
* Enables automatic form tracking
5851
* An event will be fired when a form field is changed or a form submitted.
@@ -65,14 +58,13 @@ export function enableFormTracking(
6558
configuration: FormTrackingConfiguration = {},
6659
trackers: Array<string> = Object.keys(_trackers)
6760
) {
68-
const { options, context } = configuration;
6961
trackers.forEach((t) => {
7062
if (_trackers[t]) {
7163
if (_trackers[t].sharedState.hasLoaded) {
72-
addFormListeners(_trackers[t], options, context);
64+
addFormListeners(_trackers[t], configuration);
7365
} else {
7466
_trackers[t].sharedState.registeredOnLoadHandlers.push(function () {
75-
addFormListeners(_trackers[t], options, context);
67+
addFormListeners(_trackers[t], configuration);
7668
});
7769
}
7870
}

plugins/browser-plugin-link-click-tracking/src/index.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,16 @@ export function enableLinkClickTracking(
104104
configuration: LinkClickTrackingConfiguration = {},
105105
trackers: Array<string> = Object.keys(_trackers)
106106
) {
107-
const { options, pseudoClicks, trackContent, context } = configuration;
108107
trackers.forEach((id) => {
109108
if (_trackers[id]) {
110109
if (_trackers[id].sharedState.hasLoaded) {
111110
// the load event has already fired, add the click listeners now
112-
configureLinkClickTracking({ options, pseudoClicks, trackContent, context }, id);
111+
configureLinkClickTracking(configuration, id);
113112
addClickListeners(id);
114113
} else {
115114
// defer until page has loaded
116115
_trackers[id].sharedState.registeredOnLoadHandlers.push(function () {
117-
configureLinkClickTracking({ options, pseudoClicks, trackContent, context }, id);
116+
configureLinkClickTracking(configuration, id);
118117
addClickListeners(id);
119118
});
120119
}
@@ -258,17 +257,7 @@ function addClickListener(tracker: string, element: HTMLAnchorElement | HTMLArea
258257
* whether to use pseudo click tracking, and what context to attach to link_click events
259258
*/
260259
function configureLinkClickTracking(
261-
{
262-
options,
263-
pseudoClicks,
264-
trackContent,
265-
context,
266-
}: {
267-
options?: FilterCriterion<HTMLElement> | null;
268-
pseudoClicks?: boolean | null;
269-
trackContent?: boolean | null;
270-
context?: DynamicContext | null;
271-
} = {},
260+
{ options, pseudoClicks, trackContent, context }: LinkClickTrackingConfiguration = {},
272261
tracker: string
273262
) {
274263
_configuration[tracker] = {

0 commit comments

Comments
 (0)