mirror of
https://github.com/svg/svgo.git
synced 2025-07-28 09:22:00 +03:00
global refactoring dump
This commit is contained in:
250
.svgo.yml
250
.svgo.yml
@ -1,216 +1,40 @@
|
|||||||
plugins:
|
plugins:
|
||||||
|
|
||||||
- name: removeDoctype
|
# - name
|
||||||
active: true
|
#
|
||||||
type: perItem
|
# or:
|
||||||
|
# - name: false
|
||||||
|
# - name: true
|
||||||
|
#
|
||||||
|
# or:
|
||||||
|
# - name:
|
||||||
|
# param1: 1
|
||||||
|
# param2: 2
|
||||||
|
|
||||||
- name: removeXMLProcInst
|
- removeDoctype
|
||||||
active: true
|
- removeXMLProcInst
|
||||||
type: perItem
|
- removeComments
|
||||||
|
- removeMetadata
|
||||||
- name: removeComments
|
- removeEditorsNSData
|
||||||
active: true
|
- cleanupAttrs
|
||||||
type: perItem
|
- convertStyleToAttrs
|
||||||
|
- removeRasterImages
|
||||||
- name: removeMetadata
|
- cleanupNumericValues
|
||||||
active: true
|
- convertColors
|
||||||
type: perItem
|
- removeUnknownsAndDefaults
|
||||||
|
- removeNonInheritableGroupAttrs
|
||||||
- name: removeEditorsNSData
|
- removeUselessStrokeAndFill
|
||||||
active: true
|
- removeViewBox
|
||||||
type: perItem
|
- cleanupEnableBackground
|
||||||
|
- removeHiddenElems
|
||||||
- name: cleanupAttrs
|
- removeEmptyText
|
||||||
active: true
|
- moveElemsAttrsToGroup
|
||||||
type: perItem
|
- collapseGroups
|
||||||
params:
|
- moveGroupAttrsToElems
|
||||||
newlines: true
|
- convertPathData
|
||||||
trim: true
|
- convertTransform
|
||||||
spaces: true
|
- removeEmptyAttrs
|
||||||
|
- removeEmptyContainers
|
||||||
- name: convertStyleToAttrs
|
- cleanupIDs
|
||||||
active: true
|
- removeUnusedNS
|
||||||
type: perItem
|
- cropAndCenterAlongPath
|
||||||
|
|
||||||
- name: removeRasterImages
|
|
||||||
active: false
|
|
||||||
type: perItem
|
|
||||||
|
|
||||||
- name: cleanupNumericValues
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
floatPrecision: 3
|
|
||||||
leadingZero: true
|
|
||||||
defaultPx: true
|
|
||||||
|
|
||||||
- name: convertColors
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
names2hex: true
|
|
||||||
rgb2hex: true
|
|
||||||
shorthex: true
|
|
||||||
|
|
||||||
- name: removeUnknownsAndDefaults
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
SVGid: true
|
|
||||||
unknownContent: true
|
|
||||||
unknownAttrs: true
|
|
||||||
defaultAttrs: true
|
|
||||||
|
|
||||||
- name: removeNonInheritableGroupAttrs
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
|
|
||||||
- name: removeUselessStrokeAndFill
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
stroke: true
|
|
||||||
fill: true
|
|
||||||
|
|
||||||
- name: removeViewBox
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
|
|
||||||
- name: cleanupEnableBackground
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
|
|
||||||
- name: removeHiddenElems
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
displayNone: true
|
|
||||||
opacity0: true
|
|
||||||
circleR0: true
|
|
||||||
ellipseRX0: true
|
|
||||||
ellipseRY0: true
|
|
||||||
rectWidth0: true
|
|
||||||
rectHeight0: true
|
|
||||||
patternWidth0: true
|
|
||||||
patternHeight0: true
|
|
||||||
imageWidth0: true
|
|
||||||
imageHeight0: true
|
|
||||||
pathEmptyD: true
|
|
||||||
polylineEmptyPoints: true
|
|
||||||
polygonEmptyPoints: true
|
|
||||||
|
|
||||||
- name: removeEmptyText
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
text: true
|
|
||||||
tspan: true
|
|
||||||
tref: true
|
|
||||||
|
|
||||||
- name: moveElemsAttrsToGroup
|
|
||||||
active: true
|
|
||||||
type: perItemReverse
|
|
||||||
|
|
||||||
- name: collapseGroups
|
|
||||||
active: true
|
|
||||||
type: perItemReverse
|
|
||||||
|
|
||||||
- name: moveGroupAttrsToElems
|
|
||||||
active: true
|
|
||||||
type: perItemReverse
|
|
||||||
|
|
||||||
- name: convertPathData
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
applyTransforms: true
|
|
||||||
straightCurves: true
|
|
||||||
lineShorthands: true
|
|
||||||
curveSmoothShorthands: true
|
|
||||||
floatPrecision: 3
|
|
||||||
removeUseless: true
|
|
||||||
collapseRepeated: true
|
|
||||||
leadingZero: true
|
|
||||||
negativeExtraSpace: true
|
|
||||||
|
|
||||||
- name: convertTransform
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
params:
|
|
||||||
convertToShorts: true
|
|
||||||
floatPrecision: 3
|
|
||||||
matrixToTransform: true
|
|
||||||
shortTranslate: true
|
|
||||||
shortScale: true
|
|
||||||
shortRotate: true
|
|
||||||
removeUseless: true
|
|
||||||
collapseIntoOne: true
|
|
||||||
leadingZero: true
|
|
||||||
negativeExtraSpace: false
|
|
||||||
|
|
||||||
- name: removeEmptyAttrs
|
|
||||||
active: true
|
|
||||||
type: perItem
|
|
||||||
|
|
||||||
- name: removeEmptyContainers
|
|
||||||
active: true
|
|
||||||
type: perItemReverse
|
|
||||||
|
|
||||||
- name: cleanupIDs
|
|
||||||
active: true
|
|
||||||
type: full
|
|
||||||
params:
|
|
||||||
remove: true
|
|
||||||
minify: true
|
|
||||||
|
|
||||||
- name: removeUnusedNS
|
|
||||||
active: true
|
|
||||||
type: full
|
|
||||||
|
|
||||||
- name: cropAndCenterAlongPath
|
|
||||||
active: false
|
|
||||||
type: full
|
|
||||||
params:
|
|
||||||
hcrop: true
|
|
||||||
vcenter: true
|
|
||||||
floatPrecision: 3
|
|
||||||
leadingZero: true
|
|
||||||
negativeExtraSpace: true
|
|
||||||
|
|
||||||
svg2js:
|
|
||||||
|
|
||||||
strict: true
|
|
||||||
trim: true
|
|
||||||
normalize: true
|
|
||||||
lowercase: true
|
|
||||||
xmlns: true
|
|
||||||
position: false
|
|
||||||
|
|
||||||
js2svg:
|
|
||||||
|
|
||||||
doctypeStart: "<!DOCTYPE"
|
|
||||||
doctypeEnd: ">"
|
|
||||||
procInstStart: "<?"
|
|
||||||
procInstEnd: "?>"
|
|
||||||
tagOpenStart: "<"
|
|
||||||
tagOpenEnd: ">"
|
|
||||||
tagCloseStart: "</"
|
|
||||||
tagCloseEnd: ">"
|
|
||||||
tagShortStart: "<"
|
|
||||||
tagShortEnd: "/>"
|
|
||||||
attrStart: "=\""
|
|
||||||
attrEnd: "\""
|
|
||||||
commentStart: "<!--"
|
|
||||||
commentEnd: "-->"
|
|
||||||
cdataStart: "<![CDATA["
|
|
||||||
cdataEnd: "]]>"
|
|
||||||
textStart: ""
|
|
||||||
textEnd: ""
|
|
||||||
indent: " "
|
|
||||||
entities:
|
|
||||||
"&": "&"
|
|
||||||
"'": "'"
|
|
||||||
"\"": """
|
|
||||||
">": ">"
|
|
||||||
"<": "<"
|
|
||||||
pretty: false
|
|
||||||
|
110
lib/svgo.js
110
lib/svgo.js
@ -5,118 +5,32 @@
|
|||||||
*
|
*
|
||||||
* @see http://deepsweet.github.com/svgo/
|
* @see http://deepsweet.github.com/svgo/
|
||||||
*
|
*
|
||||||
* @module svgo
|
|
||||||
*
|
|
||||||
* @author Kir Belevich <kir@soulshine.in> (https://github.com/deepsweet)
|
* @author Kir Belevich <kir@soulshine.in> (https://github.com/deepsweet)
|
||||||
* @copyright © 2012 Kir Belevich
|
* @copyright © 2012 Kir Belevich
|
||||||
* @license MIT https://raw.github.com/deepsweet/svgo/master/LICENSE
|
* @license MIT https://raw.github.com/deepsweet/svgo/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var INHERIT = require('inherit'),
|
var CONFIG = require('./svgo/config'),
|
||||||
Q = require('q'),
|
|
||||||
FS = require('fs'),
|
|
||||||
CONFIG = require('./svgo/config'),
|
|
||||||
SVG2JS = require('./svgo/svg2js'),
|
SVG2JS = require('./svgo/svg2js'),
|
||||||
PLUGINS = require('./svgo/plugins'),
|
PLUGINS = require('./svgo/plugins'),
|
||||||
JS2SVG = require('./svgo/js2svg'),
|
JS2SVG = require('./svgo/js2svg');
|
||||||
decodeSVGDatauri = require('./svgo/tools').decodeSVGDatauri;
|
|
||||||
|
|
||||||
/**
|
var SVGO = module.exports = function(config) {
|
||||||
* @class SVGO.
|
|
||||||
*/
|
|
||||||
module.exports = INHERIT(/** @lends SVGO.prototype */{
|
|
||||||
|
|
||||||
/**
|
this.config = CONFIG(config);
|
||||||
* @param {Object} [config] custom config to extend default
|
|
||||||
*
|
|
||||||
* @constructs
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
__constructor: function(config) {
|
|
||||||
|
|
||||||
this.config = CONFIG(config);
|
};
|
||||||
|
|
||||||
},
|
SVGO.prototype.optimize = function(svgstr, callback) {
|
||||||
|
|
||||||
/**
|
var config = this.config;
|
||||||
* Optimize SVG data from string.
|
|
||||||
*
|
|
||||||
* @param {String} str input string
|
|
||||||
*
|
|
||||||
* @return {Object} output string deferred promise
|
|
||||||
*/
|
|
||||||
fromString: function(str) {
|
|
||||||
|
|
||||||
var startTime = Date.now();
|
SVG2JS(svgstr, function(svgjs) {
|
||||||
|
|
||||||
str = decodeSVGDatauri(str);
|
svgjs = PLUGINS(svgjs, config.plugins);
|
||||||
|
|
||||||
return this.config
|
callback(JS2SVG(svgjs, config.js2svg));
|
||||||
.then(function(config) {
|
|
||||||
|
|
||||||
return SVG2JS(str, config.svg2js)
|
});
|
||||||
.then(function(jsdata) {
|
|
||||||
|
|
||||||
var result = JS2SVG(PLUGINS(jsdata, config.plugins), config.js2svg);
|
};
|
||||||
|
|
||||||
result.info.inBytes = Buffer.byteLength(str, 'utf-8');
|
|
||||||
result.info.outBytes = Buffer.byteLength(result.data, 'utf-8');
|
|
||||||
|
|
||||||
result.info.time = Date.now() - startTime;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optimize SVG data from Stream.
|
|
||||||
*
|
|
||||||
* @param {Object} stream input stream
|
|
||||||
*
|
|
||||||
* @return {Object} output string deferred promise
|
|
||||||
*/
|
|
||||||
fromStream: function(stream) {
|
|
||||||
|
|
||||||
var deferred = Q.defer(),
|
|
||||||
inputData = '',
|
|
||||||
self = this;
|
|
||||||
|
|
||||||
stream.pause();
|
|
||||||
|
|
||||||
stream
|
|
||||||
.on('data', function(chunk) {
|
|
||||||
inputData += chunk;
|
|
||||||
})
|
|
||||||
.once('end', function() {
|
|
||||||
deferred.resolve(inputData);
|
|
||||||
})
|
|
||||||
.resume();
|
|
||||||
|
|
||||||
return deferred.promise
|
|
||||||
.then(function(str) {
|
|
||||||
|
|
||||||
return self.fromString(str);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optimize SVG data from file.
|
|
||||||
*
|
|
||||||
* @param {String} path file path
|
|
||||||
*
|
|
||||||
* @return {Object} output string deferred promise
|
|
||||||
*/
|
|
||||||
fromFile: function(path) {
|
|
||||||
|
|
||||||
return this.fromStream(FS.createReadStream(path, { encoding: 'utf8' }));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
256
lib/svgo/coa.js
256
lib/svgo/coa.js
@ -1,13 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('colors');
|
require('colors');
|
||||||
|
require('js-yaml');
|
||||||
|
|
||||||
var FS = require('fs'),
|
var FS = require('fs'),
|
||||||
QFS = require('q-fs'),
|
|
||||||
PATH = require('path'),
|
PATH = require('path'),
|
||||||
UTIL = require('util'),
|
UTIL = require('util'),
|
||||||
SVGO = require('../svgo'),
|
SVGO = require('../svgo'),
|
||||||
info = JSON.parse(require('fs').readFileSync(__dirname + '/../../package.json')),
|
PKG = require('../../package.json'),
|
||||||
encodeSVGDatauri = require('./tools').encodeSVGDatauri,
|
encodeSVGDatauri = require('./tools').encodeSVGDatauri,
|
||||||
regSVGFile = /\.svg$/;
|
regSVGFile = /\.svg$/;
|
||||||
|
|
||||||
@ -15,20 +15,18 @@ var FS = require('fs'),
|
|||||||
* Command-Option-Argument.
|
* Command-Option-Argument.
|
||||||
*
|
*
|
||||||
* @see https://github.com/veged/coa
|
* @see https://github.com/veged/coa
|
||||||
*
|
|
||||||
* @module coa
|
|
||||||
*/
|
*/
|
||||||
module.exports = require('coa').Cmd()
|
module.exports = require('coa').Cmd()
|
||||||
.helpful()
|
.helpful()
|
||||||
.name(info.name)
|
.name(PKG.name)
|
||||||
.title(info.description)
|
.title(PKG.description)
|
||||||
.opt()
|
.opt()
|
||||||
.name('version').title('Version')
|
.name('version').title('Version')
|
||||||
.short('v').long('version')
|
.short('v').long('version')
|
||||||
.only()
|
.only()
|
||||||
.flag()
|
.flag()
|
||||||
.act(function() {
|
.act(function() {
|
||||||
return info.version;
|
return PKG.version;
|
||||||
})
|
})
|
||||||
.end()
|
.end()
|
||||||
.opt()
|
.opt()
|
||||||
@ -99,109 +97,144 @@ module.exports = require('coa').Cmd()
|
|||||||
|
|
||||||
var input = args && args.input ? args.input : opts.input,
|
var input = args && args.input ? args.input : opts.input,
|
||||||
output = args && args.output ? args.output : opts.output,
|
output = args && args.output ? args.output : opts.output,
|
||||||
string = opts.string,
|
config;
|
||||||
folder = opts.folder,
|
|
||||||
svgo;
|
|
||||||
|
|
||||||
|
// w/o anything
|
||||||
if (
|
if (
|
||||||
(!input || input === '-') &&
|
(!input || input === '-') &&
|
||||||
!string &&
|
!opts.string &&
|
||||||
!opts.stdin &&
|
!opts.stdin &&
|
||||||
!opts.folder &&
|
!opts.folder &&
|
||||||
process.stdin.isTTY
|
process.stdin.isTTY
|
||||||
) return this.usage();
|
) return this.usage();
|
||||||
|
|
||||||
|
// --config
|
||||||
|
if (opts.config) {
|
||||||
|
|
||||||
|
// string
|
||||||
|
if (opts.config.charAt(0) === '{') {
|
||||||
|
config = JSON.parse(opts.config);
|
||||||
|
|
||||||
|
// external file
|
||||||
|
} else {
|
||||||
|
config = require(opts.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// --pretty
|
||||||
|
if (opts.pretty) {
|
||||||
|
|
||||||
|
config = config || {};
|
||||||
|
config.js2svg = config.js2svg || {};
|
||||||
|
config.js2svg.pretty = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// --folder
|
// --folder
|
||||||
if (folder) {
|
if (opts.folder) {
|
||||||
optimizeFolder(folder, opts);
|
optimizeFolder(opts.folder, config);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --string
|
// --inpput
|
||||||
if (string) {
|
if (input) {
|
||||||
svgo = new SVGO({ coa: opts }).fromString(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
// STDIN
|
// STDIN
|
||||||
else if (input === '-') {
|
if (input === '-') {
|
||||||
svgo = new SVGO({ coa: opts }).fromStream(process.stdin);
|
|
||||||
}
|
|
||||||
|
|
||||||
// file
|
var data = '';
|
||||||
else if (input) {
|
|
||||||
svgo = new SVGO({ coa: opts }).fromFile(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
return svgo.then(function(result) {
|
process.stdin.pause();
|
||||||
|
|
||||||
// --datauri
|
process.stdin
|
||||||
if (opts.datauri) {
|
.on('data', function(chunk) {
|
||||||
// convert to Data URI base64 string
|
data += chunk;
|
||||||
result.data = encodeSVGDatauri(result.data);
|
})
|
||||||
}
|
.once('end', function() {
|
||||||
|
optimizeFromString(data, config, input, output);
|
||||||
// stdout
|
})
|
||||||
if (output === '-' || (input === '-' && !output)) {
|
.resume();
|
||||||
process.stdout.write(result.data + '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
// file
|
// file
|
||||||
else {
|
} else {
|
||||||
|
|
||||||
// if input is from file - overwrite it
|
FS.readFile(input, 'utf8', function(err, data) {
|
||||||
if (!output && input) {
|
if (err) {
|
||||||
output = input;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
UTIL.puts('\r');
|
optimizeFromString(data, config, input, output);
|
||||||
saveFileAndPrintInfo(result, output, opts.pretty);
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
// --string
|
||||||
.done();
|
} else if (opts.string) {
|
||||||
|
|
||||||
|
optimizeFromString(opts.string, config, input, output);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
function optimizeFromString(svgstr, config, input, output) {
|
||||||
* Save file and print info.
|
|
||||||
*
|
|
||||||
* @param {Object} result SVGO result
|
|
||||||
* @param {String} output output filename
|
|
||||||
* @param {Boolean} pretty is pretty printed?
|
|
||||||
*/
|
|
||||||
function saveFileAndPrintInfo(result, output, pretty) {
|
|
||||||
|
|
||||||
// output file
|
var startTime = Date.now(config),
|
||||||
output = FS.createWriteStream(output, { encoding: 'utf8' });
|
time,
|
||||||
output.write(result.data);
|
inBytes = Buffer.byteLength(svgstr, 'utf8'),
|
||||||
output.end();
|
outBytes,
|
||||||
|
svgo = new SVGO(config);
|
||||||
|
|
||||||
// print time info
|
svgo.optimize(svgstr, function(result) {
|
||||||
printTimeInfo(result.info.time);
|
|
||||||
|
|
||||||
// print optimization profit info
|
outBytes = Buffer.byteLength(result.data, 'utf8');
|
||||||
printProfitInfo(result.info.inBytes, result.info.outBytes);
|
time = Date.now() - startTime;
|
||||||
|
|
||||||
|
// stdout
|
||||||
|
if (output === '-' || (input === '-' && !output)) {
|
||||||
|
|
||||||
|
process.stdout.write(result.data + '\n');
|
||||||
|
|
||||||
|
// file
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// overwrite input file if there is no output
|
||||||
|
if (!output && input) {
|
||||||
|
output = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
UTIL.puts('\r');
|
||||||
|
|
||||||
|
saveFileAndPrintInfo(result.data, output, inBytes, outBytes, time);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveFileAndPrintInfo(data, path, inBytes, outBytes, time) {
|
||||||
|
|
||||||
|
FS.writeFile(path, data, 'utf8', function() {
|
||||||
|
|
||||||
|
// print time info
|
||||||
|
printTimeInfo(time);
|
||||||
|
|
||||||
|
// print optimization profit info
|
||||||
|
printProfitInfo(inBytes, outBytes);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Print time info.
|
|
||||||
*
|
|
||||||
* @param {Number} time working time in ms
|
|
||||||
*/
|
|
||||||
function printTimeInfo(time) {
|
function printTimeInfo(time) {
|
||||||
|
|
||||||
UTIL.puts('Done in ' + time + ' ms!');
|
UTIL.puts('Done in ' + time + ' ms!');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Print optimization profit info.
|
|
||||||
*
|
|
||||||
* @param {Number} inBytes input file byteLength
|
|
||||||
* @param {Number} outBytes output file byteLength
|
|
||||||
*/
|
|
||||||
function printProfitInfo(inBytes, outBytes) {
|
function printProfitInfo(inBytes, outBytes) {
|
||||||
|
|
||||||
var profitPercents = 100 - outBytes * 100 / inBytes;
|
var profitPercents = 100 - outBytes * 100 / inBytes;
|
||||||
@ -215,55 +248,66 @@ function printProfitInfo(inBytes, outBytes) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function optimizeFolder(path, config) {
|
||||||
* Optimize all *.svg files in a specific folder.
|
|
||||||
*
|
|
||||||
* @param {String} folder folder path
|
|
||||||
* @param {Object} opts COA options
|
|
||||||
*/
|
|
||||||
function optimizeFolder(folder, opts) {
|
|
||||||
|
|
||||||
var svgo = new SVGO({ coa: opts });
|
var svgo = new SVGO(config);
|
||||||
|
|
||||||
folder = PATH.resolve(process.cwd(), folder);
|
// absoluted folder path
|
||||||
|
path = PATH.resolve(process.cwd(), path);
|
||||||
|
|
||||||
UTIL.puts('\n' + folder + ':\n');
|
UTIL.puts('\n' + path + ':\n');
|
||||||
|
|
||||||
// list directory
|
// list folder content
|
||||||
QFS.list(folder).then(function(list) {
|
FS.readdir(path, function(err, files) {
|
||||||
|
|
||||||
list.forEach(function(item) {
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
var filename = item;
|
files.forEach(function(filename) {
|
||||||
|
|
||||||
item = folder + '/' + item;
|
// absoluted file path
|
||||||
|
var filepath = PATH.resolve(path, filename);
|
||||||
|
|
||||||
// checkif item is a file
|
// check if file name matches *.svg
|
||||||
QFS.isFile(item)
|
if (regSVGFile.test(filepath)) {
|
||||||
.then(function(isFile) {
|
|
||||||
|
|
||||||
// and file name matches *.svg
|
FS.readFile(filepath, 'utf8', function(err, data) {
|
||||||
if (isFile && regSVGFile.test(item)) {
|
|
||||||
|
|
||||||
// then optimize it and output profit information
|
|
||||||
return svgo.fromFile(item)
|
|
||||||
.then(function(result) {
|
|
||||||
|
|
||||||
UTIL.puts(filename + ':');
|
|
||||||
saveFileAndPrintInfo(result, item, opts.pretty);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
var startTime = Date.now(),
|
||||||
.fail(function(e) {
|
time,
|
||||||
UTIL.puts(filename + ':\n' + String('Error! "' + e.message + '"').red + '\n');
|
inBytes = Buffer.byteLength(data, 'utf8'),
|
||||||
|
outBytes;
|
||||||
|
|
||||||
|
svgo.optimize(data, function(result) {
|
||||||
|
|
||||||
|
outBytes = Buffer.byteLength(result.data, 'utf8');
|
||||||
|
time = Date.now() - startTime;
|
||||||
|
|
||||||
|
FS.writeFile(filepath, result.data, 'utf8', function() {
|
||||||
|
|
||||||
|
UTIL.puts(filename + ':');
|
||||||
|
|
||||||
|
// print time info
|
||||||
|
printTimeInfo(time);
|
||||||
|
|
||||||
|
// print optimization profit info
|
||||||
|
printProfitInfo(inBytes, outBytes);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
});
|
||||||
.done();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,177 +1,166 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var QFS = require('q-fs'),
|
require('js-yaml');
|
||||||
PATH = require('path'),
|
|
||||||
YAML = require('js-yaml'),
|
var EXTEND = require('node.extend');
|
||||||
extend = require('./tools').extend,
|
|
||||||
defaultConfigPath = PATH.resolve(__dirname, '../../.svgo.yml');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read and/or extend default config file,
|
* Read and/or extend default config file,
|
||||||
* prepare and optimize plugins array.
|
* prepare and optimize plugins array.
|
||||||
*
|
*
|
||||||
* @module config
|
* @param {Object} [config] input config
|
||||||
*
|
* @return {Object} output config
|
||||||
* @param {Object} [params] config object to extend or coa params
|
|
||||||
*
|
|
||||||
* @return {Object} config deferred promise
|
|
||||||
*/
|
*/
|
||||||
module.exports = function(params) {
|
module.exports = function(config) {
|
||||||
|
|
||||||
return _getConfig(params).then(function(config) {
|
var defaults = require('../../.svgo.yml');
|
||||||
|
|
||||||
config.plugins = preparePluginsArray(config.plugins);
|
defaults.plugins = preparePluginsArray(defaults.plugins);
|
||||||
config.plugins = optimizePluginsArray(config.plugins);
|
|
||||||
|
|
||||||
return config;
|
if (config) {
|
||||||
|
defaults = extendConfig(defaults, config);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
defaults.plugins = optimizePluginsArray(defaults.plugins);
|
||||||
|
|
||||||
|
return defaults;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get default or extended config.
|
* Require() all plugins in array.
|
||||||
*
|
|
||||||
* @param {Object} [params] config object to extend or coa params
|
|
||||||
*
|
|
||||||
* @return {Object} default or extended config
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function _getConfig(params) {
|
|
||||||
|
|
||||||
// if there are no any params then return default config
|
|
||||||
if (!params) return readConfig(defaultConfigPath);
|
|
||||||
|
|
||||||
// COA params
|
|
||||||
if (params.coa) {
|
|
||||||
|
|
||||||
params = params.coa;
|
|
||||||
|
|
||||||
return readConfig(defaultConfigPath)
|
|
||||||
.then(function(defaultConfig) {
|
|
||||||
|
|
||||||
// --pretty
|
|
||||||
if (params.pretty) defaultConfig.js2svg.pretty = true;
|
|
||||||
|
|
||||||
// --disable
|
|
||||||
if (params.disable) return changePluginsState(params.disable, false, defaultConfig);
|
|
||||||
|
|
||||||
// --enable
|
|
||||||
if (params.enable) return changePluginsState(params.enable, true, defaultConfig);
|
|
||||||
|
|
||||||
// --config
|
|
||||||
if (params.config) {
|
|
||||||
|
|
||||||
var localConfigPath = PATH.resolve(process.cwd, params.config);
|
|
||||||
|
|
||||||
// check for the local config file
|
|
||||||
return QFS.exists(localConfigPath)
|
|
||||||
.then(function(exist) {
|
|
||||||
|
|
||||||
// if it doesn't exists then return default
|
|
||||||
if (!exist) return defaultConfig;
|
|
||||||
|
|
||||||
// if it exists then return extended default
|
|
||||||
return readConfig(localConfigPath);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultConfig;
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// inline {} params
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// return extended default
|
|
||||||
return readConfig(defaultConfigPath)
|
|
||||||
.then(function(defaultConfig) {
|
|
||||||
|
|
||||||
return extend(true, defaultConfig, params);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read and YAML.parse config file by path.
|
|
||||||
*
|
|
||||||
* @param {String} path config path
|
|
||||||
*
|
|
||||||
* @return {Object} read config deferred promise
|
|
||||||
*/
|
|
||||||
function readConfig(path) {
|
|
||||||
|
|
||||||
return QFS.read(path)
|
|
||||||
.then(function(data) {
|
|
||||||
return YAML.load(data.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Require() all plugins in array and convert it to array of arrays.
|
|
||||||
*
|
*
|
||||||
* @param {Array} plugins input plugins array
|
* @param {Array} plugins input plugins array
|
||||||
*
|
|
||||||
* @return {Array} input plugins array of arrays
|
* @return {Array} input plugins array of arrays
|
||||||
*/
|
*/
|
||||||
function preparePluginsArray(plugins) {
|
function preparePluginsArray(plugins) {
|
||||||
|
|
||||||
return plugins.map(function(plugin) {
|
var plugin,
|
||||||
plugin.fn = require('../../plugins/' + plugin.name)[plugin.name];
|
key;
|
||||||
|
|
||||||
|
return plugins.map(function(item) {
|
||||||
|
|
||||||
|
// {}
|
||||||
|
if (typeof item === 'object') {
|
||||||
|
|
||||||
|
key = Object.keys(item)[0];
|
||||||
|
plugin = require('../../plugins/' + key);
|
||||||
|
|
||||||
|
// name: {}
|
||||||
|
if (typeof item[key] === 'object') {
|
||||||
|
plugin.params = EXTEND(plugin.params || {}, item[key]);
|
||||||
|
|
||||||
|
// name: false
|
||||||
|
} else if (item[key] === false) {
|
||||||
|
plugin.active = false;
|
||||||
|
|
||||||
|
// name: true
|
||||||
|
} else if (item[key] === true) {
|
||||||
|
plugin.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.name = key;
|
||||||
|
|
||||||
|
// name
|
||||||
|
} else {
|
||||||
|
|
||||||
|
plugin = require('../../plugins/' + item);
|
||||||
|
plugin.name = item;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
|
||||||
return [plugin];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend plugins with the custom config object.
|
||||||
|
*
|
||||||
|
* @param {Array} plugins input plugins
|
||||||
|
* @param {Object} config config
|
||||||
|
* @return {Array} output plugins
|
||||||
|
*/
|
||||||
|
function extendConfig(defaults, config) {
|
||||||
|
|
||||||
|
var key;
|
||||||
|
|
||||||
|
// plugins
|
||||||
|
if (config.plugins) {
|
||||||
|
|
||||||
|
config.plugins.forEach(function(item) {
|
||||||
|
|
||||||
|
// {}
|
||||||
|
if (typeof item === 'object') {
|
||||||
|
|
||||||
|
key = Object.keys(item)[0];
|
||||||
|
|
||||||
|
defaults.plugins.forEach(function(plugin) {
|
||||||
|
|
||||||
|
if (plugin.name === key) {
|
||||||
|
// name: {}
|
||||||
|
if (typeof item[key] === 'object') {
|
||||||
|
plugin.params = EXTEND(plugin.params || {}, item[key]);
|
||||||
|
plugin.active = true;
|
||||||
|
|
||||||
|
// name: false
|
||||||
|
} else if (item[key] === false) {
|
||||||
|
plugin.active = false;
|
||||||
|
|
||||||
|
// name: true
|
||||||
|
} else if (item[key] === true) {
|
||||||
|
plugin.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// svg2js
|
||||||
|
if (config.svg2js) {
|
||||||
|
defaults.svg2js = config.svg2js;
|
||||||
|
}
|
||||||
|
|
||||||
|
// js2svg
|
||||||
|
if (config.js2svg) {
|
||||||
|
defaults.js2svg = config.js2svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaults;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to group sequential elements of plugins array.
|
* Try to group sequential elements of plugins array.
|
||||||
*
|
*
|
||||||
* @param {Object} plugins input plugins array
|
* @param {Object} plugins input plugins
|
||||||
*
|
* @return {Array} output plugins
|
||||||
* @return {Array} output plugins array
|
|
||||||
*/
|
*/
|
||||||
function optimizePluginsArray(plugins) {
|
function optimizePluginsArray(plugins) {
|
||||||
|
|
||||||
var prev;
|
var prev;
|
||||||
|
|
||||||
plugins = plugins.filter(function(item) {
|
plugins = plugins.map(function(item) {
|
||||||
|
return [item];
|
||||||
|
});
|
||||||
|
|
||||||
|
return plugins.filter(function(item) {
|
||||||
|
|
||||||
if (prev && item[0].type === prev[0].type) {
|
if (prev && item[0].type === prev[0].type) {
|
||||||
prev.push(item[0]);
|
prev.push(item[0]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = item;
|
prev = item;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return plugins;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change plugins state by names array.
|
|
||||||
*
|
|
||||||
* @param {Array} names plugins names
|
|
||||||
* @param {Boolean} state active state
|
|
||||||
* @param {Object} config original config
|
|
||||||
*
|
|
||||||
* @return {Object} changed config
|
|
||||||
*/
|
|
||||||
function changePluginsState(names, state, config) {
|
|
||||||
|
|
||||||
config.plugins.forEach(function(plugin) {
|
|
||||||
if (names.indexOf(plugin.name) > -1) {
|
|
||||||
plugin.active = state;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return config;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,282 +1,290 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var INHERIT = require('inherit'),
|
var EXTEND = require('./tools').extend;
|
||||||
extend = require('./tools').extend;
|
|
||||||
|
var defaults = {
|
||||||
|
doctypeStart: '<!DOCTYPE',
|
||||||
|
doctypeEnd: '>',
|
||||||
|
procInstStart: '<?',
|
||||||
|
procInstEnd: '?>',
|
||||||
|
tagOpenStart: '<',
|
||||||
|
tagOpenEnd: '>',
|
||||||
|
tagCloseStart: '</',
|
||||||
|
tagCloseEnd: '>',
|
||||||
|
tagShortStart: '<',
|
||||||
|
tagShortEnd: '/>',
|
||||||
|
attrStart: '="',
|
||||||
|
attrEnd: '"',
|
||||||
|
commentStart: '<!--',
|
||||||
|
commentEnd: '-->',
|
||||||
|
cdataStart: '<![CDATA[',
|
||||||
|
cdataEnd: ']]>',
|
||||||
|
textStart: '',
|
||||||
|
textEnd: '',
|
||||||
|
indent: ' ',
|
||||||
|
entities: {
|
||||||
|
'&': '&',
|
||||||
|
'\'': ''',
|
||||||
|
'"': '"',
|
||||||
|
'>': '>',
|
||||||
|
'<': '<',
|
||||||
|
},
|
||||||
|
pretty: false
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert SVG-as-JS object to SVG (XML) string.
|
* Convert SVG-as-JS object to SVG (XML) string.
|
||||||
*
|
*
|
||||||
* @module js2svg
|
* @param {Object} data input data
|
||||||
*
|
|
||||||
* @param {Object} jsdata input data
|
|
||||||
* @param {Object} config config
|
* @param {Object} config config
|
||||||
*
|
*
|
||||||
* @return {Object} output data
|
* @return {Object} output data
|
||||||
*/
|
*/
|
||||||
module.exports = function(jsdata, config) {
|
module.exports = function(data, config) {
|
||||||
|
|
||||||
return new Converter(config).run(jsdata);
|
return new JS2SVG(config).convert(data);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function JS2SVG(config) {
|
||||||
|
|
||||||
|
if (config) {
|
||||||
|
this.config = EXTEND(true, {}, defaults, config);
|
||||||
|
} else {
|
||||||
|
this.config = defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.config.pretty) {
|
||||||
|
this.config.doctypeEnd += '\n';
|
||||||
|
this.config.procInstEnd += '\n';
|
||||||
|
this.config.commentEnd += '\n';
|
||||||
|
this.config.cdataEnd += '\n';
|
||||||
|
this.config.tagShortEnd += '\n';
|
||||||
|
this.config.tagOpenEnd += '\n';
|
||||||
|
this.config.tagCloseEnd += '\n';
|
||||||
|
this.config.textEnd += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.indentLevel = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start conversion.
|
||||||
|
*
|
||||||
|
* @param {Object} data input data
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.convert = function(data) {
|
||||||
|
|
||||||
|
var svg = '';
|
||||||
|
|
||||||
|
if (data.content) {
|
||||||
|
|
||||||
|
this.indentLevel++;
|
||||||
|
|
||||||
|
data.content.forEach(function(item) {
|
||||||
|
|
||||||
|
if (item.elem) {
|
||||||
|
svg += this.createElem(item);
|
||||||
|
} else if (item.text) {
|
||||||
|
svg += this.createText(item.text);
|
||||||
|
} else if (item.doctype) {
|
||||||
|
svg += this.createDoctype(item.doctype);
|
||||||
|
} else if (item.processinginstruction) {
|
||||||
|
svg += this.createProcInst(item.processinginstruction);
|
||||||
|
} else if (item.comment) {
|
||||||
|
svg += this.createComment(item.comment);
|
||||||
|
} else if (item.cdata) {
|
||||||
|
svg += this.createCDATA(item.cdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.indentLevel--;
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: svg,
|
||||||
|
info: {
|
||||||
|
width: this.width,
|
||||||
|
height: this.height
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Converter
|
* Create indent string in accordance with the current node level.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
*/
|
*/
|
||||||
var Converter = INHERIT(/** @lends Nodes.prototype */{
|
JS2SVG.prototype.createIndent = function() {
|
||||||
|
|
||||||
/**
|
var indent = '';
|
||||||
* @constructs
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
__constructor: function(config) {
|
|
||||||
|
|
||||||
/**
|
if (this.config.pretty) {
|
||||||
* Shallow copy of converter config.
|
for (var i = 1; i < this.indentLevel; i++) {
|
||||||
*
|
indent += this.config.indent;
|
||||||
* @type {Object}
|
|
||||||
*/
|
|
||||||
this.config = extend({}, config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Current indent level hack.
|
|
||||||
*
|
|
||||||
* @type {Number}
|
|
||||||
*/
|
|
||||||
this.indentLevel = 0;
|
|
||||||
|
|
||||||
// pretty
|
|
||||||
if (this.config.pretty) {
|
|
||||||
this.config.doctypeEnd += '\n';
|
|
||||||
this.config.procInstEnd += '\n';
|
|
||||||
this.config.commentEnd += '\n';
|
|
||||||
this.config.cdataEnd += '\n';
|
|
||||||
this.config.tagShortEnd += '\n';
|
|
||||||
this.config.tagOpenEnd += '\n';
|
|
||||||
this.config.tagCloseEnd += '\n';
|
|
||||||
this.config.textEnd += '\n';
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
return indent;
|
||||||
|
|
||||||
/**
|
};
|
||||||
* Start conversion.
|
|
||||||
*
|
|
||||||
* @param {Object} svg-as-js data object
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
run: function(data) {
|
|
||||||
|
|
||||||
var svg = '';
|
/**
|
||||||
|
* Create doctype tag.
|
||||||
|
*
|
||||||
|
* @param {String} doctype doctype body string
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.createDoctype = function(doctype) {
|
||||||
|
|
||||||
if (data.content) {
|
return this.config.doctypeStart +
|
||||||
|
doctype +
|
||||||
|
this.config.doctypeEnd;
|
||||||
|
|
||||||
this.indentLevel++;
|
};
|
||||||
|
|
||||||
data.content.forEach(function(item) {
|
/**
|
||||||
|
* Create XML Processing Instruction tag.
|
||||||
|
*
|
||||||
|
* @param {Object} instruction instruction object
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.createProcInst = function(instruction) {
|
||||||
|
|
||||||
if (item.elem) {
|
return this.config.procInstStart +
|
||||||
svg += this.createElem(item);
|
instruction.name +
|
||||||
} else if (item.text) {
|
' ' +
|
||||||
svg += this.createText(item.text);
|
instruction.body +
|
||||||
} else if (item.doctype) {
|
this.config.procInstEnd;
|
||||||
svg += this.createDoctype(item.doctype);
|
|
||||||
} else if (item.processinginstruction) {
|
|
||||||
svg += this.createProcInst(item.processinginstruction);
|
|
||||||
} else if (item.comment) {
|
|
||||||
svg += this.createComment(item.comment);
|
|
||||||
} else if (item.cdata) {
|
|
||||||
svg += this.createCDATA(item.cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, this);
|
};
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Create comment tag.
|
||||||
|
*
|
||||||
|
* @param {String} comment comment body
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.createComment = function(comment) {
|
||||||
|
|
||||||
this.indentLevel--;
|
return this.config.commentStart +
|
||||||
|
comment +
|
||||||
|
this.config.commentEnd;
|
||||||
|
|
||||||
return {
|
};
|
||||||
data: svg,
|
|
||||||
info: {
|
|
||||||
width: this.width,
|
|
||||||
height: this.height
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
},
|
/**
|
||||||
|
* Create CDATA section.
|
||||||
|
*
|
||||||
|
* @param {String} cdata CDATA body
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.createCDATA = function(cdata) {
|
||||||
|
|
||||||
/**
|
return this.config.cdataStart +
|
||||||
* Create indent string in accordance with the current node level.
|
cdata +
|
||||||
*
|
this.config.cdataEnd;
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createIndent: function() {
|
|
||||||
|
|
||||||
var indent = '';
|
};
|
||||||
|
|
||||||
if (this.config.pretty) {
|
/**
|
||||||
for (var i = 1; i < this.indentLevel; i++) {
|
* Create element tag.
|
||||||
indent += this.config.indent;
|
*
|
||||||
}
|
* @param {Object} data element object
|
||||||
}
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.createElem = function(data) {
|
||||||
|
|
||||||
return indent;
|
// beautiful injection for obtaining SVG information :)
|
||||||
|
if (
|
||||||
|
data.isElem('svg') &&
|
||||||
|
data.hasAttr('width') &&
|
||||||
|
data.hasAttr('height')
|
||||||
|
) {
|
||||||
|
this.width = data.attr('width').value;
|
||||||
|
this.height = data.attr('height').value;
|
||||||
|
}
|
||||||
|
|
||||||
},
|
// empty element and short tag
|
||||||
|
if (data.isEmpty()) {
|
||||||
/**
|
|
||||||
* Create doctype tag.
|
|
||||||
*
|
|
||||||
* @param {String} doctype doctype body string
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createDoctype: function(doctype) {
|
|
||||||
|
|
||||||
return this.config.doctypeStart +
|
|
||||||
doctype +
|
|
||||||
this.config.doctypeEnd;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create XML Processing Instruction tag.
|
|
||||||
*
|
|
||||||
* @param {Object} instruction instruction object
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createProcInst: function(instruction) {
|
|
||||||
|
|
||||||
return this.config.procInstStart +
|
|
||||||
instruction.name +
|
|
||||||
' ' +
|
|
||||||
instruction.body +
|
|
||||||
this.config.procInstEnd;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create comment tag.
|
|
||||||
*
|
|
||||||
* @param {String} comment comment body
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createComment: function(comment) {
|
|
||||||
|
|
||||||
return this.config.commentStart +
|
|
||||||
comment +
|
|
||||||
this.config.commentEnd;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create CDATA section.
|
|
||||||
*
|
|
||||||
* @param {String} cdata CDATA body
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createCDATA: function(cdata) {
|
|
||||||
|
|
||||||
return this.config.cdataStart +
|
|
||||||
cdata +
|
|
||||||
this.config.cdataEnd;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create element tag.
|
|
||||||
*
|
|
||||||
* @param {Object} data element object
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createElem: function(data) {
|
|
||||||
|
|
||||||
// beautiful injection for obtaining SVG information :)
|
|
||||||
if (
|
|
||||||
data.isElem('svg') &&
|
|
||||||
data.hasAttr('width') &&
|
|
||||||
data.hasAttr('height')
|
|
||||||
) {
|
|
||||||
this.width = data.attr('width').value;
|
|
||||||
this.height = data.attr('height').value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// empty element and short tag
|
|
||||||
if (data.isEmpty()) {
|
|
||||||
|
|
||||||
return this.createIndent() +
|
|
||||||
this.config.tagShortStart +
|
|
||||||
data.elem +
|
|
||||||
this.createAttrs(data) +
|
|
||||||
this.config.tagShortEnd;
|
|
||||||
|
|
||||||
// non-empty element
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return this.createIndent() +
|
|
||||||
this.config.tagOpenStart +
|
|
||||||
data.elem +
|
|
||||||
this.createAttrs(data) +
|
|
||||||
this.config.tagOpenEnd +
|
|
||||||
this.run(data).data +
|
|
||||||
this.createIndent() +
|
|
||||||
this.config.tagCloseStart +
|
|
||||||
data.elem +
|
|
||||||
this.config.tagCloseEnd;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create element attributes.
|
|
||||||
*
|
|
||||||
* @param {Object} elem attributes object
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createAttrs: function(elem) {
|
|
||||||
|
|
||||||
var attrs = '';
|
|
||||||
|
|
||||||
elem.eachAttr(function(attr) {
|
|
||||||
|
|
||||||
attrs += ' ' +
|
|
||||||
attr.name +
|
|
||||||
this.config.attrStart +
|
|
||||||
attr.value +
|
|
||||||
this.config.attrEnd;
|
|
||||||
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
return attrs;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create text node.
|
|
||||||
*
|
|
||||||
* @param {String} text text
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
*/
|
|
||||||
createText: function(text) {
|
|
||||||
|
|
||||||
// convert entities back
|
|
||||||
for (var entity in this.config.entities) {
|
|
||||||
text = text.split(entity).join(this.config.entities[entity]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.createIndent() +
|
return this.createIndent() +
|
||||||
this.config.textStart +
|
this.config.tagShortStart +
|
||||||
text +
|
data.elem +
|
||||||
this.config.textEnd;
|
this.createAttrs(data) +
|
||||||
|
this.config.tagShortEnd;
|
||||||
|
|
||||||
|
// non-empty element
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return this.createIndent() +
|
||||||
|
this.config.tagOpenStart +
|
||||||
|
data.elem +
|
||||||
|
this.createAttrs(data) +
|
||||||
|
this.config.tagOpenEnd +
|
||||||
|
this.convert(data).data +
|
||||||
|
this.createIndent() +
|
||||||
|
this.config.tagCloseStart +
|
||||||
|
data.elem +
|
||||||
|
this.config.tagCloseEnd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create element attributes.
|
||||||
|
*
|
||||||
|
* @param {Object} elem attributes object
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.createAttrs = function(elem) {
|
||||||
|
|
||||||
|
var attrs = '';
|
||||||
|
|
||||||
|
elem.eachAttr(function(attr) {
|
||||||
|
|
||||||
|
attrs += ' ' +
|
||||||
|
attr.name +
|
||||||
|
this.config.attrStart +
|
||||||
|
attr.value +
|
||||||
|
this.config.attrEnd;
|
||||||
|
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
return attrs;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create text node.
|
||||||
|
*
|
||||||
|
* @param {String} text text
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
JS2SVG.prototype.createText = function(text) {
|
||||||
|
|
||||||
|
// convert entities back
|
||||||
|
for (var entity in this.config.entities) {
|
||||||
|
text = text.split(entity).join(this.config.entities[entity]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createIndent() +
|
||||||
|
this.config.textStart +
|
||||||
|
text +
|
||||||
|
this.config.textEnd;
|
||||||
|
|
||||||
|
};
|
||||||
|
@ -1,159 +1,139 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var INHERIT = require('inherit'),
|
var EXTEND = require('node.extend');
|
||||||
extend = require('./tools').extend;
|
|
||||||
|
var JSAPI = module.exports = function(data) {
|
||||||
|
|
||||||
|
EXTEND(this, data);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @module jsAPI
|
* Determine if item is an element
|
||||||
|
* (any, with a specific name or in a names array).
|
||||||
*
|
*
|
||||||
* @class SVG-as-JS Nodes API.
|
* @param {String|Array} [param] element name or names arrays
|
||||||
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
module.exports = INHERIT(/** @lends Nodes.prototype */{
|
JSAPI.prototype.isElem = function(param) {
|
||||||
|
|
||||||
/**
|
if (!param) return !!this.elem;
|
||||||
* @constructs
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
__constructor: function(data) {
|
|
||||||
|
|
||||||
extend(this, data);
|
if (Array.isArray(param)) return !!this.elem && (param.indexOf(this.elem) > -1);
|
||||||
|
|
||||||
},
|
return !!this.elem && this.elem === param;
|
||||||
|
|
||||||
/**
|
};
|
||||||
* Determine if item is an element
|
|
||||||
* (any, with a specific name or in a names array).
|
|
||||||
*
|
|
||||||
* @param {String|Array} [param] element name or names arrays
|
|
||||||
*
|
|
||||||
* @return {Boolean}
|
|
||||||
*/
|
|
||||||
isElem: function(param) {
|
|
||||||
|
|
||||||
if (!param) return !!this.elem;
|
/**
|
||||||
|
* Determine if element is empty.
|
||||||
|
*
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
JSAPI.prototype.isEmpty = function() {
|
||||||
|
|
||||||
if (Array.isArray(param)) return !!this.elem && (param.indexOf(this.elem) > -1);
|
return !this.content || !this.content.length;
|
||||||
|
|
||||||
return !!this.elem && this.elem === param;
|
};
|
||||||
|
|
||||||
},
|
/**
|
||||||
|
* Determine if element has an attribute
|
||||||
|
* (any, or by name or by name + value).
|
||||||
|
*
|
||||||
|
* @param {String} [name] attribute name
|
||||||
|
* @param {String} [val] attribute value (will be toString()'ed)
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
JSAPI.prototype.hasAttr = function(name, val) {
|
||||||
|
|
||||||
/**
|
if (!this.attrs || !Object.keys(this.attrs).length) return false;
|
||||||
* Determine if element is empty.
|
|
||||||
*
|
|
||||||
* @return {Boolean}
|
|
||||||
*/
|
|
||||||
isEmpty: function() {
|
|
||||||
|
|
||||||
return !this.content || !this.content.length;
|
if (!arguments.length) return !!this.attrs;
|
||||||
|
|
||||||
},
|
if (val !== undefined) return !!this.attrs[name] && this.attrs[name].value === val.toString();
|
||||||
|
|
||||||
/**
|
return !!this.attrs[name];
|
||||||
* Determine if element has an attribute
|
|
||||||
* (any, or by name or by name + value).
|
|
||||||
*
|
|
||||||
* @param {String} [name] attribute name
|
|
||||||
* @param {String} [val] attribute value (will be toString()'ed)
|
|
||||||
*
|
|
||||||
* @return {Boolean}
|
|
||||||
*/
|
|
||||||
hasAttr: function(name, val) {
|
|
||||||
|
|
||||||
if (!this.attrs || !Object.keys(this.attrs).length) return false;
|
};
|
||||||
|
|
||||||
if (!arguments.length) return !!this.attrs;
|
/**
|
||||||
|
* Get a specific attribute from an element
|
||||||
|
* (by name or name + value).
|
||||||
|
*
|
||||||
|
* @param {String} name attribute name
|
||||||
|
* @param {String} [val] attribute value (will be toString()'ed)
|
||||||
|
* @return {Object|Undefined}
|
||||||
|
*/
|
||||||
|
JSAPI.prototype.attr = function(name, val) {
|
||||||
|
|
||||||
if (val !== undefined) return !!this.attrs[name] && this.attrs[name].value === val.toString();
|
if (!this.hasAttr() || !arguments.length) return undefined;
|
||||||
|
|
||||||
return !!this.attrs[name];
|
if (val !== undefined) return this.hasAttr(name, val) ? this.attrs[name] : undefined;
|
||||||
|
|
||||||
},
|
return this.attrs[name];
|
||||||
|
|
||||||
/**
|
};
|
||||||
* Get a specific attribute from an element
|
|
||||||
* (by name or name + value).
|
|
||||||
*
|
|
||||||
* @param {String} name attribute name
|
|
||||||
* @param {String} [val] attribute value (will be toString()'ed)
|
|
||||||
*
|
|
||||||
* @return {Object|Undefined}
|
|
||||||
*/
|
|
||||||
attr: function(name, val) {
|
|
||||||
|
|
||||||
if (!this.hasAttr() || !arguments.length) return undefined;
|
/**
|
||||||
|
* Remove a specific attribute.
|
||||||
|
*
|
||||||
|
* @param {String} name attribute name
|
||||||
|
* @param {String} [val] attribute value
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
JSAPI.prototype.removeAttr = function(name, val) {
|
||||||
|
|
||||||
if (val !== undefined) return this.hasAttr(name, val) ? this.attrs[name] : undefined;
|
if (!arguments.length) return false;
|
||||||
|
|
||||||
return this.attrs[name];
|
if (!this.hasAttr(name)) return false;
|
||||||
|
|
||||||
},
|
if (val && this.attrs[name].value !== val) return false;
|
||||||
|
|
||||||
/**
|
delete this.attrs[name];
|
||||||
* Remove a specific attribute.
|
|
||||||
*
|
|
||||||
* @param {String} name attribute name
|
|
||||||
* @param {String} [val] attribute value
|
|
||||||
*
|
|
||||||
* @return {Boolean}
|
|
||||||
*/
|
|
||||||
removeAttr: function(name, val) {
|
|
||||||
|
|
||||||
if (!arguments.length) return false;
|
if (!Object.keys(this.attrs).length) delete this.attrs;
|
||||||
|
|
||||||
if (!this.hasAttr(name)) return false;
|
return true;
|
||||||
|
|
||||||
if (val && this.attrs[name].value !== val) return false;
|
};
|
||||||
|
|
||||||
delete this.attrs[name];
|
/**
|
||||||
|
* Add attribute.
|
||||||
|
*
|
||||||
|
* @param {Object} attr attribute object
|
||||||
|
* @return {Object} created attribute
|
||||||
|
*/
|
||||||
|
JSAPI.prototype.addAttr = function(attr) {
|
||||||
|
|
||||||
if (!Object.keys(this.attrs).length) delete this.attrs;
|
if (!attr ||
|
||||||
|
(attr && attr.name === undefined) ||
|
||||||
|
(attr && attr.value === undefined) ||
|
||||||
|
(attr && attr.prefix === undefined) ||
|
||||||
|
(attr && attr.local === undefined)
|
||||||
|
) return false;
|
||||||
|
|
||||||
return true;
|
this.attrs = this.attrs || {};
|
||||||
|
this.attrs[attr.name] = attr;
|
||||||
|
|
||||||
},
|
return this.attrs[attr.name];
|
||||||
|
|
||||||
/**
|
};
|
||||||
* Add attribute.
|
|
||||||
*
|
|
||||||
* @param {Object} attr attribute object
|
|
||||||
*
|
|
||||||
* @return {Object} created attribute
|
|
||||||
*/
|
|
||||||
addAttr: function(attr) {
|
|
||||||
|
|
||||||
if (!attr ||
|
/**
|
||||||
(attr && attr.name === undefined) ||
|
* Iterates over all attributes.
|
||||||
(attr && attr.value === undefined) ||
|
*
|
||||||
(attr && attr.prefix === undefined) ||
|
* @param {Function} callback callback
|
||||||
(attr && attr.local === undefined)
|
* @param {Object} [context] callback context
|
||||||
) return false;
|
* @return {Boolean} false if there are no any attributes
|
||||||
|
*/
|
||||||
|
JSAPI.prototype.eachAttr = function(callback, context) {
|
||||||
|
|
||||||
this.attrs = this.attrs || {};
|
if (!this.hasAttr()) return false;
|
||||||
|
|
||||||
return (this.attrs[attr.name] = attr);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over all attributes.
|
|
||||||
*
|
|
||||||
* @param {Function} callback callback
|
|
||||||
* @param {Object} [context] callback context
|
|
||||||
*
|
|
||||||
* @return {Boolean} false if there are no any attributes
|
|
||||||
*/
|
|
||||||
eachAttr: function(callback, context) {
|
|
||||||
|
|
||||||
if (!this.hasAttr()) return false;
|
|
||||||
|
|
||||||
for (var name in this.attrs) {
|
|
||||||
callback.call(context, this.attrs[name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
for (var name in this.attrs) {
|
||||||
|
callback.call(context, this.attrs[name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
return true;
|
||||||
|
|
||||||
|
};
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
*
|
*
|
||||||
* @param {Object} data input data
|
* @param {Object} data input data
|
||||||
* @param {Object} plugins plugins object from config
|
* @param {Object} plugins plugins object from config
|
||||||
*
|
|
||||||
* @return {Object} output data
|
* @return {Object} output data
|
||||||
*/
|
*/
|
||||||
module.exports = function(data, plugins) {
|
module.exports = function(data, plugins) {
|
||||||
@ -38,7 +37,6 @@ module.exports = function(data, plugins) {
|
|||||||
* @param {Object} data input data
|
* @param {Object} data input data
|
||||||
* @param {Array} plugins plugins list to process
|
* @param {Array} plugins plugins list to process
|
||||||
* @param {Boolean} [reverse] reverse pass?
|
* @param {Boolean} [reverse] reverse pass?
|
||||||
*
|
|
||||||
* @return {Object} output data
|
* @return {Object} output data
|
||||||
*/
|
*/
|
||||||
function perItem(data, plugins, reverse) {
|
function perItem(data, plugins, reverse) {
|
||||||
@ -89,7 +87,6 @@ function perItem(data, plugins, reverse) {
|
|||||||
*
|
*
|
||||||
* @param {Object} data input data
|
* @param {Object} data input data
|
||||||
* @param {Array} plugins plugins list to process
|
* @param {Array} plugins plugins list to process
|
||||||
*
|
|
||||||
* @return {Object} output data
|
* @return {Object} output data
|
||||||
*/
|
*/
|
||||||
function full(data, plugins) {
|
function full(data, plugins) {
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var Q = require('q'),
|
var SAX = require('sax'),
|
||||||
SAX = require('sax'),
|
|
||||||
JSAPI = require('./jsAPI');
|
JSAPI = require('./jsAPI');
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
strict: true,
|
||||||
|
trim: true,
|
||||||
|
normalize: true,
|
||||||
|
lowercase: true,
|
||||||
|
xmlns: true,
|
||||||
|
position: false
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert SVG (XML) string to SVG-as-JS object.
|
* Convert SVG (XML) string to SVG-as-JS object.
|
||||||
*
|
*
|
||||||
* @module svg2js
|
* @param {String} data input data
|
||||||
*
|
* @param {Function} callback
|
||||||
* @param {String} svg input data
|
|
||||||
* @param {Object} config sax xml parser config
|
|
||||||
*
|
|
||||||
* @return {Object} output data deferred promise
|
|
||||||
*/
|
*/
|
||||||
module.exports = function(svg, config) {
|
module.exports = function(data, callback) {
|
||||||
|
|
||||||
var deferred = Q.defer(),
|
var sax = SAX.parser(config.strict, config),
|
||||||
sax = SAX.parser(config.strict, config),
|
|
||||||
root = {},
|
root = {},
|
||||||
current = root,
|
current = root,
|
||||||
stack = [];
|
stack = [];
|
||||||
@ -109,23 +112,21 @@ module.exports = function(svg, config) {
|
|||||||
|
|
||||||
sax.onerror = function(e) {
|
sax.onerror = function(e) {
|
||||||
|
|
||||||
deferred.reject(new Error('svg2js: ' + e.message));
|
|
||||||
|
|
||||||
// https://github.com/isaacs/sax-js#events
|
// https://github.com/isaacs/sax-js#events
|
||||||
// "The error will be hanging out on parser.error,
|
// "The error will be hanging out on parser.error,
|
||||||
// and must be deleted before parsing can continue"
|
// and must be deleted before parsing can continue"
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
|
throw new Error('svg2js: ' + e.message);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sax.onend = function() {
|
sax.onend = function() {
|
||||||
|
|
||||||
deferred.resolve(root);
|
callback(root);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sax.write(svg).close();
|
sax.write(data).close();
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
11
package.json
11
package.json
@ -32,25 +32,20 @@
|
|||||||
"example": "./examples"
|
"example": "./examples"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "./node_modules/.bin/mocha --reporter spec --recursive",
|
"test": "./node_modules/.bin/mocha --reporter spec test/plugins test/svg2js",
|
||||||
"cover": "./node_modules/.bin/istanbul instrument --output lib-cov --no-compact --variable global.__coverage__ lib && ./node_modules/.bin/mocha --reporter mocha-istanbul --recursive",
|
"cover": "./node_modules/.bin/istanbul instrument --output lib-cov --no-compact --variable global.__coverage__ lib && ./node_modules/.bin/mocha --reporter mocha-istanbul --recursive",
|
||||||
"jshint": "jshint --show-non-errors ."
|
"jshint": "jshint --show-non-errors ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sax": "~0.5.0",
|
"sax": "~0.5.0",
|
||||||
"q": "~0.8.10",
|
|
||||||
"q-fs": "~0.1.0",
|
|
||||||
"coa": "~0.3.7",
|
"coa": "~0.3.7",
|
||||||
"inherit": "",
|
|
||||||
"node.extend": "",
|
|
||||||
"js-yaml": "",
|
"js-yaml": "",
|
||||||
"colors": "~0.6.0"
|
"colors": "~0.6.0",
|
||||||
|
"node.extend": ""
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"mocha": "~1.8.0",
|
"mocha": "~1.8.0",
|
||||||
"mocha-as-promised": "~1.2.0",
|
|
||||||
"chai": "~1.5.0",
|
"chai": "~1.5.0",
|
||||||
"chai-as-promised": "~3.2.3",
|
|
||||||
"istanbul": "~0.1.0",
|
"istanbul": "~0.1.0",
|
||||||
"mocha-istanbul": ""
|
"mocha-istanbul": ""
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
newlines: true,
|
||||||
|
trim: true,
|
||||||
|
spaces: true
|
||||||
|
};
|
||||||
|
|
||||||
var regNewlines = /\n/g,
|
var regNewlines = /\n/g,
|
||||||
regSpaces = /\s{2,}/g;
|
regSpaces = /\s{2,}/g;
|
||||||
|
|
||||||
@ -12,7 +22,7 @@ var regNewlines = /\n/g,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.cleanupAttrs = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
if (item.isElem()) {
|
if (item.isElem()) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var regEnableBackground = /^new\s0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)$/,
|
var regEnableBackground = /^new\s0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)$/,
|
||||||
elems = ['svg', 'mask', 'pattern'];
|
elems = ['svg', 'mask', 'pattern'];
|
||||||
|
|
||||||
@ -18,7 +22,7 @@ var regEnableBackground = /^new\s0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.cleanupEnableBackground = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
item.isElem(elems) &&
|
item.isElem(elems) &&
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'full';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
remove: true,
|
||||||
|
minify: true
|
||||||
|
};
|
||||||
|
|
||||||
var referencesProps = require('./_collections').referencesProps,
|
var referencesProps = require('./_collections').referencesProps,
|
||||||
regReferencesUrl = /^url\(#(.+?)\)$/,
|
regReferencesUrl = /^url\(#(.+?)\)$/,
|
||||||
regReferencesHref = /^#(.+?)$/,
|
regReferencesHref = /^#(.+?)$/,
|
||||||
@ -19,7 +28,7 @@ var referencesProps = require('./_collections').referencesProps,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.cleanupIDs = function(data, params) {
|
exports.fn = function(data, params) {
|
||||||
|
|
||||||
var currentID,
|
var currentID,
|
||||||
currentIDstring,
|
currentIDstring,
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
floatPrecision: 3,
|
||||||
|
leadingZero: true,
|
||||||
|
defaultPx: true
|
||||||
|
};
|
||||||
|
|
||||||
var regNumericValues = /^([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/,
|
var regNumericValues = /^([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/,
|
||||||
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero;
|
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero;
|
||||||
|
|
||||||
@ -13,7 +23,7 @@ var regNumericValues = /^([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)(px|pt|pc|mm|cm|m|in|f
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.cleanupNumericValues = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
if (item.isElem()) {
|
if (item.isElem()) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItemReverse';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var flattenOneLevel = require('../lib/svgo/tools').flattenOneLevel;
|
var flattenOneLevel = require('../lib/svgo/tools').flattenOneLevel;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -25,7 +29,7 @@ var flattenOneLevel = require('../lib/svgo/tools').flattenOneLevel;
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.collapseGroups = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
// non-empty elements
|
// non-empty elements
|
||||||
if (item.elem && !item.isEmpty()) {
|
if (item.elem && !item.isEmpty()) {
|
||||||
|
@ -1,26 +1,19 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
names2hex: true,
|
||||||
|
rgb2hex: true,
|
||||||
|
shorthex: true
|
||||||
|
};
|
||||||
|
|
||||||
var collections = require('./_collections'),
|
var collections = require('./_collections'),
|
||||||
regRGB = /^rgb\((\d+%?),\s*(\d+%?),\s*(\d+%?)\)$/,
|
regRGB = /^rgb\((\d+%?),\s*(\d+%?),\s*(\d+%?)\)$/,
|
||||||
regHEX = /^\#(([a-fA-F0-9])\2){3}$/;
|
regHEX = /^\#(([a-fA-F0-9])\2){3}$/;
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert [r, g, b] to #rrggbb.
|
|
||||||
*
|
|
||||||
* @see https://gist.github.com/983535
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* rgb2hex([255, 255, 255]) // '#ffffff'
|
|
||||||
*
|
|
||||||
* @param {Array} rgb [r, g, b]
|
|
||||||
* @return {String} #rrggbb
|
|
||||||
*
|
|
||||||
* @author Jed Schmidt
|
|
||||||
*/
|
|
||||||
function rgb2hex(rgb) {
|
|
||||||
return '#' + ((256 + rgb[0] << 8 | rgb[1]) << 8 | rgb[2]).toString(16).slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert different colors formats in element attributes to hex.
|
* Convert different colors formats in element attributes to hex.
|
||||||
*
|
*
|
||||||
@ -44,7 +37,7 @@ function rgb2hex(rgb) {
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.convertColors = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
if (item.elem) {
|
if (item.elem) {
|
||||||
|
|
||||||
@ -88,3 +81,20 @@ exports.convertColors = function(item, params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert [r, g, b] to #rrggbb.
|
||||||
|
*
|
||||||
|
* @see https://gist.github.com/983535
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* rgb2hex([255, 255, 255]) // '#ffffff'
|
||||||
|
*
|
||||||
|
* @param {Array} rgb [r, g, b]
|
||||||
|
* @return {String} #rrggbb
|
||||||
|
*
|
||||||
|
* @author Jed Schmidt
|
||||||
|
*/
|
||||||
|
function rgb2hex(rgb) {
|
||||||
|
return '#' + ((256 + rgb[0] << 8 | rgb[1]) << 8 | rgb[2]).toString(16).slice(1);
|
||||||
|
}
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
applyTransforms: true,
|
||||||
|
straightCurves: true,
|
||||||
|
lineShorthands: true,
|
||||||
|
curveSmoothShorthands: true,
|
||||||
|
floatPrecision: 3,
|
||||||
|
removeUseless: true,
|
||||||
|
collapseRepeated: true,
|
||||||
|
leadingZero: true,
|
||||||
|
negativeExtraSpace: true
|
||||||
|
};
|
||||||
|
|
||||||
var pathElems = require('./_collections.js').pathElems,
|
var pathElems = require('./_collections.js').pathElems,
|
||||||
path2js = require('./_path.js').path2js,
|
path2js = require('./_path.js').path2js,
|
||||||
js2path = require('./_path.js').js2path,
|
js2path = require('./_path.js').js2path,
|
||||||
@ -22,7 +38,7 @@ var pathElems = require('./_collections.js').pathElems,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.convertPathData = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
if (item.isElem(pathElems) && item.hasAttr('d')) {
|
if (item.isElem(pathElems) && item.hasAttr('d')) {
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var extend = require('../lib/svgo/tools').extend,
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
var EXTEND = require('node.extend'),
|
||||||
stylingProps = require('./_collections').stylingProps,
|
stylingProps = require('./_collections').stylingProps,
|
||||||
regCleanupStyle = /(:|;)\s+/g;
|
regCleanupStyle = /(:|;)\s+/g;
|
||||||
|
|
||||||
@ -22,7 +26,7 @@ var extend = require('../lib/svgo/tools').extend,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.convertStyleToAttrs = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (item.elem && item.hasAttr('style')) {
|
if (item.elem && item.hasAttr('style')) {
|
||||||
// ['opacity: 1', 'color: #000']
|
// ['opacity: 1', 'color: #000']
|
||||||
@ -57,7 +61,7 @@ exports.convertStyleToAttrs = function(item) {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
extend(item.attrs, attrs);
|
EXTEND(item.attrs, attrs);
|
||||||
|
|
||||||
if (styles.length) {
|
if (styles.length) {
|
||||||
item.attr('style').value = styles.join(';')
|
item.attr('style').value = styles.join(';')
|
||||||
|
@ -1,5 +1,22 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
convertToShorts: true,
|
||||||
|
floatPrecision: 3,
|
||||||
|
matrixToTransform: true,
|
||||||
|
shortTranslate: true,
|
||||||
|
shortScale: true,
|
||||||
|
shortRotate: true,
|
||||||
|
removeUseless: true,
|
||||||
|
collapseIntoOne: true,
|
||||||
|
leadingZero: true,
|
||||||
|
negativeExtraSpace: false
|
||||||
|
};
|
||||||
|
|
||||||
var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
|
var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
|
||||||
transform2js = require('./_transforms.js').transform2js,
|
transform2js = require('./_transforms.js').transform2js,
|
||||||
transformsMultiply = require('./_transforms.js').transformsMultiply,
|
transformsMultiply = require('./_transforms.js').transformsMultiply,
|
||||||
@ -19,7 +36,7 @@ var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.convertTransform = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
if (item.elem) {
|
if (item.elem) {
|
||||||
|
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'full';
|
||||||
|
|
||||||
|
exports.active = false;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
hcrop: true,
|
||||||
|
vcenter: true,
|
||||||
|
floatPrecision: 3,
|
||||||
|
leadingZero: true,
|
||||||
|
negativeExtraSpace: true
|
||||||
|
};
|
||||||
|
|
||||||
var relative2absolute = require('./_path.js').relative2absolute,
|
var relative2absolute = require('./_path.js').relative2absolute,
|
||||||
computeCubicBoundingBox = require('./_path.js').computeCubicBoundingBox,
|
computeCubicBoundingBox = require('./_path.js').computeCubicBoundingBox,
|
||||||
computeQuadraticBoundingBox = require('./_path.js').computeQuadraticBoundingBox,
|
computeQuadraticBoundingBox = require('./_path.js').computeQuadraticBoundingBox,
|
||||||
@ -7,7 +19,7 @@ var relative2absolute = require('./_path.js').relative2absolute,
|
|||||||
js2path = require('./_path.js').js2path,
|
js2path = require('./_path.js').js2path,
|
||||||
extend = require('../lib/svgo/tools').extend;
|
extend = require('../lib/svgo/tools').extend;
|
||||||
|
|
||||||
exports.cropAndCenterAlongPath = function(data, params) {
|
exports.fn = function(data, params) {
|
||||||
|
|
||||||
data.content.forEach(function(item) {
|
data.content.forEach(function(item) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItemReverse';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var inheritableAttrs = require('./_collections').inheritableAttrs,
|
var inheritableAttrs = require('./_collections').inheritableAttrs,
|
||||||
pathElems = require('./_collections.js').pathElems;
|
pathElems = require('./_collections.js').pathElems;
|
||||||
|
|
||||||
@ -27,7 +31,7 @@ var inheritableAttrs = require('./_collections').inheritableAttrs,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.moveElemsAttrsToGroup = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (item.isElem('g') && !item.isEmpty() && item.content.length > 1) {
|
if (item.isElem('g') && !item.isEmpty() && item.content.length > 1) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItemReverse';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var pathElems = require('./_collections.js').pathElems;
|
var pathElems = require('./_collections.js').pathElems;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +25,7 @@ var pathElems = require('./_collections.js').pathElems;
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.moveGroupAttrsToElems = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
// move group transform attr to content's pathElems
|
// move group transform attr to content's pathElems
|
||||||
if (
|
if (
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove comments.
|
* Remove comments.
|
||||||
*
|
*
|
||||||
@ -12,7 +16,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeComments = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (item.comment && item.comment.charAt(0) !== '!') {
|
if (item.comment && item.comment.charAt(0) !== '!') {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove DOCTYPE declaration.
|
* Remove DOCTYPE declaration.
|
||||||
*
|
*
|
||||||
@ -25,7 +29,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeDoctype = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
// remove doctype only if custom XML entities declaration block does not presents
|
// remove doctype only if custom XML entities declaration block does not presents
|
||||||
// http://en.wikipedia.org/wiki/Document_Type_Definition#Entity_declarations
|
// http://en.wikipedia.org/wiki/Document_Type_Definition#Entity_declarations
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var editorNamespaces = require('./_collections').editorNamespaces,
|
var editorNamespaces = require('./_collections').editorNamespaces,
|
||||||
prefixes = [];
|
prefixes = [];
|
||||||
|
|
||||||
@ -16,7 +20,7 @@ var editorNamespaces = require('./_collections').editorNamespaces,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeEditorsNSData = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (item.elem) {
|
if (item.elem) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove attributes with empty values.
|
* Remove attributes with empty values.
|
||||||
*
|
*
|
||||||
@ -8,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeEmptyAttrs = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (item.elem) {
|
if (item.elem) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItemReverse';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var container = require('./_collections').elemsGroups.container;
|
var container = require('./_collections').elemsGroups.container;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,7 +22,7 @@ var container = require('./_collections').elemsGroups.container;
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeEmptyContainers = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
return !(item.isElem(container) && !item.isElem('svg') && item.isEmpty());
|
return !(item.isElem(container) && !item.isElem('svg') && item.isEmpty());
|
||||||
|
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
text: true,
|
||||||
|
tspan: true,
|
||||||
|
tref: true
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove empty Text elements.
|
* Remove empty Text elements.
|
||||||
*
|
*
|
||||||
@ -21,7 +31,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeEmptyText = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
// Remove empty text element
|
// Remove empty text element
|
||||||
if (
|
if (
|
||||||
|
@ -1,5 +1,26 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
displayNone: true,
|
||||||
|
opacity0: true,
|
||||||
|
circleR0: true,
|
||||||
|
ellipseRX0: true,
|
||||||
|
ellipseRY0: true,
|
||||||
|
rectWidth0: true,
|
||||||
|
rectHeight0: true,
|
||||||
|
patternWidth0: true,
|
||||||
|
patternHeight0: true,
|
||||||
|
imageWidth0: true,
|
||||||
|
imageHeight0: true,
|
||||||
|
pathEmptyD: true,
|
||||||
|
polylineEmptyPoints: true,
|
||||||
|
polygonEmptyPoints: true
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove hidden elements with disabled rendering:
|
* Remove hidden elements with disabled rendering:
|
||||||
* - display="none"
|
* - display="none"
|
||||||
@ -19,7 +40,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeHiddenElems = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
if (item.elem) {
|
if (item.elem) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove <metadata>.
|
* Remove <metadata>.
|
||||||
*
|
*
|
||||||
@ -10,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeMetadata = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
return !item.isElem('metadata');
|
return !item.isElem('metadata');
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var inheritableAttrs = require('./_collections').inheritableAttrs,
|
var inheritableAttrs = require('./_collections').inheritableAttrs,
|
||||||
presentationAttrs = require('./_collections').attrsGroups.presentation,
|
presentationAttrs = require('./_collections').attrsGroups.presentation,
|
||||||
excludedAttrs = ['display', 'opacity'];
|
excludedAttrs = ['display', 'opacity'];
|
||||||
@ -12,7 +16,7 @@ var inheritableAttrs = require('./_collections').inheritableAttrs,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeNonInheritableGroupAttrs = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (item.isElem('g')) {
|
if (item.isElem('g')) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove raster images references in <image>.
|
* Remove raster images references in <image>.
|
||||||
*
|
*
|
||||||
@ -10,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeRasterImages = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
item.isElem('image') &&
|
item.isElem('image') &&
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
SVGid: true,
|
||||||
|
unknownContent: true,
|
||||||
|
unknownAttrs: true,
|
||||||
|
defaultAttrs: true
|
||||||
|
};
|
||||||
|
|
||||||
var collections = require('./_collections'),
|
var collections = require('./_collections'),
|
||||||
elems = collections.elems,
|
elems = collections.elems,
|
||||||
attrsGroups = collections.attrsGroups,
|
attrsGroups = collections.attrsGroups,
|
||||||
@ -48,7 +59,7 @@ for (var elem in elems) {
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeUnknownsAndDefaults = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
// elems w/o namespace prefix
|
// elems w/o namespace prefix
|
||||||
if (item.isElem() && !item.prefix) {
|
if (item.isElem() && !item.prefix) {
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'full';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove unused namespaces declaration.
|
* Remove unused namespaces declaration.
|
||||||
*
|
*
|
||||||
@ -8,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeUnusedNS = function(data) {
|
exports.fn = function(data) {
|
||||||
|
|
||||||
var svgElem,
|
var svgElem,
|
||||||
xmlnsCollection = [];
|
xmlnsCollection = [];
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'peItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
|
exports.params = {
|
||||||
|
stroke: true,
|
||||||
|
fill: true
|
||||||
|
};
|
||||||
|
|
||||||
var regStrokeProps = /^stroke/,
|
var regStrokeProps = /^stroke/,
|
||||||
regFillProps = /^fill/;
|
regFillProps = /^fill/;
|
||||||
|
|
||||||
@ -12,7 +21,7 @@ var regStrokeProps = /^stroke/,
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeUselessStrokeAndFill = function(item, params) {
|
exports.fn = function(item, params) {
|
||||||
|
|
||||||
if (item.isElem()) {
|
if (item.isElem()) {
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
var regViewBox = /^0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)$/,
|
var regViewBox = /^0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)$/,
|
||||||
viewBoxElems = ['svg', 'pattern'];
|
viewBoxElems = ['svg', 'pattern'];
|
||||||
|
|
||||||
@ -18,7 +22,7 @@ var regViewBox = /^0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]?\d*\.?\d+([eE
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeViewBox = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
item.isElem(viewBoxElems) &&
|
item.isElem(viewBoxElems) &&
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
exports.type = 'perItem';
|
||||||
|
|
||||||
|
exports.active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove XML Processing Instruction.
|
* Remove XML Processing Instruction.
|
||||||
*
|
*
|
||||||
@ -11,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
* @author Kir Belevich
|
* @author Kir Belevich
|
||||||
*/
|
*/
|
||||||
exports.removeXMLProcInst = function(item) {
|
exports.fn = function(item) {
|
||||||
|
|
||||||
return !(item.processinginstruction && item.processinginstruction.name === 'xml');
|
return !(item.processinginstruction && item.processinginstruction.name === 'xml');
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user