geoproject-app/src/composables/useCssSync.js

120 lines
4 KiB
JavaScript
Raw Normal View History

import { useStylesheetStore } from '../stores/stylesheet';
export function useCssSync() {
const store = useStylesheetStore();
/**
* Extract a simple CSS value (string)
*/
const extractValue = (selector, property) => {
const block = store.extractBlock(selector);
if (!block) return null;
const match = block.match(new RegExp(`${property}:\\s*([^;]+)`, 'i'));
return match ? match[1].trim() : null;
};
/**
* Extract a numeric CSS value with unit
* Returns { value: number, unit: string } or null
*/
const extractNumericValue = (selector, property, allowedUnits = ['px', 'em', 'rem', 'mm']) => {
const block = store.extractBlock(selector);
if (!block) return null;
const unitsPattern = allowedUnits.join('|');
const match = block.match(new RegExp(`${property}:\\s*([0-9.]+)(${unitsPattern})`, 'i'));
if (match) {
return {
value: parseFloat(match[1]),
unit: match[2].toLowerCase()
};
}
return null;
};
/**
* Extract margin/padding shorthand (handles 1 or 4 values)
* Returns { simple: { value, unit } } or { detailed: { top, right, bottom, left } }
*/
const extractSpacing = (selector, property, allowedUnits = ['mm', 'px']) => {
const block = store.extractBlock(selector);
if (!block) return null;
const unitsPattern = allowedUnits.join('|');
// Check for detailed properties first (property-top, property-right, etc.)
const topMatch = block.match(new RegExp(`${property}-top:\\s*([0-9.]+)(${unitsPattern})`, 'i'));
if (topMatch) {
const rightMatch = block.match(new RegExp(`${property}-right:\\s*([0-9.]+)(${unitsPattern})`, 'i'));
const bottomMatch = block.match(new RegExp(`${property}-bottom:\\s*([0-9.]+)(${unitsPattern})`, 'i'));
const leftMatch = block.match(new RegExp(`${property}-left:\\s*([0-9.]+)(${unitsPattern})`, 'i'));
return {
detailed: {
top: topMatch ? { value: parseFloat(topMatch[1]), unit: topMatch[2] } : { value: 0, unit: 'mm' },
right: rightMatch ? { value: parseFloat(rightMatch[1]), unit: rightMatch[2] } : { value: 0, unit: 'mm' },
bottom: bottomMatch ? { value: parseFloat(bottomMatch[1]), unit: bottomMatch[2] } : { value: 0, unit: 'mm' },
left: leftMatch ? { value: parseFloat(leftMatch[1]), unit: leftMatch[2] } : { value: 0, unit: 'mm' },
}
};
}
// Check for shorthand property
const shorthandMatch = block.match(new RegExp(`${property}:\\s*([^;]+)`, 'i'));
if (!shorthandMatch) return null;
const shorthandValue = shorthandMatch[1].trim();
// Check for 4-value format: "0mm 0mm 24mm 0mm" (top right bottom left)
const fourValuePattern = new RegExp(
`^([0-9.]+)(${unitsPattern})\\s+([0-9.]+)(${unitsPattern})\\s+([0-9.]+)(${unitsPattern})\\s+([0-9.]+)(${unitsPattern})$`,
'i'
);
const fourValueMatch = shorthandValue.match(fourValuePattern);
if (fourValueMatch) {
return {
detailed: {
top: { value: parseFloat(fourValueMatch[1]), unit: fourValueMatch[2] },
right: { value: parseFloat(fourValueMatch[3]), unit: fourValueMatch[4] },
bottom: { value: parseFloat(fourValueMatch[5]), unit: fourValueMatch[6] },
left: { value: parseFloat(fourValueMatch[7]), unit: fourValueMatch[8] },
}
};
}
// Single value format: "10mm"
const singleValuePattern = new RegExp(`^([0-9.]+)(${unitsPattern})$`, 'i');
const singleValueMatch = shorthandValue.match(singleValuePattern);
if (singleValueMatch) {
return {
simple: {
value: parseFloat(singleValueMatch[1]),
unit: singleValueMatch[2]
}
};
}
return null;
};
/**
* Check if a property value equals a specific string
*/
const hasValue = (selector, property, expectedValue) => {
const value = extractValue(selector, property);
return value === expectedValue;
};
return {
extractValue,
extractNumericValue,
extractSpacing,
hasValue,
};
}