diff --git a/inventory/static/js/components/draw.js b/inventory/static/js/components/draw.js index 7963123..f5a3f5d 100644 --- a/inventory/static/js/components/draw.js +++ b/inventory/static/js/components/draw.js @@ -1,7 +1,3 @@ -document.querySelectorAll('[data-grid-widget]').forEach((root, index) => { - initGridWidget(root, { storageKey: `gridDoc:${index}` }); -}); - let activeGridWidget = null; document.addEventListener('keydown', (e) => { @@ -619,12 +615,6 @@ function initGridWidget(root, opts = {}) { } function snapToGrid(x, y) { - /* - Shapes are stored in grid units (document units), not pixels. - 1 unit renders as cellSize pixels, so changing cellSize rescales (zooms) the whole drawing. - Grid modes only affect snapping/visuals; storage is always in document units for portability. - */ - const rect = gridEl.getBoundingClientRect(); const clampedX = Math.min(Math.max(x, rect.left), rect.right); const clampedY = Math.min(Math.max(y, rect.top), rect.bottom); @@ -636,9 +626,6 @@ function initGridWidget(root, opts = {}) { const maxIx = Math.floor(rect.width / grid); const maxIy = Math.floor(rect.height / grid); - // Math.round means we actually snap to the nearest dot. Math.floor - // makes for ugly snapping behavior where it only goes to the top left - // of the cell. Cells are not where we draw to, so floor is not good. const ix = Math.min(Math.max(Math.round(localX / grid), 0), maxIx); const iy = Math.min(Math.max(Math.round(localY / grid), 0), maxIy); @@ -1028,4 +1015,54 @@ function initGridWidget(root, opts = {}) { }; } }); -} \ No newline at end of file +} + +(function autoBootGridWidgets() { + function bootRoot(root) { + if (root.__gridBooted) return; + root.__gridBooted = true; + + const mode = root.dataset.mode || 'editor'; + const storageKey = root.dataset.storageKey || root.dataset.key || 'gridDoc'; + + const api = initGridWidget(root, { mode, storageKey }); + root.__gridApi = api; + + if (mode !== 'editor') { + const script = root.querySelector('[data-grid-doc]'); + if (script?.textContent?.trim()) { + try { api.setDoc(JSON.parse(script.textContent)); } catch { } + return; + } + + const src = root.dataset.src; + if (src) { + fetch(src, { credentials: 'same-origin' }) + .then(r => r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`))) + .then(doc => api.setDoc(doc)) + .catch(() => { }); + return; + } + + const raw = root.dataset.doc; + if (raw) { + try { api.setDoc(JSON.parse(raw)); } catch { } + } + } + } + + document.querySelectorAll('[data-grid-widget]').forEach(bootRoot); + + const mo = new MutationObserver((mutations) => { + for (const m of mutations) { + for (const node of m.addedNodes) { + if (!(node instanceof Element)) continue; + + if (node.matches?.('[data-grid-widget]')) bootRoot(node); + node.querySelectorAll?.('[data-grid-widget]').forEach(bootRoot); + } + } + }); + + mo.observe(document.documentElement, { childList: true, subtree: true }); +})(); diff --git a/inventory/templates/components/draw.html b/inventory/templates/components/draw.html index 4627b83..263aafa 100644 --- a/inventory/templates/components/draw.html +++ b/inventory/templates/components/draw.html @@ -1,5 +1,5 @@ {% macro drawWidget(uid) %} -
+
@@ -196,7 +196,7 @@ - 100% + 100%