From 03df4018564cb2f0b7f1b2775fb9463c82a7a896 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 7 Sep 2019 11:42:11 -0400 Subject: [PATCH] add valueAsDate binding - fixes #3399 --- src/compiler/compile/nodes/Element.ts | 17 ++++++++++++++++ .../render_dom/wrappers/Element/Binding.ts | 4 ---- .../compile/render_ssr/handlers/Element.ts | 8 -------- .../samples/binding-input-date/_config.js | 20 +++++++++++++------ .../samples/binding-input-date/main.svelte | 2 +- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 593f303a2f..f81afdd13f 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -575,7 +575,24 @@ export default class Element extends Node { message: `'files' binding can only be used with ` }); } + } 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 ` + }); + } } else if (name === 'open') { if (this.name !== 'details') { component.error(binding, { diff --git a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts index 04f72a41e1..44372f8793 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts @@ -325,10 +325,6 @@ function get_value_from_dom( return `@to_number(this.${name})`; } - if (type === 'date') { - return `@value_as_date(this.${name})`; - } - if ((name === 'buffered' || name === 'seekable' || name === 'played')) { return `@time_ranges_to_array(this.${name})`; } diff --git a/src/compiler/compile/render_ssr/handlers/Element.ts b/src/compiler/compile/render_ssr/handlers/Element.ts index ab7c7e1948..146324f2a4 100644 --- a/src/compiler/compile/render_ssr/handlers/Element.ts +++ b/src/compiler/compile/render_ssr/handlers/Element.ts @@ -64,11 +64,6 @@ export default function(node: Element, renderer: Renderer, options: RenderOption 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 component = node.find_nearest(/InlineComponent/); if (slot && component) { @@ -167,9 +162,6 @@ export default function(node: Element, renderer: Renderer, options: RenderOption } else if (binding.name === 'value' && node.name === 'textarea') { const snippet = snip(expression); 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 { const snippet = snip(expression); opening_tag += '${@add_attribute("' + name + '", ' + snippet + ', 1)}'; diff --git a/test/runtime/samples/binding-input-date/_config.js b/test/runtime/samples/binding-input-date/_config.js index d74274a233..668d660dd8 100644 --- a/test/runtime/samples/binding-input-date/_config.js +++ b/test/runtime/samples/binding-input-date/_config.js @@ -21,12 +21,15 @@ export default { async test({ assert, component, target, window }) { 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()); 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); assert.equal(component.date.toString(), OCT_07_2019_DATE_VALUE.toString()); @@ -36,20 +39,25 @@ export default { `); 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, `

[object Date] ${SEP_03_2019_DATE_VALUE}

`); + // https://github.com/jsdom/jsdom/issues/2658 // empty string should be treated as undefined - input.value = ''; + // input.value = ''; + + input.valueAsDate = null; await input.dispatchEvent(event); - assert.equal(component.date, undefined); + assert.equal(component.date, null); assert.htmlEqual(target.innerHTML, ` -

[object Undefined] undefined

+

[object Null] null

`); }, }; diff --git a/test/runtime/samples/binding-input-date/main.svelte b/test/runtime/samples/binding-input-date/main.svelte index f6f0fbc953..07be7de59e 100644 --- a/test/runtime/samples/binding-input-date/main.svelte +++ b/test/runtime/samples/binding-input-date/main.svelte @@ -2,5 +2,5 @@ export let date; - +

{Object.prototype.toString.call(date)} {date}