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

@datadog/browser-rum-core

Package Overview
Dependencies
Maintainers
1
Versions
179
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@datadog/browser-rum-core - npm Package Compare versions

Comparing version 3.11.0 to 4.0.0

2

cjs/boot/buildEnv.js

@@ -6,4 +6,4 @@ "use strict";

buildMode: 'release',
sdkVersion: '3.11.0',
sdkVersion: '4.0.0',
};
//# sourceMappingURL=buildEnv.js.map

@@ -1,2 +0,2 @@

import { Duration, Omit, RelativeTime } from '@datadog/browser-core';
import { Duration, RelativeTime } from '@datadog/browser-core';
import { RumConfiguration } from '../domain/configuration';

@@ -3,0 +3,0 @@ import { LifeCycle } from '../domain/lifeCycle';

@@ -7,3 +7,8 @@ import { Configuration, DefaultPrivacyLevel, InitConfiguration } from '@datadog/browser-core';

beforeSend?: ((event: RumEvent, context: RumEventDomainContext) => void | boolean) | undefined;
allowedTracingOrigins?: ReadonlyArray<string | RegExp> | undefined;
defaultPrivacyLevel?: DefaultPrivacyLevel | undefined;
replaySampleRate?: number | undefined;
trackInteractions?: boolean | undefined;
actionNameAttribute?: string | undefined;
trackViewsManually?: boolean | undefined;
}

@@ -10,0 +15,0 @@ export declare type HybridInitConfiguration = Omit<RumInitConfiguration, 'applicationId' | 'clientToken'>;

@@ -19,4 +19,4 @@ "use strict";

(userProgrammaticAttribute && getActionNameFromElementProgrammatically(element, userProgrammaticAttribute)) ||
getActionNameFromElementForStrategies(element, priorityStrategies) ||
getActionNameFromElementForStrategies(element, fallbackStrategies) ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, priorityStrategies) ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, fallbackStrategies) ||
'');

@@ -52,3 +52,3 @@ }

// associated LABEL text
function (element) {
function (element, userProgrammaticAttribute) {
// IE does not support element.labels, so we fallback to a CSS selector based on the element id

@@ -58,3 +58,3 @@ // instead

if ('labels' in element && element.labels && element.labels.length > 0) {
return getTextualContent(element.labels[0]);
return getTextualContent(element.labels[0], userProgrammaticAttribute);
}

@@ -64,3 +64,3 @@ }

var label = element.ownerDocument && element.ownerDocument.querySelector("label[for=\"" + element.id.replace('"', '\\"') + "\"]");
return label && getTextualContent(label);
return label && getTextualContent(label, userProgrammaticAttribute);
}

@@ -79,5 +79,5 @@ },

