@datadog/browser-rum-core
Advanced tools
Comparing version 5.31.1 to 5.32.0
@@ -99,3 +99,3 @@ "use strict"; | ||
} | ||
(0, plugins_1.callPluginsMethod)(initConfiguration.betaPlugins, 'onInit', { initConfiguration: initConfiguration, publicApi: publicApi }); | ||
(0, plugins_1.callPluginsMethod)(initConfiguration.plugins, 'onInit', { initConfiguration: initConfiguration, publicApi: publicApi }); | ||
if (initConfiguration.remoteConfigurationId && | ||
@@ -102,0 +102,0 @@ (0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.REMOTE_CONFIGURATION)) { |
@@ -47,2 +47,5 @@ "use strict"; | ||
position: action.position, | ||
name_source: (0, browser_core_1.isExperimentalFeatureEnabled)(browser_core_1.ExperimentalFeature.ACTION_NAME_MASKING) | ||
? action.nameSource | ||
: undefined, | ||
}, | ||
@@ -49,0 +52,0 @@ }, |
@@ -9,2 +9,14 @@ import { NodePrivacyLevel } from '../privacy'; | ||
export declare const ACTION_NAME_PLACEHOLDER = "Masked Element"; | ||
export declare function getActionNameFromElement(element: Element, { enablePrivacyForActionName, actionNameAttribute: userProgrammaticAttribute }: RumConfiguration, nodePrivacyLevel?: NodePrivacyLevel): string; | ||
export declare const enum ActionNameSource { | ||
CUSTOM_ATTRIBUTE = "custom_attribute", | ||
MASK_PLACEHOLDER = "mask_placeholder", | ||
TEXT_CONTENT = "text_content", | ||
STANDARD_ATTRIBUTE = "standard_attribute", | ||
BLANK = "blank" | ||
} | ||
type ActionName = { | ||
name: string; | ||
nameSource: ActionNameSource; | ||
}; | ||
export declare function getActionNameFromElement(element: Element, { enablePrivacyForActionName, actionNameAttribute: userProgrammaticAttribute }: RumConfiguration, nodePrivacyLevel?: NodePrivacyLevel): ActionName; | ||
export {}; |
@@ -18,4 +18,5 @@ "use strict"; | ||
// * first, get the name programmatically, explicitly defined by the user. | ||
// * then, use strategies that are known to return good results. Those strategies will be used on | ||
// the element and a few parents, but it's likely that they won't succeed at all. | ||
// * then, if privacy is set to mask, return a placeholder for the undefined. | ||
// * if privacy is not set to mask, use strategies that are known to return good results. | ||
// Those strategies will be used on the element and a few parents, but it's likely that they won't succeed at all. | ||
// * if no name is found this way, use strategies returning less accurate names as a fallback. | ||
@@ -25,9 +26,10 @@ // Those are much likely to succeed. | ||
(userProgrammaticAttribute && getActionNameFromElementProgrammatically(element, userProgrammaticAttribute)); | ||
if (nodePrivacyLevel === privacy_1.NodePrivacyLevel.MASK) { | ||
return defaultActionName || exports.ACTION_NAME_PLACEHOLDER; | ||
if (defaultActionName) { | ||
return { name: defaultActionName, nameSource: "custom_attribute" /* ActionNameSource.CUSTOM_ATTRIBUTE */ }; | ||
} | ||
return (defaultActionName || | ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, priorityStrategies, enablePrivacyForActionName) || | ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, fallbackStrategies, enablePrivacyForActionName) || | ||
''); | ||
else if (nodePrivacyLevel === privacy_1.NodePrivacyLevel.MASK) { | ||
return { name: exports.ACTION_NAME_PLACEHOLDER, nameSource: "mask_placeholder" /* ActionNameSource.MASK_PLACEHOLDER */ }; | ||
} | ||
return (getActionNameFromElementForStrategies(element, userProgrammaticAttribute, priorityStrategies, enablePrivacyForActionName) || | ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, fallbackStrategies, enablePrivacyForActionName) || { name: '', nameSource: "blank" /* ActionNameSource.BLANK */ }); | ||
} | ||
@@ -66,3 +68,3 @@ function getActionNameFromElementProgrammatically(targetElement, programmaticAttribute) { | ||
if ('labels' in element && element.labels && element.labels.length > 0) { | ||
return getTextualContent(element.labels[0], userProgrammaticAttribute); | ||
return getActionNameFromTextualContent(element.labels[0], userProgrammaticAttribute); | ||
} | ||
@@ -73,3 +75,3 @@ } | ||
(0, browser_core_1.find)(element.ownerDocument.querySelectorAll('label'), function (label) { return label.htmlFor === element.id; }); | ||
return label && getTextualContent(label, userProgrammaticAttribute, privacy); | ||
return label && getActionNameFromTextualContent(label, userProgrammaticAttribute, privacy); | ||
} | ||
@@ -83,3 +85,3 @@ }, | ||
if (type === 'button' || type === 'submit' || type === 'reset') { | ||
return input.value; | ||
return { name: input.value, nameSource: "text_content" /* ActionNameSource.TEXT_CONTENT */ }; | ||
} | ||
@@ -91,6 +93,6 @@ } | ||
if (element.nodeName === 'BUTTON' || element.nodeName === 'LABEL' || element.getAttribute('role') === 'button') { | ||
return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
return getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
} | ||
}, | ||
function (element) { return element.getAttribute('aria-label'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'aria-label'); }, | ||
// associated element text designated by the aria-labelledby attribute | ||
@@ -100,18 +102,21 @@ function (element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
if (labelledByAttribute) { | ||
return labelledByAttribute | ||
.split(/\s+/) | ||
.map(function (id) { return getElementById(element, id); }) | ||
.filter(function (label) { return Boolean(label); }) | ||
.map(function (element) { return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); }) | ||
.join(' '); | ||
return { | ||
name: labelledByAttribute | ||
.split(/\s+/) | ||
.map(function (id) { return getElementById(element, id); }) | ||
.filter(function (label) { return Boolean(label); }) | ||
.map(function (element) { return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); }) | ||
.join(' '), | ||
nameSource: "text_content" /* ActionNameSource.TEXT_CONTENT */, | ||
}; | ||
} | ||
}, | ||
function (element) { return element.getAttribute('alt'); }, | ||
function (element) { return element.getAttribute('name'); }, | ||
function (element) { return element.getAttribute('title'); }, | ||
function (element) { return element.getAttribute('placeholder'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'alt'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'name'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'title'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'placeholder'); }, | ||
// SELECT first OPTION text | ||
function (element, userProgrammaticAttribute) { | ||
if ('options' in element && element.options.length > 0) { | ||
return getTextualContent(element.options[0], userProgrammaticAttribute); | ||
return getActionNameFromTextualContent(element.options[0], userProgrammaticAttribute); | ||
} | ||
@@ -122,3 +127,3 @@ }, | ||
function (element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
return getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
}, | ||
@@ -141,7 +146,8 @@ ]; | ||
var strategy = strategies_1[_i]; | ||
var name_1 = strategy(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
if (typeof name_1 === 'string') { | ||
var trimmedName = name_1.trim(); | ||
var actionName = strategy(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
if (actionName) { | ||
var name_1 = actionName.name, nameSource = actionName.nameSource; | ||
var trimmedName = name_1 && name_1.trim(); | ||
if (trimmedName) { | ||
return truncate(normalizeWhitespace(trimmedName)); | ||
return { name: truncate(normalizeWhitespace(trimmedName)), nameSource: nameSource }; | ||
} | ||
@@ -170,2 +176,14 @@ } | ||
} | ||
function getActionNameFromStandardAttribute(element, attribute) { | ||
return { | ||
name: element.getAttribute(attribute) || '', | ||
nameSource: "standard_attribute" /* ActionNameSource.STANDARD_ATTRIBUTE */, | ||
}; | ||
} | ||
function getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
return { | ||
name: getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) || '', | ||
nameSource: "text_content" /* ActionNameSource.TEXT_CONTENT */, | ||
}; | ||
} | ||
function getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
@@ -172,0 +190,0 @@ if (element.isContentEditable) { |
@@ -17,2 +17,3 @@ import type { Duration, ClocksState, RelativeTime, TimeStamp, ValueHistory } from '@datadog/browser-core'; | ||
name: string; | ||
nameSource: string; | ||
target?: { | ||
@@ -43,3 +44,3 @@ selector: string | undefined; | ||
}; | ||
type ClickActionBase = Pick<ClickAction, 'type' | 'name' | 'target' | 'position'>; | ||
type ClickActionBase = Pick<ClickAction, 'type' | 'name' | 'nameSource' | 'target' | 'position'>; | ||
export type Click = ReturnType<typeof newClick>; | ||
@@ -46,0 +47,0 @@ declare function newClick(lifeCycle: LifeCycle, history: ClickActionIdHistory, getUserActivity: () => UserActivity, clickActionBase: ClickActionBase, startEvent: MouseEventOnElement): { |
@@ -123,2 +123,3 @@ "use strict"; | ||
} | ||
var actionName = (0, getActionNameFromElement_1.getActionNameFromElement)(event.target, configuration, nodePrivacyLevel); | ||
return { | ||
@@ -136,3 +137,4 @@ type: "click" /* ActionType.CLICK */, | ||
}, | ||
name: (0, getActionNameFromElement_1.getActionNameFromElement)(event.target, configuration, nodePrivacyLevel), | ||
name: actionName.name, | ||
nameSource: actionName.nameSource, | ||
}; | ||
@@ -139,0 +141,0 @@ } |
@@ -65,3 +65,3 @@ "use strict"; | ||
}, | ||
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "5.31.1" : undefined, | ||
browser_sdk_version: (0, browser_core_1.canUseEventBridge)() ? "5.32.0" : undefined, | ||
}, | ||
@@ -68,0 +68,0 @@ application: { |
@@ -107,3 +107,3 @@ import type { Configuration, InitConfiguration, MatchOption } from '@datadog/browser-core'; | ||
*/ | ||
betaPlugins?: RumPlugin[] | undefined; | ||
plugins?: RumPlugin[] | undefined; | ||
} | ||
@@ -110,0 +110,0 @@ export type HybridInitConfiguration = Omit<RumInitConfiguration, 'applicationId' | 'clientToken'>; |
@@ -55,3 +55,3 @@ "use strict"; | ||
: browser_core_1.TraceContextInjection.ALL, | ||
plugins: initConfiguration.betaPlugins || [], | ||
plugins: initConfiguration.plugins || [], | ||
}, baseConfiguration); | ||
@@ -127,5 +127,5 @@ } | ||
track_long_task: configuration.trackLongTasks, | ||
plugins: (_a = configuration.betaPlugins) === null || _a === void 0 ? void 0 : _a.map(function (plugin) { var _a; return (0, browser_core_1.assign)({ name: plugin.name }, (_a = plugin.getConfigurationTelemetry) === null || _a === void 0 ? void 0 : _a.call(plugin)); }), | ||
plugins: (_a = configuration.plugins) === null || _a === void 0 ? void 0 : _a.map(function (plugin) { var _a; return (0, browser_core_1.assign)({ name: plugin.name }, (_a = plugin.getConfigurationTelemetry) === null || _a === void 0 ? void 0 : _a.call(plugin)); }), | ||
}, baseSerializedConfiguration); | ||
} | ||
//# sourceMappingURL=configuration.js.map |
@@ -67,3 +67,5 @@ "use strict"; | ||
var resizeObserver_1 = new ResizeObserver((0, browser_core_1.monitor)(throttledNotify_1.throttled)); | ||
resizeObserver_1.observe(observerTarget_1); | ||
if (observerTarget_1) { | ||
resizeObserver_1.observe(observerTarget_1); | ||
} | ||
var eventListener_1 = (0, browser_core_1.addEventListener)(configuration, window, "scroll" /* DOM_EVENT.SCROLL */, throttledNotify_1.throttled, { | ||
@@ -70,0 +72,0 @@ passive: true, |
@@ -222,2 +222,3 @@ import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause, DefaultPrivacyLevel, Connectivity, Csp } from '@datadog/browser-core'; | ||
}; | ||
name_source?: string; | ||
position?: { | ||
@@ -224,0 +225,0 @@ x: number; |
@@ -96,3 +96,3 @@ import { createBoundedBuffer, display, canUseEventBridge, displayAlreadyInitializedError, willSyntheticsInjectRum, noop, timeStampNow, clocksNow, assign, getEventBridge, ExperimentalFeature, isExperimentalFeatureEnabled, initFeatureFlags, addTelemetryConfiguration, initFetchObservable, } from '@datadog/browser-core'; | ||
} | ||
callPluginsMethod(initConfiguration.betaPlugins, 'onInit', { initConfiguration: initConfiguration, publicApi: publicApi }); | ||
callPluginsMethod(initConfiguration.plugins, 'onInit', { initConfiguration: initConfiguration, publicApi: publicApi }); | ||
if (initConfiguration.remoteConfigurationId && | ||
@@ -99,0 +99,0 @@ isExperimentalFeatureEnabled(ExperimentalFeature.REMOTE_CONFIGURATION)) { |
@@ -1,2 +0,2 @@ | ||
import { noop, assign, combine, toServerDuration, generateUUID } from '@datadog/browser-core'; | ||
import { noop, assign, combine, toServerDuration, generateUUID, ExperimentalFeature, isExperimentalFeatureEnabled, } from '@datadog/browser-core'; | ||
import { discardNegativeDuration } from '../discardNegativeDuration'; | ||
@@ -44,2 +44,5 @@ import { trackClickActions } from './trackClickActions'; | ||
position: action.position, | ||
name_source: isExperimentalFeatureEnabled(ExperimentalFeature.ACTION_NAME_MASKING) | ||
? action.nameSource | ||
: undefined, | ||
}, | ||
@@ -46,0 +49,0 @@ }, |
@@ -9,2 +9,14 @@ import { NodePrivacyLevel } from '../privacy'; | ||
export declare const ACTION_NAME_PLACEHOLDER = "Masked Element"; | ||
export declare function getActionNameFromElement(element: Element, { enablePrivacyForActionName, actionNameAttribute: userProgrammaticAttribute }: RumConfiguration, nodePrivacyLevel?: NodePrivacyLevel): string; | ||
export declare const enum ActionNameSource { | ||
CUSTOM_ATTRIBUTE = "custom_attribute", | ||
MASK_PLACEHOLDER = "mask_placeholder", | ||
TEXT_CONTENT = "text_content", | ||
STANDARD_ATTRIBUTE = "standard_attribute", | ||
BLANK = "blank" | ||
} | ||
type ActionName = { | ||
name: string; | ||
nameSource: ActionNameSource; | ||
}; | ||
export declare function getActionNameFromElement(element: Element, { enablePrivacyForActionName, actionNameAttribute: userProgrammaticAttribute }: RumConfiguration, nodePrivacyLevel?: NodePrivacyLevel): ActionName; | ||
export {}; |
@@ -14,4 +14,5 @@ import { safeTruncate, isIE, find } from '@datadog/browser-core'; | ||
// * first, get the name programmatically, explicitly defined by the user. | ||
// * then, use strategies that are known to return good results. Those strategies will be used on | ||
// the element and a few parents, but it's likely that they won't succeed at all. | ||
// * then, if privacy is set to mask, return a placeholder for the undefined. | ||
// * if privacy is not set to mask, use strategies that are known to return good results. | ||
// Those strategies will be used on the element and a few parents, but it's likely that they won't succeed at all. | ||
// * if no name is found this way, use strategies returning less accurate names as a fallback. | ||
@@ -21,9 +22,10 @@ // Those are much likely to succeed. | ||
(userProgrammaticAttribute && getActionNameFromElementProgrammatically(element, userProgrammaticAttribute)); | ||
if (nodePrivacyLevel === NodePrivacyLevel.MASK) { | ||
return defaultActionName || ACTION_NAME_PLACEHOLDER; | ||
if (defaultActionName) { | ||
return { name: defaultActionName, nameSource: "custom_attribute" /* ActionNameSource.CUSTOM_ATTRIBUTE */ }; | ||
} | ||
return (defaultActionName || | ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, priorityStrategies, enablePrivacyForActionName) || | ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, fallbackStrategies, enablePrivacyForActionName) || | ||
''); | ||
else if (nodePrivacyLevel === NodePrivacyLevel.MASK) { | ||
return { name: ACTION_NAME_PLACEHOLDER, nameSource: "mask_placeholder" /* ActionNameSource.MASK_PLACEHOLDER */ }; | ||
} | ||
return (getActionNameFromElementForStrategies(element, userProgrammaticAttribute, priorityStrategies, enablePrivacyForActionName) || | ||
getActionNameFromElementForStrategies(element, userProgrammaticAttribute, fallbackStrategies, enablePrivacyForActionName) || { name: '', nameSource: "blank" /* ActionNameSource.BLANK */ }); | ||
} | ||
@@ -62,3 +64,3 @@ function getActionNameFromElementProgrammatically(targetElement, programmaticAttribute) { | ||
if ('labels' in element && element.labels && element.labels.length > 0) { | ||
return getTextualContent(element.labels[0], userProgrammaticAttribute); | ||
return getActionNameFromTextualContent(element.labels[0], userProgrammaticAttribute); | ||
} | ||
@@ -69,3 +71,3 @@ } | ||
find(element.ownerDocument.querySelectorAll('label'), function (label) { return label.htmlFor === element.id; }); | ||
return label && getTextualContent(label, userProgrammaticAttribute, privacy); | ||
return label && getActionNameFromTextualContent(label, userProgrammaticAttribute, privacy); | ||
} | ||
@@ -79,3 +81,3 @@ }, | ||
if (type === 'button' || type === 'submit' || type === 'reset') { | ||
return input.value; | ||
return { name: input.value, nameSource: "text_content" /* ActionNameSource.TEXT_CONTENT */ }; | ||
} | ||
@@ -87,6 +89,6 @@ } | ||
if (element.nodeName === 'BUTTON' || element.nodeName === 'LABEL' || element.getAttribute('role') === 'button') { | ||
return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
return getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
} | ||
}, | ||
function (element) { return element.getAttribute('aria-label'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'aria-label'); }, | ||
// associated element text designated by the aria-labelledby attribute | ||
@@ -96,18 +98,21 @@ function (element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
if (labelledByAttribute) { | ||
return labelledByAttribute | ||
.split(/\s+/) | ||
.map(function (id) { return getElementById(element, id); }) | ||
.filter(function (label) { return Boolean(label); }) | ||
.map(function (element) { return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); }) | ||
.join(' '); | ||
return { | ||
name: labelledByAttribute | ||
.split(/\s+/) | ||
.map(function (id) { return getElementById(element, id); }) | ||
.filter(function (label) { return Boolean(label); }) | ||
.map(function (element) { return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); }) | ||
.join(' '), | ||
nameSource: "text_content" /* ActionNameSource.TEXT_CONTENT */, | ||
}; | ||
} | ||
}, | ||
function (element) { return element.getAttribute('alt'); }, | ||
function (element) { return element.getAttribute('name'); }, | ||
function (element) { return element.getAttribute('title'); }, | ||
function (element) { return element.getAttribute('placeholder'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'alt'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'name'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'title'); }, | ||
function (element) { return getActionNameFromStandardAttribute(element, 'placeholder'); }, | ||
// SELECT first OPTION text | ||
function (element, userProgrammaticAttribute) { | ||
if ('options' in element && element.options.length > 0) { | ||
return getTextualContent(element.options[0], userProgrammaticAttribute); | ||
return getActionNameFromTextualContent(element.options[0], userProgrammaticAttribute); | ||
} | ||
@@ -118,3 +123,3 @@ }, | ||
function (element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
return getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
}, | ||
@@ -137,7 +142,8 @@ ]; | ||
var strategy = strategies_1[_i]; | ||
var name_1 = strategy(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
if (typeof name_1 === 'string') { | ||
var trimmedName = name_1.trim(); | ||
var actionName = strategy(element, userProgrammaticAttribute, privacyEnabledActionName); | ||
if (actionName) { | ||
var name_1 = actionName.name, nameSource = actionName.nameSource; | ||
var trimmedName = name_1 && name_1.trim(); | ||
if (trimmedName) { | ||
return truncate(normalizeWhitespace(trimmedName)); | ||
return { name: truncate(normalizeWhitespace(trimmedName)), nameSource: nameSource }; | ||
} | ||
@@ -166,2 +172,14 @@ } | ||
} | ||
function getActionNameFromStandardAttribute(element, attribute) { | ||
return { | ||
name: element.getAttribute(attribute) || '', | ||
nameSource: "standard_attribute" /* ActionNameSource.STANDARD_ATTRIBUTE */, | ||
}; | ||
} | ||
function getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
return { | ||
name: getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) || '', | ||
nameSource: "text_content" /* ActionNameSource.TEXT_CONTENT */, | ||
}; | ||
} | ||
function getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) { | ||
@@ -168,0 +186,0 @@ if (element.isContentEditable) { |
@@ -17,2 +17,3 @@ import type { Duration, ClocksState, RelativeTime, TimeStamp, ValueHistory } from '@datadog/browser-core'; | ||
name: string; | ||
nameSource: string; | ||
target?: { | ||
@@ -43,3 +44,3 @@ selector: string | undefined; | ||
}; | ||
type ClickActionBase = Pick<ClickAction, 'type' | 'name' | 'target' | 'position'>; | ||
type ClickActionBase = Pick<ClickAction, 'type' | 'name' | 'nameSource' | 'target' | 'position'>; | ||
export type Click = ReturnType<typeof newClick>; | ||
@@ -46,0 +47,0 @@ declare function newClick(lifeCycle: LifeCycle, history: ClickActionIdHistory, getUserActivity: () => UserActivity, clickActionBase: ClickActionBase, startEvent: MouseEventOnElement): { |
@@ -118,2 +118,3 @@ import { includes, timeStampNow, Observable, assign, getRelativeTime, ONE_MINUTE, generateUUID, clocksNow, elapsed, createValueHistory, } from '@datadog/browser-core'; | ||
} | ||
var actionName = getActionNameFromElement(event.target, configuration, nodePrivacyLevel); | ||
return { | ||
@@ -131,3 +132,4 @@ type: "click" /* ActionType.CLICK */, | ||
}, | ||
name: getActionNameFromElement(event.target, configuration, nodePrivacyLevel), | ||
name: actionName.name, | ||
nameSource: actionName.nameSource, | ||
}; | ||
@@ -134,0 +136,0 @@ } |
@@ -62,3 +62,3 @@ import { combine, isEmptyObject, timeStampNow, currentDrift, display, createEventRateLimiter, canUseEventBridge, assign, round, isExperimentalFeatureEnabled, ExperimentalFeature, getConnectivity, } from '@datadog/browser-core'; | ||
}, | ||
browser_sdk_version: canUseEventBridge() ? "5.31.1" : undefined, | ||
browser_sdk_version: canUseEventBridge() ? "5.32.0" : undefined, | ||
}, | ||
@@ -65,0 +65,0 @@ application: { |
@@ -107,3 +107,3 @@ import type { Configuration, InitConfiguration, MatchOption } from '@datadog/browser-core'; | ||
*/ | ||
betaPlugins?: RumPlugin[] | undefined; | ||
plugins?: RumPlugin[] | undefined; | ||
} | ||
@@ -110,0 +110,0 @@ export type HybridInitConfiguration = Omit<RumInitConfiguration, 'applicationId' | 'clientToken'>; |
@@ -50,3 +50,3 @@ import { getType, arrayFrom, isMatchOption, serializeConfiguration, assign, DefaultPrivacyLevel, TraceContextInjection, display, objectHasValue, validateAndBuildConfiguration, isSampleRate, } from '@datadog/browser-core'; | ||
: TraceContextInjection.ALL, | ||
plugins: initConfiguration.betaPlugins || [], | ||
plugins: initConfiguration.plugins || [], | ||
}, baseConfiguration); | ||
@@ -122,5 +122,5 @@ } | ||
track_long_task: configuration.trackLongTasks, | ||
plugins: (_a = configuration.betaPlugins) === null || _a === void 0 ? void 0 : _a.map(function (plugin) { var _a; return assign({ name: plugin.name }, (_a = plugin.getConfigurationTelemetry) === null || _a === void 0 ? void 0 : _a.call(plugin)); }), | ||
plugins: (_a = configuration.plugins) === null || _a === void 0 ? void 0 : _a.map(function (plugin) { var _a; return assign({ name: plugin.name }, (_a = plugin.getConfigurationTelemetry) === null || _a === void 0 ? void 0 : _a.call(plugin)); }), | ||
}, baseSerializedConfiguration); | ||
} | ||
//# sourceMappingURL=configuration.js.map |
@@ -61,3 +61,5 @@ import { Observable, ONE_SECOND, elapsed, relativeNow, throttle, addEventListener, monitor, } from '@datadog/browser-core'; | ||
var resizeObserver_1 = new ResizeObserver(monitor(throttledNotify_1.throttled)); | ||
resizeObserver_1.observe(observerTarget_1); | ||
if (observerTarget_1) { | ||
resizeObserver_1.observe(observerTarget_1); | ||
} | ||
var eventListener_1 = addEventListener(configuration, window, "scroll" /* DOM_EVENT.SCROLL */, throttledNotify_1.throttled, { | ||
@@ -64,0 +66,0 @@ passive: true, |
@@ -222,2 +222,3 @@ import type { Context, Duration, ErrorSource, ErrorHandling, ResourceType, ServerDuration, TimeStamp, RawErrorCause, DefaultPrivacyLevel, Connectivity, Csp } from '@datadog/browser-core'; | ||
}; | ||
name_source?: string; | ||
position?: { | ||
@@ -224,0 +225,0 @@ x: number; |
{ | ||
"name": "@datadog/browser-rum-core", | ||
"version": "5.31.1", | ||
"version": "5.32.0", | ||
"license": "Apache-2.0", | ||
@@ -15,3 +15,3 @@ "main": "cjs/index.js", | ||
"dependencies": { | ||
"@datadog/browser-core": "5.31.1" | ||
"@datadog/browser-core": "5.32.0" | ||
}, | ||
@@ -32,3 +32,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "aa852195227ff9e7a8e7e4763803b65c43d5a73f" | ||
"gitHead": "bbd2e32d488059fcb4dfea26a14c8113f63f326e" | ||
} |
@@ -159,3 +159,3 @@ import { | ||
callPluginsMethod(initConfiguration.betaPlugins, 'onInit', { initConfiguration, publicApi }) | ||
callPluginsMethod(initConfiguration.plugins, 'onInit', { initConfiguration, publicApi }) | ||
@@ -162,0 +162,0 @@ if ( |
import type { ClocksState, Context, Observable } from '@datadog/browser-core' | ||
import { noop, assign, combine, toServerDuration, generateUUID } from '@datadog/browser-core' | ||
import { | ||
noop, | ||
assign, | ||
combine, | ||
toServerDuration, | ||
generateUUID, | ||
ExperimentalFeature, | ||
isExperimentalFeatureEnabled, | ||
} from '@datadog/browser-core' | ||
@@ -86,2 +94,5 @@ import { discardNegativeDuration } from '../discardNegativeDuration' | ||
position: action.position, | ||
name_source: isExperimentalFeatureEnabled(ExperimentalFeature.ACTION_NAME_MASKING) | ||
? action.nameSource | ||
: undefined, | ||
}, | ||
@@ -88,0 +99,0 @@ }, |
@@ -12,2 +12,14 @@ import { safeTruncate, isIE, find } from '@datadog/browser-core' | ||
export const ACTION_NAME_PLACEHOLDER = 'Masked Element' | ||
export const enum ActionNameSource { | ||
CUSTOM_ATTRIBUTE = 'custom_attribute', | ||
MASK_PLACEHOLDER = 'mask_placeholder', | ||
TEXT_CONTENT = 'text_content', | ||
STANDARD_ATTRIBUTE = 'standard_attribute', | ||
BLANK = 'blank', | ||
} | ||
type ActionName = { | ||
name: string | ||
nameSource: ActionNameSource | ||
} | ||
export function getActionNameFromElement( | ||
@@ -17,7 +29,8 @@ element: Element, | ||
nodePrivacyLevel?: NodePrivacyLevel | ||
): string { | ||
): ActionName { | ||
// Proceed to get the action name in two steps: | ||
// * first, get the name programmatically, explicitly defined by the user. | ||
// * then, use strategies that are known to return good results. Those strategies will be used on | ||
// the element and a few parents, but it's likely that they won't succeed at all. | ||
// * then, if privacy is set to mask, return a placeholder for the undefined. | ||
// * if privacy is not set to mask, use strategies that are known to return good results. | ||
// Those strategies will be used on the element and a few parents, but it's likely that they won't succeed at all. | ||
// * if no name is found this way, use strategies returning less accurate names as a fallback. | ||
@@ -29,8 +42,9 @@ // Those are much likely to succeed. | ||
if (nodePrivacyLevel === NodePrivacyLevel.MASK) { | ||
return defaultActionName || ACTION_NAME_PLACEHOLDER | ||
if (defaultActionName) { | ||
return { name: defaultActionName, nameSource: ActionNameSource.CUSTOM_ATTRIBUTE } | ||
} else if (nodePrivacyLevel === NodePrivacyLevel.MASK) { | ||
return { name: ACTION_NAME_PLACEHOLDER, nameSource: ActionNameSource.MASK_PLACEHOLDER } | ||
} | ||
return ( | ||
defaultActionName || | ||
getActionNameFromElementForStrategies( | ||
@@ -47,4 +61,3 @@ element, | ||
enablePrivacyForActionName | ||
) || | ||
'' | ||
) || { name: '', nameSource: ActionNameSource.BLANK } | ||
) | ||
@@ -83,3 +96,3 @@ } | ||
privacyEnabledActionName?: boolean | ||
) => string | undefined | null | ||
) => ActionName | undefined | null | ||
@@ -93,3 +106,3 @@ const priorityStrategies: NameStrategy[] = [ | ||
if ('labels' in element && element.labels && element.labels.length > 0) { | ||
return getTextualContent(element.labels[0], userProgrammaticAttribute) | ||
return getActionNameFromTextualContent(element.labels[0], userProgrammaticAttribute) | ||
} | ||
@@ -100,3 +113,3 @@ } else if (element.id) { | ||
find(element.ownerDocument.querySelectorAll('label'), (label) => label.htmlFor === element.id) | ||
return label && getTextualContent(label, userProgrammaticAttribute, privacy) | ||
return label && getActionNameFromTextualContent(label, userProgrammaticAttribute, privacy) | ||
} | ||
@@ -110,3 +123,3 @@ }, | ||
if (type === 'button' || type === 'submit' || type === 'reset') { | ||
return input.value | ||
return { name: input.value, nameSource: ActionNameSource.TEXT_CONTENT } | ||
} | ||
@@ -118,6 +131,6 @@ } | ||
if (element.nodeName === 'BUTTON' || element.nodeName === 'LABEL' || element.getAttribute('role') === 'button') { | ||
return getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) | ||
return getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) | ||
} | ||
}, | ||
(element) => element.getAttribute('aria-label'), | ||
(element) => getActionNameFromStandardAttribute(element, 'aria-label'), | ||
// associated element text designated by the aria-labelledby attribute | ||
@@ -127,18 +140,21 @@ (element, userProgrammaticAttribute, privacyEnabledActionName) => { | ||
if (labelledByAttribute) { | ||
return labelledByAttribute | ||
.split(/\s+/) | ||
.map((id) => getElementById(element, id)) | ||
.filter((label): label is HTMLElement => Boolean(label)) | ||
.map((element) => getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName)) | ||
.join(' ') | ||
return { | ||
name: labelledByAttribute | ||
.split(/\s+/) | ||
.map((id) => getElementById(element, id)) | ||
.filter((label): label is HTMLElement => Boolean(label)) | ||
.map((element) => getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName)) | ||
.join(' '), | ||
nameSource: ActionNameSource.TEXT_CONTENT, | ||
} | ||
} | ||
}, | ||
(element) => element.getAttribute('alt'), | ||
(element) => element.getAttribute('name'), | ||
(element) => element.getAttribute('title'), | ||
(element) => element.getAttribute('placeholder'), | ||
(element) => getActionNameFromStandardAttribute(element, 'alt'), | ||
(element) => getActionNameFromStandardAttribute(element, 'name'), | ||
(element) => getActionNameFromStandardAttribute(element, 'title'), | ||
(element) => getActionNameFromStandardAttribute(element, 'placeholder'), | ||
// SELECT first OPTION text | ||
(element, userProgrammaticAttribute) => { | ||
if ('options' in element && element.options.length > 0) { | ||
return getTextualContent(element.options[0], userProgrammaticAttribute) | ||
return getActionNameFromTextualContent(element.options[0], userProgrammaticAttribute) | ||
} | ||
@@ -150,3 +166,3 @@ }, | ||
(element, userProgrammaticAttribute, privacyEnabledActionName) => | ||
getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName), | ||
getActionNameFromTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName), | ||
] | ||
@@ -175,7 +191,8 @@ | ||
for (const strategy of strategies) { | ||
const name = strategy(element, userProgrammaticAttribute, privacyEnabledActionName) | ||
if (typeof name === 'string') { | ||
const trimmedName = name.trim() | ||
const actionName = strategy(element, userProgrammaticAttribute, privacyEnabledActionName) | ||
if (actionName) { | ||
const { name, nameSource } = actionName | ||
const trimmedName = name && name.trim() | ||
if (trimmedName) { | ||
return truncate(normalizeWhitespace(trimmedName)) | ||
return { name: truncate(normalizeWhitespace(trimmedName)), nameSource } | ||
} | ||
@@ -208,2 +225,20 @@ } | ||
function getActionNameFromStandardAttribute(element: Element | HTMLElement, attribute: string): ActionName { | ||
return { | ||
name: element.getAttribute(attribute) || '', | ||
nameSource: ActionNameSource.STANDARD_ATTRIBUTE, | ||
} | ||
} | ||
function getActionNameFromTextualContent( | ||
element: Element | HTMLElement, | ||
userProgrammaticAttribute: string | undefined, | ||
privacyEnabledActionName?: boolean | ||
): ActionName { | ||
return { | ||
name: getTextualContent(element, userProgrammaticAttribute, privacyEnabledActionName) || '', | ||
nameSource: ActionNameSource.TEXT_CONTENT, | ||
} | ||
} | ||
function getTextualContent( | ||
@@ -210,0 +245,0 @@ element: Element | HTMLElement, |
@@ -41,2 +41,3 @@ import type { Duration, ClocksState, RelativeTime, TimeStamp, ValueHistory } from '@datadog/browser-core' | ||
name: string | ||
nameSource: string | ||
target?: { | ||
@@ -223,3 +224,3 @@ selector: string | undefined | ||
type ClickActionBase = Pick<ClickAction, 'type' | 'name' | 'target' | 'position'> | ||
type ClickActionBase = Pick<ClickAction, 'type' | 'name' | 'nameSource' | 'target' | 'position'> | ||
@@ -236,2 +237,3 @@ function computeClickActionBase( | ||
} | ||
const actionName = getActionNameFromElement(event.target, configuration, nodePrivacyLevel) | ||
@@ -250,3 +252,4 @@ return { | ||
}, | ||
name: getActionNameFromElement(event.target, configuration, nodePrivacyLevel), | ||
name: actionName.name, | ||
nameSource: actionName.nameSource, | ||
} | ||
@@ -253,0 +256,0 @@ } |
@@ -132,3 +132,3 @@ import type { Configuration, InitConfiguration, MatchOption, RawTelemetryConfiguration } from '@datadog/browser-core' | ||
*/ | ||
betaPlugins?: RumPlugin[] | undefined | ||
plugins?: RumPlugin[] | undefined | ||
} | ||
@@ -217,3 +217,3 @@ | ||
: TraceContextInjection.ALL, | ||
plugins: initConfiguration.betaPlugins || [], | ||
plugins: initConfiguration.plugins || [], | ||
}, | ||
@@ -300,3 +300,3 @@ baseConfiguration | ||
track_long_task: configuration.trackLongTasks, | ||
plugins: configuration.betaPlugins?.map((plugin) => | ||
plugins: configuration.plugins?.map((plugin) => | ||
assign({ name: plugin.name }, plugin.getConfigurationTelemetry?.()) | ||
@@ -303,0 +303,0 @@ ), |
@@ -105,3 +105,5 @@ import type { ClocksState, Duration } from '@datadog/browser-core' | ||
const resizeObserver = new ResizeObserver(monitor(throttledNotify.throttled)) | ||
resizeObserver.observe(observerTarget) | ||
if (observerTarget) { | ||
resizeObserver.observe(observerTarget) | ||
} | ||
const eventListener = addEventListener(configuration, window, DOM_EVENT.SCROLL, throttledNotify.throttled, { | ||
@@ -108,0 +110,0 @@ passive: true, |
@@ -254,2 +254,3 @@ import type { | ||
} | ||
name_source?: string | ||
position?: { | ||
@@ -256,0 +257,0 @@ x: number |
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
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
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
1553521
28436
+ Added@datadog/browser-core@5.32.0(transitive)
- Removed@datadog/browser-core@5.31.1(transitive)
Updated@datadog/browser-core@5.32.0