@qooxdoo/framework 7.1.1 → 7.2.0
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/Manifest.json +1 -1
- package/lib/compiler/compile-info.json +83 -83
- package/lib/compiler/index.js +279 -274
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -1
- package/npm-shrinkwrap.json +235 -11095
- package/package.json +6 -6
- package/source/class/qx/Interface.js +13 -15
- package/source/class/qx/dev/unit/MTestLoader.js +25 -33
- package/source/class/qx/dev/unit/TestResult.js +9 -13
- package/source/class/qx/html/Element.js +1 -1
- package/source/class/qx/html/Node.js +0 -1
- package/source/class/qx/io/request/AbstractRequest.js +42 -66
- package/source/class/qx/test/Interface.js +70 -6
- package/source/class/qx/test/Mixin.js +20 -17
- package/source/class/qx/test/Promise.js +67 -91
- package/source/class/qx/test/bom/History.js +11 -19
- package/source/class/qx/test/bom/WebWorker.js +7 -15
- package/source/class/qx/test/bom/media/MediaTestCase.js +10 -18
- package/source/class/qx/test/bom/media/Video.js +10 -18
- package/source/class/qx/test/bom/rest/Resource.js +3 -7
- package/source/class/qx/test/bom/rest/ResourceWithRemote.js +40 -56
- package/source/class/qx/test/bom/webfonts/Validator.js +12 -20
- package/source/class/qx/test/core/Object.js +3 -7
- package/source/class/qx/test/data/controller/List.js +18 -22
- package/source/class/qx/test/data/marshal/Json.js +10 -14
- package/source/class/qx/test/data/store/Json.js +337 -428
- package/source/class/qx/test/data/store/Jsonp.js +46 -66
- package/source/class/qx/test/data/store/RestWithRemote.js +10 -18
- package/source/class/qx/test/html/Element.js +4 -8
- package/source/class/qx/test/html/Iframe.js +48 -60
- package/source/class/qx/test/io/jsonrpc/Client.js +1 -1
- package/source/class/qx/test/io/request/JsonpWithRemote.js +6 -10
- package/source/class/qx/test/io/request/MRequest.js +13 -25
- package/source/class/qx/test/io/request/Xhr.js +5 -9
- package/source/class/qx/test/io/request/XhrWithRemote.js +50 -78
- package/source/class/qx/test/io/rest/Resource.js +3 -7
- package/source/class/qx/test/io/rest/ResourceWithRemote.js +41 -57
- package/source/class/qx/test/mobile/basic/Image.js +16 -24
- package/source/class/qx/test/mobile/container/Navigation.js +3 -7
- package/source/class/qx/test/mobile/container/Scroll.js +8 -12
- package/source/class/qx/test/mobile/page/Page.js +24 -44
- package/source/class/qx/test/performance/Property.js +2 -2
- package/source/class/qx/test/ui/basic/Image.js +32 -52
- package/source/class/qx/test/ui/core/Blocker.js +6 -14
- package/source/class/qx/test/ui/embed/Iframe.js +13 -21
- package/source/class/qx/test/ui/form/FileSelectorButton.js +32 -0
- package/source/class/qx/test/ui/form/FormValidator.js +147 -211
- package/source/class/qx/test/ui/form/Label.js +8 -16
- package/source/class/qx/test/ui/root/Inline.js +9 -13
- package/source/class/qx/test/ui/table/Table.js +6 -14
- package/source/class/qx/test/ui/toolbar/OverflowHandling.js +18 -30
- package/source/class/qx/test/ui/virtual/Pane.js +3 -7
- package/source/class/qx/test/util/DynamicScriptLoader.js +23 -42
- package/source/class/qx/theme/tangible/Appearance.js +22 -3
- package/source/class/qx/tool/cli/Watch.js +3 -7
- package/source/class/qx/tool/cli/api/AbstractApi.js +1 -1
- package/source/class/qx/tool/cli/api/CompilerApi.js +3 -7
- package/source/class/qx/tool/cli/commands/Compile.js +3 -3
- package/source/class/qx/tool/cli/commands/Lint.js +8 -5
- package/source/class/qx/tool/compiler/ClassFile.js +22 -12
- package/source/class/qx/tool/compiler/Es6ify.js +7 -3
- package/source/class/qx/tool/compiler/TargetError.js +3 -4
- package/source/class/qx/tool/compiler/app/Application.js +3 -3
- package/source/class/qx/tool/compiler/app/WebFont.js +8 -6
- package/source/class/qx/tool/compiler/targets/SourceCodeCopier.js +1 -1
- package/source/class/qx/tool/compiler/targets/Target.js +2 -1
- package/source/class/qx/tool/compiler/targets/meta/AbstractJavascriptMeta.js +1 -1
- package/source/class/qx/tool/compiler/targets/meta/Browserify.js +77 -83
- package/source/class/qx/tool/compiler/targets/meta/Uglify.js +11 -3
- package/source/class/qx/tool/utils/Website.js +2 -2
- package/source/class/qx/ui/basic/Label.js +13 -17
- package/source/class/qx/ui/core/MPlacement.js +13 -21
- package/source/class/qx/ui/core/Widget.js +2 -3
- package/source/class/qx/ui/core/scroll/NativeScrollBar.js +3 -7
- package/source/class/qx/ui/core/scroll/ScrollBar.js +3 -7
- package/source/class/qx/ui/embed/Iframe.js +40 -50
- package/source/class/qx/ui/form/AbstractField.js +8 -12
- package/source/class/qx/ui/form/ComboBox.js +7 -15
- package/source/class/qx/ui/form/DateField.js +9 -18
- package/source/class/qx/ui/form/FileSelectorButton.js +157 -0
- package/source/class/qx/ui/form/Spinner.js +7 -15
- package/source/class/qx/ui/form/TextArea.js +3 -7
- package/source/class/qx/ui/form/VirtualComboBox.js +8 -16
- package/source/class/qx/ui/form/VirtualSelectBox.js +21 -37
- package/source/class/qx/ui/layout/Canvas.js +2 -2
- package/source/class/qx/ui/mobile/container/MIScroll.js +3 -7
- package/source/class/qx/ui/progressive/headfoot/Progress.js +22 -34
- package/source/class/qx/ui/progressive/renderer/table/Row.js +1 -1
- package/source/class/qx/ui/splitpane/Pane.js +14 -22
- package/source/class/qx/ui/table/MTableContextMenu.js +63 -71
- package/source/class/qx/ui/table/Table.js +3 -7
- package/source/class/qx/ui/table/model/Abstract.js +5 -2
- package/source/class/qx/ui/table/pane/Scroller.js +8 -12
- package/source/class/qx/ui/toolbar/FileSelectorButton.js +57 -0
- package/source/class/qx/ui/toolbar/Part.js +3 -7
- package/source/class/qx/ui/tree/VirtualTree.js +5 -9
- package/source/class/qx/ui/treevirtual/MNode.js +5 -3
- package/source/class/qx/ui/treevirtual/TreeVirtual.js +3 -7
- package/source/class/qx/ui/virtual/core/Pane.js +30 -42
- package/source/class/qx/util/DynamicScriptLoader.js +31 -43
|
@@ -124,10 +124,18 @@ qx.Class.define("qx.tool.compiler.targets.meta.Uglify", {
|
|
|
124
124
|
throw new Error("UglifyJS failed to minimise: " + (err.message || err));
|
|
125
125
|
}
|
|
126
126
|
await fs.writeFileAsync(outJsFilename, result.code, { encoding: "utf8" });
|
|
127
|
-
await fs.writeFileAsync(outJsFilename + ".map", result.map, {
|
|
127
|
+
await fs.writeFileAsync(outJsFilename + ".map", result.map, {
|
|
128
|
+
encoding: "utf8"
|
|
129
|
+
});
|
|
128
130
|
if (this._appMeta.getTarget().isSaveUnminified()) {
|
|
129
|
-
await fs.writeFileAsync(outJsFilename + ".unminified", inSourceCode, {
|
|
130
|
-
|
|
131
|
+
await fs.writeFileAsync(outJsFilename + ".unminified", inSourceCode, {
|
|
132
|
+
encoding: "utf8"
|
|
133
|
+
});
|
|
134
|
+
await fs.writeFileAsync(
|
|
135
|
+
outJsFilename + ".unminified.map",
|
|
136
|
+
JSON.stringify(inSourceMap, null, 2),
|
|
137
|
+
{ encoding: "utf8" }
|
|
138
|
+
);
|
|
131
139
|
}
|
|
132
140
|
|
|
133
141
|
this.fireDataEvent("minifiedApplication", {
|
|
@@ -25,8 +25,8 @@ const rimraf = require("rimraf");
|
|
|
25
25
|
const dot = require("dot");
|
|
26
26
|
require("jstransformer-dot");
|
|
27
27
|
const metalsmith = require("metalsmith");
|
|
28
|
-
const layouts = require("metalsmith
|
|
29
|
-
const markdown = require("metalsmith
|
|
28
|
+
const layouts = require("@metalsmith/layouts");
|
|
29
|
+
const markdown = require("@metalsmith/markdown");
|
|
30
30
|
//const filenames = require("metalsmith-filenames");
|
|
31
31
|
//var permalinks = require("metalsmith-permalinks");
|
|
32
32
|
/**
|
|
@@ -415,23 +415,19 @@ qx.Class.define("qx.ui.basic.Label", {
|
|
|
415
415
|
|
|
416
416
|
if (value != null) {
|
|
417
417
|
value.bind("enabled", this, "enabled");
|
|
418
|
-
this.__tapListenerId = this.addListener(
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
},
|
|
433
|
-
this
|
|
434
|
-
);
|
|
418
|
+
this.__tapListenerId = this.addListener("tap", () => {
|
|
419
|
+
// only focus focusable elements [BUG #3555]
|
|
420
|
+
if (value.isFocusable()) {
|
|
421
|
+
value.focus.apply(value);
|
|
422
|
+
}
|
|
423
|
+
// furthermore toggle if possible [BUG #6881]
|
|
424
|
+
if (
|
|
425
|
+
"toggleValue" in value &&
|
|
426
|
+
typeof value.toggleValue === "function"
|
|
427
|
+
) {
|
|
428
|
+
value.toggleValue();
|
|
429
|
+
}
|
|
430
|
+
});
|
|
435
431
|
}
|
|
436
432
|
},
|
|
437
433
|
|
|
@@ -461,20 +461,16 @@ qx.Mixin.define("qx.ui.core.MPlacement", {
|
|
|
461
461
|
);
|
|
462
462
|
|
|
463
463
|
// Remove the listener when the element disappears.
|
|
464
|
-
this.addListener(
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
this
|
|
477
|
-
);
|
|
464
|
+
this.addListener("disappear", () => {
|
|
465
|
+
if (this.__ptwLiveUpdater) {
|
|
466
|
+
qx.event.Idle.getInstance().removeListener(
|
|
467
|
+
"interval",
|
|
468
|
+
this.__ptwLiveUpdater
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
this.__ptwLiveUpdater = null;
|
|
472
|
+
}
|
|
473
|
+
});
|
|
478
474
|
}
|
|
479
475
|
|
|
480
476
|
this._place(coords);
|
|
@@ -532,13 +528,9 @@ qx.Mixin.define("qx.ui.core.MPlacement", {
|
|
|
532
528
|
}
|
|
533
529
|
|
|
534
530
|
if (size == null) {
|
|
535
|
-
this.addListenerOnce(
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
this.__getPlacementSize(callback);
|
|
539
|
-
},
|
|
540
|
-
this
|
|
541
|
-
);
|
|
531
|
+
this.addListenerOnce("appear", () => {
|
|
532
|
+
this.__getPlacementSize(callback);
|
|
533
|
+
});
|
|
542
534
|
} else {
|
|
543
535
|
callback.call(this, size);
|
|
544
536
|
}
|
|
@@ -2109,13 +2109,12 @@ qx.Class.define("qx.ui.core.Widget", {
|
|
|
2109
2109
|
var manager = qx.locale.Manager.getInstance();
|
|
2110
2110
|
this.__toolTipTextListenerId = manager.addListener(
|
|
2111
2111
|
"changeLocale",
|
|
2112
|
-
|
|
2112
|
+
() => {
|
|
2113
2113
|
var toolTipText = this.getToolTipText();
|
|
2114
2114
|
if (toolTipText && toolTipText.translate) {
|
|
2115
2115
|
this.setToolTipText(toolTipText.translate());
|
|
2116
2116
|
}
|
|
2117
|
-
}
|
|
2118
|
-
this
|
|
2117
|
+
}
|
|
2119
2118
|
);
|
|
2120
2119
|
}
|
|
2121
2120
|
},
|
|
@@ -71,13 +71,9 @@ qx.Class.define("qx.ui.core.scroll.NativeScrollBar", {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// prevent drag & drop on scrolling
|
|
74
|
-
this.addListener(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
e.stopPropagation();
|
|
78
|
-
},
|
|
79
|
-
this
|
|
80
|
-
);
|
|
74
|
+
this.addListener("track", e => {
|
|
75
|
+
e.stopPropagation();
|
|
76
|
+
});
|
|
81
77
|
},
|
|
82
78
|
|
|
83
79
|
events: {
|
|
@@ -81,13 +81,9 @@ qx.Class.define("qx.ui.core.scroll.ScrollBar", {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// prevent drag & drop on scrolling
|
|
84
|
-
this.addListener(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
e.stopPropagation();
|
|
88
|
-
},
|
|
89
|
-
this
|
|
90
|
-
);
|
|
84
|
+
this.addListener("track", e => {
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
});
|
|
91
87
|
},
|
|
92
88
|
|
|
93
89
|
events: {
|
|
@@ -92,64 +92,54 @@ qx.Class.define("qx.ui.embed.Iframe", {
|
|
|
92
92
|
this.__blockerElement = this._createBlockerElement();
|
|
93
93
|
|
|
94
94
|
if (qx.core.Environment.get("ecmascript.mutationobserver")) {
|
|
95
|
-
this.addListenerOnce(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (mutationRecord.addedNodes[i] == element) {
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
95
|
+
this.addListenerOnce("appear", () => {
|
|
96
|
+
var element = this.getContentElement().getDomElement();
|
|
97
|
+
|
|
98
|
+
// Mutation record check callback
|
|
99
|
+
var isDOMNodeInserted = function (mutationRecord) {
|
|
100
|
+
var i;
|
|
101
|
+
// 'our' iframe was either added...
|
|
102
|
+
if (mutationRecord.addedNodes) {
|
|
103
|
+
for (i = mutationRecord.addedNodes.length; i >= 0; --i) {
|
|
104
|
+
if (mutationRecord.addedNodes[i] == element) {
|
|
105
|
+
return true;
|
|
109
106
|
}
|
|
110
107
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
108
|
+
}
|
|
109
|
+
// ...or removed
|
|
110
|
+
if (mutationRecord.removedNodes) {
|
|
111
|
+
for (i = mutationRecord.removedNodes.length; i >= 0; --i) {
|
|
112
|
+
if (mutationRecord.removedNodes[i] == element) {
|
|
113
|
+
return true;
|
|
117
114
|
}
|
|
118
115
|
}
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
};
|
|
121
119
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
observer.observe(parent, { childList: true, subtree: true });
|
|
135
|
-
},
|
|
136
|
-
this
|
|
137
|
-
);
|
|
120
|
+
var observer = new MutationObserver(
|
|
121
|
+
function (mutationRecords) {
|
|
122
|
+
if (mutationRecords.some(isDOMNodeInserted)) {
|
|
123
|
+
this._syncSourceAfterDOMMove();
|
|
124
|
+
}
|
|
125
|
+
}.bind(this)
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Observe parent element
|
|
129
|
+
var parent = this.getLayoutParent().getContentElement().getDomElement();
|
|
130
|
+
observer.observe(parent, { childList: true, subtree: true });
|
|
131
|
+
});
|
|
138
132
|
}
|
|
139
133
|
// !qx.core.Environment.get("ecmascript.mutationobserver")
|
|
140
134
|
else {
|
|
141
|
-
this.addListenerOnce(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
);
|
|
150
|
-
},
|
|
151
|
-
this
|
|
152
|
-
);
|
|
135
|
+
this.addListenerOnce("appear", () => {
|
|
136
|
+
var element = this.getContentElement().getDomElement();
|
|
137
|
+
qx.bom.Event.addNativeListener(
|
|
138
|
+
element,
|
|
139
|
+
"DOMNodeInserted",
|
|
140
|
+
this._onDOMNodeInserted
|
|
141
|
+
);
|
|
142
|
+
});
|
|
153
143
|
|
|
154
144
|
this._onDOMNodeInserted = qx.lang.Function.listener(
|
|
155
145
|
this._syncSourceAfterDOMMove,
|
|
@@ -994,18 +994,14 @@ qx.Class.define("qx.ui.form.AbstractField", {
|
|
|
994
994
|
/* qx Bug #8870: Firefox 35 will not display a text area's
|
|
995
995
|
placeholder text if the attribute is set before the
|
|
996
996
|
element is added to the DOM. This is fixed in FF 36. */
|
|
997
|
-
this.addListenerOnce(
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
.setAttribute("placeholder", value);
|
|
1006
|
-
},
|
|
1007
|
-
this
|
|
1008
|
-
);
|
|
997
|
+
this.addListenerOnce("appear", () => {
|
|
998
|
+
this.getContentElement()
|
|
999
|
+
.getDomElement()
|
|
1000
|
+
.removeAttribute("placeholder");
|
|
1001
|
+
this.getContentElement()
|
|
1002
|
+
.getDomElement()
|
|
1003
|
+
.setAttribute("placeholder", value);
|
|
1004
|
+
});
|
|
1009
1005
|
}
|
|
1010
1006
|
}
|
|
1011
1007
|
}
|
|
@@ -53,21 +53,13 @@ qx.Class.define("qx.ui.form.ComboBox", {
|
|
|
53
53
|
|
|
54
54
|
// forward the focusin and focusout events to the textfield. The textfield
|
|
55
55
|
// is not focusable so the events need to be forwarded manually.
|
|
56
|
-
this.addListener(
|
|
57
|
-
"focusin",
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
this.addListener(
|
|
65
|
-
"focusout",
|
|
66
|
-
function (e) {
|
|
67
|
-
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
68
|
-
},
|
|
69
|
-
this
|
|
70
|
-
);
|
|
56
|
+
this.addListener("focusin", e => {
|
|
57
|
+
textField.fireNonBubblingEvent("focusin", qx.event.type.Focus);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
this.addListener("focusout", e => {
|
|
61
|
+
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
62
|
+
});
|
|
71
63
|
},
|
|
72
64
|
|
|
73
65
|
/*
|
|
@@ -67,21 +67,13 @@ qx.Class.define("qx.ui.form.DateField", {
|
|
|
67
67
|
|
|
68
68
|
// forward the focusin and focusout events to the textfield. The textfield
|
|
69
69
|
// is not focusable so the events need to be forwarded manually.
|
|
70
|
-
this.addListener(
|
|
71
|
-
"focusin",
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
this.addListener(
|
|
79
|
-
"focusout",
|
|
80
|
-
function (e) {
|
|
81
|
-
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
82
|
-
},
|
|
83
|
-
this
|
|
84
|
-
);
|
|
70
|
+
this.addListener("focusin", e => {
|
|
71
|
+
textField.fireNonBubblingEvent("focusin", qx.event.type.Focus);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
this.addListener("focusout", e => {
|
|
75
|
+
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
76
|
+
});
|
|
85
77
|
|
|
86
78
|
// initializes the DateField with the default format
|
|
87
79
|
this._setDefaultDateFormat();
|
|
@@ -225,10 +217,9 @@ qx.Class.define("qx.ui.form.DateField", {
|
|
|
225
217
|
if (qx.core.Environment.get("qx.dynlocale")) {
|
|
226
218
|
this.__localeListenerId = qx.locale.Manager.getInstance().addListener(
|
|
227
219
|
"changeLocale",
|
|
228
|
-
|
|
220
|
+
() => {
|
|
229
221
|
this._setDefaultDateFormat();
|
|
230
|
-
}
|
|
231
|
-
this
|
|
222
|
+
}
|
|
232
223
|
);
|
|
233
224
|
}
|
|
234
225
|
},
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/* ************************************************************************
|
|
2
|
+
|
|
3
|
+
qooxdoo
|
|
4
|
+
|
|
5
|
+
https://qooxdoo.org
|
|
6
|
+
|
|
7
|
+
Copyright:
|
|
8
|
+
2022 OETIKER+PARTNER AG
|
|
9
|
+
|
|
10
|
+
License:
|
|
11
|
+
MIT: https://opensource.org/licenses/MIT
|
|
12
|
+
See the LICENSE file in the project's top-level directory for details.
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
* Tobias Oetiker (oetiker)
|
|
16
|
+
|
|
17
|
+
************************************************************************ */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The FileSelectorButton opens a window and lets the user pick one or several
|
|
21
|
+
* files from the local filesystem. A FileList is returned which allows access
|
|
22
|
+
* to the content of the selected files from javascript. The file(s) can now be
|
|
23
|
+
* processed in javascript, or it/they can be uploaded to a server.
|
|
24
|
+
*
|
|
25
|
+
* *Example*
|
|
26
|
+
*
|
|
27
|
+
* Post the content of the file to the server.
|
|
28
|
+
*
|
|
29
|
+
* ```javascript
|
|
30
|
+
* let button = new qx.ui.form.FileSelectorButton("Select File");
|
|
31
|
+
* button.addListener('changeFileSelection',function(e){
|
|
32
|
+
* let fileList = e.getData();
|
|
33
|
+
* let form = new FormData();
|
|
34
|
+
* form.append('file',fileList[0]);
|
|
35
|
+
* let req = new qx.io.request.Xhr("upload",'POST').set({
|
|
36
|
+
* requestData: form
|
|
37
|
+
* });
|
|
38
|
+
* req.addListener('success',(e) => {
|
|
39
|
+
* let response = req.getResponse();
|
|
40
|
+
* });
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Process the file directly in javascript using the FileReader API.
|
|
45
|
+
*
|
|
46
|
+
* ```javascript
|
|
47
|
+
* let button = new qx.ui.form.FileSelectorButton("Select File");
|
|
48
|
+
* button.addListener('changeFileSelection',function(e){
|
|
49
|
+
* let fileList = e.getData();
|
|
50
|
+
* const reader = new FileReader();
|
|
51
|
+
* reader.addEventListener('load', () => {
|
|
52
|
+
* let response = reader.result;
|
|
53
|
+
* console.log("The first 4 chrs are: " + response);
|
|
54
|
+
* });
|
|
55
|
+
* const file = fileList[0];
|
|
56
|
+
* reader.readAsText(file.slice(0,4));
|
|
57
|
+
* });
|
|
58
|
+
|
|
59
|
+
*
|
|
60
|
+
* [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/File_API/Using_files_from_web_applications)
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
let InputElementIdCounter = 0;
|
|
64
|
+
qx.Class.define("qx.ui.form.FileSelectorButton", {
|
|
65
|
+
extend: qx.ui.form.Button,
|
|
66
|
+
events: {
|
|
67
|
+
/**
|
|
68
|
+
* The event is fired when the file selection changes.
|
|
69
|
+
*
|
|
70
|
+
* The method {@link qx.event.type.Data#getData} returns the
|
|
71
|
+
* current [fileList](https://developer.mozilla.org/en-US/docs/Web/API/FileList)
|
|
72
|
+
*/
|
|
73
|
+
changeFileSelection: "qx.event.type.Data"
|
|
74
|
+
},
|
|
75
|
+
properties: {
|
|
76
|
+
/**
|
|
77
|
+
* What type of files should be offered in the fileselection dialog.
|
|
78
|
+
* Use a comma separated list of [Unique file type specifiers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers). If you dont set anything, all files
|
|
79
|
+
* are allowed.
|
|
80
|
+
*
|
|
81
|
+
* *Example*
|
|
82
|
+
*
|
|
83
|
+
* `.doc,.docx,application/msword`
|
|
84
|
+
*/
|
|
85
|
+
accept: {
|
|
86
|
+
nullable: true,
|
|
87
|
+
check: "String",
|
|
88
|
+
apply: "_applyAttribute"
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* Specify that the camera should be used for getting the "file". The
|
|
92
|
+
* value defines which camera should be used for capturing images.
|
|
93
|
+
* `user` indicates the user-facing camera.
|
|
94
|
+
* `environment` indicates the camera facing away from the user.
|
|
95
|
+
*/
|
|
96
|
+
capture: {
|
|
97
|
+
nullable: true,
|
|
98
|
+
check: ["user", "environment"],
|
|
99
|
+
apply: "_applyAttribute"
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* Set to "true" if you want to allow the selection of multiple files.
|
|
103
|
+
*/
|
|
104
|
+
multiple: {
|
|
105
|
+
nullable: true,
|
|
106
|
+
check: "Boolean",
|
|
107
|
+
apply: "_applyAttribute"
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* If present, indicates that only directories should be available for
|
|
111
|
+
* selection.
|
|
112
|
+
*/
|
|
113
|
+
directoriesOnly: {
|
|
114
|
+
nullable: true,
|
|
115
|
+
check: "Boolean",
|
|
116
|
+
apply: "_applyAttribute"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
members: {
|
|
120
|
+
__inputObject: null,
|
|
121
|
+
|
|
122
|
+
_applyAttribute: function (value, old, attr) {
|
|
123
|
+
if (attr === "directoriesOnly") {
|
|
124
|
+
// while the name of the attribute indicates that this only
|
|
125
|
+
// works for webkit borwsers, this is not the case. These
|
|
126
|
+
// days the attribute is supported by
|
|
127
|
+
// [everyone](https://caniuse.com/?search=webkitdirectory).
|
|
128
|
+
attr = "webkitdirectory";
|
|
129
|
+
}
|
|
130
|
+
this.__inputObject.setAttribute(attr, value);
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
_createContentElement: function () {
|
|
134
|
+
let id = "qxFileSelector_" + InputElementIdCounter++;
|
|
135
|
+
let input = (this.__inputObject = new qx.html.Input(
|
|
136
|
+
"file",
|
|
137
|
+
{ display: "none" },
|
|
138
|
+
{ id: id }
|
|
139
|
+
));
|
|
140
|
+
let label = new qx.html.Element("label", {}, { for: id });
|
|
141
|
+
label.addListenerOnce(
|
|
142
|
+
"appear",
|
|
143
|
+
e => {
|
|
144
|
+
label.add(input);
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
input.addListenerOnce("appear", e => {
|
|
148
|
+
let inputEl = input.getDomElement();
|
|
149
|
+
inputEl.addEventListener("change", e => {
|
|
150
|
+
this.fireDataEvent("changeFileSelection", inputEl.files);
|
|
151
|
+
inputEl.value = "";
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
return label;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
@@ -116,21 +116,13 @@ qx.Class.define("qx.ui.form.Spinner", {
|
|
|
116
116
|
|
|
117
117
|
// forward the focusin and focusout events to the textfield. The textfield
|
|
118
118
|
// is not focusable so the events need to be forwarded manually.
|
|
119
|
-
this.addListener(
|
|
120
|
-
"focusin",
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
this.addListener(
|
|
128
|
-
"focusout",
|
|
129
|
-
function (e) {
|
|
130
|
-
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
131
|
-
},
|
|
132
|
-
this
|
|
133
|
-
);
|
|
119
|
+
this.addListener("focusin", e => {
|
|
120
|
+
textField.fireNonBubblingEvent("focusin", qx.event.type.Focus);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
this.addListener("focusout", e => {
|
|
124
|
+
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
125
|
+
});
|
|
134
126
|
},
|
|
135
127
|
|
|
136
128
|
/*
|
|
@@ -193,13 +193,9 @@ qx.Class.define("qx.ui.form.TextArea", {
|
|
|
193
193
|
|
|
194
194
|
// On init, the clone is not yet present. Try again on appear.
|
|
195
195
|
} else {
|
|
196
|
-
this.getContentElement().addListenerOnce(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
this.__autoSize();
|
|
200
|
-
},
|
|
201
|
-
this
|
|
202
|
-
);
|
|
196
|
+
this.getContentElement().addListenerOnce("appear", () => {
|
|
197
|
+
this.__autoSize();
|
|
198
|
+
});
|
|
203
199
|
}
|
|
204
200
|
}
|
|
205
201
|
},
|
|
@@ -46,22 +46,14 @@ qx.Class.define("qx.ui.form.VirtualComboBox", {
|
|
|
46
46
|
|
|
47
47
|
// forward the focusin and focusout events to the textfield. The textfield
|
|
48
48
|
// is not focusable so the events need to be forwarded manually.
|
|
49
|
-
this.addListener(
|
|
50
|
-
"focusin",
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.addListener(
|
|
58
|
-
"focusout",
|
|
59
|
-
function (e) {
|
|
60
|
-
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
61
|
-
this.fireNonBubblingEvent("blur", qx.event.type.Focus);
|
|
62
|
-
},
|
|
63
|
-
this
|
|
64
|
-
);
|
|
49
|
+
this.addListener("focusin", e => {
|
|
50
|
+
textField.fireNonBubblingEvent("focusin", qx.event.type.Focus);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
this.addListener("focusout", e => {
|
|
54
|
+
textField.fireNonBubblingEvent("focusout", qx.event.type.Focus);
|
|
55
|
+
this.fireNonBubblingEvent("blur", qx.event.type.Focus);
|
|
56
|
+
});
|
|
65
57
|
},
|
|
66
58
|
|
|
67
59
|
properties: {
|