@dimailn/vuetify 2.7.2-alpha55 → 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.
Files changed (61) hide show
  1. package/dist/json/attributes.json +3945 -417
  2. package/dist/json/tags.json +1120 -133
  3. package/dist/json/web-types.json +12516 -2651
  4. package/dist/vuetify.js +72 -78
  5. package/dist/vuetify.js.map +1 -1
  6. package/dist/vuetify.min.css +1 -1
  7. package/dist/vuetify.min.js +2 -2
  8. package/es5/components/VFileInput/VFileInput.js +3 -1
  9. package/es5/components/VFileInput/VFileInput.js.map +1 -1
  10. package/es5/components/VTextField/VTextField.js +3 -1
  11. package/es5/components/VTextField/VTextField.js.map +1 -1
  12. package/es5/directives/click-outside/index.js +19 -21
  13. package/es5/directives/click-outside/index.js.map +1 -1
  14. package/es5/directives/intersect/index.js +12 -17
  15. package/es5/directives/intersect/index.js.map +1 -1
  16. package/es5/directives/mutate/index.js +9 -11
  17. package/es5/directives/mutate/index.js.map +1 -1
  18. package/es5/directives/resize/index.js +8 -10
  19. package/es5/directives/resize/index.js.map +1 -1
  20. package/es5/directives/scroll/index.js +11 -12
  21. package/es5/directives/scroll/index.js.map +1 -1
  22. package/es5/directives/touch/index.js +6 -5
  23. package/es5/directives/touch/index.js.map +1 -1
  24. package/es5/framework.js +1 -1
  25. package/es5/services/theme/utils.js.map +1 -1
  26. package/lib/components/VFileInput/VFileInput.js +2 -0
  27. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  28. package/lib/components/VTextField/VTextField.js +2 -0
  29. package/lib/components/VTextField/VTextField.js.map +1 -1
  30. package/lib/directives/click-outside/index.js +17 -19
  31. package/lib/directives/click-outside/index.js.map +1 -1
  32. package/lib/directives/intersect/index.js +12 -16
  33. package/lib/directives/intersect/index.js.map +1 -1
  34. package/lib/directives/mutate/index.js +9 -11
  35. package/lib/directives/mutate/index.js.map +1 -1
  36. package/lib/directives/resize/index.js +8 -8
  37. package/lib/directives/resize/index.js.map +1 -1
  38. package/lib/directives/scroll/index.js +8 -8
  39. package/lib/directives/scroll/index.js.map +1 -1
  40. package/lib/directives/touch/index.js +6 -5
  41. package/lib/directives/touch/index.js.map +1 -1
  42. package/lib/framework.js +1 -1
  43. package/lib/services/theme/utils.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/components/VFileInput/VFileInput.ts +1 -1
  46. package/src/components/VMenu/__tests__/VMenuActivatorTest.spec.ts +25 -0
  47. package/src/components/VMenu/__tests__/test-with-directives.spec.ts +50 -0
  48. package/src/components/VTextField/VTextField.ts +1 -1
  49. package/src/directives/click-outside/__tests__/click-outside-shadow-dom.spec.ts +2 -1
  50. package/src/directives/click-outside/__tests__/click-outside.spec.ts +2 -1
  51. package/src/directives/click-outside/index.ts +25 -18
  52. package/src/directives/intersect/__tests__/intersect.spec.ts +31 -13
  53. package/src/directives/intersect/index.ts +15 -19
  54. package/src/directives/mutate/__tests__/mutate.spec.ts +35 -27
  55. package/src/directives/mutate/index.ts +12 -6
  56. package/src/directives/resize/__tests__/resize.spec.ts +4 -4
  57. package/src/directives/resize/index.ts +11 -18
  58. package/src/directives/scroll/__tests__/scroll.spec.ts +5 -29
  59. package/src/directives/scroll/index.ts +14 -7
  60. package/src/directives/touch/index.ts +6 -5
  61. package/src/services/theme/utils.ts +1 -1
@@ -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, { ctx: { uid: 1 } } as any)
30
+ } as any, {} as any)
14
31
 
15
- expect((el as any)._observe).toBeTruthy()
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, { ctx: { uid: 1 } } 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, { ctx: { uid: 1 } } as any)
57
+ } as any, {} as any)
39
58
 
40
59
  expect(callback).toHaveBeenCalledTimes(0)
41
- expect((el as any)._observe[1]).toBeTruthy()
60
+ expect(observerInstance).toBeTruthy()
42
61
 
43
- ;(el as any)._observe[1].observer.callback([{ isIntersecting: false }])
62
+ observerInstance.callback([{ isIntersecting: false }], observerInstance)
44
63
 
45
- expect(callback).toHaveBeenCalledTimes(1)
46
- expect((el as any)._observe[1]).toBeTruthy()
64
+ expect(callback).toHaveBeenCalledTimes(0)
47
65
 
48
- ;(el as any)._observe[1].observer.callback([{ isIntersecting: true }])
66
+ observerInstance.callback([{ isIntersecting: true }], observerInstance)
49
67
 
50
- expect(callback).toHaveBeenCalledTimes(2)
51
- expect((el as any)._observe[1]).toBeFalsy()
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
- // Расширяем HTMLElement для хранения данных наблюдателя
21
- declare global {
22
- interface HTMLElement {
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 _observe = el._observe?.[vnode.ctx!.uid]
52
- if (!_observe) return // Just in case, should never fire
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 || _observe.init) &&
62
- (!modifiers.once || isIntersecting || _observe.init)
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 _observe.init = true
65
+ else state.init = true
69
66
  },
