@dimailn/vuetify 2.7.2-alpha56 → 2.7.2-alpha57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/json/attributes.json +3945 -417
- package/dist/json/tags.json +1120 -133
- package/dist/json/web-types.json +12516 -2651
- package/dist/vuetify.js +66 -76
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +1 -1
- package/dist/vuetify.min.js +2 -2
- package/es5/directives/click-outside/index.js +19 -21
- package/es5/directives/click-outside/index.js.map +1 -1
- package/es5/directives/intersect/index.js +12 -17
- package/es5/directives/intersect/index.js.map +1 -1
- package/es5/directives/mutate/index.js +9 -11
- package/es5/directives/mutate/index.js.map +1 -1
- package/es5/directives/resize/index.js +8 -10
- package/es5/directives/resize/index.js.map +1 -1
- package/es5/directives/scroll/index.js +11 -12
- package/es5/directives/scroll/index.js.map +1 -1
- package/es5/directives/touch/index.js +6 -5
- package/es5/directives/touch/index.js.map +1 -1
- package/es5/framework.js +1 -1
- package/es5/services/theme/utils.js.map +1 -1
- package/lib/directives/click-outside/index.js +17 -19
- package/lib/directives/click-outside/index.js.map +1 -1
- package/lib/directives/intersect/index.js +12 -16
- package/lib/directives/intersect/index.js.map +1 -1
- package/lib/directives/mutate/index.js +9 -11
- package/lib/directives/mutate/index.js.map +1 -1
- package/lib/directives/resize/index.js +8 -8
- package/lib/directives/resize/index.js.map +1 -1
- package/lib/directives/scroll/index.js +8 -8
- package/lib/directives/scroll/index.js.map +1 -1
- package/lib/directives/touch/index.js +6 -5
- package/lib/directives/touch/index.js.map +1 -1
- package/lib/framework.js +1 -1
- package/lib/services/theme/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/components/VMenu/__tests__/VMenuActivatorTest.spec.ts +25 -0
- package/src/components/VMenu/__tests__/test-with-directives.spec.ts +50 -0
- package/src/directives/click-outside/__tests__/click-outside-shadow-dom.spec.ts +2 -1
- package/src/directives/click-outside/__tests__/click-outside.spec.ts +2 -1
- package/src/directives/click-outside/index.ts +25 -18
- package/src/directives/intersect/__tests__/intersect.spec.ts +31 -13
- package/src/directives/intersect/index.ts +15 -19
- package/src/directives/mutate/__tests__/mutate.spec.ts +35 -27
- package/src/directives/mutate/index.ts +12 -6
- package/src/directives/resize/__tests__/resize.spec.ts +4 -4
- package/src/directives/resize/index.ts +11 -18
- package/src/directives/scroll/__tests__/scroll.spec.ts +5 -29
- package/src/directives/scroll/index.ts +14 -7
- package/src/directives/touch/index.ts +6 -5
- package/src/services/theme/utils.ts +1 -1
|
@@ -12,6 +12,14 @@ type ClickOutsideDirective = VNodeDirective & {
|
|
|
12
12
|
value?: ((e: Event) => void) | ClickOutsideBindingArgs
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
interface ClickOutsideState {
|
|
16
|
+
onClick: (e: Event) => void
|
|
17
|
+
onMousedown: (e: Event) => void
|
|
18
|
+
lastMousedownWasOutside: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const clickOutsideState = new WeakMap<HTMLElement, ClickOutsideState>()
|
|
22
|
+
|
|
15
23
|
function defaultConditional () {
|
|
16
24
|
return true
|
|
17
25
|
}
|
|
@@ -55,8 +63,10 @@ function checkIsActive (e: PointerEvent, binding: ClickOutsideDirective): boolea
|
|
|
55
63
|
|
|
56
64
|
function directive (e: PointerEvent, el: HTMLElement, binding: ClickOutsideDirective) {
|
|
57
65
|
const handler = typeof binding.value === 'function' ? binding.value : binding.value!.handler
|
|
66
|
+
const state = clickOutsideState.get(el)
|
|
67
|
+
if (!state) return
|
|
58
68
|
|
|
59
|
-
|
|
69
|
+
state.lastMousedownWasOutside && checkEvent(e, el, binding) && setTimeout(() => {
|
|
60
70
|
checkIsActive(e, binding) && handler && handler(e)
|
|
61
71
|
}, 0)
|
|
62
72
|
}
|
|
@@ -80,39 +90,36 @@ export const ClickOutside = {
|
|
|
80
90
|
mounted (el: HTMLElement, binding: ClickOutsideDirective, vnode: VNode) {
|
|
81
91
|
const onClick = (e: Event) => directive(e as PointerEvent, el, binding)
|
|
82
92
|
const onMousedown = (e: Event) => {
|
|
83
|
-
|
|
93
|
+
const state = clickOutsideState.get(el)
|
|
94
|
+
if (!state) return
|
|
95
|
+
state.lastMousedownWasOutside = checkEvent(e as PointerEvent, el, binding)
|
|
84
96
|
}
|
|
85
97
|
|
|
98
|
+
clickOutsideState.set(el, {
|
|
99
|
+
onClick,
|
|
100
|
+
onMousedown,
|
|
101
|
+
lastMousedownWasOutside: true
|
|
102
|
+
})
|
|
103
|
+
|
|
86
104
|
handleShadow(el, (app: HTMLElement) => {
|
|
87
105
|
app.addEventListener('click', onClick, true)
|
|
88
106
|
app.addEventListener('mousedown', onMousedown, true)
|
|
89
107
|
})
|
|
90
|
-
|
|
91
|
-
if (!el._clickOutside) {
|
|
92
|
-
el._clickOutside = {
|
|
93
|
-
lastMousedownWasOutside: true
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
el._clickOutside[vnode.ctx.uid] = {
|
|
98
|
-
onClick,
|
|
99
|
-
onMousedown
|
|
100
|
-
}
|
|
101
108
|
},
|
|
102
109
|
|
|
103
110
|
unmounted (el: HTMLElement, binding: ClickOutsideDirective, vnode: VNode) {
|
|
104
|
-
|
|
111
|
+
const state = clickOutsideState.get(el)
|
|
112
|
+
if (!state) return
|
|
105
113
|
|
|
106
114
|
handleShadow(el, (app: HTMLElement) => {
|
|
107
|
-
if (!app
|
|
108
|
-
|
|
109
|
-
const { onClick, onMousedown } = el._clickOutside[vnode.ctx.uid]!
|
|
115
|
+
if (!app) return
|
|
110
116
|
|
|
117
|
+
const { onClick, onMousedown } = state
|
|
111
118
|
app.removeEventListener('click', onClick, true)
|
|
112
119
|
app.removeEventListener('mousedown', onMousedown, true)
|
|
113
120
|
})
|
|
114
121
|
|
|
115
|
-
delete
|
|
122
|
+
clickOutsideState.delete(el)
|
|
116
123
|
}
|
|
117
124
|
}
|
|
118
125
|
|
|
@@ -2,27 +2,45 @@
|
|
|
2
2
|
import Intersect from '../'
|
|
3
3
|
|
|
4
4
|
describe('intersect', () => {
|
|
5
|
+
let observerInstance: any
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
observerInstance = undefined
|
|
9
|
+
;(global as any).IntersectionObserver = class IntersectionObserver {
|
|
10
|
+
callback: (entries: any, observer: any) => void
|
|
11
|
+
observe = jest.fn()
|
|
12
|
+
unobserve = jest.fn()
|
|
13
|
+
|
|
14
|
+
constructor (callback: (entries: any, observer: any) => void) {
|
|
15
|
+
this.callback = callback
|
|
16
|
+
observerInstance = this
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
|
|
5
21
|
it('should bind event on mounted', () => {
|
|
6
22
|
const callback = jest.fn()
|
|
7
23
|
const el = document.createElement('div')
|
|
8
24
|
document.body.appendChild(el)
|
|
9
25
|
|
|
10
26
|
Intersect.mounted(el, {
|
|
27
|
+
instance: { $: { uid: 1 } },
|
|
11
28
|
value: callback,
|
|
12
29
|
modifiers: { quiet: true }
|
|
13
|
-
} as any, {
|
|
30
|
+
} as any, {} as any)
|
|
14
31
|
|
|
15
|
-
expect(
|
|
32
|
+
expect(observerInstance).toBeTruthy()
|
|
33
|
+
expect(observerInstance.observe).toHaveBeenCalledWith(el)
|
|
16
34
|
expect(callback).not.toHaveBeenCalled()
|
|
17
35
|
|
|
18
36
|
document.body.removeChild(el)
|
|
19
37
|
|
|
20
38
|
Intersect.unmounted(el, {
|
|
39
|
+
instance: { $: { uid: 1 } },
|
|
21
40
|
value: callback,
|
|
22
41
|
modifiers: { quiet: true }
|
|
23
|
-
} as any, {
|
|
24
|
-
|
|
25
|
-
expect((el as any)._observe[1]).toBeFalsy()
|
|
42
|
+
} as any, {} as any)
|
|
43
|
+
expect(observerInstance.unobserve).toHaveBeenCalledWith(el)
|
|
26
44
|
})
|
|
27
45
|
|
|
28
46
|
it('should invoke callback once and unbind', () => {
|
|
@@ -33,21 +51,21 @@ describe('intersect', () => {
|
|
|
33
51
|
const callback = jest.fn()
|
|
34
52
|
|
|
35
53
|
Intersect.mounted(el, {
|
|
54
|
+
instance: { $: { uid: 1 } },
|
|
36
55
|
value: callback,
|
|
37
56
|
modifiers: { once: true }
|
|
38
|
-
} as any, {
|
|
57
|
+
} as any, {} as any)
|
|
39
58
|
|
|
40
59
|
expect(callback).toHaveBeenCalledTimes(0)
|
|
41
|
-
expect(
|
|
60
|
+
expect(observerInstance).toBeTruthy()
|
|
42
61
|
|
|
43
|
-
|
|
62
|
+
observerInstance.callback([{ isIntersecting: false }], observerInstance)
|
|
44
63
|
|
|
45
|
-
expect(callback).toHaveBeenCalledTimes(
|
|
46
|
-
expect((el as any)._observe[1]).toBeTruthy()
|
|
64
|
+
expect(callback).toHaveBeenCalledTimes(0)
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
observerInstance.callback([{ isIntersecting: true }], observerInstance)
|
|
49
67
|
|
|
50
|
-
expect(callback).toHaveBeenCalledTimes(
|
|
51
|
-
expect(
|
|
68
|
+
expect(callback).toHaveBeenCalledTimes(1)
|
|
69
|
+
expect(observerInstance.unobserve).toHaveBeenCalledWith(el)
|
|
52
70
|
})
|
|
53
71
|
})
|
|
@@ -17,16 +17,13 @@ interface ObserveDirectiveBinding
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
_observe?: Record<
|
|
24
|
-
number,
|
|
25
|
-
{ init: boolean, observer: IntersectionObserver }
|
|
26
|
-
>
|
|
27
|
-
}
|
|
20
|
+
interface IntersectState {
|
|
21
|
+
init: boolean
|
|
22
|
+
observer: IntersectionObserver
|
|
28
23
|
}
|
|
29
24
|
|
|
25
|
+
const intersectState = new WeakMap<HTMLElement, IntersectState>()
|
|
26
|
+
|
|
30
27
|
function mounted (
|
|
31
28
|
el: HTMLElement,
|
|
32
29
|
binding: ObserveDirectiveBinding,
|
|
@@ -48,8 +45,8 @@ function mounted (
|
|
|
48
45
|
entries: IntersectionObserverEntry[] = [],
|
|
49
46
|
observer: IntersectionObserver
|
|
50
47
|
) => {
|
|
51
|
-
const
|
|
52
|
-
if (!
|
|
48
|
+
const state = intersectState.get(el)
|
|
49
|
+
if (!state) return // Just in case, should never fire
|
|
53
50
|
|
|
54
51
|
const isIntersecting = entries.some(entry => entry.isIntersecting)
|
|
55
52
|
|
|
@@ -58,20 +55,19 @@ function mounted (
|
|
|
58
55
|
if (
|
|
59
56
|
handler &&
|
|
60
57
|
typeof handler === 'function' &&
|
|
61
|
-
(!modifiers.quiet ||
|
|
62
|
-
(!modifiers.once || isIntersecting ||
|
|
58
|
+
(!modifiers.quiet || state.init) &&
|
|
59
|
+
(!modifiers.once || isIntersecting || state.init)
|
|
63
60
|
) {
|
|
64
61
|
handler(entries, observer, isIntersecting)
|
|
65
62
|
}
|
|
66
63
|
|
|
67
64
|
if (isIntersecting && modifiers.once) unmounted(el, binding, vnode)
|
|
68
|
-
else
|
|
65
|
+
else state.init = true
|
|
69
66
|
},
|
|
70
67
|
options
|
|
71
68
|
)
|
|
72
69
|
|
|
73
|
-
el
|
|
74
|
-
el._observe![vnode.ctx!.uid] = { init: false, observer }
|
|
70
|
+
intersectState.set(el, { init: false, observer })
|
|
75
71
|
|
|
76
72
|
observer.observe(el)
|
|
77
73
|
}
|
|
@@ -93,11 +89,11 @@ function unmounted (
|
|
|
93
89
|
binding: ObserveDirectiveBinding,
|
|
94
90
|
vnode: VNode
|
|
95
91
|
) {
|
|
96
|
-
const
|
|
97
|
-
if (!
|
|
92
|
+
const state = intersectState.get(el)
|
|
93
|
+
if (!state) return
|
|
98
94
|
|
|
99
|
-
|
|
100
|
-
delete
|
|
95
|
+
state.observer.unobserve(el)
|
|
96
|
+
intersectState.delete(el)
|
|
101
97
|
}
|
|
102
98
|
|
|
103
99
|
export const Intersect: ObjectDirective<
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
// Directives
|
|
2
2
|
import Mutate from '../'
|
|
3
3
|
|
|
4
|
+
const observers: any[] = [];
|
|
5
|
+
|
|
4
6
|
(global as any).MutationObserver = class { // Mock MutationObserver
|
|
5
7
|
_callback: Function
|
|
6
|
-
|
|
7
8
|
_observe = jest.fn()
|
|
9
|
+
disconnect = jest.fn()
|
|
8
10
|
|
|
9
11
|
constructor (callback) {
|
|
10
12
|
this._callback = callback
|
|
13
|
+
observers.push(this)
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
disconnect () {}
|
|
14
|
-
|
|
15
16
|
observe (_, options) {
|
|
16
17
|
this._observe(options)
|
|
17
18
|
}
|
|
@@ -22,26 +23,30 @@ import Mutate from '../'
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
describe('mutate.ts', () => {
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
observers.length = 0
|
|
28
|
+
})
|
|
29
|
+
|
|
25
30
|
it('should bind event on inserted', () => {
|
|
26
31
|
const callback = jest.fn()
|
|
27
32
|
const el = document.createElement('div') as any
|
|
28
33
|
document.body.appendChild(el)
|
|
29
34
|
|
|
30
35
|
Mutate.mounted(el, {
|
|
36
|
+
instance: { $: { uid: 1 } },
|
|
31
37
|
value: callback
|
|
32
|
-
} as any, {
|
|
38
|
+
} as any, {} as any)
|
|
33
39
|
|
|
34
|
-
expect(
|
|
40
|
+
expect(observers).toHaveLength(1)
|
|
35
41
|
expect(callback).not.toHaveBeenCalled()
|
|
36
42
|
|
|
37
43
|
document.body.removeChild(el)
|
|
38
44
|
|
|
39
45
|
Mutate.unmounted(el, {
|
|
46
|
+
instance: { $: { uid: 1 } },
|
|
40
47
|
value: callback
|
|
41
|
-
} as any, {
|
|
42
|
-
|
|
43
|
-
const uid = Object.keys(el._mutate)[0]
|
|
44
|
-
expect(el._mutate[uid]).toBeFalsy()
|
|
48
|
+
} as any, {} as any)
|
|
49
|
+
expect(observers[0].disconnect).toHaveBeenCalled()
|
|
45
50
|
})
|
|
46
51
|
|
|
47
52
|
it('should fire event on mutation', () => {
|
|
@@ -50,19 +55,20 @@ describe('mutate.ts', () => {
|
|
|
50
55
|
document.body.appendChild(el)
|
|
51
56
|
|
|
52
57
|
Mutate.mounted(el, {
|
|
58
|
+
instance: { $: { uid: 1 } },
|
|
53
59
|
value: callback
|
|
54
|
-
} as any, {
|
|
60
|
+
} as any, {} as any)
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
el._mutate[uid]?.observer?.trigger([{}])
|
|
62
|
+
observers[0]?.trigger([{} as any])
|
|
58
63
|
|
|
59
64
|
expect(callback).toHaveBeenCalledTimes(1)
|
|
60
65
|
|
|
61
66
|
document.body.removeChild(el)
|
|
62
67
|
|
|
63
68
|
Mutate.unmounted(el, {
|
|
69
|
+
instance: { $: { uid: 1 } },
|
|
64
70
|
value: callback
|
|
65
|
-
} as any, {
|
|
71
|
+
} as any, {} as any)
|
|
66
72
|
})
|
|
67
73
|
|
|
68
74
|
it('should fire event once', () => {
|
|
@@ -71,18 +77,18 @@ describe('mutate.ts', () => {
|
|
|
71
77
|
document.body.appendChild(el)
|
|
72
78
|
|
|
73
79
|
Mutate.mounted(el, {
|
|
80
|
+
instance: { $: { uid: 1 } },
|
|
74
81
|
value: callback,
|
|
75
82
|
modifiers: {
|
|
76
83
|
once: true
|
|
77
84
|
}
|
|
78
|
-
} as any, {
|
|
85
|
+
} as any, {} as any)
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
el._mutate[uid]?.observer?.trigger([{}])
|
|
87
|
+
observers[0]?.trigger([{} as any])
|
|
82
88
|
|
|
83
89
|
expect(callback).toHaveBeenCalledTimes(1)
|
|
84
90
|
// Once modifier should remove the observer
|
|
85
|
-
expect(
|
|
91
|
+
expect(observers[0].disconnect).toHaveBeenCalled()
|
|
86
92
|
|
|
87
93
|
document.body.removeChild(el)
|
|
88
94
|
})
|
|
@@ -93,6 +99,7 @@ describe('mutate.ts', () => {
|
|
|
93
99
|
document.body.appendChild(el)
|
|
94
100
|
|
|
95
101
|
Mutate.mounted(el, {
|
|
102
|
+
instance: { $: { uid: 1 } },
|
|
96
103
|
value: {
|
|
97
104
|
options: {
|
|
98
105
|
attributes: false,
|
|
@@ -100,17 +107,17 @@ describe('mutate.ts', () => {
|
|
|
100
107
|
},
|
|
101
108
|
handler: callback
|
|
102
109
|
}
|
|
103
|
-
} as any, {
|
|
110
|
+
} as any, {} as any)
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
el._mutate[uid]?.observer?.trigger([{}])
|
|
112
|
+
observers[0]?.trigger([{} as any])
|
|
107
113
|
|
|
108
114
|
expect(callback).toHaveBeenCalledTimes(1)
|
|
109
|
-
expect(
|
|
115
|
+
expect(observers[0]._observe).toHaveBeenLastCalledWith({ attributes: false, subtree: true })
|
|
110
116
|
|
|
111
117
|
document.body.removeChild(el)
|
|
112
118
|
|
|
113
119
|
Mutate.unmounted(el, {
|
|
120
|
+
instance: { $: { uid: 1 } },
|
|
114
121
|
value: {
|
|
115
122
|
options: {
|
|
116
123
|
attributes: false,
|
|
@@ -118,7 +125,7 @@ describe('mutate.ts', () => {
|
|
|
118
125
|
},
|
|
119
126
|
handler: callback
|
|
120
127
|
}
|
|
121
|
-
} as any, {
|
|
128
|
+
} as any, {} as any)
|
|
122
129
|
})
|
|
123
130
|
|
|
124
131
|
it('should work with observer modifiers', () => {
|
|
@@ -127,29 +134,30 @@ describe('mutate.ts', () => {
|
|
|
127
134
|
document.body.appendChild(el)
|
|
128
135
|
|
|
129
136
|
Mutate.mounted(el, {
|
|
137
|
+
instance: { $: { uid: 1 } },
|
|
130
138
|
value: callback,
|
|
131
139
|
modifiers: {
|
|
132
140
|
attr: true,
|
|
133
141
|
child: true,
|
|
134
142
|
sub: true
|
|
135
143
|
}
|
|
136
|
-
} as any, {
|
|
144
|
+
} as any, {} as any)
|
|
137
145
|
|
|
138
|
-
|
|
139
|
-
el._mutate[uid]?.observer?.trigger([{}])
|
|
146
|
+
observers[0]?.trigger([{} as any])
|
|
140
147
|
|
|
141
148
|
expect(callback).toHaveBeenCalledTimes(1)
|
|
142
|
-
expect(
|
|
149
|
+
expect(observers[0]._observe).toHaveBeenLastCalledWith({ attributes: true, childList: true, subtree: true })
|
|
143
150
|
|
|
144
151
|
document.body.removeChild(el)
|
|
145
152
|
|
|
146
153
|
Mutate.unmounted(el, {
|
|
154
|
+
instance: { $: { uid: 1 } },
|
|
147
155
|
value: callback,
|
|
148
156
|
modifiers: {
|
|
149
157
|
attr: true,
|
|
150
158
|
child: true,
|
|
151
159
|
sub: true
|
|
152
160
|
}
|
|
153
|
-
} as any, {
|
|
161
|
+
} as any, {} as any)
|
|
154
162
|
})
|
|
155
163
|
})
|
|
@@ -17,6 +17,12 @@ type MutateModifiers = {
|
|
|
17
17
|
char?: boolean
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
interface MutateState {
|
|
21
|
+
observer: MutationObserver
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const mutateState = new WeakMap<HTMLElement, MutateState>()
|
|
25
|
+
|
|
20
26
|
function mounted (
|
|
21
27
|
el: HTMLElement,
|
|
22
28
|
binding: DirectiveBinding<MutateValue>,
|
|
@@ -51,7 +57,7 @@ function mounted (
|
|
|
51
57
|
const observer = new MutationObserver(
|
|
52
58
|
(mutationsList: MutationRecord[], observer: MutationObserver) => {
|
|
53
59
|
/* istanbul ignore if */
|
|
54
|
-
if (!el
|
|
60
|
+
if (!mutateState.has(el)) return // Just in case, should never fire
|
|
55
61
|
|
|
56
62
|
callback(mutationsList, observer)
|
|
57
63
|
|
|
@@ -61,8 +67,7 @@ function mounted (
|
|
|
61
67
|
)
|
|
62
68
|
|
|
63
69
|
observer.observe(el, options)
|
|
64
|
-
el
|
|
65
|
-
el._mutate![vnode.ctx!.uid] = { observer }
|
|
70
|
+
mutateState.set(el, { observer })
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
function unmounted (
|
|
@@ -70,10 +75,11 @@ function unmounted (
|
|
|
70
75
|
binding: DirectiveBinding<MutateValue>,
|
|
71
76
|
vnode: VNode
|
|
72
77
|
) {
|
|
73
|
-
|
|
78
|
+
const state = mutateState.get(el)
|
|
79
|
+
if (!state) return
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
delete
|
|
81
|
+
state.observer.disconnect()
|
|
82
|
+
mutateState.delete(el)
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
export const Mutate = {
|
|
@@ -8,10 +8,10 @@ describe('resize.ts', () => {
|
|
|
8
8
|
jest.spyOn(window, 'removeEventListener')
|
|
9
9
|
const el = {}
|
|
10
10
|
|
|
11
|
-
Resize.mounted(el as HTMLElement, {
|
|
11
|
+
Resize.mounted(el as HTMLElement, { instance: { $: { uid: 1 } }, value: callback } as any, {} as any)
|
|
12
12
|
expect(callback).toHaveBeenCalled()
|
|
13
13
|
expect(window.addEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })
|
|
14
|
-
Resize.unmounted(el as HTMLElement, {
|
|
14
|
+
Resize.unmounted(el as HTMLElement, { instance: { $: { uid: 1 } }, value: callback } as any, {} as any)
|
|
15
15
|
expect(window.removeEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })
|
|
16
16
|
})
|
|
17
17
|
|
|
@@ -21,10 +21,10 @@ describe('resize.ts', () => {
|
|
|
21
21
|
jest.spyOn(window, 'removeEventListener')
|
|
22
22
|
const el = {}
|
|
23
23
|
|
|
24
|
-
Resize.mounted(el as HTMLElement, { value: callback, modifiers: { quiet: true } } as any, {
|
|
24
|
+
Resize.mounted(el as HTMLElement, { instance: { $: { uid: 1 } }, value: callback, modifiers: { quiet: true } } as any, {} as any)
|
|
25
25
|
expect(callback).not.toHaveBeenCalled()
|
|
26
26
|
expect(window.addEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })
|
|
27
|
-
Resize.unmounted(el as HTMLElement, { value: callback, modifiers: { quiet: true } } as any, {
|
|
27
|
+
Resize.unmounted(el as HTMLElement, { instance: { $: { uid: 1 } }, value: callback, modifiers: { quiet: true } } as any, {} as any)
|
|
28
28
|
expect(window.removeEventListener).toHaveBeenCalledWith('resize', callback, { passive: true })
|
|
29
29
|
})
|
|
30
30
|
})
|
|
@@ -5,18 +5,13 @@ interface ResizeDirectiveBinding extends DirectiveBinding {
|
|
|
5
5
|
options?: boolean | AddEventListenerOptions
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
number,
|
|
12
|
-
{
|
|
13
|
-
callback: () => void
|
|
14
|
-
options: boolean | AddEventListenerOptions
|
|
15
|
-
}
|
|
16
|
-
>
|
|
17
|
-
}
|
|
8
|
+
interface ResizeState {
|
|
9
|
+
callback: () => void
|
|
10
|
+
options: boolean | AddEventListenerOptions
|
|
18
11
|
}
|
|
19
12
|
|
|
13
|
+
const resizeState = new WeakMap<HTMLElement, ResizeState>()
|
|
14
|
+
|
|
20
15
|
function mounted (
|
|
21
16
|
el: HTMLElement,
|
|
22
17
|
binding: ResizeDirectiveBinding,
|
|
@@ -27,11 +22,10 @@ function mounted (
|
|
|
27
22
|
|
|
28
23
|
window.addEventListener('resize', callback, options)
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
el._onResize![vnode.ctx!.uid] = {
|
|
25
|
+
resizeState.set(el, {
|
|
32
26
|
callback,
|
|
33
27
|
options
|
|
34
|
-
}
|
|
28
|
+
})
|
|
35
29
|
|
|
36
30
|
if (!binding.modifiers || !binding.modifiers.quiet) {
|
|
37
31
|
callback()
|
|
@@ -43,13 +37,12 @@ function unmounted (
|
|
|
43
37
|
binding: ResizeDirectiveBinding,
|
|
44
38
|
vnode: VNode
|
|
45
39
|
) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const { callback, options } =
|
|
40
|
+
const state = resizeState.get(el)
|
|
41
|
+
if (!state) return
|
|
42
|
+
const { callback, options } = state
|
|
49
43
|
|
|
50
44
|
window.removeEventListener('resize', callback, options)
|
|
51
|
-
|
|
52
|
-
delete el._onResize[vnode.ctx!.uid]
|
|
45
|
+
resizeState.delete(el)
|
|
53
46
|
}
|
|
54
47
|
|
|
55
48
|
export const Resize: ObjectDirective = {
|
|
@@ -12,9 +12,10 @@ describe('scroll.ts', () => {
|
|
|
12
12
|
let vnode
|
|
13
13
|
|
|
14
14
|
beforeEach(() => {
|
|
15
|
-
vnode = {
|
|
15
|
+
vnode = {} as any
|
|
16
16
|
options = { passive: true }
|
|
17
17
|
binding = {
|
|
18
|
+
instance: { $: { uid: 1 } },
|
|
18
19
|
value: jest.fn(),
|
|
19
20
|
modifiers: {},
|
|
20
21
|
arg: null
|
|
@@ -32,16 +33,10 @@ describe('scroll.ts', () => {
|
|
|
32
33
|
mounted(el, binding, vnode)
|
|
33
34
|
|
|
34
35
|
expect(spyOnWindowAddListener).toHaveBeenCalledWith('scroll', binding.value, options)
|
|
35
|
-
expect(el._onScroll[1]).toEqual({
|
|
36
|
-
handler: binding.value,
|
|
37
|
-
options,
|
|
38
|
-
target: window
|
|
39
|
-
})
|
|
40
36
|
|
|
41
37
|
unmounted(el, binding, vnode)
|
|
42
38
|
|
|
43
39
|
expect(spyOnWindowRemoveListener).toHaveBeenCalledWith('scroll', binding.value, options)
|
|
44
|
-
expect(el._onScroll[1]).toBeUndefined()
|
|
45
40
|
})
|
|
46
41
|
|
|
47
42
|
it('should work with a provided valid querySelector string', () => {
|
|
@@ -66,16 +61,10 @@ describe('scroll.ts', () => {
|
|
|
66
61
|
mounted(el, binding, vnode)
|
|
67
62
|
|
|
68
63
|
expect(spyOnFooAddListener).toHaveBeenCalledWith('scroll', binding.value, options)
|
|
69
|
-
expect(el._onScroll[1]).toEqual({
|
|
70
|
-
handler: binding.value,
|
|
71
|
-
options,
|
|
72
|
-
target
|
|
73
|
-
})
|
|
74
64
|
|
|
75
65
|
unmounted(el, binding, vnode)
|
|
76
66
|
|
|
77
67
|
expect(spyOnFooRemoveListener).toHaveBeenCalledWith('scroll', binding.value, options)
|
|
78
|
-
expect(el._onScroll[1]).toBeUndefined()
|
|
79
68
|
|
|
80
69
|
document.body.removeChild(target)
|
|
81
70
|
})
|
|
@@ -86,16 +75,10 @@ describe('scroll.ts', () => {
|
|
|
86
75
|
mounted(el, binding, vnode)
|
|
87
76
|
|
|
88
77
|
expect(el.addEventListener).toHaveBeenCalledWith('scroll', binding.value, options)
|
|
89
|
-
expect(el._onScroll[1]).toEqual({
|
|
90
|
-
handler: binding.value,
|
|
91
|
-
options,
|
|
92
|
-
target: undefined
|
|
93
|
-
})
|
|
94
78
|
|
|
95
79
|
unmounted(el, binding, vnode)
|
|
96
80
|
|
|
97
81
|
expect(el.removeEventListener).toHaveBeenCalledWith('scroll', binding.value, options)
|
|
98
|
-
expect(el._onScroll[1]).toBeUndefined()
|
|
99
82
|
})
|
|
100
83
|
|
|
101
84
|
it('should not remove listeners if no _onScroll property present', () => {
|
|
@@ -106,25 +89,18 @@ describe('scroll.ts', () => {
|
|
|
106
89
|
|
|
107
90
|
it('should accept an object for the value with handler and/or options', () => {
|
|
108
91
|
const handler = binding.value
|
|
92
|
+
jest.spyOn(window, 'addEventListener')
|
|
109
93
|
|
|
110
94
|
binding.value = { handler }
|
|
111
95
|
|
|
112
96
|
mounted(el, binding, vnode)
|
|
113
97
|
|
|
114
|
-
expect(
|
|
115
|
-
handler,
|
|
116
|
-
target: window,
|
|
117
|
-
options: { passive: true }
|
|
118
|
-
})
|
|
98
|
+
expect(window.addEventListener).toHaveBeenLastCalledWith('scroll', handler, { passive: true })
|
|
119
99
|
|
|
120
100
|
binding.value = { handler, options: { passive: false } }
|
|
121
101
|
|
|
122
102
|
mounted(el, binding, vnode)
|
|
123
103
|
|
|
124
|
-
expect(
|
|
125
|
-
handler,
|
|
126
|
-
target: window,
|
|
127
|
-
options: { passive: false }
|
|
128
|
-
})
|
|
104
|
+
expect(window.addEventListener).toHaveBeenLastCalledWith('scroll', handler, { passive: false })
|
|
129
105
|
})
|
|
130
106
|
})
|
|
@@ -13,6 +13,14 @@ interface ScrollDirectiveBinding extends Omit<DirectiveBinding, 'modifiers'> {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
interface ScrollState {
|
|
17
|
+
handler: EventListener | EventListenerObject
|
|
18
|
+
options: boolean | AddEventListenerOptions
|
|
19
|
+
target?: EventTarget
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const scrollState = new WeakMap<HTMLElement, ScrollState>()
|
|
23
|
+
|
|
16
24
|
function mounted (
|
|
17
25
|
el: HTMLElement,
|
|
18
26
|
binding: ScrollDirectiveBinding,
|
|
@@ -38,13 +46,12 @@ function mounted (
|
|
|
38
46
|
|
|
39
47
|
target.addEventListener('scroll', handler, options)
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
el._onScroll![vnode.ctx!.uid] = {
|
|
49
|
+
scrollState.set(el, {
|
|
43
50
|
handler,
|
|
44
51
|
options,
|
|
45
52
|
// Don't reference self
|
|
46
53
|
target: self ? undefined : target
|
|
47
|
-
}
|
|
54
|
+
})
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
function unmounted (
|
|
@@ -52,12 +59,12 @@ function unmounted (
|
|
|
52
59
|
binding: ScrollDirectiveBinding,
|
|
53
60
|
vnode: VNode
|
|
54
61
|
) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const { handler, options, target = el } =
|
|
62
|
+
const state = scrollState.get(el)
|
|
63
|
+
if (!state) return
|
|
64
|
+
const { handler, options, target = el } = state
|
|
58
65
|
|
|
59
66
|
target.removeEventListener('scroll', handler, options)
|
|
60
|
-
delete
|
|
67
|
+
scrollState.delete(el)
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
export const Scroll: ObjectDirective = {
|