render server bindings

pull/1812/head
Rich Harris 7 years ago
parent 5f51856f86
commit 837d248257

@ -112,6 +112,16 @@ export default function(node, renderer, options) {
});
}
node.bindings.forEach(binding => {
const { name, value: { snippet } } = binding;
if (name === 'group') {
// TODO server-render group bindings
} else {
openingTag += ' ${(v => v ? ("' + name + '" + (v === true ? "" : "=" + JSON.stringify(v))) : "")(' + snippet + ')}';
}
});
if (addClassAttribute) {
openingTag += `\${((v) => v ? ' class="' + v + '"' : '')([${classExpr}].join(' ').trim())}`;
}

@ -165,7 +165,7 @@ describe("runtime", () => {
});
} else {
component.destroy();
assert.equal(target.innerHTML, "");
assert.htmlEqual(target.innerHTML, "");
}
})
.catch(err => {

@ -8,7 +8,28 @@ export default {
},
html: `
<div><input type="checkbox"><p>one</p></div><div><input type="checkbox"><p>two</p></div><div><input type="checkbox"><p>three</p></div>
<div>
<input type="checkbox"><p>one</p>
</div>
<div>
<input type="checkbox"><p>two</p>
</div>
<div>
<input type="checkbox"><p>three</p>
</div>
<p>1 completed</p>
`,
ssrHtml: `
<div>
<input type="checkbox" checked><p>one</p>
</div>
<div>
<input type="checkbox"><p>two</p>
</div>
<div>
<input type="checkbox"><p>three</p>
</div>
<p>1 completed</p>
`,

@ -3,7 +3,15 @@ export default {
foo: true
},
html: `<input type="checkbox">\n<p>true</p>`,
html: `
<input type="checkbox">
<p>true</p>
`,
ssrHtml: `
<input type="checkbox" checked>
<p>true</p>
`,
test ( assert, component, target, window ) {
const input = target.querySelector( 'input' );

@ -1,10 +1,15 @@
export default {
data: {
count: 42
count: 42,
},
html: `
<input type='number'>
<input type=number>
<p>number 42</p>
`,
ssrHtml: `
<input type=number value=42>
<p>number 42</p>
`,
@ -39,5 +44,5 @@ export default {
<input type='number'>
<p>undefined undefined</p>
`);
}
},
};

@ -1,10 +1,15 @@
export default {
data: {
count: 42
count: 42,
},
html: `
<input type='range'>
<input type=range>
<p>number 42</p>
`,
ssrHtml: `
<input type=range value=42>
<p>number 42</p>
`,
@ -29,5 +34,5 @@ export default {
<input type='range'>
<p>number 44</p>
`);
}
},
};

@ -1,10 +1,15 @@
export default {
data: {
count: 42
count: 42,
},
html: `
<input type='range'>
<input type=range>
<p>number 42</p>
`,
ssrHtml: `
<input type=range value=42>
<p>number 42</p>
`,
@ -29,5 +34,5 @@ export default {
<input type='range'>
<p>number 44</p>
`);
}
},
};

@ -1,12 +1,32 @@
export default {
data: {
items: [
'one',
'two',
'three'
]
items: ['one', 'two', 'three'],
},
html: `<div><input><p>one</p></div><div><input><p>two</p></div><div><input><p>three</p></div><!---->`,
html: `
<div>
<input><p>one</p>
</div>
<div>
<input><p>two</p>
</div>
<div>
<input><p>three</p>
</div>
`,
ssrHtml: `
<div>
<input value=one><p>one</p>
</div>
<div>
<input value=two><p>two</p>
</div>
<div>
<input value=three><p>three</p>
</div>
`,
test(assert, component, target, window) {
const inputs = [...target.querySelectorAll('input')];
const items = component.get().items;
@ -18,12 +38,32 @@ export default {
inputs[1].dispatchEvent(event);
assert.equal(items[1], 'four');
assert.equal( target.innerHTML, `<div><input><p>one</p></div><div><input><p>four</p></div><div><input><p>three</p></div><!---->` );
assert.htmlEqual(target.innerHTML, `
<div>
<input><p>one</p>
</div>
<div>
<input><p>four</p>
</div>
<div>
<input><p>three</p>
</div>
`);
items[2] = 'five';
component.set({ items });
assert.equal(inputs[2].value, 'five');
assert.equal( target.innerHTML, `<div><input><p>one</p></div><div><input><p>four</p></div><div><input><p>five</p></div><!---->` );
}
assert.htmlEqual(target.innerHTML, `
<div>
<input><p>one</p>
</div>
<div>
<input><p>four</p>
</div>
<div>
<input><p>five</p>
</div>
`);
},
};

@ -1,8 +1,8 @@
export default {
data: {
component: {
name: 'world'
}
name: 'world',
},
},
html: `
@ -10,6 +10,11 @@ export default {
<input>
`,
ssrHtml: `
<h1>Hello world!</h1>
<input value=world>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
assert.equal(input.value, 'world');
@ -31,5 +36,5 @@ export default {
<h1>Hello goodbye!</h1>
<input>
`);
}
},
};

@ -4,8 +4,8 @@ export default {
obj: {
foo: 'a',
bar: 'b',
baz: 'c'
}
baz: 'c',
},
},
html: `
@ -13,6 +13,11 @@ export default {
<pre>{"foo":"a","bar":"b","baz":"c"}</pre>
`,
ssrHtml: `
<input value=b>
<pre>{"foo":"a","bar":"b","baz":"c"}</pre>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
const event = new window.Event('input');
@ -51,5 +56,5 @@ export default {
<input>
<pre>{"foo":"d","bar":"e","baz":"f"}</pre>
`);
}
},
};

@ -2,11 +2,19 @@ export default {
data: {
prop: 'name',
user: {
name: 'alice'
}
name: 'alice',
},
},
html: `
<input>
<p>hello alice</p>
`,
html: `<input>\n<p>hello alice</p>`,
ssrHtml: `
<input value=alice>
<p>hello alice</p>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
@ -18,13 +26,19 @@ export default {
input.value = 'bob';
input.dispatchEvent(event);
assert.equal( target.innerHTML, `<input>\n<p>hello bob</p>` );
assert.htmlEqual(target.innerHTML, `
<input>
<p>hello bob</p>
`);
const user = component.get().user;
user.name = 'carol';
component.set({ user });
assert.equal(input.value, 'carol');
assert.equal( target.innerHTML, `<input>\n<p>hello carol</p>` );
}
assert.htmlEqual(target.innerHTML, `
<input>
<p>hello carol</p>
`);
},
};

@ -1,11 +1,13 @@
export default {
data: {
prop: 'bar',
objects: [{
objects: [
{
foo: 'a',
bar: 'b',
baz: 'c'
}]
baz: 'c',
},
],
},
html: `
@ -13,6 +15,11 @@ export default {
<pre>{"foo":"a","bar":"b","baz":"c"}</pre>
`,
ssrHtml: `
<input value=b>
<pre>{"foo":"a","bar":"b","baz":"c"}</pre>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
const event = new window.Event('input');
@ -51,5 +58,5 @@ export default {
<input>
<pre>{"foo":"d","bar":"e","baz":"f"}</pre>
`);
}
},
};

@ -3,10 +3,22 @@ export default {
items: [
{ description: 'one' },
{ description: 'two' },
{ description: 'three' }
]
{ description: 'three' },
],
},
html: `<div><input><p>one</p></div><div><input><p>two</p></div><div><input><p>three</p></div><!---->`,
html: `
<div><input><p>one</p></div>
<div><input><p>two</p></div>
<div><input><p>three</p></div>
`,
ssrHtml: `
<div><input value=one><p>one</p></div>
<div><input value=two><p>two</p></div>
<div><input value=three><p>three</p></div>
`,
test(assert, component, target, window) {
const inputs = [...target.querySelectorAll('input')];
@ -17,13 +29,21 @@ export default {
inputs[1].value = 'four';
inputs[1].dispatchEvent(event);
assert.equal( target.innerHTML, `<div><input><p>one</p></div><div><input><p>four</p></div><div><input><p>three</p></div><!---->` );
assert.htmlEqual(target.innerHTML, `
<div><input><p>one</p></div>
<div><input><p>four</p></div>
<div><input><p>three</p></div>
`);
const items = component.get().items;
items[2].description = 'five';
component.set({ items });
assert.equal(inputs[2].value, 'five');
assert.equal( target.innerHTML, `<div><input><p>one</p></div><div><input><p>four</p></div><div><input><p>five</p></div><!---->` );
}
assert.htmlEqual(target.innerHTML, `
<div><input><p>one</p></div>
<div><input><p>four</p></div>
<div><input><p>five</p></div>
`);
},
};

