mirror of
https://github.com/svg/svgo.git
synced 2025-07-31 07:44:22 +03:00
Make optimize synchronous (#1322)
Ref https://github.com/svg/svgo/issues/1015 Looks like `sax` is synchronous and we do not need to listen "end" event. This allows to avoid all callbacks and make `optimize` method synchronous.
This commit is contained in:
@ -82,20 +82,18 @@ FS.readFile(filepath, 'utf8', function(err, data) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
svgo.optimize(data, {path: filepath}).then(function(result) {
|
||||
const result = svgo.optimize(data, {path: filepath});
|
||||
|
||||
console.log(result);
|
||||
console.log(result);
|
||||
|
||||
// {
|
||||
// // optimized SVG data string
|
||||
// data: '<svg width="10" height="20">test</svg>'
|
||||
// // additional info such as width/height
|
||||
// info: {
|
||||
// width: '10',
|
||||
// height: '20'
|
||||
// }
|
||||
// }
|
||||
|
||||
});
|
||||
// {
|
||||
// // optimized SVG data string
|
||||
// data: '<svg width="10" height="20">test</svg>'
|
||||
// // additional info such as width/height
|
||||
// info: {
|
||||
// width: '10',
|
||||
// height: '20'
|
||||
// }
|
||||
// }
|
||||
|
||||
});
|
||||
|
75
lib/svgo.js
75
lib/svgo.js
@ -21,56 +21,37 @@ var SVGO = function(config) {
|
||||
this.config = CONFIG(config);
|
||||
};
|
||||
|
||||
SVGO.prototype.optimize = function(svgstr, info) {
|
||||
info = info || {};
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.config.error) {
|
||||
reject(this.config.error);
|
||||
return;
|
||||
SVGO.prototype.optimize = function(svgstr, info = {}) {
|
||||
const config = this.config;
|
||||
if (config.error) {
|
||||
throw Error(config.error);
|
||||
}
|
||||
const maxPassCount = config.multipass ? 10 : 1;
|
||||
let prevResultSize = Number.POSITIVE_INFINITY;
|
||||
let svgjs = null;
|
||||
for (let i = 0; i < maxPassCount; i += 1) {
|
||||
svgjs = SVG2JS(svgstr);
|
||||
if (svgjs.error == null) {
|
||||
svgjs = PLUGINS(svgjs, info, config.plugins);
|
||||
}
|
||||
|
||||
var config = this.config,
|
||||
maxPassCount = config.multipass ? 10 : 1,
|
||||
counter = 0,
|
||||
prevResultSize = Number.POSITIVE_INFINITY,
|
||||
optimizeOnceCallback = (svgjs) => {
|
||||
if (svgjs.error) {
|
||||
reject(svgjs.error);
|
||||
return;
|
||||
}
|
||||
|
||||
info.multipassCount = counter;
|
||||
if (++counter < maxPassCount && svgjs.data.length < prevResultSize) {
|
||||
prevResultSize = svgjs.data.length;
|
||||
this._optimizeOnce(svgjs.data, info, optimizeOnceCallback);
|
||||
} else {
|
||||
if (config.datauri) {
|
||||
svgjs.data = encodeSVGDatauri(svgjs.data, config.datauri);
|
||||
}
|
||||
if (info && info.path) {
|
||||
svgjs.path = info.path;
|
||||
}
|
||||
resolve(svgjs);
|
||||
}
|
||||
};
|
||||
|
||||
this._optimizeOnce(svgstr, info, optimizeOnceCallback);
|
||||
});
|
||||
};
|
||||
|
||||
SVGO.prototype._optimizeOnce = function(svgstr, info, callback) {
|
||||
var config = this.config;
|
||||
|
||||
SVG2JS(svgstr, function(svgjs) {
|
||||
svgjs = JS2SVG(svgjs, config.js2svg);
|
||||
if (svgjs.error) {
|
||||
callback(svgjs);
|
||||
return;
|
||||
throw Error(svgjs.error);
|
||||
}
|
||||
|
||||
svgjs = PLUGINS(svgjs, info, config.plugins);
|
||||
|
||||
callback(JS2SVG(svgjs, config.js2svg));
|
||||
});
|
||||
info.multipassCount = i;
|
||||
if (svgjs.data.length < prevResultSize) {
|
||||
prevResultSize = svgjs.data.length
|
||||
} else {
|
||||
if (config.datauri) {
|
||||
svgjs.data = encodeSVGDatauri(svgjs.data, config.datauri);
|
||||
}
|
||||
if (info && info.path) {
|
||||
svgjs.path = info.path;
|
||||
}
|
||||
return svgjs;
|
||||
}
|
||||
}
|
||||
return svgjs;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -382,24 +382,23 @@ function processSVGData(config, info, data, output, input) {
|
||||
var startTime = Date.now(),
|
||||
prevFileSize = Buffer.byteLength(data, 'utf8');
|
||||
|
||||
return svgo.optimize(data, info).then(function(result) {
|
||||
if (config.datauri) {
|
||||
result.data = encodeSVGDatauri(result.data, config.datauri);
|
||||
}
|
||||
var resultFileSize = Buffer.byteLength(result.data, 'utf8'),
|
||||
processingTime = Date.now() - startTime;
|
||||
const result = svgo.optimize(data, info);
|
||||
if (config.datauri) {
|
||||
result.data = encodeSVGDatauri(result.data, config.datauri);
|
||||
}
|
||||
var resultFileSize = Buffer.byteLength(result.data, 'utf8'),
|
||||
processingTime = Date.now() - startTime;
|
||||
|
||||
return writeOutput(input, output, result.data).then(function() {
|
||||
if (!config.quiet && output != '-') {
|
||||
if (input) {
|
||||
console.log(`\n${PATH.basename(input)}:`);
|
||||
}
|
||||
printTimeInfo(processingTime);
|
||||
printProfitInfo(prevFileSize, resultFileSize);
|
||||
return writeOutput(input, output, result.data).then(function() {
|
||||
if (!config.quiet && output != '-') {
|
||||
if (input) {
|
||||
console.log(`\n${PATH.basename(input)}:`);
|
||||
}
|
||||
},
|
||||
error => Promise.reject(new Error(error.code === 'ENOTDIR' ? `Error: output '${output}' is not a directory.` : error)));
|
||||
});
|
||||
printTimeInfo(processingTime);
|
||||
printProfitInfo(prevFileSize, resultFileSize);
|
||||
}
|
||||
},
|
||||
error => Promise.reject(new Error(error.code === 'ENOTDIR' ? `Error: output '${output}' is not a directory.` : error)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,16 +19,14 @@ var config = {
|
||||
* Convert SVG (XML) string to SVG-as-JS object.
|
||||
*
|
||||
* @param {String} data input data
|
||||
* @param {Function} callback
|
||||
*/
|
||||
module.exports = function(data, callback) {
|
||||
module.exports = function(data) {
|
||||
|
||||
var sax = SAX.parser(config.strict, config),
|
||||
root = new JSAPI({ elem: '#document', content: [] }),
|
||||
current = root,
|
||||
stack = [root],
|
||||
textContext = null,
|
||||
parsingError = false;
|
||||
textContext = null;
|
||||
|
||||
function pushToContent(content) {
|
||||
|
||||
@ -163,23 +161,12 @@ module.exports = function(data, callback) {
|
||||
|
||||
};
|
||||
|
||||
sax.onend = function() {
|
||||
|
||||
if (!this.error) {
|
||||
callback(root);
|
||||
} else {
|
||||
callback({ error: this.error.message });
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
try {
|
||||
sax.write(data);
|
||||
sax.write(data).close();
|
||||
return root;
|
||||
} catch (e) {
|
||||
callback({ error: e.message });
|
||||
parsingError = true;
|
||||
return { error: e.message };
|
||||
}
|
||||
if (!parsingError) sax.close();
|
||||
|
||||
function trim(elem) {
|
||||
if (!elem.content) return elem;
|
||||
|
@ -27,6 +27,11 @@
|
||||
"name": "Lev Solntsev",
|
||||
"email": "lev.sun@ya.ru",
|
||||
"url": "http://github.com/GreLI"
|
||||
},
|
||||
{
|
||||
"name": "Bogdan Chadkin",
|
||||
"email": "trysound@yandex.ru",
|
||||
"url": "http://github.com/TrySound"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
|
@ -44,10 +44,9 @@ describe('plugins tests', function() {
|
||||
js2svg : { pretty: true }
|
||||
});
|
||||
|
||||
return svgo.optimize(orig, {path: file}).then(function(result) {
|
||||
//FIXME: results.data has a '\n' at the end while it should not
|
||||
normalize(result.data).should.be.equal(should);
|
||||
});
|
||||
const result = svgo.optimize(orig, {path: file});
|
||||
//FIXME: results.data has a '\n' at the end while it should not
|
||||
normalize(result.data).should.be.equal(should);
|
||||
});
|
||||
|
||||
});
|
||||
@ -69,4 +68,4 @@ function readFile(file) {
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,8 @@ describe('svg2js', function() {
|
||||
throw err;
|
||||
}
|
||||
|
||||
SVG2JS(data, function(result) {
|
||||
root = result;
|
||||
done();
|
||||
});
|
||||
root = SVG2JS(data)
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
@ -423,9 +421,7 @@ describe('svg2js', function() {
|
||||
}
|
||||
|
||||
try {
|
||||
SVG2JS(data, function(result) {
|
||||
root = result;
|
||||
});
|
||||
root = SVG2JS(data)
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
@ -473,9 +469,7 @@ describe('svg2js', function() {
|
||||
FS.readFile(filepath, 'utf8', function(err, data) {
|
||||
if (err) throw err;
|
||||
|
||||
SVG2JS(data, function(result) {
|
||||
root = result;
|
||||
});
|
||||
root = SVG2JS(data);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -30,10 +30,9 @@ describe('indentation', function() {
|
||||
js2svg : { pretty: true, indent: 2 }
|
||||
});
|
||||
|
||||
svgo.optimize(orig, {path: filepath}).then(function(result) {
|
||||
normalize(result.data).should.be.equal(should);
|
||||
done();
|
||||
});
|
||||
const result = svgo.optimize(orig, {path: filepath});
|
||||
normalize(result.data).should.be.equal(should);
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user