quasar 2.4.7 → 2.4.11

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 (142) hide show
  1. package/dist/api/LoadingBar.json +7 -0
  2. package/dist/api/Platform.json +171 -0
  3. package/dist/api/QAjaxBar.json +13 -1
  4. package/dist/api/QFile.json +1 -0
  5. package/dist/api/QTree.json +7 -0
  6. package/dist/api/QUploader.json +3 -1
  7. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  8. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  11. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  12. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  13. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  17. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  18. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  19. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  20. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  21. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  22. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  23. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  24. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  25. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-mdi-v4.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-mdi-v5.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  36. package/dist/icon-set/themify.umd.prod.js +1 -1
  37. package/dist/lang/ar.umd.prod.js +1 -1
  38. package/dist/lang/az-Latn.umd.prod.js +1 -1
  39. package/dist/lang/bg.umd.prod.js +1 -1
  40. package/dist/lang/bn.umd.prod.js +1 -1
  41. package/dist/lang/ca.umd.prod.js +1 -1
  42. package/dist/lang/cs.umd.prod.js +1 -1
  43. package/dist/lang/da.umd.prod.js +1 -1
  44. package/dist/lang/de.umd.prod.js +1 -1
  45. package/dist/lang/el.umd.prod.js +1 -1
  46. package/dist/lang/en-GB.umd.prod.js +1 -1
  47. package/dist/lang/en-US.umd.prod.js +1 -1
  48. package/dist/lang/eo.umd.prod.js +1 -1
  49. package/dist/lang/es.umd.prod.js +1 -1
  50. package/dist/lang/et.umd.prod.js +1 -1
  51. package/dist/lang/fa-IR.umd.prod.js +1 -1
  52. package/dist/lang/fa.umd.prod.js +1 -1
  53. package/dist/lang/fi.umd.prod.js +1 -1
  54. package/dist/lang/fr.umd.prod.js +1 -1
  55. package/dist/lang/gn.umd.prod.js +1 -1
  56. package/dist/lang/he.umd.prod.js +1 -1
  57. package/dist/lang/hr.umd.prod.js +1 -1
  58. package/dist/lang/hu.umd.prod.js +1 -1
  59. package/dist/lang/id.umd.prod.js +1 -1
  60. package/dist/lang/is.umd.prod.js +1 -1
  61. package/dist/lang/it.umd.prod.js +1 -1
  62. package/dist/lang/ja.umd.prod.js +1 -1
  63. package/dist/lang/km.umd.prod.js +1 -1
  64. package/dist/lang/ko-KR.umd.prod.js +1 -1
  65. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  66. package/dist/lang/lt.umd.prod.js +1 -1
  67. package/dist/lang/lu.umd.prod.js +1 -1
  68. package/dist/lang/lv.umd.prod.js +1 -1
  69. package/dist/lang/ml.umd.prod.js +1 -1
  70. package/dist/lang/ms.umd.prod.js +1 -1
  71. package/dist/lang/my.umd.prod.js +6 -0
  72. package/dist/lang/nb-NO.umd.prod.js +1 -1
  73. package/dist/lang/nl.umd.prod.js +1 -1
  74. package/dist/lang/pl.umd.prod.js +1 -1
  75. package/dist/lang/pt-BR.umd.prod.js +1 -1
  76. package/dist/lang/pt.umd.prod.js +1 -1
  77. package/dist/lang/ro.umd.prod.js +1 -1
  78. package/dist/lang/ru.umd.prod.js +1 -1
  79. package/dist/lang/sk.umd.prod.js +1 -1
  80. package/dist/lang/sl.umd.prod.js +1 -1
  81. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  82. package/dist/lang/sr.umd.prod.js +1 -1
  83. package/dist/lang/sv.umd.prod.js +1 -1
  84. package/dist/lang/ta.umd.prod.js +1 -1
  85. package/dist/lang/th.umd.prod.js +1 -1
  86. package/dist/lang/tr.umd.prod.js +1 -1
  87. package/dist/lang/ug.umd.prod.js +1 -1
  88. package/dist/lang/uk.umd.prod.js +1 -1
  89. package/dist/lang/vi.umd.prod.js +1 -1
  90. package/dist/lang/zh-CN.umd.prod.js +1 -1
  91. package/dist/lang/zh-TW.umd.prod.js +1 -1
  92. package/dist/quasar.cjs.prod.js +2 -2
  93. package/dist/quasar.css +7 -4
  94. package/dist/quasar.esm.prod.js +2 -2
  95. package/dist/quasar.prod.css +1 -1
  96. package/dist/quasar.rtl.css +7 -4
  97. package/dist/quasar.rtl.prod.css +1 -1
  98. package/dist/quasar.sass +8 -4
  99. package/dist/quasar.umd.js +176 -81
  100. package/dist/quasar.umd.prod.js +2 -2
  101. package/dist/ssr-directives/Morph.js +1 -1
  102. package/dist/types/api/qfile.d.ts +8 -0
  103. package/dist/types/api/qselect.d.ts +4 -0
  104. package/dist/types/api/qtable.d.ts +12 -0
  105. package/dist/types/api/qtree.d.ts +31 -0
  106. package/dist/types/api/quploader.d.ts +28 -0
  107. package/dist/types/api/touchswipe.d.ts +11 -0
  108. package/dist/types/api/validation.d.ts +1 -1
  109. package/dist/types/api.d.ts +6 -0
  110. package/dist/types/index.d.ts +422 -314
  111. package/dist/types/ts-helpers.d.ts +6 -2
  112. package/dist/types/utils.d.ts +4 -1
  113. package/dist/vetur/quasar-attributes.json +4 -0
  114. package/dist/vetur/quasar-tags.json +1 -0
  115. package/dist/web-types/web-types.json +11 -1
  116. package/lang/index.json +4 -0
  117. package/lang/my.js +90 -0
  118. package/package.json +1 -1
  119. package/src/components/ajax-bar/QAjaxBar.js +22 -12
  120. package/src/components/ajax-bar/QAjaxBar.json +16 -1
  121. package/src/components/date/QDate.js +6 -1
  122. package/src/components/dialog-plugin/DialogPlugin.js +1 -1
  123. package/src/components/form/QForm.js +11 -1
  124. package/src/components/icon/QIcon.js +4 -9
  125. package/src/components/icon/QIcon.sass +4 -3
  126. package/src/components/infinite-scroll/QInfiniteScroll.js +3 -2
  127. package/src/components/scroll-area/QScrollArea.js +36 -11
  128. package/src/components/scroll-observer/QScrollObserver.js +12 -10
  129. package/src/components/select/QSelect.js +20 -19
  130. package/src/components/select/QSelect.sass +3 -0
  131. package/src/components/tabs/QTabs.js +10 -2
  132. package/src/components/tree/QTree.js +8 -1
  133. package/src/components/tree/QTree.json +8 -0
  134. package/src/components/uploader/uploader-core.js +2 -0
  135. package/src/components/uploader/xhr-uploader-plugin.json +2 -1
  136. package/src/components/virtual-scroll/use-virtual-scroll.js +11 -3
  137. package/src/composables/private/use-field.js +13 -1
  138. package/src/composables/private/use-file.json +1 -0
  139. package/src/plugins/LoadingBar.js +3 -3
  140. package/src/plugins/LoadingBar.json +8 -0
  141. package/src/plugins/Platform.js +15 -8
  142. package/src/plugins/Platform.json +166 -0
