Skip to content

Commit 781a514

Browse files
committed
Add a configurable default label for button_click
Fixes #1421
1 parent 25be003 commit 781a514

File tree

5 files changed

+59
-5
lines changed

5 files changed

+59
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@snowplow/browser-plugin-button-click-tracking",
5+
"comment": "Add default label to avoid bad events",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@snowplow/browser-plugin-button-click-tracking"
10+
}

plugins/browser-plugin-button-click-tracking/src/api.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ export function enableButtonClickTracking(
5858
// Store the configuration for this tracker, if it doesn't already exist
5959
// This allows us to enable click tracking for a tracker if it has been disabled
6060
_listeners[trackerId] = (event: MouseEvent) => {
61-
eventHandler(event, trackerId, filterFunctionFromFilter(configuration.filter), configuration.context);
61+
eventHandler(
62+
event,
63+
trackerId,
64+
filterFunctionFromFilter(configuration.filter),
65+
configuration.defaultLabel,
66+
configuration.context
67+
);
6268
};
6369

6470
const addClickListener = () => {
@@ -96,12 +102,18 @@ export function disableButtonClickTracking(trackers: Array<string> = Object.keys
96102
* @param filter - The filter function to use for button click tracking
97103
* @param context - The dynamic context which will be evaluated for each button click event
98104
*/
99-
function eventHandler(event: MouseEvent, trackerId: string, filter: FilterFunction, context?: DynamicContext) {
105+
function eventHandler(
106+
event: MouseEvent,
107+
trackerId: string,
108+
filter: FilterFunction,
109+
defaultLabel?: string | ((element: HTMLElement) => string),
110+
context?: DynamicContext
111+
) {
100112
let elem = (event.composed ? event.composedPath()[0] : event.target) as HTMLElement | null;
101113
while (elem) {
102114
if (elem instanceof HTMLButtonElement || (elem instanceof HTMLInputElement && elem.type === 'button')) {
103115
if (filter(elem)) {
104-
const buttonClickEvent = createEventFromButton(elem);
116+
const buttonClickEvent = createEventFromButton(elem, defaultLabel);
105117
buttonClickEvent.context = resolveDynamicContext(context, buttonClickEvent, elem);
106118
trackButtonClick(buttonClickEvent, [trackerId]);
107119
}

plugins/browser-plugin-button-click-tracking/src/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export interface ButtonClickTrackingConfiguration {
1818
filter?: Filter;
1919
/** The dynamic context which will be evaluated for each button click event */
2020
context?: DynamicContext;
21+
/** A default label to use if one can not be determined by the content or data attributes */
22+
defaultLabel?: string | ((element: HTMLElement) => string);
2123
}
2224

2325
/**

plugins/browser-plugin-button-click-tracking/src/util.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,19 @@ export function filterFunctionFromFilter(filter?: Filter): FilterFunction {
4242
* @returns The button click event
4343
*/
4444
export function createEventFromButton(
45-
button: HTMLButtonElement | HTMLInputElement
45+
button: HTMLButtonElement | HTMLInputElement,
46+
defaultLabel?: string | ((element: HTMLElement) => string)
4647
): ButtonClickEvent & CommonEventProperties {
4748
let ret = {} as ButtonClickEvent & CommonEventProperties;
4849

4950
if (button.tagName === 'INPUT') {
5051
ret.label = button.dataset.spButtonLabel || button.value;
5152
} else {
52-
ret.label = button.dataset.spButtonLabel || button.innerText;
53+
ret.label =
54+
button.dataset.spButtonLabel ||
55+
button.innerText ||
56+
(typeof defaultLabel === 'function' ? defaultLabel(button) : defaultLabel) ||
57+
'(empty)';
5358
}
5459

5560
button.id && (ret.id = button.id);

plugins/browser-plugin-button-click-tracking/test/test.test.ts

+25
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,31 @@ describe('Button Click Tracking Plugin', () => {
145145
expect(createEventFromButton(button)).toEqual(event);
146146
});
147147

148+
it('should use specified default label', () => {
149+
const button = document.createElement('button');
150+
button.innerText = '';
151+
button.id = 'testId';
152+
button.className = 'testClass testClass2';
153+
button.name = 'testName';
154+
155+
const event1 = {
156+
label: 'defaultLabel',
157+
id: 'testId',
158+
classes: ['testClass', 'testClass2'],
159+
name: 'testName',
160+
};
161+
162+
expect(createEventFromButton(button, 'defaultLabel')).toEqual(event1);
163+
164+
const event2 = {
165+
label: 'testClass testClass2',
166+
id: 'testId',
167+
classes: ['testClass', 'testClass2'],
168+
name: 'testName',
169+
};
170+
expect(createEventFromButton(button, (btn) => btn.className)).toEqual(event2);
171+
});
172+
148173
it('should prefer the data-sp-button-label attribute over the innerText', () => {
149174
const button = document.createElement('button');
150175
button.innerText = 'testLabel';

0 commit comments

Comments
 (0)