@tracing/shared
Version:
587 lines (575 loc) • 17.7 kB
JavaScript
/*!
* @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;
})({});