|
|
@@ -52,34 +52,13 @@ export const vModelText: ModelDirective<
|
|
|
'trim' | 'number' | 'lazy'
|
|
|
> = {
|
|
|
created(el, { modifiers: { lazy, trim, number } }, vnode) {
|
|
|
- el[assignKey] = getModelAssigner(vnode)
|
|
|
- const castToNumber =
|
|
|
- number || (vnode.props && vnode.props.type === 'number')
|
|
|
- addEventListener(el, lazy ? 'change' : 'input', e => {
|
|
|
- if ((e.target as any).composing) return
|
|
|
- let domValue: string | number = el.value
|
|
|
- if (trim) {
|
|
|
- domValue = domValue.trim()
|
|
|
- }
|
|
|
- if (castToNumber) {
|
|
|
- domValue = looseToNumber(domValue)
|
|
|
- }
|
|
|
- el[assignKey](domValue)
|
|
|
- })
|
|
|
- if (trim) {
|
|
|
- addEventListener(el, 'change', () => {
|
|
|
- el.value = el.value.trim()
|
|
|
- })
|
|
|
- }
|
|
|
- if (!lazy) {
|
|
|
- addEventListener(el, 'compositionstart', onCompositionStart)
|
|
|
- addEventListener(el, 'compositionend', onCompositionEnd)
|
|
|
- // Safari < 10.2 & UIWebView doesn't fire compositionend when
|
|
|
- // switching focus before confirming composition choice
|
|
|
- // this also fixes the issue where some browsers e.g. iOS Chrome
|
|
|
- // fires "change" instead of "input" on autocomplete.
|
|
|
- addEventListener(el, 'change', onCompositionEnd)
|
|
|
- }
|
|
|
+ vModelTextInit(
|
|
|
+ el,
|
|
|
+ (el[assignKey] = getModelAssigner(vnode)),
|
|
|
+ trim,
|
|
|
+ number || !!(vnode.props && vnode.props.type === 'number'),
|
|
|
+ lazy,
|
|
|
+ )
|
|
|
},
|
|
|
// set value on mounted so it's after min/max for type="range"
|
|
|
mounted(el, { value }) {
|
|
|
@@ -91,30 +70,81 @@ export const vModelText: ModelDirective<
|
|
|
vnode,
|
|
|
) {
|
|
|
el[assignKey] = getModelAssigner(vnode)
|
|
|
- // avoid clearing unresolved text. #2302
|
|
|
- if ((el as any).composing) return
|
|
|
- const elValue =
|
|
|
- (number || el.type === 'number') && !/^0\d/.test(el.value)
|
|
|
- ? looseToNumber(el.value)
|
|
|
- : el.value
|
|
|
- const newValue = value == null ? '' : value
|
|
|
+ vModelTextUpdate(el, value, oldValue, trim, number, lazy)
|
|
|
+ },
|
|
|
+}
|
|
|
|
|
|
- if (elValue === newValue) {
|
|
|
- return
|
|
|
+/**
|
|
|
+ * @internal
|
|
|
+ */
|
|
|
+export const vModelTextInit = (
|
|
|
+ el: HTMLInputElement | HTMLTextAreaElement,
|
|
|
+ set: (v: any) => void,
|
|
|
+ trim: boolean | undefined,
|
|
|
+ number: boolean | undefined,
|
|
|
+ lazy: boolean | undefined,
|
|
|
+): void => {
|
|
|
+ addEventListener(el, lazy ? 'change' : 'input', e => {
|
|
|
+ if ((e.target as any).composing) return
|
|
|
+ let domValue: string | number = el.value
|
|
|
+ if (trim) {
|
|
|
+ domValue = domValue.trim()
|
|
|
+ }
|
|
|
+ if (number) {
|
|
|
+ domValue = looseToNumber(domValue)
|
|
|
}
|
|
|
+ set(domValue)
|
|
|
+ })
|
|
|
+ if (trim) {
|
|
|
+ addEventListener(el, 'change', () => {
|
|
|
+ el.value = el.value.trim()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (!lazy) {
|
|
|
+ addEventListener(el, 'compositionstart', onCompositionStart)
|
|
|
+ addEventListener(el, 'compositionend', onCompositionEnd)
|
|
|
+ // Safari < 10.2 & UIWebView doesn't fire compositionend when
|
|
|
+ // switching focus before confirming composition choice
|
|
|
+ // this also fixes the issue where some browsers e.g. iOS Chrome
|
|
|
+ // fires "change" instead of "input" on autocomplete.
|
|
|
+ addEventListener(el, 'change', onCompositionEnd)
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- if (document.activeElement === el && el.type !== 'range') {
|
|
|
- // #8546
|
|
|
- if (lazy && value === oldValue) {
|
|
|
- return
|
|
|
- }
|
|
|
- if (trim && el.value.trim() === newValue) {
|
|
|
- return
|
|
|
- }
|
|
|
+/**
|
|
|
+ * @internal
|
|
|
+ */
|
|
|
+export const vModelTextUpdate = (
|
|
|
+ el: HTMLInputElement | HTMLTextAreaElement,
|
|
|
+ value: any,
|
|
|
+ oldValue: any,
|
|
|
+ trim: boolean | undefined,
|
|
|
+ number: boolean | undefined,
|
|
|
+ lazy: boolean | undefined,
|
|
|
+): void => {
|
|
|
+ // avoid clearing unresolved text. #2302
|
|
|
+ if ((el as any).composing) return
|
|
|
+ const elValue =
|
|
|
+ (number || el.type === 'number') && !/^0\d/.test(el.value)
|
|
|
+ ? looseToNumber(el.value)
|
|
|
+ : el.value
|
|
|
+ const newValue = value == null ? '' : value
|
|
|
+
|
|
|
+ if (elValue === newValue) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (document.activeElement === el && el.type !== 'range') {
|
|
|
+ // #8546
|
|
|
+ if (lazy && value === oldValue) {
|
|
|
+ return
|
|
|
}
|
|
|
+ if (trim && el.value.trim() === newValue) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- el.value = newValue
|
|
|
- },
|
|
|
+ el.value = newValue
|
|
|
}
|
|
|
|
|
|
export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
|