Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@financial-times/o-tracking

Package Overview
Dependencies
Maintainers
14
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@financial-times/o-tracking - npm Package Compare versions

Comparing version 1.4.3 to 1.5.0

dist/javascript/events/component-view.js

22

browser.js
/*global require, module */
'use strict'; // eslint-disable-line strict
const settings = require("./dist/javascript/core/settings.js");
const settings = require("./dist/javascript/core/settings");
const user = require("./dist/javascript/core/user.js");
const user = require("./dist/javascript/core/user");
const session = require("./dist/javascript/core/session.js");
const session = require("./dist/javascript/core/session");
const send = require("./dist/javascript/core/send.js");
const send = require("./dist/javascript/core/send");
/**

@@ -87,3 +87,3 @@ * The version of the tracking module.

Tracking.prototype.event = require("./dist/javascript/events/custom.js");
Tracking.prototype.event = require("./dist/javascript/events/custom");
/**

@@ -94,4 +94,10 @@ * Make the page tracking request.

Tracking.prototype.page = require("./dist/javascript/events/page-view.js");
Tracking.prototype.page = require("./dist/javascript/events/page-view");
/**
* To initalise view events for components/elements.
* @see {@link view#init}
*/
Tracking.prototype.view = require("./dist/javascript/events/component-view");
/**
* To initalise click events.

@@ -101,3 +107,3 @@ * @see {@link click#init}

Tracking.prototype.click = require("./dist/javascript/events/click.js");
Tracking.prototype.click = require("./dist/javascript/events/click");
/**

@@ -117,3 +123,3 @@ * Previously, the click handler was initialised as "link".

Tracking.prototype.utils = require("./dist/javascript/utils.js");
Tracking.prototype.utils = require("./dist/javascript/utils");
/**

@@ -120,0 +126,0 @@ * Initialises the Tracking object.

@@ -14,4 +14,5 @@ /*global module, require */

const getTrace = require("../../libs/get-trace");
let internalQueue;
const elementPropertiesToCollect = ["nodeName", "className", "id", "href", "text", "role"];
const eventPropertiesToCollect = ["ctrlKey", "altKey", "shiftKey", "metaKey"]; // Trigger the event tracking

@@ -35,106 +36,2 @@

}
}; // Utility for trimming strings
const sanitise = property => {
return typeof property === 'string' ? property.trim() : property;
}; // For a given container element, get the number of elements that match the
// clicked element (siblings); and the index of the clicked element (position).
const getSiblingsAndPosition = (el, clickedEl, selector) => {
const siblings = Array.from(el.querySelectorAll(selector));
const position = siblings.findIndex(item => item === clickedEl);
if (position === -1) {
return;
}
return {
siblings: siblings.length,
position
};
}; // Get all (sanitised) properties of a given element.
const getAllElementProperties = el => {
return elementPropertiesToCollect.reduce((returnObject, property) => {
if (el[property]) {
returnObject[property] = sanitise(el[property]);
} else if (el.getAttribute(property)) {
returnObject[property] = sanitise(el.getAttribute(property));
} else if (el.hasAttribute(property)) {
returnObject[property] = el.hasAttribute(property);
}
return returnObject;
}, {});
}; // Get some properties of a given element.
const getDomPathProps = (attrs, props) => {
// Collect any attribute that matches given strings.
attrs.filter(attribute => attribute.name.match(/^data-trackable|^data-o-|^aria-/i)).forEach(attribute => {
props[attribute.name] = attribute.value;
});
return props;
}; // Get only the custom data-trackable-context-? properties of a given element
const getContextProps = (attrs, props, isClickedEl) => {
const customProps = {}; // for the clicked element collect properties like className, nodeName
if (isClickedEl) {
elementPropertiesToCollect.forEach(name => {
if (typeof props[name] !== 'undefined' && name !== 'id') {
customProps[name] = props[name];
}
});
} // Collect any attribute that matches given strings.
attrs.filter(attribute => attribute.name.match(/^data-trackable-context-/i)).forEach(attribute => {
customProps[attribute.name.replace('data-trackable-context-', '')] = attribute.value;
});
return customProps;
};
const assignIfUndefined = (subject, target) => {
for (const prop in subject) {
if (!target[prop]) {
target[prop] = subject[prop];
} else {
console.warn(`You can't set a custom property called ${prop}`);
}
}
}; // Trace the clicked element and all of its parents, collecting properties as we go
const getTrace = el => {
const rootEl = document;
const clickedEl = el;
const selector = clickedEl.getAttribute('data-trackable') ? `[data-trackable="${clickedEl.getAttribute('data-trackable')}"]` : clickedEl.nodeName;
const trace = [];
const customContext = {};
while (el && el !== rootEl) {
const props = getAllElementProperties(el);
const attrs = Array.from(el.attributes);
let domPathProps = getDomPathProps(attrs, props); // If the element happens to have a data-trackable attribute, get the siblings
// and position of the clicked element (relative to the current element).
if (domPathProps["data-trackable"]) {
domPathProps = Object.assign(domPathProps, getSiblingsAndPosition(el, clickedEl, selector));
}
trace.push(domPathProps);
const contextProps = getContextProps(attrs, props, el === clickedEl);
assignIfUndefined(contextProps, customContext);
el = el.parentNode;
}
return {
trace,
customContext
};
}; // Get properties for the event (as opposed to properties of the clicked element)

