mirror of
https://github.com/svg/svgo.git
synced 2025-07-31 07:44:22 +03:00
Add plugin types (#1527)
Covered following plugins - addAttributesToSVGElement.js - addClassesToSVGElement.js - cleanupAttrs.js - convertEllipseToCircle.js - removeAttributesBySelector.js - removeAttrs.js - removeComments.js - removeDesc.js - removeDoctype.js - removeElementsByAttr.js - removeEmptyText.js - removeMetadata.js - removeRasterImages.js - removeScriptElement.js - removeStyleElement.js - removeTitle.js - removeXMLProcInst.js
This commit is contained in:
31
lib/xast.js
31
lib/xast.js
@ -1,5 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types').XastNode} XastNode
|
||||
* @typedef {import('./types').XastChild} XastChild
|
||||
* @typedef {import('./types').XastParent} XastParent
|
||||
* @typedef {import('./types').Visitor} Visitor
|
||||
*/
|
||||
|
||||
const { selectAll, selectOne, is } = require('css-select');
|
||||
const xastAdaptor = require('./svgo/css-select-adapter.js');
|
||||
|
||||
@ -8,27 +15,40 @@ const cssSelectOptions = {
|
||||
adapter: xastAdaptor,
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {(node: XastNode, selector: string) => Array<XastChild>}
|
||||
*/
|
||||
const querySelectorAll = (node, selector) => {
|
||||
return selectAll(selector, node, cssSelectOptions);
|
||||
};
|
||||
exports.querySelectorAll = querySelectorAll;
|
||||
|
||||
/**
|
||||
* @type {(node: XastNode, selector: string) => null | XastChild}
|
||||
*/
|
||||
const querySelector = (node, selector) => {
|
||||
return selectOne(selector, node, cssSelectOptions);
|
||||
};
|
||||
exports.querySelector = querySelector;
|
||||
|
||||
/**
|
||||
* @type {(node: XastChild, selector: string) => boolean}
|
||||
*/
|
||||
const matches = (node, selector) => {
|
||||
return is(node, selector, cssSelectOptions);
|
||||
};
|
||||
exports.matches = matches;
|
||||
|
||||
/**
|
||||
* @type {(node: XastChild, name: string) => null | XastChild}
|
||||
*/
|
||||
const closestByName = (node, name) => {
|
||||
let currentNode = node;
|
||||
while (currentNode) {
|
||||
if (currentNode.type === 'element' && currentNode.name === name) {
|
||||
return currentNode;
|
||||
}
|
||||
// @ts-ignore parentNode is hidden from public usage
|
||||
currentNode = currentNode.parentNode;
|
||||
}
|
||||
return null;
|
||||
@ -38,6 +58,9 @@ exports.closestByName = closestByName;
|
||||
const traverseBreak = Symbol();
|
||||
exports.traverseBreak = traverseBreak;
|
||||
|
||||
/**
|
||||
* @type {(node: any, fn: any) => any}
|
||||
*/
|
||||
const traverse = (node, fn) => {
|
||||
if (fn(node) === traverseBreak) {
|
||||
return traverseBreak;
|
||||
@ -52,7 +75,10 @@ const traverse = (node, fn) => {
|
||||
};
|
||||
exports.traverse = traverse;
|
||||
|
||||
const visit = (node, visitor, parentNode = null) => {
|
||||
/**
|
||||
* @type {(node: any, visitor: any, parentNode: any) => void}
|
||||
*/
|
||||
const visit = (node, visitor, parentNode) => {
|
||||
const callbacks = visitor[node.type];
|
||||
if (callbacks && callbacks.enter) {
|
||||
callbacks.enter(node, parentNode);
|
||||
@ -78,6 +104,9 @@ const visit = (node, visitor, parentNode = null) => {
|
||||
};
|
||||
exports.visit = visit;
|
||||
|
||||
/**
|
||||
* @type {(node: XastChild, parentNode: XastParent) => void}
|
||||
*/
|
||||
const detachNodeFromParent = (node, parentNode) => {
|
||||
// avoid splice to not break for loops
|
||||
parentNode.children = parentNode.children.filter((child) => child !== node);
|
||||
|
Reference in New Issue
Block a user