mirror of
https://github.com/svg/svgo.git
synced 2025-07-28 09:22:00 +03:00
chore: drop parentNode property (#2113)
This commit is contained in:
@ -107,11 +107,6 @@ export const parseSvg = (data, from) => {
|
|||||||
* @type {(node: XastChild) => void}
|
* @type {(node: XastChild) => void}
|
||||||
*/
|
*/
|
||||||
const pushToContent = (node) => {
|
const pushToContent = (node) => {
|
||||||
// TODO remove legacy parentNode in v4
|
|
||||||
Object.defineProperty(node, 'parentNode', {
|
|
||||||
writable: true,
|
|
||||||
value: current,
|
|
||||||
});
|
|
||||||
current.children.push(node);
|
current.children.push(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
20
lib/style.js
20
lib/style.js
@ -10,15 +10,16 @@ import {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('css-tree').Rule} CsstreeRule
|
* @typedef {import('css-tree').Rule} CsstreeRule
|
||||||
|
* @typedef {import('./types.js').ComputedStyles} ComputedStyles
|
||||||
* @typedef {import('./types.js').Specificity} Specificity
|
* @typedef {import('./types.js').Specificity} Specificity
|
||||||
* @typedef {import('./types.js').Stylesheet} Stylesheet
|
* @typedef {import('./types.js').Stylesheet} Stylesheet
|
||||||
* @typedef {import('./types.js').StylesheetRule} StylesheetRule
|
|
||||||
* @typedef {import('./types.js').StylesheetDeclaration} StylesheetDeclaration
|
* @typedef {import('./types.js').StylesheetDeclaration} StylesheetDeclaration
|
||||||
* @typedef {import('./types.js').ComputedStyles} ComputedStyles
|
* @typedef {import('./types.js').StylesheetRule} StylesheetRule
|
||||||
* @typedef {import('./types.js').XastRoot} XastRoot
|
|
||||||
* @typedef {import('./types.js').XastElement} XastElement
|
|
||||||
* @typedef {import('./types.js').XastParent} XastParent
|
|
||||||
* @typedef {import('./types.js').XastChild} XastChild
|
* @typedef {import('./types.js').XastChild} XastChild
|
||||||
|
* @typedef {import('./types.js').XastElement} XastElement
|
||||||
|
* @typedef {import('./types.js').XastNode} XastNode
|
||||||
|
* @typedef {import('./types.js').XastParent} XastParent
|
||||||
|
* @typedef {import('./types.js').XastRoot} XastRoot
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const csstreeWalkSkip = csstree.walk.skip;
|
const csstreeWalkSkip = csstree.walk.skip;
|
||||||
@ -130,9 +131,10 @@ const parseStyleDeclarations = (css) => {
|
|||||||
/**
|
/**
|
||||||
* @param {Stylesheet} stylesheet
|
* @param {Stylesheet} stylesheet
|
||||||
* @param {XastElement} node
|
* @param {XastElement} node
|
||||||
|
* @param {Map<XastNode, XastParent>=} parents
|
||||||
* @returns {ComputedStyles}
|
* @returns {ComputedStyles}
|
||||||
*/
|
*/
|
||||||
const computeOwnStyle = (stylesheet, node) => {
|
const computeOwnStyle = (stylesheet, node, parents = undefined) => {
|
||||||
/** @type {ComputedStyles} */
|
/** @type {ComputedStyles} */
|
||||||
const computedStyle = {};
|
const computedStyle = {};
|
||||||
const importantStyles = new Map();
|
const importantStyles = new Map();
|
||||||
@ -147,7 +149,7 @@ const computeOwnStyle = (stylesheet, node) => {
|
|||||||
|
|
||||||
// collect matching rules
|
// collect matching rules
|
||||||
for (const { selector, declarations, dynamic } of stylesheet.rules) {
|
for (const { selector, declarations, dynamic } of stylesheet.rules) {
|
||||||
if (matches(node, selector)) {
|
if (matches(node, selector, parents)) {
|
||||||
for (const { name, value, important } of declarations) {
|
for (const { name, value, important } of declarations) {
|
||||||
const computed = computedStyle[name];
|
const computed = computedStyle[name];
|
||||||
if (computed && computed.type === 'dynamic') {
|
if (computed && computed.type === 'dynamic') {
|
||||||
@ -259,10 +261,10 @@ export const collectStylesheet = (root) => {
|
|||||||
*/
|
*/
|
||||||
export const computeStyle = (stylesheet, node) => {
|
export const computeStyle = (stylesheet, node) => {
|
||||||
const { parents } = stylesheet;
|
const { parents } = stylesheet;
|
||||||
const computedStyles = computeOwnStyle(stylesheet, node);
|
const computedStyles = computeOwnStyle(stylesheet, node, parents);
|
||||||
let parent = parents.get(node);
|
let parent = parents.get(node);
|
||||||
while (parent != null && parent.type !== 'root') {
|
while (parent != null && parent.type !== 'root') {
|
||||||
const inheritedStyles = computeOwnStyle(stylesheet, parent);
|
const inheritedStyles = computeOwnStyle(stylesheet, parent, parents);
|
||||||
for (const [name, computed] of Object.entries(inheritedStyles)) {
|
for (const [name, computed] of Object.entries(inheritedStyles)) {
|
||||||
if (
|
if (
|
||||||
computedStyles[name] == null &&
|
computedStyles[name] == null &&
|
||||||
|
@ -11,9 +11,7 @@ import { parseSvg } from './parser.js';
|
|||||||
* @type {(node: XastParent, id: string) => XastElement}
|
* @type {(node: XastParent, id: string) => XastElement}
|
||||||
*/
|
*/
|
||||||
const getElementById = (node, id) => {
|
const getElementById = (node, id) => {
|
||||||
/**
|
/** @type {?XastElement} */
|
||||||
* @type {?XastElement}
|
|
||||||
*/
|
|
||||||
let matched = null;
|
let matched = null;
|
||||||
visit(node, {
|
visit(node, {
|
||||||
element: {
|
element: {
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
VERSION,
|
VERSION,
|
||||||
optimize as optimizeAgnostic,
|
optimize as optimizeAgnostic,
|
||||||
builtinPlugins,
|
builtinPlugins,
|
||||||
|
mapNodesToParents,
|
||||||
querySelector,
|
querySelector,
|
||||||
querySelectorAll,
|
querySelectorAll,
|
||||||
_collections,
|
_collections,
|
||||||
@ -113,6 +114,7 @@ export default {
|
|||||||
builtinPlugins,
|
builtinPlugins,
|
||||||
loadConfig,
|
loadConfig,
|
||||||
optimize,
|
optimize,
|
||||||
|
mapNodesToParents,
|
||||||
querySelector,
|
querySelector,
|
||||||
querySelectorAll,
|
querySelectorAll,
|
||||||
_collections,
|
_collections,
|
||||||
|
2
lib/svgo.d.ts
vendored
2
lib/svgo.d.ts
vendored
@ -162,4 +162,4 @@ export declare const VERSION: string;
|
|||||||
/** The core of SVGO */
|
/** The core of SVGO */
|
||||||
export declare function optimize(input: string, config?: Config): Output;
|
export declare function optimize(input: string, config?: Config): Output;
|
||||||
|
|
||||||
export { querySelector, querySelectorAll } from './xast.js';
|
export { mapNodesToParents, querySelector, querySelectorAll } from './xast.js';
|
||||||
|
@ -4,7 +4,7 @@ import { builtin } from './builtin.js';
|
|||||||
import { invokePlugins } from './svgo/plugins.js';
|
import { invokePlugins } from './svgo/plugins.js';
|
||||||
import { encodeSVGDatauri } from './svgo/tools.js';
|
import { encodeSVGDatauri } from './svgo/tools.js';
|
||||||
import { VERSION } from './version.js';
|
import { VERSION } from './version.js';
|
||||||
import { querySelector, querySelectorAll } from './xast.js';
|
import { mapNodesToParents, querySelector, querySelectorAll } from './xast.js';
|
||||||
import _collections from '../plugins/_collections.js';
|
import _collections from '../plugins/_collections.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,6 +78,7 @@ const resolvePluginConfig = (plugin) => {
|
|||||||
export {
|
export {
|
||||||
VERSION,
|
VERSION,
|
||||||
builtin as builtinPlugins,
|
builtin as builtinPlugins,
|
||||||
|
mapNodesToParents,
|
||||||
querySelector,
|
querySelector,
|
||||||
querySelectorAll,
|
querySelectorAll,
|
||||||
_collections,
|
_collections,
|
||||||
@ -147,6 +148,7 @@ export default {
|
|||||||
VERSION,
|
VERSION,
|
||||||
optimize,
|
optimize,
|
||||||
builtinPlugins: builtin,
|
builtinPlugins: builtin,
|
||||||
|
mapNodesToParents,
|
||||||
querySelector,
|
querySelector,
|
||||||
querySelectorAll,
|
querySelectorAll,
|
||||||
_collections,
|
_collections,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @typedef {Required<import('css-select').Options<XastNode & { children?: any }, XastElement & { parentNode?: any }>>['adapter']} Adapter
|
* @typedef {Required<import('css-select').Options<XastNode & { children?: any }, XastElement>>['adapter']} Adapter
|
||||||
* @typedef {import('../types.js').XastChild} XastChild
|
* @typedef {import('../types.js').XastChild} XastChild
|
||||||
* @typedef {import('../types.js').XastElement} XastElement
|
* @typedef {import('../types.js').XastElement} XastElement
|
||||||
* @typedef {import('../types.js').XastNode} XastNode
|
* @typedef {import('../types.js').XastNode} XastNode
|
||||||
@ -33,20 +33,6 @@ const getName = (elemAst) => {
|
|||||||
return elemAst.name;
|
return elemAst.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @type {Adapter['getParent']} */
|
|
||||||
const getParent = (node) => {
|
|
||||||
return node.parentNode || null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {any} elem
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
const getSiblings = (elem) => {
|
|
||||||
const parent = getParent(elem);
|
|
||||||
return parent ? getChildren(parent) : [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {Adapter['getText']} */
|
/** @type {Adapter['getText']} */
|
||||||
const getText = (node) => {
|
const getText = (node) => {
|
||||||
if (node.children[0].type === 'text' || node.children[0].type === 'cdata') {
|
if (node.children[0].type === 'text' || node.children[0].type === 'cdata') {
|
||||||
@ -60,38 +46,6 @@ const hasAttrib = (elem, name) => {
|
|||||||
return elem.attributes[name] !== undefined;
|
return elem.attributes[name] !== undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {any} nodes
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
const removeSubsets = (nodes) => {
|
|
||||||
let idx = nodes.length;
|
|
||||||
let node;
|
|
||||||
let ancestor;
|
|
||||||
let replace;
|
|
||||||
// Check if each node (or one of its ancestors) is already contained in the
|
|
||||||
// array.
|
|
||||||
while (--idx > -1) {
|
|
||||||
node = ancestor = nodes[idx];
|
|
||||||
// Temporarily remove the node under consideration
|
|
||||||
nodes[idx] = null;
|
|
||||||
replace = true;
|
|
||||||
while (ancestor) {
|
|
||||||
if (nodes.includes(ancestor)) {
|
|
||||||
replace = false;
|
|
||||||
nodes.splice(idx, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ancestor = getParent(ancestor);
|
|
||||||
}
|
|
||||||
// If the node has been found to be unique, re-insert it.
|
|
||||||
if (replace) {
|
|
||||||
nodes[idx] = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {Adapter['findAll']} */
|
/** @type {Adapter['findAll']} */
|
||||||
const findAll = (test, elems) => {
|
const findAll = (test, elems) => {
|
||||||
const result = [];
|
const result = [];
|
||||||
@ -123,19 +77,68 @@ const findOne = (test, elems) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Adapter}
|
* @param {Map<XastNode, XastParent>} parents
|
||||||
|
* @returns {Adapter}
|
||||||
*/
|
*/
|
||||||
export default {
|
export function createAdapter(parents) {
|
||||||
isTag,
|
/** @type {Adapter['getParent']} */
|
||||||
existsOne,
|
const getParent = (node) => {
|
||||||
getAttributeValue,
|
return parents.get(node) || null;
|
||||||
getChildren,
|
};
|
||||||
getName,
|
|
||||||
getParent,
|
/**
|
||||||
getSiblings,
|
* @param {any} elem
|
||||||
getText,
|
* @returns {any}
|
||||||
hasAttrib,
|
*/
|
||||||
removeSubsets,
|
const getSiblings = (elem) => {
|
||||||
findAll,
|
const parent = getParent(elem);
|
||||||
findOne,
|
return parent ? getChildren(parent) : [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} nodes
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
const removeSubsets = (nodes) => {
|
||||||
|
let idx = nodes.length;
|
||||||
|
let node;
|
||||||
|
let ancestor;
|
||||||
|
let replace;
|
||||||
|
// Check if each node (or one of its ancestors) is already contained in the
|
||||||
|
// array.
|
||||||
|
while (--idx > -1) {
|
||||||
|
node = ancestor = nodes[idx];
|
||||||
|
// Temporarily remove the node under consideration
|
||||||
|
nodes[idx] = null;
|
||||||
|
replace = true;
|
||||||
|
while (ancestor) {
|
||||||
|
if (nodes.includes(ancestor)) {
|
||||||
|
replace = false;
|
||||||
|
nodes.splice(idx, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ancestor = getParent(ancestor);
|
||||||
|
}
|
||||||
|
// If the node has been found to be unique, re-insert it.
|
||||||
|
if (replace) {
|
||||||
|
nodes[idx] = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
isTag,
|
||||||
|
existsOne,
|
||||||
|
getAttributeValue,
|
||||||
|
getChildren,
|
||||||
|
getName,
|
||||||
|
getParent,
|
||||||
|
getSiblings,
|
||||||
|
getText,
|
||||||
|
hasAttrib,
|
||||||
|
removeSubsets,
|
||||||
|
findAll,
|
||||||
|
findOne,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
76
lib/xast.js
76
lib/xast.js
@ -1,8 +1,8 @@
|
|||||||
import { selectAll, selectOne, is } from 'css-select';
|
import { selectAll, selectOne, is } from 'css-select';
|
||||||
import adapter from './svgo/css-select-adapter.js';
|
import { createAdapter } from './svgo/css-select-adapter.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('css-select').Options<XastNode & { children?: any }, XastElement & { parentNode?: any }>} Options
|
* @typedef {import('css-select').Options<XastNode & { children?: any }, XastElement>} Options
|
||||||
* @typedef {import('./types.js').XastElement} XastElement
|
* @typedef {import('./types.js').XastElement} XastElement
|
||||||
* @typedef {import('./types.js').XastNode} XastNode
|
* @typedef {import('./types.js').XastNode} XastNode
|
||||||
* @typedef {import('./types.js').XastChild} XastChild
|
* @typedef {import('./types.js').XastChild} XastChild
|
||||||
@ -10,37 +10,81 @@ import adapter from './svgo/css-select-adapter.js';
|
|||||||
* @typedef {import('./types.js').Visitor} Visitor
|
* @typedef {import('./types.js').Visitor} Visitor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @type {Options} */
|
/**
|
||||||
const cssSelectOptions = {
|
* @param {Map<XastNode, XastParent>} parents
|
||||||
xmlMode: true,
|
* @returns {Options}
|
||||||
adapter,
|
*/
|
||||||
};
|
function createCssSelectOptions(parents) {
|
||||||
|
return {
|
||||||
|
xmlMode: true,
|
||||||
|
adapter: createAdapter(parents),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {XastNode} node Element to query the children of.
|
* Maps all nodes to their parent node recursively.
|
||||||
|
*
|
||||||
|
* @param {XastParent} node
|
||||||
|
* @returns {Map<XastNode, XastParent>}
|
||||||
|
*/
|
||||||
|
export function mapNodesToParents(node) {
|
||||||
|
/** @type {Map<XastNode, XastParent>} */
|
||||||
|
const parents = new Map();
|
||||||
|
|
||||||
|
for (const child of node.children) {
|
||||||
|
parents.set(child, node);
|
||||||
|
visit(
|
||||||
|
child,
|
||||||
|
{
|
||||||
|
element: {
|
||||||
|
enter: (child, parent) => {
|
||||||
|
parents.set(child, parent);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
node,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {XastParent} node Element to query the children of.
|
||||||
* @param {string} selector CSS selector string.
|
* @param {string} selector CSS selector string.
|
||||||
|
* @param {Map<XastNode, XastParent>=} parents
|
||||||
* @returns {XastChild[]} All matching elements.
|
* @returns {XastChild[]} All matching elements.
|
||||||
*/
|
*/
|
||||||
export const querySelectorAll = (node, selector) => {
|
export const querySelectorAll = (
|
||||||
return selectAll(selector, node, cssSelectOptions);
|
node,
|
||||||
|
selector,
|
||||||
|
parents = mapNodesToParents(node),
|
||||||
|
) => {
|
||||||
|
return selectAll(selector, node, createCssSelectOptions(parents));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {XastNode} node Element to query the children of.
|
* @param {XastParent} node Element to query the children of.
|
||||||
* @param {string} selector CSS selector string.
|
* @param {string} selector CSS selector string.
|
||||||
|
* @param {Map<XastNode, XastParent>=} parents
|
||||||
* @returns {?XastChild} First match, or null if there was no match.
|
* @returns {?XastChild} First match, or null if there was no match.
|
||||||
*/
|
*/
|
||||||
export const querySelector = (node, selector) => {
|
export const querySelector = (
|
||||||
return selectOne(selector, node, cssSelectOptions);
|
node,
|
||||||
|
selector,
|
||||||
|
parents = mapNodesToParents(node),
|
||||||
|
) => {
|
||||||
|
return selectOne(selector, node, createCssSelectOptions(parents));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {XastElement} node
|
* @param {XastElement} node
|
||||||
* @param {string} selector
|
* @param {string} selector
|
||||||
|
* @param {Map<XastNode, XastParent>=} parents
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export const matches = (node, selector) => {
|
export const matches = (node, selector, parents = mapNodesToParents(node)) => {
|
||||||
return is(node, selector, cssSelectOptions);
|
return is(node, selector, createCssSelectOptions(parents));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const visitSkip = Symbol();
|
export const visitSkip = Symbol();
|
||||||
@ -48,7 +92,7 @@ export const visitSkip = Symbol();
|
|||||||
/**
|
/**
|
||||||
* @param {XastNode} node
|
* @param {XastNode} node
|
||||||
* @param {Visitor} visitor
|
* @param {Visitor} visitor
|
||||||
* @param {?any} parentNode
|
* @param {any=} parentNode
|
||||||
*/
|
*/
|
||||||
export const visit = (node, visitor, parentNode = undefined) => {
|
export const visit = (node, visitor, parentNode = undefined) => {
|
||||||
const callbacks = visitor[node.type];
|
const callbacks = visitor[node.type];
|
||||||
|
@ -129,13 +129,6 @@ export const fn = (root) => {
|
|||||||
// replace current node with all its children
|
// replace current node with all its children
|
||||||
const index = parentNode.children.indexOf(node);
|
const index = parentNode.children.indexOf(node);
|
||||||
parentNode.children.splice(index, 1, ...node.children);
|
parentNode.children.splice(index, 1, ...node.children);
|
||||||
// TODO remove legacy parentNode in v4
|
|
||||||
for (const child of node.children) {
|
|
||||||
Object.defineProperty(child, 'parentNode', {
|
|
||||||
writable: true,
|
|
||||||
value: parentNode,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -83,11 +83,6 @@ export const fn = () => {
|
|||||||
* @type {XastChild}
|
* @type {XastChild}
|
||||||
*/
|
*/
|
||||||
const child = { type: styleContentType, value: collectedStyles };
|
const child = { type: styleContentType, value: collectedStyles };
|
||||||
// TODO remove legacy parentNode in v4
|
|
||||||
Object.defineProperty(child, 'parentNode', {
|
|
||||||
writable: true,
|
|
||||||
value: firstStyleElement,
|
|
||||||
});
|
|
||||||
firstStyleElement.children = [child];
|
firstStyleElement.children = [child];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -55,14 +55,6 @@ export const fn = () => {
|
|||||||
(child) => child.type !== 'text',
|
(child) => child.type !== 'text',
|
||||||
);
|
);
|
||||||
parentNode.children.splice(index, 1, ...usefulChildren);
|
parentNode.children.splice(index, 1, ...usefulChildren);
|
||||||
|
|
||||||
// TODO remove legacy parentNode in v4
|
|
||||||
for (const child of node.children) {
|
|
||||||
Object.defineProperty(child, 'parentNode', {
|
|
||||||
writable: true,
|
|
||||||
value: parentNode,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -32,13 +32,6 @@ export const fn = () => {
|
|||||||
if (usefulNodes.length === 0) {
|
if (usefulNodes.length === 0) {
|
||||||
detachNodeFromParent(node, parentNode);
|
detachNodeFromParent(node, parentNode);
|
||||||
}
|
}
|
||||||
// TODO remove legacy parentNode in v4
|
|
||||||
for (const usefulNode of usefulNodes) {
|
|
||||||
Object.defineProperty(usefulNode, 'parentNode', {
|
|
||||||
writable: true,
|
|
||||||
value: node,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
node.children = usefulNodes;
|
node.children = usefulNodes;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -92,11 +92,6 @@ export const fn = (root) => {
|
|||||||
attributes: {},
|
attributes: {},
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
// TODO remove legacy parentNode in v4
|
|
||||||
Object.defineProperty(defsTag, 'parentNode', {
|
|
||||||
writable: true,
|
|
||||||
value: node,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
@ -129,11 +124,6 @@ export const fn = (root) => {
|
|||||||
reusablePath.attributes.id = originalId;
|
reusablePath.attributes.id = originalId;
|
||||||
delete list[0].attributes.id;
|
delete list[0].attributes.id;
|
||||||
}
|
}
|
||||||
// TODO remove legacy parentNode in v4
|
|
||||||
Object.defineProperty(reusablePath, 'parentNode', {
|
|
||||||
writable: true,
|
|
||||||
value: defsTag,
|
|
||||||
});
|
|
||||||
defsTag.children.push(reusablePath);
|
defsTag.children.push(reusablePath);
|
||||||
// convert paths to <use>
|
// convert paths to <use>
|
||||||
for (const pathNode of list) {
|
for (const pathNode of list) {
|
||||||
|
Reference in New Issue
Block a user