@@ -8,17 +8,21 @@ import {
88 toHyphenCase
99} from 'web-utility' ;
1010
11- import { DataObject , VDOMNode , VNode } from './VDOM' ;
11+ import { DataObject , VNode } from './VDOM' ;
1212
1313export class DOMRenderer {
1414 eventPattern = / ^ o n [ A - Z ] / ;
1515 ariaPattern = / ^ a i r a [ A - Z ] / ;
1616
17+ protected treeCache = new WeakMap < Node , VNode > ( ) ;
18+
1719 protected keyOf = ( { key, text, props, selector } : VNode , index ?: number ) =>
18- key || props ?. id || text || ( selector && selector + index ) ;
20+ key ?. toString ( ) || props ?. id || text || ( selector && selector + index ) ;
1921
20- protected vNodeOf = ( list : VNode [ ] , key : string ) =>
21- list . find ( ( vNode , index ) => this . keyOf ( vNode , index ) + '' === key ) ;
22+ protected vNodeOf = ( list : VNode [ ] , key ?: VNode [ 'key' ] ) =>
23+ list . find (
24+ ( vNode , index ) => `${ this . keyOf ( vNode , index ) } ` === String ( key )
25+ ) ;
2226
2327 protected propsKeyOf = ( key : string ) =>
2428 key . startsWith ( 'aria-' )
@@ -27,12 +31,12 @@ export class DOMRenderer {
2731 ? key . toLowerCase ( )
2832 : key ;
2933
30- protected updateProps < T extends DataObject > (
31- node : T ,
32- oldProps : DataObject = { } ,
33- newProps : DataObject = { } ,
34- onDelete ?: ( node : T , key : string ) => any ,
35- onAdd ?: ( node : T , key : string , value : any ) => any
34+ protected updateProps < N extends DataObject , P extends DataObject > (
35+ node : N ,
36+ oldProps = { } as P ,
37+ newProps = { } as P ,
38+ onDelete ?: ( node : N , key : string ) => any ,
39+ onAdd ?: ( node : N , key : string , value : any ) => any
3640 ) {
3741 const { group } = diffKeys (
3842 Object . keys ( oldProps ) ,
@@ -58,8 +62,19 @@ export class DOMRenderer {
5862 ? document . createElement ( vNode . tagName , { is : vNode . is } )
5963 : document . createDocumentFragment ( ) ;
6064
61- return this . patch ( { tagName : vNode . tagName , node : vNode . node } , vNode )
62- . node ;
65+ const { node } = this . patch (
66+ { tagName : vNode . tagName , node : vNode . node } ,
67+ vNode
68+ ) ;
69+ if ( node ) vNode . ref ?.( node ) ;
70+
71+ return node ;
72+ }
73+
74+ deleteNode ( { node, children } : VNode ) {
75+ if ( node instanceof DocumentFragment )
76+ children ?. forEach ( this . deleteNode ) ;
77+ else ( node as ChildNode ) ?. remove ( ) ;
6378 }
6479
6580 protected updateChildren (
@@ -73,7 +88,7 @@ export class DOMRenderer {
7388 ) ;
7489
7590 for ( const [ key ] of group [ DiffStatus . Old ] || [ ] )
76- ( this . vNodeOf ( oldList , key ) ?. node as ChildNode ) ?. remove ( ) ;
91+ this . deleteNode ( this . vNodeOf ( oldList , key ) ) ;
7792
7893 const newNodes = newList . map ( ( vNode , index ) => {
7994 const key = this . keyOf ( vNode , index ) ;
@@ -101,7 +116,7 @@ export class DOMRenderer {
101116 : node . removeAttribute (
102117 this . ariaPattern . test ( key )
103118 ? toHyphenCase ( key )
104- : VDOMNode . propsMap [ key ] || key
119+ : VNode . propsMap [ key ] || key
105120 ) ,
106121 ( node , key , value ) => {
107122 // @ts -ignore
@@ -127,9 +142,13 @@ export class DOMRenderer {
127142 }
128143
129144 render ( vNode : VNode , node : Element = document . body ) {
130- const root = new VDOMNode ( node ) ;
145+ var root = this . treeCache . get ( node ) || VNode . fromDOM ( node ) ;
146+
147+ root = this . patch ( root , { ...root , children : [ vNode ] } ) ;
148+
149+ this . treeCache . set ( node , root ) ;
131150
132- return this . patch ( root , { ... root , children : [ vNode ] } ) ;
151+ return root ;
133152 }
134153
135154 renderToStaticMarkup ( tree : VNode ) {
0 commit comments