@adobe/helix-rum-enhancer 2.11.4 → 2.13.0
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 +19 -0
- package/dist/rum-enhancer.js +416 -0
- package/package.json +15 -3
- package/rollup.config.js +54 -0
- package/src/index.js +3 -2
- package/web-test-runner.config.js +25 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# [2.13.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.12.0...v2.13.0) (2024-06-11)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* proper linted output ([f2548ee](https://github.com/adobe/helix-rum-enhancer/commit/f2548eeda287e5a8abf75a9dc2156643640406eb))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **bundle:** first step to build enhancer as a bundle ([56255db](https://github.com/adobe/helix-rum-enhancer/commit/56255db63e4d9fcd5f9dd685ee942ebda3052130))
|
|
12
|
+
|
|
13
|
+
# [2.12.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.11.4...v2.12.0) (2024-06-10)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* **paid:** enable `paid` checkpoint for two more domains ([8acd7a9](https://github.com/adobe/helix-rum-enhancer/commit/8acd7a9b91dbf2aa706bb69e917fc49fff8ca037))
|
|
19
|
+
|
|
1
20
|
## [2.11.4](https://github.com/adobe/helix-rum-enhancer/compare/v2.11.3...v2.11.4) (2024-06-10)
|
|
2
21
|
|
|
3
22
|
|
|
@@ -0,0 +1,416 @@
|
|
|
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
|
+
|
|
13
|
+
/* eslint-disable max-classes-per-file, wrap-iife */
|
|
14
|
+
// eslint-disable-next-line func-names
|
|
15
|
+
(function () {
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
/* eslint-env browser */
|
|
19
|
+
const KNOWN_PROPERTIES = ['weight', 'id', 'referer', 'checkpoint', 't', 'source', 'target', 'cwv', 'CLS', 'FID', 'LCP', 'INP', 'TTFB'];
|
|
20
|
+
const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'enterleave', 'viewblock', 'viewmedia', 'loadresource', 'utm'];
|
|
21
|
+
const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum : {};
|
|
22
|
+
|
|
23
|
+
const fflags = {
|
|
24
|
+
has: (flag) => fflags[flag].indexOf(Array.from(window.origin)
|
|
25
|
+
.map((a) => a.charCodeAt(0))
|
|
26
|
+
.reduce((a, b) => a + b, 1) % 1371) !== -1,
|
|
27
|
+
enabled: (flag, callback) => fflags.has(flag) && callback(),
|
|
28
|
+
disabled: (flag, callback) => !fflags.has(flag) && callback(),
|
|
29
|
+
onetrust: [543, 770, 1136],
|
|
30
|
+
ads: [1139, 543, 770, 984],
|
|
31
|
+
email: [1139, 543, 770, 984],
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const urlSanitizers = {
|
|
35
|
+
full: () => window.location.href,
|
|
36
|
+
origin: () => window.location.origin,
|
|
37
|
+
path: () => window.location.href.replace(/\?.*$/, ''),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const getTargetValue = (element) => element.getAttribute('data-rum-target') || element.getAttribute('href')
|
|
41
|
+
|| element.currentSrc || element.getAttribute('src') || element.dataset.action || element.action;
|
|
42
|
+
|
|
43
|
+
const targetselector = (element) => {
|
|
44
|
+
try {
|
|
45
|
+
if (!element) return undefined;
|
|
46
|
+
let value = getTargetValue(element);
|
|
47
|
+
if (!value && element.tagName !== 'A' && element.closest('a')) {
|
|
48
|
+
value = getTargetValue(element.closest('a'));
|
|
49
|
+
}
|
|
50
|
+
if (value && !value.startsWith('https://')) {
|
|
51
|
+
// resolve relative links
|
|
52
|
+
value = new URL(value, window.location).href;
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// something went wrong
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const sourceselector = (element) => {
|
|
62
|
+
try {
|
|
63
|
+
if (element === document.body || element === document.documentElement || !element) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (element.getAttribute('data-rum-source')) {
|
|
67
|
+
return element.getAttribute('data-rum-source');
|
|
68
|
+
}
|
|
69
|
+
const form = element.closest('form');
|
|
70
|
+
let formElementSelector = '';
|
|
71
|
+
if (form && Array.from(form.elements).includes(element)) {
|
|
72
|
+
formElementSelector = element.tagName === 'INPUT' ? `form input[type='${element.getAttribute('type')}']` : `form ${element.tagName.toLowerCase()}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const blockName = element.closest('.block') ? element.closest('.block').getAttribute('data-block-name') : '';
|
|
76
|
+
if (element.id || formElementSelector) {
|
|
77
|
+
const id = element.id ? `#${element.id}` : '';
|
|
78
|
+
return blockName ? `.${blockName} ${formElementSelector}${id}` : `${formElementSelector}${id}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (element.getAttribute('data-block-name')) {
|
|
82
|
+
return `.${element.getAttribute('data-block-name')}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (Array.from(element.classList).some((className) => className.match(/button|cta/))) {
|
|
86
|
+
return blockName ? `.${blockName} .button` : '.button';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return sourceselector(element.parentElement);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const formSubmitListener = (e) => sampleRUM('formsubmit', { target: targetselector(e.target), source: sourceselector(e.target) });
|
|
96
|
+
// eslint-disable-next-line no-use-before-define
|
|
97
|
+
const mutationObserver = window.MutationObserver ? new MutationObserver(mutationsCallback) : null;
|
|
98
|
+
// Gets configured collection from the config service for the current domain
|
|
99
|
+
function getCollectionConfig() {
|
|
100
|
+
// eslint-disable-next-line max-len
|
|
101
|
+
fflags.enabled('onetrust', () => DEFAULT_TRACKING_EVENTS.push('consent'));
|
|
102
|
+
fflags.enabled('ads', () => DEFAULT_TRACKING_EVENTS.push('paid'));
|
|
103
|
+
fflags.enabled('email', () => DEFAULT_TRACKING_EVENTS.push('email'));
|
|
104
|
+
return DEFAULT_TRACKING_EVENTS;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function trackCheckpoint(checkpoint, data, t) {
|
|
108
|
+
const { weight, id } = window.hlx.rum;
|
|
109
|
+
if (isSelected) {
|
|
110
|
+
const sendPing = (pdata = data) => {
|
|
111
|
+
// eslint-disable-next-line object-curly-newline, max-len
|
|
112
|
+
const body = JSON.stringify({ weight, id, referer: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'](), checkpoint, t, ...data }, KNOWN_PROPERTIES);
|
|
113
|
+
const { href: url, origin } = new URL(`.rum/${weight}`, sampleRUM.collectBaseURL || sampleRUM.baseURL);
|
|
114
|
+
if (window.location.origin === origin) {
|
|
115
|
+
const headers = { type: 'application/json' };
|
|
116
|
+
navigator.sendBeacon(url, new Blob([body], headers));
|
|
117
|
+
} else {
|
|
118
|
+
navigator.sendBeacon(url, body);
|
|
119
|
+
}
|
|
120
|
+
// eslint-disable-next-line no-console
|
|
121
|
+
console.debug(`ping:${checkpoint}`, pdata);
|
|
122
|
+
};
|
|
123
|
+
sendPing(data);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function processQueue() {
|
|
128
|
+
while (queue.length) {
|
|
129
|
+
const ck = queue.shift();
|
|
130
|
+
trackCheckpoint(...ck);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function addCWVTracking() {
|
|
135
|
+
setTimeout(() => {
|
|
136
|
+
try {
|
|
137
|
+
const cwvScript = new URL('.rum/web-vitals/dist/web-vitals.iife.js', sampleRUM.baseURL).href;
|
|
138
|
+
if (document.querySelector(`script[src="${cwvScript}"]`)) {
|
|
139
|
+
// web vitals script has been loaded already
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const script = document.createElement('script');
|
|
143
|
+
script.src = cwvScript;
|
|
144
|
+
script.onload = () => {
|
|
145
|
+
const storeCWV = (measurement) => {
|
|
146
|
+
const data = { cwv: {} };
|
|
147
|
+
data.cwv[measurement.name] = measurement.value;
|
|
148
|
+
if (measurement.name === 'LCP' && measurement.entries.length > 0) {
|
|
149
|
+
const { element } = measurement.entries.pop();
|
|
150
|
+
data.target = targetselector(element);
|
|
151
|
+
data.source = sourceselector(element) || (element && element.outerHTML.slice(0, 30));
|
|
152
|
+
}
|
|
153
|
+
sampleRUM('cwv', data);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const featureToggle = () => window.location.hostname === 'blog.adobe.com';
|
|
157
|
+
const isEager = (metric) => ['CLS', 'LCP'].includes(metric);
|
|
158
|
+
|
|
159
|
+
// When loading `web-vitals` using a classic script, all the public
|
|
160
|
+
// methods can be found on the `webVitals` global namespace.
|
|
161
|
+
['FID', 'INP', 'TTFB', 'CLS', 'LCP'].forEach((metric) => {
|
|
162
|
+
const metricFn = window.webVitals[`on${metric}`];
|
|
163
|
+
if (typeof metricFn === 'function') {
|
|
164
|
+
const opts = isEager(metric) ? { reportAllChanges: featureToggle() } : undefined;
|
|
165
|
+
metricFn(storeCWV, opts);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
document.head.appendChild(script);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
// something went wrong
|
|
172
|
+
}
|
|
173
|
+
}, 2000); // wait for delayed
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function addEnterLeaveTracking() {
|
|
177
|
+
// enter checkpoint when referrer is not the current page url
|
|
178
|
+
const navigate = (source, type) => {
|
|
179
|
+
const payload = { source, target: document.visibilityState };
|
|
180
|
+
// reload: same page, navigate: same origin, enter: everything else
|
|
181
|
+
if (type === 'reload' || source === window.location.href) {
|
|
182
|
+
sampleRUM('reload', payload);
|
|
183
|
+
} else if (type && type !== 'navigate') {
|
|
184
|
+
sampleRUM(type, payload); // back, forward, prerender, etc.
|
|
185
|
+
} else if (source && window.location.origin === new URL(source).origin) {
|
|
186
|
+
sampleRUM('navigate', payload); // internal navigation
|
|
187
|
+
} else {
|
|
188
|
+
sampleRUM('enter', payload); // enter site
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
new PerformanceObserver((list) => list
|
|
193
|
+
.getEntries().map((entry) => navigate(document.referrer, entry.type)))
|
|
194
|
+
.observe({ type: 'navigation', buffered: true });
|
|
195
|
+
|
|
196
|
+
const leave = ((event) => {
|
|
197
|
+
try {
|
|
198
|
+
if (leave.left || (event.type === 'visibilitychange' && document.visibilityState !== 'hidden')) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
leave.left = true;
|
|
202
|
+
sampleRUM('leave');
|
|
203
|
+
} catch (error) {
|
|
204
|
+
// something went wrong
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
window.addEventListener('visibilitychange', ((event) => leave(event)));
|
|
208
|
+
window.addEventListener('pagehide', ((event) => leave(event)));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function addLoadResourceTracking() {
|
|
212
|
+
const observer = new PerformanceObserver((list) => {
|
|
213
|
+
try {
|
|
214
|
+
list.getEntries()
|
|
215
|
+
.filter((entry) => !entry.responseStatus || entry.responseStatus < 400)
|
|
216
|
+
.filter((entry) => window.location.hostname === new URL(entry.name).hostname)
|
|
217
|
+
.filter((entry) => new URL(entry.name).pathname.match('.*(\\.plain\\.html|\\.json)$'))
|
|
218
|
+
.forEach((entry) => {
|
|
219
|
+
sampleRUM('loadresource', { source: entry.name, target: Math.round(entry.duration) });
|
|
220
|
+
});
|
|
221
|
+
list.getEntries()
|
|
222
|
+
.filter((entry) => entry.responseStatus === 404)
|
|
223
|
+
.forEach((entry) => {
|
|
224
|
+
sampleRUM('missingresource', { source: entry.name, target: entry.hostname });
|
|
225
|
+
});
|
|
226
|
+
} catch (error) {
|
|
227
|
+
// something went wrong
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
observer.observe({ type: 'resource', buffered: true });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function activateBlocksMutationObserver() {
|
|
234
|
+
if (!mutationObserver || mutationObserver.active) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
mutationObserver.active = true;
|
|
238
|
+
mutationObserver.observe(
|
|
239
|
+
document.body,
|
|
240
|
+
// eslint-disable-next-line object-curly-newline
|
|
241
|
+
{ subtree: true, attributes: true, attributeFilter: ['data-block-status'] },
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function getIntersectionObsever(checkpoint) {
|
|
246
|
+
if (!window.IntersectionObserver) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
activateBlocksMutationObserver();
|
|
250
|
+
const observer = new IntersectionObserver((entries) => {
|
|
251
|
+
try {
|
|
252
|
+
entries
|
|
253
|
+
.filter((entry) => entry.isIntersecting)
|
|
254
|
+
.forEach((entry) => {
|
|
255
|
+
observer.unobserve(entry.target); // observe only once
|
|
256
|
+
const target = targetselector(entry.target);
|
|
257
|
+
const source = sourceselector(entry.target);
|
|
258
|
+
sampleRUM(checkpoint, { target, source });
|
|
259
|
+
});
|
|
260
|
+
} catch (error) {
|
|
261
|
+
// something went wrong
|
|
262
|
+
}
|
|
263
|
+
}, { threshold: 0.25 });
|
|
264
|
+
return observer;
|
|
265
|
+
}
|
|
266
|
+
function addViewBlockTracking(element) {
|
|
267
|
+
const blockobserver = getIntersectionObsever('viewblock');
|
|
268
|
+
if (blockobserver) {
|
|
269
|
+
const blocks = element.getAttribute('data-block-status') ? [element] : element.querySelectorAll('div[data-block-status="loaded"]');
|
|
270
|
+
blocks.forEach((b) => blockobserver.observe(b));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function addViewMediaTracking(parent) {
|
|
275
|
+
const mediaobserver = getIntersectionObsever('viewmedia');
|
|
276
|
+
if (mediaobserver) {
|
|
277
|
+
parent.querySelectorAll('picture > img, video, audio, iframe').forEach((m) => {
|
|
278
|
+
if (!m.closest('div .block') || m.closest('div[data-block-status="loaded"]')) {
|
|
279
|
+
mediaobserver.observe(m);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function addUTMParametersTracking() {
|
|
286
|
+
const usp = new URLSearchParams(window.location.search);
|
|
287
|
+
[...usp.entries()]
|
|
288
|
+
.filter(([key]) => key.startsWith('utm_'))
|
|
289
|
+
// exclude keys that may leak PII
|
|
290
|
+
.filter(([key]) => key !== 'utm_id')
|
|
291
|
+
.filter(([key]) => key !== 'utm_term')
|
|
292
|
+
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function addAdsParametersTracking() {
|
|
296
|
+
const networks = {
|
|
297
|
+
google: /gclid|gclsrc|wbraid|gbraid/,
|
|
298
|
+
doubleclick: /dclid/,
|
|
299
|
+
microsoft: /msclkid/,
|
|
300
|
+
facebook: /fb(cl|ad_|pxl_)id/,
|
|
301
|
+
twitter: /tw(clid|src|term)/,
|
|
302
|
+
linkedin: /li_fat_id/,
|
|
303
|
+
pinterest: /epik/,
|
|
304
|
+
tiktok: /ttclid/,
|
|
305
|
+
};
|
|
306
|
+
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
307
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
308
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function addEmailParameterTracking() {
|
|
313
|
+
const networks = {
|
|
314
|
+
mailchimp: /mc_(c|e)id/,
|
|
315
|
+
marketo: /mkt_tok/,
|
|
316
|
+
|
|
317
|
+
};
|
|
318
|
+
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
319
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
320
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function addFormTracking(parent) {
|
|
325
|
+
activateBlocksMutationObserver();
|
|
326
|
+
parent.querySelectorAll('form').forEach((form) => {
|
|
327
|
+
form.removeEventListener('submit', formSubmitListener); // listen only once
|
|
328
|
+
form.addEventListener('submit', formSubmitListener);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function addCookieConsentTracking() {
|
|
333
|
+
const cmpCookie = document.cookie.split(';')
|
|
334
|
+
.map((c) => c.trim())
|
|
335
|
+
.find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));
|
|
336
|
+
|
|
337
|
+
if (cmpCookie) {
|
|
338
|
+
sampleRUM('consent', { source: 'onetrust', target: 'hidden' });
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
let consentMutationObserver;
|
|
343
|
+
const trackShowConsent = () => {
|
|
344
|
+
if (document.querySelector('body > div#onetrust-consent-sdk')) {
|
|
345
|
+
sampleRUM('consent', { source: 'onetrust', target: 'show' });
|
|
346
|
+
if (consentMutationObserver) {
|
|
347
|
+
consentMutationObserver.disconnect();
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
if (!trackShowConsent()) {
|
|
355
|
+
// eslint-disable-next-line max-len
|
|
356
|
+
consentMutationObserver = window.MutationObserver ? new MutationObserver(trackShowConsent) : null;
|
|
357
|
+
if (consentMutationObserver) {
|
|
358
|
+
consentMutationObserver.observe(
|
|
359
|
+
document.body,
|
|
360
|
+
// eslint-disable-next-line object-curly-newline
|
|
361
|
+
{ attributes: false, childList: true, subtree: false },
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const addObserver = (ck, fn, block) => getCollectionConfig().includes(ck) && fn(block);
|
|
368
|
+
function mutationsCallback(mutations) {
|
|
369
|
+
mutations.filter((m) => m.type === 'attributes' && m.attributeName === 'data-block-status')
|
|
370
|
+
.filter((m) => m.target.dataset.blockStatus === 'loaded')
|
|
371
|
+
.forEach((m) => {
|
|
372
|
+
addObserver('form', addFormTracking, m.target);
|
|
373
|
+
addObserver('viewblock', addViewBlockTracking, m.target);
|
|
374
|
+
addObserver('viewmedia', addViewMediaTracking, m.target);
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function addTrackingFromConfig() {
|
|
379
|
+
const trackingFunctions = {
|
|
380
|
+
click: () => {
|
|
381
|
+
document.addEventListener('click', (event) => {
|
|
382
|
+
sampleRUM('click', { target: targetselector(event.target), source: sourceselector(event.target) });
|
|
383
|
+
});
|
|
384
|
+
},
|
|
385
|
+
cwv: () => addCWVTracking(),
|
|
386
|
+
form: () => addFormTracking(window.document.body),
|
|
387
|
+
enterleave: () => addEnterLeaveTracking(),
|
|
388
|
+
loadresource: () => addLoadResourceTracking(),
|
|
389
|
+
utm: () => addUTMParametersTracking(),
|
|
390
|
+
viewblock: () => addViewBlockTracking(window.document.body),
|
|
391
|
+
viewmedia: () => addViewMediaTracking(window.document.body),
|
|
392
|
+
consent: () => addCookieConsentTracking(),
|
|
393
|
+
paid: () => addAdsParametersTracking(),
|
|
394
|
+
email: () => addEmailParameterTracking(),
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
getCollectionConfig().filter((ck) => trackingFunctions[ck])
|
|
398
|
+
.forEach((ck) => trackingFunctions[ck]());
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function initEnhancer() {
|
|
402
|
+
try {
|
|
403
|
+
if (sampleRUM) {
|
|
404
|
+
addTrackingFromConfig();
|
|
405
|
+
window.hlx.rum.collector = trackCheckpoint;
|
|
406
|
+
processQueue();
|
|
407
|
+
}
|
|
408
|
+
} catch (error) {
|
|
409
|
+
// something went wrong
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// eslint-disable-next-line padded-blocks
|
|
414
|
+
initEnhancer();
|
|
415
|
+
|
|
416
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-rum-enhancer",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Helix RUM Enhancer",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
8
|
+
"setup-playwright": "npx playwright install --with-deps chromium firefox webkit",
|
|
9
|
+
"test": "npm run setup-playwright && web-test-runner --node-resolve --coverage --playwright --browsers chromium firefox webkit",
|
|
10
|
+
"test:ci": "npm run setup-playwright && web-test-runner --node-resolve --coverage --playwright --browsers chromium firefox webkit",
|
|
11
|
+
"test:watch": "web-test-runner --node-resolve --coverage --watch",
|
|
9
12
|
"lint": "eslint .",
|
|
10
13
|
"docs": "npx jsdoc2md -c .jsdoc.json --files 'src/*.js' > docs/API.md",
|
|
14
|
+
"build-bundle": "rollup --config",
|
|
15
|
+
"prepack": "npm run build-bundle",
|
|
11
16
|
"semantic-release": "semantic-release",
|
|
12
17
|
"semantic-release-dry": "semantic-release --dry-run --branches $CI_BRANCH 1.x main",
|
|
13
18
|
"prepare": "husky install"
|
|
@@ -30,10 +35,15 @@
|
|
|
30
35
|
},
|
|
31
36
|
"devDependencies": {
|
|
32
37
|
"@adobe/eslint-config-helix": "2.0.6",
|
|
38
|
+
"@esm-bundle/chai": "4.3.4-fix.0",
|
|
33
39
|
"@semantic-release/changelog": "6.0.3",
|
|
34
40
|
"@semantic-release/git": "10.0.1",
|
|
35
41
|
"@semantic-release/npm": "12.0.1",
|
|
36
|
-
"
|
|
42
|
+
"@web/test-runner": "0.18.2",
|
|
43
|
+
"@web/test-runner-commands": "0.9.0",
|
|
44
|
+
"@web/test-runner-mocha": "0.9.0",
|
|
45
|
+
"@web/test-runner-playwright": "0.11.0",
|
|
46
|
+
"c8": "10.0.0",
|
|
37
47
|
"codecov": "3.8.3",
|
|
38
48
|
"eslint": "8.57.0",
|
|
39
49
|
"eslint-plugin-header": "3.1.1",
|
|
@@ -44,6 +54,8 @@
|
|
|
44
54
|
"lint-staged": "15.2.5",
|
|
45
55
|
"mocha": "10.4.0",
|
|
46
56
|
"mocha-multi-reporters": "1.5.1",
|
|
57
|
+
"rollup": "4.18.0",
|
|
58
|
+
"rollup-plugin-cleanup": "3.2.1",
|
|
47
59
|
"semantic-release": "24.0.0"
|
|
48
60
|
},
|
|
49
61
|
"lint-staged": {
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
|
|
13
|
+
import cleanup from 'rollup-plugin-cleanup';
|
|
14
|
+
|
|
15
|
+
const banner = `/*
|
|
16
|
+
* Copyright 2024 Adobe. All rights reserved.
|
|
17
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
18
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
19
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
20
|
+
*
|
|
21
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
22
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
23
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
24
|
+
* governing permissions and limitations under the License.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/* eslint-disable max-classes-per-file, wrap-iife */
|
|
28
|
+
// eslint-disable-next-line func-names`;
|
|
29
|
+
|
|
30
|
+
const bundles = [
|
|
31
|
+
{
|
|
32
|
+
source: 'src/index.js',
|
|
33
|
+
outputFile: 'dist/rum-enhancer',
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export default [...bundles.map(({ outputFile, source }) => ({
|
|
38
|
+
input: source,
|
|
39
|
+
output: [
|
|
40
|
+
{
|
|
41
|
+
file: `${outputFile}.js`,
|
|
42
|
+
format: 'iife',
|
|
43
|
+
sourcemap: false,
|
|
44
|
+
exports: 'auto',
|
|
45
|
+
banner,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
plugins: [
|
|
49
|
+
cleanup({
|
|
50
|
+
comments: ['eslint', 'jsdoc', /^\//, /^\*(?!\sc8\s)(?!\n \* Copyright)/],
|
|
51
|
+
maxEmptyLines: -1,
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
}))];
|
package/src/index.js
CHANGED
|
@@ -21,8 +21,8 @@ const fflags = {
|
|
|
21
21
|
enabled: (flag, callback) => fflags.has(flag) && callback(),
|
|
22
22
|
disabled: (flag, callback) => !fflags.has(flag) && callback(),
|
|
23
23
|
onetrust: [543, 770, 1136],
|
|
24
|
-
ads: [1139, 543],
|
|
25
|
-
email: [1139, 543],
|
|
24
|
+
ads: [1139, 543, 770, 984],
|
|
25
|
+
email: [1139, 543, 770, 984],
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
const urlSanitizers = {
|
|
@@ -410,4 +410,5 @@ function initEnhancer() {
|
|
|
410
410
|
}
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
+
// eslint-disable-next-line padded-blocks
|
|
413
414
|
initEnhancer();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 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 default {
|
|
13
|
+
coverageConfig: {
|
|
14
|
+
report: true,
|
|
15
|
+
reportDir: 'coverage',
|
|
16
|
+
exclude: [
|
|
17
|
+
'test/fixtures/**',
|
|
18
|
+
'node_modules/**',
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
files: [
|
|
22
|
+
'test/**/*.test.{html,js}',
|
|
23
|
+
'test/*.test.{html,js}',
|
|
24
|
+
],
|
|
25
|
+
};
|