forked from off-topic/apps.apple.com
init commit
This commit is contained in:
152
shared/logger/node_modules/@sentry/utils/esm/browser.js
generated
vendored
Normal file
152
shared/logger/node_modules/@sentry/utils/esm/browser.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
import { isString } from './is.js';
|
||||
import { getGlobalObject } from './worldwide.js';
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const WINDOW = getGlobalObject();
|
||||
|
||||
const DEFAULT_MAX_STRING_LENGTH = 80;
|
||||
|
||||
/**
|
||||
* Given a child DOM element, returns a query-selector statement describing that
|
||||
* and its ancestors
|
||||
* e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]
|
||||
* @returns generated DOM path
|
||||
*/
|
||||
function htmlTreeAsString(
|
||||
elem,
|
||||
options = {},
|
||||
) {
|
||||
|
||||
// try/catch both:
|
||||
// - accessing event.target (see getsentry/raven-js#838, #768)
|
||||
// - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
|
||||
// - can throw an exception in some circumstances.
|
||||
try {
|
||||
let currentElem = elem ;
|
||||
const MAX_TRAVERSE_HEIGHT = 5;
|
||||
const out = [];
|
||||
let height = 0;
|
||||
let len = 0;
|
||||
const separator = ' > ';
|
||||
const sepLength = separator.length;
|
||||
let nextStr;
|
||||
const keyAttrs = Array.isArray(options) ? options : options.keyAttrs;
|
||||
const maxStringLength = (!Array.isArray(options) && options.maxStringLength) || DEFAULT_MAX_STRING_LENGTH;
|
||||
|
||||
while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) {
|
||||
nextStr = _htmlElementAsString(currentElem, keyAttrs);
|
||||
// bail out if
|
||||
// - nextStr is the 'html' element
|
||||
// - the length of the string that would be created exceeds maxStringLength
|
||||
// (ignore this limit if we are on the first iteration)
|
||||
if (nextStr === 'html' || (height > 1 && len + out.length * sepLength + nextStr.length >= maxStringLength)) {
|
||||
break;
|
||||
}
|
||||
|
||||
out.push(nextStr);
|
||||
|
||||
len += nextStr.length;
|
||||
currentElem = currentElem.parentNode;
|
||||
}
|
||||
|
||||
return out.reverse().join(separator);
|
||||
} catch (_oO) {
|
||||
return '<unknown>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple, query-selector representation of a DOM element
|
||||
* e.g. [HTMLElement] => input#foo.btn[name=baz]
|
||||
* @returns generated DOM path
|
||||
*/
|
||||
function _htmlElementAsString(el, keyAttrs) {
|
||||
const elem = el
|
||||
|
||||
;
|
||||
|
||||
const out = [];
|
||||
let className;
|
||||
let classes;
|
||||
let key;
|
||||
let attr;
|
||||
let i;
|
||||
|
||||
if (!elem || !elem.tagName) {
|
||||
return '';
|
||||
}
|
||||
|
||||
out.push(elem.tagName.toLowerCase());
|
||||
|
||||
// Pairs of attribute keys defined in `serializeAttribute` and their values on element.
|
||||
const keyAttrPairs =
|
||||
keyAttrs && keyAttrs.length
|
||||
? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])
|
||||
: null;
|
||||
|
||||
if (keyAttrPairs && keyAttrPairs.length) {
|
||||
keyAttrPairs.forEach(keyAttrPair => {
|
||||
out.push(`[${keyAttrPair[0]}="${keyAttrPair[1]}"]`);
|
||||
});
|
||||
} else {
|
||||
if (elem.id) {
|
||||
out.push(`#${elem.id}`);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
className = elem.className;
|
||||
if (className && isString(className)) {
|
||||
classes = className.split(/\s+/);
|
||||
for (i = 0; i < classes.length; i++) {
|
||||
out.push(`.${classes[i]}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
const allowedAttrs = ['aria-label', 'type', 'name', 'title', 'alt'];
|
||||
for (i = 0; i < allowedAttrs.length; i++) {
|
||||
key = allowedAttrs[i];
|
||||
attr = elem.getAttribute(key);
|
||||
if (attr) {
|
||||
out.push(`[${key}="${attr}"]`);
|
||||
}
|
||||
}
|
||||
return out.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* A safe form of location.href
|
||||
*/
|
||||
function getLocationHref() {
|
||||
try {
|
||||
return WINDOW.document.location.href;
|
||||
} catch (oO) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a DOM element by using document.querySelector.
|
||||
*
|
||||
* This wrapper will first check for the existance of the function before
|
||||
* actually calling it so that we don't have to take care of this check,
|
||||
* every time we want to access the DOM.
|
||||
*
|
||||
* Reason: DOM/querySelector is not available in all environments.
|
||||
*
|
||||
* We have to cast to any because utils can be consumed by a variety of environments,
|
||||
* and we don't want to break TS users. If you know what element will be selected by
|
||||
* `document.querySelector`, specify it as part of the generic call. For example,
|
||||
* `const element = getDomElement<Element>('selector');`
|
||||
*
|
||||
* @param selector the selector string passed on to document.querySelector
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function getDomElement(selector) {
|
||||
if (WINDOW.document && WINDOW.document.querySelector) {
|
||||
return WINDOW.document.querySelector(selector) ;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export { getDomElement, getLocationHref, htmlTreeAsString };
|
||||
//# sourceMappingURL=browser.js.map
|
||||
Reference in New Issue
Block a user