// BUTTON, LABEL or button-like element text
function (element) {
function (element, userProgrammaticAttribute) {
if (element.nodeName === 'BUTTON' || element.nodeName === 'LABEL' || element.getAttribute('role') === 'button') {
return getTextualContent(element);
return getTextualContent(element, userProgrammaticAttribute);
}

@@ -87,3 +87,3 @@ },

// associated element text designated by the aria-labelledby attribute
function (element) {
function (element, userProgrammaticAttribute) {
var labelledByAttribute = element.getAttribute('aria-labelledby');

@@ -95,3 +95,3 @@ if (labelledByAttribute) {

.filter(function (label) { return Boolean(label); })
.map(getTextualContent)
.map(function (element) { return getTextualContent(element, userProgrammaticAttribute); })
.join(' ');

@@ -105,9 +105,11 @@ }

// SELECT first OPTION text
function (element) {
function (element, userProgrammaticAttribute) {
if ('options' in element && element.options.length > 0) {
return getTextualContent(element.options[0]);
return getTextualContent(element.options[0], userProgrammaticAttribute);
}
},
];
var fallbackStrategies = [function (element) { return getTextualContent(element); }];
var fallbackStrategies = [
function (element, userProgrammaticAttribute) { return getTextualContent(element, userProgrammaticAttribute); },
];
/**

@@ -118,3 +120,3 @@ * Iterates over the target element and its parent, using the strategies list to get an action name.

var MAX_PARENTS_TO_CONSIDER = 10;
function getActionNameFromElementForStrategies(targetElement, strategies) {
function getActionNameFromElementForStrategies(targetElement, userProgrammaticAttribute, strategies) {
var element = targetElement;

@@ -129,3 +131,3 @@ var recursionCounter = 0;

var strategy = strategies_1[_i];
var name_1 = strategy(element);
var name_1 = strategy(element, userProgrammaticAttribute);
if (typeof name_1 === 'string') {

@@ -158,3 +160,3 @@ var trimmedName = name_1.trim();

}
function getTextualContent(element) {
function getTextualContent(element, userProgrammaticAttribute) {
if (element.isContentEditable) {

@@ -164,16 +166,26 @@ return;

if ('innerText' in element) {
var text = element.innerText;
var text_1 = element.innerText;
var replaceTextFromElements = function (query, replacer) {
var list = element.querySelectorAll(query);
for (var index = 0; index < list.length; index += 1) {
var element_1 = list[index];
if ('innerText' in element_1) {
var textToReplace = element_1.innerText;
if (textToReplace && textToReplace.trim().length > 0) {
text_1 = text_1.replace(textToReplace, replacer(element_1));
}
}
}
};
if (!supportsInnerTextScriptAndStyleRemoval()) {
// remove the inner text of SCRIPT and STYLES from the result. This is a bit dirty, but should
// be relatively fast and work in most cases.
var elementsTextToRemove = element.querySelectorAll('script, style');
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (var i = 0; i < elementsTextToRemove.length; i += 1) {
var innerText = elementsTextToRemove[i].innerText;
if (innerText.trim().length > 0) {
text = text.replace(innerText, '');
}
}
replaceTextFromElements('script, style', function () { return ''; });
}
return text;
// replace the text of elements with their programmatic attribute value
replaceTextFromElements("[" + DEFAULT_PROGRAMMATIC_ATTRIBUTE + "]", function (element) { return element.getAttribute(DEFAULT_PROGRAMMATIC_ATTRIBUTE); });
if (userProgrammaticAttribute) {
replaceTextFromElements("[" + userProgrammaticAttribute + "]", function (element) { return element.getAttribute(userProgrammaticAttribute); });
}
return text_1;
}

@@ -180,0 +192,0 @@ return element.textContent;

/**
* Keep these types in a separate file in order to reference it from the official doc
*/
import { Omit } from '@datadog/browser-core';
import { RumEventType } from './rawRumEvent.types';

@@ -6,0 +5,0 @@ export declare type RumEventDomainContext<T extends RumEventType = any> = T extends RumEventType.VIEW ? RumViewEventDomainContext : T extends RumEventType.ACTION ? RumActionEventDomainContext : T extends RumEventType.RESOURCE ? RumFetchResourceEventDomainContext | RumXhrResourceEventDomainContext | RumOtherResourceEventDomainContext : T extends RumEventType.ERROR ? RumErrorEventDomainContext : T extends RumEventType.LONG_TASK ? RumLongTaskEventDomainContext : never;

export var buildEnv = {
buildMode: 'release',
sdkVersion: '3.11.0',
sdkVersion: '4.0.0',
};
//# sourceMappingURL=buildEnv.js.map

@@ -1,2 +0,2 @@

import { Duration, Omit, RelativeTime } from '@datadog/browser-core';
import { Duration, RelativeTime } from '@datadog/browser-core';
import { RumConfiguration } from '../domain/configuration';

@@ -3,0 +3,0 @@ import { LifeCycle } from '../domain/lifeCycle';

@@ -7,3 +7,8 @@ import { Configuration, DefaultPrivacyLevel, InitConfiguration } from '@datadog/browser-core';

beforeSend?: ((event: RumEvent, context: RumEventDomainContext) => void | boolean) | undefined;
allowedTracingOrigins?: ReadonlyArray<string | RegExp> | undefined;
defaultPrivacyLevel?: DefaultPrivacyLevel | undefined;
replaySampleRate?: number | undefined;
trackInteractions?: boolean | undefined;
actionNameAttribute?: string | undefined;
trackViewsManually?: boolean | undefined;
}

@@ -10,0 +15,0 @@ export declare type HybridInitConfiguration = Omit<RumInitConfiguration, 'applicationId' | 'clientToken'>;

@@ -16,4 +16,4 @@ import { safeTruncate, isIE } from '@datadog/browser-core';

(userProgrammaticAttribute && getActionNameFromElementProgrammatically(element, userProgrammaticAttribute)) ||
getActionNameFromElementForStrategies(element, priorityStrategies) ||
getActionNameFromElementForStrategies(element, fallbackStrategies) ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, priorityStrategies) ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, fallbackStrategies) ||
'');

