nav tabs on admin dashboard

This commit is contained in:
2019-03-07 00:20:34 -06:00
parent f73d6ae228
commit e4f473f376
11661 changed files with 216240 additions and 1544253 deletions

613
node_modules/svgo/lib/svgo/coa.js generated vendored
View File

@@ -1,17 +1,23 @@
/* jshint quotmark: false */
'use strict';
require('colors');
var FS = require('fs'),
PATH = require('path'),
chalk = require('chalk'),
mkdirp = require('mkdirp'),
promisify = require('util.promisify'),
readdir = promisify(FS.readdir),
readFile = promisify(FS.readFile),
writeFile = promisify(FS.writeFile),
SVGO = require('../svgo.js'),
YAML = require('js-yaml'),
PKG = require('../../package.json'),
mkdirp = require('mkdirp'),
encodeSVGDatauri = require('./tools.js').encodeSVGDatauri,
decodeSVGDatauri = require('./tools.js').decodeSVGDatauri,
regSVGFile = /\.svg$/;
checkIsDir = require('./tools.js').checkIsDir,
regSVGFile = /\.svg$/,
noop = () => {},
svgo;
/**
* Command-Option-Argument.
@@ -37,6 +43,7 @@ module.exports = require('coa').Cmd()
.opt()
.name('input').title('Input file, "-" for STDIN')
.short('i').long('input')
.arr()
.val(function(val) {
return val || this.reject("Option '--input' must have a value.");
})
@@ -55,6 +62,7 @@ module.exports = require('coa').Cmd()
.opt()
.name('output').title('Output file or folder (by default the same as the input), "-" for STDOUT')
.short('o').long('output')
.arr()
.val(function(val) {
return val || this.reject("Option '--output' must have a value.");
})
@@ -74,7 +82,7 @@ module.exports = require('coa').Cmd()
})
.end()
.opt()
.name('disable').title('Disable plugin by name')
.name('disable').title('Disable plugin by name, "--disable={PLUGIN1,PLUGIN2}" for multiple plugins (*nix)')
.long('disable')
.arr()
.val(function(val) {
@@ -82,7 +90,7 @@ module.exports = require('coa').Cmd()
})
.end()
.opt()
.name('enable').title('Enable plugin by name')
.name('enable').title('Enable plugin by name, "--enable={PLUGIN3,PLUGIN4}" for multiple plugins (*nix)')
.long('enable')
.arr()
.val(function(val) {
@@ -113,6 +121,11 @@ module.exports = require('coa').Cmd()
return !isNaN(val) ? val : this.reject("Option '--indent' must be an integer number");
})
.end()
.opt()
.name('recursive').title('Use with \'-f\'. Optimizes *.svg files in folders recursively.')
.short('r').long('recursive')
.flag()
.end()
.opt()
.name('quiet').title('Only output error messages, not regular status messages')
.short('q').long('quiet')
@@ -125,70 +138,65 @@ module.exports = require('coa').Cmd()
.end()
.arg()
.name('input').title('Alias to --input')
.end()
.arg()
.name('output').title('Alias to --output')
.arr()
.end()
.act(function(opts, args) {
var input = args && args.input ? args.input : opts.input,
output = args && args.output ? args.output : opts.output,
var input = opts.input || args.input,
output = opts.output,
config = {};
// --show-plugins
if (opts['show-plugins']) {
showAvailablePlugins();
process.exit(0);
return;
}
// w/o anything
if (
(!input || input === '-') &&
(!input || input[0] === '-') &&
!opts.string &&
!opts.stdin &&
!opts.folder &&
process.stdin.isTTY
process.stdin.isTTY === true
) return this.usage();
if (typeof process == 'object' && process.versions && process.versions.node && PKG && PKG.engines.node) {
var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) {
return printErrorAndExit(`Error: ${PKG.name} requires Node.js version ${nodeVersion} or higher.`);
}
}
// --config
if (opts.config) {
// string
if (opts.config.charAt(0) === '{') {
try {
config = JSON.parse(opts.config);
} catch (e) {
console.error("Error: Couldn't parse config JSON.");
console.error(String(e));
return;
return printErrorAndExit(`Error: Couldn't parse config JSON.\n${String(e)}`);
}
// external file
} else {
var configPath = PATH.resolve(opts.config);
var configPath = PATH.resolve(opts.config),
configData;
try {
// require() adds some weird output on YML files
config = JSON.parse(FS.readFileSync(configPath, 'utf8'));
configData = FS.readFileSync(configPath, 'utf8');
config = JSON.parse(configData);
} catch (err) {
if (err.code === 'ENOENT') {
console.error('Error: couldn\'t find config file \'' + opts.config + '\'.');
return;
return printErrorAndExit(`Error: couldn't find config file '${opts.config}'.`);
} else if (err.code === 'EISDIR') {
console.error('Error: directory \'' + opts.config + '\' is not a config file.');
return;
return printErrorAndExit(`Error: directory '${opts.config}' is not a config file.`);
}
config = YAML.safeLoad(FS.readFileSync(configPath, 'utf8'));
config = YAML.safeLoad(configData);
if (!config || Array.isArray(config)) {
console.error('Error: invalid config file \'' + opts.config + '\'.');
return;
return printErrorAndExit(`Error: invalid config file '${opts.config}'.`);
}
}
}
}
// --quiet
@@ -196,9 +204,17 @@ module.exports = require('coa').Cmd()
config.quiet = opts.quiet;
}
// --recursive
if (opts.recursive) {
config.recursive = opts.recursive;
}
// --precision
if (opts.precision) {
config.floatPrecision = Math.max(0, parseInt(opts.precision));
var precision = Math.min(Math.max(0, parseInt(opts.precision)), 20);
if (!isNaN(precision)) {
config.floatPrecision = precision;
}
}
// --disable
@@ -213,163 +229,75 @@ module.exports = require('coa').Cmd()
// --multipass
if (opts.multipass) {
config.multipass = true;
}
// --pretty
if (opts.pretty) {
config.js2svg = config.js2svg || {};
config.js2svg.pretty = true;
if (opts.indent) {
config.js2svg.indent = parseInt(opts.indent, 10);
var indent;
if (opts.indent && !isNaN(indent = parseInt(opts.indent))) {
config.js2svg.indent = indent;
}
}
svgo = new SVGO(config);
// --output
if (opts.output) {
config.output = opts.output;
if (output) {
if (input && input[0] != '-') {
if (output.length == 1 && checkIsDir(output[0])) {
var dir = output[0];
for (var i = 0; i < input.length; i++) {
output[i] = checkIsDir(input[i]) ? input[i] : PATH.resolve(dir, PATH.basename(input[i]));
}
} else if (output.length < input.length) {
output = output.concat(input.slice(output.length));
}
}
} else if (input) {
output = input;
} else if (opts.string) {
output = '-';
}
if (opts.datauri) {
config.datauri = opts.datauri;
}
// --folder
if (opts.folder) {
optimizeFolder(opts.folder, config, output);
return;
var ouputFolder = output && output[0] || opts.folder;
return optimizeFolder(config, opts.folder, ouputFolder).then(noop, printErrorAndExit);
}
// --input
if (input) {
// STDIN
if (input === '-') {
var data = '';
process.stdin.pause();
process.stdin
.on('data', function(chunk) {
data += chunk;
})
.once('end', function() {
optimizeFromString(data, config, opts.datauri, input, output);
})
.resume();
if (input[0] === '-') {
return new Promise((resolve, reject) => {
var data = '',
file = output[0];
process.stdin
.on('data', chunk => data += chunk)
.once('end', () => processSVGData(config, {input: 'string'}, data, file).then(resolve, reject));
});
// file
} else {
FS.readFile(input, 'utf8', function(err, data) {
if (err) {
if (err.code === 'EISDIR')
optimizeFolder(input, config, output);
else if (err.code === 'ENOENT')
console.error('Error: no such file or directory \'' + input + '\'.');
else
console.error(err);
return;
}
optimizeFromString(data, config, opts.datauri, input, output);
});
return Promise.all(input.map((file, n) => optimizeFile(config, file, output[n])))
.then(noop, printErrorAndExit);
}
// --string
} else if (opts.string) {
var data = decodeSVGDatauri(opts.string);
opts.string = decodeSVGDatauri(opts.string);
optimizeFromString(opts.string, config, opts.datauri, input, output);
return processSVGData(config, {input: 'string'}, data, output[0]);
}
});
function optimizeFromString(svgstr, config, datauri, input, output) {
var startTime = Date.now(config),
time,
inBytes = Buffer.byteLength(svgstr, 'utf8'),
outBytes,
svgo = new SVGO(config);
svgo.optimize(svgstr, function(result) {
if (result.error) {
console.error(result.error);
return;
}
if (datauri) {
result.data = encodeSVGDatauri(result.data, datauri);
}
outBytes = Buffer.byteLength(result.data, 'utf8');
time = Date.now() - startTime;
// stdout
if (output === '-' || (!input || input === '-') && !output) {
process.stdout.write(result.data + '\n');
// file
} else {
// overwrite input file if there is no output
if (!output && input) {
output = input;
}
if (!config.quiet) {
console.log('\r');
}
saveFileAndPrintInfo(config, result.data, output, inBytes, outBytes, time);
}
});
}
function saveFileAndPrintInfo(config, data, path, inBytes, outBytes, time) {
FS.writeFile(path, data, 'utf8', function() {
if (config.quiet) {
return;
}
// print time info
printTimeInfo(time);
// print optimization profit info
printProfitInfo(inBytes, outBytes);
});
}
function printTimeInfo(time) {
console.log('Done in ' + time + ' ms!');
}
function printProfitInfo(inBytes, outBytes) {
var profitPercents = 100 - outBytes * 100 / inBytes;
console.log(
(Math.round((inBytes / 1024) * 1000) / 1000) + ' KiB' +
(profitPercents < 0 ? ' + ' : ' - ') +
String(Math.abs((Math.round(profitPercents * 10) / 10)) + '%').green + ' = ' +
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB\n'
);
}
/**
* Change plugins state by names array.
*
@@ -379,17 +307,15 @@ function printProfitInfo(inBytes, outBytes) {
* @return {Object} changed config
*/
function changePluginsState(names, state, config) {
names.forEach(flattenPluginsCbk);
// extend config
if (config.plugins) {
names.forEach(function(name) {
var matched,
for (var name of names) {
var matched = false,
key;
config.plugins.forEach(function(plugin) {
for (var plugin of config.plugins) {
// get plugin name
if (typeof plugin === 'object') {
key = Object.keys(plugin)[0];
@@ -403,179 +329,250 @@ function changePluginsState(names, state, config) {
if (typeof plugin[key] !== 'object' || !state) {
plugin[key] = state;
}
// mark it as matched
matched = true;
}
});
}
// if not matched and current config is not full
if (!matched && !config.full) {
var obj = {};
obj[name] = state;
// push new plugin Object
config.plugins.push(obj);
config.plugins.push({ [name]: state });
matched = true;
}
});
}
// just push
} else {
config.plugins = [];
names.forEach(function(name) {
var obj = {};
obj[name] = state;
config.plugins.push(obj);
});
config.plugins = names.map(name => ({ [name]: state }));
}
return config;
}
function optimizeFolder(dir, config, output) {
/**
* Flatten an array of plugins by invoking this callback on each element
* whose value may be a comma separated list of plugins.
*
* @param {String} name Plugin name
* @param {Number} index Plugin index
* @param {Array} names Plugins being traversed
*/
function flattenPluginsCbk(name, index, names)
{
var split = name.split(',');
var svgo = new SVGO(config);
if (!config.quiet) {
console.log('Processing directory \'' + dir + '\':\n');
if(split.length > 1) {
names[index] = split.shift();
names.push.apply(names, split);
}
// absoluted folder path
var path = PATH.resolve(dir);
}
// list folder content
FS.readdir(path, function(err, files) {
/**
* Optimize SVG files in a directory.
* @param {Object} config options
* @param {string} dir input directory
* @param {string} output output directory
* @return {Promise}
*/
function optimizeFolder(config, dir, output) {
if (!config.quiet) {
console.log(`Processing directory '${dir}':\n`);
}
return readdir(dir).then(files => processDirectory(config, dir, files, output));
}
if (err) {
console.error(err);
return;
/**
* Process given files, take only SVG.
* @param {Object} config options
* @param {string} dir input directory
* @param {Array} files list of file names in the directory
* @param {string} output output directory
* @return {Promise}
*/
function processDirectory(config, dir, files, output) {
// take only *.svg files, recursively if necessary
var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output);
return svgFilesDescriptions.length ?
Promise.all(svgFilesDescriptions.map(fileDescription => optimizeFile(config, fileDescription.inputPath, fileDescription.outputPath))) :
Promise.reject(new Error(`No SVG files have been found in '${dir}' directory.`));
}
/**
* Get svg files descriptions
* @param {Object} config options
* @param {string} dir input directory
* @param {Array} files list of file names in the directory
* @param {string} output output directory
* @return {Array}
*/
function getFilesDescriptions(config, dir, files, output) {
const filesInThisFolder = files
.filter(name => regSVGFile.test(name))
.map(name => ({
inputPath: PATH.resolve(dir, name),
outputPath: PATH.resolve(output, name),
}));
return config.recursive ?
[].concat(
filesInThisFolder,
files
.filter(name => checkIsDir(PATH.resolve(dir, name)))
.map(subFolderName => {
const subFolderPath = PATH.resolve(dir, subFolderName);
const subFolderFiles = FS.readdirSync(subFolderPath);
const subFolderOutput = PATH.resolve(output, subFolderName);
return getFilesDescriptions(config, subFolderPath, subFolderFiles, subFolderOutput);
})
.reduce((a, b) => [].concat(a, b), [])
) :
filesInThisFolder;
}
/**
* Read SVG file and pass to processing.
* @param {Object} config options
* @param {string} file
* @param {string} output
* @return {Promise}
*/
function optimizeFile(config, file, output) {
return readFile(file, 'utf8').then(
data => processSVGData(config, {input: 'file', path: file}, data, output, file),
error => checkOptimizeFileError(config, file, output, error)
);
}
/**
* Optimize SVG data.
* @param {Object} config options
* @param {string} data SVG content to optimize
* @param {string} output where to write optimized file
* @param {string} [input] input file name (being used if output is a directory)
* @return {Promise}
*/
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;
if (!files.length) {
console.log('Directory \'' + dir + '\' is empty.');
return;
}
var i = 0,
found = false;
function optimizeFile(file) {
// absoluted file path
var filepath = PATH.resolve(path, file);
var outfilepath = output ? PATH.resolve(output, file) : filepath;
// check if file name matches *.svg
if (regSVGFile.test(filepath)) {
found = true;
FS.readFile(filepath, 'utf8', function(err, data) {
if (err) {
console.error(err);
return;
}
var startTime = Date.now(),
time,
inBytes = Buffer.byteLength(data, 'utf8'),
outBytes;
svgo.optimize(data, function(result) {
if (result.error) {
console.error(result.error);
return;
}
outBytes = Buffer.byteLength(result.data, 'utf8');
time = Date.now() - startTime;
writeOutput();
function writeOutput() {
FS.writeFile(outfilepath, result.data, 'utf8', report);
}
function report(err) {
if (err) {
if (err.code === 'ENOENT') {
mkdirp(output, writeOutput);
return;
} else if (err.code === 'ENOTDIR') {
console.error('Error: output \'' + output + '\' is not a directory.');
return;
}
console.error(err);
return;
}
if (!config.quiet) {
console.log(file + ':');
// print time info
printTimeInfo(time);
// print optimization profit info
printProfitInfo(inBytes, outBytes);
}
//move on to the next file
if (++i < files.length) {
optimizeFile(files[i]);
}
}
});
});
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);
}
//move on to the next file
else if (++i < files.length) {
optimizeFile(files[i]);
} else if (!found) {
console.log('No SVG files have been found.');
}
}
optimizeFile(files[i]);
},
error => Promise.reject(new Error(error.code === 'ENOTDIR' ? `Error: output '${output}' is not a directory.` : error)));
});
}
/**
* Write result of an optimization.
* @param {string} input
* @param {string} output output file name. '-' for stdout
* @param {string} data data to write
* @return {Promise}
*/
function writeOutput(input, output, data) {
if (output == '-') {
console.log(data);
return Promise.resolve();
}
mkdirp.sync(PATH.dirname(output));
return writeFile(output, data, 'utf8').catch(error => checkWriteFileError(input, output, data, error));
}
var showAvailablePlugins = function () {
/**
* Write a time taken by optimization.
* @param {number} time time in milliseconds.
*/
function printTimeInfo(time) {
console.log(`Done in ${time} ms!`);
}
var svgo = new SVGO(),
// Flatten an array of plugins grouped per type and sort alphabetically
list = Array.prototype.concat.apply([], svgo.config.plugins).sort(function(a, b) {
return a.name > b.name ? 1 : -1;
});
/**
* Write optimizing information in human readable format.
* @param {number} inBytes size before optimization.
* @param {number} outBytes size after optimization.
*/
function printProfitInfo(inBytes, outBytes) {
var profitPercents = 100 - outBytes * 100 / inBytes;
console.log(
(Math.round((inBytes / 1024) * 1000) / 1000) + ' KiB' +
(profitPercents < 0 ? ' + ' : ' - ') +
chalk.green(Math.abs((Math.round(profitPercents * 10) / 10)) + '%') + ' = ' +
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB'
);
}
/**
* Check for errors, if it's a dir optimize the dir.
* @param {Object} config
* @param {string} input
* @param {string} output
* @param {Error} error
* @return {Promise}
*/
function checkOptimizeFileError(config, input, output, error) {
if (error.code == 'EISDIR') {
return optimizeFolder(config, input, output);
} else if (error.code == 'ENOENT') {
return Promise.reject(new Error(`Error: no such file or directory '${error.path}'.`));
}
return Promise.reject(error);
}
/**
* Check for saving file error. If the output is a dir, then write file there.
* @param {string} input
* @param {string} output
* @param {string} data
* @param {Error} error
* @return {Promise}
*/
function checkWriteFileError(input, output, data, error) {
if (error.code == 'EISDIR' && input) {
return writeFile(PATH.resolve(output, PATH.basename(input)), data, 'utf8');
} else {
return Promise.reject(error);
}
}
/**
* Show list of available plugins with short description.
*/
function showAvailablePlugins() {
console.log('Currently available plugins:');
list.forEach(function (plugin) {
console.log(' [ ' + plugin.name.green + ' ] ' + plugin.description);
});
// Flatten an array of plugins grouped per type, sort and write output
var list = [].concat.apply([], new SVGO().config.plugins)
.sort((a, b) => a.name.localeCompare(b.name))
.map(plugin => ` [ ${chalk.green(plugin.name)} ] ${plugin.description}`)
.join('\n');
console.log(list);
}
//console.log(JSON.stringify(svgo, null, 4));
};
/**
* Write an error and exit.
* @param {Error} error
* @return {Promise} a promise for running tests
*/
function printErrorAndExit(error) {
console.error(chalk.red(error));
process.exit(1);
return Promise.reject(error); // for tests
}

