mirror of
https://github.com/svg/svgo.git
synced 2025-07-31 07:44:22 +03:00
Add "visitor" plugins support (#1454)
Visitor is a simple pattern which helps to avoid many type checks and provide both "perItem" and "perItemReverse" functionality without fragmentation. The most important case is an ability to define state which in many plugins specified either on module level or by polluting `params`. In this diff I added visit and detachFromParent utilities and refactored new mergeStyles plugin with it. Also fixed bug when cdata content is merged into "text" node which is not always valid.
This commit is contained in:
33
lib/xast.js
33
lib/xast.js
@ -51,3 +51,36 @@ const traverse = (node, fn) => {
|
||||
}
|
||||
};
|
||||
exports.traverse = traverse;
|
||||
|
||||
const visit = (node, visitor) => {
|
||||
const callbacks = visitor[node.type];
|
||||
if (callbacks && callbacks.enter) {
|
||||
callbacks.enter(node);
|
||||
}
|
||||
// visit root children
|
||||
if (node.type === 'root') {
|
||||
// copy children array to not loose cursor when children is spliced
|
||||
for (const child of node.children) {
|
||||
visit(child, visitor);
|
||||
}
|
||||
}
|
||||
// visit element children if still attached to parent
|
||||
if (node.type === 'element') {
|
||||
if (node.parentNode.children.includes(node)) {
|
||||
for (const child of node.children) {
|
||||
visit(child, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (callbacks && callbacks.exit) {
|
||||
callbacks.exit(node);
|
||||
}
|
||||
};
|
||||
exports.visit = visit;
|
||||
|
||||
const detachNodeFromParent = (node) => {
|
||||
const parentNode = node.parentNode;
|
||||
// avoid splice to not break for loops
|
||||
parentNode.children = parentNode.children.filter((child) => child !== node);
|
||||
};
|
||||
exports.detachNodeFromParent = detachNodeFromParent;
|
||||
|
Reference in New Issue
Block a user