Skip to content

Commit 0bc7d77

Browse files
committed
refactor(renderer): split insert/remove of views to smaller methods
methods for insert/remove from: - internal view queue (NgElements) - visual tree (NgViews)
1 parent ee29397 commit 0bc7d77

File tree

1 file changed

+74
-53
lines changed

1 file changed

+74
-53
lines changed

nativescript-angular/view-util.ts

Lines changed: 74 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -55,92 +55,113 @@ export class ViewUtil {
5555
}
5656

5757
public insertChild(parent: NgView, child: NgElement, previous?: NgElement, next?: NgElement) {
58-
// handle invisible nodes..
5958
if (!parent) {
6059
return;
6160
}
6261

63-
if (child instanceof InvisibleNode) {
64-
child.templateParent = parent;
65-
}
62+
this.addToQueue(parent, child, previous, next);
6663

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);
7368
}
69+
}
7470

75-
// update queue if there is next
71+
private addToQueue(parent: NgElement, child: NgElement, previous: NgElement, next: NgElement) {
7672
if (next) {
77-
previous.nextSibling = child;
78-
child.nextSibling = next;
73+
this.insertBetween(child, previous, next);
74+
} else {
75+
this.appendToQueue(parent, child);
7976
}
77+
}
8078

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;
8391
}
8492

85-
// create actual view
93+
parent.lastChild = view;
94+
}
95+
96+
private addToVisualTree(parent: NgView, child: NgView, next: NgView): void {
8697
if (parent.meta && parent.meta.insertChild) {
8798
parent.meta.insertChild(parent, child);
8899
} 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);
106101
} else if (isContentView(parent)) {
107102
parent.content = child;
108103
} else if (parent && (<any>parent)._addChildFromBuilder) {
109104
(<any>parent)._addChildFromBuilder(child.nodeName, child);
110105
}
111106
}
112107

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+
113125
public removeChild(parent: NgView, child: NgElement) {
114-
if (!parent || isDetachedElement(child)) {
115-
console.log("skip the removal of detached element")
126+
if (!parent) {
116127
return;
117128
}
118129

119130
if (parent.meta && parent.meta.removeChild) {
120131
parent.meta.removeChild(parent, child);
121132
} 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+
}
127140

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+
}
132146

133-
parent.removeChild(child);
147+
this.removeFromQueue(parent, child, index);
148+
parent.removeChild(child);
149+
}
134150

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;
143155
}
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;
144165
}
145166

146167
public getChildIndex(parent: any, child: NgView) {

0 commit comments

Comments
 (0)