126 lines
3.1 KiB
JavaScript
126 lines
3.1 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
exports.__esModule = true;
|
||
|
exports.default = svgoPlugin;
|
||
|
|
||
|
var _svgo = _interopRequireDefault(require("svgo"));
|
||
|
|
||
|
var _cosmiconfig = _interopRequireDefault(require("cosmiconfig"));
|
||
|
|
||
|
var _mergeDeep = _interopRequireDefault(require("merge-deep"));
|
||
|
|
||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
||
|
/* eslint-disable no-underscore-dangle */
|
||
|
const explorer = (0, _cosmiconfig.default)('svgo', {
|
||
|
searchPlaces: ['package.json', '.svgorc', '.svgorc.json', '.svgorc.yaml', '.svgorc.yml', 'svgo.config.js', '.svgo.yml'],
|
||
|
transform: result => result && result.config,
|
||
|
cache: true
|
||
|
});
|
||
|
|
||
|
function encodeSVGDatauri(str, type) {
|
||
|
let prefix = 'data:image/svg+xml'; // base64
|
||
|
|
||
|
if (!type || type === 'base64') {
|
||
|
prefix += ';base64,';
|
||
|
|
||
|
if (Buffer.from) {
|
||
|
str = prefix + Buffer.from(str).toString('base64');
|
||
|
} else {
|
||
|
// eslint-disable-next-line
|
||
|
str = prefix + new Buffer(str).toString('base64');
|
||
|
} // URI encoded
|
||
|
|
||
|
} else if (type === 'enc') {
|
||
|
str = `${prefix},${encodeURIComponent(str)}`; // unencoded
|
||
|
} else if (type === 'unenc') {
|
||
|
str = `${prefix},${str}`;
|
||
|
}
|
||
|
|
||
|
return str;
|
||
|
} // See https://github.com/svg/svgo/blob/master/lib/svgo.js#L24
|
||
|
// _optimizeOnce is synchronous internally
|
||
|
|
||
|
|
||
|
function optimizeSync(svgstr, info) {
|
||
|
const {
|
||
|
config
|
||
|
} = this;
|
||
|
|
||
|
if (config.error) {
|
||
|
throw config.error;
|
||
|
}
|
||
|
|
||
|
const maxPassCount = config.multipass ? 10 : 1;
|
||
|
let counter = 0;
|
||
|
let prevResultSize = Number.POSITIVE_INFINITY;
|
||
|
let result;
|
||
|
|
||
|
const optimizeOnceCallback = svgjs => {
|
||
|
if (svgjs.error) {
|
||
|
throw svgjs.error;
|
||
|
} // eslint-disable-next-line no-plusplus
|
||
|
|
||
|
|
||
|
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.path) {
|
||
|
svgjs.path = info.path;
|
||
|
}
|
||
|
|
||
|
result = svgjs;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
this._optimizeOnce(svgstr, info, optimizeOnceCallback);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
function getBaseSvgoConfig(config) {
|
||
|
const baseSvgoConfig = {
|
||
|
plugins: [{
|
||
|
prefixIds: true
|
||
|
}]
|
||
|
};
|
||
|
if (config.icon || config.dimensions === false) baseSvgoConfig.plugins.push({
|
||
|
removeViewBox: false
|
||
|
});
|
||
|
return baseSvgoConfig;
|
||
|
}
|
||
|
|
||
|
function getFilePath(state) {
|
||
|
return state.filePath || process.cwd();
|
||
|
}
|
||
|
|
||
|
function createSvgo(config, rcConfig) {
|
||
|
const mergedConfig = (0, _mergeDeep.default)(getBaseSvgoConfig(config), rcConfig, config.svgoConfig);
|
||
|
return new _svgo.default(mergedConfig);
|
||
|
}
|
||
|
|
||
|
function getInfo(state) {
|
||
|
return state.filePath ? {
|
||
|
input: 'file',
|
||
|
path: state.filePath
|
||
|
} : {
|
||
|
input: 'string'
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function svgoPlugin(code, config, state) {
|
||
|
if (!config.svgo) return code;
|
||
|
const filePath = getFilePath(state);
|
||
|
const svgoRcConfig = config.runtimeConfig ? explorer.searchSync(filePath) : {};
|
||
|
const svgo = createSvgo(config, svgoRcConfig);
|
||
|
const {
|
||
|
data
|
||
|
} = optimizeSync.call(svgo, code, getInfo(state));
|
||
|
return data;
|
||
|
}
|