@@ -1,4 +1,4 @@
1
- import { h, ref, computed, watch, nextTick, onBeforeUnmount, onActivated, getCurrentInstance, provide } from 'vue'
1
+ import { h, ref, computed, watch, nextTick, onBeforeUnmount, onActivated, onDeactivated, getCurrentInstance, provide } from 'vue'
2
2
 
3
3
  import QIcon from '../icon/QIcon.js'
4
4
  import QResizeObserver from '../resize-observer/QResizeObserver.js'
@@ -568,7 +568,15 @@ export default createComponent({
568
568
  unwatchRoute !== void 0 && unwatchRoute()
569
569
  })
570
570
 
571
- onActivated(recalculateScroll)
571
+ let shouldActivate = false
572
+
573
+ onDeactivated(() => {
574
+ shouldActivate = true
575
+ })
576
+
577
+ onActivated(() => {
578
+ shouldActivate === true && recalculateScroll()
579
+ })
572
580
 
573
581
  return () => {
574
582
  const child = [
@@ -58,6 +58,8 @@ export default createComponent({
58
58
  expanded: Array, // v-model:expanded
59
59
  selected: {}, // v-model:selected
60
60
 
61
+ noSelectionUnset: Boolean,
62
+
61
63
  defaultExpandAll: Boolean,
62
64
  accordion: Boolean,
63
65
 
@@ -615,7 +617,12 @@ export default createComponent({
615
617
 
616
618
  if (hasSelection.value) {
617
619
  if (meta.selectable) {
618
- emit('update:selected', meta.key !== props.selected ? meta.key : null)
620
+ if (props.noSelectionUnset === false) {
621
+ emit('update:selected', meta.key !== props.selected ? meta.key : null)
622
+ }
623
+ else if (meta.key !== props.selected) {
624
+ emit('update:selected', meta.key || null)
625
+ }
619
626
  }
620
627
  }
621
628
  else {
@@ -6,6 +6,7 @@
6
6
  "props": {
7
7
  "nodes": {
8
8
  "type": "Array",
9
+ "tsType": "QTreeNode",
9
10
  "desc": "The array of nodes that designates the tree structure",
10
11
  "required": true,
11
12
  "examples": [ "[ {...}, {...} ]" ],
@@ -106,6 +107,13 @@
106
107
  "category": "state"
107
108
  },
108
109
 
110
+ "no-selection-unset": {
111
+ "type": "Boolean",
112
+ "desc": "Do not allow un-selection when clicking currently selected node",
113
+ "category": "behavior",
114
+ "addedIn": "v2.4.10"
115
+ },
116
+
109
117
  "default-expand-all": {
110
118
  "type": "Boolean",
111
119
  "desc": "Allow the tree to have all its branches expanded, when first rendered",
@@ -436,6 +436,8 @@ export function getRenderer (getPlugin) {
436
436
  abort: state.abort
437
437
  }
438
438
 
439
+ // TODO: the result of this computed, especially the dynamic part, isn't currently typed
440
+ // This result in an error with Volar when accessing the state (eg. files array)
439
441
  const slotScope = computed(() => {
440
442
  const acc = {
441
443
  canAddFiles: canAddFiles.value,
@@ -2,6 +2,7 @@
2
2
  "props": {
3
3
  "factory": {
4
4
  "type": "Function",
5
+ "tsType": "QUploaderFactoryFn",
5
6
  "desc": "Function which should return an Object or a Promise resolving with an Object; For best performance, reference it from your scope and do not define it inline",
6
7
  "params": {
7
8
  "files": {
@@ -112,7 +113,7 @@
112
113
  },
113
114
  "returns": {
114
115
  "type": "String",
115
- "desc": "An array consists of objects with header definitions",
116
+ "desc": "An array consisting of objects with header definitions",
116
117
  "__exemption": [ "examples" ]
117
118
  },
118
119
  "category": "upload"
@@ -1,4 +1,4 @@
1
- import { h, ref, computed, watch, onActivated, onBeforeMount, onBeforeUnmount, nextTick, getCurrentInstance } from 'vue'
1
+ import { h, ref, computed, watch, onActivated, onDeactivated, onBeforeMount, onBeforeUnmount, nextTick, getCurrentInstance } from 'vue'
2
2
 
3
3
  import debounce from '../../utils/debounce.js'
4
4
  import { noop } from '../../utils/event.js'
@@ -596,9 +596,9 @@ export function useVirtualScroll ({
596
596
  : Math.ceil(scrollViewSize / virtualScrollItemSizeComputed.value)
597
597
 
598
598
  const baseSize = Math.max(
599
- 10,
599
+ 1,
600
600
  view,
601
- Math.ceil(props.virtualScrollSliceSize / multiplier)
601
+ Math.ceil((props.virtualScrollSliceSize > 0 ? props.virtualScrollSliceSize : 10) / multiplier)
602
602
  )
603
603
 
604
604
  virtualScrollSliceSizeComputed.value = {
@@ -691,7 +691,15 @@ export function useVirtualScroll ({
691
691
  setVirtualScrollSize()
692
692
  })
693
693
 
694
+ let shouldActivate = false
695
+
696
+ onDeactivated(() => {
697
+ shouldActivate = true
698
+ })
699
+
694
700
  onActivated(() => {
701
+ if (shouldActivate !== true) { return }
702
+
695
703
  const scrollEl = getVirtualScrollTarget()
696
704
 
697
705
  if (prevScrollStart !== void 0 && scrollEl !== void 0 && scrollEl !== null && scrollEl.nodeType !== 8) {
@@ -1,4 +1,4 @@
1
- import { h, ref, computed, watch, Transition, nextTick, onBeforeUnmount, onMounted, getCurrentInstance } from 'vue'
1
+ import { h, ref, computed, watch, Transition, nextTick, onActivated, onDeactivated, onBeforeUnmount, onMounted, getCurrentInstance } from 'vue'
2
2
 
3
3
  import { isRuntimeSsrPreHydration } from '../../plugins/Platform.js'
4
4
 
@@ -402,6 +402,8 @@ export default function (state) {
402
402
  name: props.clearIcon || $q.iconSet.field.clear,
403
403
  tabindex: 0,
404
404
  type: 'button',
405
+ 'aria-hidden': null,
406
+ role: null,
405
407
  onClick: clearValue
406
408
  })
407
409
  ])
@@ -530,6 +532,16 @@ export default function (state) {
530
532
  // expose public methods
531
533
  Object.assign(proxy, { focus, blur })
532
534
 
535
+ let shouldActivate = false
536
+
537
+ onDeactivated(() => {
538
+ shouldActivate = true
539
+ })
540
+
541
+ onActivated(() => {
542
+ shouldActivate === true && props.autofocus === true && proxy.focus()
543
+ })
544
+
533
545
  onMounted(() => {
534
546
  if (isRuntimeSsrPreHydration.value === true && props.for === void 0) {
535
547
  state.targetUid.value = getTargetUid()
@@ -72,6 +72,7 @@
72
72
  "params": {
73
73
  "rejectedEntries": {
74
74
  "type": "Array",
75
+ "tsType": "QRejectedEntry",
75
76
  "desc": "Array of { failedPropValidation: string, file: File } Objects for files that do not pass the validation",
76
77
  "__exemption": ["examples"]
77
78
  }
@@ -49,11 +49,11 @@ const Plugin = defineReactivePlugin({
49
49
  Object.assign(this, {
50
50
  start (speed) {
51
51
  barRef.value.start(speed)
52
- Plugin.isActive = barRef.value.calls > 0
52
+ Plugin.isActive = true
53
53
  },
54
54
  stop () {
55
- barRef.value.stop()
56
- Plugin.isActive = barRef.value.calls > 0
55
+ const sessions = barRef.value.stop()
56
+ Plugin.isActive = sessions > 0
57
57
  },
58
58
  increment () {
59
59
  barRef.value.increment.apply(null, arguments)
@@ -16,6 +16,14 @@
16
16
  }
17
17
  },
18
18
 
19
+ "props": {
20
+ "isActive": {
21
+ "type": "Boolean",
22
+ "desc": "Is LoadingBar active?",
23
+ "reactive": true
24
+ }
25
+ },
26
+
19
27
  "methods": {
20
28
  "start": {
21
29
  "desc": "Notify bar you've started a background activity",
@@ -1,6 +1,4 @@
1
1
  /* eslint-disable no-useless-escape */
2
- /* eslint-disable no-unused-expressions */
3
- /* eslint-disable no-mixed-operators */
4
2
 
5
3
  import { ref, reactive } from 'vue'
6
4
  import { injectProp } from '../utils/private/inject-obj-prop'
@@ -25,19 +23,15 @@ export let iosEmulated = false
25
23
  export let iosCorrection
26
24
 
27
25
  function getMatch (userAgent, platformMatch) {
28
- const match = /(edge|edga|edgios)\/([\w.]+)/.exec(userAgent)
26
+ const match = /(edg|edge|edga|edgios)\/([\w.]+)/.exec(userAgent)
29
27
  || /(opr)[\/]([\w.]+)/.exec(userAgent)
30
28
  || /(vivaldi)[\/]([\w.]+)/.exec(userAgent)
31
29
  || /(chrome|crios)[\/]([\w.]+)/.exec(userAgent)
32
- || /(iemobile)[\/]([\w.]+)/.exec(userAgent)
33
30
  || /(version)(applewebkit)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
34
31
  || /(webkit)[\/]([\w.]+).*(version)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent)
35
32
  || /(firefox|fxios)[\/]([\w.]+)/.exec(userAgent)
36
33
  || /(webkit)[\/]([\w.]+)/.exec(userAgent)
37
34
  || /(opera)(?:.*version|)[\/]([\w.]+)/.exec(userAgent)
38
- || /(msie) ([\w.]+)/.exec(userAgent)
39
- || (userAgent.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(userAgent))
40
- || (userAgent.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(userAgent))
41
35
  || []
42
36
 
43
37
  return {
@@ -60,6 +54,8 @@ function getPlatformMatch (userAgent) {
60
54
  || /(mac)/.exec(userAgent)
61
55
  || /(linux)/.exec(userAgent)
62
56
  || /(cros)/.exec(userAgent)
57
+ // TODO: Remove BlackBerry detection. BlackBerry OS, BlackBerry 10, and BlackBerry PlayBook OS
58
+ // is officially dead as of January 4, 2022 (https://www.blackberry.com/us/en/support/devices/end-of-life)
63
59
  || /(playbook)/.exec(userAgent)
64
60
  || /(bb)/.exec(userAgent)
65
61
  || /(blackberry)/.exec(userAgent)
@@ -151,6 +147,10 @@ function getPlatform (UA) {
151
147
  delete browser[ 'windows phone' ]
152
148
  }
153
149
 
150
+ // TODO: The assumption about WebKit based browsers below is not completely accurate.
151
+ // Google released Blink(a fork of WebKit) engine on April 3, 2013, which is really different than WebKit today.
152
+ // Today, one might want to check for WebKit to deal with its bugs, which is used on all browsers on iOS, and Safari browser on all platforms.
153
+
154
154
  // Chrome, Opera 15+, Vivaldi and Safari are webkit based browsers
155
155
  if (
156
156
  browser.chrome
@@ -167,8 +167,15 @@ function getPlatform (UA) {
167
167
  browser.webkit = true
168
168
  }
169
169
 
170
+ // TODO: (Qv3) rename the terms 'edge' to 'edge legacy'(or remove it) then 'edge chromium' to 'edge' to match with the known up-to-date terms
171
+ // Microsoft Edge is the new Chromium-based browser. Microsoft Edge Legacy is the old EdgeHTML-based browser (EOL: March 9, 2021).
172
+ if (browser.edg) {
173
+ matched.browser = 'edgechromium'
174
+ browser.edgeChromium = true
175
+ }
176
+
170
177
  // Blackberry browsers are marked as Safari on BlackBerry
171
- if (browser.safari && browser.blackberry || browser.bb) {
178
+ if ((browser.safari && browser.blackberry) || browser.bb) {
172
179
  matched.browser = 'blackberry'
173
180
  browser.blackberry = true
174
181
  }
@@ -17,6 +17,172 @@
17
17
  "is": {
18
18
  "type": "Object",
19
19
  "desc": "Client browser details (property names depend on browser)",
20
+ "definition": {
21
+ "name": {
22
+ "type": "String",
23
+ "desc": "Browser name",
24
+ "examples": [ "chrome" ]
25
+ },
26
+ "platform": {
27
+ "type": "String",
28
+ "desc": "Platform name",
29
+ "examples": [ "mac" ]
30
+ },
31
+ "version": {
32
+ "type": "String",
33
+ "required": false,
34
+ "desc": "Detailed browser version",
35
+ "examples": [ "71.0.3578.98" ]
36
+ },
37
+ "versionNumber": {
38
+ "type": "Number",
39
+ "required": false,
40
+ "desc": "Major browser version as a number",
41
+ "examples": [ 71 ]
42
+ },
43
+
44
+ "desktop": {
45
+ "type": "Boolean",
46
+ "required": false,
47
+ "desc": "Whether the platform is desktop"
48
+ },
49
+ "mobile": {
50
+ "type": "Boolean",
51
+ "required": false,
52
+ "desc": "Whether the platform is mobile"
53
+ },
54
+ "electron": {
55
+ "type": "Boolean",
56
+ "required": false,
57
+ "desc": "Whether the platform is Electron"
58
+ },
59
+ "bex": {
60
+ "type": "Boolean",
61
+ "required": false,
62
+ "desc": "Whether the platform is BEX(Browser Extension)"
63
+ },
64
+ "capacitor": {
65
+ "type": "Boolean",
66
+ "required": false,
67
+ "desc": "Whether the platform is Capacitor"
68
+ },
69
+ "cordova": {
70
+ "type": "Boolean",
71
+ "required": false,
72
+ "desc": "Whether the platform is Cordova"
73
+ },
74
+ "nativeMobile": {
75
+ "type": "Boolean",
76
+ "required": false,
77
+ "desc": "Whether the platform is a native mobile wrapper"
78
+ },
79
+ "nativeMobileWrapper": {
80
+ "type": "String",
81
+ "required": false,
82
+ "values": ["cordova", "capacitor"],
83
+ "desc": "Type of the native mobile wrapper"
84
+ },
85
+
86
+ "chrome": {
87
+ "type": "Boolean",
88
+ "required": false,
89
+ "desc": "Whether the browser is Google Chrome"
90
+ },
91
+ "firefox": {
92
+ "type": "Boolean",
93
+ "required": false,
94
+ "desc": "Whether the browser is Firefox"
95
+ },
96
+ "safari": {
97
+ "type": "Boolean",
98
+ "required": false,
99
+ "desc": "Whether the browser is Safari"
100
+ },
101
+ "edgeChromium": {
102
+ "type": "Boolean",
103
+ "required": false,
104
+ "desc": "Whether the browser is Microsoft Edge (Chromium)"
105
+ },
106
+ "edge": {
107
+ "type": "Boolean",
108
+ "required": false,
109
+ "desc": "Whether the browser is Microsoft Edge Legacy"
110
+ },
111
+ "opera": {
112
+ "type": "Boolean",
113
+ "required": false,
114
+ "desc": "Whether the browser is Opera"
115
+ },
116
+ "vivaldi": {
117
+ "type": "Boolean",
118
+ "required": false,
119
+ "desc": "Whether the browser is Vivaldi"
120
+ },
121
+
122
+ "win": {
123
+ "type": "Boolean",
124
+ "required": false,
125
+ "desc": "Whether the operating system is Windows"
126
+ },
127
+ "linux": {
128
+ "type": "Boolean",
129
+ "required": false,
130
+ "desc": "Whether the operating system is Linux"
131
+ },
132
+ "mac": {
133
+ "type": "Boolean",
134
+ "required": false,
135
+ "desc": "Whether the operating system is Mac OS"
136
+ },
137
+ "cros": {
138
+ "type": "Boolean",
139
+ "required": false,
140
+ "desc": "Whether the operating system is Chrome OS"
141
+ },
142
+
143
+ "android": {
144
+ "type": "Boolean",
145
+ "required": false,
146
+ "desc": "Whether the operating system is Android"
147
+ },
148
+ "ios": {
149
+ "type": "Boolean",
150
+ "required": false,
151
+ "desc": "Whether the operating system is iOS"
152
+ },
153
+ "winphone": {
154
+ "type": "Boolean",
155
+ "required": false,
156
+ "desc": "Whether the operating system is Windows Phone"
157
+ },
158
+
159
+ "iphone": {
160
+ "type": "Boolean",
161
+ "required": false,
162
+ "desc": "Whether the device is an iPhone"
163
+ },
164
+ "ipad": {
165
+ "type": "Boolean",
166
+ "required": false,
167
+ "desc": "Whether the device is an iPad"
168
+ },
169
+ "ipod": {
170
+ "type": "Boolean",
171
+ "required": false,
172
+ "desc": "Whether the device is an iPod"
173
+ },
174
+
175
+ "kindle": {
176
+ "type": "Boolean",
177
+ "required": false,
178
+ "desc": "Whether the device is a Kindle"
179
+ },
180
+ "silk": {
181
+ "type": "Boolean",
182
+ "required": false,
183
+ "desc": "Whether the browser is Amazon Silk"
184
+ }
185
+ },
20
186
  "examples": [
21
187
  "{ chrome: true, version: '71.0.3578.98', versionNumber: 71, mac: true, desktop: true, webkit: true, name: 'chrome', platform: 'mac' }"
22
188
  ]