@@ -27,9 +27,9 @@ const attributeBlacklist = [
2727]
2828
2929/**
30- * Wilderness' accepted node types.
30+ * Wilderness' accepted node types core props .
3131 */
32- const nodeTypes = [
32+ const nodeCoreProps = [
3333 {
3434 type : 'circle' ,
3535 coreProps : [ 'cx' , 'cy' , 'r' ]
@@ -64,6 +64,11 @@ const nodeTypes = [
6464 }
6565]
6666
67+ /**
68+ * Wilderness' accepted node types.
69+ */
70+ const nodeTypes = nodeCoreProps . map ( ( { type } ) => type )
71+
6772/**
6873 * Core props for the defined node type.
6974 *
@@ -74,7 +79,7 @@ const nodeTypes = [
7479 * @example
7580 * coreProps('rect')
7681 */
77- const coreProps = type => nodeTypes . filter ( node => node . type === type ) [ 0 ] . coreProps
82+ const coreProps = type => nodeCoreProps . filter ( node => node . type === type ) [ 0 ] . coreProps
7883
7984/**
8085 * Diffs two objects and returns an object with remove and update props.
@@ -88,16 +93,21 @@ const coreProps = type => nodeTypes.filter(node => node.type === type)[ 0 ].core
8893 * diff(current, next)
8994 */
9095const diff = ( current , next ) => {
91- const currentKeys = Object . keys ( current )
92- const nextKeys = Object . keys ( next )
93- const remove = currentKeys . filter ( k => nextKeys . indexOf ( k ) === - 1 )
96+ const result = { remove : [ ] , update : [ ] }
9497
95- const update = nextKeys . filter ( k => (
96- currentKeys . indexOf ( k ) !== - 1 ||
97- current [ k ] !== next [ k ]
98- ) )
98+ for ( let currentKey in current ) {
99+ if ( typeof next [ currentKey ] === 'undefined' ) {
100+ result . remove . push ( currentKey )
101+ }
102+ }
99103
100- return { remove, update }
104+ for ( let nextKey in next ) {
105+ if ( typeof current [ nextKey ] === 'undefined' || current [ nextKey ] !== next [ nextKey ] ) {
106+ result . update . push ( nextKey )
107+ }
108+ }
109+
110+ return result
101111}
102112
103113/**
@@ -162,9 +172,9 @@ const node = frameShp => {
162172 ? groupNode ( childFrameShapes )
163173 : pathNode ( points )
164174
165- Object . keys ( attributes ) . map ( attr => {
175+ for ( let attr in attributes ) {
166176 el . setAttribute ( attr , attributes [ attr ] )
167- } )
177+ }
168178
169179 return el
170180 }
@@ -257,13 +267,13 @@ const plainShapeObjectFromAttrs = (type, attributes) => {
257267 const props = coreProps ( type )
258268 const result = { type }
259269
260- Object . keys ( attributes ) . map ( k => {
270+ for ( let k in attributes ) {
261271 if ( props . indexOf ( k ) !== - 1 ) {
262272 const v = attributes [ k ]
263273 const n = Number ( v )
264274 result [ k ] = Number . isNaN ( n ) ? v : n
265275 }
266- } )
276+ }
267277
268278 return result
269279}
@@ -283,11 +293,11 @@ const removeCoreProps = (type, attributes) => {
283293 const props = coreProps ( type )
284294 const result = { }
285295
286- Object . keys ( attributes ) . map ( k => {
296+ for ( let k in attributes ) {
287297 if ( props . indexOf ( k ) === - 1 ) {
288298 result [ k ] = attributes [ k ]
289299 }
290- } )
300+ }
291301
292302 return result
293303}
@@ -301,40 +311,45 @@ const removeCoreProps = (type, attributes) => {
301311 * @returns {Node }
302312 *
303313 * @example
304- * updateNode()
314+ * updateNode(el, frameShape )
305315 */
306316const updateNode = ( el , frameShp ) => {
307- if ( validNode ( el ) && validFrameShape ( frameShp ) ) {
308- const { attributes : nextAttributes , childFrameShapes, points } = frameShp
317+ if ( __DEV__ ) {
318+ if ( ! validNode ( el ) ) {
319+ throw new TypeError ( `The first argument of the updateNode function must be a valid DOM node` )
320+ }
309321
310- if ( childFrameShapes ) {
311- const childNodes = [ ...el . childNodes ] . filter ( validNodeType )
322+ if ( ! validFrameShape ( frameShp ) ) {
323+ throw new TypeError ( `The second argument of the updateNode function must be a valid frameShape` )
324+ }
325+ }
312326
313- childFrameShapes . map ( ( childFrameShape , i ) => {
314- updateNode ( childNodes [ i ] , childFrameShape )
315- } )
316- } else {
317- const nextPath = toPath ( points )
327+ if ( frameShp . childFrameShapes ) {
328+ const childNodes = [ ...el . childNodes ] . filter ( validNodeType )
318329
319- if ( nextPath !== el . getAttribute ( 'd' ) ) {
320- el . setAttribute ( 'd' , nextPath )
321- }
330+ for ( let i = 0 , l = frameShp . childFrameShapes . length ; i < l ; i ++ ) {
331+ updateNode ( childNodes [ i ] , frameShp . childFrameShapes [ i ] )
322332 }
333+ } else {
334+ const nextPath = toPath ( frameShp . points )
323335
324- const { attributes : currentAttributes } = el
325-
326- const { remove, update } = diff ( currentAttributes , nextAttributes )
336+ if ( nextPath !== el . getAttribute ( 'd' ) ) {
337+ el . setAttribute ( 'd' , nextPath )
338+ }
339+ }
327340
328- remove . map ( attr => {
329- el . removeAttribute ( attr )
330- } )
341+ const result = diff ( el . attributes , frameShp . attributes )
331342
332- update . map ( attr => {
333- el . setAttribute ( attr , nextAttributes [ attr ] )
334- } )
343+ for ( let i = 0 , l = result . remove . length ; i < l ; i ++ ) {
344+ el . removeAttribute ( result . remove [ i ] )
345+ }
335346
336- return el
347+ for ( let i = 0 , l = result . update . length ; i < l ; i ++ ) {
348+ const attr = result . update [ i ]
349+ el . setAttribute ( attr , frameShp . attributes [ attr ] )
337350 }
351+
352+ return el
338353}
339354
340355/**
@@ -425,6 +440,6 @@ const validNode = el => {
425440 * @example
426441 * validNodeType(node)
427442 */
428- const validNodeType = ( { nodeName } ) => nodeTypes . map ( ( { type } ) => type ) . indexOf ( nodeName ) !== - 1
443+ const validNodeType = ( { nodeName } ) => nodeTypes . indexOf ( nodeName ) !== - 1
429444
430445export { frameShape , node , plainShapeObject , updateNode }
0 commit comments