@dynatrace/react-native-plugin
Version:
This plugin gives you the ability to use the Dynatrace Mobile agent in your react native application.
122 lines (121 loc) • 4.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.findTouchableName = exports.chooseTouchableName = exports.wrapOnPress = exports.withOnPressMonitoring = void 0;
const ReactNative = require("react-native");
const React = require("react");
const ConsoleLogger_1 = require("../../lib/core/logging/ConsoleLogger");
const ConfigurationHandler_1 = require("../../lib/core/configuration/ConfigurationHandler");
const Dynatrace_1 = require("../../lib/core/Dynatrace");
const ComponentUtil_1 = require("../jsx/components/ComponentUtil");
const Logger = new ConsoleLogger_1.ConsoleLogger('TouchableHelper');
function withOnPressMonitoring(Component, fallbackName) {
return React.forwardRef((props, ref) => {
const { onPress, onLongPress } = props;
const touchableName = (0, exports.chooseTouchableName)(props, fallbackName);
const dynatraceIgnored = (0, ComponentUtil_1.isDynatraceIgnored)(props);
const propsWithoutRef = Object.assign(Object.assign(Object.assign({}, props), (!dynatraceIgnored &&
onPress && {
onPress: (0, exports.wrapOnPress)(onPress, touchableName),
})), (!dynatraceIgnored &&
onLongPress && {
onLongPress: (0, exports.wrapOnPress)(onLongPress, touchableName),
}));
const propsWithRef = Object.assign(Object.assign({}, propsWithoutRef), { ref });
return React.createElement(Component, Object.assign({}, propsWithRef));
});
}
exports.withOnPressMonitoring = withOnPressMonitoring;
const wrapOnPress = (onPress, touchableName) => {
return (...args) => {
if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
Logger.info('React Native plugin has not been started yet! Touch will not be reported!');
onPress(...args);
}
else {
const action = Dynatrace_1.Dynatrace.enterAutoAction(`Touch on ${touchableName}`);
let isSync = true;
try {
const returnValue = onPress(...args);
if (returnValue instanceof Promise) {
isSync = false;
return Promise.resolve(returnValue).finally(() => {
action.leaveAction();
});
}
}
finally {
if (isSync) {
action.leaveAction();
}
}
}
};
};
exports.wrapOnPress = wrapOnPress;
const chooseTouchableName = (props, fallbackName) => {
if (props.dtActionName) {
return props.dtActionName;
}
if (ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable() &&
ConfigurationHandler_1.ConfigurationHandler.isActionNamePrivacyEnabled()) {
return fallbackName;
}
return (0, exports.findTouchableName)(props) || fallbackName;
};
exports.chooseTouchableName = chooseTouchableName;
const findTouchableName = (props) => {
if ('title' in props) {
return props.title;
}
if (props.accessibilityLabel !== undefined) {
return props.accessibilityLabel;
}
if (typeof props.children === 'function') {
return null;
}
return findTouchableNameRecursive(props.children);
};
exports.findTouchableName = findTouchableName;
function findTouchableNameRecursive(node) {
if (typeof node === 'string') {
return node;
}
if (isReactNodeIterable(node)) {
for (const child of node) {
const result = findTouchableNameRecursive(child);
if (result !== null)
return result;
}
}
if (React.isValidElement(node)) {
if (isReactNativeImage(node)) {
const uri = getUriFromSource(node.props.source);
return uri ? 'Image Button: ' + uri : 'Image Button';
}
if (isCustomIcon(node)) {
return node.props.name;
}
if (hasReactNodeChildren(node))
return findTouchableNameRecursive(node.props.children);
}
return null;
}
function getUriFromSource(source) {
if (typeof source === 'object' &&
'uri' in source &&
source.uri !== undefined) {
return source.uri;
}
return null;
}
const isReactNodeIterable = (node) => typeof node === 'object' && node !== null && Symbol.iterator in node;
const isReactNativeImage = (element) => element.type === ReactNative.Image;
const isCustomIcon = (element) => typeof element.type === 'function' &&
element.type.name === 'Icon' &&
typeof element.props === 'object' &&
element.props !== null &&
'name' in element.props &&
typeof element.props.name === 'string';
const hasReactNodeChildren = (element) => typeof element.props === 'object' &&
element.props !== null &&
'children' in element.props;