svg-path-simplify 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +7 -4
  3. package/dist/svg-path-simplify.esm.js +3593 -1279
  4. package/dist/svg-path-simplify.esm.min.js +2 -2
  5. package/dist/svg-path-simplify.js +3594 -1278
  6. package/dist/svg-path-simplify.min.js +2 -2
  7. package/dist/svg-path-simplify.pathdata.esm.js +1017 -538
  8. package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
  9. package/dist/svg-path-simplify.poly.cjs +9 -8
  10. package/docs/privacy-webapp.md +24 -0
  11. package/index.html +331 -152
  12. package/package.json +1 -1
  13. package/src/constants.js +4 -0
  14. package/src/css_parse.js +317 -0
  15. package/src/detect_input.js +76 -28
  16. package/src/index.js +8 -0
  17. package/src/pathData_simplify_cubic.js +26 -16
  18. package/src/pathData_simplify_harmonize_cpts.js +77 -1
  19. package/src/pathData_simplify_revertToquadratics.js +0 -1
  20. package/src/pathSimplify-main.js +304 -276
  21. package/src/pathSimplify-only-pathdata.js +7 -2
  22. package/src/pathSimplify-presets.js +254 -0
  23. package/src/poly-fit-curve-schneider.js +14 -7
  24. package/src/simplify_poly_RC.js +102 -0
  25. package/src/simplify_poly_RDP.js +109 -1
  26. package/src/simplify_poly_radial_distance.js +3 -3
  27. package/src/string_helpers.js +130 -4
  28. package/src/svg-getAttributes.js +4 -2
  29. package/src/svgii/convert_units.js +1 -1
  30. package/src/svgii/geometry.js +322 -5
  31. package/src/svgii/geometry_bbox_element.js +1 -1
  32. package/src/svgii/geometry_deduceRadius.js +116 -27
  33. package/src/svgii/geometry_length.js +253 -0
  34. package/src/svgii/pathData_analyze.js +18 -0
  35. package/src/svgii/pathData_convert.js +193 -89
  36. package/src/svgii/pathData_fix_directions.js +12 -14
  37. package/src/svgii/pathData_fromPoly.js +3 -3
  38. package/src/svgii/pathData_getLength.js +86 -0
  39. package/src/svgii/pathData_parse.js +2 -0
  40. package/src/svgii/pathData_parse_els.js +66 -68
  41. package/src/svgii/pathData_reorder.js +122 -16
  42. package/src/svgii/pathData_simplify_refineCorners.js +130 -35
  43. package/src/svgii/pathData_simplify_refine_round.js +420 -0
  44. package/src/svgii/pathData_split_to_groups.js +168 -0
  45. package/src/svgii/pathData_stringify.js +26 -64
  46. package/src/svgii/pathData_toPolygon.js +3 -4
  47. package/src/svgii/poly_analyze.js +61 -0
  48. package/src/svgii/poly_normalize.js +11 -2
  49. package/src/svgii/poly_to_pathdata.js +85 -24
  50. package/src/svgii/rounding.js +80 -78
  51. package/src/svgii/svg_cleanup.js +421 -619
  52. package/src/svgii/svg_cleanup_convertPathLength.js +39 -0
  53. package/src/svgii/svg_cleanup_general_svg_atts.js +97 -0
  54. package/src/svgii/svg_cleanup_normalize_transforms.js +83 -0
  55. package/src/svgii/svg_cleanup_remove_els_and_atts.js +77 -0
  56. package/src/svgii/svg_cleanup_ungroup.js +36 -0
  57. package/src/svgii/svg_el_parse_style_props.js +72 -47
  58. package/src/svgii/svg_getElementLength.js +67 -0
  59. package/src/svgii/svg_validate.js +220 -0
  60. package/tests/testSVG.js +14 -1
  61. package/src/svgii/pathData_refine_round.js +0 -222
