@hereorcode/dom-inspector 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/overlay.ts","../src/path.ts","../src/pseudo.ts","../src/inspector.ts"],"sourcesContent":["export {\n createDOMInspector,\n type DOMInspectResult,\n type DOMInspector,\n type DOMInspectorHighlightOptions,\n type DOMInspectorModifierKey,\n type DOMInspectorSelectionScopeOptions,\n type DOMInspectorOptions\n} from \"./inspector\";\n\nexport {\n getCssSelector,\n getElementPath,\n getJSPath,\n getXPath,\n type DOMElementPath,\n type DOMInspectorFramePath,\n type DOMInspectorShadowPath,\n type DOMPathRootKind,\n type XPathOptions\n} from \"./path\";\n\nexport type {\n DOMInspectorPseudoElement,\n PseudoElementHit,\n PseudoElementInfo,\n PseudoElementMatch\n} from \"./pseudo\";\n","export type HighlighterOptions = {\n borderColor?: string;\n backgroundColor?: string;\n borderRadius?: number;\n zIndex?: number;\n};\n\ntype RectLike = {\n height: number;\n left: number;\n top: number;\n width: number;\n};\n\nconst DEFAULT_BORDER_COLOR = \"#7c3aed\";\nconst DEFAULT_BACKGROUND_COLOR = \"rgba(124, 58, 237, 0.12)\";\nconst DEFAULT_Z_INDEX = 2147483647;\n\nexport class ElementHighlighter {\n private readonly element: HTMLElement;\n\n constructor(\n private readonly document: Document,\n options: HighlighterOptions = {}\n ) {\n this.element = document.createElement(\"dom-inspector-overlay\");\n this.element.setAttribute(\"data-dom-inspector-overlay\", \"true\");\n this.element.style.cssText = [\n \"position: fixed\",\n \"top: 0\",\n \"left: 0\",\n \"display: none\",\n \"pointer-events: none\",\n \"box-sizing: border-box\",\n `border: 1px dashed ${options.borderColor ?? DEFAULT_BORDER_COLOR}`,\n `background: ${options.backgroundColor ?? DEFAULT_BACKGROUND_COLOR}`,\n `border-radius: ${options.borderRadius ?? 0}px`,\n `z-index: ${options.zIndex ?? DEFAULT_Z_INDEX}`,\n \"transition: transform 80ms ease, width 80ms ease, height 80ms ease\"\n ].join(\";\");\n\n const parent = document.body ?? document.documentElement;\n parent.appendChild(this.element);\n }\n\n show(target: Element): void {\n this.showRect(target.getBoundingClientRect());\n }\n\n showRect(rect: RectLike): void {\n this.element.style.display = \"block\";\n this.element.style.transform = `translate(${rect.left}px, ${rect.top}px)`;\n this.element.style.width = `${rect.width}px`;\n this.element.style.height = `${rect.height}px`;\n }\n\n hide(): void {\n this.element.style.display = \"none\";\n }\n\n destroy(): void {\n this.element.remove();\n }\n}\n","export type XPathOptions = {\n /**\n * Include [1] even when the element is the first or only matching sibling.\n */\n alwaysIncludeIndex?: boolean;\n};\n\nexport type DOMPathRootKind = \"document\" | \"iframe\" | \"shadow\";\n\nexport type DOMInspectorFramePath = {\n element: HTMLIFrameElement;\n selector: string;\n xpath: string;\n fullXPath: string;\n jsPath: string;\n};\n\nexport type DOMInspectorShadowPath = {\n host: Element;\n hostSelector: string;\n hostXPath: string;\n hostFullXPath: string;\n jsPath: string;\n};\n\nexport type DOMElementPath = {\n rootKind: DOMPathRootKind;\n selector: string;\n xpath: string;\n fullXPath: string;\n jsPath: string;\n framePath: DOMInspectorFramePath[];\n shadowPath: DOMInspectorShadowPath[];\n};\n\nconst ROOT_TAGS = new Set([\"html\", \"body\"]);\n\ntype AccessBridge =\n | {\n element: HTMLIFrameElement;\n fullXPath: string;\n kind: \"iframe\";\n selector: string;\n xpath: string;\n }\n | {\n fullXPath: string;\n host: Element;\n kind: \"shadow\";\n selector: string;\n xpath: string;\n };\n\nexport function getCssSelector(element: Element): string {\n const segments: string[] = [];\n let current: Element | null = element;\n\n while (current && current.nodeType === 1) {\n const tagName = getTagName(current);\n segments.unshift(getCssSegment(current));\n\n if (ROOT_TAGS.has(tagName)) {\n break;\n }\n\n current = current.parentElement;\n }\n\n return segments.join(\" > \");\n}\n\nexport function getXPath(element: Element, options: XPathOptions = {}): string {\n const segments: string[] = [];\n let current: Element | null = element;\n\n while (current && current.nodeType === 1) {\n const tagName = getTagName(current);\n const index = getSameTagIndex(current);\n const shouldIncludeIndex =\n options.alwaysIncludeIndex || hasSameTagSibling(current);\n\n segments.unshift(`${tagName}${shouldIncludeIndex ? `[${index}]` : \"\"}`);\n\n if (tagName === \"html\") {\n break;\n }\n\n current = current.parentElement;\n }\n\n return `/${segments.join(\"/\")}`;\n}\n\nexport function getJSPath(element: Element): string {\n return `document.querySelector(${JSON.stringify(getCssSelector(element))})`;\n}\n\nexport function getElementPath(\n element: Element,\n options: { rootDocument?: Document } = {}\n): DOMElementPath {\n const rootDocument = options.rootDocument ?? element.ownerDocument;\n const selector = getCssSelector(element);\n const xpath = getXPath(element);\n const fullXPath = getXPath(element, { alwaysIncludeIndex: true });\n const bridges = collectAccessBridges(element, rootDocument);\n const orderedBridges = [...bridges].reverse();\n const framePath: DOMInspectorFramePath[] = [];\n const shadowPath: DOMInspectorShadowPath[] = [];\n let expression = \"document\";\n\n for (const bridge of orderedBridges) {\n if (bridge.kind === \"iframe\") {\n const frameExpression = `${expression}.querySelector(${JSON.stringify(\n bridge.selector\n )})`;\n\n framePath.push({\n element: bridge.element,\n selector: bridge.selector,\n xpath: bridge.xpath,\n fullXPath: bridge.fullXPath,\n jsPath: frameExpression\n });\n expression = `${frameExpression}.contentDocument`;\n continue;\n }\n\n const hostExpression = `${expression}.querySelector(${JSON.stringify(\n bridge.selector\n )})`;\n\n shadowPath.push({\n host: bridge.host,\n hostSelector: bridge.selector,\n hostXPath: bridge.xpath,\n hostFullXPath: bridge.fullXPath,\n jsPath: hostExpression\n });\n expression = `${hostExpression}.shadowRoot`;\n }\n\n return {\n rootKind: getRootKind(bridges),\n selector,\n xpath,\n fullXPath,\n jsPath: `${expression}.querySelector(${JSON.stringify(selector)})`,\n framePath,\n shadowPath\n };\n}\n\nfunction getCssSegment(element: Element): string {\n const tagName = getTagName(element);\n\n if (ROOT_TAGS.has(tagName)) {\n return tagName;\n }\n\n if (!hasSameTagSibling(element)) {\n return tagName;\n }\n\n return `${tagName}:nth-child(${getElementIndex(element)})`;\n}\n\nfunction getTagName(element: Element): string {\n return element.localName.toLowerCase();\n}\n\nfunction getElementIndex(element: Element): number {\n const siblings = getElementSiblings(element);\n\n if (!siblings) {\n return 1;\n }\n\n return siblings.indexOf(element) + 1;\n}\n\nfunction getSameTagIndex(element: Element): number {\n const siblings = getElementSiblings(element);\n\n if (!siblings) {\n return 1;\n }\n\n const tagName = getTagName(element);\n let index = 0;\n\n for (const child of siblings) {\n if (getTagName(child) === tagName) {\n index += 1;\n }\n\n if (child === element) {\n return index;\n }\n }\n\n return 1;\n}\n\nfunction hasSameTagSibling(element: Element): boolean {\n const siblings = getElementSiblings(element);\n\n if (!siblings) {\n return false;\n }\n\n const tagName = getTagName(element);\n let count = 0;\n\n for (const child of siblings) {\n if (getTagName(child) === tagName) {\n count += 1;\n }\n\n if (count > 1) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction collectAccessBridges(\n element: Element,\n rootDocument: Document\n): AccessBridge[] {\n const bridges: AccessBridge[] = [];\n let current: Element = element;\n let root = current.getRootNode();\n\n while (true) {\n if (isShadowRoot(root)) {\n const host = root.host;\n\n bridges.push({\n kind: \"shadow\",\n host,\n selector: getCssSelector(host),\n xpath: getXPath(host),\n fullXPath: getXPath(host, { alwaysIncludeIndex: true })\n });\n\n current = host;\n root = current.getRootNode();\n continue;\n }\n\n if (isDocument(root) && root !== rootDocument) {\n const frameElement = findFrameElementForDocument(root, rootDocument);\n\n if (!frameElement) {\n break;\n }\n\n bridges.push({\n kind: \"iframe\",\n element: frameElement,\n selector: getCssSelector(frameElement),\n xpath: getXPath(frameElement),\n fullXPath: getXPath(frameElement, { alwaysIncludeIndex: true })\n });\n\n current = frameElement;\n root = current.getRootNode();\n continue;\n }\n\n break;\n }\n\n return bridges;\n}\n\nfunction getRootKind(bridges: AccessBridge[]): DOMPathRootKind {\n const innermostBridge = bridges[0];\n\n if (!innermostBridge) {\n return \"document\";\n }\n\n return innermostBridge.kind === \"shadow\" ? \"shadow\" : \"iframe\";\n}\n\nfunction findFrameElementForDocument(\n targetDocument: Document,\n searchDocument: Document\n): HTMLIFrameElement | null {\n const directFrame = targetDocument.defaultView?.frameElement;\n\n if (directFrame && getTagName(directFrame) === \"iframe\") {\n return directFrame as HTMLIFrameElement;\n }\n\n for (const frame of Array.from(searchDocument.querySelectorAll(\"iframe\"))) {\n const childDocument = getAccessibleFrameDocument(frame);\n\n if (!childDocument) {\n continue;\n }\n\n if (childDocument === targetDocument) {\n return frame;\n }\n\n const nestedFrame = findFrameElementForDocument(\n targetDocument,\n childDocument\n );\n\n if (nestedFrame) {\n return nestedFrame;\n }\n }\n\n return null;\n}\n\nfunction getAccessibleFrameDocument(\n frame: HTMLIFrameElement\n): Document | null {\n try {\n return frame.contentDocument?.documentElement ? frame.contentDocument : null;\n } catch {\n return null;\n }\n}\n\nfunction getElementSiblings(element: Element): Element[] | null {\n if (element.parentElement) {\n return Array.from(element.parentElement.children);\n }\n\n const parentNode = element.parentNode;\n\n if (!parentNode || parentNode.nodeType !== 11) {\n return null;\n }\n\n return Array.from(parentNode.childNodes).filter(isElement);\n}\n\nfunction isDocument(root: Node): root is Document {\n return root.nodeType === 9;\n}\n\nfunction isElement(node: Node): node is Element {\n return node.nodeType === 1;\n}\n\nfunction isShadowRoot(root: Node): root is ShadowRoot {\n return root.nodeType === 11 && \"host\" in root;\n}\n","export type DOMInspectorPseudoElement = \"::before\" | \"::after\";\n\nexport type RectLike = {\n bottom: number;\n height: number;\n left: number;\n right: number;\n top: number;\n width: number;\n x: number;\n y: number;\n};\n\nexport type PseudoElementHit = {\n pseudoElement: DOMInspectorPseudoElement;\n rect: RectLike;\n};\n\nexport type PseudoElementInfo = {\n pseudoElement: DOMInspectorPseudoElement;\n rect: RectLike | null;\n};\n\nexport type PseudoElementMatch = {\n hit: PseudoElementHit | null;\n pseudoElements: PseudoElementInfo[];\n};\n\nconst PSEUDO_ELEMENTS: DOMInspectorPseudoElement[] = [\"::after\", \"::before\"];\nconst HIT_SLOP = 4;\n\nexport function getPseudoElementHit(\n element: Element,\n clientX: number,\n clientY: number\n): PseudoElementHit | null {\n return getPseudoElementMatch(element, clientX, clientY).hit;\n}\n\nexport function getPseudoElementMatch(\n element: Element,\n clientX: number,\n clientY: number\n): PseudoElementMatch {\n const pseudoElements = getPseudoElements(element);\n\n for (const info of pseudoElements) {\n if (!info.rect) {\n continue;\n }\n\n if (containsPoint(info.rect, clientX, clientY, HIT_SLOP)) {\n return {\n hit: { pseudoElement: info.pseudoElement, rect: info.rect },\n pseudoElements\n };\n }\n }\n\n return { hit: null, pseudoElements };\n}\n\nexport function getPseudoElements(element: Element): PseudoElementInfo[] {\n const view = element.ownerDocument.defaultView;\n\n if (!view) {\n return [];\n }\n\n const pseudoElements: PseudoElementInfo[] = [];\n\n for (const pseudoElement of PSEUDO_ELEMENTS) {\n if (!hasVisiblePseudoElement(element, pseudoElement)) {\n continue;\n }\n\n pseudoElements.push({\n pseudoElement,\n rect: getPseudoElementRect(element, pseudoElement)\n });\n }\n\n return pseudoElements;\n}\n\nfunction getPseudoElementRect(\n element: Element,\n pseudoElement: DOMInspectorPseudoElement\n): RectLike | null {\n const view = element.ownerDocument.defaultView;\n\n if (!view) {\n return null;\n }\n\n const style = view.getComputedStyle(element, pseudoElement);\n\n if (!isVisiblePseudoStyle(style)) {\n return null;\n }\n\n const baseRect = element.getBoundingClientRect();\n const leftInset = readLength(style.left, baseRect.width);\n const rightInset = readLength(style.right, baseRect.width);\n const topInset = readLength(style.top, baseRect.height);\n const bottomInset = readLength(style.bottom, baseRect.height);\n let width = readLength(style.width, baseRect.width);\n let height = readLength(style.height, baseRect.height);\n const hasGeometrySignal =\n style.position === \"absolute\" ||\n style.position === \"fixed\" ||\n width !== null ||\n height !== null ||\n leftInset !== null ||\n rightInset !== null ||\n topInset !== null ||\n bottomInset !== null;\n\n if (!hasGeometrySignal) {\n return null;\n }\n\n if (width === null && leftInset !== null && rightInset !== null) {\n width = Math.max(baseRect.width - leftInset - rightInset, 0);\n }\n\n if (height === null && topInset !== null && bottomInset !== null) {\n height = Math.max(baseRect.height - topInset - bottomInset, 0);\n }\n\n if (width === null || height === null) {\n return null;\n }\n\n const x =\n leftInset !== null\n ? baseRect.left + leftInset\n : rightInset !== null\n ? baseRect.right - rightInset - width\n : pseudoElement === \"::before\"\n ? baseRect.left\n : baseRect.right - width;\n const y =\n topInset !== null\n ? baseRect.top + topInset\n : bottomInset !== null\n ? baseRect.bottom - bottomInset - height\n : pseudoElement === \"::before\"\n ? baseRect.top\n : baseRect.bottom - height;\n\n return {\n x,\n y,\n top: y,\n left: x,\n width,\n height,\n right: x + width,\n bottom: y + height\n };\n}\n\nfunction hasVisiblePseudoElement(\n element: Element,\n pseudoElement: DOMInspectorPseudoElement\n): boolean {\n const view = element.ownerDocument.defaultView;\n\n if (!view) {\n return false;\n }\n\n return isVisiblePseudoStyle(view.getComputedStyle(element, pseudoElement));\n}\n\nfunction isVisiblePseudoStyle(style: CSSStyleDeclaration | null): boolean {\n return Boolean(\n style &&\n style.display !== \"none\" &&\n style.visibility !== \"hidden\" &&\n style.content !== \"none\" &&\n style.content !== \"normal\"\n );\n}\n\nfunction containsPoint(\n rect: RectLike,\n clientX: number,\n clientY: number,\n slop: number\n): boolean {\n return (\n clientX >= rect.left - slop &&\n clientX <= rect.right + slop &&\n clientY >= rect.top - slop &&\n clientY <= rect.bottom + slop\n );\n}\n\nfunction readLength(value: string, basis: number): number | null {\n if (!value || value === \"auto\") {\n return null;\n }\n\n if (value.endsWith(\"%\")) {\n const percentage = Number.parseFloat(value);\n\n return Number.isFinite(percentage) ? (basis * percentage) / 100 : null;\n }\n\n const pixels = Number.parseFloat(value);\n\n return Number.isFinite(pixels) ? pixels : null;\n}\n","import { ElementHighlighter, type HighlighterOptions } from \"./overlay\";\nimport { getElementPath, type DOMElementPath } from \"./path\";\nimport {\n type DOMInspectorPseudoElement,\n getPseudoElementMatch,\n type PseudoElementInfo,\n type RectLike\n} from \"./pseudo\";\n\nexport type DOMInspectorHighlightOptions = HighlighterOptions;\n\nexport type DOMInspectorModifierKey = \"Alt\" | \"Control\" | \"Meta\" | \"Shift\";\n\nexport type DOMInspectorSelectionScopeOptions = {\n modifierKey?: DOMInspectorModifierKey;\n};\n\nexport type DOMInspectResult = DOMElementPath & {\n element: Element;\n ownerDocument: Document;\n pseudoElement: DOMInspectorPseudoElement | null;\n pseudoElements: PseudoElementInfo[];\n pseudoElementRect: RectLike | null;\n rect: DOMRect;\n event: MouseEvent;\n selectorWithPseudo: string;\n};\n\nexport type DOMInspectorOptions = {\n onSelect?: (result: DOMInspectResult) => void;\n onHover?: (result: DOMInspectResult) => void;\n onCancel?: () => void;\n autoStop?: boolean;\n preventDefault?: boolean;\n highlight?: boolean | DOMInspectorHighlightOptions;\n selectionScope?: false | DOMInspectorSelectionScopeOptions;\n document?: Document;\n exclude?: (element: Element) => boolean;\n};\n\nexport type DOMInspector = {\n start: () => void;\n stop: () => void;\n destroy: () => void;\n isActive: () => boolean;\n};\n\ntype ManagedDocument = {\n document: Document;\n highlighter: ElementHighlighter | null;\n observer: MutationObserver | null;\n previousCursor: string;\n};\n\nexport function createDOMInspector(options: DOMInspectorOptions): DOMInspector {\n return new DOMInspectorController(options);\n}\n\nclass DOMInspectorController implements DOMInspector {\n private readonly document: Document;\n private readonly frameLoadHandlers = new Map<HTMLIFrameElement, EventListener>();\n private readonly managedDocuments = new Map<Document, ManagedDocument>();\n private readonly selectionScope: Required<DOMInspectorSelectionScopeOptions> | null;\n private active = false;\n private hoveredElement: Element | null = null;\n private hoveredPseudoElement: DOMInspectorPseudoElement | null = null;\n private hoveredPath: Element[] = [];\n private hoveredPathIndex = 0;\n\n constructor(private readonly options: DOMInspectorOptions) {\n this.document = options.document ?? document;\n this.selectionScope = getSelectionScope(options.selectionScope);\n }\n\n start(): void {\n if (this.active) {\n return;\n }\n\n this.active = true;\n this.attachDocument(this.document);\n }\n\n stop(): void {\n if (!this.active) {\n return;\n }\n\n this.active = false;\n this.hoveredElement = null;\n this.hoveredPseudoElement = null;\n this.hoveredPath = [];\n this.hoveredPathIndex = 0;\n\n for (const [frame, handler] of this.frameLoadHandlers) {\n frame.removeEventListener(\"load\", handler);\n }\n\n this.frameLoadHandlers.clear();\n\n for (const state of this.managedDocuments.values()) {\n state.document.documentElement.style.cursor = state.previousCursor;\n state.document.removeEventListener(\"mousemove\", this.handleMouseMove, true);\n state.document.removeEventListener(\"mousedown\", this.handleMouseDown, true);\n state.document.removeEventListener(\"click\", this.handleClick, true);\n state.document.removeEventListener(\"keydown\", this.handleKeyDown, true);\n state.document.removeEventListener(\"wheel\", this.handleWheel, true);\n state.document.defaultView?.removeEventListener(\n \"scroll\",\n this.handleViewportChange,\n true\n );\n state.document.defaultView?.removeEventListener(\n \"resize\",\n this.handleViewportChange,\n true\n );\n state.observer?.disconnect();\n state.highlighter?.destroy();\n }\n\n this.managedDocuments.clear();\n }\n\n destroy(): void {\n this.stop();\n }\n\n isActive(): boolean {\n return this.active;\n }\n\n private readonly handleMouseMove = (event: MouseEvent): void => {\n const path = this.getInspectablePath(event);\n const target = path[0];\n\n if (!target) {\n return;\n }\n\n const nextIndex =\n this.hoveredPath[0] === target\n ? Math.min(this.hoveredPathIndex, path.length - 1)\n : 0;\n\n this.hoveredPath = path;\n this.hoveredPathIndex = nextIndex;\n this.updateHoveredElement(path[nextIndex]!, event);\n };\n\n private readonly handleMouseDown = (event: MouseEvent): void => {\n if (event.button !== 0) {\n return;\n }\n\n const target = this.getInspectablePath(event)[0];\n\n if (!target) {\n return;\n }\n\n if (this.options.preventDefault !== false) {\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n }\n };\n\n private readonly handleClick = (event: MouseEvent): void => {\n const path = this.getInspectablePath(event);\n const target = this.getClickTarget(path);\n\n if (!target) {\n return;\n }\n\n const result = this.createResult(target, event);\n\n if (this.options.preventDefault !== false) {\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n }\n\n this.showHighlight(result);\n\n try {\n this.options.onSelect?.(result);\n } finally {\n if (this.options.autoStop !== false) {\n this.stop();\n }\n }\n };\n\n private readonly handleWheel = (event: WheelEvent): void => {\n if (\n !this.selectionScope ||\n !hasModifierKey(event, this.selectionScope.modifierKey)\n ) {\n return;\n }\n\n const direction = getWheelDirection(event);\n\n if (direction === 0) {\n return;\n }\n\n const path = this.getInspectablePath(event);\n\n if (path.length > 0 && path[0] !== this.hoveredPath[0]) {\n this.hoveredPath = path;\n this.hoveredPathIndex = 0;\n }\n\n if (this.hoveredPath.length === 0) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n\n const nextIndex = clamp(\n this.hoveredPathIndex + direction,\n 0,\n this.hoveredPath.length - 1\n );\n\n if (nextIndex === this.hoveredPathIndex) {\n return;\n }\n\n this.hoveredPathIndex = nextIndex;\n this.updateHoveredElement(this.hoveredPath[nextIndex]!, event);\n };\n\n private readonly handleKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== \"Escape\") {\n return;\n }\n\n event.preventDefault();\n this.stop();\n this.options.onCancel?.();\n };\n\n private readonly handleViewportChange = (): void => {\n if (!this.hoveredElement) {\n return;\n }\n\n const highlighter = this.getHighlighter(this.hoveredElement.ownerDocument);\n\n if (highlighter) {\n this.hideInactiveHighlighters(this.hoveredElement.ownerDocument);\n highlighter.show(this.hoveredElement);\n }\n };\n\n private getInspectablePath(event: MouseEvent): Element[] {\n const path = event.composedPath().filter(isElementLike);\n\n if (path.some((entry) => this.options.exclude?.(entry))) {\n return [];\n }\n\n const inspectablePath: Element[] = [];\n\n for (const entry of path) {\n if (\n this.managedDocuments.has(entry.ownerDocument) &&\n !entry.hasAttribute(\"data-dom-inspector-overlay\")\n ) {\n inspectablePath.push(entry);\n }\n }\n\n if (inspectablePath.length > 0) {\n return inspectablePath;\n }\n\n return isElementLike(event.target) &&\n this.managedDocuments.has(event.target.ownerDocument)\n ? [event.target]\n : [];\n }\n\n private getClickTarget(path: Element[]): Element | null {\n if (this.hoveredElement && path.includes(this.hoveredElement)) {\n return this.hoveredElement;\n }\n\n return path[0] ?? null;\n }\n\n private updateHoveredElement(element: Element, event: MouseEvent): void {\n const result = this.createResult(element, event);\n\n if (\n element === this.hoveredElement &&\n result.pseudoElement === this.hoveredPseudoElement\n ) {\n return;\n }\n\n this.hoveredElement = element;\n this.hoveredPseudoElement = result.pseudoElement;\n this.showHighlight(result);\n this.options.onHover?.(result);\n }\n\n private createResult(element: Element, event: MouseEvent): DOMInspectResult {\n const path = getElementPath(element, { rootDocument: this.document });\n const pseudoMatch = getPseudoElementMatch(\n element,\n event.clientX,\n event.clientY\n );\n const pseudoHit = pseudoMatch.hit;\n\n return {\n ...path,\n element,\n ownerDocument: element.ownerDocument,\n pseudoElement: pseudoHit?.pseudoElement ?? null,\n pseudoElements: pseudoMatch.pseudoElements,\n pseudoElementRect: pseudoHit?.rect ?? null,\n rect: element.getBoundingClientRect(),\n event,\n selectorWithPseudo: pseudoHit\n ? `${path.selector}${pseudoHit.pseudoElement}`\n : path.selector\n };\n }\n\n private attachDocument(targetDocument: Document): void {\n if (this.managedDocuments.has(targetDocument)) {\n return;\n }\n\n const previousCursor = targetDocument.documentElement.style.cursor;\n const highlighter =\n this.options.highlight === false\n ? null\n : new ElementHighlighter(\n targetDocument,\n typeof this.options.highlight === \"object\"\n ? this.options.highlight\n : undefined\n );\n const Observer = targetDocument.defaultView?.MutationObserver;\n const observer = Observer\n ? new Observer(() => this.syncChildFrames(targetDocument))\n : null;\n\n targetDocument.documentElement.style.cursor = \"crosshair\";\n targetDocument.addEventListener(\"mousemove\", this.handleMouseMove, true);\n targetDocument.addEventListener(\"mousedown\", this.handleMouseDown, true);\n targetDocument.addEventListener(\"click\", this.handleClick, true);\n targetDocument.addEventListener(\"keydown\", this.handleKeyDown, true);\n targetDocument.addEventListener(\"wheel\", this.handleWheel, {\n capture: true,\n passive: false\n });\n targetDocument.defaultView?.addEventListener(\n \"scroll\",\n this.handleViewportChange,\n true\n );\n targetDocument.defaultView?.addEventListener(\n \"resize\",\n this.handleViewportChange,\n true\n );\n observer?.observe(targetDocument.documentElement, {\n childList: true,\n subtree: true\n });\n\n this.managedDocuments.set(targetDocument, {\n document: targetDocument,\n highlighter,\n observer,\n previousCursor\n });\n this.syncChildFrames(targetDocument);\n }\n\n private syncChildFrames(targetDocument: Document): void {\n for (const frame of Array.from(\n targetDocument.querySelectorAll(\"iframe\")\n )) {\n this.observeFrameLoad(frame);\n\n const frameDocument = getAccessibleFrameDocument(frame);\n\n if (frameDocument) {\n this.attachDocument(frameDocument);\n }\n }\n }\n\n private observeFrameLoad(frame: HTMLIFrameElement): void {\n if (this.frameLoadHandlers.has(frame)) {\n return;\n }\n\n const handler = (): void => {\n if (!this.active) {\n return;\n }\n\n const frameDocument = getAccessibleFrameDocument(frame);\n\n if (frameDocument) {\n this.attachDocument(frameDocument);\n }\n };\n\n frame.addEventListener(\"load\", handler);\n this.frameLoadHandlers.set(frame, handler);\n }\n\n private showHighlight(result: DOMInspectResult): void {\n const highlighter = this.getHighlighter(result.element.ownerDocument);\n\n if (!highlighter) {\n return;\n }\n\n this.hideInactiveHighlighters(result.element.ownerDocument);\n\n if (result.pseudoElementRect) {\n highlighter.showRect(result.pseudoElementRect);\n return;\n }\n\n highlighter.show(result.element);\n }\n\n private hideInactiveHighlighters(activeDocument: Document): void {\n for (const state of this.managedDocuments.values()) {\n if (state.document !== activeDocument) {\n state.highlighter?.hide();\n }\n }\n }\n\n private getHighlighter(targetDocument: Document): ElementHighlighter | null {\n return this.managedDocuments.get(targetDocument)?.highlighter ?? null;\n }\n}\n\nfunction getAccessibleFrameDocument(\n frame: HTMLIFrameElement\n): Document | null {\n try {\n return frame.contentDocument?.documentElement ? frame.contentDocument : null;\n } catch {\n return null;\n }\n}\n\nfunction getSelectionScope(\n options: false | DOMInspectorSelectionScopeOptions | undefined\n): Required<DOMInspectorSelectionScopeOptions> | null {\n if (options === false) {\n return null;\n }\n\n return {\n modifierKey: options?.modifierKey ?? \"Alt\"\n };\n}\n\nfunction hasModifierKey(\n event: MouseEvent,\n modifierKey: DOMInspectorModifierKey\n): boolean {\n switch (modifierKey) {\n case \"Alt\":\n return event.altKey;\n case \"Control\":\n return event.ctrlKey;\n case \"Meta\":\n return event.metaKey;\n case \"Shift\":\n return event.shiftKey;\n }\n}\n\nfunction getWheelDirection(event: WheelEvent): number {\n if (event.deltaY < 0) {\n return 1;\n }\n\n if (event.deltaY > 0) {\n return -1;\n }\n\n return 0;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction isElementLike(value: unknown): value is Element {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Node).nodeType === 1 &&\n typeof (value as Element).tagName === \"string\"\n );\n}\n"],"mappings":"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","names":["document","getAccessibleFrameDocument"]}
@@ -0,0 +1,103 @@
1
+ type HighlighterOptions = {
2
+ borderColor?: string;
3
+ backgroundColor?: string;
4
+ borderRadius?: number;
5
+ zIndex?: number;
6
+ };
7
+
8
+ type XPathOptions = {
9
+ /**
10
+ * Include [1] even when the element is the first or only matching sibling.
11
+ */
12
+ alwaysIncludeIndex?: boolean;
13
+ };
14
+ type DOMPathRootKind = "document" | "iframe" | "shadow";
15
+ type DOMInspectorFramePath = {
16
+ element: HTMLIFrameElement;
17
+ selector: string;
18
+ xpath: string;
19
+ fullXPath: string;
20
+ jsPath: string;
21
+ };
22
+ type DOMInspectorShadowPath = {
23
+ host: Element;
24
+ hostSelector: string;
25
+ hostXPath: string;
26
+ hostFullXPath: string;
27
+ jsPath: string;
28
+ };
29
+ type DOMElementPath = {
30
+ rootKind: DOMPathRootKind;
31
+ selector: string;
32
+ xpath: string;
33
+ fullXPath: string;
34
+ jsPath: string;
35
+ framePath: DOMInspectorFramePath[];
36
+ shadowPath: DOMInspectorShadowPath[];
37
+ };
38
+ declare function getCssSelector(element: Element): string;
39
+ declare function getXPath(element: Element, options?: XPathOptions): string;
40
+ declare function getJSPath(element: Element): string;
41
+ declare function getElementPath(element: Element, options?: {
42
+ rootDocument?: Document;
43
+ }): DOMElementPath;
44
+
45
+ type DOMInspectorPseudoElement = "::before" | "::after";
46
+ type RectLike = {
47
+ bottom: number;
48
+ height: number;
49
+ left: number;
50
+ right: number;
51
+ top: number;
52
+ width: number;
53
+ x: number;
54
+ y: number;
55
+ };
56
+ type PseudoElementHit = {
57
+ pseudoElement: DOMInspectorPseudoElement;
58
+ rect: RectLike;
59
+ };
60
+ type PseudoElementInfo = {
61
+ pseudoElement: DOMInspectorPseudoElement;
62
+ rect: RectLike | null;
63
+ };
64
+ type PseudoElementMatch = {
65
+ hit: PseudoElementHit | null;
66
+ pseudoElements: PseudoElementInfo[];
67
+ };
68
+
69
+ type DOMInspectorHighlightOptions = HighlighterOptions;
70
+ type DOMInspectorModifierKey = "Alt" | "Control" | "Meta" | "Shift";
71
+ type DOMInspectorSelectionScopeOptions = {
72
+ modifierKey?: DOMInspectorModifierKey;
73
+ };
74
+ type DOMInspectResult = DOMElementPath & {
75
+ element: Element;
76
+ ownerDocument: Document;
77
+ pseudoElement: DOMInspectorPseudoElement | null;
78
+ pseudoElements: PseudoElementInfo[];
79
+ pseudoElementRect: RectLike | null;
80
+ rect: DOMRect;
81
+ event: MouseEvent;
82
+ selectorWithPseudo: string;
83
+ };
84
+ type DOMInspectorOptions = {
85
+ onSelect?: (result: DOMInspectResult) => void;
86
+ onHover?: (result: DOMInspectResult) => void;
87
+ onCancel?: () => void;
88
+ autoStop?: boolean;
89
+ preventDefault?: boolean;
90
+ highlight?: boolean | DOMInspectorHighlightOptions;
91
+ selectionScope?: false | DOMInspectorSelectionScopeOptions;
92
+ document?: Document;
93
+ exclude?: (element: Element) => boolean;
94
+ };
95
+ type DOMInspector = {
96
+ start: () => void;
97
+ stop: () => void;
98
+ destroy: () => void;
99
+ isActive: () => boolean;
100
+ };
101
+ declare function createDOMInspector(options: DOMInspectorOptions): DOMInspector;
102
+
103
+ export { type DOMElementPath, type DOMInspectResult, type DOMInspector, type DOMInspectorFramePath, type DOMInspectorHighlightOptions, type DOMInspectorModifierKey, type DOMInspectorOptions, type DOMInspectorPseudoElement, type DOMInspectorSelectionScopeOptions, type DOMInspectorShadowPath, type DOMPathRootKind, type PseudoElementHit, type PseudoElementInfo, type PseudoElementMatch, type XPathOptions, createDOMInspector, getCssSelector, getElementPath, getJSPath, getXPath };
@@ -0,0 +1,103 @@
1
+ type HighlighterOptions = {
2
+ borderColor?: string;
3
+ backgroundColor?: string;
4
+ borderRadius?: number;
5
+ zIndex?: number;
6
+ };
7
+
8
+ type XPathOptions = {
9
+ /**
10
+ * Include [1] even when the element is the first or only matching sibling.
11
+ */
12
+ alwaysIncludeIndex?: boolean;
13
+ };
14
+ type DOMPathRootKind = "document" | "iframe" | "shadow";
15
+ type DOMInspectorFramePath = {
16
+ element: HTMLIFrameElement;
17
+ selector: string;
18
+ xpath: string;
19
+ fullXPath: string;
20
+ jsPath: string;
21
+ };
22
+ type DOMInspectorShadowPath = {
23
+ host: Element;
24
+ hostSelector: string;
25
+ hostXPath: string;
26
+ hostFullXPath: string;
27
+ jsPath: string;
28
+ };
29
+ type DOMElementPath = {
30
+ rootKind: DOMPathRootKind;
31
+ selector: string;
32
+ xpath: string;
33
+ fullXPath: string;
34
+ jsPath: string;
35
+ framePath: DOMInspectorFramePath[];
36
+ shadowPath: DOMInspectorShadowPath[];
37
+ };
38
+ declare function getCssSelector(element: Element): string;
39
+ declare function getXPath(element: Element, options?: XPathOptions): string;
40
+ declare function getJSPath(element: Element): string;
41
+ declare function getElementPath(element: Element, options?: {
42
+ rootDocument?: Document;
43
+ }): DOMElementPath;
44
+
45
+ type DOMInspectorPseudoElement = "::before" | "::after";
46
+ type RectLike = {
47
+ bottom: number;
48
+ height: number;
49
+ left: number;
50
+ right: number;
51
+ top: number;
52
+ width: number;
53
+ x: number;
54
+ y: number;
55
+ };
56
+ type PseudoElementHit = {
57
+ pseudoElement: DOMInspectorPseudoElement;
58
+ rect: RectLike;
59
+ };
60
+ type PseudoElementInfo = {
61
+ pseudoElement: DOMInspectorPseudoElement;
62
+ rect: RectLike | null;
63
+ };
64
+ type PseudoElementMatch = {
65
+ hit: PseudoElementHit | null;
66
+ pseudoElements: PseudoElementInfo[];
67
+ };
68
+
69
+ type DOMInspectorHighlightOptions = HighlighterOptions;
70
+ type DOMInspectorModifierKey = "Alt" | "Control" | "Meta" | "Shift";
71
+ type DOMInspectorSelectionScopeOptions = {
72
+ modifierKey?: DOMInspectorModifierKey;
73
+ };
74
+ type DOMInspectResult = DOMElementPath & {
75
+ element: Element;
76
+ ownerDocument: Document;
77
+ pseudoElement: DOMInspectorPseudoElement | null;
78
+ pseudoElements: PseudoElementInfo[];
79
+ pseudoElementRect: RectLike | null;
80
+ rect: DOMRect;
81
+ event: MouseEvent;
82
+ selectorWithPseudo: string;
83
+ };
84
+ type DOMInspectorOptions = {
85
+ onSelect?: (result: DOMInspectResult) => void;
86
+ onHover?: (result: DOMInspectResult) => void;
87
+ onCancel?: () => void;
88
+ autoStop?: boolean;
89
+ preventDefault?: boolean;
90
+ highlight?: boolean | DOMInspectorHighlightOptions;
91
+ selectionScope?: false | DOMInspectorSelectionScopeOptions;
92
+ document?: Document;
93
+ exclude?: (element: Element) => boolean;
94
+ };
95
+ type DOMInspector = {
96
+ start: () => void;
97
+ stop: () => void;
98
+ destroy: () => void;
99
+ isActive: () => boolean;
100
+ };
101
+ declare function createDOMInspector(options: DOMInspectorOptions): DOMInspector;
102
+
103
+ export { type DOMElementPath, type DOMInspectResult, type DOMInspector, type DOMInspectorFramePath, type DOMInspectorHighlightOptions, type DOMInspectorModifierKey, type DOMInspectorOptions, type DOMInspectorPseudoElement, type DOMInspectorSelectionScopeOptions, type DOMInspectorShadowPath, type DOMPathRootKind, type PseudoElementHit, type PseudoElementInfo, type PseudoElementMatch, type XPathOptions, createDOMInspector, getCssSelector, getElementPath, getJSPath, getXPath };