@@ -55,92 +55,113 @@ export class ViewUtil {
55
55
}
56
56
57
57
public insertChild ( parent : NgView , child : NgElement , previous ?: NgElement , next ?: NgElement ) {
58
- // handle invisible nodes..
59
58
if ( ! parent ) {
60
59
return ;
61
60
}
62
61
63
- if ( child instanceof InvisibleNode ) {
64
- child . templateParent = parent ;
65
- }
62
+ this . addToQueue ( parent , child , previous , next ) ;
66
63
67
- // add to end of queue if no next
68
- if ( parent && ! next ) {
69
- if ( parent . lastChild ) {
70
- parent . lastChild . nextSibling = child ;
71
- }
72
- parent . lastChild = child ;
64
+ if ( isDetachedElement ( child ) ) {
65
+ child . templateParent = parent ;
66
+ } else {
67
+ this . addToVisualTree ( parent , child , next ) ;
73
68
}
69
+ }
74
70
75
- // update queue if there is next
71
+ private addToQueue ( parent : NgElement , child : NgElement , previous : NgElement , next : NgElement ) {
76
72
if ( next ) {
77
- previous . nextSibling = child ;
78
- child . nextSibling = next ;
73
+ this . insertBetween ( child , previous , next ) ;
74
+ } else {
75
+ this . appendToQueue ( parent , child ) ;
79
76
}
77
+ }
80
78
81
- if ( isDetachedElement ( child ) ) {
82
- return ;
79
+ private insertBetween (
80
+ view : NgElement ,
81
+ previous : NgElement ,
82
+ next : NgElement
83
+ ) : void {
84
+ previous . nextSibling = view ;
85
+ view . nextSibling = next ;
86
+ }
87
+
88
+ private appendToQueue ( parent : NgElement , view : NgElement ) {
89
+ if ( parent . lastChild ) {
90
+ parent . lastChild . nextSibling = view ;
83
91
}
84
92
85
- // create actual view
93
+ parent . lastChild = view ;
94
+ }
95
+
96
+ private addToVisualTree ( parent : NgView , child : NgView , next : NgView ) : void {
86
97
if ( parent . meta && parent . meta . insertChild ) {
87
98
parent . meta . insertChild ( parent , child ) ;
88
99
} else if ( isLayout ( parent ) ) {
89
- // remove child if already exists
90
- if ( child . parent === parent ) {
91
- const index = parent . getChildIndex ( child ) ;
92
- if ( index !== - 1 ) {
93
- parent . removeChild ( child ) ;
94
- }
95
- }
96
-
97
- // insert child
98
-
99
- if ( next ) {
100
- const atIndex = parent . getChildIndex ( next ) ;
101
- parent . insertChild ( child , atIndex ) ;
102
- } else {
103
- parent . addChild ( child ) ;
104
- }
105
-
100
+ this . insertToLayout ( parent , child , next ) ;
106
101
} else if ( isContentView ( parent ) ) {
107
102
parent . content = child ;
108
103
} else if ( parent && ( < any > parent ) . _addChildFromBuilder ) {
109
104
( < any > parent ) . _addChildFromBuilder ( child . nodeName , child ) ;
110
105
}
111
106
}
112
107
108
+ private insertToLayout (
109
+ parent : NgLayoutBase ,
110
+ child : NgView ,
111
+ next : NgView
112
+ ) : void {
113
+ if ( child . parent === parent ) {
114
+ this . removeLayoutChild ( parent , child ) ;
115
+ }
116
+
117
+ if ( next ) {
118
+ const index = parent . getChildIndex ( next ) ;
119
+ parent . insertChild ( child , index ) ;
120
+ } else {
121
+ parent . addChild ( child ) ;
122
+ }
123
+ }
124
+
113
125
public removeChild ( parent : NgView , child : NgElement ) {
114
- if ( ! parent || isDetachedElement ( child ) ) {
115
- console . log ( "skip the removal of detached element" )
126
+ if ( ! parent ) {
116
127
return ;
117
128
}
118
129
119
130
if ( parent . meta && parent . meta . removeChild ) {
120
131
parent . meta . removeChild ( parent , child ) ;
121
132
} else if ( isLayout ( parent ) ) {
122
- console . log ( "remove child from layout" )
123
- const atIndex = parent . getChildIndex ( child ) ;
124
- if ( atIndex === - 1 ) {
125
- return ;
126
- }
133
+ this . removeLayoutChild ( parent , child ) ;
134
+ } else if ( isContentView ( parent ) && parent . content === child ) {
135
+ parent . content = null ;
136
+ } else if ( isView ( parent ) ) {
137
+ parent . _removeView ( child ) ;
138
+ }
139
+ }
127
140
128
- if ( atIndex !== 0 ) {
129
- const previous = parent . getChildAt ( atIndex - 1 ) as NgElement ;
130
- previous . nextSibling = child . nextSibling ;
131
- }
141
+ private removeLayoutChild ( parent : NgLayoutBase , child : NgView ) : void {
142
+ const index = parent . getChildIndex ( child ) ;
143
+ if ( index === - 1 ) {
144
+ return ;
145
+ }
132
146
133
- parent . removeChild ( child ) ;
147
+ this . removeFromQueue ( parent , child , index ) ;
148
+ parent . removeChild ( child ) ;
149
+ }
134
150
135
- } else if ( isContentView ( parent ) ) {
136
- console . log ( "remove child from content view" ) ;
137
- if ( parent . content === child ) {
138
- parent . content = null ;
139
- }
140
- } else if ( isView ( parent ) ) {
141
- console . log ( "remove child from view element" ) ;
142
- parent . _removeView ( child ) ;
151
+ private removeFromQueue ( parent : NgLayoutBase , child : NgView , index : number ) {
152
+ let previous = parent . getChildAt ( index - 1 ) as NgElement ;
153
+ if ( ! previous ) {
154
+ return ;
143
155
}
156
+
157
+ // since detached elements are not added to the visual tree,
158
+ // we need to find the actual previous sibling of the view,
159
+ // which may be an invisible node
160
+ while ( previous && previous !== child && isDetachedElement ( previous . nextSibling ) ) {
161
+ previous = previous . nextSibling ;
162
+ }
163
+
164
+ previous . nextSibling = child . nextSibling ;
144
165
}
145
166
146
167
public getChildIndex ( parent : any , child : NgView ) {
0 commit comments