From d9f3ede661eb256de3fdcbed08a04f21b80c848b Mon Sep 17 00:00:00 2001 From: isUnknown Date: Wed, 10 Dec 2025 12:04:58 +0100 Subject: [PATCH] feat: persist inheritance lock state per element via data attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Store unlock state in data-inheritance-unlocked attribute on DOM element - Each element/page now remembers its own inheritance state - Re-locking removes element-specific CSS block to restore inheritance - Elements revert to general styles from TextSettings/PageSettings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/components/ElementPopup.vue | 35 ++++++++++++++++++++++++++++++++- src/components/PagePopup.vue | 13 ++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/components/ElementPopup.vue b/src/components/ElementPopup.vue index de79b52..9d36142 100644 --- a/src/components/ElementPopup.vue +++ b/src/components/ElementPopup.vue @@ -369,6 +369,22 @@ const elementCss = computed(() => { return stylesheetStore.extractBlock(selector.value) || ''; }); +// Remove the element-specific CSS block to restore inheritance +const removeElementBlock = () => { + if (!selector.value) return; + + const block = stylesheetStore.extractBlock(selector.value); + if (block) { + // Escape special regex characters in selector + const escaped = selector.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + // Remove the block and any surrounding whitespace + stylesheetStore.content = stylesheetStore.content.replace( + new RegExp(`\\n?${escaped}\\s*\\{[^}]*\\}\\n?`), + '\n' + ); + } +}; + const highlightedCss = computed(() => { if (!elementCss.value) return ''; return hljs.highlight(elementCss.value, { language: 'css' }).value; @@ -601,6 +617,9 @@ const open = (element, event, count = null) => { // Store instance count if provided, otherwise calculate it elementInstanceCount.value = count !== null ? count : getInstanceCount(selector.value); + // Read inheritance state from element's data attribute + inheritanceLocked.value = element.dataset.inheritanceUnlocked !== 'true'; + // Load values from stylesheet loadValuesFromStylesheet(); @@ -664,8 +683,22 @@ const handleIframeClick = (event, targetElement = null, elementCount = null) => }; const toggleInheritance = () => { + const wasLocked = inheritanceLocked.value; inheritanceLocked.value = !inheritanceLocked.value; - // TODO: Implement CSS priority logic when unlocked + + // Store the inheritance state in the element's data attribute + if (selectedElement.value) { + if (inheritanceLocked.value) { + delete selectedElement.value.dataset.inheritanceUnlocked; + } else { + selectedElement.value.dataset.inheritanceUnlocked = 'true'; + } + } + + // When re-locking, remove the element-specific CSS block to restore inheritance + if (inheritanceLocked.value && !wasLocked) { + removeElementBlock(); + } }; defineExpose({ handleIframeClick, close, visible }); diff --git a/src/components/PagePopup.vue b/src/components/PagePopup.vue index c48c390..aae5505 100644 --- a/src/components/PagePopup.vue +++ b/src/components/PagePopup.vue @@ -532,8 +532,8 @@ const open = (pageElement, event, count = 1) => { // Extract template name from data-page-type attribute templateName.value = pageElement.getAttribute('data-page-type') || ''; - // Reset inheritance state when opening - inheritanceLocked.value = true; + // Read inheritance state from page element's data attribute + inheritanceLocked.value = pageElement.dataset.inheritanceUnlocked !== 'true'; // Load values from stylesheet (@page block) loadValuesFromStylesheet(); @@ -583,6 +583,15 @@ const toggleInheritance = () => { const wasLocked = inheritanceLocked.value; inheritanceLocked.value = !inheritanceLocked.value; + // Store the inheritance state in the page element's data attribute + if (selectedPageElement.value) { + if (inheritanceLocked.value) { + delete selectedPageElement.value.dataset.inheritanceUnlocked; + } else { + selectedPageElement.value.dataset.inheritanceUnlocked = 'true'; + } + } + if (inheritanceLocked.value && !wasLocked) { // Re-locking: remove the template-specific block // Fields keep their values, but preview returns to @page defaults