+79
-55
lines changedFilter options
+79
-55
lines changed Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
1
1
/* @flow */
2
2
3
-
export function mergeVNodeHook (def: Object, hookKey: string, hook: Function, key: string) {
4
-
key = key + hookKey
5
-
const injectedHash: Object = def.__injected || (def.__injected = {})
6
-
if (!injectedHash[key]) {
7
-
injectedHash[key] = true
8
-
const oldHook: ?Function = def[hookKey]
9
-
if (oldHook) {
10
-
def[hookKey] = function () {
11
-
oldHook.apply(this, arguments)
12
-
hook.apply(this, arguments)
13
-
}
3
+
import { remove } from 'shared/util'
4
+
import { createFnInvoker } from './update-listeners'
5
+
6
+
export function mergeVNodeHook (def: Object, hookKey: string, hook: Function) {
7
+
let invoker
8
+
const oldHook = def[hookKey]
9
+
10
+
function wrappedHook () {
11
+
hook.apply(this, arguments)
12
+
// important: remove merged hook to ensure it's called only once
13
+
// and prevent memory leak
14
+
remove(invoker.fns, wrappedHook)
15
+
}
16
+
17
+
if (!oldHook) {
18
+
// no existing hook
19
+
invoker = createFnInvoker([wrappedHook])
20
+
} else {
21
+
/* istanbul ignore if */
22
+
if (oldHook.fns && oldHook.merged) {
23
+
// already a merged invoker
24
+
invoker = oldHook
25
+
invoker.fns.push(wrappedHook)
14
26
} else {
15
-
def[hookKey] = hook
27
+
// existing plain hook
28
+
invoker = createFnInvoker([oldHook, wrappedHook])
16
29
}
17
30
}
31
+
32
+
invoker.merged = true
33
+
def[hookKey] = invoker
18
34
}
Original file line number Diff line number Diff line change
@@ -19,25 +19,20 @@ const normalizeEvent = cached((name: string): {
19
19
}
20
20
})
21
21
22
-
function createEventHandle (fn: Function | Array<Function>): {
23
-
fn: Function | Array<Function>;
24
-
invoker: Function;
25
-
} {
26
-
const handle = {
27
-
fn,
28
-
invoker: function () {
29
-
const fn = handle.fn
30
-
if (Array.isArray(fn)) {
31
-
for (let i = 0; i < fn.length; i++) {
32
-
fn[i].apply(null, arguments)
33
-
}
34
-
} else {
35
-
// return handler return value for single handlers
36
-
return fn.apply(null, arguments)
22
+
export function createFnInvoker (fns: Function | Array<Function>): Function {
23
+
function invoker () {
24
+
const fns = invoker.fns
25
+
if (Array.isArray(fns)) {
26
+
for (let i = 0; i < fns.length; i++) {
27
+
fns[i].apply(null, arguments)
37
28
}
29
+
} else {
30
+
// return handler return value for single handlers
31
+
return fns.apply(null, arguments)
38
32
}
39
33
}
40
-
return handle
34
+
invoker.fns = fns
35
+
return invoker
41
36
}
42
37
43
38
export function updateListeners (
@@ -58,19 +53,19 @@ export function updateListeners (
58
53
vm
59
54
)
60
55
} else if (!old) {
61
-
if (!cur.invoker) {
62
-
cur = on[name] = createEventHandle(cur)
56
+
if (!cur.fns) {
57
+
cur = on[name] = createFnInvoker(cur)
63
58
}
64
-
add(event.name, cur.invoker, event.once, event.capture)
59
+
add(event.name, cur, event.once, event.capture)
65
60
} else if (cur !== old) {
66
-
old.fn = cur
61
+
old.fns = cur
67
62
on[name] = old
68
63
}
69
64
}
70
65
for (name in oldOn) {
71
66
if (!on[name]) {
72
67
event = normalizeEvent(name)
73
-
remove(event.name, oldOn[name].invoker, event.capture)
68
+
remove(event.name, oldOn[name], event.capture)
74
69
}
75
70
}
76
71
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
1
1
/* @flow */
2
2
3
+
import { emptyNode } from 'core/vdom/patch'
3
4
import { resolveAsset } from 'core/util/options'
4
5
import { mergeVNodeHook } from 'core/vdom/helpers/index'
5
-
import { emptyNode } from 'core/vdom/patch'
6
6
7
7
export default {
8
8
create: updateDirectives,
@@ -54,7 +54,7 @@ function _update (oldVnode, vnode) {
54
54
}
55
55
}
56
56
if (isCreate) {
57
-
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', callInsert, 'dir-insert')
57
+
mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', callInsert)
58
58
} else {
59
59
callInsert()
60
60
}
@@ -65,7 +65,7 @@ function _update (oldVnode, vnode) {
65
65
for (let i = 0; i < dirsWithPostpatch.length; i++) {
66
66
callHook(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode)
67
67
}
68
-
}, 'dir-postpatch')
68
+
})
69
69
}
70
70
71
71
if (!isCreate) {
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ export function extractTransitionData (comp: Component): Object {
47
47
// extract listeners and pass them directly to the transition methods
48
48
const listeners: ?Object = options._parentListeners
49
49
for (const key in listeners) {
50
-
data[camelize(key)] = listeners[key].fn
50
+
data[camelize(key)] = listeners[key]
51
51
}
52
52
return data
53
53
}
@@ -132,11 +132,12 @@ export default {
132
132
// component instance. This key will be used to remove pending leaving nodes
133
133
// during entering.
134
134
const id: string = `__transition-${this._uid}-`
135
-
const key: string = child.key = child.key == null
135
+
child.key = child.key == null
136
136
? id + child.tag
137
137
: isPrimitive(child.key)
138
138
? (String(child.key).indexOf(id) === 0 ? child.key : id + child.key)
139
139
: child.key
140
+
140
141
const data: Object = (child.data || (child.data = {})).transition = extractTransitionData(this)
141
142
const oldRawChild: VNode = this._vnode
142
143
const oldChild: VNode = getRealChild(oldRawChild)
@@ -158,16 +159,14 @@ export default {
158
159
mergeVNodeHook(oldData, 'afterLeave', () => {
159
160
this._leaving = false
160
161
this.$forceUpdate()
161
-
}, key)
162
+
})
162
163
return placeholder(h, rawChild)
163
164
} else if (mode === 'in-out') {
164
165
let delayedLeave
165
166
const performLeave = () => { delayedLeave() }
166
-
mergeVNodeHook(data, 'afterEnter', performLeave, key)
167
-
mergeVNodeHook(data, 'enterCancelled', performLeave, key)
168
-
mergeVNodeHook(oldData, 'delayLeave', leave => {
169
-
delayedLeave = leave
170
-
}, key)
167
+
mergeVNodeHook(data, 'afterEnter', performLeave)
168
+
mergeVNodeHook(data, 'enterCancelled', performLeave)
169
+
mergeVNodeHook(oldData, 'delayLeave', leave => { delayedLeave = leave })
171
170
}
172
171
}
173
172
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import { RANGE_TOKEN, CHECKBOX_RADIO_TOKEN } from 'web/compiler/directives/model
10
10
// user-attached handlers.
11
11
function normalizeEvents (on) {
12
12
let event
13
+
/* istanbul ignore if */
13
14
if (on[RANGE_TOKEN]) {
14
15
// IE input[type=range] only supports `change` event
15
16
event = isIE ? 'change' : 'input'
Original file line number Diff line number Diff line change
@@ -83,11 +83,7 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
83
83
}
84
84
85
85
const expectsCSS = css !== false && !isIE9
86
-
const userWantsControl =
87
-
enterHook &&
88
-
// enterHook may be a bound method which exposes
89
-
// the length of original fn as _length
90
-
(enterHook._length || enterHook.length) > 1
86
+
const userWantsControl = getHookAgumentsLength(enterHook)
91
87
92
88
const cb = el._enterCb = once(() => {
93
89
if (expectsCSS) {
@@ -116,7 +112,7 @@ export function enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
116
112
pendingNode.elm._leaveCb()
117
113
}
118
114
enterHook && enterHook(el, cb)
119
-
}, 'transition-insert')
115
+
})
120
116
}
121
117
122
118
// start enter transition
@@ -181,11 +177,7 @@ export function leave (vnode: VNodeWithData, rm: Function) {
181
177
} = data
182
178
183
179
const expectsCSS = css !== false && !isIE9
184
-
const userWantsControl =
185
-
leave &&
186
-
// leave hook may be a bound method which exposes
187
-
// the length of original fn as _length
188
-
(leave._length || leave.length) > 1
180
+
const userWantsControl = getHookAgumentsLength(leave)
189
181
190
182
const explicitLeaveDuration = isObject(duration) ? duration.leave : duration
191
183
if (process.env.NODE_ENV !== 'production' && explicitLeaveDuration != null) {
@@ -271,6 +263,27 @@ function isValidDuration (val) {
271
263
return typeof val === 'number' && !isNaN(val)
272
264
}
273
265
266
+
/**
267
+
* Normalize a transition hook's argument length. The hook may be:
268
+
* - a merged hook (invoker) with the original in .fns
269
+
* - a wrapped component method (check ._length)
270
+
* - a plain function (.length)
271
+
*/
272
+
function getHookAgumentsLength (fn: Function): boolean {
273
+
if (!fn) return false
274
+
const invokerFns = fn.fns
275
+
if (invokerFns) {
276
+
// invoker
277
+
return getHookAgumentsLength(
278
+
Array.isArray(invokerFns)
279
+
? invokerFns[0]
280
+
: invokerFns
281
+
)
282
+
} else {
283
+
return (fn._length || fn.length) > 1
284
+
}
285
+
}
286
+
274
287
function _enter (_: any, vnode: VNodeWithData) {
275
288
if (!vnode.data.show) {
276
289
enter(vnode)
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4