Skip to content

Commit

Permalink
Merge branch 'main' into duck-dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
trieloff committed Aug 15, 2024
2 parents 6983cb2 + 92b8da7 commit 6601e1a
Show file tree
Hide file tree
Showing 27 changed files with 2,105 additions and 629 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ logs
test-results.xml
.env
.idea
src
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
npx lint-staged
npm test
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ node_modules/
snykmocha.js
test
test-results.xml
src/index.map.js
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# [2.19.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.18.0...v2.19.0) (2024-08-13)


### Features

* **onetrust:** enable on all domains ([6039f11](https://github.com/adobe/helix-rum-enhancer/commit/6039f1198f6484d623a3e42ffdd24807b6ed7c54))

# [2.18.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.17.1...v2.18.0) (2024-08-08)


### Features

* **loadresource:** include API calls in `loadresouce` requests for content request counting ([45449c2](https://github.com/adobe/helix-rum-enhancer/commit/45449c2e6a1602d80321f4ffa8698cbd116f1383))

## [2.17.1](https://github.com/adobe/helix-rum-enhancer/compare/v2.17.0...v2.17.1) (2024-08-02)


### Bug Fixes

* **loadresource:** fix closing bracket ([0978b71](https://github.com/adobe/helix-rum-enhancer/commit/0978b7138f16421b5eb22c49b3c757116cb7053b))
* **loadresource:** include all JSON resources, and GraphQL resources ([8ebaa97](https://github.com/adobe/helix-rum-enhancer/commit/8ebaa97e844ff605ec2e6a458fc43adc3c5a37dd))

# [2.17.0](https://github.com/adobe/helix-rum-enhancer/compare/v2.16.0...v2.17.0) (2024-07-03)


Expand Down
5 changes: 4 additions & 1 deletion modules/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import { fflags } from './fflags.js';

export const KNOWN_PROPERTIES = ['weight', 'id', 'referer', 'checkpoint', 't', 'source', 'target', 'cwv', 'CLS', 'FID', 'LCP', 'INP', 'TTFB'];
export const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'enterleave', 'viewblock', 'viewmedia', 'loadresource', 'utm', 'paid', 'email'];
export const DEFAULT_TRACKING_EVENTS = ['click', 'cwv', 'form', 'enterleave', 'viewblock', 'viewmedia', 'loadresource', 'utm', 'paid', 'email', 'consent'];
fflags.enabled('example', () => DEFAULT_TRACKING_EVENTS.push('example'));
7 changes: 5 additions & 2 deletions modules/fflags.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
export const fflags = {
has: (flag) => fflags[flag].indexOf(Array.from(window.origin)
.map((a) => a.charCodeAt(0))
.reduce((a, b) => a + b, 1) % 1371) !== -1,
.reduce((a, b) => a + b, 1) % 1371) !== -1
|| !!window.origin.match(/localhost/),
enabled: (flag, callback) => fflags.has(flag) && callback(),
/* c8 ignore next */
disabled: (flag, callback) => !fflags.has(flag) && callback(),
onetrust: [543, 770, 1136],
eagercwv: [683],
example: [543, 770, 1136],
};
168 changes: 42 additions & 126 deletions modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,35 @@
/* eslint-env browser */

import { KNOWN_PROPERTIES, DEFAULT_TRACKING_EVENTS } from './defaults.js';
import { fflags } from './fflags.js';
import { urlSanitizers } from './utils.js';
import { targetSelector, sourceSelector } from './dom.js';
import {
addAdsParametersTracking,
addCookieConsentTracking,
addEmailParameterTracking,
addUTMParametersTracking,
} from './martech.js';
import { fflags } from './fflags.js';

const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum : {};
const { sampleRUM, queue, isSelected } = (window.hlx && window.hlx.rum) ? window.hlx.rum
/* c8 ignore next */ : {};

const formSubmitListener = (e) => sampleRUM('formsubmit', { target: targetSelector(e.target), source: sourceSelector(e.target) });
// eslint-disable-next-line no-use-before-define
const mutationObserver = window.MutationObserver ? new MutationObserver(mutationsCallback) : null;

// eslint-disable-next-line no-unused-vars
function optedIn(checkpoint, data) {
// TODO: check config service to know if
return true;
}
// Gets configured collection from the config service for the current domain
function getCollectionConfig() {
// eslint-disable-next-line max-len
fflags.enabled('onetrust', () => DEFAULT_TRACKING_EVENTS.push('consent'));
return DEFAULT_TRACKING_EVENTS;
}
const mutationObserver = window.MutationObserver ? new MutationObserver(mutationsCallback)
/* c8 ignore next */ : null;

function trackCheckpoint(checkpoint, data, t) {
const { weight, id } = window.hlx.rum;
if (optedIn(checkpoint, data) && isSelected) {
if (isSelected) {
const sendPing = (pdata = data) => {
// eslint-disable-next-line object-curly-newline, max-len
const body = JSON.stringify({ weight, id, referer: urlSanitizers[window.hlx.RUM_MASK_URL || 'path'](), checkpoint, t, ...data }, KNOWN_PROPERTIES);
const { href: url, origin } = new URL(`.rum/${weight}`, sampleRUM.collectBaseURL || sampleRUM.baseURL);
if (window.location.origin === origin) {
const headers = { type: 'application/json' };
navigator.sendBeacon(url, new Blob([body], headers));
/* c8 ignore next 3 */
} else {
navigator.sendBeacon(url, body);
}
Expand Down Expand Up @@ -83,20 +80,23 @@ function addCWVTracking() {
sampleRUM('cwv', data);
};

const featureToggle = () => window.location.hostname === 'blog.adobe.com';
const isEager = (metric) => ['CLS', 'LCP'].includes(metric);

// When loading `web-vitals` using a classic script, all the public
// methods can be found on the `webVitals` global namespace.
['FID', 'INP', 'TTFB', 'CLS', 'LCP'].forEach((metric) => {
const metricFn = window.webVitals[`on${metric}`];
if (typeof metricFn === 'function') {
const opts = isEager(metric) ? { reportAllChanges: featureToggle() } : undefined;
let opts = {};
fflags.enabled('eagercwv', () => {
opts = { reportAllChanges: isEager(metric) };
});
metricFn(storeCWV, opts);
}
});
};
document.head.appendChild(script);
/* c8 ignore next 3 */
} catch (error) {
// something went wrong
}
Expand All @@ -120,19 +120,15 @@ function addEnterLeaveTracking() {
};

new PerformanceObserver((list) => list
.getEntries().map((entry) => navigate(document.referrer, entry.type)))
.getEntries().map((entry) => navigate(window.hlx.referrer || document.referrer, entry.type)))
.observe({ type: 'navigation', buffered: true });

const leave = ((event) => {
try {
if (leave.left || (event.type === 'visibilitychange' && document.visibilityState !== 'hidden')) {
return;
}
leave.left = true;
sampleRUM('leave');
} catch (error) {
// something went wrong
if (leave.left || (event.type === 'visibilitychange' && document.visibilityState !== 'hidden')) {
return;
}
leave.left = true;
sampleRUM('leave');
});
window.addEventListener('visibilitychange', ((event) => leave(event)));
window.addEventListener('pagehide', ((event) => leave(event)));
Expand All @@ -144,7 +140,7 @@ function addLoadResourceTracking() {
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)$'))
.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) });
});
Expand All @@ -153,6 +149,7 @@ function addLoadResourceTracking() {
.forEach((entry) => {
sampleRUM('missingresource', { source: entry.name, target: entry.hostname });
});
/* c8 ignore next 3 */
} catch (error) {
// something went wrong
}
Expand All @@ -173,9 +170,8 @@ function activateBlocksMutationObserver() {
}

function getIntersectionObsever(checkpoint) {
if (!window.IntersectionObserver) {
return null;
}
/* c8 ignore next */
if (!window.IntersectionObserver) return null;
activateBlocksMutationObserver();
const observer = new IntersectionObserver((entries) => {
try {
Expand All @@ -187,6 +183,7 @@ function getIntersectionObsever(checkpoint) {
const source = sourceSelector(entry.target);
sampleRUM(checkpoint, { target, source });
});
/* c8 ignore next 3 */
} catch (error) {
// something went wrong
}
Expand All @@ -212,45 +209,6 @@ function addViewMediaTracking(parent) {
}
}

function addUTMParametersTracking() {
const usp = new URLSearchParams(window.location.search);
[...usp.entries()]
.filter(([key]) => key.startsWith('utm_'))
// exclude keys that may leak PII
.filter(([key]) => key !== 'utm_id')
.filter(([key]) => key !== 'utm_term')
.forEach(([source, target]) => sampleRUM('utm', { source, target }));
}

function addAdsParametersTracking() {
const networks = {
google: /gclid|gclsrc|wbraid|gbraid/,
doubleclick: /dclid/,
microsoft: /msclkid/,
facebook: /fb(cl|ad_|pxl_)id/,
twitter: /tw(clid|src|term)/,
linkedin: /li_fat_id/,
pinterest: /epik/,
tiktok: /ttclid/,
};
const params = Array.from(new URLSearchParams(window.location.search).keys());
Object.entries(networks).forEach(([network, regex]) => {
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('paid', { source: network, target: param }));
});
}

function addEmailParameterTracking() {
const networks = {
mailchimp: /mc_(c|e)id/,
marketo: /mkt_tok/,

};
const params = Array.from(new URLSearchParams(window.location.search).keys());
Object.entries(networks).forEach(([network, regex]) => {
params.filter((param) => regex.test(param)).forEach((param) => sampleRUM('email', { source: network, target: param }));
});
}

function addFormTracking(parent) {
activateBlocksMutationObserver();
parent.querySelectorAll('form').forEach((form) => {
Expand All @@ -259,42 +217,7 @@ function addFormTracking(parent) {
});
}

function addCookieConsentTracking() {
const cmpCookie = document.cookie.split(';')
.map((c) => c.trim())
.find((cookie) => cookie.startsWith('OptanonAlertBoxClosed='));

if (cmpCookie) {
sampleRUM('consent', { source: 'onetrust', target: 'hidden' });
return;
}

let consentMutationObserver;
const trackShowConsent = () => {
if (document.querySelector('body > div#onetrust-consent-sdk')) {
sampleRUM('consent', { source: 'onetrust', target: 'show' });
if (consentMutationObserver) {
consentMutationObserver.disconnect();
}
return true;
}
return false;
};

if (!trackShowConsent()) {
// eslint-disable-next-line max-len
consentMutationObserver = window.MutationObserver ? new MutationObserver(trackShowConsent) : null;
if (consentMutationObserver) {
consentMutationObserver.observe(
document.body,
// eslint-disable-next-line object-curly-newline
{ attributes: false, childList: true, subtree: false },
);
}
}
}

const addObserver = (ck, fn, block) => getCollectionConfig().includes(ck) && fn(block);
const addObserver = (ck, fn, block) => DEFAULT_TRACKING_EVENTS.includes(ck) && fn(block);
function mutationsCallback(mutations) {
mutations.filter((m) => m.type === 'attributes' && m.attributeName === 'data-block-status')
.filter((m) => m.target.dataset.blockStatus === 'loaded')
Expand All @@ -306,26 +229,19 @@ function mutationsCallback(mutations) {
}

function addTrackingFromConfig() {
const trackingFunctions = {
click: () => {
document.addEventListener('click', (event) => {
sampleRUM('click', { target: targetSelector(event.target), source: sourceSelector(event.target) });
});
},
cwv: () => addCWVTracking(),
form: () => addFormTracking(window.document.body),
enterleave: () => addEnterLeaveTracking(),
loadresource: () => addLoadResourceTracking(),
utm: () => addUTMParametersTracking(),
viewblock: () => addViewBlockTracking(window.document.body),
viewmedia: () => addViewMediaTracking(window.document.body),
consent: () => addCookieConsentTracking(),
paid: () => addAdsParametersTracking(),
email: () => addEmailParameterTracking(),
};

getCollectionConfig().filter((ck) => trackingFunctions[ck])
.forEach((ck) => trackingFunctions[ck]());
document.addEventListener('click', (event) => {
sampleRUM('click', { target: targetSelector(event.target), source: sourceSelector(event.target) });
});
addCWVTracking();
addFormTracking(window.document.body);
addEnterLeaveTracking();
addLoadResourceTracking();
addUTMParametersTracking(sampleRUM);
addViewBlockTracking(window.document.body);
addViewMediaTracking(window.document.body);
addCookieConsentTracking(sampleRUM);
addAdsParametersTracking(sampleRUM);
addEmailParameterTracking(sampleRUM);
}

function initEnhancer() {
Expand Down
Loading

0 comments on commit 6601e1a

Please sign in to comment.