From f8ee3b9a80685c9852fbeeecf7e8ceb8226b83f6 Mon Sep 17 00:00:00 2001 From: Maira Bello Date: Wed, 31 Aug 2016 12:52:07 -0300 Subject: [PATCH] Stores both nodes and components with ref inside "refs" It'll still be possible to access components via their refs through the "components" variable inside the owner. Now it'll also be possible to access refs through the "refs" variable though, which will also contain nodes with refs, besides components. --- .../src/ComponentDataManager.js | 2 + .../src/IncrementalDomRenderer.js | 9 +++++ .../test/IncrementalDomRenderer.js | 38 ++++++++++++++----- 3 files changed, 39 insertions(+), 10 deletions(-) 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() {