1
0
mirror of https://github.com/svg/svgo.git synced 2025-08-07 15:22:54 +03:00

Format lib with prettier (#1386)

Note: review with hidden whitespaces
This commit is contained in:
Bogdan Chadkin
2021-02-28 10:56:16 +03:00
committed by GitHub
parent a99cc08e4f
commit 71e47370bd
13 changed files with 1312 additions and 1282 deletions

View File

@@ -5,7 +5,6 @@ var csstree = require('css-tree'),
stable = require('stable'), stable = require('stable'),
specificity = require('csso/lib/restructure/prepare/specificity'); specificity = require('csso/lib/restructure/prepare/specificity');
/** /**
* Flatten a CSS AST to a selectors list. * Flatten a CSS AST to a selectors list.
* *
@@ -15,7 +14,9 @@ var csstree = require('css-tree'),
function flattenToSelectors(cssAst) { function flattenToSelectors(cssAst) {
var selectors = []; var selectors = [];
csstree.walk(cssAst, {visit: 'Rule', enter: function(node) { csstree.walk(cssAst, {
visit: 'Rule',
enter: function (node) {
if (node.type !== 'Rule') { if (node.type !== 'Rule') {
return; return;
} }
@@ -28,22 +29,29 @@ function flattenToSelectors(cssAst) {
item: selectorItem, item: selectorItem,
atrule: atrule, atrule: atrule,
rule: rule, rule: rule,
pseudos: [] pseudos: [],
}; };
selectorNode.children.each(function(selectorChildNode, selectorChildItem, selectorChildList) { selectorNode.children.each(function (
if (selectorChildNode.type === 'PseudoClassSelector' || selectorChildNode,
selectorChildNode.type === 'PseudoElementSelector') { selectorChildItem,
selectorChildList
) {
if (
selectorChildNode.type === 'PseudoClassSelector' ||
selectorChildNode.type === 'PseudoElementSelector'
) {
selector.pseudos.push({ selector.pseudos.push({
item: selectorChildItem, item: selectorChildItem,
list: selectorChildList list: selectorChildList,
}); });
} }
}); });
selectors.push(selector); selectors.push(selector);
}); });
}}); },
});
return selectors; return selectors;
} }
@@ -63,8 +71,10 @@ function filterByMqs(selectors, useMqs) {
var mqName = selector.atrule.name; var mqName = selector.atrule.name;
var mqStr = mqName; var mqStr = mqName;
if (selector.atrule.expression && if (
selector.atrule.expression.children.first().type === 'MediaQueryList') { selector.atrule.expression &&
selector.atrule.expression.children.first().type === 'MediaQueryList'
) {
var mqExpr = csstree.generate(selector.atrule.expression); var mqExpr = csstree.generate(selector.atrule.expression);
mqStr = [mqName, mqExpr].join(' '); mqStr = [mqName, mqExpr].join(' ');
} }
@@ -84,9 +94,11 @@ function filterByPseudos(selectors, usePseudos) {
return selectors.filter(function (selector) { return selectors.filter(function (selector) {
var pseudoSelectorsStr = csstree.generate({ var pseudoSelectorsStr = csstree.generate({
type: 'Selector', type: 'Selector',
children: new List().fromArray(selector.pseudos.map(function(pseudo) { children: new List().fromArray(
selector.pseudos.map(function (pseudo) {
return pseudo.item.data; return pseudo.item.data;
})) })
),
}); });
return ~usePseudos.indexOf(pseudoSelectorsStr); return ~usePseudos.indexOf(pseudoSelectorsStr);
}); });
@@ -106,7 +118,6 @@ function cleanPseudos(selectors) {
}); });
} }
/** /**
* Compares two selector specificities. * Compares two selector specificities.
* extracted from https://github.com/keeganstreet/specificity/blob/master/specificity.js#L211 * extracted from https://github.com/keeganstreet/specificity/blob/master/specificity.js#L211
@@ -127,7 +138,6 @@ function compareSpecificity(aSpecificity, bSpecificity) {
return 0; return 0;
} }
/** /**
* Compare two simple selectors. * Compare two simple selectors.
* *
@@ -145,7 +155,6 @@ function _bySelectorSpecificity(selectorA, selectorB) {
return compareSimpleSelectorNode(selectorA.item.data, selectorB.item.data); return compareSimpleSelectorNode(selectorA.item.data, selectorB.item.data);
} }
/** /**
* Sort selectors stably by their specificity. * Sort selectors stably by their specificity.
* *
@@ -156,7 +165,6 @@ function sortSelectors(selectors) {
return stable(selectors, _bySelectorSpecificity); return stable(selectors, _bySelectorSpecificity);
} }
/** /**
* Convert a css-tree AST style declaration to CSSStyleDeclaration property. * Convert a css-tree AST style declaration to CSSStyleDeclaration property.
* *
@@ -166,15 +174,14 @@ function sortSelectors(selectors) {
function csstreeToStyleDeclaration(declaration) { function csstreeToStyleDeclaration(declaration) {
var propertyName = declaration.property, var propertyName = declaration.property,
propertyValue = csstree.generate(declaration.value), propertyValue = csstree.generate(declaration.value),
propertyPriority = (declaration.important ? 'important' : ''); propertyPriority = declaration.important ? 'important' : '';
return { return {
name: propertyName, name: propertyName,
value: propertyValue, value: propertyValue,
priority: propertyPriority priority: propertyPriority,
}; };
} }
/** /**
* Gets the CSS string of a style element * Gets the CSS string of a style element
* *
@@ -204,7 +211,6 @@ function setCssStr(elem, css) {
return elem.content[0].text; return elem.content[0].text;
} }
module.exports.flattenToSelectors = flattenToSelectors; module.exports.flattenToSelectors = flattenToSelectors;
module.exports.filterByMqs = filterByMqs; module.exports.filterByMqs = filterByMqs;

View File

@@ -8,7 +8,7 @@ const {
createContentItem, createContentItem,
} = require('./svgo.js'); } = require('./svgo.js');
const importConfig = async configFile => { const importConfig = async (configFile) => {
const config = require(configFile); const config = require(configFile);
if (config == null || typeof config !== 'object' || Array.isArray(config)) { if (config == null || typeof config !== 'object' || Array.isArray(config)) {
throw Error(`Invalid config file "${configFile}"`); throw Error(`Invalid config file "${configFile}"`);
@@ -23,7 +23,7 @@ const isFile = async (file) => {
} catch { } catch {
return false; return false;
} }
} };
const loadConfig = async (configFile, cwd = process.cwd()) => { const loadConfig = async (configFile, cwd = process.cwd()) => {
if (configFile != null) { if (configFile != null) {
@@ -36,7 +36,7 @@ const loadConfig = async (configFile, cwd = process.cwd()) => {
let dir = cwd; let dir = cwd;
// eslint-disable-next-line no-constant-condition // eslint-disable-next-line no-constant-condition
while (true) { while (true) {
const file = path.join(dir, "svgo.config.js"); const file = path.join(dir, 'svgo.config.js');
if (await isFile(file)) { if (await isFile(file)) {
return await importConfig(file); return await importConfig(file);
} }

View File

@@ -13,7 +13,7 @@
const { const {
defaultPlugins, defaultPlugins,
resolvePluginConfig, resolvePluginConfig,
extendDefaultPlugins extendDefaultPlugins,
} = require('./svgo/config.js'); } = require('./svgo/config.js');
const svg2js = require('./svgo/svg2js.js'); const svg2js = require('./svgo/svg2js.js');
const js2svg = require('./svgo/js2svg.js'); const js2svg = require('./svgo/js2svg.js');
@@ -28,12 +28,12 @@ const optimize = (input, config) => {
config = {}; config = {};
} }
if (typeof config !== 'object') { if (typeof config !== 'object') {
throw Error('Config should be an object') throw Error('Config should be an object');
} }
const maxPassCount = config.multipass ? 10 : 1; const maxPassCount = config.multipass ? 10 : 1;
let prevResultSize = Number.POSITIVE_INFINITY; let prevResultSize = Number.POSITIVE_INFINITY;
let svgjs = null; let svgjs = null;
const info = {} const info = {};
if (config.path != null) { if (config.path != null) {
info.path = config.path; info.path = config.path;
} }
@@ -48,9 +48,13 @@ const optimize = (input, config) => {
} }
const plugins = config.plugins || defaultPlugins; const plugins = config.plugins || defaultPlugins;
if (Array.isArray(plugins) === false) { if (Array.isArray(plugins) === false) {
throw Error('Invalid plugins list. Provided \'plugins\' in config should be an array.'); throw Error(
"Invalid plugins list. Provided 'plugins' in config should be an array."
);
} }
const resolvedPlugins = plugins.map(plugin => resolvePluginConfig(plugin, config)) const resolvedPlugins = plugins.map((plugin) =>
resolvePluginConfig(plugin, config)
);
svgjs = invokePlugins(svgjs, info, resolvedPlugins); svgjs = invokePlugins(svgjs, info, resolvedPlugins);
svgjs = js2svg(svgjs, config.js2svg); svgjs = js2svg(svgjs, config.js2svg);
if (svgjs.error) { if (svgjs.error) {
@@ -58,7 +62,7 @@ const optimize = (input, config) => {
} }
if (svgjs.data.length < prevResultSize) { if (svgjs.data.length < prevResultSize) {
input = svgjs.data; input = svgjs.data;
prevResultSize = svgjs.data.length prevResultSize = svgjs.data.length;
} else { } else {
if (config.datauri) { if (config.datauri) {
svgjs.data = encodeSVGDatauri(svgjs.data, config.datauri); svgjs.data = encodeSVGDatauri(svgjs.data, config.datauri);

View File

@@ -25,52 +25,83 @@ module.exports = function makeProgram(program) {
program program
.name(PKG.name) .name(PKG.name)
.description(PKG.description, { .description(PKG.description, {
INPUT: 'Alias to --input' INPUT: 'Alias to --input',
}) })
.version(PKG.version, '-v, --version') .version(PKG.version, '-v, --version')
.arguments('[INPUT...]') .arguments('[INPUT...]')
.option('-i, --input <INPUT...>', 'Input files, "-" for STDIN') .option('-i, --input <INPUT...>', 'Input files, "-" for STDIN')
.option('-s, --string <STRING>', 'Input SVG data string') .option('-s, --string <STRING>', 'Input SVG data string')
.option('-f, --folder <FOLDER>', 'Input folder, optimize and rewrite all *.svg files') .option(
.option('-o, --output <OUTPUT...>', 'Output file or folder (by default the same as the input), "-" for STDOUT') '-f, --folder <FOLDER>',
.option('-p, --precision <INTEGER>', 'Set number of digits in the fractional part, overrides plugins params') 'Input folder, optimize and rewrite all *.svg files'
)
.option(
'-o, --output <OUTPUT...>',
'Output file or folder (by default the same as the input), "-" for STDOUT'
)
.option(
'-p, --precision <INTEGER>',
'Set number of digits in the fractional part, overrides plugins params'
)
.option('--config <CONFIG>', 'Custom config file, only .js is supported') .option('--config <CONFIG>', 'Custom config file, only .js is supported')
.option('--datauri <FORMAT>', 'Output as Data URI string (base64), URI encoded (enc) or unencoded (unenc)') .option(
.option('--multipass', 'Pass over SVGs multiple times to ensure all optimizations are applied') '--datauri <FORMAT>',
'Output as Data URI string (base64), URI encoded (enc) or unencoded (unenc)'
)
.option(
'--multipass',
'Pass over SVGs multiple times to ensure all optimizations are applied'
)
.option('--pretty', 'Make SVG pretty printed') .option('--pretty', 'Make SVG pretty printed')
.option('--indent <INTEGER>', 'Indent number when pretty printing SVGs') .option('--indent <INTEGER>', 'Indent number when pretty printing SVGs')
.option('-r, --recursive', 'Use with \'-f\'. Optimizes *.svg files in folders recursively.') .option(
.option('-q, --quiet', 'Only output error messages, not regular status messages') '-r, --recursive',
"Use with '-f'. Optimizes *.svg files in folders recursively."
)
.option(
'-q, --quiet',
'Only output error messages, not regular status messages'
)
.option('--show-plugins', 'Show available plugins and exit') .option('--show-plugins', 'Show available plugins and exit')
.action(action); .action(action);
} };
async function action(args, opts, command) { async function action(args, opts, command) {
var input = opts.input || args; var input = opts.input || args;
var output = opts.output; var output = opts.output;
var config = {} var config = {};
if (opts.precision != null) { if (opts.precision != null) {
const number = Number.parseInt(opts.precision, 0); const number = Number.parseInt(opts.precision, 0);
if (Number.isNaN(number)) { if (Number.isNaN(number)) {
console.error("error: option '-p, --precision' argument must be an integer number"); console.error(
process.exit(1) "error: option '-p, --precision' argument must be an integer number"
);
process.exit(1);
} else { } else {
opts.precision = number; opts.precision = number;
} }
} }
if (opts.datauri != null) { if (opts.datauri != null) {
if (opts.datauri !== 'base64' && opts.datauri !== 'enc' && opts.datauri !== 'unenc') { if (
console.error("error: option '--datauri' must have one of the following values: 'base64', 'enc' or 'unenc'") opts.datauri !== 'base64' &&
process.exit(1) opts.datauri !== 'enc' &&
opts.datauri !== 'unenc'
) {
console.error(
"error: option '--datauri' must have one of the following values: 'base64', 'enc' or 'unenc'"
);
process.exit(1);
} }
} }
if (opts.indent != null) { if (opts.indent != null) {
const number = Number.parseInt(opts.indent, 0); const number = Number.parseInt(opts.indent, 0);
if (Number.isNaN(number)) { if (Number.isNaN(number)) {
console.error("error: option '--indent' argument must be an integer number"); console.error(
"error: option '--indent' argument must be an integer number"
);
process.exit(1); process.exit(1);
} else { } else {
opts.indent = number; opts.indent = number;
@@ -94,10 +125,18 @@ async function action(args, opts, command) {
return command.help(); return command.help();
} }
if (typeof process == 'object' && process.versions && process.versions.node && PKG && PKG.engines.node) { if (
typeof process == 'object' &&
process.versions &&
process.versions.node &&
PKG &&
PKG.engines.node
) {
var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0]; var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) { if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) {
throw Error(`${PKG.name} requires Node.js version ${nodeVersion} or higher.`); throw Error(
`${PKG.name} requires Node.js version ${nodeVersion} or higher.`
);
} }
} }
@@ -143,7 +182,9 @@ async function action(args, opts, command) {
if (output.length == 1 && checkIsDir(output[0])) { if (output.length == 1 && checkIsDir(output[0])) {
var dir = output[0]; var dir = output[0];
for (var i = 0; i < input.length; i++) { for (var i = 0; i < input.length; i++) {
output[i] = checkIsDir(input[i]) ? input[i] : PATH.resolve(dir, PATH.basename(input[i])); output[i] = checkIsDir(input[i])
? input[i]
: PATH.resolve(dir, PATH.basename(input[i]));
} }
} else if (output.length < input.length) { } else if (output.length < input.length) {
output = output.concat(input.slice(output.length)); output = output.concat(input.slice(output.length));
@@ -161,7 +202,7 @@ async function action(args, opts, command) {
// --folder // --folder
if (opts.folder) { if (opts.folder) {
var ouputFolder = output && output[0] || opts.folder; var ouputFolder = (output && output[0]) || opts.folder;
await optimizeFolder(config, opts.folder, ouputFolder); await optimizeFolder(config, opts.folder, ouputFolder);
} }
@@ -174,8 +215,13 @@ async function action(args, opts, command) {
file = output[0]; file = output[0];
process.stdin process.stdin
.on('data', chunk => data += chunk) .on('data', (chunk) => (data += chunk))
.once('end', () => processSVGData(config, {input: 'string'}, data, file).then(resolve, reject)); .once('end', () =>
processSVGData(config, { input: 'string' }, data, file).then(
resolve,
reject
)
);
}); });
// file // file
} else { } else {
@@ -203,7 +249,9 @@ function optimizeFolder(config, dir, output) {
if (!config.quiet) { if (!config.quiet) {
console.log(`Processing directory '${dir}':\n`); console.log(`Processing directory '${dir}':\n`);
} }
return FS.promises.readdir(dir).then(files => processDirectory(config, dir, files, output)); return FS.promises
.readdir(dir)
.then((files) => processDirectory(config, dir, files, output));
} }
/** /**
@@ -218,9 +266,19 @@ function processDirectory(config, dir, files, output) {
// take only *.svg files, recursively if necessary // take only *.svg files, recursively if necessary
var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output); var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output);
return svgFilesDescriptions.length ? return svgFilesDescriptions.length
Promise.all(svgFilesDescriptions.map(fileDescription => optimizeFile(config, fileDescription.inputPath, fileDescription.outputPath))) : ? Promise.all(
Promise.reject(new Error(`No SVG files have been found in '${dir}' directory.`)); svgFilesDescriptions.map((fileDescription) =>
optimizeFile(
config,
fileDescription.inputPath,
fileDescription.outputPath
)
)
)
: Promise.reject(
new Error(`No SVG files have been found in '${dir}' directory.`)
);
} }
/** /**
@@ -233,26 +291,31 @@ function processDirectory(config, dir, files, output) {
*/ */
function getFilesDescriptions(config, dir, files, output) { function getFilesDescriptions(config, dir, files, output) {
const filesInThisFolder = files const filesInThisFolder = files
.filter(name => regSVGFile.test(name)) .filter((name) => regSVGFile.test(name))
.map(name => ({ .map((name) => ({
inputPath: PATH.resolve(dir, name), inputPath: PATH.resolve(dir, name),
outputPath: PATH.resolve(output, name), outputPath: PATH.resolve(output, name),
})); }));
return config.recursive ? return config.recursive
[].concat( ? [].concat(
filesInThisFolder, filesInThisFolder,
files files
.filter(name => checkIsDir(PATH.resolve(dir, name))) .filter((name) => checkIsDir(PATH.resolve(dir, name)))
.map(subFolderName => { .map((subFolderName) => {
const subFolderPath = PATH.resolve(dir, subFolderName); const subFolderPath = PATH.resolve(dir, subFolderName);
const subFolderFiles = FS.readdirSync(subFolderPath); const subFolderFiles = FS.readdirSync(subFolderPath);
const subFolderOutput = PATH.resolve(output, subFolderName); const subFolderOutput = PATH.resolve(output, subFolderName);
return getFilesDescriptions(config, subFolderPath, subFolderFiles, subFolderOutput); return getFilesDescriptions(
config,
subFolderPath,
subFolderFiles,
subFolderOutput
);
}) })
.reduce((a, b) => [].concat(a, b), []) .reduce((a, b) => [].concat(a, b), [])
) : )
filesInThisFolder; : filesInThisFolder;
} }
/** /**
@@ -264,8 +327,9 @@ function getFilesDescriptions(config, dir, files, output) {
*/ */
function optimizeFile(config, file, output) { function optimizeFile(config, file, output) {
return FS.promises.readFile(file, 'utf8').then( return FS.promises.readFile(file, 'utf8').then(
data => processSVGData(config, {input: 'file', path: file}, data, output, file), (data) =>
error => checkOptimizeFileError(config, file, output, error) processSVGData(config, { input: 'file', path: file }, data, output, file),
(error) => checkOptimizeFileError(config, file, output, error)
); );
} }
@@ -285,9 +349,9 @@ function processSVGData(config, info, data, output, input) {
if (result.error) { if (result.error) {
let message = result.error; let message = result.error;
if (result.path != null) { if (result.path != null) {
message += `\nFile: ${result.path}` message += `\nFile: ${result.path}`;
} }
throw Error(message) throw Error(message);
} }
if (config.datauri) { if (config.datauri) {
result.data = encodeSVGDatauri(result.data, config.datauri); result.data = encodeSVGDatauri(result.data, config.datauri);
@@ -295,7 +359,8 @@ function processSVGData(config, info, data, output, input) {
var resultFileSize = Buffer.byteLength(result.data, 'utf8'), var resultFileSize = Buffer.byteLength(result.data, 'utf8'),
processingTime = Date.now() - startTime; processingTime = Date.now() - startTime;
return writeOutput(input, output, result.data).then(function() { return writeOutput(input, output, result.data).then(
function () {
if (!config.quiet && output != '-') { if (!config.quiet && output != '-') {
if (input) { if (input) {
console.log(`\n${PATH.basename(input)}:`); console.log(`\n${PATH.basename(input)}:`);
@@ -304,7 +369,15 @@ function processSVGData(config, info, data, output, input) {
printProfitInfo(prevFileSize, resultFileSize); printProfitInfo(prevFileSize, resultFileSize);
} }
}, },
error => Promise.reject(new Error(error.code === 'ENOTDIR' ? `Error: output '${output}' is not a directory.` : error))); (error) =>
Promise.reject(
new Error(
error.code === 'ENOTDIR'
? `Error: output '${output}' is not a directory.`
: error
)
)
);
} }
/** /**
@@ -322,10 +395,11 @@ function writeOutput(input, output, data) {
FS.mkdirSync(PATH.dirname(output), { recursive: true }); FS.mkdirSync(PATH.dirname(output), { recursive: true });
return FS.promises.writeFile(output, data, 'utf8').catch(error => checkWriteFileError(input, output, data, error)); return FS.promises
.writeFile(output, data, 'utf8')
.catch((error) => checkWriteFileError(input, output, data, error));
} }
/** /**
* Write a time taken by optimization. * Write a time taken by optimization.
* @param {number} time time in milliseconds. * @param {number} time time in milliseconds.
@@ -340,13 +414,16 @@ function printTimeInfo(time) {
* @param {number} outBytes size after optimization. * @param {number} outBytes size after optimization.
*/ */
function printProfitInfo(inBytes, outBytes) { function printProfitInfo(inBytes, outBytes) {
var profitPercents = 100 - outBytes * 100 / inBytes; var profitPercents = 100 - (outBytes * 100) / inBytes;
console.log( console.log(
(Math.round((inBytes / 1024) * 1000) / 1000) + ' KiB' + Math.round((inBytes / 1024) * 1000) / 1000 +
' KiB' +
(profitPercents < 0 ? ' + ' : ' - ') + (profitPercents < 0 ? ' + ' : ' - ') +
chalk.green(Math.abs((Math.round(profitPercents * 10) / 10)) + '%') + ' = ' + chalk.green(Math.abs(Math.round(profitPercents * 10) / 10) + '%') +
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB' ' = ' +
Math.round((outBytes / 1024) * 1000) / 1000 +
' KiB'
); );
} }
@@ -362,7 +439,9 @@ function checkOptimizeFileError(config, input, output, error) {
if (error.code == 'EISDIR') { if (error.code == 'EISDIR') {
return optimizeFolder(config, input, output); return optimizeFolder(config, input, output);
} else if (error.code == 'ENOENT') { } else if (error.code == 'ENOENT') {
return Promise.reject(new Error(`Error: no such file or directory '${error.path}'.`)); return Promise.reject(
new Error(`Error: no such file or directory '${error.path}'.`)
);
} }
return Promise.reject(error); return Promise.reject(error);
} }
@@ -377,7 +456,11 @@ function checkOptimizeFileError(config, input, output, error) {
*/ */
function checkWriteFileError(input, output, data, error) { function checkWriteFileError(input, output, data, error) {
if (error.code == 'EISDIR' && input) { if (error.code == 'EISDIR' && input) {
return FS.promises.writeFile(PATH.resolve(output, PATH.basename(input)), data, 'utf8'); return FS.promises.writeFile(
PATH.resolve(output, PATH.basename(input)),
data,
'utf8'
);
} else { } else {
return Promise.reject(error); return Promise.reject(error);
} }

View File

@@ -53,11 +53,14 @@ const pluginsOrder = [
'removeOffCanvasPaths', 'removeOffCanvasPaths',
'reusePaths', 'reusePaths',
]; ];
const defaultPlugins = pluginsOrder.filter(name => pluginsMap[name].active); const defaultPlugins = pluginsOrder.filter((name) => pluginsMap[name].active);
exports.defaultPlugins = defaultPlugins; exports.defaultPlugins = defaultPlugins;
const extendDefaultPlugins = (plugins) => { const extendDefaultPlugins = (plugins) => {
const extendedPlugins = pluginsOrder.map(name => ({ name, ...pluginsMap[name] })); const extendedPlugins = pluginsOrder.map((name) => ({
name,
...pluginsMap[name],
}));
for (const plugin of plugins) { for (const plugin of plugins) {
const resolvedPlugin = resolvePluginConfig(plugin, {}); const resolvedPlugin = resolvePluginConfig(plugin, {});
const index = pluginsOrder.indexOf(resolvedPlugin.name); const index = pluginsOrder.indexOf(resolvedPlugin.name);
@@ -68,7 +71,7 @@ const extendDefaultPlugins = (plugins) => {
} }
} }
return extendedPlugins; return extendedPlugins;
} };
exports.extendDefaultPlugins = extendDefaultPlugins; exports.extendDefaultPlugins = extendDefaultPlugins;
const resolvePluginConfig = (plugin, config) => { const resolvePluginConfig = (plugin, config) => {
@@ -86,7 +89,7 @@ const resolvePluginConfig = (plugin, config) => {
...pluginConfig, ...pluginConfig,
name: plugin, name: plugin,
active: true, active: true,
params: { ...pluginConfig.params, ...configParams } params: { ...pluginConfig.params, ...configParams },
}; };
} }
if (typeof plugin === 'object' && plugin != null) { if (typeof plugin === 'object' && plugin != null) {
@@ -98,7 +101,7 @@ const resolvePluginConfig = (plugin, config) => {
return { return {
active: true, active: true,
...plugin, ...plugin,
params: { configParams, ...plugin.params } params: { configParams, ...plugin.params },
}; };
} else { } else {
// resolve builtin plugin specified as object without implementation // resolve builtin plugin specified as object without implementation
@@ -110,7 +113,7 @@ const resolvePluginConfig = (plugin, config) => {
...pluginConfig, ...pluginConfig,
active: true, active: true,
...plugin, ...plugin,
params: { ...pluginConfig.params, ...configParams, ...plugin.params } params: { ...pluginConfig.params, ...configParams, ...plugin.params },
}; };
} }
} }

View File

@@ -31,24 +31,23 @@ CSSClassList.prototype.clone = function(parentNode) {
}; };
CSSClassList.prototype.hasClass = function () { CSSClassList.prototype.hasClass = function () {
this.classAttr = { // empty class attr this.classAttr = {
'name': 'class', // empty class attr
'value': null name: 'class',
value: null,
}; };
this.addClassHandler(); this.addClassHandler();
}; };
// attr.class // attr.class
CSSClassList.prototype.addClassHandler = function () { CSSClassList.prototype.addClassHandler = function () {
Object.defineProperty(this.parentNode.attrs, 'class', { Object.defineProperty(this.parentNode.attrs, 'class', {
get: this.getClassAttr.bind(this), get: this.getClassAttr.bind(this),
set: this.setClassAttr.bind(this), set: this.setClassAttr.bind(this),
enumerable: true, enumerable: true,
configurable: true configurable: true,
}); });
this.addClassValueHandler(); this.addClassValueHandler();
@@ -57,12 +56,11 @@ CSSClassList.prototype.addClassHandler = function() {
// attr.class.value // attr.class.value
CSSClassList.prototype.addClassValueHandler = function () { CSSClassList.prototype.addClassValueHandler = function () {
Object.defineProperty(this.classAttr, 'value', { Object.defineProperty(this.classAttr, 'value', {
get: this.getClassValue.bind(this), get: this.getClassValue.bind(this),
set: this.setClassValue.bind(this), set: this.setClassValue.bind(this),
enumerable: true, enumerable: true,
configurable: true configurable: true,
}); });
}; };
@@ -91,7 +89,6 @@ CSSClassList.prototype.setClassValue = function(newValue) {
this.classNames = new Set(arrClassNames); this.classNames = new Set(arrClassNames);
}; };
CSSClassList.prototype.add = function (/* variadic */) { CSSClassList.prototype.add = function (/* variadic */) {
this.hasClass(); this.hasClass();
Object.values(arguments).forEach(this._addSingle.bind(this)); Object.values(arguments).forEach(this._addSingle.bind(this));
@@ -101,7 +98,6 @@ CSSClassList.prototype._addSingle = function(className) {
this.classNames.add(className); this.classNames.add(className);
}; };
CSSClassList.prototype.remove = function (/* variadic */) { CSSClassList.prototype.remove = function (/* variadic */) {
this.hasClass(); this.hasClass();
Object.values(arguments).forEach(this._removeSingle.bind(this)); Object.values(arguments).forEach(this._removeSingle.bind(this));
@@ -111,7 +107,6 @@ CSSClassList.prototype._removeSingle = function(className) {
this.classNames.delete(className); this.classNames.delete(className);
}; };
CSSClassList.prototype.item = function (index) { CSSClassList.prototype.item = function (index) {
var arrClassNames = Array.from(this.classNames); var arrClassNames = Array.from(this.classNames);
return arrClassNames[index]; return arrClassNames[index];
@@ -128,5 +123,4 @@ CSSClassList.prototype.contains = function(className) {
return this.classNames.has(className); return this.classNames.has(className);
}; };
module.exports = CSSClassList; module.exports = CSSClassList;

View File

@@ -6,7 +6,6 @@ var baseCssAdapter = require('css-select-base-adapter');
* DOMUtils API for SVGO AST (used by css-select) * DOMUtils API for SVGO AST (used by css-select)
*/ */
var svgoCssSelectAdapterMin = { var svgoCssSelectAdapterMin = {
// is the node a tag? // is the node a tag?
// isTag: ( node:Node ) => isTag:Boolean // isTag: ( node:Node ) => isTag:Boolean
isTag: function (node) { isTag: function (node) {
@@ -44,7 +43,7 @@ var svgoCssSelectAdapterMin = {
// returns null when attribute doesn't exist // returns null when attribute doesn't exist
getAttributeValue: function (elem, name) { getAttributeValue: function (elem, name) {
return elem.hasAttr(name) ? elem.attr(name).value : null; return elem.hasAttr(name) ? elem.attr(name).value : null;
} },
}; };
// use base adapter for default implementation // use base adapter for default implementation

View File

@@ -3,7 +3,6 @@
var csstree = require('css-tree'), var csstree = require('css-tree'),
csstools = require('../css-tools'); csstools = require('../css-tools');
var CSSStyleDeclaration = function (node) { var CSSStyleDeclaration = function (node) {
this.parentNode = node; this.parentNode = node;
@@ -43,23 +42,20 @@ CSSStyleDeclaration.prototype.hasStyle = function() {
this.addStyleHandler(); this.addStyleHandler();
}; };
// attr.style // attr.style
CSSStyleDeclaration.prototype.addStyleHandler = function () { CSSStyleDeclaration.prototype.addStyleHandler = function () {
this.styleAttr = {
this.styleAttr = { // empty style attr // empty style attr
'name': 'style', name: 'style',
'value': null value: null,
}; };
Object.defineProperty(this.parentNode.attrs, 'style', { Object.defineProperty(this.parentNode.attrs, 'style', {
get: this.getStyleAttr.bind(this), get: this.getStyleAttr.bind(this),
set: this.setStyleAttr.bind(this), set: this.setStyleAttr.bind(this),
enumerable: true, enumerable: true,
configurable: true configurable: true,
}); });
this.addStyleValueHandler(); this.addStyleValueHandler();
@@ -68,12 +64,11 @@ CSSStyleDeclaration.prototype.addStyleHandler = function() {
// attr.style.value // attr.style.value
CSSStyleDeclaration.prototype.addStyleValueHandler = function () { CSSStyleDeclaration.prototype.addStyleValueHandler = function () {
Object.defineProperty(this.styleAttr, 'value', { Object.defineProperty(this.styleAttr, 'value', {
get: this.getStyleValue.bind(this), get: this.getStyleValue.bind(this),
set: this.setStyleValue.bind(this), set: this.setStyleValue.bind(this),
enumerable: true, enumerable: true,
configurable: true configurable: true,
}); });
}; };
@@ -99,9 +94,6 @@ CSSStyleDeclaration.prototype.setStyleValue = function(newValue) {
this.hasSynced = false; // raw css changed this.hasSynced = false; // raw css changed
}; };
CSSStyleDeclaration.prototype._loadCssText = function () { CSSStyleDeclaration.prototype._loadCssText = function () {
if (this.hasSynced) { if (this.hasSynced) {
return; return;
@@ -117,7 +109,7 @@ CSSStyleDeclaration.prototype._loadCssText = function() {
try { try {
declarations = csstree.parse(inlineCssStr, { declarations = csstree.parse(inlineCssStr, {
context: 'declarationList', context: 'declarationList',
parseValue: false parseValue: false,
}); });
} catch (parseError) { } catch (parseError) {
this.parseError = parseError; this.parseError = parseError;
@@ -129,7 +121,11 @@ CSSStyleDeclaration.prototype._loadCssText = function() {
declarations.children.each(function (declaration) { declarations.children.each(function (declaration) {
try { try {
var styleDeclaration = csstools.csstreeToStyleDeclaration(declaration); var styleDeclaration = csstools.csstreeToStyleDeclaration(declaration);
self.setProperty(styleDeclaration.name, styleDeclaration.value, styleDeclaration.priority); self.setProperty(
styleDeclaration.name,
styleDeclaration.value,
styleDeclaration.priority
);
} catch (styleError) { } catch (styleError) {
if (styleError.message !== 'Unknown node type: undefined') { if (styleError.message !== 'Unknown node type: undefined') {
self.parseError = styleError; self.parseError = styleError;
@@ -138,7 +134,6 @@ CSSStyleDeclaration.prototype._loadCssText = function() {
}); });
}; };
// only reads from properties // only reads from properties
/** /**
@@ -157,18 +152,22 @@ CSSStyleDeclaration.prototype.getCssText = function() {
var cssText = []; var cssText = [];
properties.forEach(function (property, propertyName) { properties.forEach(function (property, propertyName) {
var strImportant = property.priority === 'important' ? '!important' : ''; var strImportant = property.priority === 'important' ? '!important' : '';
cssText.push(propertyName.trim() + ':' + property.value.trim() + strImportant); cssText.push(
propertyName.trim() + ':' + property.value.trim() + strImportant
);
}); });
return cssText.join(';'); return cssText.join(';');
}; };
CSSStyleDeclaration.prototype._handleParseError = function () { CSSStyleDeclaration.prototype._handleParseError = function () {
if (this.parseError) { if (this.parseError) {
console.warn('Warning: Parse error when parsing inline styles, style properties of this element cannot be used. The raw styles can still be get/set using .attr(\'style\').value. Error details: ' + this.parseError); console.warn(
"Warning: Parse error when parsing inline styles, style properties of this element cannot be used. The raw styles can still be get/set using .attr('style').value. Error details: " +
this.parseError
);
} }
}; };
CSSStyleDeclaration.prototype._getProperty = function (propertyName) { CSSStyleDeclaration.prototype._getProperty = function (propertyName) {
if (typeof propertyName === 'undefined') { if (typeof propertyName === 'undefined') {
throw Error('1 argument required, but only 0 present.'); throw Error('1 argument required, but only 0 present.');
@@ -230,7 +229,6 @@ CSSStyleDeclaration.prototype.getProperties = function() {
return this.properties; return this.properties;
}; };
// writes to properties // writes to properties
/** /**
@@ -262,7 +260,11 @@ CSSStyleDeclaration.prototype.removeProperty = function(propertyName) {
* @param {String} [priority] allowing the "important" CSS priority to be set. If not specified, treated as the empty string. * @param {String} [priority] allowing the "important" CSS priority to be set. If not specified, treated as the empty string.
* @return {undefined} * @return {undefined}
*/ */
CSSStyleDeclaration.prototype.setProperty = function(propertyName, value, priority) { CSSStyleDeclaration.prototype.setProperty = function (
propertyName,
value,
priority
) {
if (typeof propertyName === 'undefined') { if (typeof propertyName === 'undefined') {
throw Error('propertyName argument required, but only not present.'); throw Error('propertyName argument required, but only not present.');
} }
@@ -274,12 +276,11 @@ CSSStyleDeclaration.prototype.setProperty = function(propertyName, value, priori
var property = { var property = {
value: value.trim(), value: value.trim(),
priority: priority.trim() priority: priority.trim(),
}; };
properties.set(propertyName.trim(), property); properties.set(propertyName.trim(), property);
return property; return property;
}; };
module.exports = CSSStyleDeclaration; module.exports = CSSStyleDeclaration;

View File

@@ -27,12 +27,12 @@ var defaults = {
regValEntities: /[&"<>]/g, regValEntities: /[&"<>]/g,
encodeEntity: encodeEntity, encodeEntity: encodeEntity,
pretty: false, pretty: false,
useShortTags: true useShortTags: true,
}; };
var entities = { var entities = {
'&': '&amp;', '&': '&amp;',
'\'': '&apos;', "'": '&apos;',
'"': '&quot;', '"': '&quot;',
'>': '&gt;', '>': '&gt;',
'<': '&lt;', '<': '&lt;',
@@ -47,13 +47,10 @@ var entities = {
* @return {Object} output data * @return {Object} output data
*/ */
module.exports = function (data, config) { module.exports = function (data, config) {
return new JS2SVG(config).convert(data); return new JS2SVG(config).convert(data);
}; };
function JS2SVG(config) { function JS2SVG(config) {
if (config) { if (config) {
this.config = Object.assign({}, defaults, config); this.config = Object.assign({}, defaults, config);
} else { } else {
@@ -62,7 +59,7 @@ function JS2SVG(config) {
var indent = this.config.indent; var indent = this.config.indent;
if (typeof indent == 'number' && !isNaN(indent)) { if (typeof indent == 'number' && !isNaN(indent)) {
this.config.indent = (indent < 0) ? '\t' : ' '.repeat(indent); this.config.indent = indent < 0 ? '\t' : ' '.repeat(indent);
} else if (typeof indent != 'string') { } else if (typeof indent != 'string') {
this.config.indent = ' '; this.config.indent = ' ';
} }
@@ -80,7 +77,6 @@ function JS2SVG(config) {
this.indentLevel = 0; this.indentLevel = 0;
this.textContext = null; this.textContext = null;
} }
function encodeEntity(char) { function encodeEntity(char) {
@@ -95,15 +91,12 @@ function encodeEntity(char) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.convert = function (data) { JS2SVG.prototype.convert = function (data) {
var svg = ''; var svg = '';
if (data.content) { if (data.content) {
this.indentLevel++; this.indentLevel++;
data.content.forEach(function (item) { data.content.forEach(function (item) {
if (item.elem) { if (item.elem) {
svg += this.createElem(item); svg += this.createElem(item);
} else if (item.text) { } else if (item.text) {
@@ -117,9 +110,7 @@ JS2SVG.prototype.convert = function(data) {
} else if (item.cdata) { } else if (item.cdata) {
svg += this.createCDATA(item.cdata); svg += this.createCDATA(item.cdata);
} }
}, this); }, this);
} }
this.indentLevel--; this.indentLevel--;
@@ -128,10 +119,9 @@ JS2SVG.prototype.convert = function(data) {
data: svg, data: svg,
info: { info: {
width: this.width, width: this.width,
height: this.height height: this.height,
} },
}; };
}; };
/** /**
@@ -140,7 +130,6 @@ JS2SVG.prototype.convert = function(data) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createIndent = function () { JS2SVG.prototype.createIndent = function () {
var indent = ''; var indent = '';
if (this.config.pretty && !this.textContext) { if (this.config.pretty && !this.textContext) {
@@ -148,7 +137,6 @@ JS2SVG.prototype.createIndent = function() {
} }
return indent; return indent;
}; };
/** /**
@@ -159,11 +147,7 @@ JS2SVG.prototype.createIndent = function() {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createDoctype = function (doctype) { JS2SVG.prototype.createDoctype = function (doctype) {
return this.config.doctypeStart + doctype + this.config.doctypeEnd;
return this.config.doctypeStart +
doctype +
this.config.doctypeEnd;
}; };
/** /**
@@ -174,13 +158,13 @@ JS2SVG.prototype.createDoctype = function(doctype) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createProcInst = function (instruction) { JS2SVG.prototype.createProcInst = function (instruction) {
return (
return this.config.procInstStart + this.config.procInstStart +
instruction.name + instruction.name +
' ' + ' ' +
instruction.body + instruction.body +
this.config.procInstEnd; this.config.procInstEnd
);
}; };
/** /**
@@ -191,11 +175,7 @@ JS2SVG.prototype.createProcInst = function(instruction) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createComment = function (comment) { JS2SVG.prototype.createComment = function (comment) {
return this.config.commentStart + comment + this.config.commentEnd;
return this.config.commentStart +
comment +
this.config.commentEnd;
}; };
/** /**
@@ -206,12 +186,9 @@ JS2SVG.prototype.createComment = function(comment) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createCDATA = function (cdata) { JS2SVG.prototype.createCDATA = function (cdata) {
return (
return this.createIndent() + this.createIndent() + this.config.cdataStart + cdata + this.config.cdataEnd
this.config.cdataStart + );
cdata +
this.config.cdataEnd;
}; };
/** /**
@@ -222,13 +199,8 @@ JS2SVG.prototype.createCDATA = function(cdata) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createElem = function (data) { JS2SVG.prototype.createElem = function (data) {
// beautiful injection for obtaining SVG information :) // beautiful injection for obtaining SVG information :)
if ( if (data.isElem('svg') && data.hasAttr('width') && data.hasAttr('height')) {
data.isElem('svg') &&
data.hasAttr('width') &&
data.hasAttr('height')
) {
this.width = data.attr('width').value; this.width = data.attr('width').value;
this.height = data.attr('height').value; this.height = data.attr('height').value;
} }
@@ -236,20 +208,24 @@ JS2SVG.prototype.createElem = function(data) {
// empty element and short tag // empty element and short tag
if (data.isEmpty()) { if (data.isEmpty()) {
if (this.config.useShortTags) { if (this.config.useShortTags) {
return this.createIndent() + return (
this.createIndent() +
this.config.tagShortStart + this.config.tagShortStart +
data.elem + data.elem +
this.createAttrs(data) + this.createAttrs(data) +
this.config.tagShortEnd; this.config.tagShortEnd
);
} else { } else {
return this.createIndent() + return (
this.createIndent() +
this.config.tagShortStart + this.config.tagShortStart +
data.elem + data.elem +
this.createAttrs(data) + this.createAttrs(data) +
this.config.tagOpenEnd + this.config.tagOpenEnd +
this.config.tagCloseStart + this.config.tagCloseStart +
data.elem + data.elem +
this.config.tagCloseEnd; this.config.tagCloseEnd
);
} }
// non-empty element // non-empty element
} else { } else {
@@ -281,7 +257,8 @@ JS2SVG.prototype.createElem = function(data) {
this.textContext = null; this.textContext = null;
} }
return openIndent + return (
openIndent +
tagOpenStart + tagOpenStart +
data.elem + data.elem +
this.createAttrs(data) + this.createAttrs(data) +
@@ -291,10 +268,9 @@ JS2SVG.prototype.createElem = function(data) {
closeIndent + closeIndent +
tagCloseStart + tagCloseStart +
data.elem + data.elem +
tagCloseEnd; tagCloseEnd
);
} }
}; };
/** /**
@@ -305,28 +281,25 @@ JS2SVG.prototype.createElem = function(data) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createAttrs = function (elem) { JS2SVG.prototype.createAttrs = function (elem) {
var attrs = ''; var attrs = '';
elem.eachAttr(function (attr) { elem.eachAttr(function (attr) {
if (attr.value !== undefined) { if (attr.value !== undefined) {
attrs += ' ' + attrs +=
' ' +
attr.name + attr.name +
this.config.attrStart + this.config.attrStart +
String(attr.value).replace(this.config.regValEntities, this.config.encodeEntity) + String(attr.value).replace(
this.config.regValEntities,
this.config.encodeEntity
) +
this.config.attrEnd; this.config.attrEnd;
} else {
attrs += ' ' + attr.name;
} }
else {
attrs += ' ' +
attr.name;
}
}, this); }, this);
return attrs; return attrs;
}; };
/** /**
@@ -337,10 +310,10 @@ JS2SVG.prototype.createAttrs = function(elem) {
* @return {String} * @return {String}
*/ */
JS2SVG.prototype.createText = function (text) { JS2SVG.prototype.createText = function (text) {
return (
return this.createIndent() + this.createIndent() +
this.config.textStart + this.config.textStart +
text.replace(this.config.regEntities, this.config.encodeEntity) + text.replace(this.config.regEntities, this.config.encodeEntity) +
(this.textContext ? '' : this.config.textEnd); (this.textContext ? '' : this.config.textEnd)
);
}; };

View File

@@ -5,18 +5,19 @@ const svgoCssSelectAdapter = require('./css-select-adapter');
var cssSelectOpts = { var cssSelectOpts = {
xmlMode: true, xmlMode: true,
adapter: svgoCssSelectAdapter adapter: svgoCssSelectAdapter,
}; };
var JSAPI = module.exports = function(data, parentNode) { var JSAPI = function (data, parentNode) {
Object.assign(this, data); Object.assign(this, data);
if (parentNode) { if (parentNode) {
Object.defineProperty(this, 'parentNode', { Object.defineProperty(this, 'parentNode', {
writable: true, writable: true,
value: parentNode value: parentNode,
}); });
} }
}; };
module.exports = JSAPI;
/** /**
* Perform a deep clone of this node. * Perform a deep clone of this node.
@@ -66,13 +67,11 @@ JSAPI.prototype.clone = function() {
* @return {Boolean} * @return {Boolean}
*/ */
JSAPI.prototype.isElem = function (param) { JSAPI.prototype.isElem = function (param) {
if (!param) return !!this.elem; if (!param) return !!this.elem;
if (Array.isArray(param)) return !!this.elem && (param.indexOf(this.elem) > -1); if (Array.isArray(param)) return !!this.elem && param.indexOf(this.elem) > -1;
return !!this.elem && this.elem === param; return !!this.elem && this.elem === param;
}; };
/** /**
@@ -82,12 +81,9 @@ JSAPI.prototype.isElem = function(param) {
* @return {Object} element * @return {Object} element
*/ */
JSAPI.prototype.renameElem = function (name) { JSAPI.prototype.renameElem = function (name) {
if (name && typeof name === 'string') this.elem = this.local = name;
if (name && typeof name === 'string')
this.elem = this.local = name;
return this; return this;
}; };
/** /**
@@ -96,9 +92,7 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Boolean} * @return {Boolean}
*/ */
JSAPI.prototype.isEmpty = function () { JSAPI.prototype.isEmpty = function () {
return !this.content || !this.content.length; return !this.content || !this.content.length;
}; };
/** /**
@@ -124,17 +118,16 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Array} Removed elements. * @return {Array} Removed elements.
*/ */
JSAPI.prototype.spliceContent = function (start, n, insertion) { JSAPI.prototype.spliceContent = function (start, n, insertion) {
if (arguments.length < 2) return []; if (arguments.length < 2) return [];
if (!Array.isArray(insertion)) if (!Array.isArray(insertion))
insertion = Array.apply(null, arguments).slice(2); insertion = Array.apply(null, arguments).slice(2);
insertion.forEach(function(inner) { inner.parentNode = this }, this); insertion.forEach(function (inner) {
inner.parentNode = this;
}, this);
return this.content.splice.apply(this.content, [start, n].concat(insertion)); return this.content.splice.apply(this.content, [start, n].concat(insertion));
}; };
/** /**
@@ -146,15 +139,14 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Boolean} * @return {Boolean}
*/ */
JSAPI.prototype.hasAttr = function (name, val) { JSAPI.prototype.hasAttr = function (name, val) {
if (!this.attrs || !Object.keys(this.attrs).length) return false; if (!this.attrs || !Object.keys(this.attrs).length) return false;
if (!arguments.length) return !!this.attrs; if (!arguments.length) return !!this.attrs;
if (val !== undefined) return !!this.attrs[name] && this.attrs[name].value === val.toString(); if (val !== undefined)
return !!this.attrs[name] && this.attrs[name].value === val.toString();
return !!this.attrs[name]; return !!this.attrs[name];
}; };
/** /**
@@ -166,7 +158,6 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Boolean} * @return {Boolean}
*/ */
JSAPI.prototype.hasAttrLocal = function (localName, val) { JSAPI.prototype.hasAttrLocal = function (localName, val) {
if (!this.attrs || !Object.keys(this.attrs).length) return false; if (!this.attrs || !Object.keys(this.attrs).length) return false;
if (!arguments.length) return !!this.attrs; if (!arguments.length) return !!this.attrs;
@@ -175,10 +166,17 @@ JSAPI.prototype.renameElem = function(name) {
switch (val != null && val.constructor && val.constructor.name) { switch (val != null && val.constructor && val.constructor.name) {
case 'Number': // same as String case 'Number': // same as String
case 'String': callback = stringValueTest; break; case 'String':
case 'RegExp': callback = regexpValueTest; break; callback = stringValueTest;
case 'Function': callback = funcValueTest; break; break;
default: callback = nameTest; case 'RegExp':
callback = regexpValueTest;
break;
case 'Function':
callback = funcValueTest;
break;
default:
callback = nameTest;
} }
return this.someAttr(callback); return this.someAttr(callback);
@@ -197,7 +195,6 @@ JSAPI.prototype.renameElem = function(name) {
function funcValueTest(attr) { function funcValueTest(attr) {
return attr.local === localName && val(attr.value); return attr.local === localName && val(attr.value);
} }
}; };
/** /**
@@ -209,13 +206,12 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Object|Undefined} * @return {Object|Undefined}
*/ */
JSAPI.prototype.attr = function (name, val) { JSAPI.prototype.attr = function (name, val) {
if (!this.hasAttr() || !arguments.length) return undefined; if (!this.hasAttr() || !arguments.length) return undefined;
if (val !== undefined) return this.hasAttr(name, val) ? this.attrs[name] : undefined; if (val !== undefined)
return this.hasAttr(name, val) ? this.attrs[name] : undefined;
return this.attrs[name]; return this.attrs[name];
}; };
/** /**
@@ -227,14 +223,17 @@ JSAPI.prototype.renameElem = function(name) {
JSAPI.prototype.computedAttr = function (name, val) { JSAPI.prototype.computedAttr = function (name, val) {
if (!arguments.length) return; if (!arguments.length) return;
for (var elem = this; elem && (!elem.hasAttr(name) || !elem.attr(name).value); elem = elem.parentNode); for (
var elem = this;
elem && (!elem.hasAttr(name) || !elem.attr(name).value);
elem = elem.parentNode
);
if (val != null) { if (val != null) {
return elem ? elem.hasAttr(name, val) : false; return elem ? elem.hasAttr(name, val) : false;
} else if (elem && elem.hasAttr(name)) { } else if (elem && elem.hasAttr(name)) {
return elem.attrs[name].value; return elem.attrs[name].value;
} }
}; };
/** /**
@@ -245,7 +244,6 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Boolean} * @return {Boolean}
*/ */
JSAPI.prototype.removeAttr = function (name, val, recursive) { JSAPI.prototype.removeAttr = function (name, val, recursive) {
if (!arguments.length) return false; if (!arguments.length) return false;
if (Array.isArray(name)) { if (Array.isArray(name)) {
@@ -262,7 +260,6 @@ JSAPI.prototype.renameElem = function(name) {
if (!Object.keys(this.attrs).length) delete this.attrs; if (!Object.keys(this.attrs).length) delete this.attrs;
return true; return true;
}; };
/** /**
@@ -274,24 +271,27 @@ JSAPI.prototype.renameElem = function(name) {
JSAPI.prototype.addAttr = function (attr) { JSAPI.prototype.addAttr = function (attr) {
attr = attr || {}; attr = attr || {};
if (attr.name === undefined || if (
attr.name === undefined ||
attr.prefix === undefined || attr.prefix === undefined ||
attr.local === undefined attr.local === undefined
) return false; )
return false;
this.attrs = this.attrs || {}; this.attrs = this.attrs || {};
this.attrs[attr.name] = attr; this.attrs[attr.name] = attr;
if(attr.name === 'class') { // newly added class attribute if (attr.name === 'class') {
// newly added class attribute
this.class.hasClass(); this.class.hasClass();
} }
if(attr.name === 'style') { // newly added style attribute if (attr.name === 'style') {
// newly added style attribute
this.style.hasStyle(); this.style.hasStyle();
} }
return this.attrs[attr.name]; return this.attrs[attr.name];
}; };
/** /**
@@ -302,7 +302,6 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Boolean} false if there are no any attributes * @return {Boolean} false if there are no any attributes
*/ */
JSAPI.prototype.eachAttr = function (callback, context) { JSAPI.prototype.eachAttr = function (callback, context) {
if (!this.hasAttr()) return false; if (!this.hasAttr()) return false;
for (const attr of Object.values(this.attrs)) { for (const attr of Object.values(this.attrs)) {
@@ -310,7 +309,6 @@ JSAPI.prototype.renameElem = function(name) {
} }
return true; return true;
}; };
/** /**
@@ -321,7 +319,6 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Boolean} false if there are no any attributes * @return {Boolean} false if there are no any attributes
*/ */
JSAPI.prototype.someAttr = function (callback, context) { JSAPI.prototype.someAttr = function (callback, context) {
if (!this.hasAttr()) return false; if (!this.hasAttr()) return false;
for (const attr of Object.values(this.attrs)) { for (const attr of Object.values(this.attrs)) {
@@ -329,7 +326,6 @@ JSAPI.prototype.renameElem = function(name) {
} }
return false; return false;
}; };
/** /**
@@ -339,11 +335,9 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Array} null if no elements matched * @return {Array} null if no elements matched
*/ */
JSAPI.prototype.querySelectorAll = function (selectors) { JSAPI.prototype.querySelectorAll = function (selectors) {
var matchedEls = selectAll(selectors, this, cssSelectOpts); var matchedEls = selectAll(selectors, this, cssSelectOpts);
return matchedEls.length > 0 ? matchedEls : null; return matchedEls.length > 0 ? matchedEls : null;
}; };
/** /**
@@ -353,9 +347,7 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Array} null if no element matched * @return {Array} null if no element matched
*/ */
JSAPI.prototype.querySelector = function (selectors) { JSAPI.prototype.querySelector = function (selectors) {
return selectOne(selectors, this, cssSelectOpts); return selectOne(selectors, this, cssSelectOpts);
}; };
/** /**
@@ -365,7 +357,5 @@ JSAPI.prototype.renameElem = function(name) {
* @return {Boolean} true if element would be selected by selector string, false if it does not * @return {Boolean} true if element would be selected by selector string, false if it does not
*/ */
JSAPI.prototype.matches = function (selector) { JSAPI.prototype.matches = function (selector) {
return is(this, selector, cssSelectOpts); return is(this, selector, cssSelectOpts);
}; };

View File

@@ -49,11 +49,8 @@ module.exports = function(data, info, plugins) {
* @return {Object} output data * @return {Object} output data
*/ */
function perItem(data, info, plugins, reverse) { function perItem(data, info, plugins, reverse) {
function monkeys(items) { function monkeys(items) {
items.content = items.content.filter(function (item) { items.content = items.content.filter(function (item) {
// reverse pass // reverse pass
if (reverse && item.content) { if (reverse && item.content) {
monkeys(item); monkeys(item);
@@ -76,15 +73,12 @@ function perItem(data, info, plugins, reverse) {
} }
return filter; return filter;
}); });
return items; return items;
} }
return monkeys(data); return monkeys(data);
} }
/** /**
@@ -96,7 +90,6 @@ function perItem(data, info, plugins, reverse) {
* @return {Object} output data * @return {Object} output data
*/ */
function full(data, info, plugins) { function full(data, info, plugins) {
plugins.forEach(function (plugin) { plugins.forEach(function (plugin) {
if (plugin.active) { if (plugin.active) {
data = plugin.fn(data, plugin.params, info); data = plugin.fn(data, plugin.params, info);
@@ -104,5 +97,4 @@ function full(data, info, plugins) {
}); });
return data; return data;
} }

View File

@@ -13,7 +13,7 @@ var config = {
normalize: false, normalize: false,
lowercase: true, lowercase: true,
xmlns: true, xmlns: true,
position: true position: true,
}; };
/** /**
@@ -22,26 +22,22 @@ var config = {
* @param {String} data input data * @param {String} data input data
*/ */
module.exports = function (data) { module.exports = function (data) {
var sax = SAX.parser(config.strict, config), var sax = SAX.parser(config.strict, config),
root = new JSAPI({ elem: '#document', content: [] }), root = new JSAPI({ elem: '#document', content: [] }),
current = root, current = root,
stack = [root]; stack = [root];
function pushToContent(content) { function pushToContent(content) {
content = new JSAPI(content, current); content = new JSAPI(content, current);
(current.content = current.content || []).push(content); (current.content = current.content || []).push(content);
return content; return content;
} }
sax.ondoctype = function (doctype) { sax.ondoctype = function (doctype) {
pushToContent({ pushToContent({
doctype: doctype doctype: doctype,
}); });
var subsetStart = doctype.indexOf('['), var subsetStart = doctype.indexOf('['),
@@ -57,36 +53,29 @@ module.exports = function(data) {
}; };
sax.onprocessinginstruction = function (data) { sax.onprocessinginstruction = function (data) {
pushToContent({ pushToContent({
processinginstruction: data processinginstruction: data,
}); });
}; };
sax.oncomment = function (comment) { sax.oncomment = function (comment) {
pushToContent({ pushToContent({
comment: comment.trim() comment: comment.trim(),
}); });
}; };
sax.oncdata = function (cdata) { sax.oncdata = function (cdata) {
pushToContent({ pushToContent({
cdata: cdata cdata: cdata,
}); });
}; };
sax.onopentag = function (data) { sax.onopentag = function (data) {
var elem = { var elem = {
elem: data.name, elem: data.name,
prefix: data.prefix, prefix: data.prefix,
local: data.local, local: data.local,
attrs: {} attrs: {},
}; };
elem.class = new CSSClassList(elem); elem.class = new CSSClassList(elem);
@@ -94,12 +83,13 @@ module.exports = function(data) {
if (Object.keys(data.attributes).length) { if (Object.keys(data.attributes).length) {
for (const [name, attr] of Object.entries(data.attributes)) { for (const [name, attr] of Object.entries(data.attributes)) {
if (name === 'class') {
if (name === 'class') { // has class attribute // has class attribute
elem.class.hasClass(); elem.class.hasClass();
} }
if (name === 'style') { // has style attribute if (name === 'style') {
// has style attribute
elem.style.hasStyle(); elem.style.hasStyle();
} }
@@ -107,7 +97,7 @@ module.exports = function(data) {
name: name, name: name,
value: attr.value, value: attr.value,
prefix: attr.prefix, prefix: attr.prefix,
local: attr.local local: attr.local,
}; };
} }
} }
@@ -116,7 +106,6 @@ module.exports = function(data) {
current = elem; current = elem;
stack.push(elem); stack.push(elem);
}; };
sax.ontext = function (text) { sax.ontext = function (text) {
@@ -134,12 +123,10 @@ module.exports = function(data) {
}; };
sax.onerror = function (e) { sax.onerror = function (e) {
e.message = 'Error in parsing SVG: ' + e.message; e.message = 'Error in parsing SVG: ' + e.message;
if (e.message.indexOf('Unexpected end') < 0) { if (e.message.indexOf('Unexpected end') < 0) {
throw e; throw e;
} }
}; };
try { try {
@@ -148,5 +135,4 @@ module.exports = function(data) {
} catch (e) { } catch (e) {
return { error: e.message }; return { error: e.message };
} }
}; };

View File

@@ -99,9 +99,7 @@ exports.cleanupOutData = function(data, params, command) {
if ( if (
params.negativeExtraSpace && params.negativeExtraSpace &&
delimiter != '' && delimiter != '' &&
(item < 0 || (item < 0 || (String(item).charCodeAt(0) == 46 && prev % 1 !== 0))
(String(item).charCodeAt(0) == 46 && prev % 1 !== 0)
)
) { ) {
delimiter = ''; delimiter = '';
} }
@@ -125,7 +123,7 @@ exports.cleanupOutData = function(data, params, command) {
* *
* @return {String} output number as string * @return {String} output number as string
*/ */
var removeLeadingZero = exports.removeLeadingZero = function(num) { var removeLeadingZero = function (num) {
var strNum = num.toString(); var strNum = num.toString();
if (0 < num && num < 1 && strNum.charCodeAt(0) == 48) { if (0 < num && num < 1 && strNum.charCodeAt(0) == 48) {
@@ -135,3 +133,4 @@ var removeLeadingZero = exports.removeLeadingZero = function(num) {
} }
return strNum; return strNum;
}; };
exports.removeLeadingZero = removeLeadingZero;