@qooxdoo/framework 7.0.0-beta → 7.0.0-beta.4

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 (224) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/Manifest.json +11 -8
  3. package/bin/deploy/qx +0 -0
  4. package/lib/compiler/compile-info.json +86 -96
  5. package/lib/compiler/index.js +35547 -47284
  6. package/{source/class/qx/tool/compiler/targets → lib/resource/qx/tool/cli/templates}/TypeScriptWriter-base_declaration.txt +0 -0
  7. package/lib/resource/qx/tool/cli/templates/loader/loader-browser.tmpl.js +8 -2
  8. package/lib/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +24 -11
  9. package/lib/resource/qx/tool/cli/templates/loader/loader-rhino.tmpl.js +9 -2
  10. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css +1 -1
  11. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -44
  12. package/lib/resource/qx/tool/cli/templates/template_vars.js +1 -1
  13. package/lib/resource/qx/tool/loadsass.js +13 -0
  14. package/lib/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
  15. package/lib/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
  16. package/lib/resource/qx/tool/schema/compile-1-0-0.json +19 -9
  17. package/lib/resource/qx/tool/website/sass/qooxdoo.css +1 -1
  18. package/lib/resource/qx/tool/website/sass/qooxdoo.css.map +1 -9
  19. package/package.json +14 -14
  20. package/source/class/qx/Annotation.js +2 -2
  21. package/source/class/qx/Class.js +20 -4
  22. package/source/class/qx/Interface.js +6 -0
  23. package/source/class/qx/Promise.js +32 -2
  24. package/source/class/qx/bom/Element.js +1 -0
  25. package/source/class/qx/bom/Font.js +17 -2
  26. package/source/class/qx/bom/Iframe.js +10 -5
  27. package/source/class/qx/bom/Label.js +2 -1
  28. package/source/class/qx/bom/Template.js +2 -0
  29. package/source/class/qx/bom/client/Browser.js +11 -2
  30. package/source/class/qx/bom/client/OperatingSystem.js +16 -0
  31. package/source/class/qx/bom/element/Decoration.js +8 -5
  32. package/source/class/qx/bom/element/Dimension.js +46 -0
  33. package/source/class/qx/bom/webfonts/WebFont.js +10 -0
  34. package/source/class/qx/core/BaseInit.js +9 -3
  35. package/source/class/qx/core/Environment.js +1 -0
  36. package/source/class/qx/core/Property.js +2 -2
  37. package/source/class/qx/data/SingleValueBinding.js +6 -3
  38. package/source/class/qx/data/controller/CheckedList.js +18 -9
  39. package/source/class/qx/data/controller/List.js +8 -0
  40. package/source/class/qx/dev/unit/Sinon.js +1 -1
  41. package/source/class/qx/event/Utils.js +1 -1
  42. package/source/class/qx/event/handler/DragDrop.js +1 -1
  43. package/source/class/qx/event/handler/Gesture.js +3 -1
  44. package/source/class/qx/event/handler/Mouse.js +61 -22
  45. package/source/class/qx/event/handler/Video.js +111 -0
  46. package/source/class/qx/html/Element.js +47 -32
  47. package/source/class/qx/html/Image.js +2 -2
  48. package/source/class/qx/html/Node.js +34 -4
  49. package/source/class/qx/lang/Json.js +1 -0
  50. package/source/class/qx/lang/String.js +53 -1
  51. package/source/class/qx/test/Annotation.js +2 -1
  52. package/source/class/qx/test/Promise.js +5 -3
  53. package/source/class/qx/test/bom/Font.js +10 -1
  54. package/source/class/qx/test/core/Property.js +5 -3
  55. package/source/class/qx/test/html/Element.js +3 -3
  56. package/source/class/qx/test/lang/String.js +28 -0
  57. package/source/class/qx/test/type/BaseString.js +7 -0
  58. package/source/class/qx/test/ui/embed/Iframe.js +1 -0
  59. package/source/class/qx/test/ui/form/ComboBox.js +0 -42
  60. package/source/class/qx/test/ui/virtual/performance/AbstractLayerTest.js +6 -2
  61. package/source/class/qx/theme/manager/Decoration.js +0 -0
  62. package/source/class/qx/theme/manager/Font.js +11 -0
  63. package/source/class/qx/theme/tangible/Appearance.js +10 -0
  64. package/source/class/qx/theme/tangible/ColorDark.js +0 -0
  65. package/source/class/qx/theme/tangible/Decoration.js +6 -0
  66. package/source/class/qx/tool/cli/Cli.js +5 -3
  67. package/source/class/qx/tool/cli/Watch.js +52 -0
  68. package/source/class/qx/tool/cli/api/AbstractApi.js +1 -1
  69. package/source/class/qx/tool/cli/api/CompilerApi.js +16 -6
  70. package/source/class/qx/tool/cli/api/LibraryApi.js +1 -1
  71. package/source/class/qx/tool/cli/commands/Command.js +7 -0
  72. package/source/class/qx/tool/cli/commands/Compile.js +28 -9
  73. package/source/class/qx/tool/cli/commands/Lint.js +30 -11
  74. package/source/class/qx/tool/cli/commands/Package.js +1 -2
  75. package/source/class/qx/tool/cli/commands/Run.js +2 -25
  76. package/source/class/qx/tool/cli/commands/Serve.js +9 -0
  77. package/source/class/qx/tool/cli/commands/package/Publish.js +19 -10
  78. package/source/class/qx/tool/compiler/Analyser.js +22 -23
  79. package/source/class/qx/tool/compiler/ClassFile.js +3 -2
  80. package/source/class/qx/tool/compiler/Console.js +17 -1
  81. package/source/class/qx/tool/compiler/Preprocess.js +1 -1
  82. package/source/class/qx/tool/compiler/app/Application.js +4 -2
  83. package/source/class/qx/tool/compiler/app/Cldr.js +1 -1
  84. package/source/class/qx/tool/compiler/app/Library.js +82 -88
  85. package/source/class/qx/tool/compiler/app/Part.js +1 -1
  86. package/source/class/qx/tool/compiler/app/Translation.js +1 -1
  87. package/source/class/qx/tool/compiler/app/WebFont.js +5 -4
  88. package/source/class/qx/tool/compiler/jsdoc/ChildControlParser.js +1 -1
  89. package/source/class/qx/tool/compiler/jsdoc/CommandParser.js +1 -1
  90. package/source/class/qx/tool/compiler/jsdoc/ParamParser.js +1 -1
  91. package/source/class/qx/tool/compiler/jsdoc/Parser.js +1 -1
  92. package/source/class/qx/tool/compiler/jsdoc/ReturnParser.js +1 -1
  93. package/source/class/qx/tool/compiler/jsdoc/ThrowsParser.js +1 -1
  94. package/source/class/qx/tool/compiler/makers/AbstractAppMaker.js +1 -1
  95. package/source/class/qx/tool/compiler/makers/AppMaker.js +14 -14
  96. package/source/class/qx/tool/compiler/makers/Maker.js +1 -1
  97. package/source/class/qx/tool/compiler/resources/AbstractMatcher.js +1 -1
  98. package/source/class/qx/tool/compiler/resources/Asset.js +2 -2
  99. package/source/class/qx/tool/compiler/resources/ImageLoader.js +3 -2
  100. package/source/class/qx/tool/compiler/resources/Manager.js +5 -5
  101. package/source/class/qx/tool/compiler/resources/MetaLoader.js +1 -1
  102. package/source/class/qx/tool/compiler/resources/ResourceConverter.js +1 -1
  103. package/source/class/qx/tool/compiler/resources/ResourceLoader.js +1 -1
  104. package/source/class/qx/tool/compiler/resources/ScssConverter.js +9 -3
  105. package/source/class/qx/tool/compiler/resources/ScssFile.js +13 -12
  106. package/source/class/qx/tool/compiler/resources/ScssIncludeConverter.js +1 -1
  107. package/source/class/qx/tool/compiler/targets/BuildTarget.js +1 -1
  108. package/source/class/qx/tool/compiler/targets/SourceCodeCopier.js +1 -1
  109. package/source/class/qx/tool/compiler/targets/SourceTarget.js +1 -1
  110. package/source/class/qx/tool/compiler/targets/Target.js +70 -32
  111. package/source/class/qx/tool/compiler/targets/TypeScriptWriter.js +3 -4
  112. package/source/class/qx/tool/compiler/targets/meta/AbstractJavascriptMeta.js +22 -0
  113. package/source/class/qx/tool/compiler/targets/meta/ApplicationMeta.js +30 -0
  114. package/source/class/qx/tool/compiler/targets/meta/BootJs.js +22 -0
  115. package/source/class/qx/tool/compiler/targets/meta/Javascript.js +22 -0
  116. package/source/class/qx/tool/compiler/targets/meta/Package.js +37 -2
  117. package/source/class/qx/tool/compiler/targets/meta/PackageJavascript.js +22 -0
  118. package/source/class/qx/tool/compiler/targets/meta/Part.js +22 -0
  119. package/source/class/qx/tool/compiler/targets/meta/PolyfillJs.js +29 -7
  120. package/source/class/qx/tool/compiler/targets/meta/Uglify.js +23 -1
  121. package/source/class/qx/tool/config/Abstract.js +3 -3
  122. package/source/class/qx/tool/config/Utils.js +10 -1
  123. package/source/class/qx/tool/utils/IndexedArray.js +1 -1
  124. package/source/class/qx/tool/utils/Json.js +2 -2
  125. package/source/class/qx/tool/utils/LogManager.js +1 -1
  126. package/source/class/qx/tool/utils/Logger.js +1 -1
  127. package/source/class/qx/tool/utils/Promisify.js +1 -1
  128. package/source/class/qx/tool/utils/Utils.js +118 -1
  129. package/source/class/qx/tool/utils/Values.js +1 -1
  130. package/source/class/qx/tool/utils/Website.js +23 -18
  131. package/source/class/qx/tool/utils/files/FindFiles.js +1 -1
  132. package/source/class/qx/tool/utils/files/Utils.js +1 -1
  133. package/source/class/qx/tool/utils/json/Parser.js +1 -1
  134. package/source/class/qx/tool/utils/json/Stringify.js +1 -1
  135. package/source/class/qx/tool/utils/json/Tokenizer.js +1 -1
  136. package/source/class/qx/tool/utils/json/Writer.js +1 -1
  137. package/source/class/qx/type/BaseString.js +2 -1
  138. package/source/class/qx/ui/basic/Image.js +15 -7
  139. package/source/class/qx/ui/basic/Label.js +3 -1
  140. package/source/class/qx/ui/container/SlideBar.js +3 -0
  141. package/source/class/qx/ui/control/DateChooser.js +20 -1
  142. package/source/class/qx/ui/core/scroll/NativeScrollBar.js +3 -0
  143. package/source/class/qx/ui/core/scroll/ScrollBar.js +3 -0
  144. package/source/class/qx/ui/form/AbstractSelectBox.js +38 -6
  145. package/source/class/qx/ui/form/Button.js +3 -0
  146. package/source/class/qx/ui/form/CheckBox.js +25 -1
  147. package/source/class/qx/ui/form/CheckedList.js +2 -1
  148. package/source/class/qx/ui/form/ComboBox.js +36 -27
  149. package/source/class/qx/ui/form/List.js +3 -0
  150. package/source/class/qx/ui/form/MenuButton.js +24 -2
  151. package/source/class/qx/ui/form/RadioButton.js +7 -0
  152. package/source/class/qx/ui/form/RadioButtonGroup.js +3 -0
  153. package/source/class/qx/ui/form/RadioGroup.js +19 -0
  154. package/source/class/qx/ui/form/SelectBox.js +23 -1
  155. package/source/class/qx/ui/form/Slider.js +15 -0
  156. package/source/class/qx/ui/form/SplitButton.js +3 -0
  157. package/source/class/qx/ui/form/ToggleButton.js +8 -0
  158. package/source/class/qx/ui/menu/AbstractButton.js +24 -0
  159. package/source/class/qx/ui/menu/Button.js +3 -0
  160. package/source/class/qx/ui/menu/CheckBox.js +8 -0
  161. package/source/class/qx/ui/menu/Manager.js +2 -0
  162. package/source/class/qx/ui/menu/Menu.js +63 -1
  163. package/source/class/qx/ui/menu/RadioButton.js +10 -1
  164. package/source/class/qx/ui/menubar/Button.js +0 -27
  165. package/source/class/qx/ui/menubar/MenuBar.js +12 -0
  166. package/source/class/qx/ui/splitpane/Blocker.js +3 -0
  167. package/source/class/qx/ui/splitpane/HLayout.js +2 -2
  168. package/source/class/qx/ui/splitpane/Pane.js +4 -1
  169. package/source/class/qx/ui/splitpane/VLayout.js +2 -2
  170. package/source/class/qx/ui/table/Table.js +24 -2
  171. package/source/class/qx/ui/table/cellrenderer/Abstract.js +3 -1
  172. package/source/class/qx/ui/table/cellrenderer/AbstractImage.js +7 -3
  173. package/source/class/qx/ui/table/headerrenderer/HeaderCell.js +3 -0
  174. package/source/class/qx/ui/table/pane/Header.js +3 -0
  175. package/source/class/qx/ui/table/pane/Scroller.js +3 -7
  176. package/source/class/qx/ui/table/rowrenderer/Default.js +1 -1
  177. package/source/class/qx/ui/tabview/Page.js +26 -0
  178. package/source/class/qx/ui/tabview/TabView.js +3 -0
  179. package/source/class/qx/ui/toolbar/Button.js +2 -27
  180. package/source/class/qx/ui/toolbar/CheckBox.js +0 -27
  181. package/source/class/qx/ui/toolbar/RadioButton.js +21 -0
  182. package/source/class/qx/ui/toolbar/SplitButton.js +0 -28
  183. package/source/class/qx/ui/toolbar/ToolBar.js +3 -0
  184. package/source/class/qx/util/ColorUtil.js +2 -1
  185. package/source/class/qx/util/ResourceManager.js +16 -7
  186. package/source/class/qx/util/format/DateFormat.js +9 -0
  187. package/source/class/qxWeb.js +8 -4
  188. package/source/resource/qx/decoration/Indigo/font/JosefinSlab-SemiBold.ttf +0 -0
  189. package/source/resource/qx/decoration/Indigo/font/SIL Open Font License 1.1.txt +0 -0
  190. package/source/resource/qx/iconfont/MaterialIcons/fetch-fonts.sh +0 -0
  191. package/source/resource/qx/mobile/scss/common/_gradients.scss +3 -1
  192. package/source/resource/qx/mobile/scss/theme/indigo/_styles.scss +1 -1
  193. package/source/resource/qx/mobile/scss/ui/_carousel.scss +2 -2
  194. package/source/resource/qx/mobile/scss/ui/_checkbox.scss +3 -3
  195. package/source/resource/qx/mobile/scss/ui/_collapsible.scss +2 -2
  196. package/source/resource/qx/mobile/scss/ui/_picker.scss +4 -4
  197. package/source/resource/qx/mobile/scss/ui/_radiobutton.scss +4 -4
  198. package/source/resource/qx/mobile/scss/ui/_slider.scss +7 -7
  199. package/source/resource/qx/scss/_gradients.scss +3 -1
  200. package/source/resource/qx/scss/_mixins.scss +4 -2
  201. package/source/resource/qx/tool/bin/build-devtools +0 -0
  202. package/source/resource/qx/tool/bin/build-website +0 -0
  203. package/source/resource/qx/tool/bin/download-assets +0 -0
  204. package/source/resource/qx/tool/cli/templates/TypeScriptWriter-base_declaration.txt +13 -0
  205. package/source/resource/qx/tool/cli/templates/loader/loader-browser.tmpl.js +8 -2
  206. package/source/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +24 -11
  207. package/source/resource/qx/tool/cli/templates/loader/loader-rhino.tmpl.js +9 -2
  208. package/source/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/scss/_styles.scss +1 -1
  209. package/source/resource/qx/tool/cli/templates/template_vars.js +1 -1
  210. package/source/resource/qx/tool/loadsass.js +13 -0
  211. package/source/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
  212. package/source/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
  213. package/source/resource/qx/tool/schema/compile-1-0-0.json +19 -9
  214. package/source/resource/qx/website/scss/ui/_carousel.scss +2 -2
  215. package/lib/resource/qx/tool/website/.gitignore +0 -2
  216. package/source/class/qx/io/request/auth/.gitignore +0 -0
  217. package/source/class/qx/test/bom/client/.gitignore +0 -0
  218. package/source/class/qx/test/ui/control/.gitignore +0 -0
  219. package/source/class/qx/tool/compiler/Version.js +0 -20
  220. package/source/resource/qx/decoration/Modern/treevirtual/.gitignore +0 -0
  221. package/source/resource/qx/mobile/css/.gitignore +0 -3
  222. package/source/resource/qx/tool/website/.gitignore +0 -2
  223. package/source/resource/qx/website/.gitignore +0 -1
  224. package/source/resource/qx/website/scss/.gitignore +0 -1
