1
0
mirror of https://github.com/svg/svgo.git synced 2025-07-29 20:21:14 +03:00

Format all plugins with prettier

This commit is contained in:
Bogdan Chadkin
2021-03-09 19:58:00 +03:00
parent 1be0d0dba1
commit 00ec0f71fe
41 changed files with 2053 additions and 1992 deletions

View File

@ -43,7 +43,7 @@ plugins: [
}
}
]
`
`;
/**
* Add attributes to an outer <svg> element. Example config:
@ -66,7 +66,7 @@ exports.fn = function(data, params) {
svg.addAttr({
name: attribute,
prefix: '',
local: attribute
local: attribute,
});
}
} else if (typeof attribute === 'object') {
@ -76,7 +76,7 @@ exports.fn = function(data, params) {
name: key,
value: attribute[key],
prefix: '',
local: key
local: key,
});
}
});
@ -85,5 +85,4 @@ exports.fn = function(data, params) {
}
return data;
};

View File

@ -33,7 +33,13 @@ plugins:
* @author April Arcus
*/
exports.fn = function (data, params) {
if (!params || !(Array.isArray(params.classNames) && params.classNames.some(String) || params.className)) {
if (
!params ||
!(
(Array.isArray(params.classNames) && params.classNames.some(String)) ||
params.className
)
) {
console.error(ENOCLS);
return data;
}
@ -46,5 +52,4 @@ exports.fn = function(data, params) {
}
return data;
};

View File

@ -4,12 +4,13 @@ exports.type = 'perItem';
exports.active = true;
exports.description = 'cleanups attributes from newlines, trailing and repeating spaces';
exports.description =
'cleanups attributes from newlines, trailing and repeating spaces';
exports.params = {
newlines: true,
trim: true,
spaces: true
spaces: true,
};
var regNewlinesNeedSpace = /(\S)\r?\n(\S)/g,
@ -26,16 +27,16 @@ var regNewlinesNeedSpace = /(\S)\r?\n(\S)/g,
* @author Kir Belevich
*/
exports.fn = function (item, params) {
if (item.isElem()) {
item.eachAttr(function (attr) {
if (params.newlines) {
// new line which requires a space instead of themselve
attr.value = attr.value.replace(regNewlinesNeedSpace, function(match, p1, p2) {
attr.value = attr.value.replace(
regNewlinesNeedSpace,
function (match, p1, p2) {
return p1 + ' ' + p2;
});
}
);
// simple new line
attr.value = attr.value.replace(regNewlines, '');
@ -48,9 +49,6 @@ exports.fn = function(item, params) {
if (params.spaces) {
attr.value = attr.value.replace(regSpaces, ' ');
}
});
}
};

View File

@ -4,7 +4,8 @@ exports.type = 'full';
exports.active = true;
exports.description = 'remove or cleanup enable-background attribute when possible';
exports.description =
'remove or cleanup enable-background attribute when possible';
/**
* Remove or cleanup enable-background attr which coincides with a width/height box.
@ -22,7 +23,6 @@ exports.description = 'remove or cleanup enable-background attribute when possib
* @author Kir Belevich
*/
exports.fn = function (data) {
var regEnableBackground = /^new\s0\s0\s([-+]?\d*\.?\d+([eE][-+]?\d+)?)\s([-+]?\d*\.?\d+([eE][-+]?\d+)?)$/,
hasFilter = false,
elems = ['svg', 'mask', 'pattern'];
@ -34,8 +34,9 @@ exports.fn = function(data) {
item.hasAttr('width') &&
item.hasAttr('height')
) {
var match = item.attr('enable-background').value.match(regEnableBackground);
var match = item
.attr('enable-background')
.value.match(regEnableBackground);
if (match) {
if (
@ -49,7 +50,6 @@ exports.fn = function(data) {
}
}
}
}
}
@ -77,7 +77,9 @@ exports.fn = function(data) {
}
});
return hasFilter ? firstStep : monkeys(firstStep, function(item) {
return hasFilter
? firstStep
: monkeys(firstStep, function (item) {
//we don't need 'enable-background' if we have no filters
item.removeAttr('enable-background');
});

View File

@ -12,7 +12,7 @@ exports.params = {
prefix: '',
preserve: [],
preservePrefixes: [],
force: false
force: false,
};
var referencesProps = new Set(require('./_collections').referencesProps),
@ -21,8 +21,58 @@ var referencesProps = new Set(require('./_collections').referencesProps),
regReferencesBegin = /(\w+)\./,
styleOrScript = ['style', 'script'],
generateIDchars = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
],
maxIDindex = generateIDchars.length - 1;
@ -41,8 +91,20 @@ exports.fn = function(data, params) {
IDs = new Map(),
referencesIDs = new Map(),
hasStyleOrScript = false,
preserveIDs = new Set(Array.isArray(params.preserve) ? params.preserve : params.preserve ? [params.preserve] : []),
preserveIDPrefixes = new Set(Array.isArray(params.preservePrefixes) ? params.preservePrefixes : (params.preservePrefixes ? [params.preservePrefixes] : [])),
preserveIDs = new Set(
Array.isArray(params.preserve)
? params.preserve
: params.preserve
? [params.preserve]
: []
),
preserveIDPrefixes = new Set(
Array.isArray(params.preservePrefixes)
? params.preservePrefixes
: params.preservePrefixes
? [params.preservePrefixes]
: []
),
idValuePrefix = '#',
idValuePostfix = '.';
@ -95,11 +157,16 @@ exports.fn = function(data, params) {
return;
}
// save references
if (referencesProps.has(attr.name) && (match = attr.value.match(regReferencesUrl))) {
if (
referencesProps.has(attr.name) &&
(match = attr.value.match(regReferencesUrl))
) {
key = match[2]; // url() reference
} else if (
attr.local === 'href' && (match = attr.value.match(regReferencesHref)) ||
attr.name === 'begin' && (match = attr.value.match(regReferencesBegin))
(attr.local === 'href' &&
(match = attr.value.match(regReferencesHref))) ||
(attr.name === 'begin' &&
(match = attr.value.match(regReferencesBegin)))
) {
key = match[1]; // href reference
}
@ -124,7 +191,8 @@ exports.fn = function(data, params) {
return data;
}
const idPreserved = id => preserveIDs.has(id) || idMatchesPrefix(preserveIDPrefixes, id);
const idPreserved = (id) =>
preserveIDs.has(id) || idMatchesPrefix(preserveIDPrefixes, id);
for (var ref of referencesIDs) {
var key = ref[0];
@ -133,15 +201,24 @@ exports.fn = function(data, params) {
// replace referenced IDs with the minified ones
if (params.minify && !idPreserved(key)) {
do {
currentIDstring = getIDstring(currentID = generateID(currentID), params);
currentIDstring = getIDstring(
(currentID = generateID(currentID)),
params
);
} while (idPreserved(currentIDstring));
IDs.get(key).attr('id').value = currentIDstring;
for (var attr of ref[1]) {
attr.value = attr.value.includes(idValuePrefix) ?
attr.value.replace(idValuePrefix + key, idValuePrefix + currentIDstring) :
attr.value.replace(key + idValuePostfix, currentIDstring + idValuePostfix);
attr.value = attr.value.includes(idValuePrefix)
? attr.value.replace(
idValuePrefix + key,
idValuePrefix + currentIDstring
)
: attr.value.replace(
key + idValuePostfix,
currentIDstring + idValuePostfix
);
}
}
// don't remove referenced IDs
@ -208,5 +285,5 @@ function generateID(currentID) {
*/
function getIDstring(arr, params) {
var str = params.prefix;
return str + arr.map(i => generateIDchars[i]).join('');
return str + arr.map((i) => generateIDchars[i]).join('');
}

View File

@ -10,18 +10,19 @@ exports.params = {
floatPrecision: 3,
leadingZero: true,
defaultPx: true,
convertToPx: true
convertToPx: true,
};
var regNumericValues = /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/,
regSeparator = /\s+,?\s*|,\s*/,
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero,
absoluteLengths = { // relative to px
absoluteLengths = {
// relative to px
cm: 96 / 2.54,
mm: 96 / 25.4,
in: 96,
pt: 4 / 3,
pc: 16
pc: 16,
};
/**
@ -45,8 +46,6 @@ var regNumericValues = /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|
* @author kiyopikko
*/
exports.fn = function (item, params) {
if (item.hasAttr('points')) {
roundValues(item.attrs.points);
}
@ -79,10 +78,9 @@ exports.fn = function(item, params) {
roundValues(item.attrs.y);
}
function roundValues($prop) {
var num, units,
var num,
units,
match,
matchNew,
lists = $prop.value,
@ -91,23 +89,23 @@ exports.fn = function(item, params) {
roundedList;
listsArr.forEach(function (elem) {
match = elem.match(regNumericValues);
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] || '';
(num = +(+match[1]).toFixed(params.floatPrecision)),
(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 (params.convertToPx && units && units in absoluteLengths) {
var pxNum = +(absoluteLengths[units] * match[1]).toFixed(
params.floatPrecision
);
if (String(pxNum).length < match[0].length)
num = pxNum,
units = 'px';
(num = pxNum), (units = 'px');
}
// and remove leading zero
@ -128,12 +126,9 @@ exports.fn = function(item, params) {
} else if (elem) {
roundedListArr.push(elem);
}
});
roundedList = roundedListArr.join(' ');
$prop.value = roundedList;
}
};

View File

@ -4,23 +4,25 @@ exports.type = 'perItem';
exports.active = true;
exports.description = 'rounds numeric values to the fixed precision, removes default px units';
exports.description =
'rounds numeric values to the fixed precision, removes default px units';
exports.params = {
floatPrecision: 3,
leadingZero: true,
defaultPx: true,
convertToPx: true
convertToPx: true,
};
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
absoluteLengths = {
// relative to px
cm: 96 / 2.54,
mm: 96 / 25.4,
in: 96,
pt: 4 / 3,
pc: 16
pc: 16,
};
/**
@ -34,22 +36,24 @@ var regNumericValues = /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|
* @author Kir Belevich
*/
exports.fn = function (item, params) {
if (item.isElem()) {
var floatPrecision = params.floatPrecision;
if (item.hasAttr('viewBox')) {
var nums = item.attr('viewBox').value.split(/\s,?\s*|,\s*/g);
item.attr('viewBox').value = nums.map(function(value) {
item.attr('viewBox').value = nums
.map(function (value) {
var num = +value;
return isNaN(num) ? value : +num.toFixed(floatPrecision);
}).join(' ');
})
.join(' ');
}
item.eachAttr(function (attr) {
// The `version` attribute is a text string and cannot be rounded
if (attr.name === 'version') { return }
if (attr.name === 'version') {
return;
}
var match = attr.value.match(regNumericValues);
@ -60,8 +64,10 @@ exports.fn = function(item, params) {
units = match[3] || '';
// convert absolute values to pixels
if (params.convertToPx && units && (units in absoluteLengths)) {
var pxNum = +(absoluteLengths[units] * match[1]).toFixed(floatPrecision);
if (params.convertToPx && units && units in absoluteLengths) {
var pxNum = +(absoluteLengths[units] * match[1]).toFixed(
floatPrecision
);
if (String(pxNum).length < match[0].length) {
num = pxNum;
@ -82,7 +88,5 @@ exports.fn = function(item, params) {
attr.value = num + units;
}
});
}
};

View File

@ -11,8 +11,10 @@ var collections = require('./_collections'),
animationElems = collections.elemsGroups.animation;
function hasAnimatedAttr(item) {
return item.isElem(animationElems) && item.hasAttr('attributeName', this) ||
!item.isEmpty() && item.content.some(hasAnimatedAttr, this);
return (
(item.isElem(animationElems) && item.hasAttr('attributeName', this)) ||
(!item.isEmpty() && item.content.some(hasAnimatedAttr, this))
);
}
/*
@ -39,7 +41,6 @@ function hasAnimatedAttr(item) {
* @author Kir Belevich
*/
exports.fn = function (item) {
// non-empty elements
if (item.isElem() && !item.isElem('switch') && !item.isEmpty()) {
item.content.forEach(function (g, i) {
@ -49,11 +50,15 @@ exports.fn = function(item) {
if (g.hasAttr() && g.content.length === 1) {
var inner = g.content[0];
if (inner.isElem() && !inner.hasAttr('id') && !g.hasAttr('filter') &&
!(g.hasAttr('class') && inner.hasAttr('class')) && (
!g.hasAttr('clip-path') && !g.hasAttr('mask') ||
inner.isElem('g') && !g.hasAttr('transform') && !inner.hasAttr('transform')
)
if (
inner.isElem() &&
!inner.hasAttr('id') &&
!g.hasAttr('filter') &&
!(g.hasAttr('class') && inner.hasAttr('class')) &&
((!g.hasAttr('clip-path') && !g.hasAttr('mask')) ||
(inner.isElem('g') &&
!g.hasAttr('transform') &&
!inner.hasAttr('transform')))
) {
g.eachAttr(function (attr) {
if (g.content.some(hasAnimatedAttr, attr.name)) return;
@ -61,7 +66,8 @@ exports.fn = function(item) {
if (!inner.hasAttr(attr.name)) {
inner.addAttr(attr);
} else if (attr.name == 'transform') {
inner.attr(attr.name).value = attr.value + ' ' + inner.attr(attr.name).value;
inner.attr(attr.name).value =
attr.value + ' ' + inner.attr(attr.name).value;
} else if (inner.hasAttr(attr.name, 'inherit')) {
inner.attr(attr.name).value = attr.value;
} else if (
@ -77,7 +83,12 @@ exports.fn = function(item) {
}
// collapse groups without attributes
if (!g.hasAttr() && !g.content.some(function(item) { return item.isElem(animationElems) })) {
if (
!g.hasAttr() &&
!g.content.some(function (item) {
return item.isElem(animationElems);
})
) {
item.spliceContent(i, 1, g.content);
}
}

View File

@ -11,13 +11,15 @@ exports.params = {
names2hex: true,
rgb2hex: true,
shorthex: true,
shortname: true
shortname: true,
};
var collections = require('./_collections'),
rNumber = '([+-]?(?:\\d*\\.\\d+|\\d+\\.?)%?)',
rComma = '\\s*,\\s*',
regRGB = new RegExp('^rgb\\(\\s*' + rNumber + rComma + rNumber + rComma + rNumber + '\\s*\\)$'),
regRGB = new RegExp(
'^rgb\\(\\s*' + rNumber + rComma + rNumber + rComma + rNumber + '\\s*\\)$'
),
regHEX = /^#(([a-fA-F0-9])\2){3}$/,
none = /\bnone\b/i;
@ -48,13 +50,9 @@ var collections = require('./_collections'),
* @author Kir Belevich
*/
exports.fn = function (item, params) {
if (item.elem) {
item.eachAttr(function (attr) {
if (collections.colorsProps.indexOf(attr.name) > -1) {
var val = attr.value,
match;
@ -80,8 +78,7 @@ exports.fn = function(item, params) {
// Convert rgb() to long hex
if (params.rgb2hex && (match = val.match(regRGB))) {
match = match.slice(1, 4).map(function (m) {
if (m.indexOf('%') > -1)
m = Math.round(parseFloat(m) * 2.55);
if (m.indexOf('%') > -1) m = Math.round(parseFloat(m) * 2.55);
return Math.max(0, Math.min(m, 255));
});
@ -103,13 +100,9 @@ exports.fn = function(item, params) {
}
attr.value = val;
}
});
}
};
/**
@ -126,5 +119,10 @@ exports.fn = function(item, params) {
* @author Jed Schmidt
*/
function rgb2hex(rgb) {
return '#' + ('00000' + (rgb[0] << 16 | rgb[1] << 8 | rgb[2]).toString(16)).slice(-6).toUpperCase();
return (
'#' +
('00000' + ((rgb[0] << 16) | (rgb[1] << 8) | rgb[2]).toString(16))
.slice(-6)
.toUpperCase()
);
}

View File

@ -18,11 +18,13 @@ exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
*/
exports.fn = function (item) {
if (item.isElem('ellipse')) {
var rx = item.hasAttr('rx') && item.attr('rx').value || 0;
var ry = item.hasAttr('ry') && item.attr('ry').value || 0;
var rx = (item.hasAttr('rx') && item.attr('rx').value) || 0;
var ry = (item.hasAttr('ry') && item.attr('ry').value) || 0;
if (rx === ry ||
rx === 'auto' || ry === 'auto' // SVG2
if (
rx === ry ||
rx === 'auto' ||
ry === 'auto' // SVG2
) {
var radius = rx !== 'auto' ? rx : ry;
item.renameElem('circle');

View File

@ -7,7 +7,7 @@ exports.active = false;
exports.description = 'converts style to attributes';
exports.params = {
keepImportant: false
keepImportant: false,
};
var stylingProps = require('./_collections').attrsGroups.presentation,
@ -16,25 +16,37 @@ var stylingProps = require('./_collections').attrsGroups.presentation,
rSingleQuotes = "'(?:[^'\\n\\r\\\\]|" + rEscape + ")*?(?:'|$)", // string in single quotes: 'smth'
rQuotes = '"(?:[^"\\n\\r\\\\]|' + rEscape + ')*?(?:"|$)', // string in double quotes: "smth"
rQuotedString = new RegExp('^' + g(rSingleQuotes, rQuotes) + '$'),
// Parentheses, E.g.: url(data:image/png;base64,iVBO...).
// ':' and ';' inside of it should be threated as is. (Just like in strings.)
rParenthesis = '\\(' + g('[^\'"()\\\\]+', rEscape, rSingleQuotes, rQuotes) + '*?' + '\\)',
rParenthesis =
'\\(' + g('[^\'"()\\\\]+', rEscape, rSingleQuotes, rQuotes) + '*?' + '\\)',
// The value. It can have strings and parentheses (see above). Fallbacks to anything in case of unexpected input.
rValue = '\\s*(' + g('[^!\'"();\\\\]+?', rEscape, rSingleQuotes, rQuotes, rParenthesis, '[^;]*?') + '*?' + ')',
rValue =
'\\s*(' +
g(
'[^!\'"();\\\\]+?',
rEscape,
rSingleQuotes,
rQuotes,
rParenthesis,
'[^;]*?'
) +
'*?' +
')',
// End of declaration. Spaces outside of capturing groups help to do natural trimming.
rDeclEnd = '\\s*(?:;\\s*|$)',
// Important rule
rImportant = '(\\s*!important(?![-(\\w]))?',
// Final RegExp to parse CSS declarations.
regDeclarationBlock = new RegExp(rAttr + ':' + rValue + rImportant + rDeclEnd, 'ig'),
regDeclarationBlock = new RegExp(
rAttr + ':' + rValue + rImportant + rDeclEnd,
'ig'
),
// Comments expression. Honors escape sequences and strings.
regStripComments = new RegExp(g(rEscape, rSingleQuotes, rQuotes, '/\\*[^]*?\\*/'), 'ig');
regStripComments = new RegExp(
g(rEscape, rSingleQuotes, rQuotes, '/\\*[^]*?\\*/'),
'ig'
);
/**
* Convert style in attributes. Cleanups comments and illegal declarations (without colon) as a side effect.
@ -55,7 +67,6 @@ var stylingProps = require('./_collections').attrsGroups.presentation,
* @author Kir Belevich
*/
exports.fn = function (item, params) {
if (item.elem && item.hasAttr('style')) {
// ['opacity: 1', 'color: #000']
var styleValue = item.attr('style').value,
@ -64,20 +75,22 @@ exports.fn = function(item, params) {
// Strip CSS comments preserving escape sequences and strings.
styleValue = styleValue.replace(regStripComments, function (match) {
return match[0] == '/' ? '' :
match[0] == '\\' && /[-g-z]/i.test(match[1]) ? match[1] : match;
return match[0] == '/'
? ''
: match[0] == '\\' && /[-g-z]/i.test(match[1])
? match[1]
: match;
});
regDeclarationBlock.lastIndex = 0;
// eslint-disable-next-line no-cond-assign
for (var rule; rule = regDeclarationBlock.exec(styleValue);) {
for (var rule; (rule = regDeclarationBlock.exec(styleValue)); ) {
if (!params.keepImportant || !rule[3]) {
styles.push([rule[1], rule[2]]);
}
}
if (styles.length) {
styles = styles.filter(function (style) {
if (style[0]) {
var prop = style[0].toLowerCase(),
@ -88,12 +101,11 @@ exports.fn = function(item, params) {
}
if (stylingProps.indexOf(prop) > -1) {
attrs[prop] = {
name: prop,
value: val,
local: prop,
prefix: ''
prefix: '',
};
return false;
@ -107,16 +119,15 @@ exports.fn = function(item, params) {
if (styles.length) {
item.attr('style').value = styles
.map(function(declaration) { return declaration.join(':') })
.map(function (declaration) {
return declaration.join(':');
})
.join(';');
} else {
item.removeAttr('style');
}
}
}
};
function g() {

View File

@ -18,7 +18,7 @@ exports.params = {
removeUseless: true,
collapseIntoOne: true,
leadingZero: true,
negativeExtraSpace: false
negativeExtraSpace: false,
};
var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
@ -44,9 +44,7 @@ var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
* @author Kir Belevich
*/
exports.fn = function (item, params) {
if (item.elem) {
// transform
if (item.hasAttr('transform')) {
convertTransform(item, 'transform', params);
@ -61,9 +59,7 @@ exports.fn = function(item, params) {
if (item.hasAttr('patternTransform')) {
convertTransform(item, 'patternTransform', params);
}
}
};
/**
@ -118,27 +114,39 @@ function definePrecision(data, params) {
// Limit transform precision with matrix one. Calculating with larger precision doesn't add any value.
if (matrixData.length) {
params.transformPrecision = Math.min(params.transformPrecision,
Math.max.apply(Math, matrixData.map(floatDigits)) || params.transformPrecision);
params.transformPrecision = Math.min(
params.transformPrecision,
Math.max.apply(Math, matrixData.map(floatDigits)) ||
params.transformPrecision
);
significantDigits = Math.max.apply(Math, matrixData.map(function(n) {
significantDigits = Math.max.apply(
Math,
matrixData.map(function (n) {
return String(n).replace(/\D+/g, '').length; // Number of digits in a number. 123.45 → 5
}));
})
);
}
// No sense in angle precision more then number of significant digits in matrix.
if (!('degPrecision' in params)) {
params.degPrecision = Math.max(0, Math.min(params.floatPrecision, significantDigits - 2));
params.degPrecision = Math.max(
0,
Math.min(params.floatPrecision, significantDigits - 2)
);
}
floatRound = params.floatPrecision >= 1 && params.floatPrecision < 20 ?
smartRound.bind(this, params.floatPrecision) :
round;
degRound = params.degPrecision >= 1 && params.floatPrecision < 20 ?
smartRound.bind(this, params.degPrecision) :
round;
transformRound = params.transformPrecision >= 1 && params.floatPrecision < 20 ?
smartRound.bind(this, params.transformPrecision) :
round;
floatRound =
params.floatPrecision >= 1 && params.floatPrecision < 20
? smartRound.bind(this, params.floatPrecision)
: round;
degRound =
params.degPrecision >= 1 && params.floatPrecision < 20
? smartRound.bind(this, params.degPrecision)
: round;
transformRound =
params.transformPrecision >= 1 && params.floatPrecision < 20
? smartRound.bind(this, params.transformPrecision)
: round;
return params;
}
@ -169,20 +177,17 @@ function floatDigits(n) {
* @return {Array} output array
*/
function convertToShorts(transforms, params) {
for (var i = 0; i < transforms.length; i++) {
var transform = transforms[i];
// convert matrix to the short aliases
if (
params.matrixToTransform &&
transform.name === 'matrix'
) {
if (params.matrixToTransform && transform.name === 'matrix') {
var decomposed = matrixToTransform(transform, params);
if (decomposed != transform &&
js2transform(decomposed, params).length <= js2transform([transform], params).length) {
if (
decomposed != transform &&
js2transform(decomposed, params).length <=
js2transform([transform], params).length
) {
transforms.splice.apply(transforms, [i, 1].concat(decomposed));
}
transform = transforms[i];
@ -230,18 +235,16 @@ function convertToShorts(transforms, params) {
data: [
transforms[i - 1].data[0],
transforms[i - 2].data[0],
transforms[i - 2].data[1]
]
transforms[i - 2].data[1],
],
});
// splice compensation
i -= 2;
}
}
return transforms;
}
/**
@ -251,38 +254,36 @@ function convertToShorts(transforms, params) {
* @return {Array} output array
*/
function removeUseless(transforms) {
return transforms.filter(function (transform) {
// translate(0), rotate(0[, cx, cy]), skewX(0), skewY(0)
if (
['translate', 'rotate', 'skewX', 'skewY'].indexOf(transform.name) > -1 &&
(['translate', 'rotate', 'skewX', 'skewY'].indexOf(transform.name) > -1 &&
(transform.data.length == 1 || transform.name == 'rotate') &&
!transform.data[0] ||
!transform.data[0]) ||
// translate(0, 0)
transform.name == 'translate' &&
(transform.name == 'translate' &&
!transform.data[0] &&
!transform.data[1] ||
!transform.data[1]) ||
// scale(1)
transform.name == 'scale' &&
(transform.name == 'scale' &&
transform.data[0] == 1 &&
(transform.data.length < 2 || transform.data[1] == 1) ||
(transform.data.length < 2 || transform.data[1] == 1)) ||
// matrix(1 0 0 1 0 0)
transform.name == 'matrix' &&
(transform.name == 'matrix' &&
transform.data[0] == 1 &&
transform.data[3] == 1 &&
!(transform.data[1] || transform.data[2] || transform.data[4] || transform.data[5])
!(
transform.data[1] ||
transform.data[2] ||
transform.data[4] ||
transform.data[5]
))
) {
return false;
}
return true;
});
}
/**
@ -293,17 +294,20 @@ function removeUseless(transforms) {
* @return {String} output string
*/
function js2transform(transformJS, params) {
var transformString = '';
// collect output value string
transformJS.forEach(function (transform) {
roundTransform(transform);
transformString += (transformString && ' ') + transform.name + '(' + cleanupOutData(transform.data, params) + ')';
transformString +=
(transformString && ' ') +
transform.name +
'(' +
cleanupOutData(transform.data, params) +
')';
});
return transformString;
}
function roundTransform(transform) {
@ -312,7 +316,9 @@ function roundTransform(transform) {
transform.data = floatRound(transform.data);
break;
case 'rotate':
transform.data = degRound(transform.data.slice(0, 1)).concat(floatRound(transform.data.slice(1)));
transform.data = degRound(transform.data.slice(0, 1)).concat(
floatRound(transform.data.slice(1))
);
break;
case 'skewX':
case 'skewY':
@ -322,7 +328,9 @@ function roundTransform(transform) {
transform.data = transformRound(transform.data);
break;
case 'matrix':
transform.data = transformRound(transform.data.slice(0, 4)).concat(floatRound(transform.data.slice(4)));
transform.data = transformRound(transform.data.slice(0, 4)).concat(
floatRound(transform.data.slice(4))
);
break;
}
return transform;
@ -348,12 +356,18 @@ function round(data) {
* @return {Array} output data array
*/
function smartRound(precision, data) {
for (var i = data.length, tolerance = +Math.pow(.1, precision).toFixed(precision); i--;) {
for (
var i = data.length,
tolerance = +Math.pow(0.1, precision).toFixed(precision);
i--;
) {
if (data[i].toFixed(precision) != data[i]) {
var rounded = +data[i].toFixed(precision - 1);
data[i] = +Math.abs(rounded - data[i]).toFixed(precision + 1) >= tolerance ?
+data[i].toFixed(precision) :
rounded;
data[i] =
+Math.abs(rounded - data[i]).toFixed(precision + 1) >= tolerance
? +data[i].toFixed(precision)
: rounded;
}
}
return data;

View File

@ -4,7 +4,8 @@ exports.type = 'full';
exports.active = true;
exports.description = 'minifies styles and removes unused styles based on usage data';
exports.description =
'minifies styles and removes unused styles based on usage data';
exports.params = {
// ... CSSO options goes here
@ -14,8 +15,8 @@ exports.params = {
force: false, // force to use usage data even if it unsafe (document contains <script> or on* attributes)
ids: true,
classes: true,
tags: true
}
tags: true,
},
};
var csso = require('csso');
@ -39,14 +40,23 @@ exports.fn = function(ast, options) {
if (elem.isElem('style')) {
// <style> element
var styleCss = elem.content[0].text || elem.content[0].cdata || [];
var DATA = styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0 ? 'cdata' : 'text';
var DATA =
styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0
? 'cdata'
: 'text';
elem.content[0][DATA] = csso.minify(styleCss, minifyOptionsForStylesheet).css;
elem.content[0][DATA] = csso.minify(
styleCss,
minifyOptionsForStylesheet
).css;
} else {
// style attribute
var elemStyle = elem.attr('style').value;
elem.attr('style').value = csso.minifyBlock(elemStyle, minifyOptionsForAttribute).css;
elem.attr('style').value = csso.minifyBlock(
elemStyle,
minifyOptionsForAttribute
).css;
}
});
@ -58,7 +68,6 @@ function cloneObject(obj) {
}
function findStyleElems(ast) {
function walk(items, styles) {
for (var i = 0; i < items.content.length; i++) {
var item = items.content[i];
@ -94,7 +103,6 @@ function shouldFilter(options, name) {
}
function collectUsageData(ast, options) {
function walk(items, usageData) {
for (var i = 0; i < items.content.length; i++) {
var item = items.content[i];
@ -116,12 +124,21 @@ function collectUsageData(ast, options) {
}
if (item.hasAttr('class')) {
item.attr('class').value.replace(/^\s+|\s+$/g, '').split(/\s+/).forEach(function(className) {
item
.attr('class')
.value.replace(/^\s+|\s+$/g, '')
.split(/\s+/)
.forEach(function (className) {
usageData.classes[className] = true;
});
}
if (item.attrs && Object.keys(item.attrs).some(function(name) { return /^on/i.test(name); })) {
if (
item.attrs &&
Object.keys(item.attrs).some(function (name) {
return /^on/i.test(name);
})
) {
safe = false;
}
}
@ -136,7 +153,7 @@ function collectUsageData(ast, options) {
var rawData = walk(ast, {
ids: Object.create(null),
classes: Object.create(null),
tags: Object.create(null)
tags: Object.create(null),
});
if (!safe && options.usage && options.usage.force) {

View File

@ -34,9 +34,7 @@ var inheritableAttrs = require('./_collections').inheritableAttrs,
* @author Kir Belevich
*/
exports.fn = function (item) {
if (item.isElem('g') && !item.isEmpty() && item.content.length > 1) {
var intersection = {},
hasTransform = false,
hasClip = item.hasAttr('clip-path') || item.hasAttr('mask'),
@ -60,13 +58,9 @@ exports.fn = function(item) {
});
if (intersected) {
item.content.forEach(function (g) {
for (const [name, attr] of Object.entries(intersection)) {
if (!allPath && !hasClip || name !== 'transform') {
if ((!allPath && !hasClip) || name !== 'transform') {
g.removeAttr(name);
if (name === 'transform') {
@ -82,16 +76,11 @@ exports.fn = function(item) {
} else {
item.addAttr(attr);
}
}
}
});
}
}
};
/**
@ -103,7 +92,6 @@ exports.fn = function(item) {
* @return {Object} intersected attrs object
*/
function intersectInheritableAttrs(a, b) {
var c = {};
for (const [n, attr] of Object.entries(a)) {
@ -123,5 +111,4 @@ function intersectInheritableAttrs(a, b) {
if (!Object.keys(c).length) return false;
return c;
}

View File

@ -30,7 +30,6 @@ var collections = require('./_collections.js'),
* @author Kir Belevich
*/
exports.fn = function (item) {
// move group transform attr to content's pathElems
if (
item.isElem('g') &&
@ -46,18 +45,18 @@ exports.fn = function(item) {
item.content.forEach(function (inner) {
var attr = item.attr('transform');
if (inner.hasAttr('transform')) {
inner.attr('transform').value = attr.value + ' ' + inner.attr('transform').value;
inner.attr('transform').value =
attr.value + ' ' + inner.attr('transform').value;
} else {
inner.addAttr({
'name': attr.name,
'local': attr.local,
'prefix': attr.prefix,
'value': attr.value
name: attr.name,
local: attr.local,
prefix: attr.prefix,
value: attr.value,
});
}
});
item.removeAttr('transform');
}
};

View File

@ -19,14 +19,14 @@ var csstree = require('css-tree'),
addPrefix = null;
const unquote = (string) => {
const first = string.charAt(0)
const first = string.charAt(0);
if (first === "'" || first === '"') {
if (first === string.charAt(string.length - 1)) {
return string.slice(1, -1);
}
}
return string;
}
};
// Escapes a string for being used as ID
var escapeIdentifierName = function (str) {
@ -53,7 +53,7 @@ var matchUrl = function(val) {
// Checks if attribute is empty
var attrNotEmpty = function (attr) {
return (attr && attr.value && attr.value.length > 0);
return attr && attr.value && attr.value.length > 0;
};
// prefixes an #ID
@ -65,7 +65,6 @@ var prefixId = function(val) {
return '#' + addPrefix(idName);
};
// attr.value helper methods
// prefixes a class attribute value
@ -168,7 +167,6 @@ const getBasename = (path) => {
* @author strarsis <strarsis@gmail.com>
*/
exports.fn = function (node, opts, extra) {
// skip subsequent passes when multipass is used
if (extra.multipassCount && extra.multipassCount > 0) {
return node;
@ -189,7 +187,6 @@ exports.fn = function(node, opts, extra) {
prefix = filename;
}
// prefixes a normal value
addPrefix = function (name) {
if (prefix === false) {
@ -198,7 +195,6 @@ exports.fn = function(node, opts, extra) {
return escapeIdentifierName(prefix + opts.delim + name);
};
// <style/> property values
if (node.elem === 'style') {
@ -213,34 +209,40 @@ exports.fn = function(node, opts, extra) {
try {
cssAst = csstree.parse(cssStr, {
parseValue: true,
parseCustomProperty: false
parseCustomProperty: false,
});
} catch (parseError) {
console.warn('Warning: Parse error of styles of <style/> element, skipped. Error details: ' + parseError);
console.warn(
'Warning: Parse error of styles of <style/> element, skipped. Error details: ' +
parseError
);
return node;
}
var idPrefixed = '';
csstree.walk(cssAst, function (node) {
// #ID, .class
if (((opts.prefixIds && node.type === 'IdSelector') ||
if (
((opts.prefixIds && node.type === 'IdSelector') ||
(opts.prefixClassNames && node.type === 'ClassSelector')) &&
node.name) {
node.name
) {
node.name = addPrefix(node.name);
return;
}
// url(...) in value
if (node.type === 'Url' &&
node.value.value && node.value.value.length > 0) {
if (
node.type === 'Url' &&
node.value.value &&
node.value.value.length > 0
) {
idPrefixed = prefixId(unquote(node.value.value));
if (!idPrefixed) {
return;
}
node.value.value = idPrefixed;
}
});
// update <style>s
@ -248,14 +250,12 @@ exports.fn = function(node, opts, extra) {
return node;
}
// element attributes
if (!node.attrs) {
return node;
}
// Nodes
if (opts.prefixIds) {
@ -268,7 +268,6 @@ exports.fn = function(node, opts, extra) {
addPrefixToClassAttr(node.attrs.class);
}
// References
// href

View File

@ -4,8 +4,8 @@ exports.type = 'perItem';
exports.active = false;
exports.description = 'removes attributes of elements that match a css selector';
exports.description =
'removes attributes of elements that match a css selector';
/**
* Removes attributes of elements that match a css selector.
@ -58,7 +58,6 @@ exports.description = 'removes attributes of elements that match a css selector'
* @author Bradley Mease
*/
exports.fn = function (item, params) {
var selectors = Array.isArray(params.selectors) ? params.selectors : [params];
selectors.map(function (i) {
@ -66,5 +65,4 @@ exports.fn = function(item, params) {
item.removeAttr(i.attributes);
}
});
};

View File

@ -11,7 +11,7 @@ exports.description = 'removes specified attributes';
exports.params = {
elemSeparator: DEFAULT_SEPARATOR,
preserveCurrentColor: false,
attrs: []
attrs: [],
};
/**
@ -88,12 +88,17 @@ exports.fn = function(item, params) {
}
if (item.isElem()) {
var elemSeparator = typeof params.elemSeparator == 'string' ? params.elemSeparator : DEFAULT_SEPARATOR;
var preserveCurrentColor = typeof params.preserveCurrentColor == 'boolean' ? params.preserveCurrentColor : false;
var elemSeparator =
typeof params.elemSeparator == 'string'
? params.elemSeparator
: DEFAULT_SEPARATOR;
var preserveCurrentColor =
typeof params.preserveCurrentColor == 'boolean'
? params.preserveCurrentColor
: false;
// prepare patterns
var patterns = params.attrs.map(function (pattern) {
// if no element separators (:), assume it's attribute name, and apply to all elements *regardless of value*
if (pattern.indexOf(elemSeparator) === -1) {
pattern = ['.*', elemSeparator, pattern, elemSeparator, '.*'].join('');
@ -104,47 +109,40 @@ exports.fn = function(item, params) {
}
// create regexps for element, attribute name, and attribute value
return pattern.split(elemSeparator)
.map(function(value) {
return pattern.split(elemSeparator).map(function (value) {
// adjust single * to match anything
if (value === '*') { value = '.*'; }
if (value === '*') {
value = '.*';
}
return new RegExp(['^', value, '$'].join(''), 'i');
});
});
// loop patterns
patterns.forEach(function (pattern) {
// matches element
if (pattern[0].test(item.elem)) {
// loop attributes
item.eachAttr(function (attr) {
var name = attr.name;
var value = attr.value;
var isFillCurrentColor = preserveCurrentColor && name == 'fill' && value == 'currentColor';
var isStrokeCurrentColor = preserveCurrentColor && name == 'stroke' && value == 'currentColor';
var isFillCurrentColor =
preserveCurrentColor && name == 'fill' && value == 'currentColor';
var isStrokeCurrentColor =
preserveCurrentColor && name == 'stroke' && value == 'currentColor';
if (!(isFillCurrentColor || isStrokeCurrentColor)) {
// matches attribute name
if (pattern[1].test(name)) {
// matches attribute value
if (pattern[2].test(attr.value)) {
item.removeAttr(name);
}
}
}
});
}
});
}
};

View File

@ -19,9 +19,7 @@ exports.description = 'removes comments';
* @author Kir Belevich
*/
exports.fn = function (item) {
if (item.comment && item.comment.charAt(0) !== '!') {
return false;
}
};

View File

@ -5,7 +5,7 @@ exports.type = 'perItem';
exports.active = true;
exports.params = {
removeAny: true
removeAny: true,
};
exports.description = 'removes <desc>';
@ -25,8 +25,12 @@ var standardDescs = /^(Created with|Created using)/;
* @author Daniel Wabyick
*/
exports.fn = function (item, params) {
return !item.isElem('desc') || !(params.removeAny || item.isEmpty() ||
standardDescs.test(item.content[0].text));
return (
!item.isElem('desc') ||
!(
params.removeAny ||
item.isEmpty() ||
standardDescs.test(item.content[0].text)
)
);
};

View File

@ -4,7 +4,8 @@ exports.type = 'perItem';
exports.active = false;
exports.description = 'removes width and height in presence of viewBox (opposite to removeViewBox, disable it first)';
exports.description =
'removes width and height in presence of viewBox (opposite to removeViewBox, disable it first)';
/**
* Remove width/height attributes and add the viewBox attribute if it's missing
@ -20,7 +21,6 @@ exports.description = 'removes width and height in presence of viewBox (opposite
* @author Benny Schudel
*/
exports.fn = function (item) {
if (item.isElem('svg')) {
if (item.hasAttr('viewBox')) {
item.removeAttr('width');
@ -39,11 +39,10 @@ exports.fn = function(item) {
' ' +
Number(item.attr('height').value),
prefix: '',
local: 'viewBox'
local: 'viewBox',
});
item.removeAttr('width');
item.removeAttr('height');
}
}
};

View File

@ -32,9 +32,7 @@ exports.description = 'removes doctype declaration';
* @author Kir Belevich
*/
exports.fn = function (item) {
if (item.doctype) {
return false;
}
};

View File

@ -10,7 +10,7 @@ var editorNamespaces = require('./_collections').editorNamespaces,
prefixes = [];
exports.params = {
additionalNamespaces: []
additionalNamespaces: [],
};
/**
@ -28,24 +28,23 @@ exports.params = {
* @author Kir Belevich
*/
exports.fn = function (item, params) {
if (Array.isArray(params.additionalNamespaces)) {
editorNamespaces = editorNamespaces.concat(params.additionalNamespaces);
}
if (item.elem) {
if (item.isElem('svg')) {
item.eachAttr(function (attr) {
if (attr.prefix === 'xmlns' && editorNamespaces.indexOf(attr.value) > -1) {
if (
attr.prefix === 'xmlns' &&
editorNamespaces.indexOf(attr.value) > -1
) {
prefixes.push(attr.local);
// <svg xmlns:sodipodi="">
item.removeAttr(attr.name);
}
});
}
// <* sodipodi:*="">
@ -59,7 +58,5 @@ exports.fn = function(item, params) {
if (prefixes.indexOf(item.prefix) > -1) {
return false;
}
}
};

View File

@ -4,11 +4,12 @@ exports.type = 'perItem';
exports.active = false;
exports.description = 'removes arbitrary elements by ID or className (disabled by default)';
exports.description =
'removes arbitrary elements by ID or className (disabled by default)';
exports.params = {
id: [],
class: []
class: [],
};
/**
@ -73,6 +74,6 @@ exports.fn = function(item, params) {
const elemClass = item.attr('class');
if (elemClass && params.class.length !== 0) {
const classList = elemClass.value.split(' ');
return params.class.some(item => classList.includes(item)) === false;
return params.class.some((item) => classList.includes(item)) === false;
}
};

View File

@ -9,7 +9,7 @@ exports.description = 'removes empty <text> elements';
exports.params = {
text: true,
tspan: true,
tref: true
tref: true,
};
/**
@ -34,26 +34,13 @@ exports.params = {
* @author Kir Belevich
*/
exports.fn = function (item, params) {
// Remove empty text element
if (
params.text &&
item.isElem('text') &&
item.isEmpty()
) return false;
if (params.text && item.isElem('text') && item.isEmpty()) return false;
// Remove empty tspan element
if (
params.tspan &&
item.isElem('tspan') &&
item.isEmpty()
) return false;
if (params.tspan && item.isElem('tspan') && item.isEmpty()) return false;
// Remove tref with empty xlink:href attribute
if (
params.tref &&
item.isElem('tref') &&
!item.hasAttrLocal('href')
) return false;
if (params.tref && item.isElem('tref') && !item.hasAttrLocal('href'))
return false;
};

View File

@ -17,7 +17,5 @@ exports.description = 'removes <metadata>';
* @author Kir Belevich
*/
exports.fn = function (item) {
return !item.isElem('metadata');
};

View File

@ -4,7 +4,8 @@ exports.type = 'perItem';
exports.active = true;
exports.description = 'removes non-inheritable groups presentational attributes';
exports.description =
'removes non-inheritable groups presentational attributes';
var inheritableAttrs = require('./_collections').inheritableAttrs,
attrsGroups = require('./_collections').attrsGroups,
@ -19,9 +20,7 @@ var inheritableAttrs = require('./_collections').inheritableAttrs,
* @author Kir Belevich
*/
exports.fn = function (item) {
if (item.isElem('g')) {
item.eachAttr(function (attr) {
if (
~attrsGroups.presentation.indexOf(attr.name) &&
@ -31,7 +30,5 @@ exports.fn = function(item) {
item.removeAttr(attr.name);
}
});
}
};

View File

@ -4,7 +4,8 @@ exports.type = 'perItem';
exports.active = false;
exports.description = 'removes elements that are drawn outside of the viewbox (disabled by default)';
exports.description =
'removes elements that are drawn outside of the viewbox (disabled by default)';
const JSAPI = require('../lib/svgo/jsAPI.js');
@ -23,19 +24,19 @@ var _path = require('./_path.js'),
* @author JoshyPHP
*/
exports.fn = function (item) {
if (item.isElem('path') && item.hasAttr('d') && typeof viewBox !== 'undefined')
{
if (
item.isElem('path') &&
item.hasAttr('d') &&
typeof viewBox !== 'undefined'
) {
// Consider that any item with a transform attribute or a M instruction
// within the viewBox is visible
if (hasTransform(item) || pathMovesWithinViewBox(item.attr('d').value))
{
if (hasTransform(item) || pathMovesWithinViewBox(item.attr('d').value)) {
return true;
}
var pathJS = path2js(item);
if (pathJS.length === 2)
{
if (pathJS.length === 2) {
// Use a closed clone of the path if it's too short for intersects()
pathJS = JSON.parse(JSON.stringify(pathJS));
pathJS.push({ instruction: 'z' });
@ -43,8 +44,7 @@ exports.fn = function(item) {
return intersects(viewBoxJS, pathJS);
}
if (item.isElem('svg'))
{
if (item.isElem('svg')) {
parseViewBox(item);
}
@ -57,9 +57,11 @@ exports.fn = function(item) {
* @param {String} path
* @return {Boolean}
*/
function hasTransform(item)
{
return item.hasAttr('transform') || (item.parentNode && hasTransform(item.parentNode));
function hasTransform(item) {
return (
item.hasAttr('transform') ||
(item.parentNode && hasTransform(item.parentNode))
);
}
/**
@ -67,26 +69,27 @@ function hasTransform(item)
*
* @param {Object} svg svg element item
*/
function parseViewBox(svg)
{
function parseViewBox(svg) {
var viewBoxData = '';
if (svg.hasAttr('viewBox'))
{
if (svg.hasAttr('viewBox')) {
// Remove commas and plus signs, normalize and trim whitespace
viewBoxData = svg.attr('viewBox').value;
}
else if (svg.hasAttr('height') && svg.hasAttr('width'))
{
viewBoxData = '0 0 ' + svg.attr('width').value + ' ' + svg.attr('height').value;
} else if (svg.hasAttr('height') && svg.hasAttr('width')) {
viewBoxData =
'0 0 ' + svg.attr('width').value + ' ' + svg.attr('height').value;
}
// Remove commas and plus signs, normalize and trim whitespace
viewBoxData = viewBoxData.replace(/[,+]|px/g, ' ').replace(/\s+/g, ' ').replace(/^\s*|\s*$/g, '');
viewBoxData = viewBoxData
.replace(/[,+]|px/g, ' ')
.replace(/\s+/g, ' ')
.replace(/^\s*|\s*$/g, '');
// Ensure that the dimensions are 4 values separated by space
var m = /^(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+)$/.exec(viewBoxData);
if (!m)
{
var m = /^(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+)$/.exec(
viewBoxData
);
if (!m) {
return;
}
@ -95,19 +98,19 @@ function parseViewBox(svg)
left: parseFloat(m[1]),
top: parseFloat(m[2]),
right: parseFloat(m[1]) + parseFloat(m[3]),
bottom: parseFloat(m[2]) + parseFloat(m[4])
bottom: parseFloat(m[2]) + parseFloat(m[4]),
};
var path = new JSAPI({
elem: 'path',
prefix: '',
local: 'path'
local: 'path',
});
path.addAttr({
name: 'd',
prefix: '',
local: 'd',
value: 'M' + m[1] + ' ' + m[2] + 'h' + m[3] + 'v' + m[4] + 'H' + m[1] + 'z'
value: 'M' + m[1] + ' ' + m[2] + 'h' + m[3] + 'v' + m[4] + 'H' + m[1] + 'z',
});
viewBoxJS = path2js(path);
@ -119,13 +122,16 @@ function parseViewBox(svg)
* @param {String} path
* @return {Boolean}
*/
function pathMovesWithinViewBox(path)
{
var regexp = /M\s*(-?\d*\.?\d+)(?!\d)\s*(-?\d*\.?\d+)/g, m;
while (null !== (m = regexp.exec(path)))
{
if (m[1] >= viewBox.left && m[1] <= viewBox.right && m[2] >= viewBox.top && m[2] <= viewBox.bottom)
{
function pathMovesWithinViewBox(path) {
var regexp = /M\s*(-?\d*\.?\d+)(?!\d)\s*(-?\d*\.?\d+)/g,
m;
while (null !== (m = regexp.exec(path))) {
if (
m[1] >= viewBox.left &&
m[1] <= viewBox.right &&
m[2] >= viewBox.top &&
m[2] <= viewBox.bottom
) {
return true;
}
}

View File

@ -17,12 +17,10 @@ exports.description = 'removes raster images (disabled by default)';
* @author Kir Belevich
*/
exports.fn = function (item) {
if (
item.isElem('image') &&
item.hasAttrLocal('href', /(\.|image\/)(jpg|png|gif)/)
) {
return false;
}
};

View File

@ -17,7 +17,5 @@ exports.description = 'removes <script> elements (disabled by default)';
* @author Patrick Klingemann
*/
exports.fn = function (item) {
return !item.isElem('script');
};

View File

@ -17,7 +17,5 @@ exports.description = 'removes <style> element (disabled by default)';
* @author Betsy Dupuis
*/
exports.fn = function (item) {
return !item.isElem('style');
};

View File

@ -17,7 +17,5 @@ exports.description = 'removes <title>';
* @author Igor Kalashnikov
*/
exports.fn = function (item) {
return !item.isElem('title');
};

View File

@ -4,7 +4,8 @@ exports.type = 'perItem';
exports.active = true;
exports.description = 'removes unknown elements content and attributes, removes attrs with default values';
exports.description =
'removes unknown elements content and attributes, removes attrs with default values';
exports.params = {
unknownContent: true,
@ -13,7 +14,7 @@ exports.params = {
uselessOverrides: true,
keepDataAttrs: true,
keepAriaAttrs: true,
keepRoleAttr: false
keepRoleAttr: false,
};
var collections = require('./_collections'),
@ -42,7 +43,6 @@ for (const elem of Object.values(elems)) {
}
}
});
}
if (elem.contentGroups) {
@ -65,10 +65,8 @@ for (const elem of Object.values(elems)) {
* @author Kir Belevich
*/
exports.fn = function (item, params) {
// elems w/o namespace prefix
if (item.isElem() && !item.prefix) {
var elem = item.elem;
// remove unknown element's content
@ -82,16 +80,10 @@ exports.fn = function(item, params) {
if (
content.isElem() &&
!content.prefix &&
(
(
elems[elem].content && // Do we have a record of its permitted content?
elems[elem].content.indexOf(content.elem) === -1
) ||
(
!elems[elem].content && // we dont know about its permitted content
!elems[content.elem] // check that we know about the element at all
)
)
((elems[elem].content && // Do we have a record of its permitted content?
elems[elem].content.indexOf(content.elem) === -1) ||
(!elems[elem].content && // we dont know about its permitted content
!elems[content.elem])) // check that we know about the element at all
) {
item.content.splice(i, 1);
}
@ -100,9 +92,7 @@ exports.fn = function(item, params) {
// remove element's unknown attrs and attrs with default values
if (elems[elem] && elems[elem].attrs) {
item.eachAttr(function (attr) {
if (
attr.name !== 'xmlns' &&
(attr.prefix === 'xml' || !attr.prefix) &&
@ -112,37 +102,26 @@ exports.fn = function(item, params) {
) {
if (
// unknown attrs
(
params.unknownAttrs &&
elems[elem].attrs.indexOf(attr.name) === -1
) ||
(params.unknownAttrs &&
elems[elem].attrs.indexOf(attr.name) === -1) ||
// attrs with default values
(
params.defaultAttrs &&
(params.defaultAttrs &&
!item.hasAttr('id') &&
elems[elem].defaults &&
elems[elem].defaults[attr.name] === attr.value && (
attrsInheritable.indexOf(attr.name) < 0 ||
!item.parentNode.computedAttr(attr.name)
)
) ||
elems[elem].defaults[attr.name] === attr.value &&
(attrsInheritable.indexOf(attr.name) < 0 ||
!item.parentNode.computedAttr(attr.name))) ||
// useless overrides
(
params.uselessOverrides &&
(params.uselessOverrides &&
!item.hasAttr('id') &&
applyGroups.indexOf(attr.name) < 0 &&
attrsInheritable.indexOf(attr.name) > -1 &&
item.parentNode.computedAttr(attr.name, attr.value)
)
item.parentNode.computedAttr(attr.name, attr.value))
) {
item.removeAttr(attr.name);
}
}
});
}
}
};

View File

@ -15,7 +15,6 @@ exports.description = 'removes unused namespaces declaration';
* @author Kir Belevich
*/
exports.fn = function (data) {
var svgElem,
xmlnsCollection = [];
@ -25,14 +24,12 @@ exports.fn = function(data) {
* @param {String} ns namescape name
*/
function removeNSfromCollection(ns) {
var pos = xmlnsCollection.indexOf(ns);
// if found - remove ns from the namespaces collection
if (pos > -1) {
xmlnsCollection.splice(pos, 1);
}
}
/**
@ -43,16 +40,13 @@ exports.fn = function(data) {
* @return {Array} output items
*/
function monkeys(items) {
var i = 0,
length = items.content.length;
while (i < length) {
var item = items.content[i];
if (item.isElem('svg')) {
item.eachAttr(function (attr) {
// collect namespaces
if (attr.prefix === 'xmlns' && attr.local) {
@ -65,11 +59,9 @@ exports.fn = function(data) {
// save svg element
svgElem = item;
}
}
if (xmlnsCollection.length) {
// check item for the ns-attrs
if (item.prefix) {
removeNSfromCollection(item.prefix);
@ -79,7 +71,6 @@ exports.fn = function(data) {
item.eachAttr(function (attr) {
removeNSfromCollection(attr.prefix);
});
}
// if nothing is found - go deeper
@ -88,11 +79,9 @@ exports.fn = function(data) {
}
i++;
}
return items;
}
data = monkeys(data);
@ -105,5 +94,4 @@ exports.fn = function(data) {
}
return data;
};

View File

@ -17,35 +17,24 @@ var nonRendering = require('./_collections').elemsGroups.nonRendering;
* @author Lev Solntsev
*/
exports.fn = function (item) {
if (item.isElem('defs')) {
if (item.content) {
item.content = getUsefulItems(item, []);
}
if (item.isEmpty()) return false;
} else if (item.isElem(nonRendering) && !item.hasAttr('id')) {
return false;
}
};
function getUsefulItems(item, usefulItems) {
item.content.forEach(function (child) {
if (child.hasAttr('id') || child.isElem('style')) {
usefulItems.push(child);
child.parentNode = item;
} else if (!child.isEmpty()) {
child.content = getUsefulItems(child, usefulItems);
}
});

View File

@ -10,7 +10,7 @@ exports.params = {
stroke: true,
fill: true,
removeNone: false,
hasStyleOrScript: false
hasStyleOrScript: false,
};
var shape = require('./_collections').elemsGroups.shape,
@ -28,25 +28,25 @@ var shape = require('./_collections').elemsGroups.shape,
* @author Kir Belevich
*/
exports.fn = function (item, params) {
if (item.isElem(styleOrScript)) {
params.hasStyleOrScript = true;
}
if (!params.hasStyleOrScript && item.isElem(shape) && !item.computedAttr('id')) {
if (
!params.hasStyleOrScript &&
item.isElem(shape) &&
!item.computedAttr('id')
) {
var stroke = params.stroke && item.computedAttr('stroke'),
fill = params.fill && !item.computedAttr('fill', 'none');
// remove stroke*
if (
params.stroke &&
(
!stroke ||
(!stroke ||
stroke == 'none' ||
item.computedAttr('stroke-opacity', '0') ||
item.computedAttr('stroke-width', '0')
)
item.computedAttr('stroke-width', '0'))
) {
// stroke-width may affect the size of marker-end
if (
@ -62,20 +62,18 @@ exports.fn = function(item, params) {
}
});
if (declineStroke) item.addAttr({
if (declineStroke)
item.addAttr({
name: 'stroke',
value: 'none',
prefix: '',
local: 'stroke'
local: 'stroke',
});
}
}
// remove fill*
if (
params.fill &&
(!fill || item.computedAttr('fill-opacity', '0'))
) {
if (params.fill && (!fill || item.computedAttr('fill-opacity', '0'))) {
item.eachAttr(function (attr) {
if (regFillProps.test(attr.name)) {
item.removeAttr(attr.name);
@ -83,25 +81,24 @@ exports.fn = function(item, params) {
});
if (fill) {
if (item.hasAttr('fill'))
item.attr('fill').value = 'none';
if (item.hasAttr('fill')) item.attr('fill').value = 'none';
else
item.addAttr({
name: 'fill',
value: 'none',
prefix: '',
local: 'fill'
local: 'fill',
});
}
}
if (params.removeNone &&
(!stroke || item.hasAttr('stroke') && item.attr('stroke').value=='none') &&
(!fill || item.hasAttr('fill') && item.attr('fill').value=='none')) {
if (
params.removeNone &&
(!stroke ||
(item.hasAttr('stroke') && item.attr('stroke').value == 'none')) &&
(!fill || (item.hasAttr('fill') && item.attr('fill').value == 'none'))
) {
return false;
}
}
};

View File

@ -4,7 +4,8 @@ exports.type = 'perItem';
exports.active = false;
exports.description = 'removes xmlns attribute (for inline svg, disabled by default)';
exports.description =
'removes xmlns attribute (for inline svg, disabled by default)';
/**
* Remove the xmlns attribute when present.
@ -20,9 +21,7 @@ exports.description = 'removes xmlns attribute (for inline svg, disabled by defa
* @author Ricardo Tomasi
*/
exports.fn = function (item) {
if (item.isElem('svg') && item.hasAttr('xmlns')) {
item.removeAttr('xmlns');
}
};

View File

@ -18,7 +18,7 @@ exports.description = 'removes XML processing instructions';
* @author Kir Belevich
*/
exports.fn = function (item) {
return !(item.processinginstruction && item.processinginstruction.name === 'xml');
return !(
item.processinginstruction && item.processinginstruction.name === 'xml'
);
};

View File

@ -84,7 +84,8 @@ exports.type = 'full';
exports.active = false;
exports.description = 'Finds <path> elements with the same d, fill, and ' +
exports.description =
'Finds <path> elements with the same d, fill, and ' +
'stroke, and converts them to <use> elements ' +
'referencing a single <path> def.';
@ -98,7 +99,7 @@ exports.fn = function(data) {
const seen = new Map();
let count = 0;
const defs = [];
traverse(data, item => {
traverse(data, (item) => {
if (!item.isElem('path') || !item.hasAttr('d')) {
return;
}
@ -114,16 +115,28 @@ exports.fn = function(data) {
if (!hasSeen.reused) {
hasSeen.reused = true;
if (!hasSeen.elem.hasAttr('id')) {
hasSeen.elem.addAttr({name: 'id', local: 'id',
prefix: '', value: 'reuse-' + (count++)});
hasSeen.elem.addAttr({
name: 'id',
local: 'id',
prefix: '',
value: 'reuse-' + count++,
});
}
defs.push(hasSeen.elem);
}
convertToUse(item, hasSeen.elem.attr('id').value);
});
if (defs.length > 0) {
const defsTag = new JSAPI({
elem: 'defs', prefix: '', local: 'defs', content: [], attrs: []}, data);
const defsTag = new JSAPI(
{
elem: 'defs',
prefix: '',
local: 'defs',
content: [],
attrs: [],
},
data
);
data.content[0].spliceContent(0, 0, defsTag);
for (let def of defs) {
// Remove class and style before copying to avoid circular refs in
@ -152,8 +165,12 @@ function convertToUse(item, href) {
item.removeAttr('d');
item.removeAttr('stroke');
item.removeAttr('fill');
item.addAttr({name: 'xlink:href', local: 'xlink:href',
prefix: 'none', value: '#' + href});
item.addAttr({
name: 'xlink:href',
local: 'xlink:href',
prefix: 'none',
value: '#' + href,
});
delete item.pathJS;
return item;
}

View File

@ -9,13 +9,23 @@ exports.description = 'sorts element attributes (disabled by default)';
exports.params = {
order: [
'id',
'width', 'height',
'x', 'x1', 'x2',
'y', 'y1', 'y2',
'cx', 'cy', 'r',
'fill', 'stroke', 'marker',
'd', 'points'
]
'width',
'height',
'x',
'x1',
'x2',
'y',
'y1',
'y2',
'cx',
'cy',
'r',
'fill',
'stroke',
'marker',
'd',
'points',
],
};
/**
@ -27,14 +37,12 @@ exports.params = {
* @author Nikolay Frantsev
*/
exports.fn = function (item, params) {
var attrs = [],
sorted = {},
orderlen = params.order.length + 1,
xmlnsOrder = params.xmlnsOrder || 'front';
if (item.elem) {
item.eachAttr(function (attr) {
attrs.push(attr);
});
@ -43,10 +51,8 @@ exports.fn = function(item, params) {
if (a.prefix != b.prefix) {
// xmlns attributes implicitly have the prefix xmlns
if (xmlnsOrder == 'front') {
if (a.prefix == 'xmlns')
return -1;
if (b.prefix == 'xmlns')
return 1;
if (a.prefix == 'xmlns') return -1;
if (b.prefix == 'xmlns') return 1;
}
return a.prefix < b.prefix ? -1 : 1;
}
@ -58,12 +64,12 @@ exports.fn = function(item, params) {
if (a.name == params.order[i]) {
aindex = i;
} else if (a.name.indexOf(params.order[i] + '-') === 0) {
aindex = i + .5;
aindex = i + 0.5;
}
if (b.name == params.order[i]) {
bindex = i;
} else if (b.name.indexOf(params.order[i] + '-') === 0) {
bindex = i + .5;
bindex = i + 0.5;
}
}
@ -78,7 +84,5 @@ exports.fn = function(item, params) {
});
item.attrs = sorted;
}
};

View File

@ -16,9 +16,7 @@ exports.description = 'Sorts children of <defs> to improve compression';
* @author David Leston
*/
exports.fn = function (item) {
if (item.isElem('defs')) {
if (item.content) {
var frequency = item.content.reduce(function (frequency, child) {
if (child.elem in frequency) {
@ -37,11 +35,10 @@ exports.fn = function(item) {
if (lengthComparison !== 0) {
return lengthComparison;
}
return a.elem != b.elem ? a.elem > b.elem ? -1 : 1 : 0;
return a.elem != b.elem ? (a.elem > b.elem ? -1 : 1) : 0;
});
}
return true;
}
};