@qooxdoo/framework 8.0.0-beta.1 → 8.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 +42 -0
- package/Manifest.json +1 -1
- package/lib/compiler/compile-info.json +54 -55
- package/lib/compiler/index.js +19039 -23607
- package/lib/resource/qx/tool/compiler/cli/templates/class/default.tmpl.js +6 -7
- package/lib/resource/qx/tool/compiler/cli/templates/class/singleton.tmpl.js +5 -6
- package/lib/resource/qx/tool/compiler/schema/compile-1-0-0.json +6 -2
- package/package.json +8 -10
- package/source/class/qx/Class.js +26 -7
- package/source/class/qx/Mixin.js +15 -6
- package/source/class/qx/core/BaseInit.js +14 -13
- package/source/class/qx/core/MObjectId.js +16 -0
- package/source/class/qx/core/MProperty.js +147 -175
- package/source/class/qx/core/check/AbstractCheck.js +5 -1
- package/source/class/qx/core/check/CheckFactory.js +6 -0
- package/source/class/qx/core/check/DynamicTypeCheck.js +9 -0
- package/source/class/qx/core/property/ExplicitPropertyStorage.js +7 -19
- package/source/class/qx/core/property/IPropertyStorage.js +2 -21
- package/source/class/qx/core/property/Property.js +115 -90
- package/source/class/qx/core/property/SimplePropertyStorage.js +2 -18
- package/source/class/qx/data/MBinding.js +1 -1
- package/source/class/qx/data/SingleValueBinding.js +63 -107
- package/source/class/qx/data/binding/AbstractSegment.js +16 -11
- package/source/class/qx/data/binding/ArrayIndexSegment.js +17 -10
- package/source/class/qx/data/binding/IInputReceiver.js +1 -1
- package/source/class/qx/data/binding/PropNameSegment.js +35 -12
- package/source/class/qx/dev/unit/TestCase.js +4 -1
- package/source/class/qx/event/handler/Focus.js +2 -1
- package/source/class/qx/html/Jsx.js +2 -3
- package/source/class/qx/html/Node.js +3 -3
- package/source/class/qx/io/jsonrpc/Client.js +1 -1
- package/source/class/qx/promise/NativeWrapper.js +1 -1
- package/source/class/qx/test/Mixin.js +219 -0
- package/source/class/qx/test/Promise.js +10 -11
- package/source/class/qx/test/core/Property.js +50 -16
- package/source/class/qx/test/data/singlevalue/Async.js +17 -4
- package/source/class/qx/test/data/singlevalue/Simple.js +6 -0
- package/source/class/qx/test/locale/Date.js +2 -2
- package/source/class/qx/test/performance/Property.js +0 -1
- package/source/class/qx/test/ui/core/SingleSelectionManager.js +150 -0
- package/source/class/qx/theme/classic/Appearance.js +21 -0
- package/source/class/qx/theme/modern/Appearance.js +21 -0
- package/source/class/qx/theme/simple/Appearance.js +21 -0
- package/source/class/qx/theme/tangible/Appearance.js +2 -0
- package/source/class/qx/tool/cli/AbstractCliApp.js +18 -2
- package/source/class/qx/tool/compiler/ClassFile.js +0 -4
- package/source/class/qx/tool/compiler/MetaDatabase.js +47 -0
- package/source/class/qx/tool/compiler/cli/api/CompilerApi.js +1 -2
- package/source/class/qx/tool/compiler/cli/commands/Compile.js +139 -8
- package/source/class/qx/tool/compiler/cli/commands/Create.js +1 -1
- package/source/class/qx/tool/compiler/cli/commands/Serve.js +1 -1
- package/source/class/qx/tool/compiler/cli/commands/Typescript.js +26 -39
- package/source/class/qx/tool/compiler/cli/commands/add/Script.js +1 -1
- package/source/class/qx/tool/compiler/cli/commands/package/Publish.js +3 -2
- package/source/class/qx/tool/compiler/cli/commands/package/Update.js +2 -2
- package/source/class/qx/tool/compiler/targets/TypeScriptWriter.js +3 -0
- package/source/class/qx/tool/compiler/targets/meta/Browserify.js +142 -80
- package/source/class/qx/tool/migration/M8_0_0.js +4 -4
- package/source/class/qx/ui/core/SingleSelectionManager.js +4 -4
- package/source/class/qx/ui/form/validation/Manager.js +1 -1
- package/source/class/qx/ui/toolbar/ToolBar.js +4 -4
- package/source/resource/qx/decoration/Modern/table/boolean-false.png +0 -0
- package/source/resource/qx/decoration/Modern/table/boolean-true.png +0 -0
- package/source/resource/qx/tool/compiler/cli/templates/class/default.tmpl.js +6 -7
- package/source/resource/qx/tool/compiler/cli/templates/class/singleton.tmpl.js +5 -6
- package/source/resource/qx/tool/compiler/schema/compile-1-0-0.json +6 -2
|
@@ -13,22 +13,13 @@
|
|
|
13
13
|
|
|
14
14
|
Authors:
|
|
15
15
|
* John Spackman (github.com/johnspackman)
|
|
16
|
+
* Patryk Malinowski (https://github.com/patryk-m-malinowski, pmalinowski116@gmail.com)
|
|
16
17
|
|
|
17
18
|
************************************************************************ */
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Property implementation for actual properties
|
|
21
22
|
*
|
|
22
|
-
* TODO:
|
|
23
|
-
*
|
|
24
|
-
* `validate` implementation
|
|
25
|
-
* `delegate` implementation
|
|
26
|
-
* `inheritable` implementation (pass onto `obj._getChildren`; check for special `inherit` value)
|
|
27
|
-
* Array check
|
|
28
|
-
* FunctionCheck
|
|
29
|
-
*
|
|
30
|
-
* how does init of property values work? `init` per class and `initFunction` per instance?
|
|
31
|
-
*
|
|
32
23
|
*/
|
|
33
24
|
qx.Bootstrap.define("qx.core.property.Property", {
|
|
34
25
|
implement: qx.core.property.IProperty,
|
|
@@ -50,19 +41,20 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
50
41
|
* will return null, instead of throwing an error.
|
|
51
42
|
*/
|
|
52
43
|
"qx.core.property.Property.inheritableDefaultIsNull": false,
|
|
44
|
+
|
|
53
45
|
/**
|
|
54
46
|
* If set to true, then properties with init values will have their apply method called during construction.
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
"qx.core.property.Property.applyDuringConstruct":
|
|
47
|
+
* You should only set this to false if you have a lot of legacy code which would take too much time/effort to modify to work with the new behavior.
|
|
48
|
+
*/
|
|
49
|
+
"qx.core.property.Property.applyDuringConstruct": true,
|
|
58
50
|
|
|
59
51
|
/**
|
|
60
52
|
* Only relevant when applyDuringConstruct is true.
|
|
61
53
|
* This contains regexes matching classnames which are excluded from the auto apply behaviour.
|
|
62
54
|
* They refer to concrete classes only, not the superclasses.
|
|
63
55
|
*
|
|
64
|
-
* Currently (2025-
|
|
65
|
-
* would create problems which are difficult to fix.
|
|
56
|
+
* Currently (2025-DEC-03), only "qx." classes are excluded because enabling applyDuringConstruct
|
|
57
|
+
* would create problems which are too difficult and time-consuming to fix.
|
|
66
58
|
*
|
|
67
59
|
* @type {Array<RegExp | string>}
|
|
68
60
|
*/
|
|
@@ -83,14 +75,14 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
83
75
|
/** @type {String} the name of the property */
|
|
84
76
|
__propertyName: null,
|
|
85
77
|
|
|
86
|
-
/** @type {qx.
|
|
78
|
+
/** @type {new () => qx.core.Object} the class that defined the property */
|
|
87
79
|
__clazz: null,
|
|
88
80
|
|
|
89
81
|
/** @type {Boolean} whether this is a pseudo property or not */
|
|
90
82
|
__pseudoProperty: false,
|
|
91
83
|
|
|
92
84
|
/**
|
|
93
|
-
* @type {qx.
|
|
85
|
+
* @type {new () => qx.core.Object} the class that original defined this property, before it was cloned and
|
|
94
86
|
* refined for the current `__clazz`
|
|
95
87
|
*/
|
|
96
88
|
__superClass: null,
|
|
@@ -134,11 +126,9 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
134
126
|
/** @type {Boolean} whether the property needs to be dereferenced */
|
|
135
127
|
__needsDereference: false,
|
|
136
128
|
|
|
137
|
-
isRefineAllowed(def) {},
|
|
138
|
-
|
|
139
129
|
/**
|
|
140
130
|
* The class where this property is defined
|
|
141
|
-
* @returns {
|
|
131
|
+
* @returns {new () => qx.core.Object}
|
|
142
132
|
*/
|
|
143
133
|
getClass() {
|
|
144
134
|
return this.__clazz;
|
|
@@ -200,10 +190,11 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
200
190
|
|
|
201
191
|
// Figure out the storage implementation
|
|
202
192
|
if (def.storage) {
|
|
193
|
+
//if it's an object, use it directly as storage
|
|
203
194
|
if (qx.Class.hasInterface(def.storage.constructor, qx.core.property.IPropertyStorage)) {
|
|
204
195
|
this.__storage = def.storage;
|
|
205
196
|
} else {
|
|
206
|
-
this.__storage =
|
|
197
|
+
this.__storage = qx.core.property.PropertyStorageFactory.getStorage(def.storage);
|
|
207
198
|
}
|
|
208
199
|
} else {
|
|
209
200
|
if (def.immutable == "replace") {
|
|
@@ -212,7 +203,7 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
212
203
|
} else if (def.check == "Object") {
|
|
213
204
|
this.__storage = qx.core.property.PropertyStorageFactory.getStorage(qx.core.property.ImmutableObjectStorage);
|
|
214
205
|
} else if (def.check == "qx.data.Array") {
|
|
215
|
-
this.__storage = qx.core.property.PropertyStorageFactory.getStorage(qx.core.property.ImmutableDataArrayStorage)
|
|
206
|
+
this.__storage = qx.core.property.PropertyStorageFactory.getStorage(qx.core.property.ImmutableDataArrayStorage);//cbh
|
|
216
207
|
} else {
|
|
217
208
|
throw new Error(
|
|
218
209
|
`${this}: ` + "only `check : 'Array'` and `check : 'Object'` " + "properties may have `immutable : 'replace'`."
|
|
@@ -220,7 +211,7 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
220
211
|
}
|
|
221
212
|
} else {
|
|
222
213
|
if (typeof def.get == "function" || typeof def.getAsync == "function") {
|
|
223
|
-
this.__storage = new qx.core.property.ExplicitPropertyStorage(this
|
|
214
|
+
this.__storage = new qx.core.property.ExplicitPropertyStorage(this);
|
|
224
215
|
} else {
|
|
225
216
|
this.__storage = qx.core.property.PropertyStorageFactory.getStorage(qx.core.property.SimplePropertyStorage);
|
|
226
217
|
}
|
|
@@ -274,11 +265,21 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
274
265
|
}
|
|
275
266
|
}
|
|
276
267
|
|
|
277
|
-
|
|
268
|
+
let hasInitVal = def.init !== undefined;
|
|
269
|
+
|
|
270
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
271
|
+
if (hasInitVal && def.initFunction) {
|
|
272
|
+
throw new Error(`${this}: init and initFunction are mutually exclusive. Please specify only one of them.`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (hasInitVal) {
|
|
278
277
|
this.__initValue = def.init;
|
|
278
|
+
this.__initFunction = undefined;
|
|
279
279
|
}
|
|
280
280
|
if (def.initFunction) {
|
|
281
281
|
this.__initFunction = def.initFunction;
|
|
282
|
+
this.__initValue = undefined;
|
|
282
283
|
}
|
|
283
284
|
|
|
284
285
|
if (qx.core.Environment.get("qx.debug")) {
|
|
@@ -433,6 +434,8 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
433
434
|
let initValue = this.__initValue;
|
|
434
435
|
if (initValue !== undefined) {
|
|
435
436
|
clazz.prototype["$$init_" + propertyName] = initValue;
|
|
437
|
+
} else if (this.__initFunction) {
|
|
438
|
+
clazz.prototype["$$init_" + propertyName] = undefined;
|
|
436
439
|
}
|
|
437
440
|
|
|
438
441
|
addMethod("init" + upname, function (...args) {
|
|
@@ -536,6 +539,12 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
536
539
|
return self.resetAsync(this);
|
|
537
540
|
});
|
|
538
541
|
}
|
|
542
|
+
|
|
543
|
+
if (this.__pseudoProperty) {
|
|
544
|
+
this.__supportsGetAsync = this.__clazz.prototype["get" + qx.Bootstrap.firstUp(this.__propertyName) + "Async"] !== undefined;
|
|
545
|
+
} else {
|
|
546
|
+
this.__supportsGetAsync = this.__storage.supportsGetAsync();
|
|
547
|
+
}
|
|
539
548
|
},
|
|
540
549
|
|
|
541
550
|
/**
|
|
@@ -567,9 +576,9 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
567
576
|
}
|
|
568
577
|
state.initMethodCalled = true;
|
|
569
578
|
|
|
570
|
-
if (value !== undefined && this.
|
|
579
|
+
if (value !== undefined && (this.__initValue !== undefined || this.__initFunction !== undefined)) {
|
|
571
580
|
this.warn(
|
|
572
|
-
`${this}: init() called with a value, ignoring - use deferredInit and do not specify an init value in the property definition`
|
|
581
|
+
`${this}: init() called with a value, ignoring - use deferredInit and do not specify an init/function value in the property definition`
|
|
573
582
|
);
|
|
574
583
|
value = undefined;
|
|
575
584
|
}
|
|
@@ -840,35 +849,20 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
840
849
|
}
|
|
841
850
|
}
|
|
842
851
|
|
|
852
|
+
//store the old value
|
|
853
|
+
let oldValue = this.__getImpl(thisObj, true);
|
|
843
854
|
let state = this.getPropertyState(thisObj);
|
|
844
855
|
|
|
856
|
+
//validate and transform the value
|
|
845
857
|
if (this.__validate) {
|
|
846
858
|
this.__callFunction(thisObj, this.__validate, value, this);
|
|
847
859
|
}
|
|
848
860
|
|
|
849
|
-
let oldValue = this.__getImpl(thisObj, true);
|
|
850
|
-
|
|
851
861
|
if (this.__transform) {
|
|
852
862
|
value = this.__callFunction(thisObj, this.__transform, value, oldValue, this.__propertyName);
|
|
853
863
|
}
|
|
854
864
|
|
|
855
|
-
|
|
856
|
-
if (scope == "user") {
|
|
857
|
-
this.__storage.reset(thisObj, this, value);
|
|
858
|
-
} else if (scope == "themed") {
|
|
859
|
-
if (value === undefined) {
|
|
860
|
-
delete state.themeValue;
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
value = this.__getImpl(thisObj, true);
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
if (this.isInheritable()) {
|
|
867
|
-
if (value === "inherit") {
|
|
868
|
-
value = state.inheritedValue;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
|
|
865
|
+
//perform additional checks if promise
|
|
872
866
|
let check = this.getCheck();
|
|
873
867
|
if (qx.core.Environment.get("qx.debug")) {
|
|
874
868
|
if (!check || check instanceof qx.core.check.Any) {
|
|
@@ -876,13 +870,15 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
876
870
|
this.warn(
|
|
877
871
|
"Property " +
|
|
878
872
|
this +
|
|
879
|
-
" is being set to a promise,
|
|
873
|
+
" is being set to a promise, but its check is not a Promise. The property will be set to the promise itself."
|
|
880
874
|
);
|
|
881
875
|
}
|
|
882
876
|
}
|
|
883
877
|
}
|
|
884
878
|
|
|
885
|
-
|
|
879
|
+
//use check for validation and coercion if necessary,
|
|
880
|
+
//but only if not resetting
|
|
881
|
+
if (!(value === "inherit" && this.isInheritable()) && method !== "reset" && check) {
|
|
886
882
|
if (!(value === null && oldValue === null) && !check.matches(value, thisObj)) {
|
|
887
883
|
let coerced = check.coerce(value, thisObj);
|
|
888
884
|
if (qx.lang.Type.isPromise(value) || coerced === null || !check.matches(coerced, thisObj)) {
|
|
@@ -892,6 +888,39 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
892
888
|
}
|
|
893
889
|
}
|
|
894
890
|
|
|
891
|
+
//Modify the value in the underlying storage
|
|
892
|
+
if (method == "reset") {
|
|
893
|
+
if (scope == "user") {
|
|
894
|
+
this.__storage.set(thisObj, this, value);
|
|
895
|
+
} else if (scope == "themed") {
|
|
896
|
+
if (value === undefined) {
|
|
897
|
+
delete state.themeValue;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
value = this.__getImpl(thisObj, true);
|
|
901
|
+
} else {
|
|
902
|
+
if (scope == "user") {
|
|
903
|
+
// Always set the value to the storage if it is a user value; this is because themable properties
|
|
904
|
+
// might be equal now, but if the theme value changes, the user's override needs to remain.
|
|
905
|
+
if (method == "set" || method == "init") {
|
|
906
|
+
this.__storage.set(thisObj, this, value);
|
|
907
|
+
}
|
|
908
|
+
} else if (scope == "themed") {
|
|
909
|
+
if (value !== undefined) {
|
|
910
|
+
state.themeValue = value;
|
|
911
|
+
value = this.__getImpl(thisObj);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// If the value is "inherit" and the property is inheritable, we need to calculate the inherited value
|
|
917
|
+
if (this.isInheritable() && value === "inherit") {
|
|
918
|
+
value = state.inheritedValue;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
//the final value has now been deternined.
|
|
922
|
+
//If it's not equal to the old value or state.applyMethodCalled was not set,
|
|
923
|
+
//we call apply and fire event
|
|
895
924
|
let isEqual = this.isEqual(thisObj, value, oldValue);
|
|
896
925
|
if (!isEqual && this.isMutating(thisObj)) {
|
|
897
926
|
this.warn("Property " + this + " is currently mutating");
|
|
@@ -913,23 +942,6 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
913
942
|
|
|
914
943
|
this.__setMutating(thisObj, true);
|
|
915
944
|
|
|
916
|
-
if (scope == "user") {
|
|
917
|
-
// Always set the value to the storage if it is a user value; this is because themable properties
|
|
918
|
-
// might be equal now, but if the theme value changes, the user's override needs to remain.
|
|
919
|
-
if (method == "set" || method == "init") {
|
|
920
|
-
this.__storage.set(thisObj, this, value);
|
|
921
|
-
}
|
|
922
|
-
} else if (scope == "themed") {
|
|
923
|
-
if (method != "reset") {
|
|
924
|
-
if (value !== undefined) {
|
|
925
|
-
state.themeValue = value;
|
|
926
|
-
value = this.get(thisObj);
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
} else if (qx.core.Environment.get("qx.debug")) {
|
|
930
|
-
throw new Error(`Invalid scope=${scope} in ${this.classname}.__setImpl`);
|
|
931
|
-
}
|
|
932
|
-
|
|
933
945
|
if (value === undefined) {
|
|
934
946
|
value = null;
|
|
935
947
|
}
|
|
@@ -975,21 +987,22 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
975
987
|
|
|
976
988
|
let state = this.getPropertyState(thisObj);
|
|
977
989
|
|
|
990
|
+
//store the old value
|
|
991
|
+
//we get it synchronously here because if this property supports async get,
|
|
992
|
+
//we may not always want to fetch the value asynchronously
|
|
993
|
+
//this means the apply method will be called with undefined as oldValue
|
|
994
|
+
let oldValue = this.__getImpl(thisObj, true);
|
|
995
|
+
|
|
996
|
+
//validate and transform the value
|
|
978
997
|
if (this.__validate) {
|
|
979
998
|
this.__callFunction(thisObj, this.__validate, value, this);
|
|
980
999
|
}
|
|
981
1000
|
|
|
982
|
-
let oldValue = await this.__getAsyncImpl(thisObj, true);
|
|
983
1001
|
|
|
984
1002
|
if (this.__transform) {
|
|
985
1003
|
value = this.__callFunction(thisObj, this.__transform, value, oldValue, this.__propertyName);
|
|
986
1004
|
}
|
|
987
1005
|
|
|
988
|
-
if (method == "reset") {
|
|
989
|
-
this.__storage.reset(thisObj, this, value);
|
|
990
|
-
value = await this.__getAsyncImpl(thisObj, true);
|
|
991
|
-
}
|
|
992
|
-
|
|
993
1006
|
let check = this.getCheck();
|
|
994
1007
|
if (qx.core.Environment.get("qx.debug")) {
|
|
995
1008
|
if (!check || check instanceof qx.core.check.Any) {
|
|
@@ -1013,6 +1026,22 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
1013
1026
|
}
|
|
1014
1027
|
}
|
|
1015
1028
|
|
|
1029
|
+
//Actually modify the underlying storage
|
|
1030
|
+
if (method == "reset") {
|
|
1031
|
+
this.__storage.set(thisObj, this, value);
|
|
1032
|
+
value = this.__getImpl(thisObj, true);
|
|
1033
|
+
} else {
|
|
1034
|
+
if (scope == "user") {
|
|
1035
|
+
// Always set the value to the storage if it is a user value; this is because themable properties
|
|
1036
|
+
// might be equal now, but if the theme value changes, the user's override needs to remain.
|
|
1037
|
+
if (method == "set" || method == "init") {
|
|
1038
|
+
this.__storage.set(thisObj, this, value);
|
|
1039
|
+
}
|
|
1040
|
+
} else if (qx.core.Environment.get("qx.debug")) {
|
|
1041
|
+
throw new Error(`Invalid scope=${scope} in ${this.classname}.__setAsyncImpl`);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1016
1045
|
let isEqual = this.isEqual(thisObj, value, oldValue);
|
|
1017
1046
|
if (!isEqual && this.isMutating(thisObj)) {
|
|
1018
1047
|
this.warn("Property " + this + " is currently mutating");
|
|
@@ -1036,16 +1065,6 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
1036
1065
|
let promise = new Promise(r => (resolve = r));
|
|
1037
1066
|
this.__setMutating(thisObj, promise);
|
|
1038
1067
|
|
|
1039
|
-
if (scope == "user") {
|
|
1040
|
-
// Always set the value to the storage if it is a user value; this is because themable properties
|
|
1041
|
-
// might be equal now, but if the theme value changes, the user's override needs to remain.
|
|
1042
|
-
if (method == "set" || method == "init") {
|
|
1043
|
-
this.__storage.set(thisObj, this, value);
|
|
1044
|
-
}
|
|
1045
|
-
} else if (qx.core.Environment.get("qx.debug")) {
|
|
1046
|
-
throw new Error(`Invalid scope=${scope} in ${this.classname}.__setAsyncImpl`);
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
1068
|
if (value === undefined) {
|
|
1050
1069
|
value = null;
|
|
1051
1070
|
}
|
|
@@ -1074,8 +1093,6 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
1074
1093
|
|
|
1075
1094
|
if (value !== undefined) {
|
|
1076
1095
|
return value;
|
|
1077
|
-
} else if (this.isAsync()) {
|
|
1078
|
-
return undefined;
|
|
1079
1096
|
}
|
|
1080
1097
|
|
|
1081
1098
|
let state = this.getPropertyState(thisObj);
|
|
@@ -1104,7 +1121,7 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
1104
1121
|
|
|
1105
1122
|
if (value !== undefined) {
|
|
1106
1123
|
return value;
|
|
1107
|
-
} else if (this.
|
|
1124
|
+
} else if (this.__supportsGetAsync) {
|
|
1108
1125
|
if (!safe) {
|
|
1109
1126
|
throw new Error("Property " + this + " has not been initialized - try using getAsync() instead");
|
|
1110
1127
|
} else {
|
|
@@ -1132,6 +1149,11 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
1132
1149
|
* @returns {Promise<*>}
|
|
1133
1150
|
*/
|
|
1134
1151
|
async __getAsyncImpl(thisObj, safe) {
|
|
1152
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1153
|
+
if (!this.__supportsGetAsync) {
|
|
1154
|
+
this.warn(`Called getAsync/resetAsync in property ${this} which does not support async getter.`);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1135
1157
|
const getRaw = async () => {
|
|
1136
1158
|
let value = this.__storage.get(thisObj, this);
|
|
1137
1159
|
|
|
@@ -1139,12 +1161,14 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
1139
1161
|
return value;
|
|
1140
1162
|
}
|
|
1141
1163
|
|
|
1142
|
-
value =
|
|
1164
|
+
value = this.getInitValue(thisObj);
|
|
1143
1165
|
if (value !== undefined) {
|
|
1144
1166
|
return value;
|
|
1145
1167
|
}
|
|
1146
1168
|
|
|
1147
|
-
|
|
1169
|
+
if (this.__supportsGetAsync) {
|
|
1170
|
+
return await this.__storage.getAsync(thisObj, this);
|
|
1171
|
+
}
|
|
1148
1172
|
};
|
|
1149
1173
|
|
|
1150
1174
|
let value = await getRaw();
|
|
@@ -1382,23 +1406,24 @@ qx.Bootstrap.define("qx.core.property.Property", {
|
|
|
1382
1406
|
promiseReady(thisObj) {},
|
|
1383
1407
|
|
|
1384
1408
|
/**
|
|
1385
|
-
* Whether the property
|
|
1409
|
+
* Whether the property has a defined value stored locally,
|
|
1410
|
+
* meaning we can safely get it synchronously
|
|
1386
1411
|
*
|
|
1387
1412
|
* @param {qx.core.Object} thisObj the object on which the property is defined
|
|
1388
1413
|
* @return {Boolean}
|
|
1389
1414
|
*/
|
|
1390
|
-
|
|
1415
|
+
hasLocalValue(thisObj) {
|
|
1391
1416
|
let value = this.__getImpl(thisObj, true);
|
|
1392
1417
|
return value !== undefined;
|
|
1393
1418
|
},
|
|
1394
1419
|
|
|
1395
1420
|
/**
|
|
1396
|
-
* Whether the property supports
|
|
1421
|
+
* Whether the property supports getting asynchronously from the underlying storage
|
|
1397
1422
|
*
|
|
1398
1423
|
* @return {Boolean}
|
|
1399
1424
|
*/
|
|
1400
|
-
|
|
1401
|
-
return
|
|
1425
|
+
supportsGetAsync() {
|
|
1426
|
+
return this.__supportsGetAsync;
|
|
1402
1427
|
},
|
|
1403
1428
|
|
|
1404
1429
|
/**
|
|
@@ -37,7 +37,7 @@ qx.Bootstrap.define("qx.core.property.SimplePropertyStorage", {
|
|
|
37
37
|
* @Override
|
|
38
38
|
*/
|
|
39
39
|
async getAsync(thisObj, property) {
|
|
40
|
-
|
|
40
|
+
// nothing
|
|
41
41
|
},
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -52,22 +52,6 @@ qx.Bootstrap.define("qx.core.property.SimplePropertyStorage", {
|
|
|
52
52
|
data.value = value;
|
|
53
53
|
},
|
|
54
54
|
|
|
55
|
-
/**
|
|
56
|
-
* @Override
|
|
57
|
-
*/
|
|
58
|
-
async setAsync(thisObj, property, value) {
|
|
59
|
-
return qx.Promise.resolve(value).then(value => {
|
|
60
|
-
this.set(thisObj, property, value);
|
|
61
|
-
});
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @Override
|
|
66
|
-
*/
|
|
67
|
-
reset(thisObj, property, value) {
|
|
68
|
-
this.set(thisObj, property, value);
|
|
69
|
-
},
|
|
70
|
-
|
|
71
55
|
/**
|
|
72
56
|
* @Override
|
|
73
57
|
*/
|
|
@@ -78,7 +62,7 @@ qx.Bootstrap.define("qx.core.property.SimplePropertyStorage", {
|
|
|
78
62
|
/**
|
|
79
63
|
* @Override
|
|
80
64
|
*/
|
|
81
|
-
|
|
65
|
+
supportsGetAsync() {
|
|
82
66
|
return false;
|
|
83
67
|
},
|
|
84
68
|
|
|
@@ -77,7 +77,7 @@ qx.Mixin.define("qx.data.MBinding", {
|
|
|
77
77
|
*/
|
|
78
78
|
bindAsync: qx.core.Environment.select("qx.promise", {
|
|
79
79
|
true(sourcePropertyChain, targetObject, targetProperty, options) {
|
|
80
|
-
var binding = qx.data.SingleValueBinding.bind(this, sourcePropertyChain, targetObject, targetProperty || "value", options);
|
|
80
|
+
var binding = qx.data.SingleValueBinding.bind(this, sourcePropertyChain, targetObject, targetProperty || "value", {...options, async: true});
|
|
81
81
|
return binding.getInitPromise().then(() => binding);
|
|
82
82
|
},
|
|
83
83
|
false(sourcePropertyChain, targetObject, targetProperty, options) {
|