Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
One-time setup that gathers your project's design context and saves it to CLAUDE.md for future sessions.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/live-browser-dom.js
1/**2* Browser-side DOM helpers for Impeccable live mode.3*4* Kept separate from live-browser.js so future browser script parts can share5* chrome mounting, lookup, focus, and picker helpers without depending on the6* full overlay UI bundle.7*/8(function (root) {9'use strict';10if (!root) return;1112function createLiveBrowserDomHelpers({13prefix,14skipTags,15document: doc = root.document,16css = root.CSS,17crypto = root.crypto,18} = {}) {19if (!prefix) throw new Error('prefix required');20if (!doc) throw new Error('document required');21const tagsToSkip = skipTags || new Set();2223function own(el) {24return el && (el.id?.startsWith(prefix) || el.closest?.('[id^="' + prefix + '"]'));25}2627function pickable(el) {28if (!el || el.nodeType !== 1) return false;29if (tagsToSkip.has(String(el.tagName || '').toLowerCase())) return false;30if (own(el)) return false;31const r = el.getBoundingClientRect();32return r.width >= 20 && r.height >= 20;33}3435function desc(el) {36if (!el) return '';37let s = el.tagName.toLowerCase();38if (el.id) s += '#' + el.id;39else if (el.classList.length) s += '.' + [...el.classList].slice(0, 2).join('.');40return s;41}4243function rectIsUsableAnchor(rect) {44return !!rect && rect.width > 0.5 && rect.height > 0.5;45}4647function makeFrozenAnchor(el) {48if (!el || !el.getBoundingClientRect) return null;49const r = el.getBoundingClientRect();50if (!rectIsUsableAnchor(r)) return null;51const rect = {52x: r.x, y: r.y,53top: r.top, left: r.left,54right: r.right, bottom: r.bottom,55width: r.width, height: r.height,56};57return {58__impeccableFrozenAnchor: true,59tagName: el.tagName || 'DIV',60id: el.id || '',61classList: el.classList ? [...el.classList] : [],62hasAttribute: () => false,63getBoundingClientRect: () => rect,64};65}6667function id8() {68if (crypto?.randomUUID) return crypto.randomUUID().replace(/-/g, '').slice(0, 8);69return (Math.random().toString(16).slice(2) + Date.now().toString(16)).slice(0, 8);70}7172function cssId(id) {73if (css?.escape) return css.escape(id);74return String(id).replace(/([ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, '\\$1');75}7677function liveUiRoot() {78const uiRoot = root.__IMPECCABLE_LIVE_UI_ROOT__;79if (uiRoot && typeof uiRoot.appendChild === 'function') return uiRoot;80return doc.body;81}8283function uiAppend(el) {84liveUiRoot().appendChild(el);85return el;86}8788function uiAppendStyle(styleEl) {89const uiRoot = liveUiRoot();90if (uiRoot && uiRoot !== doc.body) uiRoot.appendChild(styleEl);91else doc.head.appendChild(styleEl);92return styleEl;93}9495function uiGetById(id) {96const uiRoot = liveUiRoot();97if (uiRoot?.getElementById) {98const found = uiRoot.getElementById(id);99if (found) return found;100}101if (uiRoot?.querySelector) {102const found = uiRoot.querySelector('#' + cssId(id));103if (found) return found;104}105return doc.getElementById(id);106}107108function activeElementDeep() {109let active = doc.activeElement;110while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;111return active;112}113114function defangOutsideHandlers(rootEl, { setPointerEvents = true } = {}) {115if (!rootEl) return;116if (setPointerEvents) {117rootEl.style.setProperty('pointer-events', 'auto', 'important');118}119const stop = (e) => e.stopPropagation();120rootEl.addEventListener('pointerdown', stop);121rootEl.addEventListener('mousedown', stop);122rootEl.addEventListener('focusin', stop);123}124125return {126own,127pickable,128desc,129rectIsUsableAnchor,130makeFrozenAnchor,131id8,132cssId,133liveUiRoot,134uiAppend,135uiAppendStyle,136uiGetById,137activeElementDeep,138defangOutsideHandlers,139};140}141142root.__IMPECCABLE_LIVE_DOM__ = {143version: 1,144createLiveBrowserDomHelpers,145};146})(typeof window !== 'undefined' ? window : globalThis);147