Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 7df0640

Browse files
author
twifty
committed
Give context to nodes
1 parent 5072c1b commit 7df0640

File tree

5 files changed

+67
-4
lines changed

5 files changed

+67
-4
lines changed

lib/component-helpers.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ function isValidVirtualNode (virtualNode) {
1010
return virtualNode != null && virtualNode !== false
1111
}
1212

13+
function applyContext (context, virtualNode) {
14+
virtualNode.context = context
15+
virtualNode.ambiguous.forEach(node => {
16+
node.context = context
17+
})
18+
delete virtualNode.ambiguous
19+
}
20+
1321
// This function associates a component object with a DOM element by calling
1422
// the components `render` method, assigning an `.element` property on the
1523
// object and also returning the element.
@@ -35,6 +43,8 @@ function initialize(component) {
3543
throw new Error('invalid falsy value ' + virtualNode + ' returned from render()' + namePart)
3644
}
3745

46+
applyContext(component, virtualNode)
47+
3848
component.refs = {}
3949
component.virtualNode = virtualNode
4050
component.element = render(component.virtualNode, {
@@ -110,6 +120,8 @@ function updateSync (component, replaceNode=true) {
110120
throw new Error('invalid falsy value ' + newVirtualNode + ' returned from render()' + namePart)
111121
}
112122

123+
applyContext(component, newVirtualNode)
124+
113125
syncUpdatesInProgressCounter++
114126
let oldVirtualNode = component.virtualNode
115127
let oldDomNode = component.element

lib/dom.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ const EVENT_LISTENER_PROPS = require('./event-listener-props')
22
const SVG_TAGS = require('./svg-tags')
33

44
function dom (tag, props, ...children) {
5+
let ambiguous = []
6+
57
for (let i = 0; i < children.length;) {
68
const child = children[i]
79
switch (typeof child) {
@@ -17,6 +19,12 @@ function dom (tag, props, ...children) {
1719
} else if (!child) {
1820
children.splice(i, 1)
1921
} else {
22+
if (!child.context) {
23+
ambiguous.push(child)
24+
if (child.ambiguous && child.ambiguous.length) {
25+
ambiguous = ambiguous.concat(child.ambiguous)
26+
}
27+
}
2028
i++
2129
}
2230
break;
@@ -40,7 +48,7 @@ function dom (tag, props, ...children) {
4048
}
4149
}
4250

43-
return {tag, props, children}
51+
return {tag, props, children, ambiguous}
4452
}
4553

4654
const HTML_TAGS = [

lib/patch.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function updateComponent (oldVirtualNode, newVirtualNode, options) {
4949
if (newRefName) refs[newRefName] = component
5050
}
5151
}
52-
component.update(newProps || {}, newChildren, options)
52+
component.update(newProps || {}, newChildren)
5353
return component.element
5454
}
5555

lib/render.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@ function render (virtualNode, options) {
77
domNode = document.createTextNode(virtualNode.text)
88
} else {
99
const {tag, children} = virtualNode
10-
let {props} = virtualNode
10+
let {props, context} = virtualNode
11+
12+
if (context) {
13+
options = {refs: context.refs, listenerContext: context}
14+
}
1115

1216
if (typeof tag === 'function') {
1317
let ref
1418
if (props && props.ref) {
1519
ref = props.ref
1620
}
17-
const component = new tag(props || {}, children, options)
21+
const component = new tag(props || {}, children)
1822
virtualNode.component = component
1923
domNode = component.element
2024
if (options && options.refs && ref) {

test/unit/initialize.test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,45 @@ describe('etch.initialize(component)', () => {
5454
expect(component.refs.selected.textContent).to.equal('one')
5555
})
5656

57+
it('nests references correctly', async () => {
58+
class Component {
59+
constructor(props, children) {
60+
this.children = children
61+
etch.initialize(this)
62+
}
63+
64+
update() {}
65+
66+
render () {
67+
return <div>{this.children}</div>
68+
}
69+
}
70+
71+
class TestHarness {
72+
constructor() {
73+
etch.initialize(this)
74+
}
75+
76+
update() {}
77+
78+
render() {
79+
return (
80+
<Component ref="outer">
81+
<Component ref="middle">
82+
<div ref="inner" />
83+
</Component>
84+
</Component>
85+
)
86+
}
87+
}
88+
89+
const harness = new TestHarness()
90+
expect(harness.refs.outer).to.be.ok
91+
expect(harness.refs.middle).to.be.ok
92+
expect(harness.refs.inner).to.be.ok
93+
expect(harness.refs.outer.refs.middle).to.be.undefined
94+
})
95+
5796
it('throws an exception if undefined is returned from render', () => {
5897
let component = {
5998
render () {},

0 commit comments

Comments
 (0)