quasar 2.8.4 → 2.9.1

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 (169) hide show
  1. package/dist/api/QBreadcrumbsEl.json +52 -0
  2. package/dist/api/QBtn.json +41 -6
  3. package/dist/api/QBtnDropdown.json +1 -1
  4. package/dist/api/QChip.json +1 -1
  5. package/dist/api/QEditor.json +7 -0
  6. package/dist/api/QExpansionItem.json +1 -1
  7. package/dist/api/QItem.json +52 -0
  8. package/dist/api/QRating.json +13 -0
  9. package/dist/api/QRouteTab.json +42 -6
  10. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  11. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  12. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  13. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  14. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  15. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  16. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  17. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  18. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  19. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  20. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  21. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  22. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  23. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  24. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  26. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  27. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  28. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  44. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  45. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  46. package/dist/icon-set/themify.umd.prod.js +1 -1
  47. package/dist/lang/ar-TN.umd.prod.js +1 -1
  48. package/dist/lang/ar.umd.prod.js +1 -1
  49. package/dist/lang/az-Latn.umd.prod.js +1 -1
  50. package/dist/lang/bg.umd.prod.js +1 -1
  51. package/dist/lang/bn.umd.prod.js +1 -1
  52. package/dist/lang/ca.umd.prod.js +1 -1
  53. package/dist/lang/cs.umd.prod.js +1 -1
  54. package/dist/lang/da.umd.prod.js +1 -1
  55. package/dist/lang/de.umd.prod.js +1 -1
  56. package/dist/lang/el.umd.prod.js +1 -1
  57. package/dist/lang/en-GB.umd.prod.js +1 -1
  58. package/dist/lang/en-US.umd.prod.js +1 -1
  59. package/dist/lang/eo.umd.prod.js +1 -1
  60. package/dist/lang/es.umd.prod.js +1 -1
  61. package/dist/lang/et.umd.prod.js +1 -1
  62. package/dist/lang/eu.umd.prod.js +1 -1
  63. package/dist/lang/fa-IR.umd.prod.js +1 -1
  64. package/dist/lang/fa.umd.prod.js +1 -1
  65. package/dist/lang/fi.umd.prod.js +1 -1
  66. package/dist/lang/fr.umd.prod.js +1 -1
  67. package/dist/lang/gn.umd.prod.js +1 -1
  68. package/dist/lang/he.umd.prod.js +1 -1
  69. package/dist/lang/hr.umd.prod.js +1 -1
  70. package/dist/lang/hu.umd.prod.js +1 -1
  71. package/dist/lang/id.umd.prod.js +1 -1
  72. package/dist/lang/is.umd.prod.js +1 -1
  73. package/dist/lang/it.umd.prod.js +1 -1
  74. package/dist/lang/ja.umd.prod.js +1 -1
  75. package/dist/lang/km.umd.prod.js +1 -1
  76. package/dist/lang/ko-KR.umd.prod.js +1 -1
  77. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  78. package/dist/lang/kz.umd.prod.js +1 -1
  79. package/dist/lang/lt.umd.prod.js +1 -1
  80. package/dist/lang/lu.umd.prod.js +1 -1
  81. package/dist/lang/lv.umd.prod.js +1 -1
  82. package/dist/lang/ml.umd.prod.js +1 -1
  83. package/dist/lang/mm.umd.prod.js +1 -1
  84. package/dist/lang/ms.umd.prod.js +1 -1
  85. package/dist/lang/my.umd.prod.js +1 -1
  86. package/dist/lang/nb-NO.umd.prod.js +1 -1
  87. package/dist/lang/nl.umd.prod.js +2 -2
  88. package/dist/lang/pl.umd.prod.js +1 -1
  89. package/dist/lang/pt-BR.umd.prod.js +1 -1
  90. package/dist/lang/pt.umd.prod.js +1 -1
  91. package/dist/lang/ro.umd.prod.js +1 -1
  92. package/dist/lang/ru.umd.prod.js +1 -1
  93. package/dist/lang/sk.umd.prod.js +1 -1
  94. package/dist/lang/sl.umd.prod.js +1 -1
  95. package/dist/lang/sm.umd.prod.js +1 -1
  96. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  97. package/dist/lang/sr.umd.prod.js +1 -1
  98. package/dist/lang/sv.umd.prod.js +1 -1
  99. package/dist/lang/ta.umd.prod.js +1 -1
  100. package/dist/lang/th.umd.prod.js +1 -1
  101. package/dist/lang/tr.umd.prod.js +1 -1
  102. package/dist/lang/ug.umd.prod.js +1 -1
  103. package/dist/lang/uk.umd.prod.js +1 -1
  104. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  105. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  106. package/dist/lang/vi.umd.prod.js +1 -1
  107. package/dist/lang/zh-CN.umd.prod.js +1 -1
  108. package/dist/lang/zh-TW.umd.prod.js +1 -1
  109. package/dist/quasar.cjs.prod.js +2 -2
  110. package/dist/quasar.esm.js +533 -337
  111. package/dist/quasar.esm.prod.js +2 -2
  112. package/dist/quasar.sass +1 -1
  113. package/dist/quasar.umd.js +532 -336
  114. package/dist/quasar.umd.prod.js +2 -2
  115. package/dist/transforms/auto-import.json +7 -3
  116. package/dist/transforms/import-map.json +2 -0
  117. package/dist/types/api/qeditor.d.ts +17 -0
  118. package/dist/types/api.d.ts +1 -0
  119. package/dist/types/index.d.ts +93 -8
  120. package/dist/types/utils/run-sequential-promises.d.ts +1 -1
  121. package/dist/vetur/quasar-attributes.json +4 -0
  122. package/dist/vetur/quasar-tags.json +1 -0
  123. package/dist/web-types/web-types.json +60 -9
  124. package/lang/nl.js +2 -2
  125. package/lang/nl.mjs +2 -2
  126. package/package.json +5 -3
  127. package/src/components/banner/__tests__/QBanner.spec.js +107 -0
  128. package/src/components/bar/__tests__/QBar.spec.js +46 -0
  129. package/src/components/breadcrumbs/QBreadcrumbsEl.js +6 -7
  130. package/src/components/breadcrumbs/QBreadcrumbsEl.json +53 -0
  131. package/src/components/btn/QBtn.js +19 -19
  132. package/src/components/btn/QBtn.json +41 -6
  133. package/src/components/btn/use-btn.js +6 -4
  134. package/src/components/btn-dropdown/QBtnDropdown.json +1 -1
  135. package/src/components/checkbox/QCheckbox.js +1 -2
  136. package/src/components/checkbox/use-checkbox.js +2 -1
  137. package/src/components/chip/QChip.json +1 -1
  138. package/src/components/dialog/QDialog.js +6 -4
  139. package/src/components/drawer/QDrawer.js +7 -4
  140. package/src/components/editor/QEditor.json +9 -0
  141. package/src/components/expansion-item/QExpansionItem.json +1 -1
  142. package/src/components/item/QItem.js +4 -5
  143. package/src/components/item/QItem.json +53 -0
  144. package/src/components/menu/QMenu.js +4 -5
  145. package/src/components/menu/__tests__/QMenu.spec.js +7 -0
  146. package/src/components/popup-edit/QPopupEdit.js +2 -5
  147. package/src/components/radio/QRadio.js +3 -3
  148. package/src/components/rating/QRating.js +48 -10
  149. package/src/components/rating/QRating.json +11 -0
  150. package/src/components/stepper/QStep.js +5 -3
  151. package/src/components/table/QTable.js +3 -5
  152. package/src/components/tabs/QRouteTab.js +6 -4
  153. package/src/components/tabs/QRouteTab.json +42 -6
  154. package/src/components/tabs/QTabs.js +188 -108
  155. package/src/components/tabs/use-tab.js +62 -38
  156. package/src/components/tooltip/QTooltip.js +7 -13
  157. package/src/components/tree/QTree.js +1 -1
  158. package/src/composables/private/__tests__/use-model-toggle.spec.js +2 -0
  159. package/src/composables/private/__tests__/use-transition.spec.js +4 -0
  160. package/src/composables/private/use-router-link.js +80 -43
  161. package/src/composables/private/use-tick.js +15 -9
  162. package/src/composables/private/use-timeout.js +20 -7
  163. package/src/directives/TouchPan.js +1 -1
  164. package/src/directives/TouchRepeat.js +1 -1
  165. package/src/directives/TouchSwipe.js +1 -1
  166. package/src/utils/extend.js +19 -19
  167. package/src/utils/private/inject-obj-prop.js +2 -0
  168. package/src/utils/private/rtl.js +10 -7
  169. package/src/utils/run-sequential-promises.js +1 -1