@ -1,11 +1,19 @@
export default {
data: {
user: {
name: 'alice'
}
name: 'alice',
},
},
html: `
<input>
<p>hello alice</p>
`,
html: `<input>\n<p>hello alice</p>`,
ssrHtml: `
<input value=alice>
<p>hello alice</p>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
@ -17,13 +25,19 @@ export default {
input.value = 'bob';
input.dispatchEvent(event);
assert.equal( target.innerHTML, `<input>\n<p>hello bob</p>` );
assert.htmlEqual(target.innerHTML, `
<input>
<p>hello bob</p>
`);
const user = component.get().user;
user.name = 'carol';
component.set({ user });
assert.equal(input.value, 'carol');
assert.equal( target.innerHTML, `<input>\n<p>hello carol</p>` );
}
assert.htmlEqual(target.innerHTML, `
<input>
<p>hello carol</p>
`);
},
};

@ -8,6 +8,11 @@ export default {
<p>hello world</p>
`,
ssrHtml: `
<input value="world">
<p>hello world</p>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
assert.equal(input.value, 'world');

@ -14,6 +14,16 @@ export default {
<p>foo: 2</p>
`,
ssrHtml: `
<select value=2>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
</select>
<p>foo: 2</p>
`,
test(assert, component, target, window) {
const select = target.querySelector('select');
const options = [...target.querySelectorAll('option')];

@ -11,8 +11,20 @@ export default {
<p>selected: b</p>
`,
ssrHtml: `
<p>selected: b</p>
<select value=b>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
<p>selected: b</p>
`,
data: {
selected: 'b'
selected: 'b',
},
test(assert, component, target) {
@ -23,5 +35,5 @@ export default {
assert.ok(options[1].selected);
component.destroy();
}
},
};

@ -11,8 +11,20 @@ export default {
<p>selected: one</p>
`,
ssrHtml: `
<p>selected: one</p>
<select value=one>
<option value='one'>one</option>
<option value='two'>two</option>
<option value='three'>three</option>
</select>
<p>selected: one</p>
`,
data: {
selected: 'one'
selected: 'one',
},
test(assert, component, target, window) {
@ -41,5 +53,5 @@ export default {
`);
component.set({ selected: 'three' });
}
},
};

@ -1,6 +1,6 @@
export default {
data: {
value: 'some text'
value: 'some text',
},
html: `
@ -8,6 +8,11 @@ export default {
<p>some text</p>
`,
ssrHtml: `
<textarea value="some text"></textarea>
<p>some text</p>
`,
test(assert, component, target, window) {
const textarea = target.querySelector('textarea');
assert.equal(textarea.value, 'some text');
@ -28,5 +33,5 @@ export default {
<textarea></textarea>
<p>goodbye</p>
`);
}
},
};

@ -4,6 +4,11 @@ export default {
<p>foo</p>
`,
ssrHtml: `
<input value=foo>
<p>foo</p>
`,
test(assert, component, target, window) {
const event = new window.MouseEvent('input');
const input = target.querySelector('input');
@ -16,7 +21,5 @@ export default {
<input>
<p>blah</p>
`);
component.destroy();
}
},
};

