mirror of
https://github.com/svg/svgo.git
synced 2025-07-29 20:21:14 +03:00
plugins/removeUnknownsAndDefaults: remove unknown elements content, attrs and attrs with default values (close #6)
This commit is contained in:
@ -36,13 +36,13 @@ plugins:
|
|||||||
active: true
|
active: true
|
||||||
type: perItem
|
type: perItem
|
||||||
|
|
||||||
- name: cleanupSVGElem
|
- name: removeUnknownsAndDefaults
|
||||||
active: true
|
active: true
|
||||||
type: perItem
|
type: perItem
|
||||||
params:
|
params:
|
||||||
id: true
|
unknownContent: true
|
||||||
version: true
|
unknownAttrs: true
|
||||||
xmlspace: true
|
defaultAttrs: true
|
||||||
|
|
||||||
- name: removeViewBox
|
- name: removeViewBox
|
||||||
active: true
|
active: true
|
||||||
|
@ -1,3 +1,822 @@
|
|||||||
|
// http://www.w3.org/TR/SVG/intro.html#Definitions
|
||||||
|
var elemsGroups = exports.elemsGroups = {
|
||||||
|
animation: ['animate', 'animateColor', 'animateMotion', 'animateTransform', 'set'],
|
||||||
|
descriptive: ['desc', 'metadata', 'title'],
|
||||||
|
shape: ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect'],
|
||||||
|
structural: ['defs', 'g', 'svg', 'symbol', 'use'],
|
||||||
|
gradient: ['linearGradient', 'radialGradient'],
|
||||||
|
container: ['a', 'defs', 'glyph', 'g', 'marker', 'mask', 'missing-glyph', 'pattern', 'svg', 'switch', 'symbol']
|
||||||
|
};
|
||||||
|
|
||||||
|
// var defaults = exports.defaults = {
|
||||||
|
// 'externalResourcesRequired': 'false',
|
||||||
|
// 'xlink:type': 'simple'
|
||||||
|
// };
|
||||||
|
|
||||||
|
// http://www.w3.org/TR/SVG/intro.html#Definitions
|
||||||
|
var attrsGroups = exports.attrsGroups = {
|
||||||
|
animationAddition: ['additive', 'accumulate'],
|
||||||
|
animationAttributeTarget: ['attributeType', 'attributeName'],
|
||||||
|
animationEvent: ['onbegin', 'onend', 'onrepeat', 'onload'],
|
||||||
|
animationTiming: ['begin', 'dur', 'end', 'min', 'max', 'restart', 'repeatCount', 'repeatDur', 'fill'],
|
||||||
|
animationValue: ['calcMode', 'values', 'keyTimes', 'keySplines', 'from', 'to', 'by'],
|
||||||
|
conditionalProcessing: ['requiredFeatures', 'requiredExtensions', 'systemLanguage'],
|
||||||
|
core: ['id', 'xml:base', 'xml:lang', 'xml:space'],
|
||||||
|
graphicalEvent: ['onfocusin', 'onfocusout', 'onactivate', 'onclick', 'onmousedown', 'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onload'],
|
||||||
|
presentation: ['alignment-baseline', 'baseline-shift', 'clip', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'display', 'dominant-baseline', 'enable-background', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'overflow', 'pointer-events', 'shape-rendering', 'stop-color', 'stop-opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'unicode-bidi', 'visibility', 'word-spacing', 'writing-mode'],
|
||||||
|
xlink: ['xlink:href', 'xlink:show', 'xlink:actuate', 'xlink:type', 'xlink:role', 'xlink:arcrole', 'xlink:title'],
|
||||||
|
documentEvent: ['onunload', 'onabort', 'onerror', 'onresize', 'onscroll', 'onzoom'],
|
||||||
|
filterPrimitive: ['x', 'y', 'width', 'height'],
|
||||||
|
transferFunction: ['type', 'tableValues', 'slope', 'intercept', 'amplitude', 'exponent', 'offset']
|
||||||
|
};
|
||||||
|
|
||||||
|
var groupDefaults = exports.groupDefaults = {
|
||||||
|
filterPrimitive: {x: '0', y: '0', width: '100%', height: '100%'},
|
||||||
|
transferFunction: {slope: '1', intercept: '0', amplitude: '1', exponent: '1', offset: '0'}
|
||||||
|
};
|
||||||
|
|
||||||
|
// http://www.w3.org/TR/SVG/eltindex.html
|
||||||
|
exports.elems = {
|
||||||
|
a: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'transform',
|
||||||
|
'target'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
target: '_self'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
elemsGroups.shape,
|
||||||
|
elemsGroups.structural,
|
||||||
|
elemsGroups.gradient,
|
||||||
|
'a',
|
||||||
|
'altGlyphDef',
|
||||||
|
'clipPath',
|
||||||
|
'color-profile',
|
||||||
|
'cursor',
|
||||||
|
'filter',
|
||||||
|
'font',
|
||||||
|
'font-face',
|
||||||
|
'foreignObject',
|
||||||
|
'image',
|
||||||
|
'marker',
|
||||||
|
'mask',
|
||||||
|
'pattern',
|
||||||
|
'script',
|
||||||
|
'style',
|
||||||
|
'switch',
|
||||||
|
'text',
|
||||||
|
'view'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
altGlyph: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'x',
|
||||||
|
'y',
|
||||||
|
'dx',
|
||||||
|
'dy',
|
||||||
|
'glyphRef',
|
||||||
|
'format',
|
||||||
|
'rotate'
|
||||||
|
],
|
||||||
|
content: []
|
||||||
|
},
|
||||||
|
altGlyphDef: {
|
||||||
|
attrs: [attrsGroups.core],
|
||||||
|
content: ['glyphRef']
|
||||||
|
},
|
||||||
|
altGlyphItem: {
|
||||||
|
attrs: [attrsGroups.core],
|
||||||
|
content: [
|
||||||
|
'glyphRef',
|
||||||
|
'altGlyphItem'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.animationAddition,
|
||||||
|
attrsGroups.animationAttributeTarget,
|
||||||
|
attrsGroups.animationEvent,
|
||||||
|
attrsGroups.animationTiming,
|
||||||
|
attrsGroups.animationValue,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
'externalResourcesRequired'
|
||||||
|
],
|
||||||
|
content: [elemsGroups.descriptive]
|
||||||
|
},
|
||||||
|
animateColor: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.animationEvent,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
attrsGroups.animationAttributeTarget,
|
||||||
|
attrsGroups.animationTiming,
|
||||||
|
attrsGroups.animationValue,
|
||||||
|
attrsGroups.animationAddition,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'externalResourcesRequired'
|
||||||
|
],
|
||||||
|
content: [elemsGroups.descriptive]
|
||||||
|
},
|
||||||
|
animateMotion: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.animationEvent,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
attrsGroups.animationTiming,
|
||||||
|
attrsGroups.animationValue,
|
||||||
|
attrsGroups.animationAddition,
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'path',
|
||||||
|
'keyPoints',
|
||||||
|
'rotate',
|
||||||
|
'origin'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
'rotate': '0'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
'mpath'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
animateTransform: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.animationEvent,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
attrsGroups.animationAttributeTarget,
|
||||||
|
attrsGroups.animationTiming,
|
||||||
|
attrsGroups.animationValue,
|
||||||
|
attrsGroups.animationAddition,
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'type'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
type: 'translate'
|
||||||
|
},
|
||||||
|
content: [elemsGroups.descriptive]
|
||||||
|
},
|
||||||
|
circle: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'transform',
|
||||||
|
'cx',
|
||||||
|
'cy',
|
||||||
|
'r'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
cx: 0,
|
||||||
|
cy: 0
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive
|
||||||
|
]
|
||||||
|
},
|
||||||
|
clipPath: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'transform',
|
||||||
|
'clipPathUnits'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
clipPathUnits: 'userSpaceOnUse'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
elemsGroups.shape,
|
||||||
|
'text',
|
||||||
|
'use'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'color-profile': {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
'local',
|
||||||
|
'name',
|
||||||
|
'rendering-intent'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
name: 'sRGB',
|
||||||
|
'rendering-intent': 'auto'
|
||||||
|
},
|
||||||
|
content: [elemsGroups.descriptive]
|
||||||
|
},
|
||||||
|
cursor: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'x',
|
||||||
|
'y'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
x: '0',
|
||||||
|
y: '0'
|
||||||
|
},
|
||||||
|
content: [elemsGroups.descriptive]
|
||||||
|
},
|
||||||
|
defs: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'transform'
|
||||||
|
],
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
elemsGroups.shape,
|
||||||
|
elemsGroups.structural,
|
||||||
|
elemsGroups.gradient,
|
||||||
|
'a',
|
||||||
|
'altGlyphDef',
|
||||||
|
'clipPath',
|
||||||
|
'color-profile',
|
||||||
|
'cursor',
|
||||||
|
'filter',
|
||||||
|
'font',
|
||||||
|
'font-face',
|
||||||
|
'foreignObject',
|
||||||
|
'image',
|
||||||
|
'marker',
|
||||||
|
'mask',
|
||||||
|
'pattern',
|
||||||
|
'script',
|
||||||
|
'style',
|
||||||
|
'switch',
|
||||||
|
'text',
|
||||||
|
'view'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
desc: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
'class',
|
||||||
|
'style'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
ellipse: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'transform',
|
||||||
|
'cx',
|
||||||
|
'cy',
|
||||||
|
'rx',
|
||||||
|
'ry'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
cx: '0',
|
||||||
|
cy: '0'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feBlend: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
// TODO: in - 'If no value is provided and this is the first filter primitive,
|
||||||
|
// then this filter primitive will use SourceGraphic as its input'
|
||||||
|
'in',
|
||||||
|
'in2',
|
||||||
|
'mode'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
defaults: {
|
||||||
|
mode: 'normal'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
'animate',
|
||||||
|
'set'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feColorMatrix: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'in',
|
||||||
|
'type',
|
||||||
|
'values'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
defaults: {
|
||||||
|
type: 'matrix'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
'animate',
|
||||||
|
'set'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feComponentTransfer: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'in'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
content: [
|
||||||
|
'feFuncA',
|
||||||
|
'feFuncB',
|
||||||
|
'feFuncG',
|
||||||
|
'feFuncR'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feComposite: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'in',
|
||||||
|
'in2',
|
||||||
|
'operator',
|
||||||
|
'k1',
|
||||||
|
'k2',
|
||||||
|
'k3',
|
||||||
|
'k4'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
defaults: {
|
||||||
|
operator: 'over',
|
||||||
|
k1: '0',
|
||||||
|
k2: '0',
|
||||||
|
k3: '0',
|
||||||
|
k4: '0'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
'animate',
|
||||||
|
'set'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feConvolveMatrix: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'in',
|
||||||
|
'order',
|
||||||
|
'kernelMatrix',
|
||||||
|
// TODO: divisor - 'The default value is the sum of all values in kernelMatrix,
|
||||||
|
// with the exception that if the sum is zero, then the divisor is set to 1'
|
||||||
|
'divisor',
|
||||||
|
'bias',
|
||||||
|
// TODO: targetX - 'By default, the convolution matrix is centered in X over each
|
||||||
|
// pixel of the input image (i.e., targetX = floor ( orderX / 2 ))'
|
||||||
|
'targetX',
|
||||||
|
'targetY',
|
||||||
|
'edgeMode',
|
||||||
|
// TODO: kernelUnitLength - 'The first number is the <dx> value. The second number
|
||||||
|
// is the <dy> value. If the <dy> value is not specified, it defaults to the same value as <dx>'
|
||||||
|
'kernelUnitLength',
|
||||||
|
'preserveAlpha'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
defaults: {
|
||||||
|
order: '3',
|
||||||
|
bias: '0',
|
||||||
|
edgeMode: 'duplicate',
|
||||||
|
preserveAlpha: 'false'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
'animate',
|
||||||
|
'set'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feDiffuseLighting: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'in',
|
||||||
|
'surfaceScale',
|
||||||
|
'diffuseConstant',
|
||||||
|
'kernelUnitLength'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
defaults: {
|
||||||
|
surfaceScale: '1',
|
||||||
|
diffuseConstant: '1'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
// TODO: 'exactly one light source element, in any order'
|
||||||
|
'feDistantLight',
|
||||||
|
'fePointLight',
|
||||||
|
'feSpotLight'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feDisplacementMap: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'in',
|
||||||
|
'in2',
|
||||||
|
'scale',
|
||||||
|
'xChannelSelector',
|
||||||
|
'yChannelSelector'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
defaults: {
|
||||||
|
scale: '0',
|
||||||
|
xChannelSelector: 'A',
|
||||||
|
yChannelSelector: 'A'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
'animate',
|
||||||
|
'set'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feDistantLight: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
'azimuth',
|
||||||
|
'elevation'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
azimuth: '0',
|
||||||
|
elevation: '0'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
'animate',
|
||||||
|
'set'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feFlood: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
content: [
|
||||||
|
'animate',
|
||||||
|
'animateColor',
|
||||||
|
'set'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feFuncA: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.transferFunction
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.transferFunction,
|
||||||
|
content: [
|
||||||
|
'set',
|
||||||
|
'animate'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feFuncB: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.transferFunction
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.transferFunction,
|
||||||
|
content: [
|
||||||
|
'set',
|
||||||
|
'animate'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feFuncG: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.transferFunction
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.transferFunction,
|
||||||
|
content: [
|
||||||
|
'set',
|
||||||
|
'animate'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feFuncR: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.transferFunction
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.transferFunction,
|
||||||
|
content: [
|
||||||
|
'set',
|
||||||
|
'animate'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feGaussianBlur: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.filterPrimitive,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'in',
|
||||||
|
'stdDeviation'
|
||||||
|
],
|
||||||
|
groupDefaults: groupDefaults.filterPrimitive,
|
||||||
|
defaults: {
|
||||||
|
stdDeviation: '0'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
'set',
|
||||||
|
'animate'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
feImage: {},
|
||||||
|
feMerge: {},
|
||||||
|
feMergeNode: {},
|
||||||
|
feMorphology: {},
|
||||||
|
feOffset: {},
|
||||||
|
fePointLight: {},
|
||||||
|
feSpecularLighting: {},
|
||||||
|
feSpotLight: {},
|
||||||
|
feTile: {},
|
||||||
|
feTurbulence: {},
|
||||||
|
filter: {},
|
||||||
|
font: {},
|
||||||
|
'font-face': {},
|
||||||
|
'font-face-format': {},
|
||||||
|
'font-face-name': {},
|
||||||
|
'font-face-src': {},
|
||||||
|
'font-face-uri': {},
|
||||||
|
foreignObject: {},
|
||||||
|
g: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'transform'
|
||||||
|
],
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
elemsGroups.shape,
|
||||||
|
elemsGroups.structural,
|
||||||
|
elemsGroups.gradient,
|
||||||
|
'a',
|
||||||
|
'altGlyphDef',
|
||||||
|
'clipPath',
|
||||||
|
'color-profile',
|
||||||
|
'cursor',
|
||||||
|
'filter',
|
||||||
|
'font',
|
||||||
|
'font-face',
|
||||||
|
'foreignObject',
|
||||||
|
'image',
|
||||||
|
'marker',
|
||||||
|
'mask',
|
||||||
|
'pattern',
|
||||||
|
'script',
|
||||||
|
'style',
|
||||||
|
'switch',
|
||||||
|
'text',
|
||||||
|
'view'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
glyph: {},
|
||||||
|
glyphRef: {},
|
||||||
|
hkern: {},
|
||||||
|
image: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'preserveAspectRatio',
|
||||||
|
'transform',
|
||||||
|
'x',
|
||||||
|
'y',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'xlink:href'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
x: '0',
|
||||||
|
y: '0',
|
||||||
|
preserveAspectRatio: 'xMidYMid meet'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive
|
||||||
|
]
|
||||||
|
},
|
||||||
|
line: {},
|
||||||
|
linearGradient: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
attrsGroups.xlink,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'x1',
|
||||||
|
'y1',
|
||||||
|
'x2',
|
||||||
|
'y2',
|
||||||
|
'gradientUnits',
|
||||||
|
'gradientTransform',
|
||||||
|
'spreadMethod',
|
||||||
|
'xlink:href'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
x1: '0',
|
||||||
|
y1: '0',
|
||||||
|
x2: '100%',
|
||||||
|
y2: '0',
|
||||||
|
spreadMethod: 'pad'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
'animate',
|
||||||
|
'animateTransform',
|
||||||
|
'set',
|
||||||
|
'stop'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
marker: {},
|
||||||
|
mask: {},
|
||||||
|
metadata: {},
|
||||||
|
'missing-glyph': {},
|
||||||
|
mpath: {},
|
||||||
|
path: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'externalResourcesRequired',
|
||||||
|
'transform',
|
||||||
|
'd',
|
||||||
|
'pathLength'
|
||||||
|
],
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive
|
||||||
|
]
|
||||||
|
},
|
||||||
|
pattern: {},
|
||||||
|
polygon: {},
|
||||||
|
polyline: {},
|
||||||
|
radialGradient: {
|
||||||
|
defaults: {
|
||||||
|
cx: '50%',
|
||||||
|
cy: '50%',
|
||||||
|
r: '50%'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rect: {},
|
||||||
|
script: {},
|
||||||
|
set: {},
|
||||||
|
stop: {},
|
||||||
|
style: {},
|
||||||
|
svg: {
|
||||||
|
attrs: [
|
||||||
|
attrsGroups.conditionalProcessing,
|
||||||
|
attrsGroups.core,
|
||||||
|
attrsGroups.documentEvent,
|
||||||
|
attrsGroups.graphicalEvent,
|
||||||
|
attrsGroups.presentation,
|
||||||
|
'class',
|
||||||
|
'style',
|
||||||
|
'x',
|
||||||
|
'y',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'viewBox',
|
||||||
|
'preserveAspectRatio',
|
||||||
|
'zoomAndPan',
|
||||||
|
'version',
|
||||||
|
'baseProfile',
|
||||||
|
'contentScriptType',
|
||||||
|
'contentStyleType'
|
||||||
|
],
|
||||||
|
defaults: {
|
||||||
|
x: '0',
|
||||||
|
y: '0',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
preserveAspectRatio: 'xMidYMid meet',
|
||||||
|
zoomAndPan: 'magnify',
|
||||||
|
version: '1.1',
|
||||||
|
baseProfile: 'none',
|
||||||
|
contentScriptType: 'application/ecmascript',
|
||||||
|
contentStyleType: 'text/css'
|
||||||
|
},
|
||||||
|
content: [
|
||||||
|
elemsGroups.animation,
|
||||||
|
elemsGroups.descriptive,
|
||||||
|
elemsGroups.shape,
|
||||||
|
elemsGroups.structural,
|
||||||
|
elemsGroups.gradient,
|
||||||
|
'a',
|
||||||
|
'altGlyphDef',
|
||||||
|
'clipPath',
|
||||||
|
'color-profile',
|
||||||
|
'cursor',
|
||||||
|
'filter',
|
||||||
|
'font',
|
||||||
|
'font-face',
|
||||||
|
'foreignObject',
|
||||||
|
'image',
|
||||||
|
'marker',
|
||||||
|
'mask',
|
||||||
|
'pattern',
|
||||||
|
'script',
|
||||||
|
'style',
|
||||||
|
'switch',
|
||||||
|
'text',
|
||||||
|
'view'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
switch: {},
|
||||||
|
symbol: {},
|
||||||
|
text: {},
|
||||||
|
textPath: {},
|
||||||
|
title: {},
|
||||||
|
tref: {},
|
||||||
|
tspan: {},
|
||||||
|
use: {},
|
||||||
|
view: {},
|
||||||
|
vkern: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// http://wiki.inkscape.org/wiki/index.php/Inkscape-specific_XML_attributes
|
// http://wiki.inkscape.org/wiki/index.php/Inkscape-specific_XML_attributes
|
||||||
exports.editorNamespaces = [
|
exports.editorNamespaces = [
|
||||||
'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
|
'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
|
||||||
@ -79,32 +898,6 @@ exports.stylingProps = [
|
|||||||
'writing-mode'
|
'writing-mode'
|
||||||
];
|
];
|
||||||
|
|
||||||
// http://www.w3.org/TR/SVG/intro.html#Definitions
|
|
||||||
var elems = exports.elems = {
|
|
||||||
'animation': ['animate', 'animateColor', 'animateMotion', 'animateTransform', 'set'],
|
|
||||||
'descriptive': ['desc', 'metadata', 'title'],
|
|
||||||
'shape': ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect'],
|
|
||||||
'structural': ['defs', 'g', 'svg', 'symbol', 'use'],
|
|
||||||
'gradient': ['linearGradient', 'radialGradient'],
|
|
||||||
// http://www.w3.org/TR/SVG/intro.html#TermContainerElement
|
|
||||||
'container': ['a', 'defs', 'glyph', 'g', 'marker', 'mask', 'missing-glyph', 'pattern', 'svg', 'switch', 'symbol']
|
|
||||||
};
|
|
||||||
|
|
||||||
// http://www.w3.org/TR/SVG/intro.html#Definitions
|
|
||||||
var attrs = exports.attrs = {
|
|
||||||
'animationAddition': ['additive', 'accumulate'],
|
|
||||||
'animationAttributeTarget': ['attributeType', 'attributeName'],
|
|
||||||
'animationEvent': ['onbegin', 'onend', 'onrepeat', 'onload'],
|
|
||||||
'animationTiming': ['begin', 'dur', 'end', 'min', 'max', 'restart', 'repeatCount', 'repeatDur', 'fill'],
|
|
||||||
'animationValue': ['calcMode', 'values', 'keyTimes', 'keySplines', 'from', 'to', 'by'],
|
|
||||||
'conditionalProcessing': ['requiredFeatures', 'requiredExtensions', 'systemLanguage'],
|
|
||||||
'core': ['id', 'xml:base', 'xml:lang', 'xml:space'],
|
|
||||||
'graphicalEvent': ['onfocusin', 'onfocusout', 'onactivate', 'onclick', 'onmousedown', 'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onload'],
|
|
||||||
'presentation': ['alignment-baseline', 'baseline-shift', 'clip', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'display', 'dominant-baseline', 'enable-background', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'overflow', 'pointer-events', 'shape-rendering', 'stop-color', 'stop-opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'unicode-bidi', 'visibility', 'word-spacing', 'writing-mode'],
|
|
||||||
'xlink': ['xlink:href', 'xlink:show', 'xlink:actuate', 'xlink:type', 'xlink:role', 'xlink:arcrole', 'xlink:title'],
|
|
||||||
'documentEvent': ['onunload', 'onabort', 'onerror', 'onresize', 'onscroll', 'onzoom']
|
|
||||||
};
|
|
||||||
|
|
||||||
// http://www.w3.org/TR/SVG/propidx.html
|
// http://www.w3.org/TR/SVG/propidx.html
|
||||||
exports.nonInheritedAttrs = [
|
exports.nonInheritedAttrs = [
|
||||||
'alignment-baseline',
|
'alignment-baseline',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
var container = require('./_collections').elems.container;
|
var container = require('./_collections').elemsGroups.container;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove empty containers.
|
* Remove empty containers.
|
||||||
|
87
plugins/removeUnknownsAndDefaults.js
Normal file
87
plugins/removeUnknownsAndDefaults.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
var flattenOneLevel = require('../lib/svgo/tools').flattenOneLevel,
|
||||||
|
elems = require('./_collections').elems;
|
||||||
|
|
||||||
|
// flatten and extend all collection references
|
||||||
|
for (var elem in elems) {
|
||||||
|
elem = elems[elem];
|
||||||
|
|
||||||
|
// attrs
|
||||||
|
if (elem.attrs) {
|
||||||
|
elem.attrs = flattenOneLevel(elem.attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// contennt
|
||||||
|
if (elem.content) {
|
||||||
|
elem.content = flattenOneLevel(elem.content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// extend defaults with groupDefaults
|
||||||
|
if (elem.groupDefaults) {
|
||||||
|
elem.defaults = elem.defaults || {};
|
||||||
|
for(var groupDefault in elem.groupDefaults) {
|
||||||
|
elem.defaults[groupDefault] = elem.groupDefaults[groupDefault];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove unknown elements content and attributes,
|
||||||
|
* remove attributes with default values.
|
||||||
|
*
|
||||||
|
* @param {Object} item current iteration item
|
||||||
|
* @param {Object} params plugin params
|
||||||
|
* @return {Boolean} if false, item will be filtered out
|
||||||
|
*
|
||||||
|
* @author Kir Belevich
|
||||||
|
*/
|
||||||
|
exports.removeUnknownsAndDefaults = function(item, params) {
|
||||||
|
|
||||||
|
// elems w/o namespace prefix
|
||||||
|
if (item.isElem() && !item.prefix) {
|
||||||
|
|
||||||
|
var elem = item.elem;
|
||||||
|
|
||||||
|
// remove unknown element's content
|
||||||
|
if (
|
||||||
|
params.unknownContent &&
|
||||||
|
!item.isEmpty() &&
|
||||||
|
elems[elem].content
|
||||||
|
) {
|
||||||
|
item.content.forEach(function(content, i) {
|
||||||
|
if (
|
||||||
|
content.isElem() &&
|
||||||
|
!content.prefix &&
|
||||||
|
elems[elem].content.indexOf(content.elem) === -1
|
||||||
|
) {
|
||||||
|
item.content.splice(i, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove element's unknown attrs and attrs with default values
|
||||||
|
if (elems[elem].attrs) {
|
||||||
|
|
||||||
|
item.eachAttr(function(attr) {
|
||||||
|
|
||||||
|
if (attr.name !== 'xmlns' && !attr.prefix) {
|
||||||
|
if (
|
||||||
|
// unknown attrs
|
||||||
|
(params.unknownAttrs &&
|
||||||
|
elems[elem].attrs.indexOf(attr.name) === -1) ||
|
||||||
|
// attrs with default values
|
||||||
|
(params.defaultAttrs &&
|
||||||
|
elems[elem].defaults &&
|
||||||
|
elems[elem].defaults[attr.name] === attr.value
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
item.removeAttr(attr.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -1,3 +0,0 @@
|
|||||||
<svg version="1.1" id="svg123" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="..."/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 115 B |
@ -1,3 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="..."/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 68 B |
3
test/plugins/removeUnknownsAndDefaults.01.orig.svg
Normal file
3
test/plugins/removeUnknownsAndDefaults.01.orig.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:test="http://" attr="val" x="0" y="10" test:attr="val">
|
||||||
|
test
|
||||||
|
</svg>
|
After Width: | Height: | Size: 132 B |
3
test/plugins/removeUnknownsAndDefaults.01.should.svg
Normal file
3
test/plugins/removeUnknownsAndDefaults.01.should.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:test="http://" y="10" test:attr="val">
|
||||||
|
test
|
||||||
|
</svg>
|
After Width: | Height: | Size: 101 B |
11
test/plugins/removeUnknownsAndDefaults.02.orig.svg
Normal file
11
test/plugins/removeUnknownsAndDefaults.02.orig.svg
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:test="http://">
|
||||||
|
<test>
|
||||||
|
test
|
||||||
|
</test>
|
||||||
|
<test:test>
|
||||||
|
test
|
||||||
|
</test:test>
|
||||||
|
<g>
|
||||||
|
test
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 181 B |
8
test/plugins/removeUnknownsAndDefaults.02.should.svg
Normal file
8
test/plugins/removeUnknownsAndDefaults.02.should.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:test="http://">
|
||||||
|
<test:test>
|
||||||
|
test
|
||||||
|
</test:test>
|
||||||
|
<g>
|
||||||
|
test
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 145 B |
Reference in New Issue
Block a user