Merge pull request #630 from sveltejs/gh-620

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

@ -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'
@ -133,8 +132,8 @@ export default function visitAttribute(
const statement = propertyName
? `${state.parentNode}.${propertyName} = ${value};`
: `${generator.helper(
method
)}( ${state.parentNode}, '${name}', ${value} );`;
method
)}( ${state.parentNode}, '${name}', ${value} );`;
block.builders.create.addLine(statement);

@ -30,6 +30,8 @@ export default function validateElement(validator: Validator, node: Node) {
attribute.start
);
}
checkTypeAttribute(validator, node);
} else if (name === 'checked') {
if (node.name !== 'input') {
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(
`'checked' binding can only be used with <input type="checkbox">`,
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') {
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(
(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') {
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