summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/utils/esm/browser.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /shared/logger/node_modules/@sentry/utils/esm/browser.js
init commit
Diffstat (limited to 'shared/logger/node_modules/@sentry/utils/esm/browser.js')
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/browser.js152
1 files changed, 152 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/utils/esm/browser.js b/shared/logger/node_modules/@sentry/utils/esm/browser.js
new file mode 100644
index 0000000..aef06de
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/browser.js
@@ -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