@guardian/ophan-tracker-js 2.2.4 → 2.2.6
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/NPM-dist/click-path-capture.js +25 -10
- package/NPM-dist/tests/click-path-capture.test.js +39 -5
- package/NPM-dist/types/types/event.d.ts +6 -6
- package/NPM-dist/types/types/product.d.ts +1 -1
- package/package.json +18 -1
- package/NPM-dist/types/types/utmparameters.d.ts +0 -26
- package/NPM-dist/types/utmparameters.js +0 -1
|
@@ -41,28 +41,43 @@ const getDataLinkNames = (el, dataLinkNames = []) => {
|
|
|
41
41
|
};
|
|
42
42
|
if (typeof document.addEventListener === 'function') {
|
|
43
43
|
document.addEventListener('click', function (e) {
|
|
44
|
-
let
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
let target = e.target;
|
|
45
|
+
let info;
|
|
46
|
+
// For anchors, use validAncestorAnchorElement
|
|
47
|
+
const anchorTarget = validAncestorAnchorElement(target);
|
|
48
|
+
const nonTrackableElements = [
|
|
49
|
+
'div',
|
|
50
|
+
'span',
|
|
51
|
+
'p',
|
|
52
|
+
'section',
|
|
53
|
+
'article',
|
|
54
|
+
'main',
|
|
55
|
+
'header',
|
|
56
|
+
'footer',
|
|
57
|
+
'nav',
|
|
58
|
+
];
|
|
59
|
+
if (nonTrackableElements.includes(target.tagName.toLowerCase()) &&
|
|
60
|
+
!anchorTarget) {
|
|
48
61
|
return;
|
|
49
62
|
}
|
|
63
|
+
// If it's an anchor, use anchorTarget, otherwise use the original target
|
|
64
|
+
const trackingTarget = anchorTarget || target;
|
|
50
65
|
info = {
|
|
51
66
|
from: [location.protocol, '//', location.host, location.pathname].join(''),
|
|
52
|
-
to:
|
|
53
|
-
referringComponent: getContainingComponent(
|
|
54
|
-
referringDataLinkNames: getDataLinkNames(
|
|
67
|
+
to: trackingTarget.href || undefined,
|
|
68
|
+
referringComponent: getContainingComponent(trackingTarget),
|
|
69
|
+
referringDataLinkNames: getDataLinkNames(trackingTarget),
|
|
55
70
|
refPlatform: ophan.servingPlatform(),
|
|
56
71
|
refViewId: ophan.viewId,
|
|
57
72
|
};
|
|
58
|
-
if (info.referringDataLinkNames
|
|
73
|
+
if (info.referringDataLinkNames && info.referringDataLinkNames.length > 0) {
|
|
59
74
|
transmit.sendMore({
|
|
60
75
|
clickComponent: info.referringComponent,
|
|
61
76
|
clickLinkNames: info.referringDataLinkNames,
|
|
62
77
|
});
|
|
63
78
|
}
|
|
64
|
-
if (anchorTarget
|
|
65
|
-
//
|
|
79
|
+
if (anchorTarget) {
|
|
80
|
+
// If it's an anchor, we may be about to navigate away from this page, so store to send on next request
|
|
66
81
|
return ophan.storeDataToSendOnNextEvent(info);
|
|
67
82
|
}
|
|
68
83
|
}, false);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import clickPathCapture, { getContainingComponent, validAncestorAnchorElement } from '../click-path-capture.js';
|
|
1
|
+
import clickPathCapture, { getContainingComponent, validAncestorAnchorElement, } from '../click-path-capture.js';
|
|
2
2
|
import ophan from '../core.js';
|
|
3
3
|
import transmit from '../transmit.js';
|
|
4
4
|
const { getDataLinkNames } = clickPathCapture;
|
|
@@ -11,6 +11,8 @@ describe('click-path-capture.js', () => {
|
|
|
11
11
|
<span id="testElement1"></span>
|
|
12
12
|
</a>
|
|
13
13
|
<span id="nonLinkElement">Non-link element</span>
|
|
14
|
+
<button id="testButton" data-link-name="buttonLink" data-component="buttonComponent">Click Me</button>
|
|
15
|
+
<label id="testLabel" data-link-name="labelLink" data-component="labelComponent">Label Text</label>
|
|
14
16
|
</div>
|
|
15
17
|
</div>
|
|
16
18
|
<div id="testElement2" data-component="component2"></div>
|
|
@@ -46,7 +48,7 @@ describe('click-path-capture.js', () => {
|
|
|
46
48
|
</div>
|
|
47
49
|
`;
|
|
48
50
|
const element = document.getElementById('testElement1');
|
|
49
|
-
expect(getContainingComponent(element)).toBe(
|
|
51
|
+
expect(getContainingComponent(element)).toBe('nested-component');
|
|
50
52
|
});
|
|
51
53
|
});
|
|
52
54
|
describe('getDataLinkNames', () => {
|
|
@@ -62,8 +64,13 @@ describe('click-path-capture.js', () => {
|
|
|
62
64
|
describe('click event handling', () => {
|
|
63
65
|
let transmitSendMoreSpy, ophanStoreDataToSendOnNextEventSpy;
|
|
64
66
|
beforeEach(() => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
jest.clearAllMocks();
|
|
68
|
+
transmitSendMoreSpy = jest
|
|
69
|
+
.spyOn(transmit, 'sendMore')
|
|
70
|
+
.mockImplementation(() => { });
|
|
71
|
+
ophanStoreDataToSendOnNextEventSpy = jest
|
|
72
|
+
.spyOn(ophan, 'storeDataToSendOnNextEvent')
|
|
73
|
+
.mockImplementation(() => { });
|
|
67
74
|
});
|
|
68
75
|
afterEach(() => {
|
|
69
76
|
jest.clearAllMocks();
|
|
@@ -71,9 +78,36 @@ describe('click-path-capture.js', () => {
|
|
|
71
78
|
test('should send request and store data when a link is clicked', () => {
|
|
72
79
|
const element = document.getElementById('testElement1');
|
|
73
80
|
element.click();
|
|
74
|
-
expect(transmitSendMoreSpy).
|
|
81
|
+
expect(transmitSendMoreSpy).toHaveBeenCalledWith({
|
|
82
|
+
clickComponent: 'component1',
|
|
83
|
+
clickLinkNames: ['link1'],
|
|
84
|
+
});
|
|
75
85
|
expect(ophanStoreDataToSendOnNextEventSpy).toHaveBeenCalled();
|
|
76
86
|
});
|
|
87
|
+
test('should send request but not store data when a button is clicked', () => {
|
|
88
|
+
const element = document.getElementById('testButton');
|
|
89
|
+
element.click();
|
|
90
|
+
expect(transmitSendMoreSpy).toHaveBeenCalledWith({
|
|
91
|
+
clickComponent: 'buttonComponent',
|
|
92
|
+
clickLinkNames: ['buttonLink'],
|
|
93
|
+
});
|
|
94
|
+
expect(ophanStoreDataToSendOnNextEventSpy).not.toHaveBeenCalled();
|
|
95
|
+
});
|
|
96
|
+
test('should send request but not store data when a label is clicked', () => {
|
|
97
|
+
const element = document.getElementById('testLabel');
|
|
98
|
+
element.click();
|
|
99
|
+
expect(transmitSendMoreSpy).toHaveBeenCalledWith({
|
|
100
|
+
clickComponent: 'labelComponent',
|
|
101
|
+
clickLinkNames: ['labelLink'],
|
|
102
|
+
});
|
|
103
|
+
expect(ophanStoreDataToSendOnNextEventSpy).not.toHaveBeenCalled();
|
|
104
|
+
});
|
|
105
|
+
test('should not send request when a non-trackable element is clicked', () => {
|
|
106
|
+
const element = document.getElementById('nonLinkElement');
|
|
107
|
+
element.click();
|
|
108
|
+
expect(transmitSendMoreSpy).not.toHaveBeenCalled();
|
|
109
|
+
expect(ophanStoreDataToSendOnNextEventSpy).not.toHaveBeenCalled();
|
|
110
|
+
});
|
|
77
111
|
test('should not send request when a non-link element within a container is clicked', () => {
|
|
78
112
|
const element = document.getElementById('testElement4');
|
|
79
113
|
element.click();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AbTestInfo } from './abtest.js';
|
|
2
|
+
import type { Acquisition } from './acquisition.js';
|
|
2
3
|
import type { ComponentEvent } from './component-event.js';
|
|
4
|
+
import type { Consent } from './consent.js';
|
|
3
5
|
import type { InPageClick } from './inpageclick.js';
|
|
4
|
-
import
|
|
6
|
+
import { Interaction } from './interaction.js';
|
|
5
7
|
import type { AudioEvent, VideoEvent } from './media.js';
|
|
6
|
-
import type { TMembershipTier, TSubscriptionType } from './subscription.js';
|
|
7
8
|
import type { TPlatform } from './platform.js';
|
|
8
|
-
import type {
|
|
9
|
-
import { Interaction } from './interaction.js';
|
|
9
|
+
import type { TMembershipTier, TSubscriptionType } from './subscription.js';
|
|
10
10
|
/**
|
|
11
11
|
* Details about a page view - only populated for _PAGE_VIEW
|
|
12
12
|
* event types
|
|
@@ -26,7 +26,7 @@ interface PageView {
|
|
|
26
26
|
totalDaysVisited?: number;
|
|
27
27
|
/** Calculated average days between recent visits */
|
|
28
28
|
averageDaysBetweenRecentVisits?: number;
|
|
29
|
-
/**
|
|
29
|
+
/** No longer used in Ophan. Replaced by Frequency */
|
|
30
30
|
regular?: boolean;
|
|
31
31
|
subscriptionType?: TSubscriptionType;
|
|
32
32
|
membershipTier?: TMembershipTier;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guardian/ophan-tracker-js",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=16"
|
|
@@ -11,6 +11,23 @@
|
|
|
11
11
|
],
|
|
12
12
|
"main": "NPM-dist/ng.js",
|
|
13
13
|
"types": "NPM-dist/types/ng.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./NPM-dist/ng.js",
|
|
17
|
+
"types": "./NPM-dist/types/ng.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./MMA": {
|
|
20
|
+
"import": "./NPM-dist/manage-my-account.js",
|
|
21
|
+
"types": "./NPM-dist/types/manage-my-account.d.ts"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"typesVersions": {
|
|
25
|
+
"*": {
|
|
26
|
+
"MMA": [
|
|
27
|
+
"NPM-dist/types/manage-my-account.d.ts"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
14
31
|
"devDependencies": {
|
|
15
32
|
"@babel/preset-env": "^7.22.10",
|
|
16
33
|
"@babel/preset-typescript": "^7.24.7",
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A set of UTM parameters
|
|
3
|
-
* https://en.wikipedia.org/wiki/UTM_parameters
|
|
4
|
-
*/
|
|
5
|
-
interface UtmParameters {
|
|
6
|
-
/**
|
|
7
|
-
* Identifies which site sent the traffic
|
|
8
|
-
*/
|
|
9
|
-
utmSource?: string;
|
|
10
|
-
/**
|
|
11
|
-
* Identifies what type of link was used, such as cost per click or email.
|
|
12
|
-
*/
|
|
13
|
-
utmMedium?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Identifies a specific product promotion or strategic campaign.
|
|
16
|
-
*/
|
|
17
|
-
utmCampaign?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Identifies search terms.
|
|
20
|
-
*/
|
|
21
|
-
utmTerm?: string;
|
|
22
|
-
/**
|
|
23
|
-
* Identifies what specifically was clicked to bring the user to the site, such as a banner ad or a text link. It is often used for A/B testing and content-targeted ads.
|
|
24
|
-
*/
|
|
25
|
-
utmContent?: string;
|
|
26
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|