1
0
mirror of https://github.com/svg/svgo.git synced 2025-08-01 18:46:52 +03:00

Replace removeAttr with delete operator (#1432)

delete operator is more explicit and not much harder to use.
This commit is contained in:
Bogdan Chadkin
2021-03-17 21:40:06 +03:00
committed by GitHub
parent 8098ab7fb6
commit 07928fc77e
24 changed files with 138 additions and 121 deletions

View File

@ -307,20 +307,23 @@ JSAPI.prototype.computedAttr = function (name, val) {
* @param {String} [val] attribute value * @param {String} [val] attribute value
* @return {Boolean} * @return {Boolean}
*/ */
JSAPI.prototype.removeAttr = function (name, val, recursive) { JSAPI.prototype.removeAttr = function (name, val) {
if (!arguments.length) return false; if (this.type !== 'element') {
if (Array.isArray(name)) {
name.forEach(this.removeAttr, this);
return false; return false;
} }
if (arguments.length === 0) {
if (!this.hasAttr(name)) return false; return false;
}
if (!recursive && val && this.attrs[name].value !== val) return false; if (Array.isArray(name)) {
for (const nameItem of name) {
delete this.attrs[name]; this.removeAttr(nameItem, val);
}
return false;
}
if (this.hasAttr(name, val) === false) {
return false;
}
delete this.attributes[name];
return true; return true;
}; };

View File

@ -118,7 +118,7 @@ const applyTransforms = (elem, pathData, params) => {
applyMatrixToPathData(pathData, matrix.data); applyMatrixToPathData(pathData, matrix.data);
// remove transform attr // remove transform attr
elem.removeAttr('transform'); delete elem.attributes.transform;
return; return;
}; };

View File

@ -30,23 +30,23 @@ exports.fn = function (data) {
function checkEnableBackground(item) { function checkEnableBackground(item) {
if ( if (
item.isElem(elems) && item.isElem(elems) &&
item.hasAttr('enable-background') && item.attributes['enable-background'] != null &&
item.hasAttr('width') && item.attributes.width != null &&
item.hasAttr('height') item.attributes.height != null
) { ) {
var match = item var match = item.attributes['enable-background'].match(
.attr('enable-background') regEnableBackground
.value.match(regEnableBackground); );
if (match) { if (match) {
if ( if (
item.attr('width').value === match[1] && item.attributes.width === match[1] &&
item.attr('height').value === match[3] item.attributes.height === match[3]
) { ) {
if (item.isElem('svg')) { if (item.isElem('svg')) {
item.removeAttr('enable-background'); delete item.attributes['enable-background'];
} else { } else {
item.attr('enable-background').value = 'new'; item.attributes['enable-background'] = 'new';
} }
} }
} }
@ -79,8 +79,10 @@ exports.fn = function (data) {
return hasFilter return hasFilter
? firstStep ? firstStep
: monkeys(firstStep, function (item) { : monkeys(firstStep, (item) => {
//we don't need 'enable-background' if we have no filters if (item.type === 'element') {
item.removeAttr('enable-background'); //we don't need 'enable-background' if we have no filters
delete item.attributes['enable-background'];
}
}); });
}; };

View File

@ -154,7 +154,7 @@ exports.fn = function (data, params) {
if (name === 'id') { if (name === 'id') {
key = value; key = value;
if (IDs.has(key)) { if (IDs.has(key)) {
item.removeAttr('id'); // remove repeated id delete item.attributes.id; // remove repeated id
} else { } else {
IDs.set(key, item); IDs.set(key, item);
} }
@ -230,7 +230,7 @@ exports.fn = function (data, params) {
if (params.remove) { if (params.remove) {
for (var keyElem of IDs) { for (var keyElem of IDs) {
if (!idPreserved(keyElem[0])) { if (!idPreserved(keyElem[0])) {
keyElem[1].removeAttr('id'); delete keyElem[1].attributes.id;
} }
} }
} }

View File

@ -46,7 +46,7 @@ exports.fn = function (item) {
// non-empty elements // non-empty elements
if ( if (
item.type === 'element' && item.type === 'element' &&
!item.isElem('switch') && item.name !== 'switch' &&
item.children.length !== 0 item.children.length !== 0
) { ) {
item.children.forEach(function (g, i) { item.children.forEach(function (g, i) {
@ -82,7 +82,7 @@ exports.fn = function (item) {
return; return;
} }
g.removeAttr(name); delete g.attributes[name];
} }
} }
} }

View File

@ -18,8 +18,8 @@ exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
*/ */
exports.fn = function (item) { exports.fn = function (item) {
if (item.isElem('ellipse')) { if (item.isElem('ellipse')) {
var rx = (item.hasAttr('rx') && item.attr('rx').value) || 0; const rx = item.attributes.rx || 0;
var ry = (item.hasAttr('ry') && item.attr('ry').value) || 0; const ry = item.attributes.ry || 0;
if ( if (
rx === ry || rx === ry ||
@ -28,12 +28,9 @@ exports.fn = function (item) {
) { ) {
var radius = rx !== 'auto' ? rx : ry; var radius = rx !== 'auto' ? rx : ry;
item.renameElem('circle'); item.renameElem('circle');
item.removeAttr(['rx', 'ry']); delete item.attributes.rx;
item.addAttr({ delete item.attributes.ry;
name: 'r', item.attributes.r = radius;
value: radius,
});
} }
} }
return;
}; };

View File

@ -59,7 +59,11 @@ exports.fn = function (item, params) {
name: 'd', name: 'd',
value: stringifyPathData({ pathData, precision }), value: stringifyPathData({ pathData, precision }),
}); });
item.renameElem('path').removeAttr(['x', 'y', 'width', 'height']); item.renameElem('path');
delete item.attributes.x;
delete item.attributes.y;
delete item.attributes.width;
delete item.attributes.height;
} }
if (item.isElem('line')) { if (item.isElem('line')) {
@ -76,7 +80,11 @@ exports.fn = function (item, params) {
name: 'd', name: 'd',
value: stringifyPathData({ pathData, precision }), value: stringifyPathData({ pathData, precision }),
}); });
item.renameElem('path').removeAttr(['x1', 'y1', 'x2', 'y2']); item.renameElem('path');
delete item.attributes.x1;
delete item.attributes.y1;
delete item.attributes.x2;
delete item.attributes.y2;
} }
if ( if (
@ -99,7 +107,8 @@ exports.fn = function (item, params) {
name: 'd', name: 'd',
value: stringifyPathData({ pathData, precision }), value: stringifyPathData({ pathData, precision }),
}); });
item.renameElem('path').removeAttr('points'); item.renameElem('path');
delete item.attributes.points;
} }
if (item.isElem('circle') && convertArcs) { if (item.isElem('circle') && convertArcs) {
@ -119,7 +128,10 @@ exports.fn = function (item, params) {
name: 'd', name: 'd',
value: stringifyPathData({ pathData, precision }), value: stringifyPathData({ pathData, precision }),
}); });
item.renameElem('path').removeAttr(['cx', 'cy', 'r']); item.renameElem('path');
delete item.attributes.cx;
delete item.attributes.cy;
delete item.attributes.r;
} }
if (item.isElem('ellipse') && convertArcs) { if (item.isElem('ellipse') && convertArcs) {
@ -140,6 +152,10 @@ exports.fn = function (item, params) {
name: 'd', name: 'd',
value: stringifyPathData({ pathData, precision }), value: stringifyPathData({ pathData, precision }),
}); });
item.renameElem('path').removeAttr(['cx', 'cy', 'rx', 'ry']); item.renameElem('path');
delete item.attributes.cx;
delete item.attributes.cy;
delete item.attributes.rx;
delete item.attributes.ry;
} }
}; };