@@ -93,7 +93,7 @@ export default createComponent({
93
93
  const hideOnRouteChange = computed(() => props.persistent !== true)
94
94
 
95
95
  const { registerTick, removeTick } = useTick()
96
- const { registerTimeout, removeTimeout } = useTimeout()
96
+ const { registerTimeout } = useTimeout()
97
97
  const { transition, transitionStyle } = useTransition(props, showing)
98
98
  const { localScrollTarget, changeScrollEvent, unconfigureScrollTarget } = useScrollTarget(props, configureScrollTarget)
99
99
 
@@ -147,11 +147,9 @@ export default createComponent({
147
147
  }
148
148
 
149
149
  function handleShow (evt) {
150
- removeTick()
151
- removeTimeout()
152
-
153
150
  showPortal()
154
151
 
152
+ // should removeTick() if this gets removed
155
153
  registerTick(() => {
156
154
  observer = new MutationObserver(() => updatePosition())
157
155
  observer.observe(innerRef.value, { attributes: false, childList: true, characterData: true, subtree: true })
@@ -166,6 +164,7 @@ export default createComponent({
166
164
  )
167
165
  }
168
166
 
167
+ // should removeTimeout() if this gets removed
169
168
  registerTimeout(() => {
170
169
  showPortal(true) // done showing portal
171
170
  emit('show', evt)
@@ -174,11 +173,11 @@ export default createComponent({
174
173
 
175
174
  function handleHide (evt) {
176
175
  removeTick()
177
- removeTimeout()
178
176
  hidePortal()
179
177
 
180
178
  anchorCleanup()
181
179
 
180
+ // should removeTimeout() if this gets removed
182
181
  registerTimeout(() => {
183
182
  hidePortal(true) // done hiding, now destroy
184
183
  emit('hide', evt)
@@ -230,14 +229,10 @@ export default createComponent({
230
229
  addEvt(anchorEvents, 'tooltipTemp', evts)
231
230
  }
232
231
 
233
- registerTimeout(() => {
234
- show(evt)
235
- }, props.delay)
232
+ registerTimeout(() => { show(evt) }, props.delay)
236
233
  }
237
234
 
238
235
  function delayHide (evt) {
239
- removeTimeout()
240
-
241
236
  if ($q.platform.is.mobile === true) {
242
237
  cleanEvt(anchorEvents, 'tooltipTemp')
243
238
  clearSelection()
@@ -247,9 +242,8 @@ export default createComponent({
247
242
  }, 10)
248
243
  }
249
244
 
250
- registerTimeout(() => {
251
- hide(evt)
252
- }, props.hideDelay)
245
+ // should removeTimeout() if this gets removed
246
+ registerTimeout(() => { hide(evt) }, props.hideDelay)
253
247
  }
254
248
 
255
249
  function configureAnchorEl () {
@@ -620,7 +620,7 @@ export default createComponent({
620
620
  emit('update:selected', meta.key !== props.selected ? meta.key : null)
621
621
  }
622
622
  else if (meta.key !== props.selected) {
623
- emit('update:selected', meta.key || null)
623
+ emit('update:selected', meta.key === void 0 ? null : meta.key)
624
624
  }
625
625
  }
626
626
  else {
@@ -79,6 +79,7 @@ describe('use-model-toggle API', () => {
79
79
  expect(fn).not.to.be.called
80
80
  cy.dataCy('wrapper')
81
81
  .click()
82
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
82
83
  cy.dataCy('menu')
83
84
  .should('exist')
84
85
  .wait(300) // Await menu animation
@@ -99,6 +100,7 @@ describe('use-model-toggle API', () => {
99
100
  cy.dataCy('wrapper')
100
101
  cy.dataCy('method-show')
101
102
  .click({ force: true }) // Element is hidden to prevent clogging the window
103
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
102
104
  cy.dataCy('menu')
103
105
  .should('exist')
104
106
  .wait(300) // Await menu animation
@@ -61,6 +61,7 @@ describe('use-transition API', () => {
61
61
  describe('(prop): transition-duration', () => {
62
62
  it('should be done with transitioning after 300ms passed', () => {
63
63
  mount(WrapperOne)
64
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
64
65
  cy.dataCy('wrapper')
65
66
  .click()
66
67
  .wait(300)
@@ -70,6 +71,7 @@ describe('use-transition API', () => {
70
71
 
71
72
  it('should not be done with transitioning before 300ms passed', () => {
72
73
  mount(WrapperOne)
74
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
73
75
  cy.dataCy('wrapper')
74
76
  .click()
75
77
  .wait(200) // Commands take some time so a high value can fail, just take a decent margin
@@ -83,6 +85,7 @@ describe('use-transition API', () => {
83
85
  transitionDuration: 1000
84
86
  }
85
87
  })
88
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
86
89
  cy.dataCy('wrapper')
87
90
  .click()
88
91
  .wait(1000)
@@ -96,6 +99,7 @@ describe('use-transition API', () => {
96
99
  transitionDuration: 1000
97
100
  }
98
101
  })
102
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
99
103
  cy.dataCy('wrapper')
100
104
  .click()
101
105
  .wait(900)
@@ -5,7 +5,6 @@
5
5
 
6
6
  import { computed, getCurrentInstance } from 'vue'
7
7
 
8
- import { prevent } from '../../utils/event.js'
9
8
  import { vmHasRouter } from '../../utils/private/vm.js'
10
9
 
11
10
  // Get the original path value of a record by following its aliasOf
@@ -102,30 +101,34 @@ export const useRouterLinkProps = {
102
101
 
103
102
  // external props: type, tag
104
103
 
105
- export default function (fallbackTag) {
104
+ export default function ({ fallbackTag, useDisableForRouterLinkProps = true } = {}) {
106
105
  const vm = getCurrentInstance()
107
- const { props, proxy } = vm
106
+ const { props, proxy, emit } = vm
108
107
 
109
108
  const hasRouter = vmHasRouter(vm)
110
109
  const hasHrefLink = computed(() => props.disable !== true && props.href !== void 0)
111
110
 
112
- const hasRouterLinkProps = computed(() =>
113
- hasRouter === true
114
- && props.disable !== true
115
- && hasHrefLink.value !== true
116
- && props.to !== void 0 && props.to !== null && props.to !== ''
117
- )
118
-
119
- const linkRoute = computed(() => {
120
- if (hasRouterLinkProps.value === true) {
121
- try { return proxy.$router.resolve(props.to) }
122
- catch (err) {}
123
- }
111
+ // for perf reasons, we use minimum amount of runtime work
112
+ const hasRouterLinkProps = useDisableForRouterLinkProps === true
113
+ ? computed(() =>
114
+ hasRouter === true
115
+ && props.disable !== true
116
+ && hasHrefLink.value !== true
117
+ && props.to !== void 0 && props.to !== null && props.to !== ''
118
+ )
119
+ : computed(() =>
120
+ hasRouter === true
121
+ && hasHrefLink.value !== true
122
+ && props.to !== void 0 && props.to !== null && props.to !== ''
123
+ )
124
124
 
125
- return null
126
- })
125
+ const resolvedLink = computed(() => (
126
+ hasRouterLinkProps.value === true
127
+ ? getLink(props.to)
128
+ : null
129
+ ))
127
130
 
128
- const hasRouterLink = computed(() => linkRoute.value !== null)
131
+ const hasRouterLink = computed(() => resolvedLink.value !== null)
129
132
  const hasLink = computed(() => hasHrefLink.value === true || hasRouterLink.value === true)
130
133
 
131
134
  const linkTag = computed(() => (
@@ -134,7 +137,7 @@ export default function (fallbackTag) {
134
137
  : (props.tag || fallbackTag || 'div')
135
138
  ))
136
139
 
137
- const linkProps = computed(() => (
140
+ const linkAttrs = computed(() => (
138
141
  hasHrefLink.value === true
139
142
  ? {
140
143
  href: props.href,
@@ -143,7 +146,7 @@ export default function (fallbackTag) {
143
146
  : (
144
147
  hasRouterLink.value === true
145
148
  ? {
146
- href: linkRoute.value.href,
149
+ href: resolvedLink.value.href,
147
150
  target: props.target
148
151
  }
149
152
  : {}
@@ -152,11 +155,11 @@ export default function (fallbackTag) {
152
155
 
153
156
  const linkActiveIndex = computed(() => {
154
157
  if (hasRouterLink.value === false) {
155
- return null
158
+ return -1
156
159
  }
157
160
 
158
161
  const
159
- { matched } = linkRoute.value,
162
+ { matched } = resolvedLink.value,
160
163
  { length } = matched,
161
164
  routeMatched = matched[ length - 1 ]
162
165
 
@@ -199,14 +202,14 @@ export default function (fallbackTag) {
199
202
 
200
203
  const linkIsActive = computed(() =>
201
204
  hasRouterLink.value === true
202
- && linkActiveIndex.value > -1
203
- && includesParams(proxy.$route.params, linkRoute.value.params)
205
+ && linkActiveIndex.value !== -1
206
+ && includesParams(proxy.$route.params, resolvedLink.value.params)
204
207
  )
205
208
 
206
209
  const linkIsExactActive = computed(() =>
207
210
  linkIsActive.value === true
208
211
  && linkActiveIndex.value === proxy.$route.matched.length - 1
209
- && isSameRouteLocationParams(proxy.$route.params, linkRoute.value.params)
212
+ && isSameRouteLocationParams(proxy.$route.params, resolvedLink.value.params)
210
213
  )
211
214
 
212
215
  const linkClass = computed(() => (
@@ -223,32 +226,64 @@ export default function (fallbackTag) {
223
226
  : ''
224
227
  ))
225
228
 
226
- // should match RouterLink from Vue Router
227
- function navigateToRouterLink (e) {
228
- if (
229
- // component is not disabled
230
- props.disable === true
229
+ function getLink (to) {
230
+ try { return proxy.$router.resolve(to) }
231
+ catch (_) {}
232
+
233
+ return null
234
+ }
231
235
 
232
- // don't redirect with control keys
233
- || e.metaKey || e.altKey || e.ctrlKey || e.shiftKey
236
+ /**
237
+ * @returns Promise<RouterError | false | undefined>
238
+ */
239
+ function navigateToRouterLink (
240
+ e,
241
+ { returnRouterError, to = props.to, replace = props.replace } = {}
242
+ ) {
243
+ if (props.disable === true) {
244
+ // ensure native navigation is prevented in all cases,
245
+ // like when useDisableForRouterLinkProps === false (QRouteTab)
246
+ e.preventDefault()
247
+ return Promise.resolve(false)
248
+ }
234
249
 
235
- // don't redirect when preventDefault called
236
- // ...unless calling go() from @click(e, go)
237
- || (e.__qNavigate !== true && e.defaultPrevented === true)
250
+ if (
251
+ // don't redirect with control keys;
252
+ // should match RouterLink from Vue Router
253
+ e.metaKey || e.altKey || e.ctrlKey || e.shiftKey
238
254
 
239
255
  // don't redirect on right click
240
- || (e.button !== undefined && e.button !== 0)
256
+ || (e.button !== void 0 && e.button !== 0)
241
257
 
242
258
  // don't redirect if it should open in a new window
243
259
  || props.target === '_blank'
244
260
  ) {
245
- return false
261
+ return Promise.resolve(false)
246
262
  }
247
263
 
248
- prevent(e)
264
+ // hinder the native navigation
265
+ e.preventDefault()
266
+
267
+ // then() can also return a "soft" router error (Vue Router behavior)
268
+ const promise = proxy.$router[ replace === true ? 'replace' : 'push' ](to)
249
269
 
250
- return proxy.$router[ props.replace === true ? 'replace' : 'push' ](props.to)
251
- .catch(err => err)
270
+ return returnRouterError === true
271
+ ? promise
272
+ // else catching hard errors and also "soft" ones - then(err => ...)
273
+ : promise.then(() => {}).catch(() => {})
274
+ }
275
+
276
+ // warning! ensure that the component using it has 'click' included in its 'emits' definition prop
277
+ function navigateOnClick (e) {
278
+ if (hasRouterLink.value === true) {
279
+ const go = opts => navigateToRouterLink(e, opts)
280
+
281
+ emit('click', e, go)
282
+ e.defaultPrevented !== true && go()
283
+ }
284
+ else {
285
+ emit('click', e)
286
+ }
252
287
  }
253
288
 
254
289
  return {
@@ -257,12 +292,14 @@ export default function (fallbackTag) {
257
292
  hasLink,
258
293
 
259
294
  linkTag,
260
- linkRoute,
295
+ resolvedLink,
261
296
  linkIsActive,
262
297
  linkIsExactActive,
263
298
  linkClass,
264
- linkProps,
299
+ linkAttrs,
265
300
 
266
- navigateToRouterLink
301
+ getLink,
302
+ navigateToRouterLink,
303
+ navigateOnClick
267
304
  }
268
305
  }
@@ -1,32 +1,38 @@
1
- import { nextTick, onBeforeUnmount } from 'vue'
1
+ import { nextTick, onDeactivated, onBeforeUnmount, getCurrentInstance } from 'vue'
2
+
3
+ import { vmIsDestroyed } from '../../utils/private/vm'
2
4
 
3
5
  /*
4
6
  * Usage:
5
7
  * registerTick(fn)
6
- * registerTick(fn)
8
+ * removeTick()
7
9
  */
8
10
 
9
11
  export default function () {
10
12
  let tickFn
13
+ const vm = getCurrentInstance()
11
14
 
12
- onBeforeUnmount(() => {
15
+ function removeTick () {
13
16
  tickFn = void 0
14
- })
17
+ }
18
+
19
+ onDeactivated(removeTick)
20
+ onBeforeUnmount(removeTick)
15
21
 
16
22
  return {
23
+ removeTick,
24
+
17
25
  registerTick (fn) {
18
26
  tickFn = fn
19
27
 
20
28
  nextTick(() => {
21
29
  if (tickFn === fn) {
22
- tickFn()
30
+ // we also check if VM is destroyed, since if it
31
+ // got to trigger one nextTick() we cannot stop it
32
+ vmIsDestroyed(vm) === false && tickFn()
23
33
  tickFn = void 0
24
34
  }
25
35
  })
26
- },
27
-
28
- removeTick () {
29
- tickFn = void 0
30
36
  }
31
37
  }
32
38
  }
@@ -1,20 +1,33 @@
1
- import { onBeforeUnmount } from 'vue'
1
+ import { onDeactivated, onBeforeUnmount, getCurrentInstance } from 'vue'
2
+
3
+ import { vmIsDestroyed } from '../../utils/private/vm'
4
+
5
+ /*
6
+ * Usage:
7
+ * registerTimeout(fn[, delay])
8
+ * removeTimeout()
9
+ */
2
10
 
3
11
  export default function () {
4
12
  let timer
13
+ const vm = getCurrentInstance()
5
14
 
6
- onBeforeUnmount(() => {
15
+ function removeTimeout () {
7
16
  clearTimeout(timer)
8
- })
17
+ }
18
+
19
+ onDeactivated(removeTimeout)
20
+ onBeforeUnmount(removeTimeout)
9
21
 
10
22
  return {
23
+ removeTimeout,
24
+
11
25
  registerTimeout (fn, delay) {
12
26
  clearTimeout(timer)
13
- timer = setTimeout(fn, delay)
14
- },
15
27
 
16
- removeTimeout () {
17
- clearTimeout(timer)
28
+ if (vmIsDestroyed(vm) === false) {
29
+ timer = setTimeout(fn, delay)
30
+ }
18
31
  }
19
32
  }
20
33
  }
@@ -388,7 +388,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
388
388
 
389
389
  client.has.touch === true && addEvt(ctx, 'main', [
390
390
  [ el, 'touchstart', 'touchStart', `passive${ modifiers.capture === true ? 'Capture' : '' }` ],
391
- [ el, 'touchmove', 'noop', 'notPassiveCapture' ]
391
+ [ el, 'touchmove', 'noop', 'notPassiveCapture' ] // cannot be passive (ex: iOS scroll)
392
392
  ])
393
393
  },
394
394
 
@@ -209,7 +209,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
209
209
 
210
210
  client.has.touch === true && addEvt(ctx, 'main', [
211
211
  [ el, 'touchstart', 'touchStart', `passive${ modifiers.capture === true ? 'Capture' : '' }` ],
212
- [ el, 'touchend', 'noop', 'notPassiveCapture' ]
212
+ [ el, 'touchend', 'noop', 'passiveCapture' ]
213
213
  ])
214
214
 
215
215
  keyboard.length > 0 && addEvt(ctx, 'main', [
@@ -234,7 +234,7 @@ export default createDirective(__QUASAR_SSR_SERVER__
234
234
 
235
235
  client.has.touch === true && addEvt(ctx, 'main', [
236
236
  [ el, 'touchstart', 'touchStart', `passive${ modifiers.capture === true ? 'Capture' : '' }` ],
237
- [ el, 'touchmove', 'noop', 'notPassiveCapture' ]
237
+ [ el, 'touchmove', 'noop', 'notPassiveCapture' ] // cannot be passive (ex: iOS scroll)
238
238
  ])
239
239
  },
240
240
 
@@ -1,24 +1,21 @@
1
1
  const
2
2
  toString = Object.prototype.toString,
3
3
  hasOwn = Object.prototype.hasOwnProperty,
4
- class2type = {}
5
-
6
- 'Boolean Number String Function Array Date RegExp Object'.split(' ').forEach(name => {
7
- class2type[ '[object ' + name + ']' ] = name.toLowerCase()
8
- })
9
-
10
- function type (obj) {
11
- return obj === null ? String(obj) : class2type[ toString.call(obj) ] || 'object'
12
- }
4
+ notPlainObject = new Set(
5
+ [ 'Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp' ]
6
+ .map(name => '[object ' + name + ']')
7
+ )
13
8
 
14
9
  function isPlainObject (obj) {
15
- if (!obj || type(obj) !== 'object') {
10
+ if (obj !== Object(obj) || notPlainObject.has(toString.call(obj)) === true) {
16
11
  return false
17
12
  }
18
13
 
19
- if (obj.constructor
20
- && !hasOwn.call(obj, 'constructor')
21
- && !hasOwn.call(obj.constructor.prototype, 'isPrototypeOf')) {
14
+ if (
15
+ obj.constructor
16
+ && hasOwn.call(obj, 'constructor') === false
17
+ && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf') === false
18
+ ) {
22
19
  return false
23
20
  }
24
21
 
@@ -42,7 +39,7 @@ export default function extend () {
42
39
  i = 2
43
40
  }
44
41
 
45
- if (Object(target) !== target && type(target) !== 'function') {
42
+ if (Object(target) !== target && typeof target !== 'function') {
46
43
  target = {}
47
44
  }
48
45
 
@@ -61,13 +58,16 @@ export default function extend () {
61
58
  continue
62
59
  }
63
60
 
64
- if (deep && copy && (isPlainObject(copy) || (copyIsArray = type(copy) === 'array'))) {
65
- if (copyIsArray) {
66
- copyIsArray = false
67
- clone = src && type(src) === 'array' ? src : []
61
+ if (
62
+ deep === true
63
+ && copy
64
+ && ((copyIsArray = Array.isArray(copy)) || isPlainObject(copy) === true)
65
+ ) {
66
+ if (copyIsArray === true) {
67
+ clone = Array.isArray(src) === true ? src : []
68
68
  }
69
69
  else {
70
- clone = src && isPlainObject(src) ? src : {}
70
+ clone = isPlainObject(src) === true ? src : {}
71
71
  }
72
72
 
73
73
  target[ name ] = extend(deep, clone, copy)
@@ -4,10 +4,12 @@ export function injectProp (target, propName, get, set) {
4
4
  set,
5
5
  enumerable: true
6
6
  })
7
+ return target
7
8
  }
8
9
 
9
10
  export function injectMultipleProps (target, props) {
10
11
  for (const key in props) {
11
12
  injectProp(target, key, props[ key ])
12
13
  }
14
+ return target
13
15
  }
@@ -3,15 +3,18 @@ let rtlHasScrollBug = false
3
3
  // mobile Chrome takes the crown for this
4
4
  if (!__QUASAR_SSR__) {
5
5
  const scroller = document.createElement('div')
6
- const spacer = document.createElement('div')
7
-
8
6
  scroller.setAttribute('dir', 'rtl')
9
- scroller.style.width = '1px'
10
- scroller.style.height = '1px'
11
- scroller.style.overflow = 'auto'
7
+ Object.assign(scroller.style, {
8
+ width: '1px',
9
+ height: '1px',
10
+ overflow: 'auto'
11
+ })
12
12
 
13
- spacer.style.width = '1000px'
14
- spacer.style.height = '1px'
13
+ const spacer = document.createElement('div')
14
+ Object.assign(spacer.style, {
15
+ width: '1000px',
16
+ height: '1px'
17
+ })
15
18
 
16
19
  document.body.appendChild(scroller)
17
20
  scroller.appendChild(spacer)
@@ -34,7 +34,7 @@ function parsePromises (sequentialPromises) {
34
34
  * Default: { threadsNumber: 1, abortOnFail: true }
35
35
  * When configuring threadsNumber AND using http requests, be
36
36
  * aware of the maximum threads that the hosting browser
37
- * supports (usually 3); any number of threads above that
37
+ * supports (usually 5); any number of threads above that
38
38
  * won't add any real benefits
39
39
  * @returns Promise<Array<Object> | Object>
40
40
  * With opts.abortOnFail set to true (which is default):