@@ -48,3 +48,3 @@ }

// associated LABEL text
function (element) {
function (element, userProgrammaticAttribute) {
// IE does not support element.labels, so we fallback to a CSS selector based on the element id

@@ -54,3 +54,3 @@ // instead

if ('labels' in element && element.labels && element.labels.length > 0) {
return getTextualContent(element.labels[0]);
return getTextualContent(element.labels[0], userProgrammaticAttribute);
}

@@ -60,3 +60,3 @@ }

var label = element.ownerDocument && element.ownerDocument.querySelector("label[for=\"" + element.id.replace('"', '\\"') + "\"]");
return label && getTextualContent(label);
return label && getTextualContent(label, userProgrammaticAttribute);
}

@@ -75,5 +75,5 @@ },

// BUTTON, LABEL or button-like element text
function (element) {
function (element, userProgrammaticAttribute) {
if (element.nodeName === 'BUTTON' || element.nodeName === 'LABEL' || element.getAttribute('role') === 'button') {
return getTextualContent(element);
return getTextualContent(element, userProgrammaticAttribute);
}

@@ -83,3 +83,3 @@ },

// associated element text designated by the aria-labelledby attribute
function (element) {
function (element, userProgrammaticAttribute) {
var labelledByAttribute = element.getAttribute('aria-labelledby');

@@ -91,3 +91,3 @@ if (labelledByAttribute) {

.filter(function (label) { return Boolean(label); })
.map(getTextualContent)
.map(function (element) { return getTextualContent(element, userProgrammaticAttribute); })
.join(' ');

@@ -101,9 +101,11 @@ }

// SELECT first OPTION text
function (element) {
function (element, userProgrammaticAttribute) {
if ('options' in element && element.options.length > 0) {
return getTextualContent(element.options[0]);
return getTextualContent(element.options[0], userProgrammaticAttribute);
}
},
];
var fallbackStrategies = [function (element) { return getTextualContent(element); }];
var fallbackStrategies = [
function (element, userProgrammaticAttribute) { return getTextualContent(element, userProgrammaticAttribute); },
];
/**

@@ -114,3 +116,3 @@ * Iterates over the target element and its parent, using the strategies list to get an action name.

var MAX_PARENTS_TO_CONSIDER = 10;
function getActionNameFromElementForStrategies(targetElement, strategies) {
function getActionNameFromElementForStrategies(targetElement, userProgrammaticAttribute, strategies) {
var element = targetElement;

@@ -125,3 +127,3 @@ var recursionCounter = 0;

var strategy = strategies_1[_i];
var name_1 = strategy(element);
var name_1 = strategy(element, userProgrammaticAttribute);
if (typeof name_1 === 'string') {

@@ -154,3 +156,3 @@ var trimmedName = name_1.trim();

}
function getTextualContent(element) {
function getTextualContent(element, userProgrammaticAttribute) {
if (element.isContentEditable) {

@@ -160,16 +162,26 @@ return;

if ('innerText' in element) {
var text = element.innerText;
var text_1 = element.innerText;
var replaceTextFromElements = function (query, replacer) {
var list = element.querySelectorAll(query);
for (var index = 0; index < list.length; index += 1) {
var element_1 = list[index];
if ('innerText' in element_1) {
var textToReplace = element_1.innerText;
if (textToReplace && textToReplace.trim().length > 0) {
text_1 = text_1.replace(textToReplace, replacer(element_1));
}
}
}
};
if (!supportsInnerTextScriptAndStyleRemoval()) {
// remove the inner text of SCRIPT and STYLES from the result. This is a bit dirty, but should
// be relatively fast and work in most cases.
var elementsTextToRemove = element.querySelectorAll('script, style');
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (var i = 0; i < elementsTextToRemove.length; i += 1) {
var innerText = elementsTextToRemove[i].innerText;
if (innerText.trim().length > 0) {
text = text.replace(innerText, '');
}
}
replaceTextFromElements('script, style', function () { return ''; });
}
return text;
// replace the text of elements with their programmatic attribute value
replaceTextFromElements("[" + DEFAULT_PROGRAMMATIC_ATTRIBUTE + "]", function (element) { return element.getAttribute(DEFAULT_PROGRAMMATIC_ATTRIBUTE); });
if (userProgrammaticAttribute) {
replaceTextFromElements("[" + userProgrammaticAttribute + "]", function (element) { return element.getAttribute(userProgrammaticAttribute); });
}
return text_1;
}

@@ -176,0 +188,0 @@ return element.textContent;

/**
* Keep these types in a separate file in order to reference it from the official doc
*/
import { Omit } from '@datadog/browser-core';
import { RumEventType } from './rawRumEvent.types';

@@ -6,0 +5,0 @@ export declare type RumEventDomainContext<T extends RumEventType = any> = T extends RumEventType.VIEW ? RumViewEventDomainContext : T extends RumEventType.ACTION ? RumActionEventDomainContext : T extends RumEventType.RESOURCE ? RumFetchResourceEventDomainContext | RumXhrResourceEventDomainContext | RumOtherResourceEventDomainContext : T extends RumEventType.ERROR ? RumErrorEventDomainContext : T extends RumEventType.LONG_TASK ? RumLongTaskEventDomainContext : never;

{
"name": "@datadog/browser-rum-core",
"version": "3.11.0",
"version": "4.0.0",
"license": "Apache-2.0",

@@ -15,3 +15,3 @@ "main": "cjs/index.js",

"dependencies": {
"@datadog/browser-core": "3.11.0",
"@datadog/browser-core": "4.0.0",
"tslib": "^1.10.0"

@@ -27,3 +27,3 @@ },

},
"gitHead": "31f3be59b072670e62fc1e2782a6210ad1d73a17"
"gitHead": "ee27a2d662363f3de31a12f756abf05f080134d8"
}

@@ -8,3 +8,2 @@ import {

monitor,
Omit,
relativeNow,

@@ -11,0 +10,0 @@ RelativeTime,

@@ -9,3 +9,2 @@ import {

display,
BeforeSendCallback,
RawError,

@@ -142,3 +141,3 @@ createEventRateLimiter,

event: RumEvent & Context,
beforeSend: BeforeSendCallback | undefined,
beforeSend: RumConfiguration['beforeSend'],
domainContext: RumEventDomainContext,

@@ -145,0 +144,0 @@ eventRateLimiters: { [key in RumEventType]?: EventRateLimiter }

@@ -15,5 +15,19 @@ import {

export interface RumInitConfiguration extends InitConfiguration {
// global options
applicationId: string
beforeSend?: ((event: RumEvent, context: RumEventDomainContext) => void | boolean) | undefined
// tracing options
allowedTracingOrigins?: ReadonlyArray<string | RegExp> | undefined
// replay options
defaultPrivacyLevel?: DefaultPrivacyLevel | undefined
replaySampleRate?: number | undefined
// action options
trackInteractions?: boolean | undefined
actionNameAttribute?: string | undefined
// view options
trackViewsManually?: boolean | undefined
}

@@ -20,0 +34,0 @@

@@ -311,3 +311,15 @@ import { getActionNameFromElement } from './getActionNameFromElement'

})
it('replaces the programmatic action name in textual content', () => {
expect(getActionNameFromElement(element`<div>Foo <div data-dd-action-name="custom action">bar<div></div>`)).toBe(
'Foo custom action'
)
})
it('replaces the programmatic action name in textual content based on the user-configured attribute', () => {
expect(
getActionNameFromElement(element`<div>Foo <div data-test-id="custom action">bar<div></div>`, 'data-test-id')
).toBe('Foo custom action')
})
})
})

