repair panel CSS

This commit is contained in:
Julie Blanc 2026-03-06 17:39:09 +01:00
parent 564de8aba8
commit 295f63d271

View file

@ -3,7 +3,7 @@
ref="basePopup"
id="element-popup"
:display-css="displayedCss"
:editable-css="elementCss"
:editable-css="editableFullCss"
:popup-width="800"
:popup-height="600"
:show-inheritance="false"
@ -596,6 +596,12 @@ const displayedCss = computed(() => {
return `${selector.value} {\n${lines.join('\n')}\n}`;
});
// Editable CSS: same as displayedCss but without "valeur par défaut" comments
// Special group defaults are always visible in edit mode so the user can modify them
const editableFullCss = computed(() => {
return displayedCss.value.replace(/ \/\* valeur par défaut \*\//g, '');
});
// Apply all properties for a given group to the stylesheet
const applyGroup = (group) => {
if (!selector.value) return;
@ -822,8 +828,45 @@ const parseCssProperties = (cssText) => {
return result;
};
// Check if a special group's parsed CSS value differs from its textDefaults value
const specialGroupDiffersFromDefault = (group, parsed) => {
switch (group) {
case 'font': {
if ('font-family' in parsed) {
const val = parsed['font-family'].split(',')[0].trim().replace(/['"]/g, '');
if (val !== textDefaults.fontFamily) return true;
}
if ('font-style' in parsed && parsed['font-style'].trim() === 'italic') return true;
if ('font-weight' in parsed) {
const v = parsed['font-weight'].trim();
if (v === 'bold' || parseInt(v) >= 700) return true;
}
return false;
}
case 'fontSize': {
if ('font-size' in parsed) {
const m = parsed['font-size'].match(/([\d.]+)(px|rem|em|mm|cm|in)?/);
if (m) return parseFloat(m[1]) !== textDefaults.fontSize.value || (m[2] || 'px') !== textDefaults.fontSize.unit;
}
return false;
}
case 'lineHeight': {
if ('line-height' in parsed) {
const m = parsed['line-height'].match(/([\d.]+)(px|rem|em|mm|cm|in)?/);
if (m) return parseFloat(m[1]) !== textDefaults.lineHeight.value || (m[2] || 'px') !== textDefaults.lineHeight.unit;
}
return false;
}
case 'color': {
if ('color' in parsed) return parsed['color'].trim() !== textDefaults.color;
return false;
}
}
return false;
};
// Sync refs from edited CSS text (bidirectional: textarea inputs)
// For special groups: if user adds/modifies a property, it becomes a "user value" (toggle ON)
// For special groups: only enable toggle if value differs from default
const syncRefsFromCss = (cssText) => {
const parsed = parseCssProperties(cssText);
const specialGroupNames = ['font', 'fontSize', 'lineHeight', 'color'];
@ -836,7 +879,6 @@ const syncRefsFromCss = (cssText) => {
for (const prop of styleProps) {
if (prop.group !== group || !(prop.css in parsed)) continue;
if (prop.css === 'font-family') {
// Take first font from the stack, strip quotes
const firstFont = parsed[prop.css].split(',')[0].trim().replace(/['"]/g, '');
fontFamily.value = firstFont;
} else {
@ -868,17 +910,22 @@ const syncRefsFromCss = (cssText) => {
}
}
// Auto-enable toggle if it was OFF (user explicitly wrote the property)
// Auto-enable toggle if it was OFF
if (!settingEnabled[group]) {
settingEnabled[group] = true;
if (specialGroupNames.includes(group)) {
settingCache[group] = null;
// Special groups: only enable if value differs from default
if (specialGroupDiffersFromDefault(group, parsed)) {
settingEnabled[group] = true;
settingCache[group] = null;
}
} else {
settingEnabled[group] = true;
}
}
} else if (settingEnabled[group]) {
// All properties from this group were removed disable toggle
settingEnabled[group] = false;
// For special groups, reset to defaults (user intentionally removed)
// For special groups, reset to defaults
if (group === 'font') {
fontFamily.value = textDefaults.fontFamily;
italic.value = false;
@ -904,15 +951,48 @@ const syncRefsFromCss = (cssText) => {
const handleCssInput = (newCss) => {
isUpdatingFromStore = true;
// Sync refs and toggles from the edited CSS
syncRefsFromCss(newCss);
// Build store block: exclude disabled special group properties
// (they are shown in the textarea as defaults but should not be persisted)
const parsed = parseCssProperties(newCss);
const specialGroupPropsMap = {
font: ['font-family', 'font-style', 'font-weight'],
fontSize: ['font-size'],
lineHeight: ['line-height'],
color: ['color'],
};
const excludedProps = new Set();
for (const [group, props] of Object.entries(specialGroupPropsMap)) {
if (!settingEnabled[group]) {
props.forEach(p => excludedProps.add(p));
}
}
const storeParts = [];
for (const [prop, val] of Object.entries(parsed)) {
if (!excludedProps.has(prop)) {
storeParts.push(` ${prop}: ${val};`);
}
}
const storeBlock = storeParts.length
? `${selector.value} {\n${storeParts.join('\n')}\n}\n`
: '';
const oldBlock = elementCss.value;
if (oldBlock) {
stylesheetStore.replaceInCustomCss(oldBlock, newCss);
} else if (newCss.trim()) {
if (oldBlock && storeBlock) {
stylesheetStore.replaceInCustomCss(oldBlock, storeBlock);
} else if (oldBlock && !storeBlock) {
stylesheetStore.replaceInCustomCss(oldBlock, '');
} else if (!oldBlock && storeBlock) {
stylesheetStore.setCustomCss(
(stylesheetStore.customCss ? stylesheetStore.customCss + '\n' : '') + newCss
(stylesheetStore.customCss ? stylesheetStore.customCss + '\n' : '') + storeBlock
);
}
syncRefsFromCss(newCss);
nextTick(() => { isUpdatingFromStore = false; });
};