@adobe/helix-rum-enhancer 2.49.0 → 2.50.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 +19 -0
- package/modules/fflags.js +1 -1
- package/package.json +21 -21
- package/plugins/martech.js +1 -0
- package/rollup.config.js +6 -1
- package/src/index.js +417 -430
- package/src/index.md5 +1 -1
- package/src/index.sri +1 -1
- package/src/plugins/a11y.map.js +1 -1
- package/src/plugins/a11y.md5 +1 -1
- package/src/plugins/cwv.js +313 -205
- package/src/plugins/cwv.map.js +314 -206
- package/src/plugins/cwv.md5 +1 -1
- package/src/plugins/form.map.js +1 -1
- package/src/plugins/martech.js +2 -1
- package/src/plugins/martech.map.js +3 -2
- package/src/plugins/martech.md5 +1 -1
- package/src/plugins/onetrust.map.js +1 -1
- package/src/plugins/onetrust.md5 +1 -1
- package/src/plugins/redirect.map.js +1 -1
- package/src/plugins/redirect.md5 +1 -1
- package/src/plugins/trustarc.map.js +1 -1
- package/src/plugins/trustarc.md5 +1 -1
- package/src/plugins/usercentrics.map.js +1 -1
- package/src/plugins/usercentrics.md5 +1 -1
- package/src/plugins/video.map.js +1 -1
- package/src/plugins/video.md5 +1 -1
- package/src/plugins/webcomponent.map.js +1 -1
- package/src/plugins/webcomponent.md5 +1 -1
package/src/index.js
CHANGED
|
@@ -9,469 +9,456 @@
|
|
|
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
|
-
(function ()
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return `${u.origin}${u.pathname}`;
|
|
12
|
+
(function(){'use strict';const h = (s, a) => [...s].reduce((p, c) => p + c.charCodeAt(0), a) % 1371;
|
|
13
|
+
const fflags = {
|
|
14
|
+
has: f => fflags[f].includes(h(window.origin, 1)) || /localhost/.test(window.origin),
|
|
15
|
+
enabled: (f, c) => fflags.has(f) && c(),
|
|
16
|
+
disabled: (f, c) => !fflags.has(f) && c(),
|
|
17
|
+
eagercwv: [683],
|
|
18
|
+
example: [543, 770, 1136],
|
|
19
|
+
allresources: [543, 1139, 339],
|
|
20
|
+
a11y: [557, 781, 897, 955, 959]
|
|
21
|
+
};const KNOWN_PROPERTIES = ['weight', 'id', 'referer', 'checkpoint', 't', 'source', 'target', 'cwv', 'CLS', 'FID', 'LCP', 'INP', 'TTFB', 'ua'];
|
|
22
|
+
const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'viewblock', 'viewmedia', 'loadresource', 'utm', 'paid', 'email', 'consent'];
|
|
23
|
+
fflags.enabled('example', () => DEFAULT_TRACKING_EVENTS.push('example'));const {
|
|
24
|
+
href
|
|
25
|
+
} = window.location;
|
|
26
|
+
const urlSanitizers = {
|
|
27
|
+
full: (url = href) => new URL(url).toString(),
|
|
28
|
+
origin: (url = href) => new URL(url).origin,
|
|
29
|
+
path: (url = href) => {
|
|
30
|
+
const u = new URL(url);
|
|
31
|
+
return `${u.origin}${u.pathname}`;
|
|
32
|
+
}
|
|
33
|
+
};const getTargetValue = el => el.getAttribute('data-rum-target') || el.getAttribute('href') || el.currentSrc || el.getAttribute('src') || el.dataset.action || el.action;
|
|
34
|
+
const targetSelector = el => {
|
|
35
|
+
try {
|
|
36
|
+
if (!el) {
|
|
37
|
+
return undefined;
|
|
39
38
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const targetSelector = el => {
|
|
44
|
-
try {
|
|
45
|
-
if (!el) {
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
let v = getTargetValue(el);
|
|
49
|
-
if (!v && el.tagName !== 'A' && el.closest('a')) {
|
|
50
|
-
v = getTargetValue(el.closest('a'));
|
|
51
|
-
}
|
|
52
|
-
if (v && !v.startsWith('https://')) {
|
|
53
|
-
v = new URL(v, window.location).href;
|
|
54
|
-
}
|
|
55
|
-
return v;
|
|
56
|
-
} catch (error) {
|
|
57
|
-
return null;
|
|
39
|
+
let v = getTargetValue(el);
|
|
40
|
+
if (!v && el.tagName !== 'A' && el.closest('a')) {
|
|
41
|
+
v = getTargetValue(el.closest('a'));
|
|
58
42
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (event && event.isTrusted === false) {
|
|
62
|
-
const ua = navigator.userAgent;
|
|
63
|
-
return {
|
|
64
|
-
ua: ua.includes('+http') ? ua : `${ua} +http://event.untrusted`
|
|
65
|
-
};
|
|
43
|
+
if (v && !v.startsWith('https://')) {
|
|
44
|
+
v = new URL(v, window.location).href;
|
|
66
45
|
}
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
46
|
+
return v;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const untrustedClickPayload = event => {
|
|
52
|
+
if (event && event.isTrusted === false) {
|
|
53
|
+
const ua = navigator.userAgent;
|
|
54
|
+
return {
|
|
55
|
+
ua: ua.includes('+http') ? ua : `${ua} +http://event.untrusted`
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return {};
|
|
59
|
+
};
|
|
60
|
+
function walk(el, check) {
|
|
61
|
+
if (!el || el === document.body || el === document.documentElement) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
return check(el) || walk(el.parentElement || el.parentNode && el.parentNode.host, check);
|
|
65
|
+
}
|
|
66
|
+
function isDialog(el) {
|
|
67
|
+
const cs = window.getComputedStyle(el);
|
|
68
|
+
return el.tagName === 'DIALOG' || ['dialog', 'alertdialog'].find(r => el.getAttribute('role') === r) || el.getAttribute('aria-modal') === 'true' || cs && cs.position === 'fixed' && cs.zIndex > 100;
|
|
69
|
+
}
|
|
70
|
+
function isButton(el) {
|
|
71
|
+
if (el.tagName === 'BUTTON' || el.tagName === 'INPUT' && el.getAttribute('type') === 'button') {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
if (el.tagName === 'A') {
|
|
75
|
+
return Array.from(el.classList).some(cls => cls.match(/button|cta/));
|
|
76
|
+
}
|
|
77
|
+
return el.getAttribute('role') === 'button';
|
|
78
|
+
}
|
|
79
|
+
function srcContext(el) {
|
|
80
|
+
const form = el.closest('form');
|
|
81
|
+
if (form) {
|
|
82
|
+
const id = form.getAttribute('id');
|
|
83
|
+
if (id) {
|
|
84
|
+
return `form#${CSS.escape(id)}`;
|
|
72
85
|
}
|
|
73
|
-
return
|
|
86
|
+
return `form${form.classList.length > 0 ? `.${CSS.escape(form.classList[0])}` : ''}`;
|
|
74
87
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
const block = el.closest('.block[data-block-name]');
|
|
89
|
+
return block && `.${block.getAttribute('data-block-name')}` || walk(el, isDialog) && 'dialog' || walk(el, e => e.tagName && e.tagName.includes('-') && e.tagName.toLowerCase()) || ['nav', 'header', 'footer', 'aside'].find(t => el.closest(t)) || walk(el, e => e.id && `#${CSS.escape(e.id)}`);
|
|
90
|
+
}
|
|
91
|
+
function srcElement(el) {
|
|
92
|
+
const f = el.closest('form');
|
|
93
|
+
if (f && Array.from(f.elements).includes(el)) {
|
|
94
|
+
return el.tagName.toLowerCase() + (['INPUT', 'BUTTON'].includes(el.tagName) ? `[type='${el.getAttribute('type') || ''}']` : '');
|
|
78
95
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
96
|
+
return walk(el, isButton) && 'button' || el.tagName.toLowerCase().match(/^(a|img|video|form)$/) && el.tagName.toLowerCase();
|
|
97
|
+
}
|
|
98
|
+
function srcId(el) {
|
|
99
|
+
return el.id && `#${CSS.escape(el.id)}` || el.getAttribute('data-block-name') && `.${el.getAttribute('data-block-name')}` || el.classList.length > 0 && `.${CSS.escape(el.classList[0])}`;
|
|
100
|
+
}
|
|
101
|
+
const sourceSelector = el => {
|
|
102
|
+
try {
|
|
103
|
+
if (!el || el === document.body || el === document.documentElement) {
|
|
104
|
+
return undefined;
|
|
82
105
|
}
|
|
83
|
-
if (el.
|
|
84
|
-
return
|
|
106
|
+
if (el.getAttribute('data-rum-source')) {
|
|
107
|
+
return el.getAttribute('data-rum-source');
|
|
85
108
|
}
|
|
86
|
-
|
|
109
|
+
const ctx = srcContext(el.parentElement) || '';
|
|
110
|
+
const name = srcElement(el) || '';
|
|
111
|
+
const id = srcId(el) || '';
|
|
112
|
+
return `${ctx} ${name}${id}`.trim() || `"${el.textContent.substring(0, 10)}"`;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return null;
|
|
87
115
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
116
|
+
};const {
|
|
117
|
+
sampleRUM,
|
|
118
|
+
queue,
|
|
119
|
+
isSelected
|
|
120
|
+
} = window.hlx && window.hlx.rum ? window.hlx.rum : {};
|
|
121
|
+
const createMO = cb => window.MutationObserver ? new MutationObserver(cb) : {};
|
|
122
|
+
const [blocksMO, mediaMO] = [blocksMCB, mediaMCB].map(createMO);
|
|
123
|
+
const hasCookie = key => document.cookie.split(';').some(c => c.trim().startsWith(`${key}=`));
|
|
124
|
+
const pluginBase = new URL(document.currentScript.src).href.replace(/index(\.map)?\.js/, 'plugins');
|
|
125
|
+
const CONSENT_PROVIDERS = [{
|
|
126
|
+
name: 'onetrust',
|
|
127
|
+
detect: () => hasCookie('OptanonAlertBoxClosed') || document.querySelector('#onetrust-banner-sdk, #onetrust-pc-sdk')
|
|
128
|
+
}, {
|
|
129
|
+
name: 'trustarc',
|
|
130
|
+
detect: () => ['notice_gdpr_prefs', 'notice_preferences'].some(hasCookie) || document.querySelector('#truste-consent-track')
|
|
131
|
+
}, {
|
|
132
|
+
name: 'usercentrics',
|
|
133
|
+
detect: () => window.localStorage.getItem('uc_gcm') || document.querySelector('#usercentrics-root')
|
|
134
|
+
}];
|
|
135
|
+
const getConsent = () => CONSENT_PROVIDERS.find(({
|
|
136
|
+
detect
|
|
137
|
+
}) => detect());
|
|
138
|
+
const bodyChildMO = {
|
|
139
|
+
target: document.body,
|
|
140
|
+
options: {
|
|
141
|
+
attributes: false,
|
|
142
|
+
childList: true,
|
|
143
|
+
subtree: false
|
|
99
144
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
145
|
+
};
|
|
146
|
+
const PLUGINS = {
|
|
147
|
+
cwv: `${pluginBase}/cwv.js`,
|
|
148
|
+
a11y: `${pluginBase}/a11y.js`,
|
|
149
|
+
form: {
|
|
150
|
+
url: `${pluginBase}/form.js`,
|
|
151
|
+
when: () => document.querySelector('form'),
|
|
152
|
+
isBlockDependent: true,
|
|
153
|
+
moParams: bodyChildMO
|
|
154
|
+
},
|
|
155
|
+
redirect: {
|
|
156
|
+
url: `${pluginBase}/redirect.js`,
|
|
157
|
+
when: ({
|
|
158
|
+
perfEntry: pe,
|
|
159
|
+
urlParameters: usp
|
|
160
|
+
}) => pe && (usp.get('redirect_from') || pe.redirectCount > 0 || pe.fetchStart > 50)
|
|
161
|
+
},
|
|
162
|
+
video: {
|
|
163
|
+
url: `${pluginBase}/video.js`,
|
|
164
|
+
when: () => document.querySelector('video'),
|
|
165
|
+
isBlockDependent: true
|
|
166
|
+
},
|
|
167
|
+
webcomponent: {
|
|
168
|
+
url: `${pluginBase}/webcomponent.js`,
|
|
169
|
+
when: () => [...document.querySelectorAll('*')].some(el => el.tagName && el.tagName.includes('-')),
|
|
170
|
+
isBlockDependent: true
|
|
171
|
+
},
|
|
172
|
+
martech: {
|
|
173
|
+
url: `${pluginBase}/martech.js`,
|
|
174
|
+
when: ({
|
|
175
|
+
urlParameters
|
|
176
|
+
}) => urlParameters.size > 0
|
|
177
|
+
},
|
|
178
|
+
consent: {
|
|
179
|
+
when: () => getConsent(),
|
|
180
|
+
isBlockDependent: true,
|
|
181
|
+
moParams: bodyChildMO
|
|
106
182
|
}
|
|
107
|
-
|
|
108
|
-
|
|
183
|
+
};
|
|
184
|
+
const MAX_EV = 1023;
|
|
185
|
+
const vmDedupe = new Set();
|
|
186
|
+
function getIntersectionObserver(checkpoint) {
|
|
187
|
+
if (!window.IntersectionObserver) {
|
|
188
|
+
return null;
|
|
109
189
|
}
|
|
110
|
-
const
|
|
190
|
+
const obs = new IntersectionObserver(entries => {
|
|
111
191
|
try {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const {
|
|
128
|
-
sampleRUM,
|
|
129
|
-
queue,
|
|
130
|
-
isSelected
|
|
131
|
-
} = window.hlx && window.hlx.rum ? window.hlx.rum : {};
|
|
132
|
-
const createMO = cb => window.MutationObserver ? new MutationObserver(cb) : {};
|
|
133
|
-
const [blocksMO, mediaMO] = [blocksMCB, mediaMCB].map(createMO);
|
|
134
|
-
const hasCookie = key => document.cookie.split(';').some(c => c.trim().startsWith(`${key}=`));
|
|
135
|
-
const pluginBase = new URL(document.currentScript.src).href.replace(/index(\.map)?\.js/, 'plugins');
|
|
136
|
-
const CONSENT_PROVIDERS = [{
|
|
137
|
-
name: 'onetrust',
|
|
138
|
-
detect: () => hasCookie('OptanonAlertBoxClosed') || document.querySelector('#onetrust-banner-sdk, #onetrust-pc-sdk')
|
|
139
|
-
}, {
|
|
140
|
-
name: 'trustarc',
|
|
141
|
-
detect: () => ['notice_gdpr_prefs', 'notice_preferences'].some(hasCookie) || document.querySelector('#truste-consent-track')
|
|
142
|
-
}, {
|
|
143
|
-
name: 'usercentrics',
|
|
144
|
-
detect: () => window.localStorage.getItem('uc_gcm') || document.querySelector('#usercentrics-root')
|
|
145
|
-
}];
|
|
146
|
-
const getConsent = () => CONSENT_PROVIDERS.find(({
|
|
147
|
-
detect
|
|
148
|
-
}) => detect());
|
|
149
|
-
const bodyChildMO = {
|
|
150
|
-
target: document.body,
|
|
151
|
-
options: {
|
|
152
|
-
attributes: false,
|
|
153
|
-
childList: true,
|
|
154
|
-
subtree: false
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
const PLUGINS = {
|
|
158
|
-
cwv: `${pluginBase}/cwv.js`,
|
|
159
|
-
a11y: `${pluginBase}/a11y.js`,
|
|
160
|
-
form: {
|
|
161
|
-
url: `${pluginBase}/form.js`,
|
|
162
|
-
when: () => document.querySelector('form'),
|
|
163
|
-
isBlockDependent: true,
|
|
164
|
-
moParams: bodyChildMO
|
|
165
|
-
},
|
|
166
|
-
redirect: {
|
|
167
|
-
url: `${pluginBase}/redirect.js`,
|
|
168
|
-
when: ({
|
|
169
|
-
perfEntry: pe,
|
|
170
|
-
urlParameters: usp
|
|
171
|
-
}) => pe && (usp.get('redirect_from') || pe.redirectCount > 0 || pe.fetchStart > 50)
|
|
172
|
-
},
|
|
173
|
-
video: {
|
|
174
|
-
url: `${pluginBase}/video.js`,
|
|
175
|
-
when: () => document.querySelector('video'),
|
|
176
|
-
isBlockDependent: true
|
|
177
|
-
},
|
|
178
|
-
webcomponent: {
|
|
179
|
-
url: `${pluginBase}/webcomponent.js`,
|
|
180
|
-
when: () => [...document.querySelectorAll('*')].some(el => el.tagName && el.tagName.includes('-')),
|
|
181
|
-
isBlockDependent: true
|
|
182
|
-
},
|
|
183
|
-
martech: {
|
|
184
|
-
url: `${pluginBase}/martech.js`,
|
|
185
|
-
when: ({
|
|
186
|
-
urlParameters
|
|
187
|
-
}) => urlParameters.size > 0
|
|
188
|
-
},
|
|
189
|
-
consent: {
|
|
190
|
-
when: () => getConsent(),
|
|
191
|
-
isBlockDependent: true,
|
|
192
|
-
moParams: bodyChildMO
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
const MAX_EV = 1023;
|
|
196
|
-
const vmDedupe = new Set();
|
|
197
|
-
function getIntersectionObserver(checkpoint) {
|
|
198
|
-
if (!window.IntersectionObserver) {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
const obs = new IntersectionObserver(entries => {
|
|
202
|
-
try {
|
|
203
|
-
entries.filter(e => e.isIntersecting).forEach(e => {
|
|
204
|
-
obs.unobserve(e.target);
|
|
205
|
-
const target = targetSelector(e.target);
|
|
206
|
-
const source = sourceSelector(e.target);
|
|
207
|
-
if (checkpoint === 'viewmedia') {
|
|
208
|
-
const key = `${source}\0${target}`;
|
|
209
|
-
if (vmDedupe.has(key)) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if (vmDedupe.size < MAX_EV) {
|
|
213
|
-
vmDedupe.add(key);
|
|
214
|
-
}
|
|
192
|
+
entries.filter(e => e.isIntersecting).forEach(e => {
|
|
193
|
+
obs.unobserve(e.target);
|
|
194
|
+
const target = targetSelector(e.target);
|
|
195
|
+
const source = sourceSelector(e.target);
|
|
196
|
+
if (checkpoint === 'viewmedia') {
|
|
197
|
+
const key = `${source}\0${target}`;
|
|
198
|
+
if (vmDedupe.has(key)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (vmDedupe.size < MAX_EV) {
|
|
202
|
+
vmDedupe.add(key);
|
|
215
203
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
204
|
+
}
|
|
205
|
+
sampleRUM(checkpoint, {
|
|
206
|
+
target,
|
|
207
|
+
source
|
|
220
208
|
});
|
|
221
|
-
}
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
if (key === 'consent') {
|
|
249
|
-
plugin.url = `${pluginBase}/${getConsent().name}.js`;
|
|
250
|
-
}
|
|
251
|
-
if (!pluginCache.has(key)) {
|
|
252
|
-
pluginCache.set(key, import(`${plugin.url || plugin}`));
|
|
209
|
+
});
|
|
210
|
+
} catch (error) {}
|
|
211
|
+
});
|
|
212
|
+
return obs;
|
|
213
|
+
}
|
|
214
|
+
const PLUGIN_PARAMS = {
|
|
215
|
+
context: document.body,
|
|
216
|
+
fflags,
|
|
217
|
+
sampleRUM,
|
|
218
|
+
sourceSelector,
|
|
219
|
+
targetSelector,
|
|
220
|
+
untrustedClickPayload,
|
|
221
|
+
getIntersectionObserver,
|
|
222
|
+
createMO
|
|
223
|
+
};
|
|
224
|
+
const pluginCache = new Map();
|
|
225
|
+
function loadPlugin(key, params) {
|
|
226
|
+
const plugin = PLUGINS[key];
|
|
227
|
+
const usp = new URLSearchParams(window.location.search);
|
|
228
|
+
if (!pluginCache.has(key) && plugin.when && !plugin.when({
|
|
229
|
+
...params,
|
|
230
|
+
urlParameters: usp
|
|
231
|
+
})) {
|
|
232
|
+
if (plugin.moParams && !plugin.isBeingObserved) {
|
|
233
|
+
createPluginMO(key, params, usp);
|
|
253
234
|
}
|
|
254
|
-
return
|
|
235
|
+
return null;
|
|
255
236
|
}
|
|
256
|
-
|
|
257
|
-
|
|
237
|
+
if (key === 'consent') {
|
|
238
|
+
plugin.url = `${pluginBase}/${getConsent().name}.js`;
|
|
258
239
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (
|
|
271
|
-
|
|
272
|
-
|
|
240
|
+
if (!pluginCache.has(key)) {
|
|
241
|
+
pluginCache.set(key, import(`${plugin.url || plugin}`));
|
|
242
|
+
}
|
|
243
|
+
return pluginCache.get(key).then(p => p.default && p.default(params) || typeof p === 'function' && p(params)).catch(() => {});
|
|
244
|
+
}
|
|
245
|
+
function loadPlugins(filter = () => true, params = PLUGIN_PARAMS) {
|
|
246
|
+
Object.entries(PLUGINS).filter(([, plugin]) => filter(plugin)).map(([key]) => loadPlugin(key, params));
|
|
247
|
+
}
|
|
248
|
+
function createPluginMO(key, params, usp) {
|
|
249
|
+
const plugin = PLUGINS[key];
|
|
250
|
+
const obs = createMO(() => {
|
|
251
|
+
if (plugin.when({
|
|
252
|
+
urlParameters: usp
|
|
253
|
+
})) {
|
|
254
|
+
plugin.isBeingObserved = false;
|
|
255
|
+
obs.disconnect();
|
|
256
|
+
loadPlugin(key, params);
|
|
273
257
|
}
|
|
258
|
+
});
|
|
259
|
+
if (obs instanceof MutationObserver) {
|
|
260
|
+
plugin.isBeingObserved = true;
|
|
261
|
+
obs.observe(plugin.moParams.target, plugin.moParams.options);
|
|
274
262
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
263
|
+
}
|
|
264
|
+
let maxEvents = MAX_EV;
|
|
265
|
+
function trackCheckpoint(checkpoint, data, t) {
|
|
266
|
+
const {
|
|
267
|
+
weight,
|
|
268
|
+
id
|
|
269
|
+
} = window.hlx.rum;
|
|
270
|
+
if (isSelected && maxEvents) {
|
|
271
|
+
maxEvents -= 1;
|
|
272
|
+
const body = JSON.stringify({
|
|
278
273
|
weight,
|
|
279
|
-
id
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const headers = {
|
|
298
|
-
type: 'application/json'
|
|
299
|
-
};
|
|
300
|
-
navigator.sendBeacon(url, new Blob([body], headers));
|
|
301
|
-
} else {
|
|
302
|
-
navigator.sendBeacon(url, body);
|
|
303
|
-
}
|
|
304
|
-
console.debug(`ping:${checkpoint}`, data);
|
|
274
|
+
id,
|
|
275
|
+
referer: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'](),
|
|
276
|
+
checkpoint,
|
|
277
|
+
t,
|
|
278
|
+
...data
|
|
279
|
+
}, KNOWN_PROPERTIES);
|
|
280
|
+
const urlParams = window.RUM_PARAMS ? `?${new URLSearchParams(window.RUM_PARAMS).toString()}` : '';
|
|
281
|
+
const {
|
|
282
|
+
href: url,
|
|
283
|
+
origin
|
|
284
|
+
} = new URL(`.rum/${weight}${urlParams.length > 1 ? urlParams : ''}`, sampleRUM.collectBaseURL);
|
|
285
|
+
if (window.location.origin === origin) {
|
|
286
|
+
const headers = {
|
|
287
|
+
type: 'application/json'
|
|
288
|
+
};
|
|
289
|
+
navigator.sendBeacon(url, new Blob([body], headers));
|
|
290
|
+
} else {
|
|
291
|
+
navigator.sendBeacon(url, body);
|
|
305
292
|
}
|
|
293
|
+
console.debug(`ping:${checkpoint}`, data);
|
|
306
294
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
295
|
+
}
|
|
296
|
+
function processQueue() {
|
|
297
|
+
while (queue && queue.length) {
|
|
298
|
+
const ck = queue.shift();
|
|
299
|
+
trackCheckpoint(...ck);
|
|
312
300
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}, {
|
|
324
|
-
once: true
|
|
325
|
-
});
|
|
326
|
-
if (type === 'navigate') {
|
|
327
|
-
sampleRUM('prerender', payload);
|
|
328
|
-
}
|
|
329
|
-
} else if (type === 'reload' || source === window.location.href) {
|
|
330
|
-
sampleRUM('reload', payload);
|
|
331
|
-
} else if (type && type !== 'navigate') {
|
|
332
|
-
sampleRUM(type, payload);
|
|
333
|
-
} else if (source && window.location.origin === new URL(source).origin) {
|
|
301
|
+
}
|
|
302
|
+
function addNavigationTracking() {
|
|
303
|
+
const navigate = (source, type, perfEntry) => {
|
|
304
|
+
const payload = {
|
|
305
|
+
source: source && urlSanitizers.path(source),
|
|
306
|
+
target: document.visibilityState
|
|
307
|
+
};
|
|
308
|
+
if (document.prerendering) {
|
|
309
|
+
document.addEventListener('prerenderingchange', () => {
|
|
310
|
+
payload.target = 'prerendered';
|
|
334
311
|
sampleRUM('navigate', payload);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
loadPlugin('redirect', {
|
|
339
|
-
...PLUGIN_PARAMS,
|
|
340
|
-
perfEntry
|
|
312
|
+
}, {
|
|
313
|
+
once: true
|
|
341
314
|
});
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
315
|
+
if (type === 'navigate') {
|
|
316
|
+
sampleRUM('prerender', payload);
|
|
317
|
+
}
|
|
318
|
+
} else if (type === 'reload' || source === window.location.href) {
|
|
319
|
+
sampleRUM('reload', payload);
|
|
320
|
+
} else if (type && type !== 'navigate') {
|
|
321
|
+
sampleRUM(type, payload);
|
|
322
|
+
} else if (source && window.location.origin === new URL(source).origin) {
|
|
323
|
+
sampleRUM('navigate', payload);
|
|
324
|
+
} else {
|
|
325
|
+
sampleRUM('enter', payload);
|
|
326
|
+
}
|
|
327
|
+
loadPlugin('redirect', {
|
|
328
|
+
...PLUGIN_PARAMS,
|
|
329
|
+
perfEntry
|
|
349
330
|
});
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
331
|
+
};
|
|
332
|
+
const processed = new Set();
|
|
333
|
+
new PerformanceObserver(list => list.getEntries().filter(({
|
|
334
|
+
type
|
|
335
|
+
}) => !processed.has(type)).map(e => [e, processed.add(e.type)]).map(([e]) => navigate(window.hlx.referrer || document.referrer, e.type, e))).observe({
|
|
336
|
+
type: 'navigation',
|
|
337
|
+
buffered: true
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
function addLoadResourceTracking() {
|
|
341
|
+
const obs = new PerformanceObserver(list => {
|
|
342
|
+
try {
|
|
343
|
+
const entries = list.getEntries();
|
|
344
|
+
entries.filter(e => !e.responseStatus || e.responseStatus < 400).filter(e => window.location.hostname === new URL(e.name).hostname || fflags.has('allresources')).filter(e => {
|
|
345
|
+
const {
|
|
346
|
+
pathname,
|
|
347
|
+
hostname
|
|
348
|
+
} = new URL(e.name);
|
|
349
|
+
const extMatch = pathname.match(hostname !== window.location.hostname ? '.*(\\.html$|\\.json|\\.js|graphql|api)' : '.*(\\.plain\\.html$|\\.json|graphql|api)');
|
|
350
|
+
const isDropIn = fflags.has('allresources') && (pathname.includes('__dropins__/storefront-') || pathname.includes('scripts/dropins/storefront-'));
|
|
351
|
+
const isImage = fflags.has('allresources') && pathname.match(/\.(png|jpe?g|svg)$/i);
|
|
352
|
+
return extMatch || isDropIn || isImage;
|
|
353
|
+
}).forEach(e => {
|
|
354
|
+
sampleRUM('loadresource', {
|
|
355
|
+
source: e.name,
|
|
356
|
+
target: Math.round(e.duration)
|
|
369
357
|
});
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
358
|
+
});
|
|
359
|
+
entries.filter(e => e.responseStatus >= 400).filter(e => !new URL(e.name).pathname.match('.*(/\\.rum/1[0-9]{0,3})')).forEach(e => {
|
|
360
|
+
sampleRUM('missingresource', {
|
|
361
|
+
source: e.name,
|
|
362
|
+
target: e.responseStatus
|
|
375
363
|
});
|
|
376
|
-
} catch (error) {}
|
|
377
|
-
});
|
|
378
|
-
obs.observe({
|
|
379
|
-
type: 'resource',
|
|
380
|
-
buffered: true
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
function activateBlocksMO() {
|
|
384
|
-
if (!blocksMO || blocksMO.active) {
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
blocksMO.active = true;
|
|
388
|
-
blocksMO.observe(document.body, {
|
|
389
|
-
subtree: true,
|
|
390
|
-
attributes: true,
|
|
391
|
-
attributeFilter: ['data-block-status']
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
function activateMediaMO() {
|
|
395
|
-
if (!mediaMO || mediaMO.active) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
mediaMO.active = true;
|
|
399
|
-
mediaMO.observe(document.body, {
|
|
400
|
-
subtree: true,
|
|
401
|
-
attributes: false,
|
|
402
|
-
childList: true
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
function addViewBlockTracking(el) {
|
|
406
|
-
const blockObs = getIntersectionObserver('viewblock');
|
|
407
|
-
if (blockObs) {
|
|
408
|
-
const blocks = el.getAttribute('data-block-status') ? [el] : el.querySelectorAll('div[data-block-status="loaded"]');
|
|
409
|
-
blocks.forEach(b => blockObs.observe(b));
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
const observedMedia = new Set();
|
|
413
|
-
function addViewMediaTracking(parent) {
|
|
414
|
-
const mediaObs = getIntersectionObserver('viewmedia');
|
|
415
|
-
if (mediaObs) {
|
|
416
|
-
parent.querySelectorAll('img, video, audio, iframe').forEach(m => {
|
|
417
|
-
if (!observedMedia.has(m)) {
|
|
418
|
-
observedMedia.add(m);
|
|
419
|
-
mediaObs.observe(m);
|
|
420
|
-
}
|
|
421
364
|
});
|
|
422
|
-
}
|
|
365
|
+
} catch (error) {}
|
|
366
|
+
});
|
|
367
|
+
obs.observe({
|
|
368
|
+
type: 'resource',
|
|
369
|
+
buffered: true
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
function activateBlocksMO() {
|
|
373
|
+
if (!blocksMO || blocksMO.active) {
|
|
374
|
+
return;
|
|
423
375
|
}
|
|
424
|
-
|
|
425
|
-
|
|
376
|
+
blocksMO.active = true;
|
|
377
|
+
blocksMO.observe(document.body, {
|
|
378
|
+
subtree: true,
|
|
379
|
+
attributes: true,
|
|
380
|
+
attributeFilter: ['data-block-status']
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
function activateMediaMO() {
|
|
384
|
+
if (!mediaMO || mediaMO.active) {
|
|
385
|
+
return;
|
|
426
386
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
387
|
+
mediaMO.active = true;
|
|
388
|
+
mediaMO.observe(document.body, {
|
|
389
|
+
subtree: true,
|
|
390
|
+
attributes: false,
|
|
391
|
+
childList: true
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
function addViewBlockTracking(el) {
|
|
395
|
+
const blockObs = getIntersectionObserver('viewblock');
|
|
396
|
+
if (blockObs) {
|
|
397
|
+
const blocks = el.getAttribute('data-block-status') ? [el] : el.querySelectorAll('div[data-block-status="loaded"]');
|
|
398
|
+
blocks.forEach(b => blockObs.observe(b));
|
|
435
399
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
if (event.optelHandled) {
|
|
446
|
-
return;
|
|
400
|
+
}
|
|
401
|
+
const observedMedia = new Set();
|
|
402
|
+
function addViewMediaTracking(parent) {
|
|
403
|
+
const mediaObs = getIntersectionObserver('viewmedia');
|
|
404
|
+
if (mediaObs) {
|
|
405
|
+
parent.querySelectorAll('img, video, audio, iframe').forEach(m => {
|
|
406
|
+
if (!observedMedia.has(m)) {
|
|
407
|
+
observedMedia.add(m);
|
|
408
|
+
mediaObs.observe(m);
|
|
447
409
|
}
|
|
448
|
-
sampleRUM('click', {
|
|
449
|
-
target: targetSelector(event.target),
|
|
450
|
-
source: sourceSelector(event.target),
|
|
451
|
-
...untrustedClickPayload(event)
|
|
452
|
-
});
|
|
453
410
|
});
|
|
454
|
-
addNavigationTracking();
|
|
455
|
-
addLoadResourceTracking();
|
|
456
|
-
addViewBlockTracking(document.body);
|
|
457
|
-
addViewMediaTracking(document.body);
|
|
458
|
-
loadPlugins();
|
|
459
|
-
const target = navigator.language;
|
|
460
|
-
const source = document.documentElement.lang;
|
|
461
|
-
sampleRUM('language', {
|
|
462
|
-
source,
|
|
463
|
-
target
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
function initEnhancer() {
|
|
467
|
-
try {
|
|
468
|
-
if (sampleRUM) {
|
|
469
|
-
addTrackingFromConfig();
|
|
470
|
-
window.hlx.rum.collector = trackCheckpoint;
|
|
471
|
-
processQueue();
|
|
472
|
-
}
|
|
473
|
-
} catch (error) {}
|
|
474
411
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
412
|
+
}
|
|
413
|
+
function addObserver(ck, fn, block) {
|
|
414
|
+
return DEFAULT_TRACKING_EVENTS.includes(ck) && fn(block);
|
|
415
|
+
}
|
|
416
|
+
function blocksMCB(mutations) {
|
|
417
|
+
mutations.filter(m => m.type === 'attributes' && m.attributeName === 'data-block-status').filter(m => m.target.dataset.blockStatus === 'loaded').forEach(m => {
|
|
418
|
+
addObserver('form', el => loadPlugins(p => p.isBlockDependent, {
|
|
419
|
+
...PLUGIN_PARAMS,
|
|
420
|
+
context: el
|
|
421
|
+
}), m.target);
|
|
422
|
+
addObserver('viewblock', addViewBlockTracking, m.target);
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
function mediaMCB(mutations) {
|
|
426
|
+
mutations.forEach(m => {
|
|
427
|
+
addObserver('viewmedia', addViewMediaTracking, m.target);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
function addTrackingFromConfig() {
|
|
431
|
+
activateBlocksMO();
|
|
432
|
+
activateMediaMO();
|
|
433
|
+
document.addEventListener('click', event => {
|
|
434
|
+
if (event.optelHandled) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
sampleRUM('click', {
|
|
438
|
+
target: targetSelector(event.target),
|
|
439
|
+
source: sourceSelector(event.target),
|
|
440
|
+
...untrustedClickPayload(event)
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
addNavigationTracking();
|
|
444
|
+
addLoadResourceTracking();
|
|
445
|
+
addViewBlockTracking(document.body);
|
|
446
|
+
addViewMediaTracking(document.body);
|
|
447
|
+
loadPlugins();
|
|
448
|
+
const target = navigator.language;
|
|
449
|
+
const source = document.documentElement.lang;
|
|
450
|
+
sampleRUM('language', {
|
|
451
|
+
source,
|
|
452
|
+
target
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
function initEnhancer() {
|
|
456
|
+
try {
|
|
457
|
+
if (sampleRUM) {
|
|
458
|
+
addTrackingFromConfig();
|
|
459
|
+
window.hlx.rum.collector = trackCheckpoint;
|
|
460
|
+
processQueue();
|
|
461
|
+
}
|
|
462
|
+
} catch (error) {}
|
|
463
|
+
}
|
|
464
|
+
initEnhancer();})();
|