Merge pull request #630 from sveltejs/gh-620

only enforce static type if input is bound
pull/635/head
Rich Harris 8 years ago committed by GitHub
commit 61f5cbef54

@ -22,8 +22,7 @@ export default function visitAttribute(
const isIndirectlyBoundValue = const isIndirectlyBoundValue =
name === 'value' && name === 'value' &&
(node.name === 'option' || // TODO check it's actually bound (node.name === 'option' || // TODO check it's actually bound
(node.name === 'input' && (node.name === 'input' && node.attributes.find((attribute: Node) => attribute.type === 'Binding' && /checked|group/.test(attribute.name))));
/^(checkbox|radio)$/.test(getStaticAttributeValue(node, 'type'))));
const propertyName = isIndirectlyBoundValue const propertyName = isIndirectlyBoundValue
? '__value' ? '__value'

@ -30,6 +30,8 @@ export default function validateElement(validator: Validator, node: Node) {
attribute.start attribute.start
); );
} }
checkTypeAttribute(validator, node);
} else if (name === 'checked') { } else if (name === 'checked') {
if (node.name !== 'input') { if (node.name !== 'input') {
validator.error( validator.error(
@ -38,7 +40,7 @@ export default function validateElement(validator: Validator, node: Node) {
); );
} }
if (getType(validator, node) !== 'checkbox') { if (checkTypeAttribute(validator, node) !== 'checkbox') {
validator.error( validator.error(
`'checked' binding can only be used with <input type="checkbox">`, `'checked' binding can only be used with <input type="checkbox">`,
attribute.start attribute.start
@ -52,7 +54,7 @@ export default function validateElement(validator: Validator, node: Node) {
); );
} }
const type = getType(validator, node); const type = checkTypeAttribute(validator, node);
if (type !== 'checkbox' && type !== 'radio') { if (type !== 'checkbox' && type !== 'radio') {
validator.error( validator.error(
@ -133,7 +135,7 @@ export default function validateElement(validator: Validator, node: Node) {
}); });
} }
function getType(validator: Validator, node: Node) { function checkTypeAttribute(validator: Validator, node: Node) {
const attribute = node.attributes.find( const attribute = node.attributes.find(
(attribute: Node) => attribute.name === 'type' (attribute: Node) => attribute.name === 'type'
); );
@ -144,7 +146,7 @@ function getType(validator: Validator, node: Node) {
} }
if (attribute.value.length > 1 || attribute.value[0].type !== 'Text') { if (attribute.value.length > 1 || attribute.value[0].type !== 'Text') {
validator.error(`'type attribute cannot be dynamic`, attribute.start); validator.error(`'type' attribute cannot be dynamic if input uses two-way binding`, attribute.start);
} }
return attribute.value[0].data; return attribute.value[0].data;

@ -0,0 +1,19 @@
export default {
'skip-ssr': true,
data: {
inputType: 'text',
inputValue: 42
},
html: `<input type="text">`,
test(assert, component, target) {
const input = target.querySelector('input');
assert.equal(input.type, 'text');
assert.equal(input.value, '42');
component.set({ inputType: 'number' });
assert.equal(input.type, 'number');
}
};

@ -0,0 +1 @@
<input type='{{inputType}}' value='{{inputValue}}'>

@ -0,0 +1,8 @@
[{
"message": "'type' attribute cannot be dynamic if input uses two-way binding",
"loc": {
"line": 1,
"column": 24
},
"pos": 24
}]

@ -0,0 +1 @@
<input bind:value='foo' type='{{inputType}}'>
Loading…
Cancel
Save