From ae8136a48e7d7abbcc11824ea6d057f9042c890f Mon Sep 17 00:00:00 2001 From: isUnknown Date: Mon, 24 Nov 2025 18:18:27 +0100 Subject: [PATCH] refactor: make EditorPanel and ElementPopup fully autonomous MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move all popup logic into ElementPopup component (state, positioning, click handling) - Make EditorPanel autonomous with direct store access - Simplify App.vue by removing prop drilling and intermediary logic - Update EditorPanel to control paragraph font-size instead of .about - Fix CSS parsing: escape selectors in extractCssValue and updateCssValue - Remove hardcoded .about references from PagedJsWrapper 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- public/assets/css/stylesheet.css | 8 +-- src/App.vue | 81 ++----------------------------- src/components/EditorPanel.vue | 39 +++++++-------- src/components/ElementPopup.vue | 60 ++++++++++++++++++----- src/components/PagedJsWrapper.vue | 4 +- src/utils/css-parsing.js | 6 ++- 6 files changed, 82 insertions(+), 116 deletions(-) diff --git a/public/assets/css/stylesheet.css b/public/assets/css/stylesheet.css index 98badef..ea6e1c4 100644 --- a/public/assets/css/stylesheet.css +++ b/public/assets/css/stylesheet.css @@ -1,7 +1,7 @@ -.about { - font-size: 1rem; -} - #chapter-2 { font-size: 2rem; } + +p { + font-size: 1rem; +} diff --git a/src/App.vue b/src/App.vue index 9e417b4..99dca4e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -47,18 +47,14 @@ const injectStylesToIframe = () => { styleElement.textContent = stylesheetStore.content; }; +const elementPopup = ref(null); + const renderPreview = async () => { const iframe = previewFrame.value; if (!iframe) return; await stylesheetStore.loadStylesheet(); - const initialFontSize = stylesheetStore.extractValue('.about', 'font-size'); - if (initialFontSize) { - aboutFontSize.value = initialFontSize.value; - aboutFontSizeUnit.value = initialFontSize.unit; - } - iframe.srcdoc = ` @@ -73,68 +69,10 @@ const renderPreview = async () => { `; iframe.onload = () => { - iframe.contentDocument.addEventListener('click', handleIframeClick); + iframe.contentDocument.addEventListener('click', elementPopup.value.handleIframeClick); }; }; -// ============================================================================ -// Editor panel (temporary hardcoded .about selector) -// ============================================================================ -const aboutFontSize = ref(2); -const aboutFontSizeUnit = ref('rem'); - -watch(aboutFontSize, (newVal) => { - stylesheetStore.updateProperty( - '.about', - 'font-size', - newVal, - aboutFontSizeUnit.value - ); -}); - -// ============================================================================ -// Element popup -// ============================================================================ -const popupVisible = ref(false); -const popupPosition = ref({ x: 0, y: 0 }); -const popupSelector = ref(''); - -const getSelectorFromElement = (element) => { - return element.id - ? `#${element.id}` - : `.${element.className.split(' ')[0]}`; -}; - -const calculatePopupPosition = (element) => { - const rect = element.getBoundingClientRect(); - const iframeRect = previewFrame.value.getBoundingClientRect(); - return { - x: iframeRect.left + rect.left, - y: iframeRect.top + rect.bottom + 5, - }; -}; - -const openPopup = (element) => { - popupSelector.value = getSelectorFromElement(element); - popupPosition.value = calculatePopupPosition(element); - popupVisible.value = true; -}; - -const closePopup = () => { - popupVisible.value = false; -}; - -const handleIframeClick = (event) => { - const element = event.target; - - if (element.tagName === 'BODY' || element.tagName === 'HTML') { - closePopup(); - return; - } - - openPopup(element); -}; - // ============================================================================ // Lifecycle // ============================================================================ @@ -147,22 +85,13 @@ onMounted(renderPreview); - + - +