22
node_modules/svgo/lib/svgo/config.js generated vendored
View File

@@ -3,8 +3,6 @@
var FS = require('fs');
var yaml = require('js-yaml');
var EXTEND = require('whet.extend');
/**
* Read and/or extend/replace default config file,
* prepare and optimize plugins array.
@@ -28,8 +26,8 @@ module.exports = function(config) {
defaults.plugins = preparePluginsArray(defaults.plugins);
}
} else {
defaults = EXTEND({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));
defaults.plugins = preparePluginsArray(defaults.plugins);
defaults = Object.assign({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));
defaults.plugins = preparePluginsArray(defaults.plugins || []);
defaults = extendConfig(defaults, config);
}
@@ -37,11 +35,15 @@ module.exports = function(config) {
defaults.plugins.forEach(function(plugin) {
if (plugin.params && ('floatPrecision' in plugin.params)) {
// Don't touch default plugin params
plugin.params = EXTEND({}, plugin.params, { floatPrecision: config.floatPrecision });
plugin.params = Object.assign({}, plugin.params, { floatPrecision: config.floatPrecision });
}
});
}
if ('datauri' in config) {
defaults.datauri = config.datauri;
}
if (Array.isArray(defaults.plugins)) {
defaults.plugins = optimizePluginsArray(defaults.plugins);
}
@@ -74,11 +76,11 @@ function preparePluginsArray(plugins) {
} else {
plugin = EXTEND({}, require('../../plugins/' + key));
plugin = Object.assign({}, require('../../plugins/' + key));
// name: {}
if (typeof item[key] === 'object') {
plugin.params = EXTEND({}, plugin.params || {}, item[key]);
plugin.params = Object.assign({}, plugin.params || {}, item[key]);
plugin.active = true;
// name: false
@@ -96,7 +98,7 @@ function preparePluginsArray(plugins) {
// name
} else {
plugin = EXTEND({}, require('../../plugins/' + item));
plugin = Object.assign({}, require('../../plugins/' + item));
plugin.name = item;
}
@@ -138,7 +140,7 @@ function extendConfig(defaults, config) {
if (plugin.name === key) {
// name: {}
if (typeof item[key] === 'object') {
plugin.params = EXTEND({}, plugin.params || {}, item[key]);
plugin.params = Object.assign({}, plugin.params || {}, item[key]);
plugin.active = true;
// name: false
@@ -184,7 +186,7 @@ function extendConfig(defaults, config) {
*/
function setupCustomPlugin(name, plugin) {
plugin.active = true;
plugin.params = EXTEND({}, plugin.params || {});
plugin.params = Object.assign({}, plugin.params || {});
plugin.name = name;
return plugin;

12
node_modules/svgo/lib/svgo/js2svg.js generated vendored
View File

@@ -1,7 +1,6 @@
'use strict';
var EOL = require('os').EOL,
EXTEND = require('whet.extend'),
textElem = require('../../plugins/_collections.js').elemsGroups.textContent.concat('title');
var defaults = {
@@ -56,15 +55,14 @@ module.exports = function(data, config) {
function JS2SVG(config) {
if (config) {
this.config = EXTEND(true, {}, defaults, config);
this.config = Object.assign({}, defaults, config);
} else {
this.config = defaults;
this.config = Object.assign({}, defaults);
}
var indent = this.config.indent;
if (typeof indent == 'number' && !isNaN(indent)) {
this.config.indent = '';
for (var i = indent; i-- > 0;) this.config.indent += ' ';
this.config.indent = (indent < 0) ? '\t' : ' '.repeat(indent);
} else if (typeof indent != 'string') {
this.config.indent = ' ';
}
@@ -146,9 +144,7 @@ JS2SVG.prototype.createIndent = function() {
var indent = '';
if (this.config.pretty && !this.textContext) {
for (var i = 1; i < this.indentLevel; i++) {
indent += this.config.indent;
}
indent = this.config.indent.repeat(this.indentLevel - 1);
}
return indent;

86
node_modules/svgo/lib/svgo/jsAPI.js generated vendored
View File

@@ -1,9 +1,15 @@
'use strict';
var EXTEND = require('whet.extend');
var cssSelect = require('css-select');
var svgoCssSelectAdapter = require('./css-select-adapter');
var cssSelectOpts = {
xmlMode: true,
adapter: svgoCssSelectAdapter
};
var JSAPI = module.exports = function(data, parentNode) {
EXTEND(this, data);
Object.assign(this, data);
if (parentNode) {
Object.defineProperty(this, 'parentNode', {
writable: true,
@@ -22,13 +28,12 @@ JSAPI.prototype.clone = function() {
var nodeData = {};
Object.keys(node).forEach(function(key) {
if (key !== 'content') {
if (key !== 'class' && key !== 'style' && key !== 'content') {
nodeData[key] = node[key];
}
});
// Deep-clone node data
// This is still faster than using EXTEND(true…)
// Deep-clone node data.
nodeData = JSON.parse(JSON.stringify(nodeData));
// parentNode gets set to a proper object by the parent clone,
@@ -36,6 +41,12 @@ JSAPI.prototype.clone = function() {
// in the constructor.
var clonedNode = new JSAPI(nodeData, !!node.parentNode);
if (node.class) {
clonedNode.class = node.class.clone(clonedNode);
}
if (node.style) {
clonedNode.style = node.style.clone(clonedNode);
}
if (node.content) {
clonedNode.content = node.content.map(function(childNode) {
var clonedChild = childNode.clone();
@@ -90,6 +101,20 @@ JSAPI.prototype.renameElem = function(name) {
};
/**
* Find the closest ancestor of the current element.
* @param elemName
*
* @return {?Object}
*/
JSAPI.prototype.closestElem = function(elemName) {
var elem = this;
while ((elem = elem.parentNode) && !elem.isElem(elemName));
return elem;
};
/**
* Changes content by removing elements and/or adding new elements.
*
@@ -224,7 +249,10 @@ JSAPI.prototype.renameElem = function(name) {
if (!arguments.length) return false;
if (Array.isArray(name)) name.forEach(this.removeAttr, this);
if (Array.isArray(name)) {
name.forEach(this.removeAttr, this);
return false;
}
if (!this.hasAttr(name)) return false;
@@ -255,6 +283,14 @@ JSAPI.prototype.renameElem = function(name) {
this.attrs = this.attrs || {};
this.attrs[attr.name] = attr;
if(attr.name === 'class') { // newly added class attribute
this.class.hasClass();
}
if(attr.name === 'style') { // newly added style attribute
this.style.hasStyle();
}
return this.attrs[attr.name];
};
@@ -296,3 +332,41 @@ JSAPI.prototype.renameElem = function(name) {
return false;
};
/**
* Evaluate a string of CSS selectors against the element and returns matched elements.
*
* @param {String} selectors CSS selector(s) string
* @return {Array} null if no elements matched
*/
JSAPI.prototype.querySelectorAll = function(selectors) {
var matchedEls = cssSelect(selectors, this, cssSelectOpts);
return matchedEls.length > 0 ? matchedEls : null;
};
/**
* Evaluate a string of CSS selectors against the element and returns only the first matched element.
*
* @param {String} selectors CSS selector(s) string
* @return {Array} null if no element matched
*/
JSAPI.prototype.querySelector = function(selectors) {
return cssSelect.selectOne(selectors, this, cssSelectOpts);
};
/**
* Test if a selector matches a given element.
*
* @param {String} selector CSS selector string
* @return {Boolean} true if element would be selected by selector string, false if it does not
*/
JSAPI.prototype.matches = function(selector) {
return cssSelect.is(this, selector, cssSelectOpts);
};

View File

@@ -6,22 +6,23 @@
* @module plugins
*
* @param {Object} data input data
* @param {Object} info extra information
* @param {Object} plugins plugins object from config
* @return {Object} output data
*/
module.exports = function(data, plugins) {
module.exports = function(data, info, plugins) {
plugins.forEach(function(group) {
switch(group[0].type) {
case 'perItem':
data = perItem(data, group);
data = perItem(data, info, group);
break;
case 'perItemReverse':
data = perItem(data, group, true);
data = perItem(data, info, group, true);
break;
case 'full':
data = full(data, group);
data = full(data, info, group);
break;
}
@@ -35,11 +36,12 @@ module.exports = function(data, plugins) {
* Direct or reverse per-item loop.
*
* @param {Object} data input data
* @param {Object} info extra information
* @param {Array} plugins plugins list to process
* @param {Boolean} [reverse] reverse pass?
* @return {Object} output data
*/
function perItem(data, plugins, reverse) {
function perItem(data, info, plugins, reverse) {
function monkeys(items) {
@@ -56,7 +58,7 @@ function perItem(data, plugins, reverse) {
for (var i = 0; filter && i < plugins.length; i++) {
var plugin = plugins[i];
if (plugin.active && plugin.fn(item, plugin.params) === false) {
if (plugin.active && plugin.fn(item, plugin.params, info) === false) {
filter = false;
}
}
@@ -82,14 +84,15 @@ function perItem(data, plugins, reverse) {
* "Full" plugins.
*
* @param {Object} data input data
* @param {Object} info extra information
* @param {Array} plugins plugins list to process
* @return {Object} output data
*/
function full(data, plugins) {
function full(data, info, plugins) {
plugins.forEach(function(plugin) {
if (plugin.active) {
data = plugin.fn(data, plugin.params);
data = plugin.fn(data, plugin.params, info);
}
});

21
node_modules/svgo/lib/svgo/svg2js.js generated vendored
View File

@@ -2,6 +2,8 @@
var SAX = require('sax'),
JSAPI = require('./jsAPI.js'),
CSSClassList = require('./css-class-list'),
CSSStyleDeclaration = require('./css-style-declaration'),
entityDeclaration = /<!ENTITY\s+(\S+)\s+(?:'([^\']+)'|"([^\"]+)")\s*>/g;
var config = {
@@ -22,7 +24,7 @@ var config = {
module.exports = function(data, callback) {
var sax = SAX.parser(config.strict, config),
root = new JSAPI({ elem: '#document' }),
root = new JSAPI({ elem: '#document', content: [] }),
current = root,
stack = [root],
textContext = null,
@@ -85,13 +87,24 @@ module.exports = function(data, callback) {
var elem = {
elem: data.name,
prefix: data.prefix,
local: data.local
local: data.local,
attrs: {}
};
if (Object.keys(data.attributes).length) {
elem.attrs = {};
elem.class = new CSSClassList(elem);
elem.style = new CSSStyleDeclaration(elem);
if (Object.keys(data.attributes).length) {
for (var name in data.attributes) {
if (name === 'class') { // has class attribute
elem.class.hasClass();
}
if (name === 'style') { // has style attribute
elem.style.hasStyle();
}
elem.attrs[name] = {
name: name,
value: data.attributes[name].value,

24
node_modules/svgo/lib/svgo/tools.js generated vendored
View File

@@ -1,5 +1,7 @@
'use strict';
var FS = require('fs');
/**
* Encode plain SVG data string into Data URI string.
*
@@ -15,9 +17,12 @@ exports.encodeSVGDatauri = function(str, type) {
if (!type || type === 'base64') {
prefix += ';base64,';
str = prefix + new Buffer(str).toString('base64');
if (Buffer.from) {
str = prefix + Buffer.from(str).toString('base64');
} else {
str = prefix + new Buffer(str).toString('base64');
}
// URI encoded
} else if (type === 'enc') {
@@ -145,3 +150,16 @@ var removeLeadingZero = exports.removeLeadingZero = function(num) {
return strNum;
};
/**
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
* @param {string} path
*/
exports.checkIsDir = function(path) {
try {
return FS.lstatSync(path).isDirectory();
} catch(e) {
return false;
}
};