only enforce static type if input is bound (fixes #620)

pull/630/head
Rich Harris 8 years ago
parent 6eb80e3732
commit ff40308358

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

@ -25,6 +25,8 @@ export default function validateElement(validator: Validator, node: Node) {
attribute.start
);
}
checkTypeAttribute(validator, node);
} else if (name === 'checked') {
if (node.name !== 'input') {
validator.error(
@ -33,7 +35,7 @@ export default function validateElement(validator: Validator, node: Node) {
);
}
if (getType(validator, node) !== 'checkbox') {
if (checkTypeAttribute(validator, node) !== 'checkbox') {
validator.error(
`'checked' binding can only be used with <input type="checkbox">`,
attribute.start
@ -47,7 +49,7 @@ export default function validateElement(validator: Validator, node: Node) {
);
}
const type = getType(validator, node);
const type = checkTypeAttribute(validator, node);
if (type !== 'checkbox' && type !== 'radio') {
validator.error(
@ -128,7 +130,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(
(attribute: Node) => attribute.name === 'type'
);
@ -139,7 +141,7 @@ function getType(validator: Validator, node: Node) {
}
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;

@ -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