@adobe/helix-rum-enhancer 2.18.0 → 2.19.1
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/CHANGELOG.md +14 -0
- package/README.md +0 -1
- package/modules/defaults.js +4 -1
- package/modules/fflags.js +7 -5
- package/modules/index.js +34 -132
- package/modules/martech.js +83 -0
- package/package.json +6 -6
- package/src/index.js +109 -132
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [2.19.1](https://github.com/adobe/helix-rum-enhancer/compare/v2.19.0...v2.19.1) (2024-08-15)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **navigation:** remove `leave` checkpoint ([95503de](https://github.com/adobe/helix-rum-enhancer/commit/95503de3dfd83534a8692d6fa3a1af96734e65aa)), closes [/github.com/adobe/helix-rum-enhancer/pull/257#discussion_r1718152824](https://github.com//github.com/adobe/helix-rum-enhancer/pull/257/issues/discussion_r1718152824)
|
|
7
|
+
|
|
8
|
+
# [2.19.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.18.0...v2.19.0) (2024-08-13)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **onetrust:** enable on all domains ([6039f11](https://github.com/adobe/helix-rum-enhancer/commit/6039f1198f6484d623a3e42ffdd24807b6ed7c54))
|
|
14
|
+
|
|
1
15
|
# [2.18.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.17.1...v2.18.0) (2024-08-08)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -22,7 +22,6 @@ It will add following new checkpoints:
|
|
|
22
22
|
- `viewmedia`: An image or video hosted by Helix Media Bus has been scrolled into the viewport
|
|
23
23
|
- `reload`, `navigate`, `enter`: depending on how the current page was accessed
|
|
24
24
|
- `formsubmit`: when a form is submitted
|
|
25
|
-
- `leave`: when the user leaves the page
|
|
26
25
|
|
|
27
26
|
## Development
|
|
28
27
|
|
package/modules/defaults.js
CHANGED
|
@@ -9,5 +9,8 @@
|
|
|
9
9
|
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
|
+
import { fflags } from './fflags.js';
|
|
13
|
+
|
|
12
14
|
export const KNOWN_PROPERTIES = ['weight', 'id', 'referer', 'checkpoint', 't', 'source', 'target', 'cwv', 'CLS', 'FID', 'LCP', 'INP', 'TTFB'];
|
|
13
|
-
export const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', '
|
|
15
|
+
export const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'viewblock', 'viewmedia', 'loadresource', 'utm', 'paid', 'email', 'consent'];
|
|
16
|
+
fflags.enabled('example', () => DEFAULT_TRACKING_EVENTS.push('example'));
|
package/modules/fflags.js
CHANGED
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
export const fflags = {
|
|
13
|
-
has: (flag) =>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
has: (flag) => fflags[flag].indexOf(Array.from(window.origin)
|
|
14
|
+
.map((a) => a.charCodeAt(0))
|
|
15
|
+
.reduce((a, b) => a + b, 1) % 1371) !== -1
|
|
16
|
+
|| !!window.origin.match(/localhost/),
|
|
17
17
|
enabled: (flag, callback) => fflags.has(flag) && callback(),
|
|
18
|
+
/* c8 ignore next */
|
|
18
19
|
disabled: (flag, callback) => !fflags.has(flag) && callback(),
|
|
19
|
-
|
|
20
|
+
eagercwv: [683],
|
|
21
|
+
example: [543, 770, 1136],
|
|
20
22
|
};
|
package/modules/index.js
CHANGED
|
@@ -12,31 +12,27 @@
|
|
|
12
12
|
/* eslint-env browser */
|
|
13
13
|
|
|
14
14
|
import { KNOWN_PROPERTIES, DEFAULT_TRACKING_EVENTS } from './defaults.js';
|
|
15
|
-
import { fflags } from './fflags.js';
|
|
16
15
|
import { urlSanitizers } from './utils.js';
|
|
17
16
|
import { targetSelector, sourceSelector } from './dom.js';
|
|
17
|
+
import {
|
|
18
|
+
addAdsParametersTracking,
|
|
19
|
+
addCookieConsentTracking,
|
|
20
|
+
addEmailParameterTracking,
|
|
21
|
+
addUTMParametersTracking,
|
|
22
|
+
} from './martech.js';
|
|
23
|
+
import { fflags } from './fflags.js';
|
|
18
24
|
|
|
19
|
-
const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum
|
|
25
|
+
const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum
|
|
26
|
+
/* c8 ignore next */ : {};
|
|
20
27
|
|
|
21
28
|
const formSubmitListener = (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) });
|
|
22
29
|
// eslint-disable-next-line no-use-before-define
|
|
23
|
-
const mutationObserver = window.MutationObserver ? new MutationObserver(mutationsCallback)
|
|
24
|
-
|
|
25
|
-
// eslint-disable-next-line no-unused-vars
|
|
26
|
-
function optedIn(checkpoint, data) {
|
|
27
|
-
// TODO: check config service to know if
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
// Gets configured collection from the config service for the current domain
|
|
31
|
-
function getCollectionConfig() {
|
|
32
|
-
// eslint-disable-next-line max-len
|
|
33
|
-
fflags.enabled('onetrust', () => DEFAULT_TRACKING_EVENTS.push('consent'));
|
|
34
|
-
return DEFAULT_TRACKING_EVENTS;
|
|
35
|
-
}
|
|
30
|
+
const mutationObserver = window.MutationObserver ? new MutationObserver(mutationsCallback)
|
|
31
|
+
/* c8 ignore next */ : null;
|
|
36
32
|
|
|
37
33
|
function trackCheckpoint(checkpoint, data, t) {
|
|
38
34
|
const { weight, id } = window.hlx.rum;
|
|
39
|
-
if (
|
|
35
|
+
if (isSelected) {
|
|
40
36
|
const sendPing = (pdata = data) => {
|
|
41
37
|
// eslint-disable-next-line object-curly-newline, max-len
|
|
42
38
|
const body = JSON.stringify({ weight, id, referer: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'](), checkpoint, t, ...data }, KNOWN_PROPERTIES);
|
|
@@ -84,7 +80,6 @@ function addCWVTracking() {
|
|
|
84
80
|
sampleRUM('cwv', data);
|
|
85
81
|
};
|
|
86
82
|
|
|
87
|
-
const featureToggle = () => window.location.hostname === 'blog.adobe.com';
|
|
88
83
|
const isEager = (metric) => ['CLS', 'LCP'].includes(metric);
|
|
89
84
|
|
|
90
85
|
// When loading `web-vitals` using a classic script, all the public
|
|
@@ -92,7 +87,10 @@ function addCWVTracking() {
|
|
|
92
87
|
['FID', 'INP', 'TTFB', 'CLS', 'LCP'].forEach((metric) => {
|
|
93
88
|
const metricFn = window.webVitals[`on${metric}`];
|
|
94
89
|
if (typeof metricFn === 'function') {
|
|
95
|
-
|
|
90
|
+
let opts = {};
|
|
91
|
+
fflags.enabled('eagercwv', () => {
|
|
92
|
+
opts = { reportAllChanges: isEager(metric) };
|
|
93
|
+
});
|
|
96
94
|
metricFn(storeCWV, opts);
|
|
97
95
|
}
|
|
98
96
|
});
|
|
@@ -105,7 +103,7 @@ function addCWVTracking() {
|
|
|
105
103
|
}, 2000); // wait for delayed
|
|
106
104
|
}
|
|
107
105
|
|
|
108
|
-
function
|
|
106
|
+
function addNavigationTracking() {
|
|
109
107
|
// enter checkpoint when referrer is not the current page url
|
|
110
108
|
const navigate = (source, type) => {
|
|
111
109
|
const payload = { source, target: document.visibilityState };
|
|
@@ -122,22 +120,8 @@ function addEnterLeaveTracking() {
|
|
|
122
120
|
};
|
|
123
121
|
|
|
124
122
|
new PerformanceObserver((list) => list
|
|
125
|
-
.getEntries().map((entry) => navigate(document.referrer, entry.type)))
|
|
123
|
+
.getEntries().map((entry) => navigate(window.hlx.referrer || document.referrer, entry.type)))
|
|
126
124
|
.observe({ type: 'navigation', buffered: true });
|
|
127
|
-
|
|
128
|
-
const leave = ((event) => {
|
|
129
|
-
try {
|
|
130
|
-
if (leave.left || (event.type === 'visibilitychange' && document.visibilityState !== 'hidden')) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
leave.left = true;
|
|
134
|
-
sampleRUM('leave');
|
|
135
|
-
} catch (error) {
|
|
136
|
-
// something went wrong
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
window.addEventListener('visibilitychange', ((event) => leave(event)));
|
|
140
|
-
window.addEventListener('pagehide', ((event) => leave(event)));
|
|
141
125
|
}
|
|
142
126
|
|
|
143
127
|
function addLoadResourceTracking() {
|
|
@@ -176,9 +160,8 @@ function activateBlocksMutationObserver() {
|
|
|
176
160
|
}
|
|
177
161
|
|
|
178
162
|
function getIntersectionObsever(checkpoint) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
163
|
+
/* c8 ignore next */
|
|
164
|
+
if (!window.IntersectionObserver) return null;
|
|
182
165
|
activateBlocksMutationObserver();
|
|
183
166
|
const observer = new IntersectionObserver((entries) => {
|
|
184
167
|
try {
|
|
@@ -216,45 +199,6 @@ function addViewMediaTracking(parent) {
|
|
|
216
199
|
}
|
|
217
200
|
}
|
|
218
201
|
|
|
219
|
-
function addUTMParametersTracking() {
|
|
220
|
-
const usp = new URLSearchParams(window.location.search);
|
|
221
|
-
[...usp.entries()]
|
|
222
|
-
.filter(([key]) => key.startsWith('utm_'))
|
|
223
|
-
// exclude keys that may leak PII
|
|
224
|
-
.filter(([key]) => key !== 'utm_id')
|
|
225
|
-
.filter(([key]) => key !== 'utm_term')
|
|
226
|
-
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function addAdsParametersTracking() {
|
|
230
|
-
const networks = {
|
|
231
|
-
google: /gclid|gclsrc|wbraid|gbraid/,
|
|
232
|
-
doubleclick: /dclid/,
|
|
233
|
-
microsoft: /msclkid/,
|
|
234
|
-
facebook: /fb(cl|ad_|pxl_)id/,
|
|
235
|
-
twitter: /tw(clid|src|term)/,
|
|
236
|
-
linkedin: /li_fat_id/,
|
|
237
|
-
pinterest: /epik/,
|
|
238
|
-
tiktok: /ttclid/,
|
|
239
|
-
};
|
|
240
|
-
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
241
|
-
Object.entries(networks).forEach(([network, regex]) => {
|
|
242
|
-
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function addEmailParameterTracking() {
|
|
247
|
-
const networks = {
|
|
248
|
-
mailchimp: /mc_(c|e)id/,
|
|
249
|
-
marketo: /mkt_tok/,
|
|
250
|
-
|
|
251
|
-
};
|
|
252
|
-
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
253
|
-
Object.entries(networks).forEach(([network, regex]) => {
|
|
254
|
-
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
|
|
258
202
|
function addFormTracking(parent) {
|
|
259
203
|
activateBlocksMutationObserver();
|
|
260
204
|
parent.querySelectorAll('form').forEach((form) => {
|
|
@@ -263,42 +207,7 @@ function addFormTracking(parent) {
|
|
|
263
207
|
});
|
|
264
208
|
}
|
|
265
209
|
|
|
266
|
-
|
|
267
|
-
const cmpCookie = document.cookie.split(';')
|
|
268
|
-
.map((c) => c.trim())
|
|
269
|
-
.find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));
|
|
270
|
-
|
|
271
|
-
if (cmpCookie) {
|
|
272
|
-
sampleRUM('consent', { source: 'onetrust', target: 'hidden' });
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
let consentMutationObserver;
|
|
277
|
-
const trackShowConsent = () => {
|
|
278
|
-
if (document.querySelector('body > div#onetrust-consent-sdk')) {
|
|
279
|
-
sampleRUM('consent', { source: 'onetrust', target: 'show' });
|
|
280
|
-
if (consentMutationObserver) {
|
|
281
|
-
consentMutationObserver.disconnect();
|
|
282
|
-
}
|
|
283
|
-
return true;
|
|
284
|
-
}
|
|
285
|
-
return false;
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
if (!trackShowConsent()) {
|
|
289
|
-
// eslint-disable-next-line max-len
|
|
290
|
-
consentMutationObserver = window.MutationObserver ? new MutationObserver(trackShowConsent) : null;
|
|
291
|
-
if (consentMutationObserver) {
|
|
292
|
-
consentMutationObserver.observe(
|
|
293
|
-
document.body,
|
|
294
|
-
// eslint-disable-next-line object-curly-newline
|
|
295
|
-
{ attributes: false, childList: true, subtree: false },
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const addObserver = (ck, fn, block) => getCollectionConfig().includes(ck) && fn(block);
|
|
210
|
+
const addObserver = (ck, fn, block) => DEFAULT_TRACKING_EVENTS.includes(ck) && fn(block);
|
|
302
211
|
function mutationsCallback(mutations) {
|
|
303
212
|
mutations.filter((m) => m.type === 'attributes' && m.attributeName === 'data-block-status')
|
|
304
213
|
.filter((m) => m.target.dataset.blockStatus === 'loaded')
|
|
@@ -310,26 +219,19 @@ function mutationsCallback(mutations) {
|
|
|
310
219
|
}
|
|
311
220
|
|
|
312
221
|
function addTrackingFromConfig() {
|
|
313
|
-
|
|
314
|
-
click: ()
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
consent: () => addCookieConsentTracking(),
|
|
327
|
-
paid: () => addAdsParametersTracking(),
|
|
328
|
-
email: () => addEmailParameterTracking(),
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
getCollectionConfig().filter((ck) => trackingFunctions[ck])
|
|
332
|
-
.forEach((ck) => trackingFunctions[ck]());
|
|
222
|
+
document.addEventListener('click', (event) => {
|
|
223
|
+
sampleRUM('click', { target: targetSelector(event.target), source: sourceSelector(event.target) });
|
|
224
|
+
});
|
|
225
|
+
addCWVTracking();
|
|
226
|
+
addFormTracking(window.document.body);
|
|
227
|
+
addNavigationTracking();
|
|
228
|
+
addLoadResourceTracking();
|
|
229
|
+
addUTMParametersTracking(sampleRUM);
|
|
230
|
+
addViewBlockTracking(window.document.body);
|
|
231
|
+
addViewMediaTracking(window.document.body);
|
|
232
|
+
addCookieConsentTracking(sampleRUM);
|
|
233
|
+
addAdsParametersTracking(sampleRUM);
|
|
234
|
+
addEmailParameterTracking(sampleRUM);
|
|
333
235
|
}
|
|
334
236
|
|
|
335
237
|
function initEnhancer() {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
export function addCookieConsentTracking(sampleRUM) {
|
|
13
|
+
const cmpCookie = document.cookie.split(';')
|
|
14
|
+
.map((c) => c.trim())
|
|
15
|
+
.find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));
|
|
16
|
+
|
|
17
|
+
if (cmpCookie) {
|
|
18
|
+
sampleRUM('consent', { source: 'onetrust', target: 'hidden' });
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let consentMutationObserver;
|
|
23
|
+
const trackShowConsent = () => {
|
|
24
|
+
if (document.querySelector('body > div#onetrust-consent-sdk')) {
|
|
25
|
+
sampleRUM('consent', { source: 'onetrust', target: 'show' });
|
|
26
|
+
if (consentMutationObserver) {
|
|
27
|
+
consentMutationObserver.disconnect();
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
if (!trackShowConsent()) {
|
|
35
|
+
// eslint-disable-next-line max-len
|
|
36
|
+
consentMutationObserver = window.MutationObserver
|
|
37
|
+
? new MutationObserver(trackShowConsent)
|
|
38
|
+
: /* c8 ignore next */ null;
|
|
39
|
+
if (consentMutationObserver) {
|
|
40
|
+
consentMutationObserver.observe(
|
|
41
|
+
document.body,
|
|
42
|
+
// eslint-disable-next-line object-curly-newline
|
|
43
|
+
{ attributes: false, childList: true, subtree: false },
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function addUTMParametersTracking(sampleRUM) {
|
|
50
|
+
const usp = new URLSearchParams(window.location.search);
|
|
51
|
+
[...usp.entries()]
|
|
52
|
+
.filter(([key]) => key.startsWith('utm_'))
|
|
53
|
+
// exclude keys that may leak PII
|
|
54
|
+
.filter(([key]) => key !== 'utm_id')
|
|
55
|
+
.filter(([key]) => key !== 'utm_term')
|
|
56
|
+
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
|
|
57
|
+
}
|
|
58
|
+
export function addAdsParametersTracking(sampleRUM) {
|
|
59
|
+
const networks = {
|
|
60
|
+
google: /gclid|gclsrc|wbraid|gbraid/,
|
|
61
|
+
doubleclick: /dclid/,
|
|
62
|
+
microsoft: /msclkid/,
|
|
63
|
+
facebook: /fb(cl|ad_|pxl_)id/,
|
|
64
|
+
twitter: /tw(clid|src|term)/,
|
|
65
|
+
linkedin: /li_fat_id/,
|
|
66
|
+
pinterest: /epik/,
|
|
67
|
+
tiktok: /ttclid/,
|
|
68
|
+
};
|
|
69
|
+
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
70
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
71
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
export function addEmailParameterTracking(sampleRUM) {
|
|
75
|
+
const networks = {
|
|
76
|
+
mailchimp: /mc_(c|e)id/,
|
|
77
|
+
marketo: /mkt_tok/,
|
|
78
|
+
};
|
|
79
|
+
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
80
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
81
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
|
|
82
|
+
});
|
|
83
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-rum-enhancer",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.1",
|
|
4
4
|
"description": "Helix RUM Enhancer",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@adobe/eslint-config-helix": "2.0.6",
|
|
37
|
-
"@adobe/helix-rum-js": "2.
|
|
37
|
+
"@adobe/helix-rum-js": "2.2.0",
|
|
38
38
|
"@esm-bundle/chai": "4.3.4-fix.0",
|
|
39
39
|
"@semantic-release/changelog": "6.0.3",
|
|
40
40
|
"@semantic-release/git": "10.0.1",
|
|
41
41
|
"@semantic-release/npm": "12.0.1",
|
|
42
|
-
"@web/test-runner": "0.18.
|
|
42
|
+
"@web/test-runner": "0.18.3",
|
|
43
43
|
"@web/test-runner-commands": "0.9.0",
|
|
44
44
|
"@web/test-runner-mocha": "0.9.0",
|
|
45
45
|
"@web/test-runner-playwright": "0.11.0",
|
|
@@ -50,15 +50,15 @@
|
|
|
50
50
|
"eslint-plugin-import": "2.29.1",
|
|
51
51
|
"husky": "9.1.4",
|
|
52
52
|
"jsdoc-to-markdown": "8.0.3",
|
|
53
|
-
"junit-report-builder": "
|
|
53
|
+
"junit-report-builder": "5.0.0",
|
|
54
54
|
"lint-staged": "15.2.8",
|
|
55
|
-
"mocha": "10.7.
|
|
55
|
+
"mocha": "10.7.3",
|
|
56
56
|
"mocha-multi-reporters": "1.5.1",
|
|
57
57
|
"rollup": "4.20.0",
|
|
58
58
|
"rollup-plugin-cleanup": "3.2.1",
|
|
59
59
|
"rollup-plugin-eslint-bundle": "9.0.0",
|
|
60
60
|
"semantic-release": "24.0.0",
|
|
61
|
-
"web-vitals": "4.2.
|
|
61
|
+
"web-vitals": "4.2.3"
|
|
62
62
|
},
|
|
63
63
|
"lint-staged": {
|
|
64
64
|
"*.js": "eslint",
|
package/src/index.js
CHANGED
|
@@ -15,19 +15,22 @@
|
|
|
15
15
|
(function () {
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
-
const KNOWN_PROPERTIES = ['weight', 'id', 'referer', 'checkpoint', 't', 'source', 'target', 'cwv', 'CLS', 'FID', 'LCP', 'INP', 'TTFB'];
|
|
19
|
-
const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'enterleave', 'viewblock', 'viewmedia', 'loadresource', 'utm', 'paid', 'email'];
|
|
20
|
-
|
|
21
18
|
const fflags = {
|
|
22
|
-
has: (flag) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
has: (flag) => fflags[flag].indexOf(Array.from(window.origin)
|
|
20
|
+
.map((a) => a.charCodeAt(0))
|
|
21
|
+
.reduce((a, b) => a + b, 1) % 1371) !== -1
|
|
22
|
+
|| !!window.origin.match(/localhost/),
|
|
26
23
|
enabled: (flag, callback) => fflags.has(flag) && callback(),
|
|
24
|
+
|
|
27
25
|
disabled: (flag, callback) => !fflags.has(flag) && callback(),
|
|
28
|
-
|
|
26
|
+
eagercwv: [683],
|
|
27
|
+
example: [543, 770, 1136],
|
|
29
28
|
};
|
|
30
29
|
|
|
30
|
+
const KNOWN_PROPERTIES = ['weight', 'id', 'referer', 'checkpoint', 't', 'source', 'target', 'cwv', 'CLS', 'FID', 'LCP', 'INP', 'TTFB'];
|
|
31
|
+
const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'viewblock', 'viewmedia', 'loadresource', 'utm', 'paid', 'email', 'consent'];
|
|
32
|
+
fflags.enabled('example', () => DEFAULT_TRACKING_EVENTS.push('example'));
|
|
33
|
+
|
|
31
34
|
const urlSanitizers = {
|
|
32
35
|
/**
|
|
33
36
|
* Returns the full url.
|
|
@@ -123,17 +126,86 @@
|
|
|
123
126
|
}
|
|
124
127
|
};
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
function addCookieConsentTracking(sampleRUM) {
|
|
130
|
+
const cmpCookie = document.cookie.split(';')
|
|
131
|
+
.map((c) => c.trim())
|
|
132
|
+
.find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));
|
|
133
|
+
|
|
134
|
+
if (cmpCookie) {
|
|
135
|
+
sampleRUM('consent', { source: 'onetrust', target: 'hidden' });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let consentMutationObserver;
|
|
140
|
+
const trackShowConsent = () => {
|
|
141
|
+
if (document.querySelector('body > div#onetrust-consent-sdk')) {
|
|
142
|
+
sampleRUM('consent', { source: 'onetrust', target: 'show' });
|
|
143
|
+
if (consentMutationObserver) {
|
|
144
|
+
consentMutationObserver.disconnect();
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
if (!trackShowConsent()) {
|
|
152
|
+
// eslint-disable-next-line max-len
|
|
153
|
+
consentMutationObserver = window.MutationObserver
|
|
154
|
+
? new MutationObserver(trackShowConsent)
|
|
155
|
+
: null;
|
|
156
|
+
if (consentMutationObserver) {
|
|
157
|
+
consentMutationObserver.observe(
|
|
158
|
+
document.body,
|
|
159
|
+
// eslint-disable-next-line object-curly-newline
|
|
160
|
+
{ attributes: false, childList: true, subtree: false },
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function addUTMParametersTracking(sampleRUM) {
|
|
167
|
+
const usp = new URLSearchParams(window.location.search);
|
|
168
|
+
[...usp.entries()]
|
|
169
|
+
.filter(([key]) => key.startsWith('utm_'))
|
|
170
|
+
// exclude keys that may leak PII
|
|
171
|
+
.filter(([key]) => key !== 'utm_id')
|
|
172
|
+
.filter(([key]) => key !== 'utm_term')
|
|
173
|
+
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
|
|
174
|
+
}
|
|
175
|
+
function addAdsParametersTracking(sampleRUM) {
|
|
176
|
+
const networks = {
|
|
177
|
+
google: /gclid|gclsrc|wbraid|gbraid/,
|
|
178
|
+
doubleclick: /dclid/,
|
|
179
|
+
microsoft: /msclkid/,
|
|
180
|
+
facebook: /fb(cl|ad_|pxl_)id/,
|
|
181
|
+
twitter: /tw(clid|src|term)/,
|
|
182
|
+
linkedin: /li_fat_id/,
|
|
183
|
+
pinterest: /epik/,
|
|
184
|
+
tiktok: /ttclid/,
|
|
185
|
+
};
|
|
186
|
+
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
187
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
188
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
function addEmailParameterTracking(sampleRUM) {
|
|
192
|
+
const networks = {
|
|
193
|
+
mailchimp: /mc_(c|e)id/,
|
|
194
|
+
marketo: /mkt_tok/,
|
|
195
|
+
};
|
|
196
|
+
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
197
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
198
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum
|
|
203
|
+
: {};
|
|
127
204
|
|
|
128
205
|
const formSubmitListener = (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) });
|
|
129
206
|
// eslint-disable-next-line no-use-before-define
|
|
130
|
-
const mutationObserver = window.MutationObserver ? new MutationObserver(mutationsCallback)
|
|
131
|
-
|
|
132
|
-
function getCollectionConfig() {
|
|
133
|
-
// eslint-disable-next-line max-len
|
|
134
|
-
fflags.enabled('onetrust', () => DEFAULT_TRACKING_EVENTS.push('consent'));
|
|
135
|
-
return DEFAULT_TRACKING_EVENTS;
|
|
136
|
-
}
|
|
207
|
+
const mutationObserver = window.MutationObserver ? new MutationObserver(mutationsCallback)
|
|
208
|
+
: null;
|
|
137
209
|
|
|
138
210
|
function trackCheckpoint(checkpoint, data, t) {
|
|
139
211
|
const { weight, id } = window.hlx.rum;
|
|
@@ -184,7 +256,6 @@
|
|
|
184
256
|
sampleRUM('cwv', data);
|
|
185
257
|
};
|
|
186
258
|
|
|
187
|
-
const featureToggle = () => window.location.hostname === 'blog.adobe.com';
|
|
188
259
|
const isEager = (metric) => ['CLS', 'LCP'].includes(metric);
|
|
189
260
|
|
|
190
261
|
// When loading `web-vitals` using a classic script, all the public
|
|
@@ -192,7 +263,10 @@
|
|
|
192
263
|
['FID', 'INP', 'TTFB', 'CLS', 'LCP'].forEach((metric) => {
|
|
193
264
|
const metricFn = window.webVitals[`on${metric}`];
|
|
194
265
|
if (typeof metricFn === 'function') {
|
|
195
|
-
|
|
266
|
+
let opts = {};
|
|
267
|
+
fflags.enabled('eagercwv', () => {
|
|
268
|
+
opts = { reportAllChanges: isEager(metric) };
|
|
269
|
+
});
|
|
196
270
|
metricFn(storeCWV, opts);
|
|
197
271
|
}
|
|
198
272
|
});
|
|
@@ -204,7 +278,7 @@
|
|
|
204
278
|
}, 2000); // wait for delayed
|
|
205
279
|
}
|
|
206
280
|
|
|
207
|
-
function
|
|
281
|
+
function addNavigationTracking() {
|
|
208
282
|
// enter checkpoint when referrer is not the current page url
|
|
209
283
|
const navigate = (source, type) => {
|
|
210
284
|
const payload = { source, target: document.visibilityState };
|
|
@@ -221,22 +295,8 @@
|
|
|
221
295
|
};
|
|
222
296
|
|
|
223
297
|
new PerformanceObserver((list) => list
|
|
224
|
-
.getEntries().map((entry) => navigate(document.referrer, entry.type)))
|
|
298
|
+
.getEntries().map((entry) => navigate(window.hlx.referrer || document.referrer, entry.type)))
|
|
225
299
|
.observe({ type: 'navigation', buffered: true });
|
|
226
|
-
|
|
227
|
-
const leave = ((event) => {
|
|
228
|
-
try {
|
|
229
|
-
if (leave.left || (event.type === 'visibilitychange' && document.visibilityState !== 'hidden')) {
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
leave.left = true;
|
|
233
|
-
sampleRUM('leave');
|
|
234
|
-
} catch (error) {
|
|
235
|
-
// something went wrong
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
window.addEventListener('visibilitychange', ((event) => leave(event)));
|
|
239
|
-
window.addEventListener('pagehide', ((event) => leave(event)));
|
|
240
300
|
}
|
|
241
301
|
|
|
242
302
|
function addLoadResourceTracking() {
|
|
@@ -274,9 +334,7 @@
|
|
|
274
334
|
}
|
|
275
335
|
|
|
276
336
|
function getIntersectionObsever(checkpoint) {
|
|
277
|
-
if (!window.IntersectionObserver)
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
337
|
+
if (!window.IntersectionObserver) return null;
|
|
280
338
|
activateBlocksMutationObserver();
|
|
281
339
|
const observer = new IntersectionObserver((entries) => {
|
|
282
340
|
try {
|
|
@@ -313,45 +371,6 @@
|
|
|
313
371
|
}
|
|
314
372
|
}
|
|
315
373
|
|
|
316
|
-
function addUTMParametersTracking() {
|
|
317
|
-
const usp = new URLSearchParams(window.location.search);
|
|
318
|
-
[...usp.entries()]
|
|
319
|
-
.filter(([key]) => key.startsWith('utm_'))
|
|
320
|
-
// exclude keys that may leak PII
|
|
321
|
-
.filter(([key]) => key !== 'utm_id')
|
|
322
|
-
.filter(([key]) => key !== 'utm_term')
|
|
323
|
-
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
function addAdsParametersTracking() {
|
|
327
|
-
const networks = {
|
|
328
|
-
google: /gclid|gclsrc|wbraid|gbraid/,
|
|
329
|
-
doubleclick: /dclid/,
|
|
330
|
-
microsoft: /msclkid/,
|
|
331
|
-
facebook: /fb(cl|ad_|pxl_)id/,
|
|
332
|
-
twitter: /tw(clid|src|term)/,
|
|
333
|
-
linkedin: /li_fat_id/,
|
|
334
|
-
pinterest: /epik/,
|
|
335
|
-
tiktok: /ttclid/,
|
|
336
|
-
};
|
|
337
|
-
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
338
|
-
Object.entries(networks).forEach(([network, regex]) => {
|
|
339
|
-
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
function addEmailParameterTracking() {
|
|
344
|
-
const networks = {
|
|
345
|
-
mailchimp: /mc_(c|e)id/,
|
|
346
|
-
marketo: /mkt_tok/,
|
|
347
|
-
|
|
348
|
-
};
|
|
349
|
-
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
350
|
-
Object.entries(networks).forEach(([network, regex]) => {
|
|
351
|
-
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
|
|
355
374
|
function addFormTracking(parent) {
|
|
356
375
|
activateBlocksMutationObserver();
|
|
357
376
|
parent.querySelectorAll('form').forEach((form) => {
|
|
@@ -360,42 +379,7 @@
|
|
|
360
379
|
});
|
|
361
380
|
}
|
|
362
381
|
|
|
363
|
-
|
|
364
|
-
const cmpCookie = document.cookie.split(';')
|
|
365
|
-
.map((c) => c.trim())
|
|
366
|
-
.find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));
|
|
367
|
-
|
|
368
|
-
if (cmpCookie) {
|
|
369
|
-
sampleRUM('consent', { source: 'onetrust', target: 'hidden' });
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
let consentMutationObserver;
|
|
374
|
-
const trackShowConsent = () => {
|
|
375
|
-
if (document.querySelector('body > div#onetrust-consent-sdk')) {
|
|
376
|
-
sampleRUM('consent', { source: 'onetrust', target: 'show' });
|
|
377
|
-
if (consentMutationObserver) {
|
|
378
|
-
consentMutationObserver.disconnect();
|
|
379
|
-
}
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
return false;
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
if (!trackShowConsent()) {
|
|
386
|
-
// eslint-disable-next-line max-len
|
|
387
|
-
consentMutationObserver = window.MutationObserver ? new MutationObserver(trackShowConsent) : null;
|
|
388
|
-
if (consentMutationObserver) {
|
|
389
|
-
consentMutationObserver.observe(
|
|
390
|
-
document.body,
|
|
391
|
-
// eslint-disable-next-line object-curly-newline
|
|
392
|
-
{ attributes: false, childList: true, subtree: false },
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const addObserver = (ck, fn, block) => getCollectionConfig().includes(ck) && fn(block);
|
|
382
|
+
const addObserver = (ck, fn, block) => DEFAULT_TRACKING_EVENTS.includes(ck) && fn(block);
|
|
399
383
|
function mutationsCallback(mutations) {
|
|
400
384
|
mutations.filter((m) => m.type === 'attributes' && m.attributeName === 'data-block-status')
|
|
401
385
|
.filter((m) => m.target.dataset.blockStatus === 'loaded')
|
|
@@ -407,26 +391,19 @@
|
|
|
407
391
|
}
|
|
408
392
|
|
|
409
393
|
function addTrackingFromConfig() {
|
|
410
|
-
|
|
411
|
-
click: ()
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
consent: () => addCookieConsentTracking(),
|
|
424
|
-
paid: () => addAdsParametersTracking(),
|
|
425
|
-
email: () => addEmailParameterTracking(),
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
getCollectionConfig().filter((ck) => trackingFunctions[ck])
|
|
429
|
-
.forEach((ck) => trackingFunctions[ck]());
|
|
394
|
+
document.addEventListener('click', (event) => {
|
|
395
|
+
sampleRUM('click', { target: targetSelector(event.target), source: sourceSelector(event.target) });
|
|
396
|
+
});
|
|
397
|
+
addCWVTracking();
|
|
398
|
+
addFormTracking(window.document.body);
|
|
399
|
+
addNavigationTracking();
|
|
400
|
+
addLoadResourceTracking();
|
|
401
|
+
addUTMParametersTracking(sampleRUM);
|
|
402
|
+
addViewBlockTracking(window.document.body);
|
|
403
|
+
addViewMediaTracking(window.document.body);
|
|
404
|
+
addCookieConsentTracking(sampleRUM);
|
|
405
|
+
addAdsParametersTracking(sampleRUM);
|
|
406
|
+
addEmailParameterTracking(sampleRUM);
|
|
430
407
|
}
|
|
431
408
|
|
|
432
409
|
function initEnhancer() {
|