-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtext.js
159 lines (146 loc) · 4.76 KB
/
text.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
var _ = require('../../util')
module.exports = {
bind: function () {
var self = this
var el = this.el
// check params
// - lazy: update model on "change" instead of "input"
var lazy = this._checkParam('lazy') != null
// - number: cast value into number when updating model.
var number = this._checkParam('number') != null
// - debounce: debounce the input listener
var debounce = parseInt(this._checkParam('debounce'), 10)
// handle composition events.
// http://blog.evanyou.me/2014/01/03/composition-event/
// skip this for Android because it handles composition
// events quite differently. Android doesn't trigger
// composition events for language input methods e.g.
// Chinese, but instead triggers them for spelling
// suggestions... (see Discussion/#162)
var composing = false
if (!_.isAndroid) {
this.onComposeStart = function () {
composing = true
}
this.onComposeEnd = function () {
composing = false
// in IE11 the "compositionend" event fires AFTER
// the "input" event, so the input handler is blocked
// at the end... have to call it here.
self.listener()
}
_.on(el,'compositionstart', this.onComposeStart)
_.on(el,'compositionend', this.onComposeEnd)
}
function syncToModel () {
var val = number
? _.toNumber(el.value)
: el.value
self.set(val)
}
// if the directive has filters, we need to
// record cursor position and restore it after updating
// the input with the filtered value.
// also force update for type="range" inputs to enable
// "lock in range" (see #506)
if (this.hasRead || el.type === 'range') {
this.listener = function () {
if (composing) return
var charsOffset
// some HTML5 input types throw error here
try {
// record how many chars from the end of input
// the cursor was at
charsOffset = el.value.length - el.selectionStart
} catch (e) {}
// Fix IE10/11 infinite update cycle
// https://github.com/yyx990803/vue/issues/592
/* istanbul ignore if */
if (charsOffset < 0) {
return
}
syncToModel()
_.nextTick(function () {
// force a value update, because in
// certain cases the write filters output the
// same result for different input values, and
// the Observer set events won't be triggered.
var newVal = self._watcher.value
self.update(newVal)
if (charsOffset != null) {
var cursorPos =
_.toString(newVal).length - charsOffset
el.setSelectionRange(cursorPos, cursorPos)
}
})
}
} else {
this.listener = function () {
if (composing) return
syncToModel()
}
}
if (debounce) {
this.listener = _.debounce(this.listener, debounce)
}
// Now attach the main listener
this.event = lazy ? 'change' : 'input'
// Support jQuery events, since jQuery.trigger() doesn't
// trigger native events in some cases and some plugins
// rely on $.trigger()
//
// We want to make sure if a listener is attached using
// jQuery, it is also removed with jQuery, that's why
// we do the check for each directive instance and
// store that check result on itself. This also allows
// easier test coverage control by unsetting the global
// jQuery variable in tests.
this.hasjQuery = typeof jQuery === 'function'
if (this.hasjQuery) {
jQuery(el).on(this.event, this.listener)
} else {
_.on(el, this.event, this.listener)
}
// IE9 doesn't fire input event on backspace/del/cut
if (!lazy && _.isIE9) {
this.onCut = function () {
_.nextTick(self.listener)
}
this.onDel = function (e) {
if (e.keyCode === 46 || e.keyCode === 8) {
self.listener()
}
}
_.on(el, 'cut', this.onCut)
_.on(el, 'keyup', this.onDel)
}
// set initial value if present
if (
el.hasAttribute('value') ||
(el.tagName === 'TEXTAREA' && el.value.trim())
) {
this._initValue = number
? _.toNumber(el.value)
: el.value
}
},
update: function (value) {
this.el.value = _.toString(value)
},
unbind: function () {
var el = this.el
if (this.hasjQuery) {
jQuery(el).off(this.event, this.listener)
} else {
_.off(el, this.event, this.listener)
}
if (this.onComposeStart) {
_.off(el, 'compositionstart', this.onComposeStart)
_.off(el, 'compositionend', this.onComposeEnd)
}
if (this.onCut) {
_.off(el,'cut', this.onCut)
_.off(el,'keyup', this.onDel)
}
}
}