@@ -148,3 +45,3 @@ // Available properties include mouse x- and y co-ordinates, for example.

if (event[property]) {
returnObject[property] = sanitise(event[property]);
returnObject[property] = utils.sanitise(event[property]);
}

@@ -175,3 +72,3 @@ } catch (e) {

context.url = window.document.location.href || null;
assignIfUndefined(customContext, context);
utils.assignIfUndefined(customContext, context);
eventData.context = context; // Merge the event data into the "parent" config data

@@ -178,0 +75,0 @@

@@ -235,2 +235,42 @@ /*global module, require, window */

/**
* Trim strings
* @param {String} str - The string to trim.
* @return {String} The trimmed string.
*/
function sanitise(str) {
return typeof str === 'string' ? str.trim() : str;
}
/**
* Assign the subject value if the target properties are undefined
* @param {Object} subject - assign the value
* @param {Object} target - be assigned the value
* @return
*/
function assignIfUndefined(subject, target) {
for (const prop in subject) {
if (!target[prop]) {
target[prop] = subject[prop];
} else {
console.warn(`You can't set a custom property called ${prop}`);
}
}
}
/**
* Whitelist props
* @param {Object} props - An object whose props need to be whitelisted
* @param {Array} list - A list for whitelisting
* @return
*/
function whitelistProps(props, list) {
return list.reduce((acc, propName) => Object.assign({}, acc, props[propName] ? {
[propName]: props[propName]
} : undefined), {});
}
/**
* Utilities.

@@ -255,3 +295,6 @@ * @alias utils

getValueFromUrl: getValueFromUrl,
getValueFromJsVariable: getValueFromJsVariable
getValueFromJsVariable: getValueFromJsVariable,
sanitise: sanitise,
assignIfUndefined: assignIfUndefined,
whitelistProps: whitelistProps
};

@@ -14,3 +14,5 @@ {

"required": [
"CustomEvent"
"CustomEvent",
"IntersectionObserver",
"IntersectionObserverEntry"
],

@@ -17,0 +19,0 @@ "optional": [

@@ -6,5 +6,6 @@ {

"dist/",
"index.js",
"browser.js",
"src/",
"main*",
"!src/**/*.js",
"main.scss",
"img",

@@ -20,4 +21,9 @@ "*.json",

],
"keywords": [
"origami",
"component",
"ft"
],
"name": "@financial-times/o-tracking",
"version": "1.4.3",
"version": "1.5.0",
"description": "Origami module for FT tracking.",

@@ -31,4 +37,3 @@ "dependencies": {

"origami-build-tools": "^7.2.0"
},
"main": "main.js"
}
}

@@ -64,2 +64,4 @@ # Origami Tracking component [![CircleCI](https://circleci.com/gh/Financial-Times/o-tracking.svg?style=svg&circle-token=bac74d66190dbd699381ab25baab148fb3bb010c)](https://circleci.com/gh/Financial-Times/o-tracking) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](#licence)

oTracking.click.init(category);
// Components/Elements views.
oTracking.view.init({...opts...});
}

@@ -83,2 +85,4 @@ ```

oTracking.click.init(category);
// Components/Elements views.
oTracking.view.init({...opts...});
}

@@ -193,3 +197,22 @@ ```

* Click events [initalised as above](#usage), will populate a `domPathTokens` property. If the clicked element has the `data-trackable` attribute, sibling elements will also be included within `domPathTokens`.
* View events are fired for elements with the `data-o-tracking-view` attribute by default, unless `o-tracking`'s `selector` option is configured. Like click events, view events populate a `domPathTokens` property. To collect data for events, set the `category` option, or provide a callback[`getContextData`]
_Note:_ This feature requires `window.IntersectionObserver` in order to track the events
_Note:_ `getContextData` should be a function which returns `{Object}`. It accepts the viewed element as an argument
```js
const opts = {
category: 'audio', // default: 'component'
selector: '.o-teaser__audio', // default: '[data-o-tracking-view]'
getContextData: (el) => { // default: null
return {
contentId: el.getAttribute('data-id'),
type: 'audio',
subtype: 'podcast',
component: 'teaser'
};
}
}
oTracking.view.init(opts);
```
Events are decorated with config values you pass in via `init()` or `updateConfig()` if they are part of `context`, `user`, or `device` objects. Values passed in as `context` to individual events will override context values from init.

@@ -196,0 +219,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc