diff --git a/index.js b/index.js index 30984d1..97e8a30 100644 --- a/index.js +++ b/index.js @@ -5,8 +5,7 @@ Copyrights licensed under the New BSD License. See the accompanying LICENSE file var fs = require('fs'), path = require('path'), - SVGO = require('svgo'), - svgo = new SVGO(), + svgo = require('svgo'), dot = require('dot'), template = dot.template(fs.readFileSync(path.join(__dirname, 'templates', 'basic.svg'), 'utf-8')), v2 = require('./v2'), @@ -37,10 +36,19 @@ module.exports = function badge (field1, field2, color, callback) { }; // Run the SVG through SVGO. - return svgo.optimize(template(data)).then(function (object) { - if (callback) callback(null, object.data); - return object.data; + const raw = utils.fixupNumericEntities(template(data)); + const optimized = svgo.optimize(raw, { + plugins: ['preset-default'], }); + if (optimized.modernError) { + if (callback) { + callback(optimized.modernError, undefined); + return; + } + return Promise.reject(optimized.modernError); + } + if (callback) callback(null, optimized.data); + return Promise.resolve(optimized.data); }; /** diff --git a/package.json b/package.json index 08121ad..17aa16b 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,6 @@ "dependencies": { "css-color-names": "~1.0.1", "dot": "^1.1.3", - "svgo": "^1.3.2" + "svgo": "2.6.0" } } diff --git a/utils.js b/utils.js index 1de1f7c..fefe0bb 100644 --- a/utils.js +++ b/utils.js @@ -14,7 +14,18 @@ var LETTER_WIDTH = [ 8,8,8,8,8,7,7,7,6,6,6,6,6,6,9,5,6,6,6,6,3,3,3,3,6,6,6,6,6,6,6,6,7,6,6,6, 6,5,6 ]; - +/** + * Replace numeric entity codes with the related entity code name + * for the "<" and "&" characters. Prevent svgo "Unencoded ..." errors, + * see https://github.com/svg/svgo/issues/1498. + * @method replaceNumericEntities + * @param {String} string Input string + * @return {String} Fixed string + */ +module.exports.fixupNumericEntities = function replaceNumericEntitities(string) { + return string.replace(/&#(x3c|60);/gi, '<') + .replace(/&#(x26|38);/gi, '&'); +} /** * Escape the string so that it doesn't break xml diff --git a/v2.js b/v2.js index 8cc68ce..b1e31df 100644 --- a/v2.js +++ b/v2.js @@ -8,12 +8,7 @@ var colors = require('css-color-names'), fs = require('fs'), path = require('path'), utils = require('./utils'), - SVGO = require('svgo'), - svgo = new SVGO({ - plugins: [{ - sortDefsChildren: false - }] - }), + svgo = require('svgo'), TEMPLATE = dot.template(fs.readFileSync(path.join(__dirname, 'templates', 'v2.svg'), 'utf-8')), COLOR_REGEX = /^[0-9a-f]{6}$/i, STROKE_REGEX = /^s\{(.+?)\}$/i, @@ -101,11 +96,30 @@ function sectionsToData(sections) { module.exports = function badge_v2(sections, callback) { - var raw = TEMPLATE(sectionsToData(sections)); - return svgo.optimize(raw).then(function(optimized) { - if (callback) callback(undefined, optimized.data); - return optimized.data; - }); + var raw = utils.fixupNumericEntities( + TEMPLATE(sectionsToData(sections)) + ); + const optimized = svgo.optimize(raw, { + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + sortDefsChildren: false, + } + } + } + ], + }) + if (optimized.modernError) { + if (callback) { + callback(optimized.modernError, undefined); + return; + } + return Promise.reject(optimized.modernError); + } + if (callback) callback(undefined, optimized.data); + return Promise.resolve(optimized.data); };