From a3da8b3a76cee22bc650801b860e07629c68429d Mon Sep 17 00:00:00 2001 From: Seth Falco Date: Sun, 24 Dec 2023 01:54:17 +0000 Subject: [PATCH] refactor: use set in _collections (#1899) --- lib/parser.js | 2 +- lib/stringifier.js | 2 +- lib/style.js | 46 +- lib/svgo/tools.js | 2 +- plugins/_collections.js | 1460 +++++++++++---------- plugins/applyTransforms.js | 2 +- plugins/collapseGroups.js | 6 +- plugins/convertColors.js | 2 +- plugins/convertOneStopGradients.js | 2 +- plugins/convertPathData.js | 2 +- plugins/convertStyleToAttrs.js | 2 +- plugins/inlineStyles.js | 2 +- plugins/moveElemsAttrsToGroup.js | 4 +- plugins/moveGroupAttrsToElems.js | 2 +- plugins/removeEditorsNSData.js | 2 +- plugins/removeEmptyAttrs.js | 2 +- plugins/removeEmptyContainers.js | 2 +- plugins/removeHiddenElems.js | 2 +- plugins/removeNonInheritableGroupAttrs.js | 6 +- plugins/removeUnknownsAndDefaults.js | 2 +- plugins/removeUselessDefs.js | 2 +- plugins/removeUselessStrokeAndFill.js | 2 +- plugins/removeViewBox.js | 4 +- plugins/removeXlink.js | 8 +- 24 files changed, 810 insertions(+), 758 deletions(-) diff --git a/lib/parser.js b/lib/parser.js index 73875df64..4359373a9 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -213,7 +213,7 @@ const parseSvg = (data, from) => { sax.ontext = (text) => { if (current.type === 'element') { // prevent trimming of meaningful whitespace inside textual tags - if (textElems.includes(current.name)) { + if (textElems.has(current.name)) { /** * @type {XastText} */ diff --git a/lib/stringifier.js b/lib/stringifier.js index e50e723c5..1a710869d 100644 --- a/lib/stringifier.js +++ b/lib/stringifier.js @@ -235,7 +235,7 @@ const stringifyElement = (node, config, state) => { tagCloseStart = defaults.tagCloseStart; tagCloseEnd = defaults.tagCloseEnd; openIndent = ''; - } else if (textElems.includes(node.name)) { + } else if (textElems.has(node.name)) { tagOpenEnd = defaults.tagOpenEnd; tagCloseStart = defaults.tagCloseStart; closeIndent = ''; diff --git a/lib/style.js b/lib/style.js index 8a993523b..e54993a3c 100644 --- a/lib/style.js +++ b/lib/style.js @@ -130,7 +130,9 @@ const parseStyleDeclarations = (css) => { }; /** - * @type {(stylesheet: Stylesheet, node: XastElement) => ComputedStyles} + * @param {Stylesheet} stylesheet + * @param {XastElement} node + * @returns {ComputedStyles} */ const computeOwnStyle = (stylesheet, node) => { /** @type {ComputedStyles} */ @@ -139,7 +141,7 @@ const computeOwnStyle = (stylesheet, node) => { // collect attributes for (const [name, value] of Object.entries(node.attributes)) { - if (attrsGroups.presentation.includes(name)) { + if (attrsGroups.presentation.has(name)) { computedStyle[name] = { type: 'static', inherited: false, value }; importantStyles.set(name, false); } @@ -217,29 +219,31 @@ exports.compareSpecificity = compareSpecificity; * @type {(root: XastRoot) => Stylesheet} */ const collectStylesheet = (root) => { - /** @type {Array} */ + /** @type {StylesheetRule[]} */ const rules = []; /** @type {Map} */ const parents = new Map(); + visit(root, { element: { enter: (node, parentNode) => { - // store parents parents.set(node, parentNode); - // find and parse all styles - if (node.name === 'style') { + + if (node.name !== 'style') { + return; + } + + if ( + node.attributes.type == null || + node.attributes.type === '' || + node.attributes.type === 'text/css' + ) { const dynamic = node.attributes.media != null && node.attributes.media !== 'all'; - if ( - node.attributes.type == null || - node.attributes.type === '' || - node.attributes.type === 'text/css' - ) { - const children = node.children; - for (const child of children) { - if (child.type === 'text' || child.type === 'cdata') { - rules.push(...parseStylesheet(child.value, dynamic)); - } + + for (const child of node.children) { + if (child.type === 'text' || child.type === 'cdata') { + rules.push(...parseStylesheet(child.value, dynamic)); } } } @@ -253,11 +257,12 @@ const collectStylesheet = (root) => { exports.collectStylesheet = collectStylesheet; /** - * @type {(stylesheet: Stylesheet, node: XastElement) => ComputedStyles} + * @param {Stylesheet} stylesheet + * @param {XastElement} node + * @returns {ComputedStyles} */ const computeStyle = (stylesheet, node) => { const { parents } = stylesheet; - // collect inherited styles const computedStyles = computeOwnStyle(stylesheet, node); let parent = parents.get(node); while (parent != null && parent.type !== 'root') { @@ -265,9 +270,8 @@ const computeStyle = (stylesheet, node) => { for (const [name, computed] of Object.entries(inheritedStyles)) { if ( computedStyles[name] == null && - // ignore not inheritable styles - inheritableAttrs.includes(name) === true && - presentationNonInheritableGroupAttrs.includes(name) === false + inheritableAttrs.has(name) && + !presentationNonInheritableGroupAttrs.has(name) ) { computedStyles[name] = { ...computed, inherited: true }; } diff --git a/lib/svgo/tools.js b/lib/svgo/tools.js index 75a5ba823..e778034dc 100644 --- a/lib/svgo/tools.js +++ b/lib/svgo/tools.js @@ -204,7 +204,7 @@ exports.includesUrlReference = includesUrlReference; const findReferences = (attribute, value) => { const results = []; - if (referencesProps.includes(attribute)) { + if (referencesProps.has(attribute)) { const matches = value.matchAll(regReferencesUrl); for (const match of matches) { results.push(match[2]); diff --git a/plugins/_collections.js b/plugins/_collections.js index b9e67cb7c..6f11b1365 100644 --- a/plugins/_collections.js +++ b/plugins/_collections.js @@ -3,41 +3,50 @@ // https://www.w3.org/TR/SVG11/intro.html#Definitions /** - * @type {Record>} + * @type {Record>} */ exports.elemsGroups = { - animation: [ + animation: new Set([ 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'set', - ], - descriptive: ['desc', 'metadata', 'title'], - shape: ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect'], - structural: ['defs', 'g', 'svg', 'symbol', 'use'], - paintServer: [ - 'solidColor', + ]), + descriptive: new Set(['desc', 'metadata', 'title']), + shape: new Set([ + 'circle', + 'ellipse', + 'line', + 'path', + 'polygon', + 'polyline', + 'rect', + ]), + structural: new Set(['defs', 'g', 'svg', 'symbol', 'use']), + paintServer: new Set([ + 'hatch', 'linearGradient', - 'radialGradient', 'meshGradient', 'pattern', - 'hatch', - ], - nonRendering: [ - 'linearGradient', 'radialGradient', - 'pattern', + 'solidColor', + ]), + nonRendering: new Set([ 'clipPath', - 'mask', - 'marker', - 'symbol', 'filter', + 'linearGradient', + 'marker', + 'mask', + 'pattern', + 'radialGradient', 'solidColor', - ], - container: [ + 'symbol', + ]), + container: new Set([ 'a', 'defs', + 'foreignObject', 'g', 'marker', 'mask', @@ -46,28 +55,27 @@ exports.elemsGroups = { 'svg', 'switch', 'symbol', - 'foreignObject', - ], - textContent: [ + ]), + textContent: new Set([ 'altGlyph', 'altGlyphDef', 'altGlyphItem', 'glyph', 'glyphRef', - 'textPath', 'text', + 'textPath', 'tref', 'tspan', - ], - textContentChild: ['altGlyph', 'textPath', 'tref', 'tspan'], - lightSource: [ + ]), + textContentChild: new Set(['altGlyph', 'textPath', 'tref', 'tspan']), + lightSource: new Set([ 'feDiffuseLighting', - 'feSpecularLighting', 'feDistantLight', 'fePointLight', + 'feSpecularLighting', 'feSpotLight', - ], - filterPrimitive: [ + ]), + filterPrimitive: new Set([ 'feBlend', 'feColorMatrix', 'feComponentTransfer', @@ -90,7 +98,7 @@ exports.elemsGroups = { 'feSpecularLighting', 'feTile', 'feTurbulence', - ], + ]), }; /** @@ -99,81 +107,85 @@ exports.elemsGroups = { * * @see https://developer.mozilla.org/docs/Web/HTML/Element/pre */ -exports.textElems = [...exports.elemsGroups.textContent, 'title', 'pre']; +exports.textElems = new Set([ + ...exports.elemsGroups.textContent, + 'pre', + 'title', +]); -exports.pathElems = ['path', 'glyph', 'missing-glyph']; +exports.pathElems = new Set(['glyph', 'missing-glyph', 'path']); /** - * @type {Record>} + * @type {Record>} * @see https://www.w3.org/TR/SVG11/intro.html#Definitions */ exports.attrsGroups = { - animationAddition: ['additive', 'accumulate'], - animationAttributeTarget: ['attributeType', 'attributeName'], - animationEvent: ['onbegin', 'onend', 'onrepeat', 'onload'], - animationTiming: [ + animationAddition: new Set(['additive', 'accumulate']), + animationAttributeTarget: new Set(['attributeType', 'attributeName']), + animationEvent: new Set(['onbegin', 'onend', 'onrepeat', 'onload']), + animationTiming: new Set([ 'begin', 'dur', 'end', - 'min', + 'fill', 'max', - 'restart', + 'min', 'repeatCount', 'repeatDur', - 'fill', - ], - animationValue: [ + 'restart', + ]), + animationValue: new Set([ + 'by', 'calcMode', - 'values', - 'keyTimes', - 'keySplines', 'from', + 'keySplines', + 'keyTimes', 'to', - 'by', - ], - conditionalProcessing: [ - 'requiredFeatures', + 'values', + ]), + conditionalProcessing: new Set([ 'requiredExtensions', + 'requiredFeatures', 'systemLanguage', - ], - core: ['id', 'tabindex', 'xml:base', 'xml:lang', 'xml:space'], - graphicalEvent: [ - 'onfocusin', - 'onfocusout', + ]), + core: new Set(['id', 'tabindex', 'xml:base', 'xml:lang', 'xml:space']), + graphicalEvent: new Set([ 'onactivate', 'onclick', + 'onfocusin', + 'onfocusout', + 'onload', 'onmousedown', - 'onmouseup', - 'onmouseover', 'onmousemove', 'onmouseout', - 'onload', - ], - presentation: [ + 'onmouseover', + 'onmouseup', + ]), + presentation: new Set([ 'alignment-baseline', 'baseline-shift', - 'clip', 'clip-path', 'clip-rule', - 'color', - 'color-interpolation', + 'clip', 'color-interpolation-filters', + 'color-interpolation', 'color-profile', 'color-rendering', + 'color', 'cursor', 'direction', 'display', 'dominant-baseline', 'enable-background', - 'fill', 'fill-opacity', 'fill-rule', + 'fill', 'filter', 'flood-color', 'flood-opacity', 'font-family', - 'font-size', 'font-size-adjust', + 'font-size', 'font-stretch', 'font-style', 'font-variant', @@ -194,7 +206,6 @@ exports.attrsGroups = { 'shape-rendering', 'stop-color', 'stop-opacity', - 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', @@ -202,37 +213,38 @@ exports.attrsGroups = { 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', + 'stroke', 'text-anchor', 'text-decoration', 'text-overflow', 'text-rendering', - 'transform', 'transform-origin', + 'transform', 'unicode-bidi', 'vector-effect', 'visibility', 'word-spacing', 'writing-mode', - ], - xlink: [ - 'xlink:href', - 'xlink:show', + ]), + xlink: new Set([ 'xlink:actuate', - 'xlink:type', - 'xlink:role', 'xlink:arcrole', + 'xlink:href', + 'xlink:role', + 'xlink:show', 'xlink:title', - ], - documentEvent: [ + 'xlink:type', + ]), + documentEvent: new Set([ 'onabort', 'onerror', 'onresize', 'onscroll', 'onunload', 'onzoom', - ], - documentElementEvent: ['oncopy', 'oncut', 'onpaste'], - globalEvent: [ + ]), + documentElementEvent: new Set(['oncopy', 'oncut', 'onpaste']), + globalEvent: new Set([ 'oncancel', 'oncanplay', 'oncanplaythrough', @@ -289,17 +301,17 @@ exports.attrsGroups = { 'ontoggle', 'onvolumechange', 'onwaiting', - ], - filterPrimitive: ['x', 'y', 'width', 'height', 'result'], - transferFunction: [ - 'type', - 'tableValues', - 'slope', - 'intercept', + ]), + filterPrimitive: new Set(['x', 'y', 'width', 'height', 'result']), + transferFunction: new Set([ 'amplitude', 'exponent', + 'intercept', 'offset', - ], + 'slope', + 'tableValues', + 'type', + ]), }; /** @@ -371,49 +383,49 @@ exports.attrsGroupsDefaults = { /** * @type {Record, - * attrs?: Array, + * attrsGroups: Set, + * attrs?: Set, * defaults?: Record, - * contentGroups?: Array, - * content?: Array, + * contentGroups?: Set, + * content?: Set, * }>} * @see https://www.w3.org/TR/SVG11/eltindex.html */ exports.elems = { a: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'transform', + 'style', 'target', - ], + 'transform', + ]), defaults: { target: '_self', }, - contentGroups: [ + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -426,183 +438,188 @@ exports.elems = { 'view', // not spec compliant 'tspan', - ], + ]), }, altGlyph: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', - 'externalResourcesRequired', - 'x', - 'y', 'dx', 'dy', - 'glyphRef', + 'externalResourcesRequired', 'format', + 'glyphRef', 'rotate', - ], + 'style', + 'x', + 'y', + ]), }, altGlyphDef: { - attrsGroups: ['core'], - content: ['glyphRef'], + attrsGroups: new Set(['core']), + content: new Set(['glyphRef']), }, altGlyphItem: { - attrsGroups: ['core'], - content: ['glyphRef', 'altGlyphItem'], + attrsGroups: new Set(['core']), + content: new Set(['glyphRef', 'altGlyphItem']), }, animate: { - attrsGroups: [ - 'conditionalProcessing', - 'core', + attrsGroups: new Set([ 'animationAddition', 'animationAttributeTarget', 'animationEvent', 'animationTiming', 'animationValue', + 'conditionalProcessing', + 'core', 'presentation', 'xlink', - ], - attrs: ['externalResourcesRequired'], - contentGroups: ['descriptive'], + ]), + attrs: new Set(['externalResourcesRequired']), + contentGroups: new Set(['descriptive']), }, animateColor: { - attrsGroups: [ - 'conditionalProcessing', - 'core', - 'animationEvent', - 'xlink', + attrsGroups: new Set([ + 'animationAddition', 'animationAttributeTarget', + 'animationEvent', 'animationTiming', 'animationValue', - 'animationAddition', + 'conditionalProcessing', + 'core', 'presentation', - ], - attrs: ['externalResourcesRequired'], - contentGroups: ['descriptive'], + 'xlink', + ]), + attrs: new Set(['externalResourcesRequired']), + contentGroups: new Set(['descriptive']), }, animateMotion: { - attrsGroups: [ - 'conditionalProcessing', - 'core', + attrsGroups: new Set([ + 'animationAddition', 'animationEvent', - 'xlink', 'animationTiming', 'animationValue', - 'animationAddition', - ], - attrs: [ + 'conditionalProcessing', + 'core', + 'xlink', + ]), + attrs: new Set([ 'externalResourcesRequired', - 'path', 'keyPoints', - 'rotate', 'origin', - ], + 'path', + 'rotate', + ]), defaults: { rotate: '0', }, - contentGroups: ['descriptive'], - content: ['mpath'], + contentGroups: new Set(['descriptive']), + content: new Set(['mpath']), }, animateTransform: { - attrsGroups: [ - 'conditionalProcessing', - 'core', - 'animationEvent', - 'xlink', + attrsGroups: new Set([ + 'animationAddition', 'animationAttributeTarget', + 'animationEvent', 'animationTiming', 'animationValue', - 'animationAddition', - ], - attrs: ['externalResourcesRequired', 'type'], - contentGroups: ['descriptive'], + 'conditionalProcessing', + 'core', + 'xlink', + ]), + attrs: new Set(['externalResourcesRequired', 'type']), + contentGroups: new Set(['descriptive']), }, circle: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', - 'externalResourcesRequired', - 'transform', 'cx', 'cy', + 'externalResourcesRequired', 'r', - ], + 'style', + 'transform', + ]), defaults: { cx: '0', cy: '0', }, - contentGroups: ['animation', 'descriptive'], + contentGroups: new Set(['animation', 'descriptive']), }, clipPath: { - attrsGroups: ['conditionalProcessing', 'core', 'presentation'], - attrs: [ + attrsGroups: new Set(['conditionalProcessing', 'core', 'presentation']), + attrs: new Set([ 'class', - 'style', + 'clipPathUnits', 'externalResourcesRequired', + 'style', 'transform', - 'clipPathUnits', - ], + ]), defaults: { clipPathUnits: 'userSpaceOnUse', }, - contentGroups: ['animation', 'descriptive', 'shape'], - content: ['text', 'use'], + contentGroups: new Set(['animation', 'descriptive', 'shape']), + content: new Set(['text', 'use']), }, 'color-profile': { - attrsGroups: ['core', 'xlink'], - attrs: ['local', 'name', 'rendering-intent'], + attrsGroups: new Set(['core', 'xlink']), + attrs: new Set(['local', 'name', 'rendering-intent']), defaults: { name: 'sRGB', 'rendering-intent': 'auto', }, - contentGroups: ['descriptive'], + contentGroups: new Set(['descriptive']), }, cursor: { - attrsGroups: ['core', 'conditionalProcessing', 'xlink'], - attrs: ['externalResourcesRequired', 'x', 'y'], + attrsGroups: new Set(['core', 'conditionalProcessing', 'xlink']), + attrs: new Set(['externalResourcesRequired', 'x', 'y']), defaults: { x: '0', y: '0', }, - contentGroups: ['descriptive'], + contentGroups: new Set(['descriptive']), }, defs: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: ['class', 'style', 'externalResourcesRequired', 'transform'], - contentGroups: [ + ]), + attrs: new Set([ + 'class', + 'externalResourcesRequired', + 'style', + 'transform', + ]), + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -613,38 +630,38 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, desc: { - attrsGroups: ['core'], - attrs: ['class', 'style'], + attrsGroups: new Set(['core']), + attrs: new Set(['class', 'style']), }, ellipse: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', - 'externalResourcesRequired', - 'transform', 'cx', 'cy', + 'externalResourcesRequired', 'rx', 'ry', - ], + 'style', + 'transform', + ]), defaults: { cx: '0', cy: '0', }, - contentGroups: ['animation', 'descriptive'], + contentGroups: new Set(['animation', 'descriptive']), }, feBlend: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set([ 'class', 'style', // TODO: in - 'If no value is provided and this is the first filter primitive, @@ -652,28 +669,38 @@ exports.elems = { 'in', 'in2', 'mode', - ], + ]), defaults: { mode: 'normal', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feColorMatrix: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style', 'in', 'type', 'values'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style', 'in', 'type', 'values']), defaults: { type: 'matrix', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feComponentTransfer: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style', 'in'], - content: ['feFuncA', 'feFuncB', 'feFuncG', 'feFuncR'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style', 'in']), + content: new Set(['feFuncA', 'feFuncB', 'feFuncG', 'feFuncR']), }, feComposite: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style', 'in', 'in2', 'operator', 'k1', 'k2', 'k3', 'k4'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set([ + 'class', + 'in', + 'in2', + 'k1', + 'k2', + 'k3', + 'k4', + 'operator', + 'style', + ]), defaults: { operator: 'over', k1: '0', @@ -681,203 +708,203 @@ exports.elems = { k3: '0', k4: '0', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feConvolveMatrix: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set([ 'class', - 'style', 'in', - 'order', 'kernelMatrix', + 'order', + 'style', // TODO: divisor - 'The default value is the sum of all values in kernelMatrix, // with the exception that if the sum is zero, then the divisor is set to 1' - 'divisor', 'bias', + 'divisor', // TODO: targetX - 'By default, the convolution matrix is centered in X over each // pixel of the input image (i.e., targetX = floor ( orderX / 2 ))' + 'edgeMode', 'targetX', 'targetY', - 'edgeMode', // TODO: kernelUnitLength - 'The first number is the value. The second number // is the value. If the value is not specified, it defaults to the same value as ' 'kernelUnitLength', 'preserveAlpha', - ], + ]), defaults: { order: '3', bias: '0', edgeMode: 'duplicate', preserveAlpha: 'false', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feDiffuseLighting: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set([ 'class', - 'style', - 'in', - 'surfaceScale', 'diffuseConstant', + 'in', 'kernelUnitLength', - ], + 'style', + 'surfaceScale', + ]), defaults: { surfaceScale: '1', diffuseConstant: '1', }, - contentGroups: ['descriptive'], - content: [ + contentGroups: new Set(['descriptive']), + content: new Set([ // TODO: 'exactly one light source element, in any order' 'feDistantLight', 'fePointLight', 'feSpotLight', - ], + ]), }, feDisplacementMap: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set([ 'class', - 'style', 'in', 'in2', 'scale', + 'style', 'xChannelSelector', 'yChannelSelector', - ], + ]), defaults: { scale: '0', xChannelSelector: 'A', yChannelSelector: 'A', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feDistantLight: { - attrsGroups: ['core'], - attrs: ['azimuth', 'elevation'], + attrsGroups: new Set(['core']), + attrs: new Set(['azimuth', 'elevation']), defaults: { azimuth: '0', elevation: '0', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feFlood: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style'], - content: ['animate', 'animateColor', 'set'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style']), + content: new Set(['animate', 'animateColor', 'set']), }, feFuncA: { - attrsGroups: ['core', 'transferFunction'], - content: ['set', 'animate'], + attrsGroups: new Set(['core', 'transferFunction']), + content: new Set(['set', 'animate']), }, feFuncB: { - attrsGroups: ['core', 'transferFunction'], - content: ['set', 'animate'], + attrsGroups: new Set(['core', 'transferFunction']), + content: new Set(['set', 'animate']), }, feFuncG: { - attrsGroups: ['core', 'transferFunction'], - content: ['set', 'animate'], + attrsGroups: new Set(['core', 'transferFunction']), + content: new Set(['set', 'animate']), }, feFuncR: { - attrsGroups: ['core', 'transferFunction'], - content: ['set', 'animate'], + attrsGroups: new Set(['core', 'transferFunction']), + content: new Set(['set', 'animate']), }, feGaussianBlur: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style', 'in', 'stdDeviation'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style', 'in', 'stdDeviation']), defaults: { stdDeviation: '0', }, - content: ['set', 'animate'], + content: new Set(['set', 'animate']), }, feImage: { - attrsGroups: ['core', 'presentation', 'filterPrimitive', 'xlink'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive', 'xlink']), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'preserveAspectRatio', 'href', + 'preserveAspectRatio', + 'style', 'xlink:href', - ], + ]), defaults: { preserveAspectRatio: 'xMidYMid meet', }, - content: ['animate', 'animateTransform', 'set'], + content: new Set(['animate', 'animateTransform', 'set']), }, feMerge: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style'], - content: ['feMergeNode'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style']), + content: new Set(['feMergeNode']), }, feMergeNode: { - attrsGroups: ['core'], - attrs: ['in'], - content: ['animate', 'set'], + attrsGroups: new Set(['core']), + attrs: new Set(['in']), + content: new Set(['animate', 'set']), }, feMorphology: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style', 'in', 'operator', 'radius'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style', 'in', 'operator', 'radius']), defaults: { operator: 'erode', radius: '0', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feOffset: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style', 'in', 'dx', 'dy'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style', 'in', 'dx', 'dy']), defaults: { dx: '0', dy: '0', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, fePointLight: { - attrsGroups: ['core'], - attrs: ['x', 'y', 'z'], + attrsGroups: new Set(['core']), + attrs: new Set(['x', 'y', 'z']), defaults: { x: '0', y: '0', z: '0', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feSpecularLighting: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set([ 'class', - 'style', 'in', - 'surfaceScale', + 'kernelUnitLength', 'specularConstant', 'specularExponent', - 'kernelUnitLength', - ], + 'style', + 'surfaceScale', + ]), defaults: { surfaceScale: '1', specularConstant: '1', specularExponent: '1', }, - contentGroups: [ + contentGroups: new Set([ 'descriptive', // TODO: exactly one 'light source element' 'lightSource', - ], + ]), }, feSpotLight: { - attrsGroups: ['core'], - attrs: [ - 'x', - 'y', - 'z', + attrsGroups: new Set(['core']), + attrs: new Set([ + 'limitingConeAngle', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'specularExponent', - 'limitingConeAngle', - ], + 'x', + 'y', + 'z', + ]), defaults: { x: '0', y: '0', @@ -887,24 +914,24 @@ exports.elems = { pointsAtZ: '0', specularExponent: '1', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, feTile: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: ['class', 'style', 'in'], - content: ['animate', 'set'], + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set(['class', 'style', 'in']), + content: new Set(['animate', 'set']), }, feTurbulence: { - attrsGroups: ['core', 'presentation', 'filterPrimitive'], - attrs: [ - 'class', - 'style', + attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']), + attrs: new Set([ 'baseFrequency', + 'class', 'numOctaves', 'seed', 'stitchTiles', + 'style', 'type', - ], + ]), defaults: { baseFrequency: '0', numOctaves: '1', @@ -912,24 +939,24 @@ exports.elems = { stitchTiles: 'noStitch', type: 'turbulence', }, - content: ['animate', 'set'], + content: new Set(['animate', 'set']), }, filter: { - attrsGroups: ['core', 'presentation', 'xlink'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'xlink']), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'x', - 'y', - 'width', - 'height', 'filterRes', 'filterUnits', - 'primitiveUnits', + 'height', 'href', + 'primitiveUnits', + 'style', + 'width', + 'x', 'xlink:href', - ], + 'y', + ]), defaults: { primitiveUnits: 'userSpaceOnUse', x: '-10%', @@ -937,32 +964,32 @@ exports.elems = { width: '120%', height: '120%', }, - contentGroups: ['descriptive', 'filterPrimitive'], - content: ['animate', 'set'], + contentGroups: new Set(['descriptive', 'filterPrimitive']), + content: new Set(['animate', 'set']), }, font: { - attrsGroups: ['core', 'presentation'], - attrs: [ + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', + 'horiz-adv-x', 'horiz-origin-x', 'horiz-origin-y', - 'horiz-adv-x', + 'style', + 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', - 'vert-adv-y', - ], + ]), defaults: { 'horiz-origin-x': '0', 'horiz-origin-y': '0', }, - contentGroups: ['descriptive'], - content: ['font-face', 'glyph', 'hkern', 'missing-glyph', 'vkern'], + contentGroups: new Set(['descriptive']), + content: new Set(['font-face', 'glyph', 'hkern', 'missing-glyph', 'vkern']), }, 'font-face': { - attrsGroups: ['core'], - attrs: [ + attrsGroups: new Set(['core']), + attrs: new Set([ 'font-family', 'font-style', 'font-variant', @@ -996,7 +1023,7 @@ exports.elems = { 'strikethrough-thickness', 'overline-position', 'overline-thickness', - ], + ]), defaults: { 'font-style': 'all', 'font-variant': 'normal', @@ -1007,76 +1034,81 @@ exports.elems = { 'panose-1': '0 0 0 0 0 0 0 0 0 0', slope: '0', }, - contentGroups: ['descriptive'], - content: [ + contentGroups: new Set(['descriptive']), + content: new Set([ // TODO: "at most one 'font-face-src' element" 'font-face-src', - ], + ]), }, // TODO: empty content 'font-face-format': { - attrsGroups: ['core'], - attrs: ['string'], + attrsGroups: new Set(['core']), + attrs: new Set(['string']), }, 'font-face-name': { - attrsGroups: ['core'], - attrs: ['name'], + attrsGroups: new Set(['core']), + attrs: new Set(['name']), }, 'font-face-src': { - attrsGroups: ['core'], - content: ['font-face-name', 'font-face-uri'], + attrsGroups: new Set(['core']), + content: new Set(['font-face-name', 'font-face-uri']), }, 'font-face-uri': { - attrsGroups: ['core', 'xlink'], - attrs: ['href', 'xlink:href'], - content: ['font-face-format'], + attrsGroups: new Set(['core', 'xlink']), + attrs: new Set(['href', 'xlink:href']), + content: new Set(['font-face-format']), }, foreignObject: { - attrsGroups: [ - 'core', + attrsGroups: new Set([ 'conditionalProcessing', + 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', + 'height', + 'style', 'transform', + 'width', 'x', 'y', - 'width', - 'height', - ], + ]), defaults: { x: '0', y: '0', }, }, g: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: ['class', 'style', 'externalResourcesRequired', 'transform'], - contentGroups: [ + ]), + attrs: new Set([ + 'class', + 'externalResourcesRequired', + 'style', + 'transform', + ]), + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1087,43 +1119,43 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, glyph: { - attrsGroups: ['core', 'presentation'], - attrs: [ + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set([ + 'arabic-form', 'class', - 'style', 'd', + 'glyph-name', 'horiz-adv-x', + 'lang', + 'orientation', + 'style', + 'unicode', + 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', - 'vert-adv-y', - 'unicode', - 'glyph-name', - 'orientation', - 'arabic-form', - 'lang', - ], + ]), defaults: { 'arabic-form': 'initial', }, - contentGroups: [ + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1134,35 +1166,35 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, glyphRef: { - attrsGroups: ['core', 'presentation'], - attrs: [ + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set([ 'class', - 'style', 'd', 'horiz-adv-x', + 'style', + 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', - 'vert-adv-y', - ], - contentGroups: [ + ]), + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1173,21 +1205,21 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, hatch: { - attrsGroups: ['core', 'presentation', 'xlink'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'xlink']), + attrs: new Set([ 'class', - 'style', - 'x', - 'y', + 'hatchContentUnits', + 'hatchUnits', 'pitch', 'rotate', - 'hatchUnits', - 'hatchContentUnits', + 'style', 'transform', - ], + 'x', + 'y', + ]), defaults: { hatchUnits: 'objectBoundingBox', hatchContentUnits: 'userSpaceOnUse', @@ -1196,90 +1228,90 @@ exports.elems = { pitch: '0', rotate: '0', }, - contentGroups: ['animation', 'descriptive'], - content: ['hatchPath'], + contentGroups: new Set(['animation', 'descriptive']), + content: new Set(['hatchPath']), }, hatchPath: { - attrsGroups: ['core', 'presentation', 'xlink'], - attrs: ['class', 'style', 'd', 'offset'], + attrsGroups: new Set(['core', 'presentation', 'xlink']), + attrs: new Set(['class', 'style', 'd', 'offset']), defaults: { offset: '0', }, - contentGroups: ['animation', 'descriptive'], + contentGroups: new Set(['animation', 'descriptive']), }, hkern: { - attrsGroups: ['core'], - attrs: ['u1', 'g1', 'u2', 'g2', 'k'], + attrsGroups: new Set(['core']), + attrs: new Set(['u1', 'g1', 'u2', 'g2', 'k']), }, image: { - attrsGroups: [ - 'core', + attrsGroups: new Set([ 'conditionalProcessing', + 'core', 'graphicalEvent', - 'xlink', 'presentation', - ], - attrs: [ + 'xlink', + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', + 'height', + 'href', 'preserveAspectRatio', + 'style', 'transform', - 'x', - 'y', 'width', - 'height', - 'href', + 'x', 'xlink:href', - ], + 'y', + ]), defaults: { x: '0', y: '0', preserveAspectRatio: 'xMidYMid meet', }, - contentGroups: ['animation', 'descriptive'], + contentGroups: new Set(['animation', 'descriptive']), }, line: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', + 'style', 'transform', 'x1', - 'y1', 'x2', + 'y1', 'y2', - ], + ]), defaults: { x1: '0', y1: '0', x2: '0', y2: '0', }, - contentGroups: ['animation', 'descriptive'], + contentGroups: new Set(['animation', 'descriptive']), }, linearGradient: { - attrsGroups: ['core', 'presentation', 'xlink'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'xlink']), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'x1', - 'y1', - 'x2', - 'y2', - 'gradientUnits', 'gradientTransform', - 'spreadMethod', + 'gradientUnits', 'href', + 'spreadMethod', + 'style', + 'x1', + 'x2', 'xlink:href', - ], + 'y1', + 'y2', + ]), defaults: { x1: '0', y1: '0', @@ -1287,24 +1319,24 @@ exports.elems = { y2: '0', spreadMethod: 'pad', }, - contentGroups: ['descriptive'], - content: ['animate', 'animateTransform', 'set', 'stop'], + contentGroups: new Set(['descriptive']), + content: new Set(['animate', 'animateTransform', 'set', 'stop']), }, marker: { - attrsGroups: ['core', 'presentation'], - attrs: [ + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'viewBox', - 'preserveAspectRatio', - 'refX', - 'refY', + 'markerHeight', 'markerUnits', 'markerWidth', - 'markerHeight', 'orient', - ], + 'preserveAspectRatio', + 'refX', + 'refY', + 'style', + 'viewBox', + ]), defaults: { markerUnits: 'strokeWidth', refX: '0', @@ -1312,22 +1344,22 @@ exports.elems = { markerWidth: '3', markerHeight: '3', }, - contentGroups: [ + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1338,22 +1370,22 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, mask: { - attrsGroups: ['conditionalProcessing', 'core', 'presentation'], - attrs: [ + attrsGroups: new Set(['conditionalProcessing', 'core', 'presentation']), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'x', - 'y', - 'width', 'height', 'mask-type', - 'maskUnits', 'maskContentUnits', - ], + 'maskUnits', + 'style', + 'width', + 'x', + 'y', + ]), defaults: { maskUnits: 'objectBoundingBox', maskContentUnits: 'userSpaceOnUse', @@ -1362,22 +1394,22 @@ exports.elems = { width: '120%', height: '120%', }, - contentGroups: [ + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1388,38 +1420,38 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, metadata: { - attrsGroups: ['core'], + attrsGroups: new Set(['core']), }, 'missing-glyph': { - attrsGroups: ['core', 'presentation'], - attrs: [ + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set([ 'class', - 'style', 'd', 'horiz-adv-x', + 'style', + 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', - 'vert-adv-y', - ], - contentGroups: [ + ]), + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1430,48 +1462,53 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, mpath: { - attrsGroups: ['core', 'xlink'], - attrs: ['externalResourcesRequired', 'href', 'xlink:href'], - contentGroups: ['descriptive'], + attrsGroups: new Set(['core', 'xlink']), + attrs: new Set(['externalResourcesRequired', 'href', 'xlink:href']), + contentGroups: new Set(['descriptive']), }, path: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', - 'externalResourcesRequired', - 'transform', 'd', + 'externalResourcesRequired', 'pathLength', - ], - contentGroups: ['animation', 'descriptive'], + 'style', + 'transform', + ]), + contentGroups: new Set(['animation', 'descriptive']), }, pattern: { - attrsGroups: ['conditionalProcessing', 'core', 'presentation', 'xlink'], - attrs: [ + attrsGroups: new Set([ + 'conditionalProcessing', + 'core', + 'presentation', + 'xlink', + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'viewBox', - 'preserveAspectRatio', - 'x', - 'y', - 'width', 'height', - 'patternUnits', + 'href', 'patternContentUnits', 'patternTransform', - 'href', + 'patternUnits', + 'preserveAspectRatio', + 'style', + 'viewBox', + 'width', + 'x', 'xlink:href', - ], + 'y', + ]), defaults: { patternUnits: 'objectBoundingBox', patternContentUnits: 'userSpaceOnUse', @@ -1481,22 +1518,22 @@ exports.elems = { height: '0', preserveAspectRatio: 'xMidYMid meet', }, - contentGroups: [ + contentGroups: new Set([ 'animation', 'descriptive', 'paintServer', 'shape', 'structural', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1507,166 +1544,166 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, polygon: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'transform', 'points', - ], - contentGroups: ['animation', 'descriptive'], + 'style', + 'transform', + ]), + contentGroups: new Set(['animation', 'descriptive']), }, polyline: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'transform', 'points', - ], - contentGroups: ['animation', 'descriptive'], + 'style', + 'transform', + ]), + contentGroups: new Set(['animation', 'descriptive']), }, radialGradient: { - attrsGroups: ['core', 'presentation', 'xlink'], - attrs: [ + attrsGroups: new Set(['core', 'presentation', 'xlink']), + attrs: new Set([ 'class', - 'style', - 'externalResourcesRequired', 'cx', 'cy', - 'r', + 'externalResourcesRequired', + 'fr', 'fx', 'fy', - 'fr', - 'gradientUnits', 'gradientTransform', - 'spreadMethod', + 'gradientUnits', 'href', + 'r', + 'spreadMethod', + 'style', 'xlink:href', - ], + ]), defaults: { gradientUnits: 'objectBoundingBox', cx: '50%', cy: '50%', r: '50%', }, - contentGroups: ['descriptive'], - content: ['animate', 'animateTransform', 'set', 'stop'], + contentGroups: new Set(['descriptive']), + content: new Set(['animate', 'animateTransform', 'set', 'stop']), }, meshGradient: { - attrsGroups: ['core', 'presentation', 'xlink'], - attrs: ['class', 'style', 'x', 'y', 'gradientUnits', 'transform'], - contentGroups: ['descriptive', 'paintServer', 'animation'], - content: ['meshRow'], + attrsGroups: new Set(['core', 'presentation', 'xlink']), + attrs: new Set(['class', 'style', 'x', 'y', 'gradientUnits', 'transform']), + contentGroups: new Set(['descriptive', 'paintServer', 'animation']), + content: new Set(['meshRow']), }, meshRow: { - attrsGroups: ['core', 'presentation'], - attrs: ['class', 'style'], - contentGroups: ['descriptive'], - content: ['meshPatch'], + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set(['class', 'style']), + contentGroups: new Set(['descriptive']), + content: new Set(['meshPatch']), }, meshPatch: { - attrsGroups: ['core', 'presentation'], - attrs: ['class', 'style'], - contentGroups: ['descriptive'], - content: ['stop'], + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set(['class', 'style']), + contentGroups: new Set(['descriptive']), + content: new Set(['stop']), }, rect: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'transform', - 'x', - 'y', - 'width', 'height', 'rx', 'ry', - ], + 'style', + 'transform', + 'width', + 'x', + 'y', + ]), defaults: { x: '0', y: '0', }, - contentGroups: ['animation', 'descriptive'], + contentGroups: new Set(['animation', 'descriptive']), }, script: { - attrsGroups: ['core', 'xlink'], - attrs: ['externalResourcesRequired', 'type', 'href', 'xlink:href'], + attrsGroups: new Set(['core', 'xlink']), + attrs: new Set(['externalResourcesRequired', 'type', 'href', 'xlink:href']), }, set: { - attrsGroups: [ - 'conditionalProcessing', - 'core', + attrsGroups: new Set([ 'animation', - 'xlink', 'animationAttributeTarget', 'animationTiming', - ], - attrs: ['externalResourcesRequired', 'to'], - contentGroups: ['descriptive'], + 'conditionalProcessing', + 'core', + 'xlink', + ]), + attrs: new Set(['externalResourcesRequired', 'to']), + contentGroups: new Set(['descriptive']), }, solidColor: { - attrsGroups: ['core', 'presentation'], - attrs: ['class', 'style'], - contentGroups: ['paintServer'], + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set(['class', 'style']), + contentGroups: new Set(['paintServer']), }, stop: { - attrsGroups: ['core', 'presentation'], - attrs: ['class', 'style', 'offset', 'path'], - content: ['animate', 'animateColor', 'set'], + attrsGroups: new Set(['core', 'presentation']), + attrs: new Set(['class', 'style', 'offset', 'path']), + content: new Set(['animate', 'animateColor', 'set']), }, style: { - attrsGroups: ['core'], - attrs: ['type', 'media', 'title'], + attrsGroups: new Set(['core']), + attrs: new Set(['type', 'media', 'title']), defaults: { type: 'text/css', }, }, svg: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'documentEvent', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ + 'baseProfile', 'class', + 'contentScriptType', + 'contentStyleType', + 'height', + 'preserveAspectRatio', 'style', + 'version', + 'viewBox', + 'width', 'x', 'y', - 'width', - 'height', - 'viewBox', - 'preserveAspectRatio', 'zoomAndPan', - 'version', - 'baseProfile', - 'contentScriptType', - 'contentStyleType', - ], + ]), defaults: { x: '0', y: '0', @@ -1679,22 +1716,22 @@ exports.elems = { contentScriptType: 'application/ecmascript', contentStyleType: 'text/css', }, - contentGroups: [ + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1705,18 +1742,23 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, switch: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: ['class', 'style', 'externalResourcesRequired', 'transform'], - contentGroups: ['animation', 'descriptive', 'shape'], - content: [ + ]), + attrs: new Set([ + 'class', + 'externalResourcesRequired', + 'style', + 'transform', + ]), + contentGroups: new Set(['animation', 'descriptive', 'shape']), + content: new Set([ 'a', 'foreignObject', 'g', @@ -1725,39 +1767,39 @@ exports.elems = { 'switch', 'text', 'use', - ], + ]), }, symbol: { - attrsGroups: ['core', 'graphicalEvent', 'presentation'], - attrs: [ + attrsGroups: new Set(['core', 'graphicalEvent', 'presentation']), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', 'preserveAspectRatio', - 'viewBox', 'refX', 'refY', - ], + 'style', + 'viewBox', + ]), defaults: { refX: '0', refY: '0', }, - contentGroups: [ + contentGroups: new Set([ 'animation', 'descriptive', + 'paintServer', 'shape', 'structural', - 'paintServer', - ], - content: [ + ]), + content: new Set([ 'a', 'altGlyphDef', 'clipPath', 'color-profile', 'cursor', 'filter', - 'font', 'font-face', + 'font', 'foreignObject', 'image', 'marker', @@ -1768,62 +1810,62 @@ exports.elems = { 'switch', 'text', 'view', - ], + ]), }, text: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', - 'externalResourcesRequired', - 'transform', - 'lengthAdjust', - 'x', - 'y', 'dx', 'dy', + 'externalResourcesRequired', + 'lengthAdjust', 'rotate', + 'style', 'textLength', - ], + 'transform', + 'x', + 'y', + ]), defaults: { x: '0', y: '0', lengthAdjust: 'spacing', }, - contentGroups: ['animation', 'descriptive', 'textContentChild'], - content: ['a'], + contentGroups: new Set(['animation', 'descriptive', 'textContentChild']), + content: new Set(['a']), }, textPath: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', + 'd', 'externalResourcesRequired', 'href', - 'xlink:href', - 'startOffset', 'method', 'spacing', - 'd', - ], + 'startOffset', + 'style', + 'xlink:href', + ]), defaults: { startOffset: '0', method: 'align', spacing: 'exact', }, - contentGroups: ['descriptive'], - content: [ + contentGroups: new Set(['descriptive']), + content: new Set([ 'a', 'altGlyph', 'animate', @@ -1831,51 +1873,51 @@ exports.elems = { 'set', 'tref', 'tspan', - ], + ]), }, title: { - attrsGroups: ['core'], - attrs: ['class', 'style'], + attrsGroups: new Set(['core']), + attrs: new Set(['class', 'style']), }, tref: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', 'xlink', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', 'href', + 'style', 'xlink:href', - ], - contentGroups: ['descriptive'], - content: ['animate', 'animateColor', 'set'], + ]), + contentGroups: new Set(['descriptive']), + content: new Set(['animate', 'animateColor', 'set']), }, tspan: { - attrsGroups: [ + attrsGroups: new Set([ 'conditionalProcessing', 'core', 'graphicalEvent', 'presentation', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', - 'externalResourcesRequired', - 'x', - 'y', 'dx', 'dy', + 'externalResourcesRequired', + 'lengthAdjust', 'rotate', + 'style', 'textLength', - 'lengthAdjust', - ], - contentGroups: ['descriptive'], - content: [ + 'x', + 'y', + ]), + contentGroups: new Set(['descriptive']), + content: new Set([ 'a', 'altGlyph', 'animate', @@ -1883,129 +1925,128 @@ exports.elems = { 'set', 'tref', 'tspan', - ], + ]), }, use: { - attrsGroups: [ - 'core', + attrsGroups: new Set([ 'conditionalProcessing', + 'core', 'graphicalEvent', 'presentation', 'xlink', - ], - attrs: [ + ]), + attrs: new Set([ 'class', - 'style', 'externalResourcesRequired', - 'transform', - 'x', - 'y', - 'width', 'height', 'href', + 'style', + 'transform', + 'width', + 'x', 'xlink:href', - ], + 'y', + ]), defaults: { x: '0', y: '0', }, - contentGroups: ['animation', 'descriptive'], + contentGroups: new Set(['animation', 'descriptive']), }, view: { - attrsGroups: ['core'], - attrs: [ + attrsGroups: new Set(['core']), + attrs: new Set([ 'externalResourcesRequired', - 'viewBox', 'preserveAspectRatio', - 'zoomAndPan', + 'viewBox', 'viewTarget', - ], - contentGroups: ['descriptive'], + 'zoomAndPan', + ]), + contentGroups: new Set(['descriptive']), }, vkern: { - attrsGroups: ['core'], - attrs: ['u1', 'g1', 'u2', 'g2', 'k'], + attrsGroups: new Set(['core']), + attrs: new Set(['u1', 'g1', 'u2', 'g2', 'k']), }, }; // https://wiki.inkscape.org/wiki/index.php/Inkscape-specific_XML_attributes -exports.editorNamespaces = [ - 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd', +exports.editorNamespaces = new Set([ + 'http://creativecommons.org/ns#', 'http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd', - 'http://www.inkscape.org/namespaces/inkscape', - 'http://www.bohemiancoding.com/sketch/ns', 'http://ns.adobe.com/AdobeIllustrator/10.0/', - 'http://ns.adobe.com/Graphs/1.0/', 'http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/', - 'http://ns.adobe.com/Variables/1.0/', - 'http://ns.adobe.com/SaveForWeb/1.0/', 'http://ns.adobe.com/Extensibility/1.0/', 'http://ns.adobe.com/Flows/1.0/', - 'http://ns.adobe.com/ImageReplacement/1.0/', 'http://ns.adobe.com/GenericCustomNamespace/1.0/', + 'http://ns.adobe.com/Graphs/1.0/', + 'http://ns.adobe.com/ImageReplacement/1.0/', + 'http://ns.adobe.com/SaveForWeb/1.0/', + 'http://ns.adobe.com/Variables/1.0/', 'http://ns.adobe.com/XPath/1.0/', + 'http://purl.org/dc/elements/1.1/', 'http://schemas.microsoft.com/visio/2003/SVGExtensions/', + 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd', 'http://taptrix.com/vectorillustrator/svg_extensions', + 'http://www.bohemiancoding.com/sketch/ns', 'http://www.figma.com/figma/ns', - 'http://purl.org/dc/elements/1.1/', - 'http://creativecommons.org/ns#', - 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', + 'http://www.inkscape.org/namespaces/inkscape', 'http://www.serif.com/', 'http://www.vector.evaxdesign.sk', -]; + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', +]); /** * @see https://www.w3.org/TR/SVG11/linking.html#processingIRI */ -exports.referencesProps = [ +exports.referencesProps = new Set([ 'clip-path', 'color-profile', 'fill', 'filter', - 'marker-start', - 'marker-mid', 'marker-end', + 'marker-mid', + 'marker-start', 'mask', 'stroke', 'style', -]; +]); /** * @see https://www.w3.org/TR/SVG11/propidx.html */ -exports.inheritableAttrs = [ +exports.inheritableAttrs = new Set([ 'clip-rule', - 'color', - 'color-interpolation', 'color-interpolation-filters', + 'color-interpolation', 'color-profile', 'color-rendering', + 'color', 'cursor', 'direction', 'dominant-baseline', - 'fill', 'fill-opacity', 'fill-rule', - 'font', + 'fill', 'font-family', - 'font-size', 'font-size-adjust', + 'font-size', 'font-stretch', 'font-style', 'font-variant', 'font-weight', + 'font', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'letter-spacing', - 'marker', 'marker-end', 'marker-mid', 'marker-start', + 'marker', 'paint-order', 'pointer-events', 'shape-rendering', - 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', @@ -2013,24 +2054,25 @@ exports.inheritableAttrs = [ 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', + 'stroke', 'text-anchor', 'text-rendering', 'transform', 'visibility', 'word-spacing', 'writing-mode', -]; +]); -exports.presentationNonInheritableGroupAttrs = [ - 'display', +exports.presentationNonInheritableGroupAttrs = new Set([ 'clip-path', + 'display', 'filter', 'mask', 'opacity', 'text-decoration', 'transform', 'unicode-bidi', -]; +]); /** * https://www.w3.org/TR/SVG11/single-page.html#types-ColorKeywords @@ -2229,63 +2271,69 @@ exports.colorsShortNames = { /** * @see https://www.w3.org/TR/SVG11/single-page.html#types-DataTypeColor */ -exports.colorsProps = [ +exports.colorsProps = new Set([ 'color', 'fill', - 'stroke', - 'stop-color', 'flood-color', 'lighting-color', -]; + 'stop-color', + 'stroke', +]); /** @see https://developer.mozilla.org/docs/Web/CSS/Pseudo-classes */ exports.pseudoClasses = { - displayState: ['fullscreen', 'modal', 'picture-in-picture'], - input: [ + displayState: new Set(['fullscreen', 'modal', 'picture-in-picture']), + input: new Set([ 'autofill', - 'enabled', - 'disabled', - 'read-only', - 'read-write', - 'placeholder-shown', - 'default', + 'blank', 'checked', + 'default', + 'disabled', + 'enabled', + 'in-range', 'indetermined', - 'blank', - 'valid', 'invalid', - 'in-range', + 'optional', 'out-of-range', + 'placeholder-shown', + 'read-only', + 'read-write', 'required', - 'optional', 'user-invalid', - ], - linguistic: ['dir', 'lang'], - location: [ + 'valid', + ]), + linguistic: new Set(['dir', 'lang']), + location: new Set([ 'any-link', 'link', - 'visited', 'local-link', - 'target', - 'target-within', 'scope', - ], - resourceState: ['playing', 'paused'], - timeDimensional: ['current', 'past', 'future'], - treeStructural: [ - 'root', + 'target-within', + 'target', + 'visited', + ]), + resourceState: new Set(['playing', 'paused']), + timeDimensional: new Set(['current', 'past', 'future']), + treeStructural: new Set([ 'empty', - 'nth-child', - 'nth-last-child', 'first-child', - 'last-child', - 'only-child', - 'nth-of-type', - 'nth-last-of-type', 'first-of-type', + 'last-child', 'last-of-type', + 'nth-child', + 'nth-last-child', + 'nth-last-of-type', + 'nth-of-type', + 'only-child', 'only-of-type', - ], - userAction: ['hover', 'active', 'focus', 'focus-visible', 'focus-within'], - functional: ['is', 'not', 'where', 'has'], + 'root', + ]), + userAction: new Set([ + 'active', + 'focus-visible', + 'focus-within', + 'focus', + 'hover', + ]), + functional: new Set(['is', 'not', 'where', 'has']), }; diff --git a/plugins/applyTransforms.js b/plugins/applyTransforms.js index faf03a508..3817c3d64 100644 --- a/plugins/applyTransforms.js +++ b/plugins/applyTransforms.js @@ -57,7 +57,7 @@ const applyTransforms = (root, params) => { node.attributes.style != null || Object.entries(node.attributes).some( ([name, value]) => - referencesProps.includes(name) && includesUrlReference(value), + referencesProps.has(name) && includesUrlReference(value), ) ) { return; diff --git a/plugins/collapseGroups.js b/plugins/collapseGroups.js index 6042a01ce..0534ad775 100644 --- a/plugins/collapseGroups.js +++ b/plugins/collapseGroups.js @@ -15,7 +15,7 @@ exports.description = 'collapses useless groups'; const hasAnimatedAttr = (node, name) => { if (node.type === 'element') { if ( - elemsGroups.animation.includes(node.name) && + elemsGroups.animation.has(node.name) && node.attributes.attributeName === name ) { return true; @@ -95,7 +95,7 @@ exports.fn = () => { } else if (firstChild.attributes[name] === 'inherit') { firstChild.attributes[name] = value; } else if ( - inheritableAttrs.includes(name) === false && + inheritableAttrs.has(name) === false && firstChild.attributes[name] !== value ) { return; @@ -112,7 +112,7 @@ exports.fn = () => { for (const child of node.children) { if ( child.type === 'element' && - elemsGroups.animation.includes(child.name) + elemsGroups.animation.has(child.name) ) { return; } diff --git a/plugins/convertColors.js b/plugins/convertColors.js index 6fcd49321..98517a08a 100644 --- a/plugins/convertColors.js +++ b/plugins/convertColors.js @@ -76,7 +76,7 @@ exports.fn = (_root, params) => { element: { enter: (node) => { for (const [name, value] of Object.entries(node.attributes)) { - if (collections.colorsProps.includes(name)) { + if (collections.colorsProps.has(name)) { let val = value; // convert colors to currentColor diff --git a/plugins/convertOneStopGradients.js b/plugins/convertOneStopGradients.js index bca2e1729..1cf0d66b0 100644 --- a/plugins/convertOneStopGradients.js +++ b/plugins/convertOneStopGradients.js @@ -104,7 +104,7 @@ exports.fn = (root) => { const selectorVal = `url(#${node.attributes.id})`; - const selector = colorsProps + const selector = [...colorsProps] .map((attr) => `[${attr}="${selectorVal}"]`) .join(','); const elements = querySelectorAll(root, selector); diff --git a/plugins/convertPathData.js b/plugins/convertPathData.js index b7b6beefc..5272ac775 100644 --- a/plugins/convertPathData.js +++ b/plugins/convertPathData.js @@ -147,7 +147,7 @@ exports.fn = (root, params) => { return { element: { enter: (node) => { - if (pathElems.includes(node.name) && node.attributes.d != null) { + if (pathElems.has(node.name) && node.attributes.d != null) { const computedStyle = computeStyle(stylesheet, node); precision = floatPrecision; error = diff --git a/plugins/convertStyleToAttrs.js b/plugins/convertStyleToAttrs.js index f04847cb1..a9305fc4b 100644 --- a/plugins/convertStyleToAttrs.js +++ b/plugins/convertStyleToAttrs.js @@ -109,7 +109,7 @@ exports.fn = (_root, params) => { val = val.slice(1, -1); } - if (stylingProps.includes(prop)) { + if (stylingProps.has(prop)) { newAttributes[prop] = val; return false; diff --git a/plugins/inlineStyles.js b/plugins/inlineStyles.js index d83cb6d34..84b264eac 100644 --- a/plugins/inlineStyles.js +++ b/plugins/inlineStyles.js @@ -247,7 +247,7 @@ exports.fn = (root, params) => { const property = ruleDeclaration.property; if ( - attrsGroups.presentation.includes(property) && + attrsGroups.presentation.has(property) && !selectors.some((selector) => includesAttrSelector(selector.item, property), ) diff --git a/plugins/moveElemsAttrsToGroup.js b/plugins/moveElemsAttrsToGroup.js index 5f46e6329..633f44396 100644 --- a/plugins/moveElemsAttrsToGroup.js +++ b/plugins/moveElemsAttrsToGroup.js @@ -64,7 +64,7 @@ exports.fn = (root) => { let everyChildIsPath = true; for (const child of node.children) { if (child.type === 'element') { - if (pathElems.includes(child.name) === false) { + if (!pathElems.has(child.name)) { everyChildIsPath = false; } if (initial) { @@ -72,7 +72,7 @@ exports.fn = (root) => { // collect all inheritable attributes from first child element for (const [name, value] of Object.entries(child.attributes)) { // consider only inheritable attributes - if (inheritableAttrs.includes(name)) { + if (inheritableAttrs.has(name)) { commonAttributes.set(name, value); } } diff --git a/plugins/moveGroupAttrsToElems.js b/plugins/moveGroupAttrsToElems.js index d774867ef..450fb2654 100644 --- a/plugins/moveGroupAttrsToElems.js +++ b/plugins/moveGroupAttrsToElems.js @@ -37,7 +37,7 @@ exports.fn = () => { node.attributes.transform != null && Object.entries(node.attributes).some( ([name, value]) => - referencesProps.includes(name) && includesUrlReference(value), + referencesProps.has(name) && includesUrlReference(value), ) === false && node.children.every( (child) => diff --git a/plugins/removeEditorsNSData.js b/plugins/removeEditorsNSData.js index e85bef898..992241ea2 100644 --- a/plugins/removeEditorsNSData.js +++ b/plugins/removeEditorsNSData.js @@ -19,7 +19,7 @@ exports.description = 'removes editors namespaces, elements and attributes'; * @type {import('./plugins-types').Plugin<'removeEditorsNSData'>} */ exports.fn = (_root, params) => { - let namespaces = editorNamespaces; + let namespaces = [...editorNamespaces]; if (Array.isArray(params.additionalNamespaces)) { namespaces = [...editorNamespaces, ...params.additionalNamespaces]; } diff --git a/plugins/removeEmptyAttrs.js b/plugins/removeEmptyAttrs.js index 83f567c3b..194d27b81 100644 --- a/plugins/removeEmptyAttrs.js +++ b/plugins/removeEmptyAttrs.js @@ -20,7 +20,7 @@ exports.fn = () => { if ( value === '' && // empty conditional processing attributes prevents elements from rendering - attrsGroups.conditionalProcessing.includes(name) === false + !attrsGroups.conditionalProcessing.has(name) ) { delete node.attributes[name]; } diff --git a/plugins/removeEmptyContainers.js b/plugins/removeEmptyContainers.js index bff3ab9c9..039073449 100644 --- a/plugins/removeEmptyContainers.js +++ b/plugins/removeEmptyContainers.js @@ -28,7 +28,7 @@ exports.fn = () => { // remove only empty non-svg containers if ( node.name === 'svg' || - elemsGroups.container.includes(node.name) === false || + !elemsGroups.container.has(node.name) || node.children.length !== 0 ) { return; diff --git a/plugins/removeHiddenElems.js b/plugins/removeHiddenElems.js index 6ed2750bb..75720a068 100644 --- a/plugins/removeHiddenElems.js +++ b/plugins/removeHiddenElems.js @@ -114,7 +114,7 @@ exports.fn = (root, params) => { element: { enter: (node, parentNode) => { // transparent non-rendering elements still apply where referenced - if (nonRendering.includes(node.name)) { + if (nonRendering.has(node.name)) { if (node.attributes.id == null) { detachNodeFromParent(node, parentNode); return visitSkip; diff --git a/plugins/removeNonInheritableGroupAttrs.js b/plugins/removeNonInheritableGroupAttrs.js index faa93dffe..73e6bcdad 100644 --- a/plugins/removeNonInheritableGroupAttrs.js +++ b/plugins/removeNonInheritableGroupAttrs.js @@ -24,9 +24,9 @@ exports.fn = () => { if (node.name === 'g') { for (const name of Object.keys(node.attributes)) { if ( - attrsGroups.presentation.includes(name) === true && - inheritableAttrs.includes(name) === false && - presentationNonInheritableGroupAttrs.includes(name) === false + attrsGroups.presentation.has(name) && + !inheritableAttrs.has(name) && + !presentationNonInheritableGroupAttrs.has(name) ) { delete node.attributes[name]; } diff --git a/plugins/removeUnknownsAndDefaults.js b/plugins/removeUnknownsAndDefaults.js index c39d3c030..e76e4e5fe 100644 --- a/plugins/removeUnknownsAndDefaults.js +++ b/plugins/removeUnknownsAndDefaults.js @@ -197,7 +197,7 @@ exports.fn = (root, params) => { if (uselessOverrides && node.attributes.id == null) { const style = computedParentStyle?.[name]; if ( - presentationNonInheritableGroupAttrs.includes(name) === false && + presentationNonInheritableGroupAttrs.has(name) === false && style != null && style.type === 'static' && style.value === value diff --git a/plugins/removeUselessDefs.js b/plugins/removeUselessDefs.js index 46461a98f..d642b874e 100644 --- a/plugins/removeUselessDefs.js +++ b/plugins/removeUselessDefs.js @@ -39,7 +39,7 @@ exports.fn = () => { } node.children = usefulNodes; } else if ( - elemsGroups.nonRendering.includes(node.name) && + elemsGroups.nonRendering.has(node.name) && node.attributes.id == null ) { detachNodeFromParent(node, parentNode); diff --git a/plugins/removeUselessStrokeAndFill.js b/plugins/removeUselessStrokeAndFill.js index f5f998551..95193fa63 100644 --- a/plugins/removeUselessStrokeAndFill.js +++ b/plugins/removeUselessStrokeAndFill.js @@ -46,7 +46,7 @@ exports.fn = (root, params) => { if (node.attributes.id != null) { return visitSkip; } - if (elemsGroups.shape.includes(node.name) == false) { + if (!elemsGroups.shape.has(node.name)) { return; } const computedStyle = computeStyle(stylesheet, node); diff --git a/plugins/removeViewBox.js b/plugins/removeViewBox.js index 5618d8bd7..c0f23de26 100644 --- a/plugins/removeViewBox.js +++ b/plugins/removeViewBox.js @@ -3,7 +3,7 @@ exports.name = 'removeViewBox'; exports.description = 'removes viewBox attribute when possible'; -const viewBoxElems = ['svg', 'pattern', 'symbol']; +const viewBoxElems = new Set(['pattern', 'svg', 'symbol']); /** * Remove viewBox attr which coincides with a width/height box. @@ -24,7 +24,7 @@ exports.fn = () => { element: { enter: (node, parentNode) => { if ( - viewBoxElems.includes(node.name) && + viewBoxElems.has(node.name) && node.attributes.viewBox != null && node.attributes.width != null && node.attributes.height != null diff --git a/plugins/removeXlink.js b/plugins/removeXlink.js index 190e4e3d1..0411cc145 100644 --- a/plugins/removeXlink.js +++ b/plugins/removeXlink.js @@ -28,17 +28,17 @@ const SHOW_TO_TARGET = { * Elements that use xlink:href, but were deprecated in SVG 2 and therefore * don't support the SVG 2 href attribute. * - * @type {string[]} + * @type {Set} * @see https://developer.mozilla.org/docs/Web/SVG/Attribute/xlink:href * @see https://developer.mozilla.org/docs/Web/SVG/Attribute/href */ -const LEGACY_ELEMENTS = [ +const LEGACY_ELEMENTS = new Set([ 'cursor', 'filter', 'font-face-uri', 'glyphRef', 'tref', -]; +]); /** * @param {XastElement} node @@ -170,7 +170,7 @@ exports.fn = (_, params) => { if ( hrefAttrs.length > 0 && - LEGACY_ELEMENTS.includes(node.name) && + LEGACY_ELEMENTS.has(node.name) && !includeLegacy ) { hrefAttrs