diff --git a/plugins/cleanupAttrs.js b/plugins/cleanupAttrs.js index aa30369f..cb4f4942 100644 --- a/plugins/cleanupAttrs.js +++ b/plugins/cleanupAttrs.js @@ -1,52 +1,48 @@ 'use strict'; -exports.type = 'perItem'; - +exports.type = 'visitor'; exports.active = true; - exports.description = 'cleanups attributes from newlines, trailing and repeating spaces'; -exports.params = { - newlines: true, - trim: true, - spaces: true, -}; - -var regNewlinesNeedSpace = /(\S)\r?\n(\S)/g, - regNewlines = /\r?\n/g, - regSpaces = /\s{2,}/g; +const regNewlinesNeedSpace = /(\S)\r?\n(\S)/g; +const regNewlines = /\r?\n/g; +const regSpaces = /\s{2,}/g; /** * Cleanup attributes values from newlines, trailing and repeating spaces. * - * @param {Object} item current iteration item - * @param {Object} params plugin params - * @return {Boolean} if false, item will be filtered out - * * @author Kir Belevich */ -exports.fn = function (item, params) { - if (item.type === 'element') { - for (const name of Object.keys(item.attributes)) { - if (params.newlines) { - // new line which requires a space instead of themselve - item.attributes[name] = item.attributes[name].replace( - regNewlinesNeedSpace, - (match, p1, p2) => p1 + ' ' + p2 - ); - - // simple new line - item.attributes[name] = item.attributes[name].replace(regNewlines, ''); - } - - if (params.trim) { - item.attributes[name] = item.attributes[name].trim(); - } - - if (params.spaces) { - item.attributes[name] = item.attributes[name].replace(regSpaces, ' '); - } - } - } +exports.fn = (root, params) => { + const { newlines = true, trim = true, spaces = true } = params; + return { + element: { + enter: (node) => { + for (const name of Object.keys(node.attributes)) { + if (newlines) { + // new line which requires a space instead of themselve + node.attributes[name] = node.attributes[name].replace( + regNewlinesNeedSpace, + (match, p1, p2) => p1 + ' ' + p2 + ); + // simple new line + node.attributes[name] = node.attributes[name].replace( + regNewlines, + '' + ); + } + if (trim) { + node.attributes[name] = node.attributes[name].trim(); + } + if (spaces) { + node.attributes[name] = node.attributes[name].replace( + regSpaces, + ' ' + ); + } + } + }, + }, + }; }; diff --git a/plugins/convertEllipseToCircle.js b/plugins/convertEllipseToCircle.js index 2560b3ae..4d57ce83 100644 --- a/plugins/convertEllipseToCircle.js +++ b/plugins/convertEllipseToCircle.js @@ -1,9 +1,7 @@ 'use strict'; -exports.type = 'perItem'; - +exports.type = 'visitor'; exports.active = true; - exports.description = 'converts non-eccentric s to s'; /** @@ -11,26 +9,28 @@ exports.description = 'converts non-eccentric s to s'; * * @see https://www.w3.org/TR/SVG11/shapes.html * - * @param {Object} item current iteration item - * @return {Boolean} if false, item will be filtered out - * * @author Taylor Hunt */ -exports.fn = function (item) { - if (item.isElem('ellipse')) { - const rx = item.attributes.rx || 0; - const ry = item.attributes.ry || 0; - - if ( - rx === ry || - rx === 'auto' || - ry === 'auto' // SVG2 - ) { - var radius = rx !== 'auto' ? rx : ry; - item.renameElem('circle'); - delete item.attributes.rx; - delete item.attributes.ry; - item.attributes.r = radius; - } - } +exports.fn = () => { + return { + element: { + enter: (node) => { + if (node.name === 'ellipse') { + const rx = node.attributes.rx || 0; + const ry = node.attributes.ry || 0; + if ( + rx === ry || + rx === 'auto' || + ry === 'auto' // SVG2 + ) { + node.name = 'circle'; + const radius = rx === 'auto' ? ry : rx; + delete node.attributes.rx; + delete node.attributes.ry; + node.attributes.r = radius; + } + } + }, + }, + }; }; diff --git a/plugins/removeDesc.js b/plugins/removeDesc.js index 4616109c..3225e9d3 100644 --- a/plugins/removeDesc.js +++ b/plugins/removeDesc.js @@ -1,16 +1,12 @@ 'use strict'; -exports.type = 'perItem'; +const { detachNodeFromParent } = require('../lib/xast.js'); +exports.type = 'visitor'; exports.active = true; - -exports.params = { - removeAny: true, -}; - exports.description = 'removes '; -var standardDescs = /^(Created with|Created using)/; +const standardDescs = /^(Created with|Created using)/; /** * Removes . @@ -19,19 +15,24 @@ var standardDescs = /^(Created with|Created using)/; * * https://developer.mozilla.org/en-US/docs/Web/SVG/Element/desc * - * @param {Object} item current iteration item - * @return {Boolean} if false, item will be filtered out - * * @author Daniel Wabyick */ -exports.fn = function (item, params) { - return ( - !item.isElem('desc') || - !( - params.removeAny || - item.children.length === 0 || - (item.children[0].type === 'text' && - standardDescs.test(item.children[0].value)) - ) - ); +exports.fn = (root, params) => { + const { removeAny = true } = params; + return { + element: { + enter: (node, parentNode) => { + if (node.name === 'desc') { + if ( + removeAny || + node.children.length === 0 || + (node.children[0].type === 'text' && + standardDescs.test(node.children[0].value)) + ) { + detachNodeFromParent(node, parentNode); + } + } + }, + }, + }; }; diff --git a/plugins/removeDoctype.js b/plugins/removeDoctype.js index 6e17bd87..73bb9179 100644 --- a/plugins/removeDoctype.js +++ b/plugins/removeDoctype.js @@ -1,9 +1,9 @@ 'use strict'; -exports.type = 'perItem'; +const { detachNodeFromParent } = require('../lib/xast.js'); +exports.type = 'visitor'; exports.active = true; - exports.description = 'removes doctype declaration'; /** @@ -26,13 +26,14 @@ exports.description = 'removes doctype declaration'; * * ]> * - * @param {Object} item current iteration item - * @return {Boolean} if false, item will be filtered out - * * @author Kir Belevich */ -exports.fn = function (item) { - if (item.type === 'doctype') { - return false; - } +exports.fn = () => { + return { + doctype: { + enter: (node, parentNode) => { + detachNodeFromParent(node, parentNode); + }, + }, + }; }; diff --git a/plugins/removeEmptyText.js b/plugins/removeEmptyText.js index 30d3e7c2..675125a5 100644 --- a/plugins/removeEmptyText.js +++ b/plugins/removeEmptyText.js @@ -1,17 +1,11 @@ 'use strict'; -exports.type = 'perItem'; +const { detachNodeFromParent } = require('../lib/xast.js'); +exports.type = 'visitor'; exports.active = true; - exports.description = 'removes empty elements'; -exports.params = { - text: true, - tspan: true, - tref: true, -}; - /** * Remove empty Text elements. * @@ -27,31 +21,30 @@ exports.params = { * Remove tref with empty xlink:href attribute: * * - * @param {Object} item current iteration item - * @param {Object} params plugin params - * @return {Boolean} if false, item will be filtered out - * * @author Kir Belevich */ -exports.fn = function (item, params) { - if (item.type === 'element') { - // Remove empty text element - if (params.text && item.name === 'text' && item.children.length === 0) { - return false; - } - - // Remove empty tspan element - if (params.tspan && item.name === 'tspan' && item.children.length === 0) { - return false; - } - - // Remove tref with empty xlink:href attribute - if ( - params.tref && - item.name === 'tref' && - item.attributes['xlink:href'] == null - ) { - return false; - } - } +exports.fn = (root, params) => { + const { text = true, tspan = true, tref = true } = params; + return { + element: { + enter: (node, parentNode) => { + // Remove empty text element + if (text && node.name === 'text' && node.children.length === 0) { + detachNodeFromParent(node, parentNode); + } + // Remove empty tspan element + if (tspan && node.name === 'tspan' && node.children.length === 0) { + detachNodeFromParent(node, parentNode); + } + // Remove tref with empty xlink:href attribute + if ( + tref && + node.name === 'tref' && + node.attributes['xlink:href'] == null + ) { + detachNodeFromParent(node, parentNode); + } + }, + }, + }; }; diff --git a/plugins/removeMetadata.js b/plugins/removeMetadata.js index 451af5f7..2376646e 100644 --- a/plugins/removeMetadata.js +++ b/plugins/removeMetadata.js @@ -1,9 +1,9 @@ 'use strict'; -exports.type = 'perItem'; +const { detachNodeFromParent } = require('../lib/xast.js'); +exports.type = 'visitor'; exports.active = true; - exports.description = 'removes '; /** @@ -11,11 +11,16 @@ exports.description = 'removes '; * * https://www.w3.org/TR/SVG11/metadata.html * - * @param {Object} item current iteration item - * @return {Boolean} if false, item will be filtered out - * * @author Kir Belevich */ -exports.fn = function (item) { - return !item.isElem('metadata'); +exports.fn = () => { + return { + element: { + enter: (node, parentNode) => { + if (node.name === 'metadata') { + detachNodeFromParent(node, parentNode); + } + }, + }, + }; }; diff --git a/plugins/removeRasterImages.js b/plugins/removeRasterImages.js index ec87f8bd..8944552e 100644 --- a/plugins/removeRasterImages.js +++ b/plugins/removeRasterImages.js @@ -1,9 +1,9 @@ 'use strict'; -exports.type = 'perItem'; +const { detachNodeFromParent } = require('../lib/xast.js'); +exports.type = 'visitor'; exports.active = false; - exports.description = 'removes raster images (disabled by default)'; /** @@ -11,18 +11,20 @@ exports.description = 'removes raster images (disabled by default)'; * * @see https://bugs.webkit.org/show_bug.cgi?id=63548 * - * @param {Object} item current iteration item - * @return {Boolean} if false, item will be filtered out - * * @author Kir Belevich */ -exports.fn = function (item) { - if ( - item.type === 'element' && - item.name === 'image' && - item.attributes['xlink:href'] != null && - /(\.|image\/)(jpg|png|gif)/.test(item.attributes['xlink:href']) - ) { - return false; - } +exports.fn = () => { + return { + element: { + enter: (node, parentNode) => { + if ( + node.name === 'image' && + node.attributes['xlink:href'] != null && + /(\.|image\/)(jpg|png|gif)/.test(node.attributes['xlink:href']) + ) { + detachNodeFromParent(node, parentNode); + } + }, + }, + }; }; diff --git a/plugins/removeScriptElement.js b/plugins/removeScriptElement.js index 7ae4d3d8..47e4dd1d 100644 --- a/plugins/removeScriptElement.js +++ b/plugins/removeScriptElement.js @@ -1,9 +1,9 @@ 'use strict'; -exports.type = 'perItem'; +const { detachNodeFromParent } = require('../lib/xast.js'); +exports.type = 'visitor'; exports.active = false; - exports.description = 'removes