@qooxdoo/framework 7.0.0-beta.2 → 7.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/Manifest.json +2 -3
- package/bin/deploy/qx +0 -0
- package/lib/compiler/compile-info.json +63 -64
- package/lib/compiler/index.js +614 -7793
- package/lib/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +3 -1
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css +1 -1
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -1
- package/lib/resource/qx/tool/cli/templates/template_vars.js +1 -1
- package/lib/resource/qx/tool/loadsass.js +2 -10
- package/lib/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
- package/lib/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
- package/lib/resource/qx/tool/schema/compile-1-0-0.json +3 -7
- package/package.json +11 -11
- package/source/class/qx/test/ui/embed/Iframe.js +1 -0
- package/source/class/qx/test/ui/form/ComboBox.js +0 -42
- package/source/class/qx/theme/manager/Decoration.js +0 -0
- package/source/class/qx/theme/tangible/ColorDark.js +0 -0
- package/source/class/qx/tool/cli/Cli.js +5 -3
- package/source/class/qx/tool/cli/api/CompilerApi.js +15 -5
- package/source/class/qx/tool/cli/commands/Command.js +7 -0
- package/source/class/qx/tool/cli/commands/Compile.js +1 -1
- package/source/class/qx/tool/cli/commands/Lint.js +30 -11
- package/source/class/qx/tool/cli/commands/Package.js +1 -2
- package/source/class/qx/tool/cli/commands/package/Publish.js +19 -10
- package/source/class/qx/tool/compiler/Analyser.js +21 -22
- package/source/class/qx/tool/compiler/app/WebFont.js +1 -1
- package/source/class/qx/tool/compiler/makers/AppMaker.js +13 -13
- package/source/class/qx/tool/compiler/targets/TypeScriptWriter.js +1 -2
- package/source/class/qx/tool/compiler/targets/meta/PolyfillJs.js +7 -7
- package/source/class/qx/tool/config/Abstract.js +3 -3
- package/source/class/qx/tool/config/Utils.js +10 -1
- package/source/class/qx/tool/utils/Json.js +1 -1
- package/source/class/qx/ui/container/SlideBar.js +3 -0
- package/source/class/qx/ui/core/scroll/NativeScrollBar.js +3 -0
- package/source/class/qx/ui/core/scroll/ScrollBar.js +3 -0
- package/source/class/qx/ui/form/AbstractSelectBox.js +38 -6
- package/source/class/qx/ui/form/Button.js +3 -0
- package/source/class/qx/ui/form/CheckBox.js +25 -1
- package/source/class/qx/ui/form/ComboBox.js +36 -27
- package/source/class/qx/ui/form/List.js +3 -0
- package/source/class/qx/ui/form/MenuButton.js +24 -2
- package/source/class/qx/ui/form/RadioButton.js +7 -0
- package/source/class/qx/ui/form/RadioButtonGroup.js +3 -0
- package/source/class/qx/ui/form/RadioGroup.js +19 -0
- package/source/class/qx/ui/form/SelectBox.js +23 -1
- package/source/class/qx/ui/form/Slider.js +15 -0
- package/source/class/qx/ui/form/SplitButton.js +3 -0
- package/source/class/qx/ui/form/ToggleButton.js +8 -0
- package/source/class/qx/ui/menu/AbstractButton.js +24 -0
- package/source/class/qx/ui/menu/Button.js +3 -0
- package/source/class/qx/ui/menu/CheckBox.js +8 -0
- package/source/class/qx/ui/menu/Manager.js +2 -0
- package/source/class/qx/ui/menu/Menu.js +63 -1
- package/source/class/qx/ui/menu/RadioButton.js +10 -1
- package/source/class/qx/ui/menubar/Button.js +0 -27
- package/source/class/qx/ui/menubar/MenuBar.js +12 -0
- package/source/class/qx/ui/splitpane/Blocker.js +3 -0
- package/source/class/qx/ui/splitpane/Pane.js +3 -0
- package/source/class/qx/ui/table/Table.js +24 -2
- package/source/class/qx/ui/table/cellrenderer/Abstract.js +3 -1
- package/source/class/qx/ui/table/cellrenderer/AbstractImage.js +7 -3
- package/source/class/qx/ui/table/headerrenderer/HeaderCell.js +3 -0
- package/source/class/qx/ui/table/pane/Header.js +3 -0
- package/source/class/qx/ui/table/pane/Scroller.js +3 -7
- package/source/class/qx/ui/table/rowrenderer/Default.js +1 -1
- package/source/class/qx/ui/tabview/Page.js +26 -0
- package/source/class/qx/ui/tabview/TabView.js +3 -0
- package/source/class/qx/ui/toolbar/Button.js +2 -27
- package/source/class/qx/ui/toolbar/CheckBox.js +0 -27
- package/source/class/qx/ui/toolbar/RadioButton.js +21 -0
- package/source/class/qx/ui/toolbar/SplitButton.js +0 -28
- package/source/class/qx/ui/toolbar/ToolBar.js +3 -0
- package/source/class/qxWeb.js +2 -0
- package/source/resource/qx/decoration/Indigo/font/JosefinSlab-SemiBold.ttf +0 -0
- package/source/resource/qx/decoration/Indigo/font/SIL Open Font License 1.1.txt +0 -0
- package/source/resource/qx/iconfont/MaterialIcons/fetch-fonts.sh +0 -0
- package/source/resource/qx/tool/bin/build-devtools +0 -0
- package/source/resource/qx/tool/bin/build-website +0 -0
- package/source/resource/qx/tool/bin/download-assets +0 -0
- package/source/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +3 -1
- package/source/resource/qx/tool/cli/templates/template_vars.js +1 -1
- package/source/resource/qx/tool/loadsass.js +2 -10
- package/source/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
- package/source/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
- package/source/resource/qx/tool/schema/compile-1-0-0.json +3 -7
- package/lib/resource/qx/tool/website/.gitignore +0 -2
- package/source/class/qx/io/request/auth/.gitignore +0 -0
- package/source/class/qx/test/bom/client/.gitignore +0 -0
- package/source/class/qx/test/ui/control/.gitignore +0 -0
- package/source/class/qx/tool/compiler/Version.js +0 -20
- package/source/resource/qx/decoration/Modern/treevirtual/.gitignore +0 -0
- package/source/resource/qx/mobile/css/.gitignore +0 -3
- package/source/resource/qx/tool/website/.gitignore +0 -2
- package/source/resource/qx/website/.gitignore +0 -1
- package/source/resource/qx/website/scss/.gitignore +0 -1
|
@@ -191,7 +191,7 @@ qx.Class.define("qx.tool.config.Utils", {
|
|
|
191
191
|
|
|
192
192
|
throw new qx.tool.utils.Utils.UserError(`Path to the qx library cannot be determined.`);
|
|
193
193
|
};
|
|
194
|
-
|
|
194
|
+
|
|
195
195
|
this.__qxPathPromise = getQxPathImpl();
|
|
196
196
|
return await this.__qxPathPromise;
|
|
197
197
|
},
|
|
@@ -217,6 +217,15 @@ qx.Class.define("qx.tool.config.Utils", {
|
|
|
217
217
|
return qx.tool.config.Utils.getLibraryVersion(qxpath);
|
|
218
218
|
},
|
|
219
219
|
|
|
220
|
+
/**
|
|
221
|
+
* returns the compiler version.
|
|
222
|
+
* The version is written during compiler compile into the enviroment
|
|
223
|
+
* @return {String}
|
|
224
|
+
*/
|
|
225
|
+
getCompilerVersion() {
|
|
226
|
+
return qx.core.Environment.get("qx.compiler.version");
|
|
227
|
+
},
|
|
228
|
+
|
|
220
229
|
/**
|
|
221
230
|
* Returns the qooxdoo version used in the application in the current or given
|
|
222
231
|
* directory. Throws if no such version can be determined
|
|
@@ -272,6 +272,9 @@ qx.Class.define("qx.ui.container.SlideBar",
|
|
|
272
272
|
// property apply
|
|
273
273
|
_applyOrientation : function(value, old)
|
|
274
274
|
{
|
|
275
|
+
// ARIA attrs
|
|
276
|
+
this.getContentElement().setAttribute("aria-orientation", value);
|
|
277
|
+
|
|
275
278
|
var oldLayouts = [this.getLayout(), this._getLayout()];
|
|
276
279
|
var buttonForward = this.getChildControl("button-forward");
|
|
277
280
|
var buttonBackward = this.getChildControl("button-backward");
|
|
@@ -234,6 +234,9 @@ qx.Class.define("qx.ui.core.scroll.NativeScrollBar",
|
|
|
234
234
|
// property apply
|
|
235
235
|
_applyOrientation : function(value, old)
|
|
236
236
|
{
|
|
237
|
+
// ARIA attrs
|
|
238
|
+
this.getContentElement().setAttribute("aria-orientation", value);
|
|
239
|
+
|
|
237
240
|
var isHorizontal = this.__isHorizontal = value === "horizontal";
|
|
238
241
|
|
|
239
242
|
this.set({
|
|
@@ -301,6 +301,9 @@ qx.Class.define("qx.ui.core.scroll.ScrollBar",
|
|
|
301
301
|
// property apply
|
|
302
302
|
_applyOrientation : function(value, old)
|
|
303
303
|
{
|
|
304
|
+
// ARIA attrs
|
|
305
|
+
this.getContentElement().setAttribute("aria-orientation", value);
|
|
306
|
+
|
|
304
307
|
// Dispose old layout
|
|
305
308
|
var oldLayout = this._getLayout();
|
|
306
309
|
if (oldLayout) {
|
|
@@ -55,6 +55,12 @@ qx.Class.define("qx.ui.form.AbstractSelectBox",
|
|
|
55
55
|
this._setLayout(layout);
|
|
56
56
|
layout.setAlignY("middle");
|
|
57
57
|
|
|
58
|
+
// ARIA attrs
|
|
59
|
+
const contentEl = this.getContentElement();
|
|
60
|
+
contentEl.setAttribute("role", "button");
|
|
61
|
+
contentEl.setAttribute("aria-haspopup", "listbox");
|
|
62
|
+
contentEl.setAttribute("aria-expanded", false);
|
|
63
|
+
|
|
58
64
|
// Register listeners
|
|
59
65
|
this.addListener("keypress", this._onKeyPress);
|
|
60
66
|
this.addListener("blur", this._onBlur, this);
|
|
@@ -130,7 +136,7 @@ qx.Class.define("qx.ui.form.AbstractSelectBox",
|
|
|
130
136
|
|
|
131
137
|
switch(id)
|
|
132
138
|
{
|
|
133
|
-
case "list":
|
|
139
|
+
case "list": {
|
|
134
140
|
control = new qx.ui.form.List().set({
|
|
135
141
|
focusable: false,
|
|
136
142
|
keepFocus: true,
|
|
@@ -140,12 +146,18 @@ qx.Class.define("qx.ui.form.AbstractSelectBox",
|
|
|
140
146
|
selectionMode: "one",
|
|
141
147
|
quickSelection: true
|
|
142
148
|
});
|
|
149
|
+
const listId = "list-" + control.toHashCode();
|
|
150
|
+
const childrenContainerEl = control.getChildrenContainer().getContentElement();
|
|
151
|
+
childrenContainerEl.setAttribute("id", listId);
|
|
152
|
+
childrenContainerEl.setAttribute("role", "listbox");
|
|
153
|
+
this.getContentElement().setAttribute("aria-owns", listId);
|
|
143
154
|
|
|
155
|
+
control.addListener("addItem", this._onListAddItem, this);
|
|
144
156
|
control.addListener("changeSelection", this._onListChangeSelection, this);
|
|
145
157
|
control.addListener("pointerdown", this._onListPointerDown, this);
|
|
146
158
|
control.getChildControl("pane").addListener("tap", this.close, this);
|
|
147
159
|
break;
|
|
148
|
-
|
|
160
|
+
}
|
|
149
161
|
case "popup":
|
|
150
162
|
control = new qx.ui.popup.Popup(new qx.ui.layout.VBox());
|
|
151
163
|
control.setAutoHide(false);
|
|
@@ -292,8 +304,8 @@ qx.Class.define("qx.ui.form.AbstractSelectBox",
|
|
|
292
304
|
e.stopPropagation();
|
|
293
305
|
}
|
|
294
306
|
|
|
295
|
-
// hide the list always on escape
|
|
296
|
-
else if (!listPopup.isHidden() && identifier == "Escape")
|
|
307
|
+
// hide the list always on escape and tab
|
|
308
|
+
else if (!listPopup.isHidden() && (identifier == "Escape" || identifier == "Tab"))
|
|
297
309
|
{
|
|
298
310
|
this.close();
|
|
299
311
|
e.stop();
|
|
@@ -315,7 +327,23 @@ qx.Class.define("qx.ui.form.AbstractSelectBox",
|
|
|
315
327
|
_onResize : function(e){
|
|
316
328
|
this.getChildControl("popup").setMinWidth(e.getData().width);
|
|
317
329
|
},
|
|
318
|
-
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Sets ARIA attributes on the item
|
|
333
|
+
*
|
|
334
|
+
* @param e {qx.event.type.Data} Data Event
|
|
335
|
+
*/
|
|
336
|
+
_onListAddItem : function(e) {
|
|
337
|
+
const item = e.getData();
|
|
338
|
+
const contentEl = item.getContentElement();
|
|
339
|
+
contentEl.setAttribute("id", "list-item-" + item.toHashCode());
|
|
340
|
+
contentEl.setAttribute("role", "option");
|
|
341
|
+
const ariaSelected = contentEl.getAttribute("aria-selected");
|
|
342
|
+
// aria-selected may be already set from changeSelection listener
|
|
343
|
+
if (ariaSelected === null || ariaSelected === undefined) {
|
|
344
|
+
contentEl.setAttribute("aria-selected", false);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
319
347
|
|
|
320
348
|
/**
|
|
321
349
|
* Syncs the own property from the list change
|
|
@@ -343,7 +371,11 @@ qx.Class.define("qx.ui.form.AbstractSelectBox",
|
|
|
343
371
|
* @param e {qx.event.type.Data} Property change event
|
|
344
372
|
*/
|
|
345
373
|
_onPopupChangeVisibility : function(e) {
|
|
346
|
-
e.getData() == "visible"
|
|
374
|
+
const visible = e.getData() == "visible";
|
|
375
|
+
visible ? this.addState("popupOpen") : this.removeState("popupOpen");
|
|
376
|
+
|
|
377
|
+
// ARIA attrs
|
|
378
|
+
this.getContentElement().setAttribute("aria-expanded", visible);
|
|
347
379
|
}
|
|
348
380
|
}
|
|
349
381
|
});
|
|
@@ -75,6 +75,9 @@ qx.Class.define("qx.ui.form.Button",
|
|
|
75
75
|
this.setCommand(command);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
// ARIA attrs
|
|
79
|
+
this.getContentElement().setAttribute("role", "button");
|
|
80
|
+
|
|
78
81
|
// Add listeners
|
|
79
82
|
this.addListener("pointerover", this._onPointerOver);
|
|
80
83
|
this.addListener("pointerout", this._onPointerOut);
|
|
@@ -54,6 +54,12 @@ qx.Class.define("qx.ui.form.CheckBox",
|
|
|
54
54
|
// Initialize the checkbox to a valid value (the default is null which
|
|
55
55
|
// is invalid)
|
|
56
56
|
this.setValue(false);
|
|
57
|
+
|
|
58
|
+
// ARIA attrs
|
|
59
|
+
const contentEl = this.getContentElement();
|
|
60
|
+
contentEl.setAttribute("role", "checkbox");
|
|
61
|
+
contentEl.removeAttribute("aria-pressed");
|
|
62
|
+
contentEl.setAttribute("aria-checked", false);
|
|
57
63
|
},
|
|
58
64
|
|
|
59
65
|
|
|
@@ -107,6 +113,24 @@ qx.Class.define("qx.ui.form.CheckBox",
|
|
|
107
113
|
"toolTipText",
|
|
108
114
|
"value",
|
|
109
115
|
"menu"
|
|
110
|
-
]
|
|
116
|
+
],
|
|
117
|
+
|
|
118
|
+
// overridden
|
|
119
|
+
_applyValue : function(value, old) {
|
|
120
|
+
value ? this.addState("checked") : this.removeState("checked");
|
|
121
|
+
|
|
122
|
+
let ariaChecked = Boolean(value);
|
|
123
|
+
if (this.isTriState()) {
|
|
124
|
+
if (value === null) {
|
|
125
|
+
ariaChecked = "mixed";
|
|
126
|
+
this.addState("undetermined");
|
|
127
|
+
} else if (old === null) {
|
|
128
|
+
this.removeState("undetermined");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ARIA attrs
|
|
133
|
+
this.getContentElement().setAttribute("aria-checked", ariaChecked);
|
|
134
|
+
},
|
|
111
135
|
}
|
|
112
136
|
});
|
|
@@ -50,6 +50,9 @@ qx.Class.define("qx.ui.form.ComboBox",
|
|
|
50
50
|
var textField = this._createChildControl("textfield");
|
|
51
51
|
this._createChildControl("button");
|
|
52
52
|
|
|
53
|
+
// ARIA attrs
|
|
54
|
+
this.getContentElement().setAttribute("role", "combobox");
|
|
55
|
+
|
|
53
56
|
this.addListener("tap", this._onTap);
|
|
54
57
|
|
|
55
58
|
// forward the focusin and focusout events to the textfield. The textfield
|
|
@@ -242,26 +245,25 @@ qx.Class.define("qx.ui.form.ComboBox",
|
|
|
242
245
|
var popup = this.getChildControl("popup");
|
|
243
246
|
var iden = e.getKeyIdentifier();
|
|
244
247
|
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
this.toggle();
|
|
249
|
-
e.stopPropagation();
|
|
250
|
-
}
|
|
251
|
-
else if (iden == "Enter")
|
|
252
|
-
{
|
|
253
|
-
if (popup.isVisible())
|
|
254
|
-
{
|
|
248
|
+
if (popup.isVisible()) {
|
|
249
|
+
const listIdentifier = ["Up", "Down", "PageUp", "PageDown", "Escape", "Tab"];
|
|
250
|
+
if (iden == "Enter") {
|
|
255
251
|
this._setPreselectedItem();
|
|
256
252
|
this.resetAllTextSelection();
|
|
257
253
|
this.close();
|
|
258
254
|
e.stop();
|
|
255
|
+
} else if (listIdentifier.includes(iden)) {
|
|
256
|
+
this.base(arguments, e);
|
|
257
|
+
} else {
|
|
258
|
+
this.close();
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
if (iden == "Down") {
|
|
262
|
+
this.getChildControl("button").addState("selected");
|
|
263
|
+
this.open();
|
|
264
|
+
e.stop();
|
|
259
265
|
}
|
|
260
266
|
}
|
|
261
|
-
else if (popup.isVisible())
|
|
262
|
-
{
|
|
263
|
-
this.base(arguments, e);
|
|
264
|
-
}
|
|
265
267
|
},
|
|
266
268
|
|
|
267
269
|
|
|
@@ -333,6 +335,13 @@ qx.Class.define("qx.ui.form.ComboBox",
|
|
|
333
335
|
this.__preSelectedItem = null;
|
|
334
336
|
}
|
|
335
337
|
}
|
|
338
|
+
|
|
339
|
+
// Set aria-activedescendant
|
|
340
|
+
if (current && current[0]) {
|
|
341
|
+
this.getChildControl("textfield").getContentElement().setAttribute("aria-activedescendant", current[0].getContentElement().getAttribute("id"));
|
|
342
|
+
} else {
|
|
343
|
+
this.getChildControl("textfield").getContentElement().removeAttribute("aria-activedescendant");
|
|
344
|
+
}
|
|
336
345
|
},
|
|
337
346
|
|
|
338
347
|
|
|
@@ -363,16 +372,6 @@ qx.Class.define("qx.ui.form.ComboBox",
|
|
|
363
372
|
list.resetSelection();
|
|
364
373
|
}
|
|
365
374
|
}
|
|
366
|
-
else
|
|
367
|
-
{
|
|
368
|
-
// When closing the popup text should selected and field should
|
|
369
|
-
// have the focus. Identical to when reaching the field using the TAB key.
|
|
370
|
-
//
|
|
371
|
-
// Only focus if popup was visible before. Fixes [BUG #4453].
|
|
372
|
-
if (e.getOldData() == "visible") {
|
|
373
|
-
this.tabFocus();
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
375
|
|
|
377
376
|
// In all cases: Remove focused state from button
|
|
378
377
|
this.getChildControl("button").removeState("selected");
|
|
@@ -390,11 +389,12 @@ qx.Class.define("qx.ui.form.ComboBox",
|
|
|
390
389
|
var value = e.getData();
|
|
391
390
|
|
|
392
391
|
var list = this.getChildControl("list");
|
|
392
|
+
let current = null;
|
|
393
393
|
if (value != null) {
|
|
394
394
|
// Select item when possible
|
|
395
|
-
|
|
396
|
-
if (
|
|
397
|
-
list.setSelection([
|
|
395
|
+
current = list.findItem(value, false);
|
|
396
|
+
if (current) {
|
|
397
|
+
list.setSelection([current]);
|
|
398
398
|
} else {
|
|
399
399
|
list.resetSelection();
|
|
400
400
|
}
|
|
@@ -402,6 +402,15 @@ qx.Class.define("qx.ui.form.ComboBox",
|
|
|
402
402
|
list.resetSelection();
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
// ARIA attrs
|
|
406
|
+
const old = e.getOldData() ? list.findItem(e.getOldData(), false) : null;
|
|
407
|
+
if (old && old !== current) {
|
|
408
|
+
old.getContentElement().setAttribute("aria-selected", false);
|
|
409
|
+
}
|
|
410
|
+
if (current) {
|
|
411
|
+
current.getContentElement().setAttribute("aria-selected", true);
|
|
412
|
+
}
|
|
413
|
+
|
|
405
414
|
// Fire event
|
|
406
415
|
this.fireDataEvent("changeValue", value, e.getOldData());
|
|
407
416
|
},
|
|
@@ -277,6 +277,9 @@ qx.Class.define("qx.ui.form.List",
|
|
|
277
277
|
// property apply
|
|
278
278
|
_applyOrientation : function(value, old)
|
|
279
279
|
{
|
|
280
|
+
// ARIA attrs
|
|
281
|
+
this.getContentElement().setAttribute("aria-orientation", value);
|
|
282
|
+
|
|
280
283
|
var content = this.__content;
|
|
281
284
|
|
|
282
285
|
// save old layout for disposal
|
|
@@ -45,6 +45,9 @@ qx.Class.define("qx.ui.form.MenuButton",
|
|
|
45
45
|
if (menu != null) {
|
|
46
46
|
this.setMenu(menu);
|
|
47
47
|
}
|
|
48
|
+
|
|
49
|
+
// ARIA attrs
|
|
50
|
+
this.getContentElement().setAttribute("role", "button");
|
|
48
51
|
},
|
|
49
52
|
|
|
50
53
|
|
|
@@ -112,6 +115,7 @@ qx.Class.define("qx.ui.form.MenuButton",
|
|
|
112
115
|
old.resetOpener();
|
|
113
116
|
}
|
|
114
117
|
|
|
118
|
+
const contentEl = this.getContentElement();
|
|
115
119
|
if (value)
|
|
116
120
|
{
|
|
117
121
|
value.addListener("changeVisibility", this._onMenuChange, this);
|
|
@@ -119,6 +123,16 @@ qx.Class.define("qx.ui.form.MenuButton",
|
|
|
119
123
|
|
|
120
124
|
value.removeState("submenu");
|
|
121
125
|
value.removeState("contextmenu");
|
|
126
|
+
|
|
127
|
+
// ARIA attrs
|
|
128
|
+
contentEl.setAttribute("aria-haspopup", "menu");
|
|
129
|
+
contentEl.setAttribute("aria-expanded", value.isVisible());
|
|
130
|
+
contentEl.setAttribute("aria-controls", value.getContentElement().getAttribute("id"));
|
|
131
|
+
} else {
|
|
132
|
+
// ARIA attrs
|
|
133
|
+
contentEl.removeAttribute("aria-haspopup");
|
|
134
|
+
contentEl.removeAttribute("aria-expanded");
|
|
135
|
+
contentEl.removeAttribute("aria-controls");
|
|
122
136
|
}
|
|
123
137
|
},
|
|
124
138
|
|
|
@@ -142,6 +156,10 @@ qx.Class.define("qx.ui.form.MenuButton",
|
|
|
142
156
|
|
|
143
157
|
if (menu)
|
|
144
158
|
{
|
|
159
|
+
// Focus this button when the menu opens
|
|
160
|
+
if (this.isFocusable() && !qx.ui.core.FocusHandler.getInstance().isFocused(this)) {
|
|
161
|
+
this.focus();
|
|
162
|
+
}
|
|
145
163
|
// Hide all menus first
|
|
146
164
|
qx.ui.menu.Manager.getInstance().hideAll();
|
|
147
165
|
|
|
@@ -177,12 +195,15 @@ qx.Class.define("qx.ui.form.MenuButton",
|
|
|
177
195
|
_onMenuChange : function(e)
|
|
178
196
|
{
|
|
179
197
|
var menu = this.getMenu();
|
|
180
|
-
|
|
181
|
-
if (
|
|
198
|
+
const menuVisible = menu.isVisible()
|
|
199
|
+
if (menuVisible) {
|
|
182
200
|
this.addState("pressed");
|
|
183
201
|
} else {
|
|
184
202
|
this.removeState("pressed");
|
|
185
203
|
}
|
|
204
|
+
|
|
205
|
+
// ARIA attrs
|
|
206
|
+
this.getContentElement().setAttribute("aria-expanded", menuVisible);
|
|
186
207
|
},
|
|
187
208
|
|
|
188
209
|
|
|
@@ -241,6 +262,7 @@ qx.Class.define("qx.ui.form.MenuButton",
|
|
|
241
262
|
{
|
|
242
263
|
switch(e.getKeyIdentifier())
|
|
243
264
|
{
|
|
265
|
+
case "Space":
|
|
244
266
|
case "Enter":
|
|
245
267
|
this.removeState("abandoned");
|
|
246
268
|
this.addState("pressed");
|
|
@@ -68,6 +68,12 @@ qx.Class.define("qx.ui.form.RadioButton",
|
|
|
68
68
|
|
|
69
69
|
this.base(arguments, label);
|
|
70
70
|
|
|
71
|
+
// ARIA attrs
|
|
72
|
+
// Important: (Grouped) radio btns should be children of a div with role 'radiogroup'
|
|
73
|
+
const contentEl = this.getContentElement();
|
|
74
|
+
contentEl.setAttribute("role", "radio");
|
|
75
|
+
contentEl.setAttribute("aria-checked", false);
|
|
76
|
+
|
|
71
77
|
// Add listeners
|
|
72
78
|
this.addListener("execute", this._onExecute);
|
|
73
79
|
this.addListener("keypress", this._onKeyPress);
|
|
@@ -164,6 +170,7 @@ qx.Class.define("qx.ui.form.RadioButton",
|
|
|
164
170
|
value ?
|
|
165
171
|
this.addState("checked") :
|
|
166
172
|
this.removeState("checked");
|
|
173
|
+
this.getContentElement().setAttribute("aria-checked", Boolean(value));
|
|
167
174
|
},
|
|
168
175
|
|
|
169
176
|
|
|
@@ -522,7 +522,26 @@ qx.Class.define("qx.ui.form.RadioGroup",
|
|
|
522
522
|
|
|
523
523
|
if (value) {
|
|
524
524
|
value.set(groupedProperty, true);
|
|
525
|
+
|
|
526
|
+
// If Group is focused, the selection was changed by keyboard. Switch focus to new value
|
|
527
|
+
if (this.__isGroupFocused() && value.isFocusable()) {
|
|
528
|
+
value.focus();
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
},
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Checks if this group is focused by checking focused state of each item
|
|
535
|
+
* @returns {Boolean} result
|
|
536
|
+
*/
|
|
537
|
+
__isGroupFocused: function () {
|
|
538
|
+
const focusHandler = qx.ui.core.FocusHandler.getInstance();
|
|
539
|
+
for (const item of this._getItems()) {
|
|
540
|
+
if (focusHandler.isFocused(item)) {
|
|
541
|
+
return true;
|
|
542
|
+
}
|
|
525
543
|
}
|
|
544
|
+
return false;
|
|
526
545
|
}
|
|
527
546
|
},
|
|
528
547
|
|
|
@@ -221,6 +221,16 @@ qx.Class.define("qx.ui.form.SelectBox",
|
|
|
221
221
|
|
|
222
222
|
this.__updateIcon();
|
|
223
223
|
this.__updateLabel();
|
|
224
|
+
|
|
225
|
+
// ARIA attrs
|
|
226
|
+
const old = e.getOldData() ? e.getOldData()[0] : null;
|
|
227
|
+
const current = this.getSelection()[0];
|
|
228
|
+
if (old && old !== current) {
|
|
229
|
+
old.getContentElement().setAttribute("aria-selected", false);
|
|
230
|
+
}
|
|
231
|
+
if (current) {
|
|
232
|
+
current.getContentElement().setAttribute("aria-selected", true);
|
|
233
|
+
}
|
|
224
234
|
},
|
|
225
235
|
|
|
226
236
|
|
|
@@ -327,7 +337,11 @@ qx.Class.define("qx.ui.form.SelectBox",
|
|
|
327
337
|
_onKeyPress : function(e)
|
|
328
338
|
{
|
|
329
339
|
var iden = e.getKeyIdentifier();
|
|
330
|
-
if(iden == "
|
|
340
|
+
if ((iden == "Down" || iden == "Up") && e.isAltPressed()) {
|
|
341
|
+
this.toggle();
|
|
342
|
+
e.stop();
|
|
343
|
+
}
|
|
344
|
+
else if (iden == "Enter" || iden == "Space")
|
|
331
345
|
{
|
|
332
346
|
// Apply pre-selected item (translate quick selection to real selection)
|
|
333
347
|
if (this.__preSelectedItem)
|
|
@@ -337,6 +351,7 @@ qx.Class.define("qx.ui.form.SelectBox",
|
|
|
337
351
|
}
|
|
338
352
|
|
|
339
353
|
this.toggle();
|
|
354
|
+
e.stop();
|
|
340
355
|
}
|
|
341
356
|
else
|
|
342
357
|
{
|
|
@@ -413,6 +428,13 @@ qx.Class.define("qx.ui.form.SelectBox",
|
|
|
413
428
|
{
|
|
414
429
|
this.resetSelection();
|
|
415
430
|
}
|
|
431
|
+
|
|
432
|
+
// Set aria-activedescendant
|
|
433
|
+
if (current && current[0]) {
|
|
434
|
+
this.getContentElement().setAttribute("aria-activedescendant", current[0].getContentElement().getAttribute("id"));
|
|
435
|
+
} else {
|
|
436
|
+
this.getContentElement().removeAttribute("aria-activedescendant");
|
|
437
|
+
}
|
|
416
438
|
},
|
|
417
439
|
|
|
418
440
|
// overridden
|
|
@@ -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
|
}
|
|
@@ -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
|
{
|