View File

@ -122,7 +122,7 @@ exports.fn = function (item, params) {
}) })
.join(';'); .join(';');
} else { } else {
item.removeAttr('style'); delete item.attributes.style;
} }
} }
} }

View File

@ -88,9 +88,9 @@ function convertTransform(item, attrName, params) {
} }
if (data.length) { if (data.length) {
item.attr(attrName).value = js2transform(data, params); item.attributes[attrName] = js2transform(data, params);
} else { } else {
item.removeAttr(attrName); delete item.attributes[attrName];
} }
} }

View File

@ -207,12 +207,14 @@ exports.fn = function (document, opts) {
} }
// clean up now empty class attributes // clean up now empty class attributes
if (typeof selectedEl.class.item(0) === 'undefined') { if (typeof selectedEl.class.item(0) === 'undefined') {
selectedEl.removeAttr('class'); delete selectedEl.attributes.class;
} }
// ID // ID
if (firstSubSelector.type === 'IdSelector') { if (firstSubSelector.type === 'IdSelector') {
selectedEl.removeAttr('id', firstSubSelector.name); if (selectedEl.attributes.id === firstSubSelector.name) {
delete selectedEl.attributes.id;
}
} }
} }
} }

View File

@ -64,7 +64,7 @@ exports.fn = function (item) {
item.children.forEach(function (g) { item.children.forEach(function (g) {
for (const [name, value] of Object.entries(intersection)) { for (const [name, value] of Object.entries(intersection)) {
if ((!allPath && !hasClip) || name !== 'transform') { if ((!allPath && !hasClip) || name !== 'transform') {
g.removeAttr(name); delete g.attributes[name];
if (name === 'transform') { if (name === 'transform') {
if (!hasTransform) { if (!hasTransform) {

View File

@ -32,7 +32,8 @@ var collections = require('./_collections.js'),
exports.fn = function (item) { exports.fn = function (item) {
// move group transform attr to content's pathElems // move group transform attr to content's pathElems
if ( if (
item.isElem('g') && item.type === 'element' &&
item.name === 'g' &&
item.children.length !== 0 && item.children.length !== 0 &&
item.attributes.transform != null && item.attributes.transform != null &&
Object.entries(item.attributes).some( Object.entries(item.attributes).some(
@ -52,6 +53,6 @@ exports.fn = function (item) {
} }
} }
item.removeAttr('transform'); delete item.attributes.transform;
} }
}; };

View File

@ -60,9 +60,15 @@ exports.description =
exports.fn = function (item, params) { exports.fn = function (item, params) {
var selectors = Array.isArray(params.selectors) ? params.selectors : [params]; var selectors = Array.isArray(params.selectors) ? params.selectors : [params];
selectors.map(function (i) { selectors.map(({ selector, attributes }) => {
if (item.matches(i.selector)) { if (item.matches(selector)) {
item.removeAttr(i.attributes); if (Array.isArray(attributes)) {
for (const name of attributes) {
delete item.attributes[name];
}
} else {
delete item.attributes[attributes];
}
} }
}); });
}; };

View File

@ -135,7 +135,7 @@ exports.fn = function (item, params) {
if (pattern[1].test(name)) { if (pattern[1].test(name)) {
// matches attribute value // matches attribute value
if (pattern[2].test(value)) { if (pattern[2].test(value)) {
item.removeAttr(name); delete item.attributes[name];
} }
} }
} }

View File

@ -21,26 +21,21 @@ exports.description =
* @author Benny Schudel * @author Benny Schudel
*/ */
exports.fn = function (item) { exports.fn = function (item) {
if (item.isElem('svg')) { if (item.type === 'element' && item.name === 'svg') {
if (item.hasAttr('viewBox')) { if (item.attributes.viewBox != null) {
item.removeAttr('width'); delete item.attributes.width;
item.removeAttr('height'); delete item.attributes.height;
} else if ( } else if (
item.hasAttr('width') && item.attributes.width != null &&
item.hasAttr('height') && item.attributes.height != null &&
!isNaN(Number(item.attr('width').value)) && Number.isNaN(Number(item.attributes.width)) === false &&
!isNaN(Number(item.attr('height').value)) Number.isNaN(Number(item.attributes.height)) === false
) { ) {
item.addAttr({ const width = Number(item.attributes.width);
name: 'viewBox', const height = Number(item.attributes.height);
value: item.attributes.viewBox = `0 0 ${width} ${height}`;
'0 0 ' + delete item.attributes.width;
Number(item.attr('width').value) + delete item.attributes.height;
' ' +
Number(item.attr('height').value),
});
item.removeAttr('width');
item.removeAttr('height');
} }
} }
}; };

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const { parseName } = require('../lib/svgo/tools.js'); const { parseName } = require('../lib/svgo/tools.js');
const { editorNamespaces } = require('./_collections');
exports.type = 'perItem'; exports.type = 'perItem';
@ -8,8 +9,7 @@ exports.active = true;
exports.description = 'removes editors namespaces, elements and attributes'; exports.description = 'removes editors namespaces, elements and attributes';
var editorNamespaces = require('./_collections').editorNamespaces, const prefixes = [];
prefixes = [];
exports.params = { exports.params = {
additionalNamespaces: [], additionalNamespaces: [],
@ -30,19 +30,20 @@ exports.params = {
* @author Kir Belevich * @author Kir Belevich
*/ */
exports.fn = function (item, params) { exports.fn = function (item, params) {
let namespaces = editorNamespaces;
if (Array.isArray(params.additionalNamespaces)) { if (Array.isArray(params.additionalNamespaces)) {
editorNamespaces = editorNamespaces.concat(params.additionalNamespaces); namespaces = [...editorNamespaces, ...params.additionalNamespaces];
} }
if (item.type === 'element') { if (item.type === 'element') {
if (item.isElem('svg')) { if (item.isElem('svg')) {
for (const [name, value] of Object.entries(item.attributes)) { for (const [name, value] of Object.entries(item.attributes)) {
const { prefix, local } = parseName(name); const { prefix, local } = parseName(name);
if (prefix === 'xmlns' && editorNamespaces.includes(value)) { if (prefix === 'xmlns' && namespaces.includes(value)) {
prefixes.push(local); prefixes.push(local);
// <svg xmlns:sodipodi=""> // <svg xmlns:sodipodi="">
item.removeAttr(name); delete item.attributes[name];
} }
} }
} }
@ -51,7 +52,7 @@ exports.fn = function (item, params) {
for (const name of Object.keys(item.attributes)) { for (const name of Object.keys(item.attributes)) {
const { prefix } = parseName(name); const { prefix } = parseName(name);
if (prefixes.includes(prefix)) { if (prefixes.includes(prefix)) {
item.removeAttr(name); delete item.attributes[name];
} }
} }

View File

@ -24,7 +24,7 @@ exports.fn = function (item) {
// empty conditional processing attributes prevents elements from rendering // empty conditional processing attributes prevents elements from rendering
attrsGroups.conditionalProcessing.includes(name) === false attrsGroups.conditionalProcessing.includes(name) === false
) { ) {
item.removeAttr(name); delete item.attributes[name];
} }
} }
} }

View File

@ -29,7 +29,7 @@ exports.fn = function (item) {
inheritableAttrs.includes(name) === false && inheritableAttrs.includes(name) === false &&
presentationNonInheritableGroupAttrs.includes(name) === false presentationNonInheritableGroupAttrs.includes(name) === false
) { ) {
item.removeAttr(name); delete item.attributes[name];
} }
} }
} }

View File

@ -107,19 +107,19 @@ exports.fn = function (item, params) {
(params.unknownAttrs && elems[elem].attrs.indexOf(name) === -1) || (params.unknownAttrs && elems[elem].attrs.indexOf(name) === -1) ||
// attrs with default values // attrs with default values
(params.defaultAttrs && (params.defaultAttrs &&
!item.hasAttr('id') && item.attributes.id == null &&
elems[elem].defaults && elems[elem].defaults &&
elems[elem].defaults[name] === value && elems[elem].defaults[name] === value &&
(attrsInheritable.indexOf(name) < 0 || (attrsInheritable.includes(name) === false ||
!item.parentNode.computedAttr(name))) || !item.parentNode.computedAttr(name))) ||
// useless overrides // useless overrides
(params.uselessOverrides && (params.uselessOverrides &&
!item.hasAttr('id') && item.attributes.id == null &&
applyGroups.indexOf(name) < 0 && applyGroups.includes(name) === false &&
attrsInheritable.indexOf(name) > -1 && attrsInheritable.includes(name) === true &&
item.parentNode.computedAttr(name, value)) item.parentNode.computedAttr(name, value))
) { ) {
item.removeAttr(name); delete item.attributes[name];
} }
} }
} }

View File

@ -17,8 +17,8 @@ exports.description = 'removes unused namespaces declaration';
* @author Kir Belevich * @author Kir Belevich
*/ */
exports.fn = function (data) { exports.fn = function (data) {
var svgElem, let svgElem;
xmlnsCollection = []; const xmlnsCollection = [];
/** /**
* Remove namespace from collection. * Remove namespace from collection.
@ -26,7 +26,7 @@ exports.fn = function (data) {
* @param {String} ns namescape name * @param {String} ns namescape name
*/ */
function removeNSfromCollection(ns) { function removeNSfromCollection(ns) {
var pos = xmlnsCollection.indexOf(ns); const pos = xmlnsCollection.indexOf(ns);
// if found - remove ns from the namespaces collection // if found - remove ns from the namespaces collection
if (pos > -1) { if (pos > -1) {
@ -89,7 +89,7 @@ exports.fn = function (data) {
// remove svg element ns-attributes if they are not used even once // remove svg element ns-attributes if they are not used even once
if (xmlnsCollection.length) { if (xmlnsCollection.length) {
xmlnsCollection.forEach(function (name) { xmlnsCollection.forEach(function (name) {
svgElem.removeAttr('xmlns:' + name); delete svgElem.attributes['xmlns:' + name];
}); });
} }

View File

@ -58,15 +58,13 @@ exports.fn = function (item, params) {
for (const name of Object.keys(item.attributes)) { for (const name of Object.keys(item.attributes)) {
if (regStrokeProps.test(name)) { if (regStrokeProps.test(name)) {
item.removeAttr(name); delete item.attributes[name];
} }
} }
if (declineStroke) if (declineStroke) {
item.addAttr({ item.attributes.stroke = 'none';
name: 'stroke', }
value: 'none',
});
} }
} }
@ -74,17 +72,12 @@ exports.fn = function (item, params) {
if (params.fill && (!fill || item.computedAttr('fill-opacity', '0'))) { if (params.fill && (!fill || item.computedAttr('fill-opacity', '0'))) {
for (const name of Object.keys(item.attributes)) { for (const name of Object.keys(item.attributes)) {
if (regFillProps.test(name)) { if (regFillProps.test(name)) {
item.removeAttr(name); delete item.attributes[name];
} }
} }
if (fill) { if (fill) {
if (item.hasAttr('fill')) item.attr('fill').value = 'none'; item.attributes.fill = 'none';
else
item.addAttr({
name: 'fill',
value: 'none',
});
} }
} }

View File

@ -6,7 +6,7 @@ exports.active = true;
exports.description = 'removes viewBox attribute when possible'; exports.description = 'removes viewBox attribute when possible';
var viewBoxElems = ['svg', 'pattern', 'symbol']; const viewBoxElems = ['svg', 'pattern', 'symbol'];
/** /**
* Remove viewBox attr which coincides with a width/height box. * Remove viewBox attr which coincides with a width/height box.
@ -25,25 +25,26 @@ var viewBoxElems = ['svg', 'pattern', 'symbol'];
*/ */
exports.fn = function (item) { exports.fn = function (item) {
if ( if (
item.isElem(viewBoxElems) && item.type === 'element' &&
item.hasAttr('viewBox') && viewBoxElems.includes(item.name) &&
item.hasAttr('width') && item.attributes.viewBox != null &&
item.hasAttr('height') item.attributes.width != null &&
item.attributes.height != null
) { ) {
// TODO remove width/height for such case instead // TODO remove width/height for such case instead
if (item.isElem('svg') && item.closestElem('svg')) { if (item.name === 'svg' && item.closestElem('svg')) {
return; return;
} }
var nums = item.attr('viewBox').value.split(/[ ,]+/g); const nums = item.attributes.viewBox.split(/[ ,]+/g);
if ( if (
nums[0] === '0' && nums[0] === '0' &&
nums[1] === '0' && nums[1] === '0' &&
item.attr('width').value.replace(/px$/, '') === nums[2] && // could use parseFloat too item.attributes.width.replace(/px$/, '') === nums[2] && // could use parseFloat too
item.attr('height').value.replace(/px$/, '') === nums[3] item.attributes.height.replace(/px$/, '') === nums[3]
) { ) {
item.removeAttr('viewBox'); delete item.attributes.viewBox;
} }
} }
}; };

View File

@ -21,7 +21,7 @@ exports.description =
* @author Ricardo Tomasi * @author Ricardo Tomasi
*/ */
exports.fn = function (item) { exports.fn = function (item) {
if (item.isElem('svg') && item.hasAttr('xmlns')) { if (item.type === 'element' && item.name === 'svg') {
item.removeAttr('xmlns'); delete item.attributes.xmlns;
} }
}; };

View File

@ -68,11 +68,11 @@ exports.fn = function (data) {
const defClone = def.clone(); const defClone = def.clone();
def.style = style; def.style = style;
def.class = defClass; def.class = defClass;
defClone.removeAttr('transform'); delete defClone.attributes.transform;
defsTag.spliceContent(0, 0, defClone); defsTag.spliceContent(0, 0, defClone);
// Convert the original def to a use so the first usage isn't duplicated. // Convert the original def to a use so the first usage isn't duplicated.
def = convertToUse(def, defClone.attr('id').value); def = convertToUse(def, defClone.attr('id').value);
def.removeAttr('id'); delete def.attributes.id;
} }
} }
return data; return data;
@ -81,9 +81,9 @@ exports.fn = function (data) {
/** */ /** */
function convertToUse(item, href) { function convertToUse(item, href) {
item.renameElem('use'); item.renameElem('use');
item.removeAttr('d'); delete item.attributes.d;
item.removeAttr('stroke'); delete item.attributes.stroke;
item.removeAttr('fill'); delete item.attributes.fill;
item.addAttr({ item.addAttr({
name: 'xlink:href', name: 'xlink:href',
value: '#' + href, value: '#' + href,