UNPKG

@ifreeovo/highlight-dom

Version:
291 lines (283 loc) 10.7 kB
import * as tapable from 'tapable'; import { SyncHook } from 'tapable'; interface BaseStyle { width: string; height: string; } type DOMElement = HTMLElement | SVGElement; type BoxModelLevel = 'content' | 'padding' | 'border' | 'margin'; interface InlineStyle extends BaseStyle { left: string; top: string; } interface ElementInfo { borderTopWidth: number; borderRightWidth: number; borderBottomWidth: number; borderLeftWidth: number; marginTop: number; marginRight: number; marginBottom: number; marginLeft: number; paddingTop: number; paddingRight: number; paddingBottom: number; paddingLeft: number; contentWidth: number; contentHeight: number; top: number; left: number; bottom: number; tagName: string; id: string; classList: string[]; isSVG: boolean; } type ElementInfoKey = keyof ElementInfo; declare function isElementNode(ele: EventTarget): ele is DOMElement; declare function isHTMLElement(ele: EventTarget): ele is HTMLElement; declare function isSVG(ele: EventTarget): ele is SVGElement; declare function isVisibleElementNode(ele: EventTarget): boolean; declare function getOffsetHeight(ele: DOMElement): number; declare function getOffsetWidth(ele: DOMElement): number; declare function isElementInViewport(ele: DOMElement): boolean; declare function $(selector: string, parent?: Element): Element | null; declare function removeDom(ele?: Element): void; declare function getMaxZIndex(): number; /** * @example * 例如'<div class="a-1 a-2"></div>',匹配结果为'class="a-1 a-2"' */ declare function matchClassAttribute(text: string): RegExpMatchArray | null; /** * @example * 例如class="a-1 a-2",提取结果为"['a-1', 'a-2']" */ declare function extractClassNames(text: string): Array<string>; declare function getScale(ele: DOMElement): { scaleX: number; scaleY: number; }; declare function getElementInfo(ele: DOMElement): ElementInfo; /** * @remarks 元素水平方向上dom宽度的结构顺序 */ declare const horizontalOrder: readonly ["marginLeft", "borderLeftWidth", "paddingLeft", "contentWidth", "paddingRight", "borderRightWidth", "marginRight"]; /** * @remarks 元素垂直方向上dom宽度的结构顺序 */ declare const verticalOrder: readonly ["marginTop", "borderTopWidth", "paddingTop", "contentHeight", "paddingBottom", "borderBottomWidth", "marginBottom"]; /** * @example * 例如currentSide传入'padding-top',那么距离为verticalOrder数组里,padding-top前两项'margin-top'、'border-top-width'的高度相加 */ declare function calcTop(elementInfo: ElementInfo, currentSide: (typeof verticalOrder)[number]): `${string}px`; /** * @example * 例如currentSide传入'padding-left',那么距离为horizontalOrder数组里,paddingLeft前两项'marginLeft'、'borderLeftWidth'的宽度相加 */ declare function calcLeft(elementInfo: ElementInfo, currentSide: (typeof horizontalOrder)[number]): `${string}px`; /** * @example * 例如boxModel传入'padding',则在verticalOrder数据中找到以padding开头和结尾的那一段数组,即['paddingTop','contentHeight','paddingBottom'], * 然后对数组里的这些值,进行累加算出模型高度 * @remarks * 需要注意svg模型高度不受padding、border、margin影响 */ declare function getBoxModelHeight(elementInfo: ElementInfo, boxModel: BoxModelLevel): number; /** * @example * 例如boxModel传入'padding',则在horizontalOrder数据中找到以padding开头和结尾的那一段数组,即['paddingLeft','contentWidth','paddingRight'], * 然后对数组里的这些值,进行累加算出模型宽度 * @remarks * 需要注意svg模型宽度不受padding、border、margin影响 */ declare function getBoxModelWidth(elementInfo: ElementInfo, boxModel: BoxModelLevel): number; interface Plugin { name: string; hooks: Record<string, (...args: any[]) => any>; } declare class PluginManager { hooks: { beforeHighlight: SyncHook<[object, EventTarget | null], void, tapable.UnsetAdditionalOptions>; afterHighlight: SyncHook<unknown, void, tapable.UnsetAdditionalOptions>; beforeInitOverlay: SyncHook<unknown, void, tapable.UnsetAdditionalOptions>; afterInitOverlay: SyncHook<unknown, void, tapable.UnsetAdditionalOptions>; beforeCreateOverlay: SyncHook<[object, object], void, tapable.UnsetAdditionalOptions>; afterCreateOverlay: SyncHook<unknown, void, tapable.UnsetAdditionalOptions>; beforeMountOverlay: SyncHook<unknown, void, tapable.UnsetAdditionalOptions>; afterMountOverlay: SyncHook<unknown, void, tapable.UnsetAdditionalOptions>; generateCss: SyncHook<unknown, void, tapable.UnsetAdditionalOptions>; }; plugins: Map<string, Record<string, (...args: any[]) => any>>; install(plugins: Plugin[]): void; use(plugin: Plugin): void; } interface OverlayOptions { zIndex?: number; portal?: DOMElement; cache?: boolean; hash?: string; pluginManager?: PluginManager; } interface InspectorData { domInspector: InlineStyle; domInspectorContent: InlineStyle; domInspectorPaddingTop: InlineStyle; domInspectorPaddingBottom: InlineStyle; domInspectorPaddingLeft: InlineStyle; domInspectorPaddingRight: InlineStyle; domInspectorBorderTop: InlineStyle; domInspectorBorderBottom: InlineStyle; domInspectorBorderLeft: InlineStyle; domInspectorBorderRight: InlineStyle; domInspectorMarginTop: InlineStyle; domInspectorMarginBottom: InlineStyle; domInspectorMarginLeft: InlineStyle; domInspectorMarginRight: InlineStyle; } interface TipsData { tagName: string; id: string; classNames: string; size: string; tipsClass: string; style: string; left: `${string}px`; } type OverlayData = InspectorData & TipsData; declare function styled(styles: TemplateStringsArray, ...interpolations: any[]): string; /** * @example * 例如样式为'.demo {color: red;}',hash值为abc,则样式会转成'.demo-abc {color: red;}' */ declare function transformCss(css: string, hash?: string): string; declare class Overlay { #private; static instance?: Overlay; zIndex: number; /** * @remark 防止通用样式与项目样式冲突用的hash */ hash?: string; fragments: string; /** * @remark inspector挂载在页面里的位置 */ portal: DOMElement; /** * @remark 存放所有inspector的容器 */ container?: HTMLElement; pluginManager: PluginManager; cache: boolean; style: string; tipFontSize: string; tipBackgroundColor: string; tipTagColor: string; tipIdColor: string; tipClassColor: string; tipLineColor: string; tipSizeColor: string; marginBackgroundColor: string; borderBackgroundColor: string; paddingBackgroundColor: string; contentBackgroundColor: string; private constructor(); static getInstance(options: OverlayOptions): Overlay; defineDefaultTheme(hash?: string): string; createOverlayStyle(hash?: string): void; clearCache(): void; removeContainer(): void; createContainer(): void; createInspector(data: OverlayData): string; createTips(data: OverlayData): string; createWrap(content: string): string; defineTemplate(): (data: OverlayData) => string; render(templateFn: (data: OverlayData) => string, data: OverlayData): string; getInspectorData(elementInfo: ElementInfo): InspectorData; getTipsData(elementInfo: ElementInfo): TipsData; getData(elementInfo: ElementInfo): OverlayData; create(ele: DOMElement): void; mount(): void; } /** * @type single 单选 * @type siblings 多选(在可视区内,选择包含目标节点和目标的兄弟节点在内的多个节点) */ type Mode = 'single' | 'siblings'; /** * @typedef {UserConfig} UserConfig * @remarks 用户配置 * @property {HTMLElement} UserConfig.target - ssd */ interface UserConfig { /** * @remarks 高亮模式 * @type single 单选 * @type siblings 多选(在可视区内,选择包含目标节点和目标的兄弟节点在内的多个节点) */ mode?: Mode; /** * @remarks Overlay的层级。不穿的话自动获取页面最大层级。某些场景下手动传入,可以跳过自动获取阶段,从而获得更好的执行性能 */ maxZIndex?: number; /** * @remarks Overlay的挂载位置。默认挂载到html上 */ portal?: HTMLElement; /** * @remark 防止通用样式与项目样式冲突用的hash */ hash?: string; /** * @remark 批量挂载inspector的数量。高亮多个节点时可以优化性能 */ batchMountNum?: number; /** * @remark 自定义插件 */ plugins?: Plugin[]; /** * @remark 是否缓存高亮节点 */ cache?: boolean; } declare function defineConfig(config: UserConfig): UserConfig; interface Task { id: string; interruptSchedule: () => void; isInterrupt: boolean; } declare function makeHash(length?: number): string; declare function schedule(task: (...args: any[]) => void, canExec: (...args: any[]) => boolean, finished?: (...args: any[]) => void): Task; declare enum ModeEnum { Single = "single", Siblings = "siblings" } declare class HighlightDom { overlay?: Overlay; mode: Mode; maxZIndex?: number; portal?: DOMElement; taskQueue: Task[]; cache: boolean; hash: string; /** * @remark 批量挂载inspector的数量。高亮多个节点时可以优化性能 */ batchMountNum: number; pluginManager: PluginManager; constructor({ mode, maxZIndex, portal, hash, batchMountNum, plugins, cache, }?: UserConfig); registerPlugin(plugin: Plugin): void; getHash(): string; getZIndex(): number; interruptTask(): void; clearOverlay(): void; highlightNode(target: DOMElement): void; clearOverlayCache(): void; reset(): void; shouldHighlight(target: EventTarget): target is DOMElement; highlight(target: EventTarget | null, options?: Pick<UserConfig, 'mode' | 'maxZIndex' | 'hash'>): void; } export { $, type DOMElement, type ElementInfo, type ElementInfoKey, HighlightDom, type InlineStyle, type InspectorData, ModeEnum, Overlay, type OverlayData, type OverlayOptions, type Task, type TipsData, calcLeft, calcTop, defineConfig, extractClassNames, getBoxModelHeight, getBoxModelWidth, getElementInfo, getMaxZIndex, getOffsetHeight, getOffsetWidth, getScale, isElementInViewport, isElementNode, isHTMLElement, isSVG, isVisibleElementNode, makeHash, matchClassAttribute, removeDom, schedule, styled, transformCss };