From 9de471a0f4bea20581034c2d74b0652c27e0fad0 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Wed, 24 Feb 2021 00:58:11 +0300 Subject: [PATCH] Handle nested textual tags This bug was also catched by regression tests. Single state was overriden in opentag/closetag callbacks. Using stack state solved the problem with nested textual tags. Now many whitespaces bugs should go away. --- lib/svgo/svg2js.js | 36 +++++++++--------------------------- test/svgo/_index.js | 5 +++++ test/svgo/whitespaces.svg | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 27 deletions(-) create mode 100644 test/svgo/whitespaces.svg diff --git a/lib/svgo/svg2js.js b/lib/svgo/svg2js.js index f1ff513c5..bdf9c6d4d 100644 --- a/lib/svgo/svg2js.js +++ b/lib/svgo/svg2js.js @@ -26,8 +26,7 @@ module.exports = function(data) { var sax = SAX.parser(config.strict, config), root = new JSAPI({ elem: '#document', content: [] }), current = root, - stack = [root], - textContext = null; + stack = [root]; function pushToContent(content) { @@ -116,39 +115,22 @@ module.exports = function(data) { elem = pushToContent(elem); current = elem; - // Save info about tags containing text to prevent trimming of meaningful whitespace - if (textElems.includes(data.name) && !data.prefix) { - textContext = current; - } - stack.push(elem); }; sax.ontext = function(text) { - - if (/\S/.test(text) || textContext) { - - if (!textContext) - text = text.trim(); - - pushToContent({ - text: text - }); - - } - + // prevent trimming of meaningful whitespace inside textual tags + if (textElems.includes(current.elem) && !data.prefix) { + pushToContent({ text: text }); + } else if (/\S/.test(text)) { + pushToContent({ text: text.trim() }); + } }; sax.onclosetag = function() { - - var last = stack.pop(); - - if (last == textContext) { - textContext = null; - } - current = stack[stack.length - 1]; - + stack.pop(); + current = stack[stack.length - 1]; }; sax.onerror = function(e) { diff --git a/test/svgo/_index.js b/test/svgo/_index.js index 4d5d9d4ae..f0f8906ad 100644 --- a/test/svgo/_index.js +++ b/test/svgo/_index.js @@ -71,4 +71,9 @@ describe('svgo', () => { const result = optimize(original, { path: 'input.svg', plugins: [], js2svg: { pretty: true } }); expect(normalize(result.data)).to.equal(expected); }); + it('should preserve whitespaces between tspan tags', async () => { + const [original, expected] = await parseFixture('whitespaces.svg'); + const result = optimize(original, { path: 'input.svg', js2svg: { pretty: true } }); + expect(normalize(result.data)).to.equal(expected); + }); }); diff --git a/test/svgo/whitespaces.svg b/test/svgo/whitespaces.svg new file mode 100644 index 000000000..fcc2895a1 --- /dev/null +++ b/test/svgo/whitespaces.svg @@ -0,0 +1,15 @@ + + + Another tspan + Inside tspan - outside tspan + + + +@@@ + + + + Another tspan + Inside tspan - outside tspan + +