@ -4,6 +4,13 @@ export default {
<p>foo, bar, baz</p>
`,
ssrHtml: `
<input value=foo>
<input value=bar>
<input value=baz>
<p>foo, bar, baz</p>
`,
test ( assert, component, target, window ) {
const event = new window.MouseEvent( 'input' );
const inputs = target.querySelectorAll( 'input' );

@ -4,6 +4,13 @@ export default {
<p>foo, bar, baz</p>
`,
ssrHtml: `
<input value=foo>
<input value=bar>
<input value=baz>
<p>foo, bar, baz</p>
`,
test ( assert, component, target, window ) {
const event = new window.MouseEvent( 'input' );
const inputs = target.querySelectorAll( 'input' );

@ -7,6 +7,14 @@ export default {
</ul>
`,
ssrHtml: `
<ul>
<li><input value=foo></li>
<li>bar</li>
<li>baz</li>
</ul>
`,
data: {
components: [
{ name: 'foo', edit: true },

@ -11,6 +11,12 @@ export default {
<input>
`,
ssrHtml: `
<input value=x>
<input value=y>
<input value=z>
`,
test(assert, component, target, window) {
const inputs = target.querySelectorAll('input');

@ -9,6 +9,12 @@ export default {
<p>Doctor Who</p>
`,
ssrHtml: `
<input value=Doctor>
<input value=Who>
<p>Doctor Who</p>
`,
test(assert, component, target, window) {
const inputs = target.querySelectorAll('input');

@ -16,6 +16,23 @@ export default {
</div>
`,
ssrHtml: `
<div class="todo done">
<input type="checkbox" checked>
<input type="text" value="Buy some milk">
</div>
<div class="todo done">
<input type="checkbox" checked>
<input type="text" value="Do the laundry">
</div>
<div class="todo ">
<input type="checkbox">
<input type="text" value="Find life's true purpose">
</div>
`,
data: {
todos: {
first: {

@ -1,10 +1,24 @@
export default {
nestedTransitions: true,
html: '<div>A wild component appears</div><p>x</p><input type="text">',
html: `
<div>A wild component appears</div>
<p>x</p>
<input type=text>
`,
ssrHtml: `
<div>A wild component appears</div>
<p>x</p>
<input type=text value=x>
`,
test(assert, component, target) {
component.set({ x: 'y' });
assert.htmlEqual(target.innerHTML, '<div>A wild component appears</div><p>y</p><input type="text">');
assert.htmlEqual(target.innerHTML, `
<div>A wild component appears</div>
<p>y</p>
<input type=text>
`);
},
};

@ -1,6 +1,12 @@
export default {
html: `
<input type='number'>
<input type=number>
<p>field1: 1</p>
<p>field2: 2</p>
`,
ssrHtml: `
<input type=number value=1>
<p>field1: 1</p>
<p>field2: 2</p>
`,

@ -4,6 +4,11 @@ export default {
<input>
`,
ssrHtml: `
<p>foo</p>
<input value=foo>
`,
test (assert, component, target, window) {
const input = target.querySelector('input');

@ -12,6 +12,11 @@ export default {
<input>
`,
ssrHtml: `
<h1>Hello world!</h1>
<input value=world>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
const event = new window.Event('input');

@ -14,6 +14,11 @@ export default {
<input>
`,
ssrHtml: `
<h1>Hello world!</h1>
<input value=world>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
const event = new window.Event('input');

@ -8,7 +8,16 @@ export default {
store,
html: `
<input><input><input>
<input>
<input>
<input>
<p>foo, bar, baz</p>
`,
ssrHtml: `
<input value=foo>
<input value=bar>
<input value=baz>
<p>foo, bar, baz</p>
`,
@ -21,7 +30,9 @@ export default {
assert.deepEqual(store.get().a, ['blah', 'bar', 'baz']);
assert.htmlEqual(target.innerHTML, `
<input><input><input>
<input>
<input>
<input>
<p>blah, bar, baz</p>
`);

@ -12,6 +12,11 @@ export default {
<input>
`,
ssrHtml: `
<h1>Hello world!</h1>
<input value=world>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
const event = new window.Event('input');

@ -120,7 +120,9 @@ describe("ssr", () => {
store: (config.store !== true) && config.store
});
if (config.html) {
if (config.ssrHtml) {
assert.htmlEqual(html, config.ssrHtml);
} else if (config.html) {
assert.htmlEqual(html, config.html);
}
} catch (err) {

@ -0,0 +1,8 @@
<input bind:value=foo >
<script>
export default {
data() {
return { foo: 'bar' };
}
};
</script>
Loading…
Cancel
Save