70
67
  options
71
68
  )
72
69
 
73
- el._observe = Object(el._observe)
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 observe = el._observe?.[vnode.ctx!.uid]
97
- if (!observe) return
92
+ const state = intersectState.get(el)
93
+ if (!state) return
98
94
 
99
- observe.observer.unobserve(el)
100
- delete el._observe![vnode.ctx!.uid]
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, { ctx: { uid: 1 } } as any)
38
+ } as any, {} as any)
33
39
 
34
- expect(el._mutate).toBeTruthy()
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, { ctx: { uid: 1 } } 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, { ctx: { uid: 1 } } as any)
60
+ } as any, {} as any)
55
61
 
56
- const uid = Object.keys(el._mutate)[0]
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, { ctx: { uid: 1 } } 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, { ctx: { uid: 1 } } as any)
85
+ } as any, {} as any)
79
86
 
80
- const uid = Object.keys(el._mutate)[0]
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(Object.keys(el._mutate)).toHaveLength(0)
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, { ctx: { uid: 1 } } as any)
110
+ } as any, {} as any)
104
111
 
105
- const uid = Object.keys(el._mutate)[0]
106
- el._mutate[uid]?.observer?.trigger([{}])
112
+ observers[0]?.trigger([{} as any])
107
113
 
108
114
  expect(callback).toHaveBeenCalledTimes(1)
109
- expect(el._mutate[uid].observer._observe).toHaveBeenLastCalledWith({ attributes: false, subtree: true })
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, { ctx: { uid: 1 } } 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, { ctx: { uid: 1 } } as any)
144
+ } as any, {} as any)
137
145
 
138
- const uid = Object.keys(el._mutate)[0]
139
- el._mutate[uid]?.observer?.trigger([{}])
146
+ observers[0]?.trigger([{} as any])
140
147
 
141
148
  expect(callback).toHaveBeenCalledTimes(1)
142
- expect(el._mutate[uid].observer._observe).toHaveBeenLastCalledWith({ attributes: true, childList: true, subtree: true })
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, { ctx: { uid: 1 } } 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._mutate) return // Just in case, should never fire
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._mutate = Object(el._mutate)
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
- if (!el._mutate?.[vnode.ctx!.uid]) return
78
+ const state = mutateState.get(el)
79
+ if (!state) return
74
80
 
75
- el._mutate[vnode.ctx!.uid]!.observer.disconnect()
76
- delete el._mutate[vnode.ctx!.uid]
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, { value: callback } as any, { ctx: { uid: 1 } } as any)
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, { value: callback } as any, { ctx: { uid: 1 } } as any)
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, { ctx: { uid: 1 } } 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, { ctx: { uid: 1 } } 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
- declare global {
9
- interface HTMLElement {
10
- _onResize?: Record<
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
- el._onResize = Object(el._onResize)
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
- if (!el._onResize?.[vnode.ctx!.uid]) return
47
-
48
- const { callback, options } = el._onResize[vnode.ctx!.uid]!
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 = { ctx: { uid: 1 } } as any
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(el._onScroll[1]).toEqual({
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(el._onScroll[1]).toEqual({
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
- el._onScroll = Object(el._onScroll)
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
- if (!el._onScroll?.[vnode.ctx!.uid]) return
56
-
57
- const { handler, options, target = el } = el._onScroll[vnode.ctx!.uid]!
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 el._onScroll[vnode.ctx!.uid]
67
+ scrollState.delete(el)
61
68
  }
62
69
 
63
70
  export const Scroll: ObjectDirective = {
@@ -85,6 +85,8 @@ function createHandlers (value: TouchHandlers): TouchStoredHandlers {
85
85
  }
86
86
  }
87
87
 
88
+ const touchState = new WeakMap<EventTarget, TouchStoredHandlers>()
89
+
88
90
  function mounted (
89
91
  el: HTMLElement,
90
92
  binding: DirectiveBinding<TouchValue>,
@@ -98,8 +100,7 @@ function mounted (
98
100
  if (!target) return
99
101
 
100
102
  const handlers = createHandlers(binding.value)
101
- target._touchHandlers = Object(target._touchHandlers)
102
- target._touchHandlers![vnode.ctx!.uid] = handlers
103
+ touchState.set(target, handlers)
103
104
 
104
105
  keys(handlers).forEach(eventName => {
105
106
  target.addEventListener(
@@ -116,14 +117,14 @@ function unmounted (
116
117
  vnode: VNode
117
118
  ) {
118
119
  const target = binding.value.parent ? el.parentElement : el
119
- if (!target || !target._touchHandlers) return
120
+ if (!target) return
120
121
 
121
- const handlers = target._touchHandlers[vnode.ctx!.uid]
122
+ const handlers = touchState.get(target)
122
123
  if (handlers) {
123
124
  keys(handlers).forEach(eventName => {
124
125
  target.removeEventListener(eventName, handlers[eventName])
125
126
  })
126
- delete target._touchHandlers[vnode.ctx!.uid]
127
+ touchState.delete(target)
127
128
  }
128
129
  }
129
130
 
@@ -100,7 +100,7 @@ export function genStyles (theme: VuetifyParsedTheme, cssVar = false): string {
100
100
 
101
101
  const variants = keys(value)
102
102
  for (let i = 0; i < variants.length; ++i) {
103
- const variant = variants[i]
103
+ const variant = variants[i] as string
104
104
  const variantValue = value[variant]
105
105
  if (variant === 'base') continue
106
106