Skip to content

Commit e92918b

Browse files
committed
feat(change_detector): split light dom and shadow dom children
1 parent 723e8fd commit e92918b

File tree

4 files changed

+86
-36
lines changed

4 files changed

+86
-36
lines changed

modules/angular2/src/change_detection/abstract_change_detector.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,32 @@ import {BindingPropagationConfig} from './binding_propagation_config';
44
import {ChangeDetector, CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED} from './interfaces';
55

66
export class AbstractChangeDetector extends ChangeDetector {
7-
children:List;
7+
lightDomChildren:List;
8+
shadowDomChildren:List;
89
parent:ChangeDetector;
910
mode:string;
1011
bindingPropagationConfig:BindingPropagationConfig;
1112

1213
constructor() {
1314
super();
14-
this.children = [];
15+
this.lightDomChildren = [];
16+
this.shadowDomChildren = [];
1517
this.bindingPropagationConfig = new BindingPropagationConfig(this);
1618
this.mode = CHECK_ALWAYS;
1719
}
1820

1921
addChild(cd:ChangeDetector) {
20-
ListWrapper.push(this.children, cd);
22+
ListWrapper.push(this.lightDomChildren, cd);
2123
cd.parent = this;
2224
}
2325

2426
removeChild(cd:ChangeDetector) {
25-
ListWrapper.remove(this.children, cd);
27+
ListWrapper.remove(this.lightDomChildren, cd);
28+
}
29+
30+
addShadowDomChild(cd:ChangeDetector) {
31+
ListWrapper.push(this.shadowDomChildren, cd);
32+
cd.parent = this;
2633
}
2734

2835
remove() {
@@ -41,19 +48,30 @@ export class AbstractChangeDetector extends ChangeDetector {
4148
if (this.mode === DETACHED || this.mode === CHECKED) return;
4249

4350
this.detectChangesInRecords(throwOnChange);
44-
this._detectChangesInChildren(throwOnChange);
51+
52+
this._detectChangesInLightDomChildren(throwOnChange);
53+
4554
this.notifyOnAllChangesDone();
4655

56+
this._detectChangesInShadowDomChildren(throwOnChange);
57+
4758
if (this.mode === CHECK_ONCE) this.mode = CHECKED;
4859
}
4960

5061
detectChangesInRecords(throwOnChange:boolean){}
5162
notifyOnAllChangesDone(){}
5263

53-
_detectChangesInChildren(throwOnChange:boolean) {
54-
var children = this.children;
55-
for(var i = 0; i < children.length; ++i) {
56-
children[i]._detectChanges(throwOnChange);
64+
_detectChangesInLightDomChildren(throwOnChange:boolean) {
65+
var c = this.lightDomChildren;
66+
for(var i = 0; i < c.length; ++i) {
67+
c[i]._detectChanges(throwOnChange);
68+
}
69+
}
70+
71+
_detectChangesInShadowDomChildren(throwOnChange:boolean) {
72+
var c = this.shadowDomChildren;
73+
for(var i = 0; i < c.length; ++i) {
74+
c[i]._detectChanges(throwOnChange);
5775
}
5876
}
5977

modules/angular2/src/core/compiler/view.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ export class ProtoView {
350350
}
351351
}
352352

353+
//TODO: Tobias or Victor. Moving it into the constructor.
353354
// this work should be done the constructor of ProtoView once we separate
354355
// ProtoView and ProtoViewBuilder
355356
_getVariableBindings() {
@@ -367,6 +368,7 @@ export class ProtoView {
367368
return this._variableBindings;
368369
}
369370

371+
//TODO: Tobias or Victor. Moving it into the constructor.
370372
// this work should be done the constructor of ProtoView once we separate
371373
// ProtoView and ProtoViewBuilder
372374
_getDirectiveMementos() {

modules/angular2/test/change_detection/change_detection_spec.js

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ export function main() {
6262
}
6363

6464
describe(`${name} change detection`, () => {
65+
var dispatcher;
66+
67+
beforeEach(() => {
68+
dispatcher = new TestDispatcher();
69+
});
70+
6571
it('should do simple watching', () => {
6672
var person = new Person("misko");
6773
var c = createChangeDetector('name', 'name', person);
@@ -197,7 +203,6 @@ export function main() {
197203
var pcd = createProtoChangeDetector();
198204
var ast = parser.parseInterpolation("B{{a}}A", "location");
199205

200-
var dispatcher = new TestDispatcher();
201206
var cd = instantiate(pcd, dispatcher, [new BindingRecord(ast, "memo", null)]);
202207
cd.hydrate(new TestData("value"), null);
203208

@@ -250,7 +255,6 @@ export function main() {
250255
it("should notify the dispatcher when a group of records changes", () => {
251256
var pcd = createProtoChangeDetector();
252257

253-
var dispatcher = new TestDispatcher();
254258
var cd = instantiate(pcd, dispatcher, [
255259
new BindingRecord(ast("1 + 2"), "memo", dirMemento1),
256260
new BindingRecord(ast("10 + 20"), "memo", dirMemento1),
@@ -264,7 +268,7 @@ export function main() {
264268

265269
it("should notify the dispatcher before switching to the next group", () => {
266270
var pcd = createProtoChangeDetector();
267-
var dispatcher = new TestDispatcher();
271+
268272
var cd = instantiate(pcd, dispatcher, [
269273
new BindingRecord(ast("a()"), "a", dirMemento1),
270274
new BindingRecord(ast("b()"), "b", dirMemento2),
@@ -294,41 +298,60 @@ export function main() {
294298

295299
describe("onAllChangesDone", () => {
296300
it("should notify the dispatcher about processing all the children", () => {
297-
var pcd = createProtoChangeDetector();
298-
var dispatcher = new TestDispatcher();
299-
300301
var memento1 = new FakeDirectiveMemento(1, false);
301302
var memento2 = new FakeDirectiveMemento(2, true);
302303

303-
var cd = pcd.instantiate(dispatcher, [
304-
new BindingRecord(ast("1"), "a", memento1),
305-
new BindingRecord(ast("2"), "b", memento2)
306-
], null, [memento1, memento2]);
304+
var pcd = createProtoChangeDetector();
305+
var cd = pcd.instantiate(dispatcher, [], null, [memento1, memento2]);
307306

308307
cd.hydrate(null, null);
309308

310309
cd.detectChanges();
311310

312-
expect(dispatcher.loggedOnAllChangesDone).toEqual([memento2]);
311+
expect(dispatcher.loggedValues).toEqual([
312+
["onAllChangesDone", memento2]
313+
]);
313314
});
314315

315316
it("should notify in reverse order so the child is always notified before the parent", () => {
316-
var pcd = createProtoChangeDetector();
317-
var dispatcher = new TestDispatcher();
318-
319317
var memento1 = new FakeDirectiveMemento(1, true);
320318
var memento2 = new FakeDirectiveMemento(2, true);
321319

322-
var cd = pcd.instantiate(dispatcher, [
323-
new BindingRecord(ast("1"), "a", memento1),
324-
new BindingRecord(ast("2"), "b", memento2)
325-
], null, [memento1, memento2]);
320+
var pcd = createProtoChangeDetector();
321+
var cd = pcd.instantiate(dispatcher, [], null, [memento1, memento2]);
326322

327323
cd.hydrate(null, null);
328324

329325
cd.detectChanges();
330326

331-
expect(dispatcher.loggedOnAllChangesDone).toEqual([memento2, memento1]);
327+
expect(dispatcher.loggedValues).toEqual([
328+
["onAllChangesDone", memento2],
329+
["onAllChangesDone", memento1]
330+
]);
331+
});
332+
333+
it("should notify the dispatcher before processing shadow dom children", () => {
334+
var memento = new FakeDirectiveMemento(1, true);
335+
336+
var pcd = createProtoChangeDetector();
337+
var shadowDomChildPCD = createProtoChangeDetector();
338+
339+
var parent = pcd.instantiate(dispatcher, [], null, [memento]);
340+
var child = shadowDomChildPCD.instantiate(dispatcher, [
341+
new BindingRecord(ast("1"), "a", memento)], null, []);
342+
parent.addShadowDomChild(child);
343+
344+
parent.hydrate(null, null);
345+
child.hydrate(null, null);
346+
347+
parent.detectChanges();
348+
349+
// loggedValues contains everything that the dispatcher received
350+
// the first value is the directive memento passed into onAllChangesDone
351+
expect(dispatcher.loggedValues).toEqual([
352+
["onAllChangesDone", memento],
353+
[1]
354+
]);
332355
});
333356
});
334357
});
@@ -417,18 +440,25 @@ export function main() {
417440
child = instantiate(protoChild, null, []);
418441
});
419442

420-
it("should add children", () => {
443+
it("should add light dom children", () => {
421444
parent.addChild(child);
422445

423-
expect(parent.children.length).toEqual(1);
424-
expect(parent.children[0]).toBe(child);
446+
expect(parent.lightDomChildren.length).toEqual(1);
447+
expect(parent.lightDomChildren[0]).toBe(child);
448+
});
449+
450+
it("should add shadow dom children", () => {
451+
parent.addShadowDomChild(child);
452+
453+
expect(parent.shadowDomChildren.length).toEqual(1);
454+
expect(parent.shadowDomChildren[0]).toBe(child);
425455
});
426456

427-
it("should remove children", () => {
457+
it("should remove light dom children", () => {
428458
parent.addChild(child);
429459
parent.removeChild(child);
430460

431-
expect(parent.children).toEqual([]);
461+
expect(parent.lightDomChildren).toEqual([]);
432462
});
433463
});
434464
});
@@ -799,7 +829,7 @@ class TestDispatcher extends ChangeDispatcher {
799829
}
800830

801831
onAllChangesDone(directiveMemento) {
802-
ListWrapper.push(this.loggedOnAllChangesDone, directiveMemento);
832+
ListWrapper.push(this.loggedValues, ["onAllChangesDone", directiveMemento]);
803833
}
804834

805835
_asString(value) {

modules/angular2/test/core/compiler/view_container_spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,15 @@ export function main() {
228228
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
229229
expect(inj.parent).toBe(elementInjector));
230230

231-
expect(parentView.changeDetector.children.length).toBe(1);
231+
expect(parentView.changeDetector.lightDomChildren.length).toBe(1);
232232
});
233233

234234
it('dehydrating should update rootElementInjectors and parent change detector', () => {
235235
viewContainer.insert(fancyView);
236236
viewContainer.remove();
237237
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
238238
expect(inj.parent).toBe(null));
239-
expect(parentView.changeDetector.children.length).toBe(0);
239+
expect(parentView.changeDetector.lightDomChildren.length).toBe(0);
240240
expect(viewContainer.length).toBe(0);
241241
});
242242
});

0 commit comments

Comments
 (0)