@@ -82,6 +82,9 @@ qx.Class.define("qx.ui.form.Slider",
82
82
  // Force canvas layout
83
83
  this._setLayout(new qx.ui.layout.Canvas());
84
84
 
85
+ // ARIA attrs
86
+ this.getContentElement().setAttribute("role", "slider");
87
+
85
88
  // Add listeners
86
89
  this.addListener("keypress", this._onKeyPress);
87
90
  this.addListener("roll", this._onRoll);
@@ -1024,6 +1027,9 @@ qx.Class.define("qx.ui.form.Slider",
1024
1027
  // property apply
1025
1028
  _applyOrientation : function(value, old)
1026
1029
  {
1030
+ // ARIA attrs
1031
+ this.getContentElement().setAttribute("aria-orientation", value);
1032
+
1027
1033
  var knob = this.getChildControl("knob");
1028
1034
 
1029
1035
  // Update private flag for faster access
@@ -1077,6 +1083,9 @@ qx.Class.define("qx.ui.form.Slider",
1077
1083
  // property apply
1078
1084
  _applyValue : function(value, old) {
1079
1085
  if (value != null) {
1086
+ // ARIA attrs
1087
+ this.getContentElement().setAttribute("aria-valuenow", value);
1088
+
1080
1089
  this._updateKnobPosition();
1081
1090
  if (this.__dragMode) {
1082
1091
  this.__dragValue = [value,old];
@@ -1105,6 +1114,9 @@ qx.Class.define("qx.ui.form.Slider",
1105
1114
  // property apply
1106
1115
  _applyMinimum : function(value, old)
1107
1116
  {
1117
+ // ARIA attrs
1118
+ this.getContentElement().setAttribute("aria-valuemin", value);
1119
+
1108
1120
  if (this.getValue() < value) {
1109
1121
  this.setValue(value);
1110
1122
  }
@@ -1116,6 +1128,9 @@ qx.Class.define("qx.ui.form.Slider",
1116
1128
  // property apply
1117
1129
  _applyMaximum : function(value, old)
1118
1130
  {
1131
+ // ARIA attrs
1132
+ this.getContentElement().setAttribute("aria-valuemax", value);
1133
+
1119
1134
  if (this.getValue() > value) {
1120
1135
  this.setValue(value);
1121
1136
  }
@@ -48,6 +48,9 @@ qx.Class.define("qx.ui.form.SplitButton",
48
48
  {
49
49
  this.base(arguments);
50
50
 
51
+ // ARIA attrs
52
+ this.getContentElement().setAttribute("role", "button");
53
+
51
54
  this._setLayout(new qx.ui.layout.HBox);
52
55
 
53
56
  // Force arrow creation
@@ -65,6 +65,10 @@ qx.Class.define("qx.ui.form.ToggleButton",
65
65
  // register execute event
66
66
  this.addListener("execute", this._onExecute, this);
67
67
 
68
+ // ARIA attrs
69
+ const contentEl = this.getContentElement();
70
+ contentEl.setAttribute("role", "button");
71
+ contentEl.setAttribute("aria-pressed", false);
68
72
  },
69
73
 
70
74
 
@@ -159,13 +163,17 @@ qx.Class.define("qx.ui.form.ToggleButton",
159
163
  _applyValue : function(value, old) {
160
164
  value ? this.addState("checked") : this.removeState("checked");
161
165
 
166
+ let ariaPressed = Boolean(value);
162
167
  if (this.isTriState()) {
163
168
  if (value === null) {
169
+ ariaPressed = "mixed";
164
170
  this.addState("undetermined");
165
171
  } else if (old === null) {
166
172
  this.removeState("undetermined");
167
173
  }
168
174
  }
175
+
176
+ this.getContentElement().setAttribute("aria-pressed", ariaPressed);
169
177
  },
170
178
 
171
179
  /**
@@ -335,23 +335,47 @@ qx.Class.define("qx.ui.menu.AbstractButton",
335
335
  {
336
336
  if (old)
337
337
  {
338
+ old.removeListener("changeVisibility", this._onMenuChange, this);
338
339
  old.resetOpener();
339
340
  old.removeState("submenu");
340
341
  }
341
342
 
343
+ const contentEl = this.getContentElement();
342
344
  if (value)
343
345
  {
344
346
  this._showChildControl("arrow");
345
347
 
348
+ value.addListener("changeVisibility", this._onMenuChange, this);
346
349
  value.setOpener(this);
347
350
  value.addState("submenu");
351
+
352
+ // ARIA attrs
353
+ contentEl.setAttribute("aria-haspopup", "menu");
354
+ contentEl.setAttribute("aria-expanded", value.isVisible());
355
+ contentEl.setAttribute("aria-controls", value.getContentElement().getAttribute("id"));
348
356
  }
349
357
  else
350
358
  {
351
359
  this._excludeChildControl("arrow");
360
+
361
+ // ARIA attrs
362
+ contentEl.removeAttribute("aria-haspopup");
363
+ contentEl.removeAttribute("aria-expanded");
364
+ contentEl.removeAttribute("aria-controls");
352
365
  }
353
366
  },
354
367
 
368
+ /**
369
+ * Listener for visibility property changes of the attached menu
370
+ *
371
+ * @param e {qx.event.type.Data} Property change event
372
+ */
373
+ _onMenuChange : function(e)
374
+ {
375
+ // ARIA attrs
376
+ this.getContentElement().setAttribute("aria-expanded", this.getMenu().isVisible());
377
+ },
378
+
355
379
  // property apply
356
380
  _applyShowCommandLabel : function(value, old)
357
381
  {
@@ -43,6 +43,9 @@ qx.Class.define("qx.ui.menu.Button",
43
43
  {
44
44
  this.base(arguments);
45
45
 
46
+ // ARIA attrs
47
+ this.getContentElement().setAttribute("role", "button");
48
+
46
49
  // Initialize with incoming arguments
47
50
  if (label != null) {
48
51
  this.setLabel(label);
@@ -44,6 +44,11 @@ qx.Class.define("qx.ui.menu.CheckBox",
44
44
  {
45
45
  this.base(arguments);
46
46
 
47
+ // ARIA attrs
48
+ const contenEl = this.getContentElement();
49
+ contenEl.setAttribute("role", "checkbox");
50
+ contenEl.setAttribute("aria-checked", false);
51
+
47
52
  // Initialize with incoming arguments
48
53
  if (label != null) {
49
54
  // try to translate every time you create a checkbox [BUG #2699]
@@ -120,6 +125,9 @@ qx.Class.define("qx.ui.menu.CheckBox",
120
125
  value ?
121
126
  this.addState("checked") :
122
127
  this.removeState("checked");
128
+
129
+ // ARIA attrs
130
+ this.getContentElement().setAttribute("aria-checked", Boolean(value));
123
131
  },
124
132
 
125
133
 
@@ -528,6 +528,7 @@ qx.Class.define("qx.ui.menu.Manager",
528
528
  */
529
529
  __navigationKeys :
530
530
  {
531
+ "Tab" : 1,
531
532
  "Escape" : 1,
532
533
  "Up" : 1,
533
534
  "Down" : 1,
@@ -597,6 +598,7 @@ qx.Class.define("qx.ui.menu.Manager",
597
598
  this._onKeyPressRight(menu);
598
599
  break;
599
600
 
601
+ case "Tab":
600
602
  case "Escape":
601
603
  this.hideAll();
602
604
  break;
@@ -48,6 +48,11 @@ qx.Class.define("qx.ui.menu.Menu",
48
48
  var root = this.getApplicationRoot();
49
49
  root.add(this);
50
50
 
51
+ // ARIA attrs
52
+ const contentEl = this.getContentElement();
53
+ contentEl.setAttribute("role", "menu");
54
+ contentEl.setAttribute("id", "menu-" + this.toHashCode());
55
+
51
56
  // Register pointer listeners
52
57
  this.addListener("pointerover", this._onPointerOver);
53
58
  this.addListener("pointerout", this._onPointerOut);
@@ -212,7 +217,8 @@ qx.Class.define("qx.ui.menu.Menu",
212
217
  opener :
213
218
  {
214
219
  check : "qx.ui.core.Widget",
215
- nullable : true
220
+ nullable: true,
221
+ apply : "_applyOpener"
216
222
  },
217
223
 
218
224
 
@@ -488,8 +494,15 @@ qx.Class.define("qx.ui.menu.Menu",
488
494
  old.removeState("selected");
489
495
  }
490
496
 
497
+ const opener = this.__getRootOpener();
498
+ const contentEl = opener ? opener.getContentElement() : this.getContentElement();
491
499
  if (value) {
492
500
  value.addState("selected");
501
+
502
+ // ARIA attrs
503
+ contentEl.setAttribute("aria-activedescendant", value.getContentElement().getAttribute("id"));
504
+ } else {
505
+ contentEl.removeAttribute("aria-activedescendant");
493
506
  }
494
507
  },
495
508
 
@@ -506,6 +519,17 @@ qx.Class.define("qx.ui.menu.Menu",
506
519
  }
507
520
  },
508
521
 
522
+ // property apply
523
+ _applyOpener : function(value, old)
524
+ {
525
+ // ARIA attrs
526
+ if (value) {
527
+ this.getContentElement().setAttribute("aria-labelledby", value);
528
+ } else {
529
+ this.getContentElement().removeAttribute("aria-labelledby");
530
+ }
531
+ },
532
+
509
533
 
510
534
  // property apply
511
535
  _applyBlockerColor : function(value, old) {
@@ -681,6 +705,19 @@ qx.Class.define("qx.ui.menu.Menu",
681
705
  EVENT HANDLING
682
706
  ---------------------------------------------------------------------------
683
707
  */
708
+
709
+ /**
710
+ * Gets called when a child is added. Sets ARIA attrs
711
+ * @param {*} child
712
+ */
713
+ _afterAddChild: function (child) {
714
+ // Some childs, e.g. Seperators, are no meaningful menu items
715
+ if (child instanceof qx.ui.menu.AbstractButton) {
716
+ const contentEl = child.getContentElement();
717
+ contentEl.setAttribute("id", "menu-item-" + child.toHashCode());
718
+ contentEl.setAttribute("role", "menuitem");
719
+ }
720
+ },
684
721
 
685
722
  /**
686
723
  * Update position if the menu or the root is resized
@@ -790,6 +827,31 @@ qx.Class.define("qx.ui.menu.Menu",
790
827
  mgr.cancelOpen(this.__scheduledOpen);
791
828
  }
792
829
  }
830
+ },
831
+
832
+ /*
833
+ ---------------------------------------------------------------------------
834
+ HELPER FUNCTIONS
835
+ ---------------------------------------------------------------------------
836
+ */
837
+
838
+ /**
839
+ * Get the opener of the root/the first parent menu.
840
+ * parent menu.
841
+ *
842
+ * @return {qx.ui.core.Widget|null} The opener.
843
+ */
844
+ __getRootOpener: function () {
845
+ let parentMenu = this.getParentMenu();
846
+ if (!parentMenu) {
847
+ return this.getOpener();
848
+ }
849
+ let opener;
850
+ while (parentMenu) {
851
+ opener = parentMenu.getOpener();
852
+ parentMenu = parentMenu.getParentMenu();
853
+ }
854
+ return opener;
793
855
  }
794
856
  },
795
857
 
@@ -44,6 +44,12 @@ qx.Class.define("qx.ui.menu.RadioButton",
44
44
  {
45
45
  this.base(arguments);
46
46
 
47
+ // ARIA attrs
48
+ // Important: (Grouped) radio btns should be children of a div with role 'radiogroup'
49
+ const contentEl = this.getContentElement();
50
+ contentEl.setAttribute("role", "radio");
51
+ contentEl.setAttribute("aria-checked", false);
52
+
47
53
  // Initialize with incoming arguments
48
54
  if (label != null) {
49
55
  this.setLabel(label);
@@ -120,8 +126,11 @@ qx.Class.define("qx.ui.menu.RadioButton",
120
126
 
121
127
 
122
128
  // property apply
123
- _applyValue : function(value, old) {
129
+ _applyValue: function (value, old) {
124
130
  value ? this.addState("checked") : this.removeState("checked");
131
+
132
+ // ARIA attrs
133
+ this.getContentElement().setAttribute("aria-checked", Boolean(value));
125
134
  },
126
135
 
127
136
 
@@ -24,25 +24,6 @@ qx.Class.define("qx.ui.menubar.Button",
24
24
  {
25
25
  extend : qx.ui.form.MenuButton,
26
26
 
27
-
28
-
29
- /*
30
- *****************************************************************************
31
- CONSTRUCTOR
32
- *****************************************************************************
33
- */
34
-
35
- construct : function(label, icon, menu)
36
- {
37
- this.base(arguments, label, icon, menu);
38
-
39
- this.removeListener("keydown", this._onKeyDown);
40
- this.removeListener("keyup", this._onKeyUp);
41
- },
42
-
43
-
44
-
45
-
46
27
  /*
47
28
  *****************************************************************************
48
29
  PROPERTIES
@@ -62,17 +43,9 @@ qx.Class.define("qx.ui.menubar.Button",
62
43
  refine : true,
63
44
  init : "inherit"
64
45
  },
65
-
66
- focusable :
67
- {
68
- refine : true,
69
- init : false
70
- }
71
46
  },
72
47
 
73
48
 
74
-
75
-
76
49
  /*
77
50
  *****************************************************************************
78
51
  MEMBERS
@@ -22,8 +22,20 @@
22
22
  qx.Class.define("qx.ui.menubar.MenuBar",
23
23
  {
24
24
  extend : qx.ui.toolbar.ToolBar,
25
+
26
+ /*
27
+ *****************************************************************************
28
+ CONSTRUCTOR
29
+ *****************************************************************************
30
+ */
25
31
 
32
+ construct : function()
33
+ {
34
+ this.base(arguments);
26
35
 
36
+ // ARIA attrs
37
+ this.getContentElement().setAttribute("role", "menubar");
38
+ },
27
39
 
28
40
  /*
29
41
  *****************************************************************************
@@ -78,6 +78,9 @@ qx.Class.define("qx.ui.splitpane.Blocker",
78
78
 
79
79
  // property apply
80
80
  _applyOrientation : function(value, old) {
81
+ // ARIA attrs
82
+ this.setAttribute("aria-orientation", value);
83
+
81
84
  if (value == "horizontal") {
82
85
  this.setStyle("height", "100%");
83
86
  this.setStyle("cursor", "col-resize");
@@ -94,11 +94,11 @@ qx.Class.define("qx.ui.splitpane.HLayout",
94
94
  var beginFlex = begin.getLayoutProperties().flex;
95
95
  var endFlex = end.getLayoutProperties().flex;
96
96
 
97
- if (beginFlex == null) {
97
+ if (beginFlex === undefined || beginFlex === null) {
98
98
  beginFlex = 1;
99
99
  }
100
100
 
101
- if (endFlex == null) {
101
+ if (endFlex === undefined || endFlex === null) {
102
102
  endFlex = 1;
103
103
  }
104
104
 
@@ -226,6 +226,9 @@ qx.Class.define("qx.ui.splitpane.Pane",
226
226
  */
227
227
  _applyOrientation : function(value, old)
228
228
  {
229
+ // ARIA attrs
230
+ this.getContentElement().setAttribute("aria-orientation", value);
231
+
229
232
  var slider = this.getChildControl("slider");
230
233
  var splitter = this.getChildControl("splitter");
231
234
 
@@ -347,7 +350,7 @@ qx.Class.define("qx.ui.splitpane.Pane",
347
350
  */
348
351
  add : function(widget, flex)
349
352
  {
350
- if (flex == null) {
353
+ if (flex === undefined) {
351
354
  this._add(widget);
352
355
  } else {
353
356
  this._add(widget, {flex : flex});
@@ -94,11 +94,11 @@ qx.Class.define("qx.ui.splitpane.VLayout",
94
94
  var beginFlex = begin.getLayoutProperties().flex;
95
95
  var endFlex = end.getLayoutProperties().flex;
96
96
 
97
- if (beginFlex == null) {
97
+ if (beginFlex === undefined || beginFlex === null) {
98
98
  beginFlex = 1;
99
99
  }
100
100
 
101
- if (endFlex == null) {
101
+ if (endFlex === undefined || endFlex === null) {
102
102
  endFlex = 1;
103
103
  }
104
104
 
@@ -218,6 +218,9 @@ qx.Class.define("qx.ui.table.Table",
218
218
  // properties.
219
219
  tableModel.init(this);
220
220
  }
221
+
222
+ // ARIA attrs
223
+ this.getContentElement().setAttribute("role", "grid");
221
224
  },
222
225
 
223
226
 
@@ -753,6 +756,7 @@ qx.Class.define("qx.ui.table.Table",
753
756
 
754
757
  __additionalStatusBarText : null,
755
758
  __lastRowCount : null,
759
+ __lastColCount : null,
756
760
  __internalChange : null,
757
761
 
758
762
  __columnMenuButtons : null,
@@ -1399,6 +1403,19 @@ qx.Class.define("qx.ui.table.Table",
1399
1403
 
1400
1404
  this._updateScrollBarVisibility();
1401
1405
  this._updateStatusBar();
1406
+
1407
+ // ARIA attrs
1408
+ this.getContentElement().setAttribute("aria-rowcount", rowCount);
1409
+ }
1410
+
1411
+ const colCount = this.getTableModel().getColumnCount();
1412
+
1413
+ if (colCount != this.__lastColCount)
1414
+ {
1415
+ this.__lastColCount = colCount;
1416
+
1417
+ // ARIA attrs
1418
+ this.getContentElement().setAttribute("aria-colcount", colCount);
1402
1419
  }
1403
1420
  },
1404
1421
 
@@ -1703,6 +1720,10 @@ qx.Class.define("qx.ui.table.Table",
1703
1720
  if (col != null && scrollVisible) {
1704
1721
  this.scrollCellVisible(col, row);
1705
1722
  }
1723
+
1724
+ // ARIA attrs
1725
+ const cellId = "qooxdoo-table-cell-" + this.toHashCode() + "-" + row + "-" + col;
1726
+ this.getContentElement().setAttribute("aria-activedescendant", cellId);
1706
1727
  }
1707
1728
  },
1708
1729
 
@@ -1805,8 +1826,9 @@ qx.Class.define("qx.ui.table.Table",
1805
1826
  var col = this.__focusedCol;
1806
1827
  var row = this.__focusedRow;
1807
1828
 
1808
- // could also be undefined [BUG #4676]
1809
- if (col == null || row == null) {
1829
+ // could also be undefined [BUG #4676]. In that case default to first cell focus
1830
+ if (col === null || col === undefined || row === null || row === undefined) {
1831
+ this.setFocusedCell(0, 0, true);
1810
1832
  return;
1811
1833
  }
1812
1834
 
@@ -168,7 +168,9 @@ qx.Class.define("qx.ui.table.cellrenderer.Abstract",
168
168
  */
169
169
  _getCellAttributes : function(cellInfo)
170
170
  {
171
- return "";
171
+ const cellId = "qooxdoo-table-cell-" + cellInfo.table.toHashCode() + "-" + cellInfo.row + "-" + cellInfo.col;
172
+ const readOnly = cellInfo.editable !== null && cellInfo.editable !== undefined ? !cellInfo.editable : true;
173
+ return "id=" + cellId + " role=gridcell aria-readonly=" + readOnly;
172
174
  },
173
175
 
174
176
 
@@ -255,12 +255,16 @@ qx.Class.define("qx.ui.table.cellrenderer.AbstractImage",
255
255
  // overridden
256
256
  _getCellAttributes : function(cellInfo)
257
257
  {
258
- var tooltip = this.__imageData.tooltip;
258
+ let baseAttrs = this.base(arguments, cellInfo);
259
+ if (!baseAttrs) {
260
+ baseAttrs = "";
261
+ }
259
262
 
263
+ var tooltip = this.__imageData.tooltip;
260
264
  if (tooltip) {
261
- return "title='" + tooltip + "'";
265
+ return baseAttrs + " title='" + tooltip + "'";
262
266
  } else {
263
- return "";
267
+ return baseAttrs;
264
268
  }
265
269
  }
266
270
  },
@@ -36,6 +36,9 @@ qx.Class.define("qx.ui.table.headerrenderer.HeaderCell",
36
36
  layout.setColumnFlex(1, 1);
37
37
  layout.setColumnFlex(2, 1);
38
38
  this.setLayout(layout);
39
+
40
+ // ARIA attrs
41
+ this.getContentElement().setAttribute("role", "columnheader");
39
42
  },
40
43
 
41
44
  properties :
@@ -44,6 +44,9 @@ qx.Class.define("qx.ui.table.pane.Header",
44
44
  this.__blocker = new qx.ui.core.Blocker(this);
45
45
 
46
46
  this.__paneScroller = paneScroller;
47
+
48
+ // ARIA attrs
49
+ this.getContentElement().setAttribute("role", "row");
47
50
  },
48
51
 
49
52
 
@@ -697,17 +697,13 @@ qx.Class.define("qx.ui.table.pane.Scroller",
697
697
  {
698
698
  this.__tablePane.onTableModelDataChanged(firstRow, lastRow, firstColumn, lastColumn);
699
699
  var rowCount = this.getTable().getTableModel().getRowCount();
700
- var colCount = this.__table.getTableColumnModel().getOverallColumnCount();
701
700
 
702
701
  if (rowCount != this.__lastRowCount)
703
702
  {
704
703
  this.updateVerScrollBarMaximum();
705
-
706
- if (this.getFocusedRow() === null && rowCount > 0 && colCount > 0)
707
- {
708
- this.setFocusedCell(this.getFocusedColumn()||0, 0);
709
- }
710
- else if (this.getFocusedRow() >= rowCount)
704
+
705
+ const focusedRow = this.getFocusedRow();
706
+ if (focusedRow !== null && focusedRow >= rowCount)
711
707
  {
712
708
  if (rowCount == 0) {
713
709
  this.setFocusedCell(null, null);
@@ -250,7 +250,7 @@ qx.Class.define("qx.ui.table.rowrenderer.Default",
250
250
  */
251
251
  getRowAttributes : function(rowInfo)
252
252
  {
253
- return "";
253
+ return "role=row "; // Space important!
254
254
  }
255
255
  },
256
256
 
@@ -54,6 +54,22 @@ qx.Class.define("qx.ui.tabview.Page",
54
54
  this.setIcon(icon);
55
55
  }
56
56
 
57
+ // ARIA attrs
58
+ const btn = this.getButton();
59
+ const pageId = "page-" + this.toHashCode();
60
+ const btnId = "btn-" + pageId + btn.toHashCode();
61
+ const contentEl = this.getContentElement();
62
+ contentEl.setAttribute("id", pageId);
63
+ contentEl.setAttribute("role", "tabpanel");
64
+ contentEl.setAttribute("aria-labelledBy", btnId);
65
+ contentEl.setAttribute("aria-expanded", false);
66
+
67
+ const btnContentEl = btn.getContentElement();
68
+ btnContentEl.setAttribute("id", btnId);
69
+ btnContentEl.setAttribute("role", "tab");
70
+ btnContentEl.setAttribute("aria-selected", false);
71
+ btnContentEl.setAttribute("aria-controls", pageId);
72
+ btn.addListener("changeValue", this._onBtnChangeValue, this);
57
73
  },
58
74
 
59
75
 
@@ -224,6 +240,16 @@ qx.Class.define("qx.ui.tabview.Page",
224
240
  return control || this.base(arguments, id);
225
241
  },
226
242
 
243
+ /**
244
+ * Tab Change Listener
245
+ * @param {*} e
246
+ */
247
+ _onBtnChangeValue: function (e) {
248
+ const val = e.getData();
249
+ this.getContentElement().setAttribute("aria-expanded", val, true); // Set third argument to true -> direct Update
250
+ this.getButton().getContentElement().setAttribute("aria-selected", val);
251
+ },
252
+
227
253
  /*
228
254
  ---------------------------------------------------------------------------
229
255
  PROPERTY APPLY
@@ -75,6 +75,9 @@ qx.Class.define("qx.ui.tabview.TabView",
75
75
  } else {
76
76
  this.initBarPosition();
77
77
  }
78
+
79
+ // ARIA attrs
80
+ this.getContentElement().setAttribute("role", "tablist");
78
81
  },
79
82
 
80
83