@adobe/helix-rum-enhancer 2.31.0-beta.2 → 2.31.0-beta.4
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 +25 -0
- package/modules/index.js +66 -92
- package/package.json +2 -2
- package/plugins/cwv.js +61 -0
- package/plugins/form.js +32 -0
- package/plugins/martech.js +54 -0
- package/{modules/martech.js → plugins/onetrust.js} +1 -37
- package/plugins/video.js +17 -0
- package/rollup.config.js +11 -4
- package/src/index.js +168 -222
- package/src/index.md5 +1 -1
- package/src/plugins/cwv.js +411 -0
- package/src/plugins/cwv.map.js +412 -0
- package/src/plugins/cwv.md5 +1 -0
- package/src/plugins/form.js +50 -0
- package/src/plugins/form.map.js +51 -0
- package/src/plugins/form.md5 +1 -0
- package/src/plugins/martech.js +76 -0
- package/src/plugins/martech.map.js +77 -0
- package/src/plugins/martech.md5 +1 -0
- package/src/plugins/onetrust.js +62 -0
- package/src/plugins/onetrust.map.js +63 -0
- package/src/plugins/onetrust.md5 +1 -0
- package/src/plugins/video.js +23 -0
- package/src/plugins/video.map.js +24 -0
- package/src/plugins/video.md5 +1 -0
- package/web-test-runner.config.js +10 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
# [2.31.0-beta.4](https://github.com/adobe/helix-rum-enhancer/compare/v2.31.0-beta.3...v2.31.0-beta.4) (2025-01-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* plugin path resolution ([f464652](https://github.com/adobe/helix-rum-enhancer/commit/f464652df5bef5f42e0b32c1f10bebef013dd1b0))
|
|
7
|
+
|
|
8
|
+
# [2.31.0-beta.3](https://github.com/adobe/helix-rum-enhancer/compare/v2.31.0-beta.2...v2.31.0-beta.3) (2025-01-16)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* bugs and failing tests ([5c9adbc](https://github.com/adobe/helix-rum-enhancer/commit/5c9adbc2502203495a05d4fd2be6e05cc11102df))
|
|
14
|
+
* cross-browser compatibility ([1c21afd](https://github.com/adobe/helix-rum-enhancer/commit/1c21afd8cd982d4c33feba863d2251311f36e153))
|
|
15
|
+
* set proper url base for plugins ([9726dc8](https://github.com/adobe/helix-rum-enhancer/commit/9726dc8f98bd71936c8a8f430cae73b6a8f5d63f))
|
|
16
|
+
* use proper fully qualified URLs for plugin path to avoid CORS ([c73eb31](https://github.com/adobe/helix-rum-enhancer/commit/c73eb31461115529922b82c3a8b678f21052b918))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* allow external extension via window.RUM_PLUGINS ([4613b00](https://github.com/adobe/helix-rum-enhancer/commit/4613b004c617f4d503355b5c43008149df9101ef))
|
|
22
|
+
* inline web-vitals.js ([7d89e9f](https://github.com/adobe/helix-rum-enhancer/commit/7d89e9f664686d3a475ce829d7fb4f68f29ed71b))
|
|
23
|
+
* introduce minimal plugin system to offset non-essenial logic ([8642557](https://github.com/adobe/helix-rum-enhancer/commit/8642557beaef5161d1d4d51d2b04ce06bf7dbeb7))
|
|
24
|
+
* introduce minimal plugin system to offset non-essenial logic ([6066f0b](https://github.com/adobe/helix-rum-enhancer/commit/6066f0bd56393a10391e190b9a338f9a65b772b0))
|
|
25
|
+
|
|
1
26
|
# [2.31.0-beta.2](https://github.com/adobe/helix-rum-enhancer/compare/v2.31.0-beta.1...v2.31.0-beta.2) (2025-01-16)
|
|
2
27
|
|
|
3
28
|
|
package/modules/index.js
CHANGED
|
@@ -14,26 +14,66 @@
|
|
|
14
14
|
import { KNOWN_PROPERTIES, DEFAULT_TRACKING_EVENTS } from './defaults.js';
|
|
15
15
|
import { urlSanitizers } from './utils.js';
|
|
16
16
|
import { targetSelector, sourceSelector } from './dom.js';
|
|
17
|
-
import {
|
|
18
|
-
addAdsParametersTracking,
|
|
19
|
-
addCookieConsentTracking,
|
|
20
|
-
addEmailParameterTracking,
|
|
21
|
-
addUTMParametersTracking,
|
|
22
|
-
} from './martech.js';
|
|
23
17
|
import { fflags } from './fflags.js';
|
|
24
18
|
|
|
25
19
|
const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum
|
|
26
20
|
/* c8 ignore next */ : {};
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const blocksMO = window.MutationObserver ? new MutationObserver(blocksMCB)
|
|
31
|
-
/* c8 ignore next */ : {};
|
|
22
|
+
const createMO = (cb) => (window.MutationObserver ? new MutationObserver(cb)
|
|
23
|
+
/* c8 ignore next */ : {});
|
|
32
24
|
|
|
33
|
-
// media mutation observer
|
|
34
|
-
// eslint-disable-next-line no-use-before-define
|
|
35
|
-
const mediaMO =
|
|
36
|
-
|
|
25
|
+
// blocks & media mutation observer
|
|
26
|
+
// eslint-disable-next-line no-use-before-define
|
|
27
|
+
const [blocksMO, mediaMO] = [blocksMCB, mediaMCB].map(createMO);
|
|
28
|
+
|
|
29
|
+
// Check for the presence of a given cookie
|
|
30
|
+
const hasCookieKey = (key) => () => document.cookie.split(';').some((c) => c.trim().startsWith(`${key}=`));
|
|
31
|
+
|
|
32
|
+
const pluginBasePath = new URL(document.currentScript.src).href.replace(/index(\.map)?\.js/, 'plugins');
|
|
33
|
+
|
|
34
|
+
const PLUGINS = {
|
|
35
|
+
cwv: `${pluginBasePath}/cwv.js`,
|
|
36
|
+
// Interactive elements
|
|
37
|
+
form: { url: `${pluginBasePath}/form.js`, condition: () => document.querySelector('form'), isBlockDependent: true },
|
|
38
|
+
video: { url: `${pluginBasePath}/video.js`, condition: () => document.querySelector('video'), isBlockDependent: true },
|
|
39
|
+
// Martech
|
|
40
|
+
martech: { url: `${pluginBasePath}/martech.js`, condition: ({ urlParameters }) => urlParameters.size > 0 },
|
|
41
|
+
onetrust: { url: `${pluginBasePath}/onetrust.js`, condition: () => (document.querySelector('#onetrust-consent-sdk') || hasCookieKey('OptanonAlertBoxClosed')), isBlockDependent: true },
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const PLUGIN_PARAMETERS = {
|
|
45
|
+
context: document.body,
|
|
46
|
+
fflags,
|
|
47
|
+
sampleRUM,
|
|
48
|
+
sourceSelector,
|
|
49
|
+
targetSelector,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const pluginCache = new Map();
|
|
53
|
+
|
|
54
|
+
function loadPlugin(key, params) {
|
|
55
|
+
const plugin = PLUGINS[key];
|
|
56
|
+
const usp = new URLSearchParams(window.location.search);
|
|
57
|
+
if (!pluginCache.has(key) && plugin.condition && !plugin.condition({ urlParameters: usp })) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (!pluginCache.has(key)) {
|
|
61
|
+
try {
|
|
62
|
+
pluginCache.set(key, import(`${plugin.url || plugin}`));
|
|
63
|
+
} catch (e) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const pluginLoadPromise = pluginCache.get(key);
|
|
68
|
+
return pluginLoadPromise
|
|
69
|
+
.then((p) => (p.default && p.default(params)) || (typeof p === 'function' && p(params)));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function loadPlugins(filter = () => true, params = PLUGIN_PARAMETERS) {
|
|
73
|
+
Object.entries(PLUGINS)
|
|
74
|
+
.filter(([, plugin]) => filter(plugin))
|
|
75
|
+
.map(([key]) => loadPlugin(key, params));
|
|
76
|
+
}
|
|
37
77
|
|
|
38
78
|
function trackCheckpoint(checkpoint, data, t) {
|
|
39
79
|
const { weight, id } = window.hlx.rum;
|
|
@@ -64,51 +104,6 @@ function processQueue() {
|
|
|
64
104
|
}
|
|
65
105
|
}
|
|
66
106
|
|
|
67
|
-
function addCWVTracking() {
|
|
68
|
-
setTimeout(() => {
|
|
69
|
-
try {
|
|
70
|
-
const cwvScript = new URL('.rum/web-vitals/dist/web-vitals.iife.js', sampleRUM.baseURL).href;
|
|
71
|
-
if (document.querySelector(`script[src="${cwvScript}"]`)) {
|
|
72
|
-
// web vitals script has been loaded already
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
const script = document.createElement('script');
|
|
76
|
-
script.src = cwvScript;
|
|
77
|
-
script.onload = () => {
|
|
78
|
-
const storeCWV = (measurement) => {
|
|
79
|
-
const data = { cwv: {} };
|
|
80
|
-
data.cwv[measurement.name] = measurement.value;
|
|
81
|
-
if (measurement.name === 'LCP' && measurement.entries.length > 0) {
|
|
82
|
-
const { element } = measurement.entries.pop();
|
|
83
|
-
data.target = targetSelector(element);
|
|
84
|
-
data.source = sourceSelector(element) || (element && element.outerHTML.slice(0, 30));
|
|
85
|
-
}
|
|
86
|
-
sampleRUM('cwv', data);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const isEager = (metric) => ['CLS', 'LCP'].includes(metric);
|
|
90
|
-
|
|
91
|
-
// When loading `web-vitals` using a classic script, all the public
|
|
92
|
-
// methods can be found on the `webVitals` global namespace.
|
|
93
|
-
['INP', 'TTFB', 'CLS', 'LCP'].forEach((metric) => {
|
|
94
|
-
const metricFn = window.webVitals[`on${metric}`];
|
|
95
|
-
if (typeof metricFn === 'function') {
|
|
96
|
-
let opts = {};
|
|
97
|
-
fflags.enabled('eagercwv', () => {
|
|
98
|
-
opts = { reportAllChanges: isEager(metric) };
|
|
99
|
-
});
|
|
100
|
-
metricFn(storeCWV, opts);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
};
|
|
104
|
-
document.head.appendChild(script);
|
|
105
|
-
/* c8 ignore next 3 */
|
|
106
|
-
} catch (error) {
|
|
107
|
-
// something went wrong
|
|
108
|
-
}
|
|
109
|
-
}, 2000); // wait for delayed
|
|
110
|
-
}
|
|
111
|
-
|
|
112
107
|
function addNavigationTracking() {
|
|
113
108
|
// enter checkpoint when referrer is not the current page url
|
|
114
109
|
const navigate = (source, type, redirectCount) => {
|
|
@@ -210,8 +205,6 @@ function getIntersectionObsever(checkpoint) {
|
|
|
210
205
|
if (!window.IntersectionObserver) {
|
|
211
206
|
return null;
|
|
212
207
|
}
|
|
213
|
-
activateBlocksMO();
|
|
214
|
-
activateMediaMO();
|
|
215
208
|
const observer = new IntersectionObserver((entries) => {
|
|
216
209
|
try {
|
|
217
210
|
entries
|
|
@@ -250,28 +243,6 @@ function addViewMediaTracking(parent) {
|
|
|
250
243
|
}
|
|
251
244
|
}
|
|
252
245
|
|
|
253
|
-
function addFormTracking(parent) {
|
|
254
|
-
activateBlocksMO();
|
|
255
|
-
activateMediaMO();
|
|
256
|
-
parent.querySelectorAll('form').forEach((form) => {
|
|
257
|
-
form.addEventListener('submit', (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) }), { once: true });
|
|
258
|
-
let lastSource;
|
|
259
|
-
form.addEventListener('change', (e) => {
|
|
260
|
-
const source = sourceSelector(e.target);
|
|
261
|
-
if (source !== lastSource) {
|
|
262
|
-
sampleRUM('fill', { source });
|
|
263
|
-
lastSource = source;
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
form.addEventListener('focusin', (e) => {
|
|
267
|
-
if (['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'].includes(e.target.tagName)
|
|
268
|
-
|| e.target.getAttribute('contenteditable') === 'true') {
|
|
269
|
-
sampleRUM('click', { source: sourceSelector(e.target) });
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
|
|
275
246
|
function addObserver(ck, fn, block) {
|
|
276
247
|
return DEFAULT_TRACKING_EVENTS.includes(ck) && fn(block);
|
|
277
248
|
}
|
|
@@ -283,7 +254,7 @@ function blocksMCB(mutations) {
|
|
|
283
254
|
.filter((m) => m.type === 'attributes' && m.attributeName === 'data-block-status')
|
|
284
255
|
.filter((m) => m.target.dataset.blockStatus === 'loaded')
|
|
285
256
|
.forEach((m) => {
|
|
286
|
-
addObserver('form',
|
|
257
|
+
addObserver('form', (el) => loadPlugins((p) => p.isBlockDependent, { ...PLUGIN_PARAMETERS, context: el }), m.target);
|
|
287
258
|
addObserver('viewblock', addViewBlockTracking, m.target);
|
|
288
259
|
});
|
|
289
260
|
}
|
|
@@ -298,6 +269,9 @@ function mediaMCB(mutations) {
|
|
|
298
269
|
}
|
|
299
270
|
|
|
300
271
|
function addTrackingFromConfig() {
|
|
272
|
+
activateBlocksMO();
|
|
273
|
+
activateMediaMO();
|
|
274
|
+
|
|
301
275
|
let lastSource;
|
|
302
276
|
let lastTarget;
|
|
303
277
|
document.addEventListener('click', (event) => {
|
|
@@ -309,16 +283,16 @@ function addTrackingFromConfig() {
|
|
|
309
283
|
lastTarget = target;
|
|
310
284
|
}
|
|
311
285
|
});
|
|
312
|
-
|
|
313
|
-
|
|
286
|
+
|
|
287
|
+
// Core tracking
|
|
314
288
|
addNavigationTracking();
|
|
315
289
|
addLoadResourceTracking();
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
290
|
+
addViewBlockTracking(document.body);
|
|
291
|
+
addViewMediaTracking(document.body);
|
|
292
|
+
|
|
293
|
+
// Tracking extensions
|
|
294
|
+
loadPlugins();
|
|
295
|
+
|
|
322
296
|
fflags.enabled('language', () => {
|
|
323
297
|
const target = navigator.language;
|
|
324
298
|
const source = document.documentElement.lang;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-rum-enhancer",
|
|
3
|
-
"version": "2.31.0-beta.
|
|
3
|
+
"version": "2.31.0-beta.4",
|
|
4
4
|
"description": "Helix RUM Enhancer",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"@adobe/eslint-config-helix": "2.0.8",
|
|
37
37
|
"@adobe/helix-rum-js": "2.10.0",
|
|
38
38
|
"@esm-bundle/chai": "4.3.4-fix.0",
|
|
39
|
+
"@rollup/plugin-babel": "6.0.4",
|
|
39
40
|
"@semantic-release/changelog": "6.0.3",
|
|
40
41
|
"@semantic-release/git": "10.0.1",
|
|
41
42
|
"@semantic-release/npm": "12.0.1",
|
|
@@ -57,7 +58,6 @@
|
|
|
57
58
|
"mocha-multi-reporters": "1.5.1",
|
|
58
59
|
"rollup": "4.30.1",
|
|
59
60
|
"rollup-plugin-checksum": "1.0.1",
|
|
60
|
-
"rollup-plugin-cleanup": "3.2.1",
|
|
61
61
|
"rollup-plugin-eslint-bundle": "9.0.0",
|
|
62
62
|
"semantic-release": "24.2.1",
|
|
63
63
|
"semantic-release-slack-bot": "^4.0.2",
|
package/plugins/cwv.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
// eslint-disable-next-line max-len
|
|
13
|
+
// eslint-disable-next-line import/no-extraneous-dependencies, import/no-relative-packages, no-unused-vars
|
|
14
|
+
import * as webVitals from '../node_modules/web-vitals/dist/web-vitals.iife.js';
|
|
15
|
+
|
|
16
|
+
export default function addCWVTracking({
|
|
17
|
+
sampleRUM, sourceSelector, targetSelector, fflags,
|
|
18
|
+
}) {
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
try {
|
|
21
|
+
const cwvScript = new URL('.rum/web-vitals/dist/web-vitals.iife.js', sampleRUM.baseURL).href;
|
|
22
|
+
if (document.querySelector(`script[src="${cwvScript}"]`)) {
|
|
23
|
+
// web vitals script has been loaded already
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const script = document.createElement('script');
|
|
27
|
+
script.src = cwvScript;
|
|
28
|
+
script.onload = () => {
|
|
29
|
+
const storeCWV = (measurement) => {
|
|
30
|
+
const data = { cwv: {} };
|
|
31
|
+
data.cwv[measurement.name] = measurement.value;
|
|
32
|
+
if (measurement.name === 'LCP' && measurement.entries.length > 0) {
|
|
33
|
+
const { element } = measurement.entries.pop();
|
|
34
|
+
data.target = targetSelector(element);
|
|
35
|
+
data.source = sourceSelector(element) || (element && element.outerHTML.slice(0, 30));
|
|
36
|
+
}
|
|
37
|
+
sampleRUM('cwv', data);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const isEager = (metric) => ['CLS', 'LCP'].includes(metric);
|
|
41
|
+
|
|
42
|
+
// When loading `web-vitals` using a classic script, all the public
|
|
43
|
+
// methods can be found on the `webVitals` global namespace.
|
|
44
|
+
['INP', 'TTFB', 'CLS', 'LCP'].forEach((metric) => {
|
|
45
|
+
const metricFn = window.webVitals[`on${metric}`];
|
|
46
|
+
if (typeof metricFn === 'function') {
|
|
47
|
+
let opts = {};
|
|
48
|
+
fflags.enabled('eagercwv', () => {
|
|
49
|
+
opts = { reportAllChanges: isEager(metric) };
|
|
50
|
+
});
|
|
51
|
+
metricFn(storeCWV, opts);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
document.head.appendChild(script);
|
|
56
|
+
/* c8 ignore next 3 */
|
|
57
|
+
} catch (error) {
|
|
58
|
+
// something went wrong
|
|
59
|
+
}
|
|
60
|
+
}, 2000); // wait for delayed
|
|
61
|
+
}
|
package/plugins/form.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
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 default function addFormTracking({
|
|
13
|
+
sampleRUM, sourceSelector, targetSelector, context,
|
|
14
|
+
}) {
|
|
15
|
+
context.querySelectorAll('form').forEach((form) => {
|
|
16
|
+
form.addEventListener('submit', (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) }), { once: true });
|
|
17
|
+
let lastSource;
|
|
18
|
+
form.addEventListener('change', (e) => {
|
|
19
|
+
const source = sourceSelector(e.target);
|
|
20
|
+
if (source !== lastSource) {
|
|
21
|
+
sampleRUM('fill', { source });
|
|
22
|
+
lastSource = source;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
form.addEventListener('focusin', (e) => {
|
|
26
|
+
if (['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'].includes(e.target.tagName)
|
|
27
|
+
|| e.target.getAttribute('contenteditable') === 'true') {
|
|
28
|
+
sampleRUM('click', { source: sourceSelector(e.target) });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -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
|
+
function addAdsParametersTracking(usp, { sampleRUM }) {
|
|
13
|
+
const networks = {
|
|
14
|
+
google: /gclid|gclsrc|wbraid|gbraid/,
|
|
15
|
+
doubleclick: /dclid/,
|
|
16
|
+
microsoft: /msclkid/,
|
|
17
|
+
facebook: /fb(cl|ad_|pxl_)id/,
|
|
18
|
+
twitter: /tw(clid|src|term)/,
|
|
19
|
+
linkedin: /li_fat_id/,
|
|
20
|
+
pinterest: /epik/,
|
|
21
|
+
tiktok: /ttclid/,
|
|
22
|
+
};
|
|
23
|
+
const params = Array.from(usp.keys());
|
|
24
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
25
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function addEmailParameterTracking(usp, { sampleRUM }) {
|
|
30
|
+
const networks = {
|
|
31
|
+
mailchimp: /mc_(c|e)id/,
|
|
32
|
+
marketo: /mkt_tok/,
|
|
33
|
+
};
|
|
34
|
+
const params = Array.from(usp.keys());
|
|
35
|
+
Object.entries(networks).forEach(([network, regex]) => {
|
|
36
|
+
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function addUTMParametersTracking(usp, { sampleRUM }) {
|
|
41
|
+
Array.from(usp.entries())
|
|
42
|
+
.filter(([key]) => key.startsWith('utm_'))
|
|
43
|
+
// exclude keys that may leak PII
|
|
44
|
+
.filter(([key]) => key !== 'utm_id')
|
|
45
|
+
.filter(([key]) => key !== 'utm_term')
|
|
46
|
+
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default function addMartechTraking({ sampleRUM }) {
|
|
50
|
+
const usp = new URLSearchParams(window.location.search);
|
|
51
|
+
addAdsParametersTracking(usp, { sampleRUM });
|
|
52
|
+
addEmailParameterTracking(usp, { sampleRUM });
|
|
53
|
+
addUTMParametersTracking(usp, { sampleRUM });
|
|
54
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
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
|
-
export function addCookieConsentTracking(sampleRUM) {
|
|
12
|
+
export default function addCookieConsentTracking({ sampleRUM }) {
|
|
13
13
|
const cmpCookie = document.cookie.split(';')
|
|
14
14
|
.map((c) => c.trim())
|
|
15
15
|
.find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));
|
|
@@ -50,39 +50,3 @@ export function addCookieConsentTracking(sampleRUM) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
export function addUTMParametersTracking(sampleRUM) {
|
|
55
|
-
const usp = new URLSearchParams(window.location.search);
|
|
56
|
-
[...usp.entries()]
|
|
57
|
-
.filter(([key]) => key.startsWith('utm_'))
|
|
58
|
-
// exclude keys that may leak PII
|
|
59
|
-
.filter(([key]) => key !== 'utm_id')
|
|
60
|
-
.filter(([key]) => key !== 'utm_term')
|
|
61
|
-
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
|
|
62
|
-
}
|
|
63
|
-
export function addAdsParametersTracking(sampleRUM) {
|
|
64
|
-
const networks = {
|
|
65
|
-
google: /gclid|gclsrc|wbraid|gbraid/,
|
|
66
|
-
doubleclick: /dclid/,
|
|
67
|
-
microsoft: /msclkid/,
|
|
68
|
-
facebook: /fb(cl|ad_|pxl_)id/,
|
|
69
|
-
twitter: /tw(clid|src|term)/,
|
|
70
|
-
linkedin: /li_fat_id/,
|
|
71
|
-
pinterest: /epik/,
|
|
72
|
-
tiktok: /ttclid/,
|
|
73
|
-
};
|
|
74
|
-
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
75
|
-
Object.entries(networks).forEach(([network, regex]) => {
|
|
76
|
-
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
export function addEmailParameterTracking(sampleRUM) {
|
|
80
|
-
const networks = {
|
|
81
|
-
mailchimp: /mc_(c|e)id/,
|
|
82
|
-
marketo: /mkt_tok/,
|
|
83
|
-
};
|
|
84
|
-
const params = Array.from(new URLSearchParams(window.location.search).keys());
|
|
85
|
-
Object.entries(networks).forEach(([network, regex]) => {
|
|
86
|
-
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
|
|
87
|
-
});
|
|
88
|
-
}
|
package/plugins/video.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 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
|
+
export default function addVideoTracking({ context }) {
|
|
14
|
+
context.querySelectorAll('video').forEach(() => {
|
|
15
|
+
// TODO: Add video tracking
|
|
16
|
+
});
|
|
17
|
+
}
|
package/rollup.config.js
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
14
|
+
import { babel } from '@rollup/plugin-babel';
|
|
14
15
|
import pkg from 'rollup-plugin-checksum';
|
|
15
16
|
|
|
16
17
|
const checksum = pkg.default;
|
|
@@ -28,10 +29,16 @@ const banner = `/*
|
|
|
28
29
|
*/`;
|
|
29
30
|
|
|
30
31
|
const bundles = [
|
|
32
|
+
// Core library
|
|
31
33
|
{
|
|
32
34
|
source: 'modules/index.js',
|
|
33
35
|
outputFile: 'src/index',
|
|
34
36
|
},
|
|
37
|
+
// Library plugins
|
|
38
|
+
...['cwv', 'form', 'martech', 'onetrust', 'video'].map((plugin) => ({
|
|
39
|
+
source: `plugins/${plugin}.js`,
|
|
40
|
+
outputFile: `src/plugins/${plugin}`,
|
|
41
|
+
})),
|
|
35
42
|
];
|
|
36
43
|
|
|
37
44
|
export default [...bundles.map(({ outputFile, source }) => ({
|
|
@@ -53,9 +60,9 @@ export default [...bundles.map(({ outputFile, source }) => ({
|
|
|
53
60
|
},
|
|
54
61
|
],
|
|
55
62
|
plugins: [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
babel({
|
|
64
|
+
babelHelpers: 'bundled',
|
|
65
|
+
comments: false,
|
|
59
66
|
}),
|
|
60
67
|
checksum({
|
|
61
68
|
filename: `${outputFile.split('/').pop()}.md5`,
|