@@ -79,6 +79,30 @@ const nodeTypes = [
7979 */
8080const coreProps = type => nodeTypes . filter ( node => node . type === type ) [ 0 ] . coreProps
8181
82+ /**
83+ * Diffs two objects and returns an object with remove and update props.
84+ *
85+ * @param {Object } current
86+ * @param {Object } next
87+ *
88+ * @returns {Object }
89+ *
90+ * @example
91+ * diff(current, next)
92+ */
93+ const diff = ( current , next ) => {
94+ const currentKeys = Object . keys ( current )
95+ const nextKeys = Object . keys ( next )
96+ const remove = currentKeys . filter ( k => nextKeys . indexOf ( k ) === - 1 )
97+
98+ const update = nextKeys . filter ( k => (
99+ currentKeys . indexOf ( k ) !== - 1 ||
100+ current [ k ] !== next [ k ]
101+ ) )
102+
103+ return { remove, update }
104+ }
105+
82106/**
83107 * Creates a FrameShape from a Node.
84108 *
@@ -220,6 +244,47 @@ const removeCoreProps = (type, attributes) => {
220244 return result
221245}
222246
247+ /**
248+ * Updates a Node from a FrameShape.
249+ *
250+ * @param {Node } el
251+ * @param {FrameShape } frameShape
252+ *
253+ * @returns {Node }
254+ *
255+ * @example
256+ * updateNode()
257+ */
258+ const updateNode = ( el , { attributes : nextAttributes , childFrameShapes, points } ) => {
259+ if ( childFrameShapes ) {
260+ const childNodes = [ ...el . childNodes ] . filter ( validNode )
261+
262+ childFrameShapes . map ( ( childFrameShape , i ) => {
263+ updateNode ( childNodes [ i ] , childFrameShape )
264+ } )
265+ } else {
266+ const nextPath = toPath ( points )
267+
268+ if ( nextPath !== el . getAttribute ( 'd' ) ) {
269+ el . setAttribute ( 'd' , nextPath )
270+ }
271+ }
272+
273+ const { attributes : currentAttributes } = el
274+
275+ const { remove, update } = diff ( currentAttributes , nextAttributes )
276+
277+ remove . map ( attr => {
278+ el . removeAttribute ( attr )
279+ } )
280+
281+ update . map ( attr => {
282+ el . setAttribute ( attr , nextAttributes [ attr ] )
283+ } )
284+
285+ return el
286+ }
287+
223288/**
224289 * Is the node one of the accepted node types?
225290 *
@@ -232,4 +297,4 @@ const removeCoreProps = (type, attributes) => {
232297 */
233298const validNode = ( { nodeName } ) => nodeTypes . map ( ( { name } ) => name ) . indexOf ( nodeName ) !== - 1
234299
235- export { frameShape , node }
300+ export { frameShape , node , updateNode }
0 commit comments