add valueAsDate binding - fixes #3399

pull/3527/head
Richard Harris 6 years ago
parent 5ed8b03c74
commit 03df401856

@ -575,7 +575,24 @@ export default class Element extends Node {
message: `'files' binding can only be used with <input type="file">` message: `'files' binding can only be used with <input type="file">`
}); });
} }
} else if (name === 'valueAsDate') {
if (this.name !== 'input') {
component.error(binding, {
code: `invalid-binding`,
message: `'valueAsDate' is not a valid binding on <${this.name}> elements`
});
}
const type = (check_type_attribute() as string);
const valid_date_inputs = new Set(['date', 'datetime-local', 'time', 'month', 'week']);
if (!valid_date_inputs.has(type)) {
component.error(binding, {
code: `invalid-binding`,
message: `'valueAsDate' binding can only be used with <input type="${Array.from(valid_date_inputs).join('|')}">`
});
}
} else if (name === 'open') { } else if (name === 'open') {
if (this.name !== 'details') { if (this.name !== 'details') {
component.error(binding, { component.error(binding, {

@ -325,10 +325,6 @@ function get_value_from_dom(
return `@to_number(this.${name})`; return `@to_number(this.${name})`;
} }
if (type === 'date') {
return `@value_as_date(this.${name})`;
}
if ((name === 'buffered' || name === 'seekable' || name === 'played')) { if ((name === 'buffered' || name === 'seekable' || name === 'played')) {
return `@time_ranges_to_array(this.${name})`; return `@time_ranges_to_array(this.${name})`;
} }

@ -64,11 +64,6 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
node.attributes.some((attribute) => attribute.name === 'contenteditable') node.attributes.some((attribute) => attribute.name === 'contenteditable')
); );
const is_date_input = (
node.name === 'input' &&
node.attributes.some((attribute) => attribute.name === 'type' && attribute.get_static_value() === 'date')
);
const slot = node.get_static_attribute_value('slot'); const slot = node.get_static_attribute_value('slot');
const component = node.find_nearest(/InlineComponent/); const component = node.find_nearest(/InlineComponent/);
if (slot && component) { if (slot && component) {
@ -167,9 +162,6 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
} else if (binding.name === 'value' && node.name === 'textarea') { } else if (binding.name === 'value' && node.name === 'textarea') {
const snippet = snip(expression); const snippet = snip(expression);
node_contents = '${(' + snippet + ') || ""}'; node_contents = '${(' + snippet + ') || ""}';
} else if (binding.name === 'value' && is_date_input) {
const snippet = snip(expression);
opening_tag += '${@add_attribute("' + name + '", @date_as_value(' + snippet + '), 1)}';
} else { } else {
const snippet = snip(expression); const snippet = snip(expression);
opening_tag += '${@add_attribute("' + name + '", ' + snippet + ', 1)}'; opening_tag += '${@add_attribute("' + name + '", ' + snippet + ', 1)}';

@ -21,12 +21,15 @@ export default {
async test({ assert, component, target, window }) { async test({ assert, component, target, window }) {
const input = target.querySelector('input'); const input = target.querySelector('input');
assert.equal(input.value, SEP_03_2019_INPUT_VALUE); // https://github.com/jsdom/jsdom/issues/2658
// assert.equal(input.value, SEP_03_2019_INPUT_VALUE);
assert.equal(component.date.toString(), SEP_03_2019_DATE_VALUE.toString()); assert.equal(component.date.toString(), SEP_03_2019_DATE_VALUE.toString());
const event = new window.Event('input'); const event = new window.Event('input');
input.value = OCT_07_2019_INPUT_VALUE; // https://github.com/jsdom/jsdom/issues/2658
// input.value = OCT_07_2019_INPUT_VALUE;
input.valueAsDate = OCT_07_2019_DATE_VALUE;
await input.dispatchEvent(event); await input.dispatchEvent(event);
assert.equal(component.date.toString(), OCT_07_2019_DATE_VALUE.toString()); assert.equal(component.date.toString(), OCT_07_2019_DATE_VALUE.toString());
@ -36,20 +39,25 @@ export default {
`); `);
component.date = SEP_03_2019_DATE_VALUE; component.date = SEP_03_2019_DATE_VALUE;
assert.equal(input.value, SEP_03_2019_INPUT_VALUE); // https://github.com/jsdom/jsdom/issues/2658
// assert.equal(input.value, SEP_03_2019_INPUT_VALUE);
assert.equal(input.valueAsDate.toString(), SEP_03_2019_DATE_VALUE.toString());
assert.htmlEqual(target.innerHTML, ` assert.htmlEqual(target.innerHTML, `
<input type='date'> <input type='date'>
<p>[object Date] ${SEP_03_2019_DATE_VALUE}</p> <p>[object Date] ${SEP_03_2019_DATE_VALUE}</p>
`); `);
// https://github.com/jsdom/jsdom/issues/2658
// empty string should be treated as undefined // empty string should be treated as undefined
input.value = ''; // input.value = '';
input.valueAsDate = null;
await input.dispatchEvent(event); await input.dispatchEvent(event);
assert.equal(component.date, undefined); assert.equal(component.date, null);
assert.htmlEqual(target.innerHTML, ` assert.htmlEqual(target.innerHTML, `
<input type='date'> <input type='date'>
<p>[object Undefined] undefined</p> <p>[object Null] null</p>
`); `);
}, },
}; };

@ -2,5 +2,5 @@
export let date; export let date;
</script> </script>
<input type='date' bind:value={date}> <input type='date' bind:valueAsDate={date}>
<p>{Object.prototype.toString.call(date)} {date}</p> <p>{Object.prototype.toString.call(date)} {date}</p>

Loading…
Cancel
Save