--- /dev/null
+import { parse, transform, CompilerOptions } from '@vue/compiler-core'
+import { transformModel } from '../../src/transforms/vModel'
+import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
+import { DOMErrorCodes } from '../../src/errors'
+
+function transformWithModel(template: string, options: CompilerOptions = {}) {
+ const ast = parse(template)
+ transform(ast, {
+ nodeTransforms: [transformElement],
+ directiveTransforms: {
+ model: transformModel
+ },
+ ...options
+ })
+ return ast
+}
+
+describe('compiler: v-model transform', () => {
+ it('should raise error if used file input element', () => {
+ const onError = jest.fn()
+ transformWithModel(`<input type="file" v-model="test"></input>`, {
+ onError
+ })
+ expect(onError.mock.calls).toMatchObject([
+ [{ code: DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT }]
+ ])
+ })
+})
X_V_TEXT_NO_EXPRESSION,
X_V_TEXT_WITH_CHILDREN,
X_V_MODEL_ON_INVALID_ELEMENT,
- X_V_MODEL_ARG_ON_ELEMENT
+ X_V_MODEL_ARG_ON_ELEMENT,
+ X_V_MODEL_ON_FILE_INPUT_ELEMENT
}
export const DOMErrorMessages: { [code: number]: string } = {
[DOMErrorCodes.X_V_TEXT_NO_EXPRESSION]: `v-text is missing expression.`,
[DOMErrorCodes.X_V_TEXT_WITH_CHILDREN]: `v-text will override element children.`,
[DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
- [DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT]: `v-model argument is not supported on plain elements.`
+ [DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT]: `v-model argument is not supported on plain elements.`,
+ [DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT]: `v-model cannot used on file inputs since they are read-only. Use a v-on:change listener instead.`
}
if (tag === 'input' || tag === 'textarea' || tag === 'select') {
let directiveToUse = V_MODEL_TEXT
+ let isInvalidType = false
if (tag === 'input') {
const type = findProp(node, `type`)
if (type) {
case 'checkbox':
directiveToUse = V_MODEL_CHECKBOX
break
+ case 'file':
+ isInvalidType = true
+ context.onError(
+ createDOMCompilerError(
+ DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT,
+ dir.loc
+ )
+ )
+ break
}
}
}
}
// inject runtime directive
// by returning the helper symbol via needRuntime
- // the import will replace the resovleDirective call.
- res.needRuntime = context.helper(directiveToUse)
+ // the import will replaced a resovleDirective call.
+ if (!isInvalidType) {
+ res.needRuntime = context.helper(directiveToUse)
+ }
} else {
context.onError(
createDOMCompilerError(