diff --git a/packages/metal-component/src/ComponentDataManager.js b/packages/metal-component/src/ComponentDataManager.js index 4b43f361..2fa1f75e 100644 --- a/packages/metal-component/src/ComponentDataManager.js +++ b/packages/metal-component/src/ComponentDataManager.js @@ -175,7 +175,9 @@ class ComponentDataManager extends EventEmitter { ComponentDataManager.BLACKLIST = { components: true, + context: true, element: true, + refs: true, wasRendered: true }; diff --git a/packages/metal-incremental-dom/src/IncrementalDomRenderer.js b/packages/metal-incremental-dom/src/IncrementalDomRenderer.js index c52d5763..1d00d9da 100644 --- a/packages/metal-incremental-dom/src/IncrementalDomRenderer.js +++ b/packages/metal-incremental-dom/src/IncrementalDomRenderer.js @@ -21,6 +21,7 @@ class IncrementalDomRenderer extends ComponentRenderer { super(comp); comp.context = {}; + comp.refs = {}; this.config_ = comp.getInitialConfig(); this.childComponents_ = []; this.clearChanges_(); @@ -262,6 +263,7 @@ class IncrementalDomRenderer extends ComponentRenderer { if (core.isDef(config.ref)) { comp = this.match_(this.component_.components[config.ref], Ctor, config); this.component_.addSubComponent(config.ref, comp); + this.component_.refs[config.ref] = comp; } else if (core.isDef(config.key)) { comp = this.match_(data.prevComps.keys[config.key], Ctor, config); data.currComps.keys[config.key] = comp; @@ -478,9 +480,15 @@ class IncrementalDomRenderer extends ComponentRenderer { } } + var node = originalFn.apply(null, args); this.attachDecoratedListeners_(node, args); this.updateElementIfNotReached_(node); + + const config = IncrementalDomUtils.buildConfigFromCall(args); + if (core.isDefAndNotNull(config.ref)) { + this.component_.refs[config.ref] = node; + } return node; } @@ -717,6 +725,7 @@ class IncrementalDomRenderer extends ComponentRenderer { this.rootElementReached_ = false; IncrementalDomUnusedComponents.schedule(this.childComponents_); this.childComponents_ = []; + this.component_.refs = {}; this.intercept_(); this.renderIncDom(); IncrementalDomAop.stopInterception(); diff --git a/packages/metal-incremental-dom/test/IncrementalDomRenderer.js b/packages/metal-incremental-dom/test/IncrementalDomRenderer.js index 3de353d9..c859787d 100644 --- a/packages/metal-incremental-dom/test/IncrementalDomRenderer.js +++ b/packages/metal-incremental-dom/test/IncrementalDomRenderer.js @@ -423,20 +423,37 @@ describe('IncrementalDomRenderer', function() { done(); }); }); - }); - it('should not cause css classes to be added twice due to "elementClasses"', function() { - class TestComponent extends Component { - render() { - IncDom.elementVoid('div', null, null, 'class', 'test1 test2'); + it('should not cause css classes to be added twice due to "elementClasses"', function() { + class TestComponent extends Component { + render() { + IncDom.elementVoid('div', null, null, 'class', 'test1 test2'); + } } - } - TestComponent.RENDERER = IncrementalDomRenderer; + TestComponent.RENDERER = IncrementalDomRenderer; + + component = new TestComponent({ + elementClasses: 'test2 test3' + }); + assert.strictEqual('test1 test2 test3', component.element.getAttribute('class')); + }); - component = new TestComponent({ - elementClasses: 'test2 test3' + it('should store references to node elements via "ref"', function() { + class TestComponent extends Component { + render() { + IncDom.elementOpen('div', null, null, 'ref', 'root'); + IncDom.elementVoid('span', null, null, 'ref', 'child1'); + IncDom.elementVoid('span', null, null, 'ref', 'child2'); + IncDom.elementClose('div'); + } + } + TestComponent.RENDERER = IncrementalDomRenderer; + + component = new TestComponent(); + assert.strictEqual(component.element, component.refs.root); + assert.strictEqual(component.element.childNodes[0], component.refs.child1); + assert.strictEqual(component.element.childNodes[1], component.refs.child2); }); - assert.strictEqual('test1 test2 test3', component.element.getAttribute('class')); }); describe('Existing Content', function() { @@ -828,6 +845,7 @@ describe('IncrementalDomRenderer', function() { var child = component.components.child; assert.ok(child); assert.ok(child instanceof ChildComponent); + assert.strictEqual(child, component.refs.child); }); it('should render sub component at specified place', function() {