Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(convertPathData): skip if transform overridden in styles #1830

Merged
merged 1 commit into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions lib/stringifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ const encodeEntity = (char) => {
return entities[char];
};

/**
* @type {Options}
*/
/** @type {Options} */
const defaults = {
doctypeStart: '<!DOCTYPE',
doctypeEnd: '>',
Expand All @@ -58,16 +56,14 @@ const defaults = {
indent: 4,
regEntities: /[&'"<>]/g,
regValEntities: /[&"<>]/g,
encodeEntity: encodeEntity,
encodeEntity,
pretty: false,
useShortTags: true,
eol: 'lf',
finalNewline: false,
};

/**
* @type {Record<string, string>}
*/
/** @type {Record<string, string>} */
const entities = {
'&': '&amp;',
"'": '&apos;',
Expand Down Expand Up @@ -113,7 +109,7 @@ const stringifySvg = (data, userOptions = {}) => {
config.textEnd += eol;
}
let svg = stringifyNode(data, config, state);
if (config.finalNewline && svg.length > 0 && svg[svg.length - 1] !== '\n') {
if (config.finalNewline && svg.length > 0 && !svg.endsWith('\n')) {
svg += eol;
}
return svg;
Expand Down
15 changes: 15 additions & 0 deletions lib/svgo/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,18 @@ const hasScripts = (node) => {
return eventAttrs.some((attr) => node.attributes[attr] != null);
};
exports.hasScripts = hasScripts;

/**
* For example, a string that contains one or more of following would match and
* return true:
*
* * `url(#gradient001)`
* * `url('#gradient001')`
*
* @param {string} body
* @returns {boolean} If the given string includes a URL reference.
*/
const includesUrlReference = (body) => {
return /\burl\((["'])?#(.+?)\1\)/g.test(body);
};
exports.includesUrlReference = includesUrlReference;
37 changes: 23 additions & 14 deletions plugins/applyTransforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ const {
transformArc,
} = require('./_transforms.js');
const { path2js } = require('./_path.js');
const { removeLeadingZero } = require('../lib/svgo/tools.js');
const {
removeLeadingZero,
includesUrlReference,
} = require('../lib/svgo/tools.js');
const { referencesProps, attrsGroupsDefaults } = require('./_collections.js');

/**
Expand All @@ -35,9 +38,6 @@ const applyTransforms = (root, params) => {
return {
element: {
enter: (node) => {
const computedStyle = computeStyle(stylesheet, node);

// used only for paths for now
if (node.attributes.d == null) {
return;
}
Expand All @@ -48,7 +48,7 @@ const applyTransforms = (root, params) => {
}

// if there are no 'stroke' attr and references to other objects such as
// gradiends or clip-path which are also subjects to transform.
// gradients or clip-path which are also subjects to transform.
if (
node.attributes.transform == null ||
node.attributes.transform === '' ||
Expand All @@ -57,32 +57,41 @@ const applyTransforms = (root, params) => {
node.attributes.style != null ||
Object.entries(node.attributes).some(
([name, value]) =>
referencesProps.includes(name) && value.includes('url(')
referencesProps.includes(name) && includesUrlReference(value)
)
) {
return;
}

const computedStyle = computeStyle(stylesheet, node);
const transformStyle = computedStyle.transform;

// Transform overridden in <style> tag which is not considered
if (
transformStyle.type === 'static' &&
transformStyle.value !== node.attributes.transform
) {
return;
}

const matrix = transformsMultiply(
transform2js(node.attributes.transform)
);

const stroke =
computedStyle.stroke != null && computedStyle.stroke.type === 'static'
computedStyle.stroke?.type === 'static'
? computedStyle.stroke.value
: null;

const strokeWidth =
computedStyle['stroke-width'] != null &&
computedStyle['stroke-width'].type === 'static'
computedStyle['stroke-width']?.type === 'static'
? computedStyle['stroke-width'].value
: null;
const transformPrecision = params.transformPrecision;

if (
(computedStyle.stroke != null &&
computedStyle.stroke.type === 'dynamic') ||
(computedStyle.strokeWidth != null &&
computedStyle['stroke-width'].type === 'dynamic')
computedStyle.stroke?.type === 'dynamic' ||
computedStyle['stroke-width']?.type === 'dynamic'
) {
return;
}
Expand All @@ -94,7 +103,7 @@ const applyTransforms = (root, params) => {
);

if (stroke && stroke != 'none') {
if (params.applyTransformsStroked === false) {
if (!params.applyTransformsStroked) {
return;
}

Expand Down
3 changes: 2 additions & 1 deletion plugins/moveGroupAttrsToElems.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { pathElems, referencesProps } = require('./_collections.js');
const { includesUrlReference } = require('../lib/svgo/tools.js');

exports.name = 'moveGroupAttrsToElems';
exports.description = 'moves some group attributes to the content elements';
Expand Down Expand Up @@ -36,7 +37,7 @@ exports.fn = () => {
node.attributes.transform != null &&
Object.entries(node.attributes).some(
([name, value]) =>
referencesProps.includes(name) && value.includes('url(')
referencesProps.includes(name) && includesUrlReference(value)
) === false &&
node.children.every(
(child) =>
Expand Down
Loading