1
1
'use strict' ;
2
2
3
- const { detachNodeFromParent } = require ( '../lib/xast.js' ) ;
3
+ /**
4
+ * @typedef {import('../lib/types').XastChild } XastChild
5
+ */
6
+
4
7
const { collectStylesheet, computeStyle } = require ( '../lib/style.js' ) ;
5
8
const { path2js, js2path, intersects } = require ( './_path.js' ) ;
6
9
@@ -25,12 +28,18 @@ exports.fn = (root, params) => {
25
28
return {
26
29
element : {
27
30
enter : ( node ) => {
28
- let prevChild = null ;
31
+ if ( node . children . length <= 1 ) {
32
+ return ;
33
+ }
34
+
35
+ /** @type {XastChild[] } */
36
+ const elementsToRemove = [ ] ;
37
+ let prevChild = node . children [ 0 ] ;
38
+
39
+ for ( let i = 1 ; i < node . children . length ; i ++ ) {
40
+ const child = node . children [ i ] ;
29
41
30
- for ( const child of node . children ) {
31
- // skip if previous element is not path or contains animation elements
32
42
if (
33
- prevChild == null ||
34
43
prevChild . type !== 'element' ||
35
44
prevChild . name !== 'path' ||
36
45
prevChild . children . length !== 0 ||
@@ -40,7 +49,6 @@ exports.fn = (root, params) => {
40
49
continue ;
41
50
}
42
51
43
- // skip if element is not path or contains animation elements
44
52
if (
45
53
child . type !== 'element' ||
46
54
child . name !== 'path' ||
@@ -51,7 +59,6 @@ exports.fn = (root, params) => {
51
59
continue ;
52
60
}
53
61
54
- // preserve paths with markers
55
62
const computedStyle = computeStyle ( stylesheet , child ) ;
56
63
if (
57
64
computedStyle [ 'marker-start' ] ||
@@ -62,36 +69,45 @@ exports.fn = (root, params) => {
62
69
continue ;
63
70
}
64
71
65
- const prevChildAttrs = Object . keys ( prevChild . attributes ) ;
66
72
const childAttrs = Object . keys ( child . attributes ) ;
67
- let attributesAreEqual = prevChildAttrs . length === childAttrs . length ;
68
- for ( const name of childAttrs ) {
69
- if ( name !== 'd' ) {
70
- if (
71
- prevChild . attributes [ name ] == null ||
72
- prevChild . attributes [ name ] !== child . attributes [ name ]
73
- ) {
74
- attributesAreEqual = false ;
75
- }
76
- }
73
+ if ( childAttrs . length !== Object . keys ( prevChild . attributes ) . length ) {
74
+ prevChild = child ;
75
+ continue ;
76
+ }
77
+
78
+ const areAttrsEqual = childAttrs . some ( ( attr ) => {
79
+ return (
80
+ attr !== 'd' &&
81
+ prevChild . type === 'element' &&
82
+ prevChild . attributes [ attr ] !== child . attributes [ attr ]
83
+ ) ;
84
+ } ) ;
85
+
86
+ if ( areAttrsEqual ) {
87
+ prevChild = child ;
88
+ continue ;
77
89
}
90
+
78
91
const prevPathJS = path2js ( prevChild ) ;
79
92
const curPathJS = path2js ( child ) ;
80
93
81
- if (
82
- attributesAreEqual &&
83
- ( force || ! intersects ( prevPathJS , curPathJS ) )
84
- ) {
85
- js2path ( prevChild , prevPathJS . concat ( curPathJS ) , {
94
+ if ( force || ! intersects ( prevPathJS , curPathJS ) ) {
95
+ prevPathJS . push ( ...curPathJS ) ;
96
+ js2path ( prevChild , prevPathJS , {
86
97
floatPrecision,
87
98
noSpaceAfterFlags,
88
99
} ) ;
89
- detachNodeFromParent ( child , node ) ;
100
+
101
+ elementsToRemove . push ( child ) ;
90
102
continue ;
91
103
}
92
104
93
105
prevChild = child ;
94
106
}
107
+
108
+ node . children = node . children . filter (
109
+ ( child ) => ! elementsToRemove . includes ( child ) ,
110
+ ) ;
95
111
} ,
96
112
} ,
97
113
} ;
0 commit comments