|
1 |
| -import { kebabCase } from '@/util' |
| 1 | +import { kebabCase, debounce } from '@/util' |
2 | 2 | import ModelAction from '@/action/model'
|
3 | 3 | import MethodAction from '@/action/method'
|
4 | 4 | import DOMElement from '@/dom/dom_element'
|
@@ -50,16 +50,20 @@ export default {
|
50 | 50 |
|
51 | 51 | store.callHook('interceptWireModelAttachListener', el, directive, component, debounceIf)
|
52 | 52 |
|
| 53 | + // File uploads are handled by UploadFiles.js. |
| 54 | + if (el.rawNode().tagName.toLowerCase() === 'input' && el.rawNode().type === 'file') return |
| 55 | + |
53 | 56 | const event = (el.rawNode().tagName.toLowerCase() === 'select')
|
54 | 57 | || ['checkbox', 'radio'].includes(el.rawNode().type)
|
55 | 58 | || directive.modifiers.includes('lazy')
|
56 | 59 | ? 'change' : 'input'
|
57 | 60 |
|
58 | 61 | // If it's a text input and not .lazy, debounce, otherwise fire immediately.
|
59 |
| - const handler = debounceIf(hasDebounceModifier || (el.isTextInput() && ! isLazy), e => { |
| 62 | + let handler = debounceIf(hasDebounceModifier || (el.isTextInput() && ! isLazy), e => { |
60 | 63 | const model = directive.value
|
61 | 64 | const el = new DOMElement(e.target)
|
62 |
| - const value = e instanceof CustomEvent |
| 65 | + // We have to check for typeof e.detail here for IE 11. |
| 66 | + const value = e instanceof CustomEvent && typeof e.detail != 'undefined' |
63 | 67 | ? e.detail
|
64 | 68 | : el.valueFromInput(component)
|
65 | 69 |
|
@@ -93,9 +97,15 @@ export default {
|
93 | 97 | if (selectedButNotPressedKeyModifiers.length > 0) return false;
|
94 | 98 | }
|
95 | 99 |
|
| 100 | + // Strip 'debounce' modifier and time modifiers from modifiers list |
| 101 | + let modifiers = directive.modifiers.filter(modifier => { |
| 102 | + return ! modifier.match(/debounce/) |
| 103 | + && ! modifier.match(/[0-9ms]/) |
| 104 | + && ! modifier.match(/[0-9s]/) |
| 105 | + }) |
| 106 | + |
96 | 107 | // Only handle listener if no, or matching key modifiers are passed.
|
97 |
| - return (directive.modifiers.length === 0 |
98 |
| - || directive.modifiers.includes(kebabCase(e.key))) |
| 108 | + return modifiers.length === 0 || modifiers.includes(kebabCase(e.key)) |
99 | 109 | })
|
100 | 110 | break;
|
101 | 111 | case 'click':
|
@@ -155,16 +165,35 @@ export default {
|
155 | 165 | return
|
156 | 166 | }
|
157 | 167 |
|
| 168 | + if (method === '$emitSelf') { |
| 169 | + store.emitSelf(component.id, ...params) |
| 170 | + return |
| 171 | + } |
| 172 | + |
| 173 | + if (method === '$emitTo') { |
| 174 | + store.emitTo(...params) |
| 175 | + return |
| 176 | + } |
| 177 | + |
158 | 178 | if (directive.value) {
|
159 | 179 | component.addAction(new MethodAction(method, params, el))
|
160 | 180 | }
|
161 | 181 | })
|
162 | 182 | }
|
163 | 183 |
|
164 |
| - el.addEventListener(event, handler) |
| 184 | + const debounceIf = (condition, callback, time) => { |
| 185 | + return condition |
| 186 | + ? debounce(callback, time) |
| 187 | + : callback |
| 188 | + } |
| 189 | + |
| 190 | + const hasDebounceModifier = directive.modifiers.includes('debounce') |
| 191 | + const debouncedHandler = debounceIf(hasDebounceModifier, handler, directive.durationOr(150)) |
| 192 | + |
| 193 | + el.addEventListener(event, debouncedHandler) |
165 | 194 |
|
166 | 195 | component.addListenerForTeardown(() => {
|
167 |
| - el.removeEventListener(event, handler) |
| 196 | + el.removeEventListener(event, debouncedHandler) |
168 | 197 | })
|
169 | 198 | },
|
170 | 199 |
|
|
0 commit comments