mirror of
https://github.com/svg/svgo.git
synced 2025-07-31 07:44:22 +03:00
Drop node.style usages (#1534)
Parsing inline styles with csstree in place is easier. Caching does not add much value here.
This commit is contained in:
37
lib/style.js
37
lib/style.js
@ -78,7 +78,10 @@ const parseStylesheet = (css, dynamic) => {
|
||||
* @type {Array<StylesheetRule>}
|
||||
*/
|
||||
const rules = [];
|
||||
const ast = csstree.parse(css);
|
||||
const ast = csstree.parse(css, {
|
||||
parseValue: false,
|
||||
parseAtrulePrelude: false,
|
||||
});
|
||||
csstree.walk(ast, (cssNode) => {
|
||||
if (cssNode.type === 'Rule') {
|
||||
rules.push(parseRule(cssNode, dynamic || false));
|
||||
@ -100,6 +103,30 @@ const parseStylesheet = (css, dynamic) => {
|
||||
return rules;
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {(css: string) => Array<StylesheetDeclaration>}
|
||||
*/
|
||||
const parseStyleDeclarations = (css) => {
|
||||
/**
|
||||
* @type {Array<StylesheetDeclaration>}
|
||||
*/
|
||||
const declarations = [];
|
||||
const ast = csstree.parse(css, {
|
||||
context: 'declarationList',
|
||||
parseValue: false,
|
||||
});
|
||||
csstree.walk(ast, (cssNode) => {
|
||||
if (cssNode.type === 'Declaration') {
|
||||
declarations.push({
|
||||
name: cssNode.property,
|
||||
value: csstree.generate(cssNode.value),
|
||||
important: cssNode.important === true,
|
||||
});
|
||||
}
|
||||
});
|
||||
return declarations;
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {(stylesheet: Array<StylesheetRule>, node: XastElement) => ComputedStyles}
|
||||
*/
|
||||
@ -143,10 +170,12 @@ const computeOwnStyle = (stylesheet, node) => {
|
||||
}
|
||||
|
||||
// collect inline styles
|
||||
// @ts-ignore node.style is hidden from pubilc usage
|
||||
for (const [name, { value, priority }] of node.style.properties) {
|
||||
const styleDeclarations =
|
||||
node.attributes.style == null
|
||||
? []
|
||||
: parseStyleDeclarations(node.attributes.style);
|
||||
for (const { name, value, important } of styleDeclarations) {
|
||||
const computed = computedStyle[name];
|
||||
const important = priority === 'important';
|
||||
if (computed && computed.type === 'dynamic') {
|
||||
continue;
|
||||
}
|
||||
|
@ -148,32 +148,51 @@ exports.fn = function (root, opts) {
|
||||
if (selector.rule === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const styleDeclarationList = csstree.parse(
|
||||
selectedEl.attributes.style == null ? '' : selectedEl.attributes.style,
|
||||
{
|
||||
context: 'declarationList',
|
||||
parseValue: false,
|
||||
}
|
||||
);
|
||||
const styleDeclarationItems = new Map();
|
||||
csstree.walk(styleDeclarationList, {
|
||||
visit: 'Declaration',
|
||||
enter(node, item) {
|
||||
styleDeclarationItems.set(node.property, item);
|
||||
},
|
||||
});
|
||||
// merge declarations
|
||||
csstree.walk(selector.rule, {
|
||||
visit: 'Declaration',
|
||||
enter: function (styleCsstreeDeclaration) {
|
||||
enter(ruleDeclaration) {
|
||||
// existing inline styles have higher priority
|
||||
// no inline styles, external styles, external styles used
|
||||
// inline styles, external styles same priority as inline styles, inline styles used
|
||||
// inline styles, external styles higher priority than inline styles, external styles used
|
||||
var styleDeclaration = cssTools.csstreeToStyleDeclaration(
|
||||
styleCsstreeDeclaration
|
||||
const matchedItem = styleDeclarationItems.get(
|
||||
ruleDeclaration.property
|
||||
);
|
||||
if (
|
||||
selectedEl.style.getPropertyValue(styleDeclaration.name) !== null &&
|
||||
selectedEl.style.getPropertyPriority(styleDeclaration.name) >=
|
||||
styleDeclaration.priority
|
||||
const ruleDeclarationItem =
|
||||
styleDeclarationList.children.createItem(ruleDeclaration);
|
||||
if (matchedItem == null) {
|
||||
styleDeclarationList.children.append(ruleDeclarationItem);
|
||||
} else if (
|
||||
matchedItem.data.important !== true &&
|
||||
ruleDeclaration.important === true
|
||||
) {
|
||||
return;
|
||||
styleDeclarationList.children.replace(
|
||||
matchedItem,
|
||||
ruleDeclarationItem
|
||||
);
|
||||
styleDeclarationItems.set(
|
||||
ruleDeclaration.property,
|
||||
ruleDeclarationItem
|
||||
);
|
||||
}
|
||||
selectedEl.style.setProperty(
|
||||
styleDeclaration.name,
|
||||
styleDeclaration.value,
|
||||
styleDeclaration.priority
|
||||
);
|
||||
},
|
||||
});
|
||||
selectedEl.attributes.style = csstree.generate(styleDeclarationList);
|
||||
}
|
||||
|
||||
if (
|
||||
|
Reference in New Issue
Block a user