UNPKG

@tracing/shared

Version:
587 lines (575 loc) 17.7 kB
/*! * @tracing/shared v0.0.3 * (c) 2024 wermdany <https://github.com/wermdany> * license ISC * hash f6fbb5bcb01c00afbd6fb6f5826e891202a721b1 */ var TracingShared = (function (exports) { 'use strict'; const toString = Object.prototype.toString; const isType = (type) => (obj) => getType(obj) === `[object ${type}]`; const getType = (obj) => toString.call(obj); function isPrimitive(wat) { return wat === null || (typeof wat !== "object" && typeof wat !== "function"); } const isFn = (val) => typeof val === "function"; const isArr = Array.isArray; const isPlainObj = isType("Object"); const isStr = isType("String"); const isBool = isType("Boolean"); const isNum = isType("Number"); const isRegexp = isType("RegExp"); const isUndefined = isType("Undefined"); const isDate = isType("Date"); const isObj = (value) => value !== null && typeof value === "object"; function isInstanceOf(wat, base) { try { return wat instanceof base; } catch (_e) { return false; } } function isElement(value) { return typeof Element !== "undefined" && isInstanceOf(value, Element); } function isErrorEvent(value) { return isInstanceOf(value, ErrorEvent); } /** * 编码数据 * @param data - 要编码的数据 * @returns */ function encrypt(data) { return btoa(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (_, p1) => { return String.fromCharCode(Number("0x" + p1)); })); } /** * 解码数据 * @param data - 要解码的数据 * @returns */ function decrypt(data) { return decodeURIComponent(atob(data) .split("") .map(function (c) { return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); }) .join("")); } /** * 根据一个 object 返回 url query */ function qs(obj, prefix) { const qsArr = []; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { qsArr.push(`${key}=${obj[key]}`); } } return (prefix || "") + qsArr.join("&"); } // eslint-disable-next-line @typescript-eslint/no-empty-function function noop() { } function omit(origin, keys) { const ret = {}; for (const key in origin) { if (Object.prototype.hasOwnProperty.call(origin, key)) { if (!keys.includes(key)) { ret[key] = origin[key]; } } } return ret; } function pick(origin, keys) { const ret = {}; for (const key in origin) { if (Object.prototype.hasOwnProperty.call(origin, key)) { if (keys.includes(key)) { ret[key] = origin[key]; } } } return ret; } function hasOwn(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } /** * 转化参数,如果是函数就会执行 * * @param origin - 原始数据 * */ function transProfile(origin) { const finish = Object.assign({}, origin); for (const key in finish) { if (typeof finish[key] === "function") { finish[key] = finish[key].call(); } } return finish; } function choice(type) { if (typeof type == "function") { return type; } if (isRegexp(type)) { return (arg) => type.test(arg); } return (arg) => type.includes(arg); } function pickParse(obj, keys, parse, omit = []) { const finish = {}; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key) && !omit.includes(key)) { if (keys.includes(key)) { finish[key] = parse(obj[key]); } else { finish[key] = obj[key]; } } } return finish; } function formatNumber(number, precision = 0) { const weight = Math.pow(10, precision); return Math.floor(number * weight) / weight; } /** * 提供便捷的获取页面常用属性方法 */ /********************************* BOM ***********************************/ /** * 获取来源页 */ function getReferrer() { return document.referrer; } /** * 获取时区偏移值 */ function getTimezoneOffset() { return new Date().getTimezoneOffset(); } /** * 获取显示屏幕分辨率宽度 */ function getScreenWidth() { return window.screen.width; } /** * 获取显示屏幕分辨率高度 */ function getScreenHeight() { return window.screen.height; } /** * 获取当前页面的 DOM 视窗宽度 */ function getViewportWidth() { return window.innerWidth; } /** * 获取当前页面的 DOM 视窗高度 */ function getViewportHeight() { return window.innerHeight; } /** * 获取当前页面的 URL */ function getUrl() { return location.href; } /** * 获取当前页面的 URL 名称 */ function getPathName() { return location.pathname; } /** * 获取当前页面的标题 */ function getTitle() { return document.title; } /********************************* DOM ***********************************/ /** * 获取当前元素的选择器 * * @param el - 元素 * @param stopClass - 停止向上查询的 class 名列表 * @param stopById - 是否在碰到 id 时 停止向上查找 * @param isPath - 是否在获取路径中使用 * */ function getCurrentElementSelector(el, stopClass = [], stopById = true, isPath = false) { if (!el || !isElement(el)) { return ""; } if (el === document.body) { return "body"; } const { parentElement } = el; const tagName = getElementTagName(el); const tagId = getElementId(el); const classList = getElementClassList(el); /** * 此时,有三种情况 * 1. 此元素从 dom 中删除 * 2. 此元素为 html * 3. 此元素为自定义元素,并未关联父子元素 */ if (!parentElement) { if (tagId) { return `#${tagId}`; } if (classList.length) { return `${tagName}.${classList.join(".")}`; } return tagName; } if (tagId && stopById) { return `#${tagId}`; } if (stopClass.length && classList.some(v => stopClass.includes(v))) { return `${tagName}.${classList.join(".")}`; } if (isPath) { return tagName; } const fellow = Array.from((parentElement === null || parentElement === void 0 ? void 0 : parentElement.children) || []); const curTags = fellow.filter(item => getElementTagName(item) == tagName); const index = Array.prototype.indexOf.call(curTags, el); return `${tagName}:nth-of-type(${index + 1})`; } /** * 获取指定元素在 DOM 树的唯一选择器 * * @param el - 元素 * @param stopClass - 停止向上查询的class名列表 * @param stopById - 是否在碰到 id 时 停止向上查找 * */ function getElementSelector(el, stopClass = [], stopById = true) { if (!el || !isElement(el)) { return ""; } const selectorArr = []; while (el) { const currentSelector = getCurrentElementSelector(el, stopClass, stopById); if ((stopById && getElementId(el)) || el === document.body || stopClass.some(value => el.classList.contains(value)) || !el.parentElement) { selectorArr.unshift(currentSelector); return selectorArr.join(" > "); } else { selectorArr.unshift(currentSelector); el = el.parentElement; } } return selectorArr.join(" > "); } /** * 获取指定元素在 DOM 树中的路径 * * @param el - 元素 * @param stopClass - 停止向上查询的class名列表 * @param stopById - 是否在碰到 id 时 停止向上查找 * */ function getElementPath(el, stopClass = [], stopById = true) { if (!el || !isElement(el)) { return ""; } const pathArr = []; while (el) { const currentPath = getCurrentElementSelector(el, stopClass, stopById, true); if ((stopById && getElementId(el)) || el === document.body || stopClass.some(value => el.classList.contains(value)) || !el.parentElement) { pathArr.unshift(currentPath); return pathArr.join(" > "); } else { pathArr.unshift(currentPath); el = el.parentElement; } } return pathArr.join(" > "); } /** * 获取一个 DOM 元素的类名 * * @param el - 元素 * */ function getElementClassName(el) { return el.className; } /** * 获取一个 DOM 元素的主体文本内容 * * @param el - 元素 * @param isTrim - 是否去除前后空格 * */ function getElementContent(el, isTrim = true) { var _a; return (isTrim ? (_a = el.textContent) === null || _a === void 0 ? void 0 : _a.trim() : el.textContent) || ""; } /** * 获取一个 DOM 元素的标签名 * * @param el - 元素 * @param isLowerCase - 是否小写 * */ function getElementTagName(el, isLowerCase = true) { return isLowerCase ? el.tagName.toLowerCase() : el.tagName; } function getElementId(el) { return el.getAttribute("id") || ""; } /** * 获取一个 DOM 元素的类名数组 * @param el - 元素 * */ function getElementClassList(el) { return Array.from(el.classList); } /** * 获取一个 DOM 元素的属性名列表 * @param el - 元素 */ function getAttributeNames(el) { return Array.from(el.getAttributeNames()); } class BaseStorage { constructor(name, type) { this.name = name; this.s = window[type]; } get() { const value = this.s.getItem(this.name); try { const parsed = JSON.parse(value); return parsed; } catch (e) { return null; } } set(value) { try { this.s.setItem(this.name, JSON.stringify(value)); return true; } catch (e) { return false; } } clear() { this.s.removeItem(this.name); } } function createLocalStorage(name) { return new BaseStorage(name, "localStorage"); } function createSessionStorage(name) { return new BaseStorage(name, "sessionStorage"); } function createCookie(name, options = {}) { const { path, domain, expires, secure } = options; const genExpires = () => { if (!expires) return ""; if (isNum(expires)) { if (expires === Infinity) { return "; expires=Fri, 31 Dec 9999 23:59:59 GMT"; } else { return "; max-age=" + expires; } } if (isStr(expires)) { return "; expires=" + expires; } if (isDate(expires)) { return "; expires=" + expires.toUTCString(); } }; return { get() { const value = decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(name).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")); try { return JSON.parse(value); } catch (error) { return null; } }, set(value) { if (/^(?:expires|max-age|path|domain|secure)$/i.test(name)) { return false; } document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(JSON.stringify(value)) + genExpires() + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : "") + (secure ? "; secure" : ""); return true; }, clear() { document.cookie = encodeURIComponent(name) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (domain ? "; domain=" + domain : "") + (path ? "; path=" + path : ""); } }; } let _globalThis; const _funThis = (function () { return this; })(); function getGlobalThis() { return (_globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof _funThis !== "undefined" ? _funThis : {})); } function isBrowser() { return typeof window !== "undefined"; } /** * UUID4 generator * * @returns string Generated UUID4. */ function uuid4() { const crypto = window.crypto || window.msCrypto; if (crypto && crypto.randomUUID) { return crypto.randomUUID(); } const getRandomByte = crypto && crypto.getRandomValues ? () => crypto.getRandomValues(new Uint8Array(1))[0] : () => Math.random() * 16; // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 // Concatenating the following numbers as strings results in '10000000100040008000100000000000' return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => // eslint-disable-next-line no-bitwise (c ^ ((getRandomByte() & 15) >> (c / 4))).toString(16)); } /** * if you not know property return this (reduce build size) */ const unknown = "?"; /** * in tracing time only is millisecond */ const performance = window.performance; function browserPerformanceTimer() { if (performance) { return { now: () => performance.now(), timeOrigin: Date.now() - performance.now() }; } } const platformPerformance = browserPerformanceTimer(); /** * return page load relative time */ function timestamp() { if (platformPerformance) return formatNumber(platformPerformance.now(), 0); return unknown; } /** * return local now time */ function localTime() { return formatNumber(Date.now(), 0); } exports.BaseStorage = BaseStorage; exports.browserPerformanceTimer = browserPerformanceTimer; exports.choice = choice; exports.createCookie = createCookie; exports.createLocalStorage = createLocalStorage; exports.createSessionStorage = createSessionStorage; exports.decrypt = decrypt; exports.encrypt = encrypt; exports.formatNumber = formatNumber; exports.getAttributeNames = getAttributeNames; exports.getCurrentElementSelector = getCurrentElementSelector; exports.getElementClassList = getElementClassList; exports.getElementClassName = getElementClassName; exports.getElementContent = getElementContent; exports.getElementId = getElementId; exports.getElementPath = getElementPath; exports.getElementSelector = getElementSelector; exports.getElementTagName = getElementTagName; exports.getGlobalThis = getGlobalThis; exports.getPathName = getPathName; exports.getReferrer = getReferrer; exports.getScreenHeight = getScreenHeight; exports.getScreenWidth = getScreenWidth; exports.getTimezoneOffset = getTimezoneOffset; exports.getTitle = getTitle; exports.getType = getType; exports.getUrl = getUrl; exports.getViewportHeight = getViewportHeight; exports.getViewportWidth = getViewportWidth; exports.hasOwn = hasOwn; exports.isArr = isArr; exports.isBool = isBool; exports.isBrowser = isBrowser; exports.isDate = isDate; exports.isElement = isElement; exports.isErrorEvent = isErrorEvent; exports.isFn = isFn; exports.isInstanceOf = isInstanceOf; exports.isNum = isNum; exports.isObj = isObj; exports.isPlainObj = isPlainObj; exports.isPrimitive = isPrimitive; exports.isRegexp = isRegexp; exports.isStr = isStr; exports.isType = isType; exports.isUndefined = isUndefined; exports.localTime = localTime; exports.noop = noop; exports.omit = omit; exports.pick = pick; exports.pickParse = pickParse; exports.qs = qs; exports.timestamp = timestamp; exports.transProfile = transProfile; exports.unknown = unknown; exports.uuid4 = uuid4; return exports; })({});