@@ -0,0 +1,39 @@
1
+ import { scaleProps } from "./svg_cleanup_normalize_transforms";
2
+ import { getElementLength } from "./svg_getElementLength";
3
+
4
+ export function convertPathLengthAtt(el, {
5
+ styleProps = {}
6
+ } = {}) {
7
+
8
+ let pathLength = styleProps['pathLength'];
9
+
10
+ if (pathLength) {
11
+
12
+ //let strokeDasharray
13
+ if ((styleProps['stroke-dasharray'] || styleProps['stroke-dashoffset'])) {
14
+ let elLength = getElementLength(el, {
15
+ pathLength,
16
+ props: styleProps
17
+ })
18
+
19
+ let scale = elLength / pathLength
20
+ styleProps = scaleProps(styleProps, { props: ['stroke-dasharray', 'stroke-dashoffset'], scale })
21
+
22
+ // set absolute
23
+ if (styleProps['stroke-dasharray']) el.setAttribute('stroke-dasharray', styleProps['stroke-dasharray'].join(' '))
24
+ if (styleProps['stroke-dashoffset']) el.setAttribute('stroke-dashoffset', styleProps['stroke-dashoffset'][0])
25
+
26
+ }
27
+
28
+ // tag for removal
29
+ delete styleProps['pathLength'];
30
+ styleProps.remove.push('pathLength')
31
+ el.removeAttribute('pathLength')
32
+
33
+
34
+ }
35
+
36
+ return styleProps;
37
+
38
+
39
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * general clean up to remove bullshit like
3
+ * version or enable background
4
+ */
5
+
6
+ export function cleanupSVGAttributes(svg, {
7
+ removeIds = false,
8
+ removeClassNames = false,
9
+ removeDimensions = false,
10
+ stylesToAttributes = false,
11
+ allowMeta = false,
12
+ allowAriaAtts = false,
13
+ allowDataAtts = false,
14
+ } = {}) {
15
+
16
+ //console.log('cleanupSVGAtts');
17
+ let allowed = new Set(['viewBox', 'xmlns', 'width', 'height']);
18
+
19
+ if (!removeIds) allowed.add('id')
20
+ if (!removeClassNames) allowed.add('class')
21
+ if (removeDimensions) {
22
+ allowed.delete('width')
23
+ allowed.delete('height')
24
+ }
25
+
26
+ allowed = Array.from(allowed)
27
+ if (!stylesToAttributes) {
28
+ allowed.push('fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'font-size', 'font-family', 'font-style', 'style');
29
+ }
30
+
31
+ removeExcludedAttribues(svg, { allowed, allowMeta, allowAriaAtts, allowDataAtts })
32
+ }
33
+
34
+ function removeExcludedAttribues(el, {
35
+ allowed = ['viewBox', 'xmlns', 'width', 'height', 'id', 'class'],
36
+ allowAriaAtts = true,
37
+ allowDataAtts = true,
38
+ allowMeta = false
39
+ } = {}) {
40
+ let atts = [...el.attributes].map((att) => att.name);
41
+ atts.forEach((att) => {
42
+
43
+ let isMeta = allowMeta && (att === 'title')
44
+ let isAria = allowAriaAtts && att.startsWith('aria-')
45
+ let isData = allowDataAtts && att.startsWith('data-')
46
+ //console.log(att, isData, 'allowDataAtts', allowDataAtts);
47
+
48
+ if (
49
+ !allowed.includes(att) &&
50
+ !isAria && !isData && !isMeta
51
+ ) {
52
+ el.removeAttribute(att);
53
+ }
54
+ });
55
+ }
56
+
57
+
58
+
59
+ export function removeNameSpaceAtts(el, {
60
+ include = ['xlink:href']
61
+ } = {}) {
62
+ let atts = [...el.attributes].map((att) => att.name);
63
+ atts.forEach((att) => {
64
+ if (att.includes(":") && !include.includes(att)) {
65
+ el.removeAttribute(att);
66
+ }
67
+ });
68
+ }
69
+
70
+
71
+ export function removeElAtts(el, exclude = [], include = []) {
72
+ let atts = [...el.attributes].map((att) => att.name);
73
+ atts.forEach((att) => {
74
+ if (exclude.includes(att) && !include.includes(att)) {
75
+ el.removeAttribute(att);
76
+ }
77
+ });
78
+ }
79
+
80
+
81
+ /*
82
+
83
+ function cleanSvgPrologue(svgString) {
84
+ return (
85
+ svgString
86
+ // Remove XML prologues like <?xml ... ?>
87
+ .replace(/<\?xml[\s\S]*?\?>/gi, "")
88
+ // Remove DOCTYPE declarations
89
+ .replace(/<!DOCTYPE[\s\S]*?>/gi, "")
90
+ // Remove comments <!-- ... -->
91
+ .replace(/<!--[\s\S]*?-->/g, "")
92
+ // Trim extra whitespace
93
+ .trim()
94
+ );
95
+ }
96
+ */
97
+
@@ -0,0 +1,83 @@
1
+ import { roundTo } from "./rounding";
2
+
3
+ export function setNormalizedTransformsToEl(el, {
4
+ styleProps = {},
5
+ } = {}) {
6
+ let { remove, matrix, transComponents } = styleProps;
7
+ let name = el.nodeName.toLowerCase()
8
+
9
+ if(!matrix) return styleProps;
10
+
11
+ let { rotate, scaleX, scaleY, skewX, translateX, translateY } = transComponents;
12
+ //console.log(rotate, scaleX, scaleY, skewX, skewY, translateX, translateY);
13
+
14
+ // scale attributes instead of transform
15
+ let hasRot = rotate !== 0 || skewX !== 0;
16
+ let unProportional = scaleX !== scaleY;
17
+ let scalableByAtt = ['circle', 'ellipse', 'rect']
18
+ //let needsTrans = (name === 'g') || (hasRot) || unProportional
19
+ let needsTrans = (hasRot) || unProportional
20
+ needsTrans = true
21
+
22
+ if (!needsTrans && scalableByAtt.includes(name)) {
23
+
24
+ if (name === 'circle' || name === 'ellipse') {
25
+ styleProps.cx[0] = [styleProps.cx[0] * scaleX + translateX]
26
+ styleProps.cy[0] = [styleProps.cy[0] * scaleX + translateY]
27
+
28
+ if (styleProps.r) styleProps.r[0] = [styleProps.r[0] * scaleX]
29
+ if (styleProps.rx) styleProps.rx[0] = [styleProps.rx[0] * scaleX]
30
+ if (styleProps.ry) styleProps.ry[0] = [styleProps.ry[0] * scaleX]
31
+
32
+ }
33
+ else if (name === 'rect') {
34
+ let x = styleProps.x ? styleProps.x[0] + translateX : translateX;
35
+ let y = styleProps.y ? styleProps.y[0] + translateY : translateY;
36
+
37
+ let rx = styleProps.rx ? styleProps.rx[0] * scaleX : 0;
38
+ let ry = styleProps.ry ? styleProps.ry[0] * scaleY : 0;
39
+
40
+ styleProps.x = [x]
41
+ styleProps.y = [y]
42
+
43
+ styleProps.rx = [rx]
44
+ styleProps.ry = [ry]
45
+
46
+ styleProps.width = [styleProps.width[0] * scaleX]
47
+ styleProps.height = [styleProps.height[0] * scaleX]
48
+ }
49
+
50
+ // remove now obsolete transform properties
51
+ delete styleProps.matrix
52
+ delete styleProps.transformArr
53
+ delete styleProps.transComponents
54
+
55
+ // mark transform attribute for removal
56
+ styleProps.remove.push('transform')
57
+
58
+ // scale props like stroke width or dash-array
59
+ styleProps = scaleProps(styleProps, { props: ['stroke-width', 'stroke-dasharray'], scale: scaleX })
60
+
61
+ } else {
62
+ el.setAttribute('transform', transComponents.matrixAtt)
63
+
64
+ }
65
+
66
+ return styleProps
67
+
68
+ }
69
+
70
+
71
+
72
+ export function scaleProps(styleProps = {}, { props = [], scale = 1 } = {}, round = true) {
73
+ if (scale === 1 || !props.length) return props;
74
+
75
+ for (let i = 0; i < props.length; i++) {
76
+ let prop = props[i];
77
+
78
+ if (styleProps[prop] !== undefined) {
79
+ styleProps[prop] = styleProps[prop].map(val => round ? roundTo(val * scale, 2) : val * scale)
80
+ }
81
+ }
82
+ return styleProps
83
+ }
@@ -0,0 +1,77 @@
1
+ export function removeHiddenSvgEls(svg) {
2
+ let els = svg.querySelectorAll('*')
3
+ els.forEach(el => {
4
+ let name = el.nodeName.toLowerCase()
5
+ let style = el.getAttribute('style') || ''
6
+ let isHiddenByStyle = style ? style.trim().includes('display:none') : false;
7
+ let isHidden = (el.getAttribute('display') && el.getAttribute('display') === 'none') || isHiddenByStyle;
8
+ if (isHidden) el.remove();
9
+ })
10
+
11
+ }
12
+
13
+
14
+
15
+
16
+ export function removeSvgEls(svg, {
17
+ removeElements = [],
18
+ removeNameSpaced = true,
19
+ } = {}) {
20
+
21
+ // always remove scripts
22
+ removeElements.push('script');
23
+
24
+ let els = svg.querySelectorAll('*')
25
+ let allowMeta = !removeElements.includes('metadata');
26
+
27
+ els.forEach(el => {
28
+ let nodeName = el.nodeName;
29
+ let isMeta = allowMeta && el.closest('metadata')
30
+ if (
31
+ !isMeta &&
32
+ ((removeNameSpaced && nodeName.includes(':')) ||
33
+ removeElements.includes(nodeName))
34
+ ) {
35
+ el.remove()
36
+ }
37
+ })
38
+ }
39
+
40
+
41
+
42
+ /*export function removeSvgEls(svg, remove = []) {
43
+ // remove elements
44
+ if (remove.length) {
45
+ let selector = remove.join(', ').replaceAll(':', '\\:');
46
+ svg.querySelectorAll(selector).forEach(el => {
47
+ el.remove()
48
+ })
49
+ }
50
+ }
51
+ */
52
+
53
+ export function removeSvgAtts(svg, remove = []) {
54
+ removeAtts(svg, remove)
55
+ }
56
+
57
+ export function removeAtts(el, remove = []) {
58
+ remove.forEach(att => {
59
+ el.removeAttribute(att);
60
+ })
61
+ }
62
+
63
+
64
+ export function removeSvgChildAtts(svg, remove = []) {
65
+ if (remove.length) {
66
+ let selector = remove.map(att => { return `[${att}]` }).join(', ')
67
+ // escape name spaced
68
+ .replaceAll(':', '\\:')
69
+
70
+ svg.querySelectorAll(selector).forEach(el => {
71
+ remove.forEach(att => {
72
+ el.removeAttribute(att);
73
+ })
74
+ })
75
+ }
76
+ };
77
+
@@ -0,0 +1,36 @@
1
+ import { getElementAtts } from "../svg-getAttributes";
2
+
3
+ export function ungroupElements(groups) {
4
+ groups.forEach((g, i) => {
5
+ let children = [...g.children];
6
+
7
+ children.forEach(child => {
8
+ g.parentNode.insertBefore(child, g)
9
+ })
10
+ g.remove()
11
+ })
12
+ }
13
+
14
+
15
+ export function removeGroupProps(groups, {
16
+ remove = [],
17
+ allowDataAtts = true,
18
+ allowAriaAtts = true
19
+ } = {}) {
20
+
21
+ groups.forEach((g, i) => {
22
+ let atts = Object.keys(getElementAtts(g));
23
+
24
+ atts.forEach(att => {
25
+ //console.log('remove', remove);
26
+ let isData = !allowDataAtts && att.startsWith('data-')
27
+ let isAria = !allowAriaAtts && att.startsWith('aria-')
28
+ //console.log(isData, att);
29
+ //styleProps.remove.push('transform', 'style')
30
+ if (remove.includes(att) || isData || isAria) {
31
+ g.removeAttribute(att)
32
+ }
33
+ })
34
+ })
35
+
36
+ }
@@ -18,16 +18,19 @@ export function parseStylesProperties(el, {
18
18
  autoRoundValues = false,
19
19
  minifyRgbColors = false,
20
20
  removeInvalid = true,
21
+ allowDataAtts = true,
22
+ allowAriaAtts = true,
21
23
  removeDefaults = true,
22
24
  cleanUpStrokes = true,
23
25
  normalizeTransforms = true,
24
- removeIds=false,
25
- removeClassNames=false,
26
+ removeIds = false,
27
+ removeClassNames = false,
26
28
 
27
- include=[],
29
+ include = [],
28
30
  exclude = [],
29
31
  width = 0,
30
32
  height = 0,
33
+ stylesheetProps = {}
31
34
  } = {}) {
32
35
 
33
36
  //autoRoundValues = false;
@@ -35,22 +38,52 @@ export function parseStylesProperties(el, {
35
38
 
36
39
  let nodeName = el.nodeName.toLowerCase();
37
40
  let attProps = getSvgPresentationAtts(el)
38
- let cssProps = getSvgCssProps(el)
41
+ let inlineCssProps = getSvgCssProps(el)
42
+
43
+ // get CSS properties from SVG style element
44
+ let cssRuleSelectors = el.cssRules || [];
45
+ let cssProps = {};
46
+
47
+ cssRuleSelectors.forEach(selector => {
48
+ for (let prop in stylesheetProps[selector]) {
49
+ let val = stylesheetProps[selector][prop];
50
+ //console.log('!!val', val);
51
+
52
+ // check CSS vars
53
+ if (val.startsWith('var(')) {
54
+ let varName = val.replace(/[var\(|\)]/g, '').trim()
55
+ //console.log('!!isvar', val, varName, stylesheetProps[':root']);
56
+ if (stylesheetProps[':root']) {
57
+ val = `var(${varName}, ${stylesheetProps[':root'][varName]})`
58
+ }
59
+ }
60
+ cssProps[prop] = val
61
+ }
62
+ })
63
+
64
+ //console.log('cssProps', cssProps);
65
+ //console.log('styleSheetProps', cssRuleSelectors, stylesheetProps);
39
66
 
40
67
  /**
41
- * merge props
42
- * CSS has higher specificity
68
+ * merge props by specificity
69
+ * 1. attributes
70
+ * 2. CSS rules
71
+ * 3. inline CSS
43
72
  */
44
73
  let props = {
45
74
  ...attProps,
46
75
  ...cssProps,
76
+ ...inlineCssProps,
47
77
  }
48
78
 
49
79
  //console.log('!props combined', props);
50
80
 
51
-
81
+ // obsolete/not style relevant anymore
52
82
  delete props['style'];
53
- exclude.push('style')
83
+ delete props['class'];
84
+ delete props['id'];
85
+
86
+ exclude.push('style', 'class', 'id')
54
87
 
55
88
  let remove = ['style']
56
89
  let transformsStandalone = ['scale', 'translate', 'rotate'];
@@ -61,9 +94,10 @@ export function parseStylesProperties(el, {
61
94
  */
62
95
 
63
96
  if (removeInvalid || removeDefaults || removeNameSpaced) {
64
- let propsFilteredObj = filterSvgElProps(nodeName, props, { removeIds, removeClassNames, removeDefaults, removeNameSpaced, exclude, cleanUpStrokes, include: [...transformsStandalone, ...include], cleanUpStrokes: false })
97
+ let propsFilteredObj = filterSvgElProps(nodeName, props, { allowDataAtts, allowAriaAtts, removeIds, removeClassNames, removeDefaults, removeNameSpaced, exclude, cleanUpStrokes, include: [...transformsStandalone, ...include], cleanUpStrokes: false })
65
98
  props = propsFilteredObj.propsFiltered
66
99
  remove.push(...propsFilteredObj.remove)
100
+ //console.log(propsFilteredObj.remove, allowDataAtts, allowAriaAtts);
67
101
  }
68
102
 
69
103
  //console.log('???props', nodeName, props, remove);
@@ -84,11 +118,16 @@ export function parseStylesProperties(el, {
84
118
 
85
119
  // minify rgb values
86
120
  if (minifyRgbColors && colorProps.includes(prop)) {
121
+ //console.log(minifyRgbColors, nodeName, prop, valueStr);
122
+
87
123
  let color = parseColor(valueStr)
124
+
88
125
  if (color.mode === 'rgba' || color.mode === 'rgb') {
89
126
  let hex = rgba2Hex(color)
90
127
  valueStr = hex;
91
128
  }
129
+ //console.log(nodeName, color, valueStr);
130
+
92
131
  }
93
132
 
94
133
 
@@ -131,7 +170,6 @@ export function parseStylesProperties(el, {
131
170
  else {
132
171
  //console.log('other', prop);
133
172
  item.values = parseValue(valueStr);
134
-
135
173
  }
136
174
 
137
175
  if (item.values.length) {
@@ -158,10 +196,11 @@ export function parseStylesProperties(el, {
158
196
 
159
197
  if (prop !== 'transforms') {
160
198
 
161
- if (cleanUpStrokes && (prop === 'stroke-dasharray' || prop === 'stroke-dashoffset')) {
199
+ //cleanUpStrokes &&
200
+ if ((prop === 'stroke-dasharray' || prop === 'stroke-dashoffset')) {
162
201
  normalizedDiagonal = true
163
202
  for (let i = 0; i < values.length; i++) {
164
- let val = normalizeUnits(values[i].value, { unit: values[i].unit, width, height, normalizedDiagonal, fontSize })
203
+ let val = normalizeUnits(values[i].value, { unit: values[i].unit, width, height, normalizedDiagonal, fontSize, autoRoundValues })
165
204
  valsNew.push(val)
166
205
  }
167
206
  }
@@ -206,14 +245,12 @@ export function parseStylesProperties(el, {
206
245
  if (prop === 'scale' && unit === '%') {
207
246
  valAbs = valAbs * 0.01;
208
247
  } else {
209
- if (prop === 'r') normalizedDiagonal = true;
248
+ if (prop === 'r' && width!==height) normalizedDiagonal = true;
210
249
  valAbs = normalizeUnits(val.value, { unit, width, height, isHorizontal, isVertical, normalizedDiagonal, fontSize })
211
250
 
212
251
  if (autoRoundValues && isNumeric) {
213
252
  valAbs = autoRound(valAbs)
214
253
  }
215
-
216
- //console.log('norm', prop, valAbs, 'val', val, unit, isHorizontal, isVertical, width, height, 'isNumeric', isNumeric);
217
254
  }
218
255
  }
219
256
  valsNew.push(valAbs)
@@ -423,23 +460,25 @@ export function filterSvgElProps(elNodename = '', props = {}, {
423
460
  allowAriaAtts = false,
424
461
  cleanUpStrokes = true,
425
462
  //include = ['id', 'class'],
426
- include=[],
427
- removeIds=false,
428
- removeClassNames=false,
463
+ include = [],
464
+ removeIds = false,
465
+ removeClassNames = false,
429
466
  exclude = [],
467
+ inheritedProps = null,
430
468
  } = {}) {
431
469
  let propsFiltered = {}
432
470
  let remove = [];
433
471
 
434
- if(!removeIds) include.push('id')
435
- if(!removeClassNames) include.push('class')
472
+ if (!removeIds) include.push('id')
473
+ if (!removeClassNames) include.push('class')
436
474
  //console.log('???include', 'removeIds', removeIds, include);
437
475
 
476
+
438
477
  // allow defaults for nested
439
478
  //removeDefaults = false;
440
479
 
441
- let noStrokeColor = cleanUpStrokes ? (props['stroke'] === undefined) : false;
442
- //console.log('noStrokeColor', elNodename, 'cleanUpStrokes', cleanUpStrokes);
480
+ let noStrokeColor = cleanUpStrokes ? (props['stroke'] === undefined || props['stroke'][0] === 'none') : false;
481
+ //console.log('noStrokeColor', elNodename, 'cleanUpStrokes', cleanUpStrokes, 'noStrokeColor', noStrokeColor);
443
482
 
444
483
  for (let prop in props) {
445
484
  let values = props[prop]
@@ -451,13 +490,16 @@ export function filterSvgElProps(elNodename = '', props = {}, {
451
490
  (attLookup.atts[prop] ? attLookup.atts[prop].includes(elNodename) : false) :
452
491
  false;
453
492
 
493
+
454
494
  // remove null transforms
455
495
  if (prop === 'transform' && value === 'matrix(1 0 0 1 0 0)') isValid = false;
456
496
 
457
497
  // allow data attributes
458
- let isDataAtt = allowDataAtts ? prop.startsWith('data-') : false;
459
- let isMeta = allowMeta && prop === 'title'
460
- let isAria = allowAriaAtts && prop.startsWith('aria-')
498
+ let isDataAtt = prop.startsWith('data-') ? true : false;
499
+ let isMeta = prop === 'title'
500
+ let isAria = prop.startsWith('aria-')
501
+
502
+ if ((allowDataAtts && isDataAtt) || (allowAriaAtts && isAria) || (allowMeta && isMeta)) continue
461
503
 
462
504
  // filter out defaults
463
505
  let isDefault = removeDefaults ?
@@ -468,16 +510,7 @@ export function filterSvgElProps(elNodename = '', props = {}, {
468
510
 
469
511
  if (isDefault || isDataAtt || isMeta || isAria || isFutileStroke) isValid = false
470
512
  if (include.includes(prop)) isValid = true;
471
-
472
- //console.log('!valid', prop, isValid);
473
-
474
-
475
- /*
476
- if (isDataAtt || include.includes(prop)) isValid = true;
477
- if (isDefault) isValid = false
478
- if (exclude.length && exclude.includes(prop)) isValid = false;
479
- if (noStrokeColor && strokeAtts.includes(prop)) isValid = false
480
- */
513
+ if (exclude.includes(prop)) isValid = false
481
514
 
482
515
 
483
516
  if (isValid) {
@@ -489,23 +522,15 @@ export function filterSvgElProps(elNodename = '', props = {}, {
489
522
  }
490
523
  }
491
524
 
492
- /*
493
- // set explicit stroke width when disabled by stroke color
494
- if (propsFiltered['stroke'] && propsFiltered['stroke'][0] === 'none') {
495
- propsFiltered['stroke-width'] = [1]
496
- remove.push('stroke', 'stroke-width')
497
- console.log('remove', remove);
498
- }
499
- */
500
-
501
-
502
- //remove=[]
503
525
  return { propsFiltered, remove }
504
526
  }
505
527
 
506
528
 
507
529
  export function parseValue(valStr = '') {
508
- let valArr = valStr.split(/,| /);
530
+ //exclude url or var functions or font family
531
+ //let exclude = ['font-family', 'url', 'var'];
532
+ valStr = valStr.replace('!important', '');
533
+ let valArr = (valStr.includes("'") || valStr.includes('(') || valStr.includes(')')) ? [valStr] : valStr.split(/,| /).filter(Boolean);
509
534
 
510
535
  for (let i = 0; i < valArr.length; i++) {
511
536
 
@@ -0,0 +1,67 @@
1
+ import { getElementAtts } from "../svg-getAttributes";
2
+ import { getDistance } from "./geometry";
3
+ import { getEllipseLength, getPolygonLength } from "./geometry_length";
4
+ import { parsePathDataNormalized } from "./pathData_convert";
5
+ import { getPathDataLength } from "./pathData_getLength";
6
+ import { getPathDataFromEl, rectToPathData } from "./pathData_parse_els";
7
+ import { normalizePoly } from "./poly_normalize";
8
+
9
+ export function getElementLength(el, {
10
+ props = {},
11
+ pathLength = 0,
12
+ } = {}) {
13
+
14
+
15
+ let nodeName = el.nodeName;
16
+ let len = 0;
17
+
18
+ props = JSON.parse(JSON.stringify(props))
19
+
20
+ for (let prop in props) {
21
+ if (props[prop] && props[prop].length && props[prop].length === 1) {
22
+ props[prop] = props[prop][0]
23
+ //console.log(prop, props[prop]);
24
+ }
25
+ }
26
+
27
+ //console.log(props);
28
+ let { x = 0, y = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0, width = 0, height = 0, r = 0, rx = 0, ry = 0, cx = 0, cy = 0 } = props;
29
+
30
+ let pts = nodeName === 'polygon' || nodeName === 'polyline' ? el.getAttribute('points') : [];
31
+ let isPolygon = nodeName === 'polygon';
32
+ if (pts.length) {
33
+ pts = normalizePoly(pts);
34
+ }
35
+
36
+ // we need to convert rects with corner rounding
37
+ let pathData = []
38
+ if (nodeName === 'rect' && (rx || ry)) {
39
+ pathData = rectToPathData(x, y, width, height, rx, ry)
40
+ nodeName = 'path'
41
+ }
42
+
43
+ switch (nodeName) {
44
+ case 'line':
45
+ len = getDistance({ x: x1, y: y1 }, { x: x2, y: y2 });
46
+ break;
47
+ case 'rect':
48
+ len = width * 2 + height * 2;
49
+ break;
50
+ case 'circle':
51
+ len = 2 * Math.PI * r;
52
+ break;
53
+ case 'ellipse':
54
+ len = getEllipseLength(rx, ry);
55
+ break;
56
+ case 'polygon':
57
+ case 'polyline':
58
+ len = getPolygonLength(pts, isPolygon)
59
+ break;
60
+ case 'path':
61
+ pathData = pathData.length ? pathData : parsePathDataNormalized(el.getAttribute('d'));
62
+ len = getPathDataLength(pathData);
63
+ break;
64
+ }
65
+
66
+ return len
67
+ }