11import { updateDomProperties } from "./dom-utils" ;
2+ import { TEXT_ELEMENT } from "./element" ;
3+ import { createPublicInstance } from "./component" ;
24
35let rootInstance = null ;
46
@@ -8,7 +10,7 @@ export function render(element, container) {
810 rootInstance = nextInstance ;
911}
1012
11- function reconcile ( parentDom , instance , element ) {
13+ export function reconcile ( parentDom , instance , element ) {
1214 if ( instance == null ) {
1315 // Create instance
1416 const newInstance = instantiate ( element ) ;
@@ -18,17 +20,27 @@ function reconcile(parentDom, instance, element) {
1820 // Remove instance
1921 parentDom . removeChild ( instance . dom ) ;
2022 return null ;
21- } else if ( instance . element . type === element . type ) {
22- // Update instance
23+ } else if ( instance . element . type !== element . type ) {
24+ // Replace instance
25+ const newInstance = instantiate ( element ) ;
26+ parentDom . replaceChild ( newInstance . dom , instance . dom ) ;
27+ return newInstance ;
28+ } else if ( typeof element . type === "string" ) {
29+ // Update dom instance
2330 updateDomProperties ( instance . dom , instance . element . props , element . props ) ;
2431 instance . childInstances = reconcileChildren ( instance , element ) ;
2532 instance . element = element ;
2633 return instance ;
2734 } else {
28- // Replace instance
29- const newInstance = instantiate ( element ) ;
30- parentDom . replaceChild ( newInstance . dom , instance . dom ) ;
31- return newInstance ;
35+ //Update composite instance
36+ instance . publicInstance . props = element . props ;
37+ const childElement = instance . publicInstance . render ( ) ;
38+ const oldChildInstance = instance . childInstance ;
39+ const childInstance = reconcile ( parentDom , oldChildInstance , childElement ) ;
40+ instance . dom = childInstance . dom ;
41+ instance . childInstance = childInstance ;
42+ instance . element = element ;
43+ return instance ;
3244 }
3345}
3446
@@ -49,21 +61,33 @@ function reconcileChildren(instance, element) {
4961
5062function instantiate ( element ) {
5163 const { type, props } = element ;
64+ const isDomElement = typeof type === "string" ;
5265
53- // Create DOM element
54- const isTextElement = type === "TEXT ELEMENT" ;
55- const dom = isTextElement
56- ? document . createTextNode ( "" )
57- : document . createElement ( type ) ;
66+ if ( isDomElement ) {
67+ // Instantiate DOM element
68+ const isTextElement = type === TEXT_ELEMENT ;
69+ const dom = isTextElement
70+ ? document . createTextNode ( "" )
71+ : document . createElement ( type ) ;
5872
59- updateDomProperties ( dom , [ ] , props ) ;
73+ updateDomProperties ( dom , [ ] , props ) ;
6074
61- // Instantiate and append children
62- const childElements = props . children || [ ] ;
63- const childInstances = childElements . map ( instantiate ) ;
64- const childDoms = childInstances . map ( childInstance => childInstance . dom ) ;
65- childDoms . forEach ( childDom => dom . appendChild ( childDom ) ) ;
75+ const childElements = props . children || [ ] ;
76+ const childInstances = childElements . map ( instantiate ) ;
77+ const childDoms = childInstances . map ( childInstance => childInstance . dom ) ;
78+ childDoms . forEach ( childDom => dom . appendChild ( childDom ) ) ;
6679
67- const instance = { dom, element, childInstances } ;
68- return instance ;
80+ const instance = { dom, element, childInstances } ;
81+ return instance ;
82+ } else {
83+ // Instantiate component element
84+ const instance = { } ;
85+ const publicInstance = createPublicInstance ( element , instance ) ;
86+ const childElement = publicInstance . render ( ) ;
87+ const childInstance = instantiate ( childElement ) ;
88+ const dom = childInstance . dom ;
89+
90+ Object . assign ( instance , { dom, element, childInstance, publicInstance } ) ;
91+ return instance ;
92+ }
6993}
0 commit comments