@@ -19,4 +19,4 @@ import { safeTruncate, isIE } from '@datadog/browser-core'

(userProgrammaticAttribute && getActionNameFromElementProgrammatically(element, userProgrammaticAttribute)) ||
getActionNameFromElementForStrategies(element, priorityStrategies) ||
getActionNameFromElementForStrategies(element, fallbackStrategies) ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, priorityStrategies) ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, fallbackStrategies) ||
''

@@ -52,7 +52,10 @@ )

type NameStrategy = (element: Element | HTMLElement | HTMLInputElement | HTMLSelectElement) => string | undefined | null
type NameStrategy = (
element: Element | HTMLElement | HTMLInputElement | HTMLSelectElement,
userProgrammaticAttribute: string | undefined
) => string | undefined | null
const priorityStrategies: NameStrategy[] = [
// associated LABEL text
(element) => {
(element, userProgrammaticAttribute) => {
// IE does not support element.labels, so we fallback to a CSS selector based on the element id

@@ -62,3 +65,3 @@ // instead

if ('labels' in element && element.labels && element.labels.length > 0) {
return getTextualContent(element.labels[0])
return getTextualContent(element.labels[0], userProgrammaticAttribute)
}

@@ -68,3 +71,3 @@ } else if (element.id) {

element.ownerDocument && element.ownerDocument.querySelector(`label[for="${element.id.replace('"', '\\"')}"]`)
return label && getTextualContent(label)
return label && getTextualContent(label, userProgrammaticAttribute)
}

@@ -83,5 +86,5 @@ },

// BUTTON, LABEL or button-like element text
(element) => {
(element, userProgrammaticAttribute) => {
if (element.nodeName === 'BUTTON' || element.nodeName === 'LABEL' || element.getAttribute('role') === 'button') {
return getTextualContent(element)
return getTextualContent(element, userProgrammaticAttribute)
}

@@ -91,3 +94,3 @@ },

// associated element text designated by the aria-labelledby attribute
(element) => {
(element, userProgrammaticAttribute) => {
const labelledByAttribute = element.getAttribute('aria-labelledby')

@@ -99,3 +102,3 @@ if (labelledByAttribute) {

.filter((label): label is HTMLElement => Boolean(label))
.map(getTextualContent)
.map((element) => getTextualContent(element, userProgrammaticAttribute))
.join(' ')

@@ -109,5 +112,5 @@ }

// SELECT first OPTION text
(element) => {
(element, userProgrammaticAttribute) => {
if ('options' in element && element.options.length > 0) {
return getTextualContent(element.options[0])
return getTextualContent(element.options[0], userProgrammaticAttribute)
}

@@ -117,3 +120,5 @@ },

const fallbackStrategies: NameStrategy[] = [(element) => getTextualContent(element)]
const fallbackStrategies: NameStrategy[] = [
(element, userProgrammaticAttribute) => getTextualContent(element, userProgrammaticAttribute),
]

@@ -125,3 +130,7 @@ /**

const MAX_PARENTS_TO_CONSIDER = 10
function getActionNameFromElementForStrategies(targetElement: Element, strategies: NameStrategy[]) {
function getActionNameFromElementForStrategies(
targetElement: Element,
userProgrammaticAttribute: string | undefined,
strategies: NameStrategy[]
) {
let element: Element | null = targetElement

@@ -137,3 +146,3 @@ let recursionCounter = 0

for (const strategy of strategies) {
const name = strategy(element)
const name = strategy(element, userProgrammaticAttribute)
if (typeof name === 'string') {

@@ -170,3 +179,3 @@ const trimmedName = name.trim()

function getTextualContent(element: Element | HTMLElement) {
function getTextualContent(element: Element | HTMLElement, userProgrammaticAttribute: string | undefined) {
if ((element as HTMLElement).isContentEditable) {

@@ -178,14 +187,35 @@ return

let text = element.innerText
const replaceTextFromElements = (query: string, replacer: (element: Element) => string) => {
const list = element.querySelectorAll<Element | HTMLElement>(query)
for (let index = 0; index < list.length; index += 1) {
const element = list[index]
if ('innerText' in element) {
const textToReplace = element.innerText
if (textToReplace && textToReplace.trim().length > 0) {
text = text.replace(textToReplace, replacer(element))
}
}
}
}
if (!supportsInnerTextScriptAndStyleRemoval()) {
// remove the inner text of SCRIPT and STYLES from the result. This is a bit dirty, but should
// be relatively fast and work in most cases.
const elementsTextToRemove: NodeListOf<HTMLElement> = element.querySelectorAll('script, style')
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < elementsTextToRemove.length; i += 1) {
const innerText = elementsTextToRemove[i].innerText
if (innerText.trim().length > 0) {
text = text.replace(innerText, '')
}
}
replaceTextFromElements('script, style', () => '')
}
// replace the text of elements with their programmatic attribute value
replaceTextFromElements(
`[${DEFAULT_PROGRAMMATIC_ATTRIBUTE}]`,
(element) => element.getAttribute(DEFAULT_PROGRAMMATIC_ATTRIBUTE)!
)
if (userProgrammaticAttribute) {
replaceTextFromElements(
`[${userProgrammaticAttribute}]`,
(element) => element.getAttribute(userProgrammaticAttribute)!
)
}
return text

@@ -192,0 +222,0 @@ }

@@ -5,3 +5,2 @@ /**

import { Omit } from '@datadog/browser-core'
import { RumEventType } from './rawRumEvent.types'

@@ -8,0 +7,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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