diff --git a/plugins/cleanupListOfValues.js b/plugins/cleanupListOfValues.js index d32e8de7..047eb3fd 100644 --- a/plugins/cleanupListOfValues.js +++ b/plugins/cleanupListOfValues.js @@ -3,20 +3,10 @@ const { removeLeadingZero } = require('../lib/svgo/tools.js'); exports.name = 'cleanupListOfValues'; - -exports.type = 'perItem'; - +exports.type = 'visitor'; exports.active = false; - exports.description = 'rounds list of values to the fixed precision'; -exports.params = { - floatPrecision: 3, - leadingZero: true, - defaultPx: true, - convertToPx: true, -}; - const regNumericValues = /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/; const regSeparator = /\s+,?\s*|,\s*/; const absoluteLengths = { @@ -42,88 +32,48 @@ const absoluteLengths = { * * * - * @param {Object} item current iteration item - * @param {Object} params plugin params - * @return {Boolean} if false, item will be filtered out - * * @author kiyopikko */ -exports.fn = function (item, params) { - if (item.type !== 'element') { - return; - } +exports.fn = (root, params) => { + const { + floatPrecision = 3, + leadingZero = true, + defaultPx = true, + convertToPx = true, + } = params; - if (item.attributes.points != null) { - item.attributes.points = roundValues(item.attributes.points); - } + const roundValues = (lists) => { + const roundedList = []; - if (item.attributes['enable-background'] != null) { - item.attributes['enable-background'] = roundValues( - item.attributes['enable-background'] - ); - } - - if (item.attributes.viewBox != null) { - item.attributes.viewBox = roundValues(item.attributes.viewBox); - } - - if (item.attributes['stroke-dasharray'] != null) { - item.attributes['stroke-dasharray'] = roundValues( - item.attributes['stroke-dasharray'] - ); - } - - if (item.attributes.dx != null) { - item.attributes.dx = roundValues(item.attributes.dx); - } - - if (item.attributes.dy != null) { - item.attributes.dy = roundValues(item.attributes.dy); - } - - if (item.attributes.x != null) { - item.attributes.x = roundValues(item.attributes.x); - } - - if (item.attributes.y != null) { - item.attributes.y = roundValues(item.attributes.y); - } - - function roundValues(lists) { - var num, - units, - match, - matchNew, - listsArr = lists.split(regSeparator), - roundedList = []; - - for (const elem of listsArr) { - match = elem.match(regNumericValues); - matchNew = elem.match(/new/); + for (const elem of lists.split(regSeparator)) { + const match = elem.match(regNumericValues); + const matchNew = elem.match(/new/); // if attribute value matches regNumericValues if (match) { // round it to the fixed precision - (num = +(+match[1]).toFixed(params.floatPrecision)), - (units = match[3] || ''); + let num = Number(Number(match[1]).toFixed(floatPrecision)); + let units = match[3] || ''; // convert absolute values to pixels - if (params.convertToPx && units && units in absoluteLengths) { - var pxNum = +(absoluteLengths[units] * match[1]).toFixed( - params.floatPrecision + if (convertToPx && units && units in absoluteLengths) { + const pxNum = Number( + (absoluteLengths[units] * match[1]).toFixed(floatPrecision) ); - if (String(pxNum).length < match[0].length) - (num = pxNum), (units = 'px'); + if (pxNum.toString().length < match[0].length) { + num = pxNum; + units = 'px'; + } } // and remove leading zero - if (params.leadingZero) { + if (leadingZero) { num = removeLeadingZero(num); } // remove default 'px' units - if (params.defaultPx && units === 'px') { + if (defaultPx && units === 'px') { units = ''; } @@ -138,5 +88,47 @@ exports.fn = function (item, params) { } return roundedList.join(' '); - } + }; + + return { + element: { + enter: (node) => { + if (node.attributes.points != null) { + node.attributes.points = roundValues(node.attributes.points); + } + + if (node.attributes['enable-background'] != null) { + node.attributes['enable-background'] = roundValues( + node.attributes['enable-background'] + ); + } + + if (node.attributes.viewBox != null) { + node.attributes.viewBox = roundValues(node.attributes.viewBox); + } + + if (node.attributes['stroke-dasharray'] != null) { + node.attributes['stroke-dasharray'] = roundValues( + node.attributes['stroke-dasharray'] + ); + } + + if (node.attributes.dx != null) { + node.attributes.dx = roundValues(node.attributes.dx); + } + + if (node.attributes.dy != null) { + node.attributes.dy = roundValues(node.attributes.dy); + } + + if (node.attributes.x != null) { + node.attributes.x = roundValues(node.attributes.x); + } + + if (node.attributes.y != null) { + node.attributes.y = roundValues(node.attributes.y); + } + }, + }, + }; }; diff --git a/plugins/cleanupNumericValues.js b/plugins/cleanupNumericValues.js index c12dc2e5..5bb80d86 100644 --- a/plugins/cleanupNumericValues.js +++ b/plugins/cleanupNumericValues.js @@ -1,94 +1,91 @@ 'use strict'; +const { removeLeadingZero } = require('../lib/svgo/tools'); + exports.name = 'cleanupNumericValues'; - -exports.type = 'perItem'; - +exports.type = 'visitor'; exports.active = true; - exports.description = 'rounds numeric values to the fixed precision, removes default ‘px’ units'; -exports.params = { - floatPrecision: 3, - leadingZero: true, - defaultPx: true, - convertToPx: true, +const regNumericValues = /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/; +const absoluteLengths = { + // relative to px + cm: 96 / 2.54, + mm: 96 / 25.4, + in: 96, + pt: 4 / 3, + pc: 16, }; -var regNumericValues = /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/, - removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero, - absoluteLengths = { - // relative to px - cm: 96 / 2.54, - mm: 96 / 25.4, - in: 96, - pt: 4 / 3, - pc: 16, - }; - /** * Round numeric values to the fixed precision, * remove default 'px' units. * - * @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') { - var floatPrecision = params.floatPrecision; +exports.fn = (root, params) => { + const { + floatPrecision = 3, + leadingZero = true, + defaultPx = true, + convertToPx = true, + } = params; - if (item.attributes.viewBox != null) { - var nums = item.attributes.viewBox.split(/\s,?\s*|,\s*/g); - item.attributes.viewBox = nums - .map(function (value) { - var num = +value; - return isNaN(num) ? value : +num.toFixed(floatPrecision); - }) - .join(' '); - } + return { + element: { + enter: (node) => { + if (node.attributes.viewBox != null) { + const nums = node.attributes.viewBox.split(/\s,?\s*|,\s*/g); + node.attributes.viewBox = nums + .map((value) => { + const num = Number(value); + return Number.isNaN(num) + ? value + : Number(num.toFixed(floatPrecision)); + }) + .join(' '); + } - for (const [name, value] of Object.entries(item.attributes)) { - // The `version` attribute is a text string and cannot be rounded - if (name === 'version') { - continue; - } + for (const [name, value] of Object.entries(node.attributes)) { + // The `version` attribute is a text string and cannot be rounded + if (name === 'version') { + continue; + } - var match = value.match(regNumericValues); + const match = value.match(regNumericValues); - // if attribute value matches regNumericValues - if (match) { - // round it to the fixed precision - var num = +(+match[1]).toFixed(floatPrecision), - units = match[3] || ''; + // if attribute value matches regNumericValues + if (match) { + // round it to the fixed precision + let num = Number(Number(match[1]).toFixed(floatPrecision)); + let units = match[3] || ''; - // convert absolute values to pixels - if (params.convertToPx && units && units in absoluteLengths) { - var pxNum = +(absoluteLengths[units] * match[1]).toFixed( - floatPrecision - ); + // convert absolute values to pixels + if (convertToPx && units && units in absoluteLengths) { + const pxNum = Number( + (absoluteLengths[units] * match[1]).toFixed(floatPrecision) + ); + if (pxNum.toString().length < match[0].length) { + num = pxNum; + units = 'px'; + } + } - if (String(pxNum).length < match[0].length) { - num = pxNum; - units = 'px'; + // and remove leading zero + if (leadingZero) { + num = removeLeadingZero(num); + } + + // remove default 'px' units + if (defaultPx && units === 'px') { + units = ''; + } + + node.attributes[name] = num + units; } } - - // and remove leading zero - if (params.leadingZero) { - num = removeLeadingZero(num); - } - - // remove default 'px' units - if (params.defaultPx && units === 'px') { - units = ''; - } - - item.attributes[name] = num + units; - } - } - } + }, + }, + }; };