mirror of
https://github.com/svg/svgo.git
synced 2025-07-29 20:21:14 +03:00
Refactor basic plugins with visitor api (#1518)
- cleanupAttrs - convertEllipseToCircle - removeDesc - removeDoctype - removeEmptyText - removeMetadata - removeRasterImages - removeScriptElement - removeStyleElement - removeTitle - removeXMLProcInst
This commit is contained in:
@ -1,52 +1,48 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
exports.type = 'visitor';
|
||||||
|
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.description =
|
exports.description =
|
||||||
'cleanups attributes from newlines, trailing and repeating spaces';
|
'cleanups attributes from newlines, trailing and repeating spaces';
|
||||||
|
|
||||||
exports.params = {
|
const regNewlinesNeedSpace = /(\S)\r?\n(\S)/g;
|
||||||
newlines: true,
|
const regNewlines = /\r?\n/g;
|
||||||
trim: true,
|
const regSpaces = /\s{2,}/g;
|
||||||
spaces: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
var regNewlinesNeedSpace = /(\S)\r?\n(\S)/g,
|
|
||||||
regNewlines = /\r?\n/g,
|
|
||||||
regSpaces = /\s{2,}/g;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanup attributes values from newlines, trailing and repeating spaces.
|
* 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
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item, params) {
|
exports.fn = (root, params) => {
|
||||||
if (item.type === 'element') {
|
const { newlines = true, trim = true, spaces = true } = params;
|
||||||
for (const name of Object.keys(item.attributes)) {
|
return {
|
||||||
if (params.newlines) {
|
element: {
|
||||||
// new line which requires a space instead of themselve
|
enter: (node) => {
|
||||||
item.attributes[name] = item.attributes[name].replace(
|
for (const name of Object.keys(node.attributes)) {
|
||||||
regNewlinesNeedSpace,
|
if (newlines) {
|
||||||
(match, p1, p2) => p1 + ' ' + p2
|
// new line which requires a space instead of themselve
|
||||||
);
|
node.attributes[name] = node.attributes[name].replace(
|
||||||
|
regNewlinesNeedSpace,
|
||||||
// simple new line
|
(match, p1, p2) => p1 + ' ' + p2
|
||||||
item.attributes[name] = item.attributes[name].replace(regNewlines, '');
|
);
|
||||||
}
|
// simple new line
|
||||||
|
node.attributes[name] = node.attributes[name].replace(
|
||||||
if (params.trim) {
|
regNewlines,
|
||||||
item.attributes[name] = item.attributes[name].trim();
|
''
|
||||||
}
|
);
|
||||||
|
}
|
||||||
if (params.spaces) {
|
if (trim) {
|
||||||
item.attributes[name] = item.attributes[name].replace(regSpaces, ' ');
|
node.attributes[name] = node.attributes[name].trim();
|
||||||
}
|
}
|
||||||
}
|
if (spaces) {
|
||||||
}
|
node.attributes[name] = node.attributes[name].replace(
|
||||||
|
regSpaces,
|
||||||
|
' '
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
exports.type = 'visitor';
|
||||||
|
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
|
exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,26 +9,28 @@ exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
|
|||||||
*
|
*
|
||||||
* @see https://www.w3.org/TR/SVG11/shapes.html
|
* @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
|
* @author Taylor Hunt
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
if (item.isElem('ellipse')) {
|
return {
|
||||||
const rx = item.attributes.rx || 0;
|
element: {
|
||||||
const ry = item.attributes.ry || 0;
|
enter: (node) => {
|
||||||
|
if (node.name === 'ellipse') {
|
||||||
if (
|
const rx = node.attributes.rx || 0;
|
||||||
rx === ry ||
|
const ry = node.attributes.ry || 0;
|
||||||
rx === 'auto' ||
|
if (
|
||||||
ry === 'auto' // SVG2
|
rx === ry ||
|
||||||
) {
|
rx === 'auto' ||
|
||||||
var radius = rx !== 'auto' ? rx : ry;
|
ry === 'auto' // SVG2
|
||||||
item.renameElem('circle');
|
) {
|
||||||
delete item.attributes.rx;
|
node.name = 'circle';
|
||||||
delete item.attributes.ry;
|
const radius = rx === 'auto' ? ry : rx;
|
||||||
item.attributes.r = radius;
|
delete node.attributes.rx;
|
||||||
}
|
delete node.attributes.ry;
|
||||||
}
|
node.attributes.r = radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.params = {
|
|
||||||
removeAny: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.description = 'removes <desc>';
|
exports.description = 'removes <desc>';
|
||||||
|
|
||||||
var standardDescs = /^(Created with|Created using)/;
|
const standardDescs = /^(Created with|Created using)/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes <desc>.
|
* Removes <desc>.
|
||||||
@ -19,19 +15,24 @@ var standardDescs = /^(Created with|Created using)/;
|
|||||||
*
|
*
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/SVG/Element/desc
|
* 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
|
* @author Daniel Wabyick
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item, params) {
|
exports.fn = (root, params) => {
|
||||||
return (
|
const { removeAny = true } = params;
|
||||||
!item.isElem('desc') ||
|
return {
|
||||||
!(
|
element: {
|
||||||
params.removeAny ||
|
enter: (node, parentNode) => {
|
||||||
item.children.length === 0 ||
|
if (node.name === 'desc') {
|
||||||
(item.children[0].type === 'text' &&
|
if (
|
||||||
standardDescs.test(item.children[0].value))
|
removeAny ||
|
||||||
)
|
node.children.length === 0 ||
|
||||||
);
|
(node.children[0].type === 'text' &&
|
||||||
|
standardDescs.test(node.children[0].value))
|
||||||
|
) {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.description = 'removes doctype declaration';
|
exports.description = 'removes doctype declaration';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,13 +26,14 @@ exports.description = 'removes doctype declaration';
|
|||||||
* <!-- an internal subset can be embedded here -->
|
* <!-- an internal subset can be embedded here -->
|
||||||
* ]>
|
* ]>
|
||||||
*
|
*
|
||||||
* @param {Object} item current iteration item
|
|
||||||
* @return {Boolean} if false, item will be filtered out
|
|
||||||
*
|
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
if (item.type === 'doctype') {
|
return {
|
||||||
return false;
|
doctype: {
|
||||||
}
|
enter: (node, parentNode) => {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.description = 'removes empty <text> elements';
|
exports.description = 'removes empty <text> elements';
|
||||||
|
|
||||||
exports.params = {
|
|
||||||
text: true,
|
|
||||||
tspan: true,
|
|
||||||
tref: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove empty Text elements.
|
* Remove empty Text elements.
|
||||||
*
|
*
|
||||||
@ -27,31 +21,30 @@ exports.params = {
|
|||||||
* Remove tref with empty xlink:href attribute:
|
* Remove tref with empty xlink:href attribute:
|
||||||
* <tref xlink:href=""/>
|
* <tref xlink:href=""/>
|
||||||
*
|
*
|
||||||
* @param {Object} item current iteration item
|
|
||||||
* @param {Object} params plugin params
|
|
||||||
* @return {Boolean} if false, item will be filtered out
|
|
||||||
*
|
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item, params) {
|
exports.fn = (root, params) => {
|
||||||
if (item.type === 'element') {
|
const { text = true, tspan = true, tref = true } = params;
|
||||||
// Remove empty text element
|
return {
|
||||||
if (params.text && item.name === 'text' && item.children.length === 0) {
|
element: {
|
||||||
return false;
|
enter: (node, parentNode) => {
|
||||||
}
|
// Remove empty text element
|
||||||
|
if (text && node.name === 'text' && node.children.length === 0) {
|
||||||
// Remove empty tspan element
|
detachNodeFromParent(node, parentNode);
|
||||||
if (params.tspan && item.name === 'tspan' && item.children.length === 0) {
|
}
|
||||||
return false;
|
// Remove empty tspan element
|
||||||
}
|
if (tspan && node.name === 'tspan' && node.children.length === 0) {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
// Remove tref with empty xlink:href attribute
|
}
|
||||||
if (
|
// Remove tref with empty xlink:href attribute
|
||||||
params.tref &&
|
if (
|
||||||
item.name === 'tref' &&
|
tref &&
|
||||||
item.attributes['xlink:href'] == null
|
node.name === 'tref' &&
|
||||||
) {
|
node.attributes['xlink:href'] == null
|
||||||
return false;
|
) {
|
||||||
}
|
detachNodeFromParent(node, parentNode);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.description = 'removes <metadata>';
|
exports.description = 'removes <metadata>';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,11 +11,16 @@ exports.description = 'removes <metadata>';
|
|||||||
*
|
*
|
||||||
* https://www.w3.org/TR/SVG11/metadata.html
|
* 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
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
return !item.isElem('metadata');
|
return {
|
||||||
|
element: {
|
||||||
|
enter: (node, parentNode) => {
|
||||||
|
if (node.name === 'metadata') {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = false;
|
exports.active = false;
|
||||||
|
|
||||||
exports.description = 'removes raster images (disabled by default)';
|
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
|
* @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
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
if (
|
return {
|
||||||
item.type === 'element' &&
|
element: {
|
||||||
item.name === 'image' &&
|
enter: (node, parentNode) => {
|
||||||
item.attributes['xlink:href'] != null &&
|
if (
|
||||||
/(\.|image\/)(jpg|png|gif)/.test(item.attributes['xlink:href'])
|
node.name === 'image' &&
|
||||||
) {
|
node.attributes['xlink:href'] != null &&
|
||||||
return false;
|
/(\.|image\/)(jpg|png|gif)/.test(node.attributes['xlink:href'])
|
||||||
}
|
) {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = false;
|
exports.active = false;
|
||||||
|
|
||||||
exports.description = 'removes <script> elements (disabled by default)';
|
exports.description = 'removes <script> elements (disabled by default)';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,11 +11,17 @@ exports.description = 'removes <script> elements (disabled by default)';
|
|||||||
*
|
*
|
||||||
* https://www.w3.org/TR/SVG11/script.html
|
* https://www.w3.org/TR/SVG11/script.html
|
||||||
*
|
*
|
||||||
* @param {Object} item current iteration item
|
|
||||||
* @return {Boolean} if false, item will be filtered out
|
|
||||||
*
|
*
|
||||||
* @author Patrick Klingemann
|
* @author Patrick Klingemann
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
return !item.isElem('script');
|
return {
|
||||||
|
element: {
|
||||||
|
enter: (node, parentNode) => {
|
||||||
|
if (node.name === 'script') {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = false;
|
exports.active = false;
|
||||||
|
|
||||||
exports.description = 'removes <style> element (disabled by default)';
|
exports.description = 'removes <style> element (disabled by default)';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,11 +11,16 @@ exports.description = 'removes <style> element (disabled by default)';
|
|||||||
*
|
*
|
||||||
* https://www.w3.org/TR/SVG11/styling.html#StyleElement
|
* https://www.w3.org/TR/SVG11/styling.html#StyleElement
|
||||||
*
|
*
|
||||||
* @param {Object} item current iteration item
|
|
||||||
* @return {Boolean} if false, item will be filtered out
|
|
||||||
*
|
|
||||||
* @author Betsy Dupuis
|
* @author Betsy Dupuis
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
return !item.isElem('style');
|
return {
|
||||||
|
element: {
|
||||||
|
enter: (node, parentNode) => {
|
||||||
|
if (node.name === 'style') {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.description = 'removes <title>';
|
exports.description = 'removes <title>';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,11 +11,16 @@ exports.description = 'removes <title>';
|
|||||||
*
|
*
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title
|
* https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title
|
||||||
*
|
*
|
||||||
* @param {Object} item current iteration item
|
|
||||||
* @return {Boolean} if false, item will be filtered out
|
|
||||||
*
|
|
||||||
* @author Igor Kalashnikov
|
* @author Igor Kalashnikov
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
return !item.isElem('title');
|
return {
|
||||||
|
element: {
|
||||||
|
enter: (node, parentNode) => {
|
||||||
|
if (node.name === 'title') {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.type = 'perItem';
|
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||||
|
|
||||||
|
exports.type = 'visitor';
|
||||||
exports.active = true;
|
exports.active = true;
|
||||||
|
|
||||||
exports.description = 'removes XML processing instructions';
|
exports.description = 'removes XML processing instructions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,14 +12,16 @@ exports.description = 'removes XML processing instructions';
|
|||||||
* @example
|
* @example
|
||||||
* <?xml version="1.0" encoding="utf-8"?>
|
* <?xml version="1.0" encoding="utf-8"?>
|
||||||
*
|
*
|
||||||
* @param {Object} item current iteration item
|
|
||||||
* @return {Boolean} if false, item will be filtered out
|
|
||||||
*
|
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.fn = function (item) {
|
exports.fn = () => {
|
||||||
if (item.type === 'instruction' && item.name === 'xml') {
|
return {
|
||||||
return false;
|
instruction: {
|
||||||
}
|
enter: (node, parentNode) => {
|
||||||
return true;
|
if (node.name === 'xml') {
|
||||||
|
detachNodeFromParent(node, parentNode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user