@adobe/helix-rum-enhancer
Advanced tools
Comparing version 2.26.0-beta.1 to 2.26.0
@@ -1,2 +0,2 @@ | ||
# [2.26.0-beta.1](https://github.com/adobe/helix-rum-enhancer/compare/v2.25.0...v2.26.0-beta.1) (2024-10-09) | ||
# [2.26.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.25.0...v2.26.0) (2024-10-16) | ||
@@ -6,3 +6,3 @@ | ||
* handle pre-rendering ([bb11187](https://github.com/adobe/helix-rum-enhancer/commit/bb11187058b8cb521a270c316323b66414a8d817)) | ||
* handle pre-speculation rules and rendering ([#301](https://github.com/adobe/helix-rum-enhancer/issues/301)) ([196d404](https://github.com/adobe/helix-rum-enhancer/commit/196d404f3f90a247a223e8ddc7c667592a87319f)) | ||
@@ -9,0 +9,0 @@ # [2.25.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.24.0...v2.25.0) (2024-10-03) |
@@ -12,17 +12,17 @@ /* | ||
*/ | ||
export const getTargetValue = (element) => element.getAttribute('data-rum-target') || element.getAttribute('href') | ||
|| element.currentSrc || element.getAttribute('src') || element.dataset.action || element.action; | ||
export const getTargetValue = (el) => el.getAttribute('data-rum-target') || el.getAttribute('href') | ||
|| el.currentSrc || el.getAttribute('src') || el.dataset.action || el.action; | ||
export const targetSelector = (element) => { | ||
export const targetSelector = (el) => { | ||
try { | ||
if (!element) return undefined; | ||
let value = getTargetValue(element); | ||
if (!value && element.tagName !== 'A' && element.closest('a')) { | ||
value = getTargetValue(element.closest('a')); | ||
if (!el) return undefined; | ||
let v = getTargetValue(el); | ||
if (!v && el.tagName !== 'A' && el.closest('a')) { | ||
v = getTargetValue(el.closest('a')); | ||
} | ||
if (value && !value.startsWith('https://')) { | ||
if (v && !v.startsWith('https://')) { | ||
// resolve relative links | ||
value = new URL(value, window.location).href; | ||
v = new URL(v, window.location).href; | ||
} | ||
return value; | ||
return v; | ||
/* c8 ignore next 3 */ | ||
@@ -34,74 +34,74 @@ } catch (error) { | ||
function walk(element, checkFn) { | ||
if (!element || element === document.body || element === document.documentElement) { | ||
function walk(el, checkFn) { | ||
if (!el || el === document.body || el === document.documentElement) { | ||
return undefined; | ||
} | ||
const checkValue = checkFn(element); | ||
return checkValue || walk(element.parentElement, checkFn); | ||
return checkFn(el) || walk(el.parentElement, checkFn); | ||
} | ||
function isDialog(element) { | ||
function isDialog(el) { | ||
// doing it well | ||
if (element.tagName === 'DIALOG') return true; | ||
if (el.tagName === 'DIALOG') return true; | ||
// making the best of it | ||
if (element.getAttribute('role') === 'dialog') return true; | ||
if (element.getAttribute('role') === 'alertdialog') return true; | ||
if (element.getAttribute('aria-modal') === 'true') return true; | ||
if (el.getAttribute('role') === 'dialog') return true; | ||
if (el.getAttribute('role') === 'alertdialog') return true; | ||
if (el.getAttribute('aria-modal') === 'true') return true; | ||
// doing it wrong | ||
const computedStyle = window.getComputedStyle(element); | ||
return (computedStyle && computedStyle.position === 'fixed' && computedStyle.zIndex > 100); | ||
const cs = window.getComputedStyle(el); | ||
return (cs && cs.position === 'fixed' && cs.zIndex > 100); | ||
} | ||
function isButton(element) { | ||
if (element.tagName === 'BUTTON') return true; | ||
if (element.tagName === 'INPUT' && element.getAttribute('type') === 'button') return true; | ||
if (element.tagName === 'A') { | ||
const classes = Array.from(element.classList); | ||
function isButton(el) { | ||
if (el.tagName === 'BUTTON') return true; | ||
if (el.tagName === 'INPUT' && el.getAttribute('type') === 'button') return true; | ||
if (el.tagName === 'A') { | ||
const classes = Array.from(el.classList); | ||
return classes.some((className) => className.match(/button|cta/)); | ||
} | ||
return element.getAttribute('role') === 'button'; | ||
return el.getAttribute('role') === 'button'; | ||
} | ||
function getSourceContext(element) { | ||
if (element.closest('form')) { | ||
return `form${element.id ? `#${element.id}` : ''}`; | ||
function getSourceContext(el) { | ||
if (el.closest('form')) { | ||
return `form${el.id ? `#${el.id}` : ''}`; | ||
} | ||
const block = element.closest('.block[data-block-name]'); | ||
const block = el.closest('.block[data-block-name]'); | ||
if (block) return `.${block.getAttribute('data-block-name')}`; | ||
if (walk(element, isDialog)) return 'dialog'; | ||
if (element.closest('nav')) return 'nav'; | ||
if (element.closest('header')) return 'header'; | ||
if (element.closest('footer')) return 'footer'; | ||
if (element.closest('aside')) return 'aside'; | ||
return (walk(element, (e) => e.id && `#${e.id}`)); | ||
if (walk(el, isDialog)) return 'dialog'; | ||
if (el.closest('nav')) return 'nav'; | ||
if (el.closest('header')) return 'header'; | ||
if (el.closest('footer')) return 'footer'; | ||
if (el.closest('aside')) return 'aside'; | ||
return (walk(el, (e) => e.id && `#${e.id}`)); | ||
} | ||
function getSourceElement(element) { | ||
if (element.closest('form') && Array.from(element.closest('form').elements).includes(element)) { | ||
return (element.tagName.toLowerCase() | ||
+ (['INPUT', 'BUTTON'].includes(element.tagName) | ||
? `[type='${element.getAttribute('type') || ''}']` | ||
function getSourceElement(el) { | ||
const f = el.closest('form'); | ||
if (f && Array.from(f.elements).includes(el)) { | ||
return (el.tagName.toLowerCase() | ||
+ (['INPUT', 'BUTTON'].includes(el.tagName) | ||
? `[type='${el.getAttribute('type') || ''}']` | ||
: '')); | ||
} | ||
if (walk(element, isButton)) return 'button'; | ||
return element.tagName.toLowerCase().match(/^(a|img|video)$/) && element.tagName.toLowerCase(); | ||
if (walk(el, isButton)) return 'button'; | ||
return el.tagName.toLowerCase().match(/^(a|img|video)$/) && el.tagName.toLowerCase(); | ||
} | ||
function getSourceIdentifier(element) { | ||
if (element.id) return `#${element.id}`; | ||
if (element.getAttribute('data-block-name')) return `.${element.getAttribute('data-block-name')}`; | ||
return (element.classList.length > 0 && `.${element.classList[0]}`); | ||
function getSourceIdentifier(el) { | ||
if (el.id) return `#${el.id}`; | ||
if (el.getAttribute('data-block-name')) return `.${el.getAttribute('data-block-name')}`; | ||
return (el.classList.length > 0 && `.${el.classList[0]}`); | ||
} | ||
export const sourceSelector = (element) => { | ||
export const sourceSelector = (el) => { | ||
try { | ||
if (!element || element === document.body || element === document.documentElement) { | ||
if (!el || el === document.body || el === document.documentElement) { | ||
return undefined; | ||
} | ||
if (element.getAttribute('data-rum-source')) { | ||
return element.getAttribute('data-rum-source'); | ||
if (el.getAttribute('data-rum-source')) { | ||
return el.getAttribute('data-rum-source'); | ||
} | ||
const context = getSourceContext(element.parentElement) || ''; | ||
const elementName = getSourceElement(element) || ''; | ||
const identifier = getSourceIdentifier(element) || ''; | ||
return `${context} ${elementName}${identifier}`.trim() || `"${element.textContent.substring(0, 10)}"`; | ||
const ctx = getSourceContext(el.parentElement) || ''; | ||
const name = getSourceElement(el) || ''; | ||
const id = getSourceIdentifier(el) || ''; | ||
return `${ctx} ${name}${id}`.trim() || `"${el.textContent.substring(0, 10)}"`; | ||
/* c8 ignore next 3 */ | ||
@@ -108,0 +108,0 @@ } catch (error) { |
@@ -28,10 +28,10 @@ /* | ||
const formSubmitListener = (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) }); | ||
// blocks mutation observer | ||
// eslint-disable-next-line no-use-before-define, max-len | ||
const blocksMutationObserver = window.MutationObserver ? new MutationObserver(blocksMutationsCallback) | ||
const blocksMO = window.MutationObserver ? new MutationObserver(blocksMCB) | ||
/* c8 ignore next */ : {}; | ||
// media mutation observer | ||
// eslint-disable-next-line no-use-before-define, max-len | ||
const mediaMutationObserver = window.MutationObserver ? new MutationObserver(mediaMutationsCallback) | ||
const mediaMO = window.MutationObserver ? new MutationObserver(mediaMCB) | ||
/* c8 ignore next */ : {}; | ||
@@ -118,2 +118,4 @@ | ||
const payload = { source, target: document.visibilityState }; | ||
/* c8 ignore next 13 */ | ||
// prerendering cannot be tested yet with headless browsers | ||
if (document.prerendering) { | ||
@@ -149,6 +151,6 @@ // listen for "activation" of the current pre-rendered page | ||
new PerformanceObserver((list) => list | ||
.getEntries().map((entry) => navigate( | ||
.getEntries().map((e) => navigate( | ||
window.hlx.referrer || document.referrer, | ||
entry.type, | ||
entry.redirectCount, | ||
e.type, | ||
e.redirectCount, | ||
))) | ||
@@ -162,12 +164,12 @@ .observe({ type: 'navigation', buffered: true }); | ||
list.getEntries() | ||
.filter((entry) => !entry.responseStatus || entry.responseStatus < 400) | ||
.filter((entry) => window.location.hostname === new URL(entry.name).hostname) | ||
.filter((entry) => new URL(entry.name).pathname.match('.*(\\.plain\\.html$|\\.json|graphql|api)')) | ||
.forEach((entry) => { | ||
sampleRUM('loadresource', { source: entry.name, target: Math.round(entry.duration) }); | ||
.filter((e) => !e.responseStatus || e.responseStatus < 400) | ||
.filter((e) => window.location.hostname === new URL(e.name).hostname) | ||
.filter((e) => new URL(e.name).pathname.match('.*(\\.plain\\.html$|\\.json|graphql|api)')) | ||
.forEach((e) => { | ||
sampleRUM('loadresource', { source: e.name, target: Math.round(e.duration) }); | ||
}); | ||
list.getEntries() | ||
.filter((entry) => entry.responseStatus === 404) | ||
.forEach((entry) => { | ||
sampleRUM('missingresource', { source: entry.name, target: entry.hostname }); | ||
.filter((e) => e.responseStatus === 404) | ||
.forEach((e) => { | ||
sampleRUM('missingresource', { source: e.name, target: e.hostname }); | ||
}); | ||
@@ -182,8 +184,9 @@ /* c8 ignore next 3 */ | ||
function activateBlocksMutationObserver() { | ||
if (!blocksMutationObserver || blocksMutationObserver.active) { | ||
// activate blocks mutation observer | ||
function activateBlocksMO() { | ||
if (!blocksMO || blocksMO.active) { | ||
return; | ||
} | ||
blocksMutationObserver.active = true; | ||
blocksMutationObserver.observe( | ||
blocksMO.active = true; | ||
blocksMO.observe( | ||
document.body, | ||
@@ -195,8 +198,9 @@ // eslint-disable-next-line object-curly-newline | ||
function activateMediaMutationObserver() { | ||
if (!mediaMutationObserver || mediaMutationObserver.active) { | ||
// activate media mutation observer | ||
function activateMediaMO() { | ||
if (!mediaMO || mediaMO.active) { | ||
return; | ||
} | ||
mediaMutationObserver.active = true; | ||
mediaMutationObserver.observe( | ||
mediaMO.active = true; | ||
mediaMO.observe( | ||
document.body, | ||
@@ -213,12 +217,12 @@ // eslint-disable-next-line object-curly-newline | ||
} | ||
activateBlocksMutationObserver(); | ||
activateMediaMutationObserver(); | ||
activateBlocksMO(); | ||
activateMediaMO(); | ||
const observer = new IntersectionObserver((entries) => { | ||
try { | ||
entries | ||
.filter((entry) => entry.isIntersecting) | ||
.forEach((entry) => { | ||
observer.unobserve(entry.target); // observe only once | ||
const target = targetSelector(entry.target); | ||
const source = sourceSelector(entry.target); | ||
.filter((e) => e.isIntersecting) | ||
.forEach((e) => { | ||
observer.unobserve(e.target); // observe only once | ||
const target = targetSelector(e.target); | ||
const source = sourceSelector(e.target); | ||
sampleRUM(checkpoint, { target, source }); | ||
@@ -255,7 +259,6 @@ }); | ||
function addFormTracking(parent) { | ||
activateBlocksMutationObserver(); | ||
activateMediaMutationObserver(); | ||
activateBlocksMO(); | ||
activateMediaMO(); | ||
parent.querySelectorAll('form').forEach((form) => { | ||
form.removeEventListener('submit', formSubmitListener); // listen only once | ||
form.addEventListener('submit', formSubmitListener); | ||
form.addEventListener('submit', (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) }), { once: true }); | ||
}); | ||
@@ -268,3 +271,4 @@ } | ||
function blocksMutationsCallback(mutations) { | ||
// blocks mutation observer callback | ||
function blocksMCB(mutations) { | ||
// block specific mutations | ||
@@ -280,3 +284,4 @@ mutations | ||
function mediaMutationsCallback(mutations) { | ||
// media mutation observer callback | ||
function mediaMCB(mutations) { | ||
// media mutations | ||
@@ -283,0 +288,0 @@ mutations |
@@ -22,3 +22,3 @@ /* | ||
let consentMutationObserver; | ||
let consentMO; // consent mutation observer | ||
const trackShowConsent = () => { | ||
@@ -32,4 +32,4 @@ const otsdk = document.querySelector('body > div#onetrust-consent-sdk'); | ||
} | ||
if (consentMutationObserver) { | ||
consentMutationObserver.disconnect(); | ||
if (consentMO) { | ||
consentMO.disconnect(); | ||
} | ||
@@ -43,7 +43,7 @@ return true; | ||
// eslint-disable-next-line max-len | ||
consentMutationObserver = window.MutationObserver | ||
consentMO = window.MutationObserver | ||
? new MutationObserver(trackShowConsent) | ||
: /* c8 ignore next */ null; | ||
if (consentMutationObserver) { | ||
consentMutationObserver.observe( | ||
if (consentMO) { | ||
consentMO.observe( | ||
document.body, | ||
@@ -50,0 +50,0 @@ // eslint-disable-next-line object-curly-newline |
@@ -13,2 +13,4 @@ /* | ||
const { href } = window.location; | ||
export const urlSanitizers = { | ||
@@ -21,3 +23,3 @@ /** | ||
*/ | ||
full: (url = window.location.href) => new URL(url).toString(), | ||
full: (url = href) => new URL(url).toString(), | ||
/** | ||
@@ -29,3 +31,3 @@ * Returns the origin of the provided url. | ||
*/ | ||
origin: (url = window.location.href) => new URL(url).origin, | ||
origin: (url = href) => new URL(url).origin, | ||
/** | ||
@@ -37,3 +39,3 @@ * Returns the sanitized url: the origin and the path (no query params or hash) | ||
*/ | ||
path: (url = window.location.href) => { | ||
path: (url = href) => { | ||
const u = new URL(url); | ||
@@ -40,0 +42,0 @@ return `${u.origin}${u.pathname}`; |
{ | ||
"name": "@adobe/helix-rum-enhancer", | ||
"version": "2.26.0-beta.1", | ||
"version": "2.26.0", | ||
"description": "Helix RUM Enhancer", | ||
@@ -17,3 +17,3 @@ "main": "src/index.js", | ||
"semantic-release": "semantic-release", | ||
"semantic-release-dry": "semantic-release --dry-run --branches $CI_BRANCH 1.x main beta", | ||
"semantic-release-dry": "semantic-release --dry-run --branches $CI_BRANCH 1.x main", | ||
"prepare": "husky" | ||
@@ -20,0 +20,0 @@ }, |
199
src/index.js
@@ -32,6 +32,7 @@ /* | ||
const { href } = window.location; | ||
const urlSanitizers = { | ||
full: (url = window.location.href) => new URL(url).toString(), | ||
origin: (url = window.location.href) => new URL(url).origin, | ||
path: (url = window.location.href) => { | ||
full: (url = href) => new URL(url).toString(), | ||
origin: (url = href) => new URL(url).origin, | ||
path: (url = href) => { | ||
const u = new URL(url); | ||
@@ -42,15 +43,15 @@ return `${u.origin}${u.pathname}`; | ||
const getTargetValue = (element) => element.getAttribute('data-rum-target') || element.getAttribute('href') | ||
|| element.currentSrc || element.getAttribute('src') || element.dataset.action || element.action; | ||
const targetSelector = (element) => { | ||
const getTargetValue = (el) => el.getAttribute('data-rum-target') || el.getAttribute('href') | ||
|| el.currentSrc || el.getAttribute('src') || el.dataset.action || el.action; | ||
const targetSelector = (el) => { | ||
try { | ||
if (!element) return undefined; | ||
let value = getTargetValue(element); | ||
if (!value && element.tagName !== 'A' && element.closest('a')) { | ||
value = getTargetValue(element.closest('a')); | ||
if (!el) return undefined; | ||
let v = getTargetValue(el); | ||
if (!v && el.tagName !== 'A' && el.closest('a')) { | ||
v = getTargetValue(el.closest('a')); | ||
} | ||
if (value && !value.startsWith('https://')) { | ||
value = new URL(value, window.location).href; | ||
if (v && !v.startsWith('https://')) { | ||
v = new URL(v, window.location).href; | ||
} | ||
return value; | ||
return v; | ||
} catch (error) { | ||
@@ -60,66 +61,66 @@ return null; | ||
}; | ||
function walk(element, checkFn) { | ||
if (!element || element === document.body || element === document.documentElement) { | ||
function walk(el, checkFn) { | ||
if (!el || el === document.body || el === document.documentElement) { | ||
return undefined; | ||
} | ||
const checkValue = checkFn(element); | ||
return checkValue || walk(element.parentElement, checkFn); | ||
return checkFn(el) || walk(el.parentElement, checkFn); | ||
} | ||
function isDialog(element) { | ||
if (element.tagName === 'DIALOG') return true; | ||
if (element.getAttribute('role') === 'dialog') return true; | ||
if (element.getAttribute('role') === 'alertdialog') return true; | ||
if (element.getAttribute('aria-modal') === 'true') return true; | ||
const computedStyle = window.getComputedStyle(element); | ||
return (computedStyle && computedStyle.position === 'fixed' && computedStyle.zIndex > 100); | ||
function isDialog(el) { | ||
if (el.tagName === 'DIALOG') return true; | ||
if (el.getAttribute('role') === 'dialog') return true; | ||
if (el.getAttribute('role') === 'alertdialog') return true; | ||
if (el.getAttribute('aria-modal') === 'true') return true; | ||
const cs = window.getComputedStyle(el); | ||
return (cs && cs.position === 'fixed' && cs.zIndex > 100); | ||
} | ||
function isButton(element) { | ||
if (element.tagName === 'BUTTON') return true; | ||
if (element.tagName === 'INPUT' && element.getAttribute('type') === 'button') return true; | ||
if (element.tagName === 'A') { | ||
const classes = Array.from(element.classList); | ||
function isButton(el) { | ||
if (el.tagName === 'BUTTON') return true; | ||
if (el.tagName === 'INPUT' && el.getAttribute('type') === 'button') return true; | ||
if (el.tagName === 'A') { | ||
const classes = Array.from(el.classList); | ||
return classes.some((className) => className.match(/button|cta/)); | ||
} | ||
return element.getAttribute('role') === 'button'; | ||
return el.getAttribute('role') === 'button'; | ||
} | ||
function getSourceContext(element) { | ||
if (element.closest('form')) { | ||
return `form${element.id ? `#${element.id}` : ''}`; | ||
function getSourceContext(el) { | ||
if (el.closest('form')) { | ||
return `form${el.id ? `#${el.id}` : ''}`; | ||
} | ||
const block = element.closest('.block[data-block-name]'); | ||
const block = el.closest('.block[data-block-name]'); | ||
if (block) return `.${block.getAttribute('data-block-name')}`; | ||
if (walk(element, isDialog)) return 'dialog'; | ||
if (element.closest('nav')) return 'nav'; | ||
if (element.closest('header')) return 'header'; | ||
if (element.closest('footer')) return 'footer'; | ||
if (element.closest('aside')) return 'aside'; | ||
return (walk(element, (e) => e.id && `#${e.id}`)); | ||
if (walk(el, isDialog)) return 'dialog'; | ||
if (el.closest('nav')) return 'nav'; | ||
if (el.closest('header')) return 'header'; | ||
if (el.closest('footer')) return 'footer'; | ||
if (el.closest('aside')) return 'aside'; | ||
return (walk(el, (e) => e.id && `#${e.id}`)); | ||
} | ||
function getSourceElement(element) { | ||
if (element.closest('form') && Array.from(element.closest('form').elements).includes(element)) { | ||
return (element.tagName.toLowerCase() | ||
+ (['INPUT', 'BUTTON'].includes(element.tagName) | ||
? `[type='${element.getAttribute('type') || ''}']` | ||
function getSourceElement(el) { | ||
const f = el.closest('form'); | ||
if (f && Array.from(f.elements).includes(el)) { | ||
return (el.tagName.toLowerCase() | ||
+ (['INPUT', 'BUTTON'].includes(el.tagName) | ||
? `[type='${el.getAttribute('type') || ''}']` | ||
: '')); | ||
} | ||
if (walk(element, isButton)) return 'button'; | ||
return element.tagName.toLowerCase().match(/^(a|img|video)$/) && element.tagName.toLowerCase(); | ||
if (walk(el, isButton)) return 'button'; | ||
return el.tagName.toLowerCase().match(/^(a|img|video)$/) && el.tagName.toLowerCase(); | ||
} | ||
function getSourceIdentifier(element) { | ||
if (element.id) return `#${element.id}`; | ||
if (element.getAttribute('data-block-name')) return `.${element.getAttribute('data-block-name')}`; | ||
return (element.classList.length > 0 && `.${element.classList[0]}`); | ||
function getSourceIdentifier(el) { | ||
if (el.id) return `#${el.id}`; | ||
if (el.getAttribute('data-block-name')) return `.${el.getAttribute('data-block-name')}`; | ||
return (el.classList.length > 0 && `.${el.classList[0]}`); | ||
} | ||
const sourceSelector = (element) => { | ||
const sourceSelector = (el) => { | ||
try { | ||
if (!element || element === document.body || element === document.documentElement) { | ||
if (!el || el === document.body || el === document.documentElement) { | ||
return undefined; | ||
} | ||
if (element.getAttribute('data-rum-source')) { | ||
return element.getAttribute('data-rum-source'); | ||
if (el.getAttribute('data-rum-source')) { | ||
return el.getAttribute('data-rum-source'); | ||
} | ||
const context = getSourceContext(element.parentElement) || ''; | ||
const elementName = getSourceElement(element) || ''; | ||
const identifier = getSourceIdentifier(element) || ''; | ||
return `${context} ${elementName}${identifier}`.trim() || `"${element.textContent.substring(0, 10)}"`; | ||
const ctx = getSourceContext(el.parentElement) || ''; | ||
const name = getSourceElement(el) || ''; | ||
const id = getSourceIdentifier(el) || ''; | ||
return `${ctx} ${name}${id}`.trim() || `"${el.textContent.substring(0, 10)}"`; | ||
} catch (error) { | ||
@@ -138,3 +139,3 @@ return null; | ||
} | ||
let consentMutationObserver; | ||
let consentMO; | ||
const trackShowConsent = () => { | ||
@@ -148,4 +149,4 @@ const otsdk = document.querySelector('body > div#onetrust-consent-sdk'); | ||
} | ||
if (consentMutationObserver) { | ||
consentMutationObserver.disconnect(); | ||
if (consentMO) { | ||
consentMO.disconnect(); | ||
} | ||
@@ -157,7 +158,7 @@ return true; | ||
if (!trackShowConsent()) { | ||
consentMutationObserver = window.MutationObserver | ||
consentMO = window.MutationObserver | ||
? new MutationObserver(trackShowConsent) | ||
: null; | ||
if (consentMutationObserver) { | ||
consentMutationObserver.observe( | ||
if (consentMO) { | ||
consentMO.observe( | ||
document.body, | ||
@@ -206,6 +207,5 @@ { attributes: false, childList: true, subtree: false }, | ||
: {}; | ||
const formSubmitListener = (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) }); | ||
const blocksMutationObserver = window.MutationObserver ? new MutationObserver(blocksMutationsCallback) | ||
const blocksMO = window.MutationObserver ? new MutationObserver(blocksMCB) | ||
: {}; | ||
const mediaMutationObserver = window.MutationObserver ? new MutationObserver(mediaMutationsCallback) | ||
const mediaMO = window.MutationObserver ? new MutationObserver(mediaMCB) | ||
: {}; | ||
@@ -303,6 +303,6 @@ function trackCheckpoint(checkpoint, data, t) { | ||
new PerformanceObserver((list) => list | ||
.getEntries().map((entry) => navigate( | ||
.getEntries().map((e) => navigate( | ||
window.hlx.referrer || document.referrer, | ||
entry.type, | ||
entry.redirectCount, | ||
e.type, | ||
e.redirectCount, | ||
))) | ||
@@ -315,12 +315,12 @@ .observe({ type: 'navigation', buffered: true }); | ||
list.getEntries() | ||
.filter((entry) => !entry.responseStatus || entry.responseStatus < 400) | ||
.filter((entry) => window.location.hostname === new URL(entry.name).hostname) | ||
.filter((entry) => new URL(entry.name).pathname.match('.*(\\.plain\\.html$|\\.json|graphql|api)')) | ||
.forEach((entry) => { | ||
sampleRUM('loadresource', { source: entry.name, target: Math.round(entry.duration) }); | ||
.filter((e) => !e.responseStatus || e.responseStatus < 400) | ||
.filter((e) => window.location.hostname === new URL(e.name).hostname) | ||
.filter((e) => new URL(e.name).pathname.match('.*(\\.plain\\.html$|\\.json|graphql|api)')) | ||
.forEach((e) => { | ||
sampleRUM('loadresource', { source: e.name, target: Math.round(e.duration) }); | ||
}); | ||
list.getEntries() | ||
.filter((entry) => entry.responseStatus === 404) | ||
.forEach((entry) => { | ||
sampleRUM('missingresource', { source: entry.name, target: entry.hostname }); | ||
.filter((e) => e.responseStatus === 404) | ||
.forEach((e) => { | ||
sampleRUM('missingresource', { source: e.name, target: e.hostname }); | ||
}); | ||
@@ -332,8 +332,8 @@ } catch (error) { | ||
} | ||
function activateBlocksMutationObserver() { | ||
if (!blocksMutationObserver || blocksMutationObserver.active) { | ||
function activateBlocksMO() { | ||
if (!blocksMO || blocksMO.active) { | ||
return; | ||
} | ||
blocksMutationObserver.active = true; | ||
blocksMutationObserver.observe( | ||
blocksMO.active = true; | ||
blocksMO.observe( | ||
document.body, | ||
@@ -343,8 +343,8 @@ { subtree: true, attributes: true, attributeFilter: ['data-block-status'] }, | ||
} | ||
function activateMediaMutationObserver() { | ||
if (!mediaMutationObserver || mediaMutationObserver.active) { | ||
function activateMediaMO() { | ||
if (!mediaMO || mediaMO.active) { | ||
return; | ||
} | ||
mediaMutationObserver.active = true; | ||
mediaMutationObserver.observe( | ||
mediaMO.active = true; | ||
mediaMO.observe( | ||
document.body, | ||
@@ -358,12 +358,12 @@ { subtree: true, attributes: false, childList: true }, | ||
} | ||
activateBlocksMutationObserver(); | ||
activateMediaMutationObserver(); | ||
activateBlocksMO(); | ||
activateMediaMO(); | ||
const observer = new IntersectionObserver((entries) => { | ||
try { | ||
entries | ||
.filter((entry) => entry.isIntersecting) | ||
.forEach((entry) => { | ||
observer.unobserve(entry.target); | ||
const target = targetSelector(entry.target); | ||
const source = sourceSelector(entry.target); | ||
.filter((e) => e.isIntersecting) | ||
.forEach((e) => { | ||
observer.unobserve(e.target); | ||
const target = targetSelector(e.target); | ||
const source = sourceSelector(e.target); | ||
sampleRUM(checkpoint, { target, source }); | ||
@@ -396,7 +396,6 @@ }); | ||
function addFormTracking(parent) { | ||
activateBlocksMutationObserver(); | ||
activateMediaMutationObserver(); | ||
activateBlocksMO(); | ||
activateMediaMO(); | ||
parent.querySelectorAll('form').forEach((form) => { | ||
form.removeEventListener('submit', formSubmitListener); | ||
form.addEventListener('submit', formSubmitListener); | ||
form.addEventListener('submit', (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) }), { once: true }); | ||
}); | ||
@@ -407,3 +406,3 @@ } | ||
} | ||
function blocksMutationsCallback(mutations) { | ||
function blocksMCB(mutations) { | ||
mutations | ||
@@ -417,3 +416,3 @@ .filter((m) => m.type === 'attributes' && m.attributeName === 'data-block-status') | ||
} | ||
function mediaMutationsCallback(mutations) { | ||
function mediaMCB(mutations) { | ||
mutations | ||
@@ -420,0 +419,0 @@ .forEach((m) => { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1194
0
93477