@qooxdoo/framework 7.9.1 → 8.0.0-beta.1
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 +191 -33
- package/Manifest.json +3 -3
- package/bin/tools/utils.js +50 -13
- package/lib/compiler/compile-info.json +295 -225
- package/lib/compiler/index.js +56729 -44017
- package/lib/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-node.tmpl.js +1 -0
- package/lib/resource/qx/tool/compiler/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -0
- package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/cli/templates/template_vars.js +12 -9
- package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/schema/Manifest-1-0-0.json +2 -2
- package/lib/resource/qx/tool/{schema → compiler/schema}/Manifest-2-0-0.json +2 -2
- package/lib/resource/qx/tool/{schema → compiler/schema}/compile-1-0-0.json +15 -3
- package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/schema/qooxdoo-1-0-0.json +1 -1
- package/lib/resource/qx/tool/website/build/404.html +22 -22
- package/lib/resource/qx/tool/website/build/about.html +23 -23
- package/lib/resource/qx/tool/website/build/assets/common.js +30 -18
- package/lib/resource/qx/tool/website/build/assets/custom.css +290 -0
- package/lib/resource/qx/tool/website/build/assets/qxWeb.js +28 -0
- package/lib/resource/qx/tool/website/build/diagnostics/dependson.html +30 -30
- package/lib/resource/qx/tool/website/build/diagnostics/dependson.js +49 -40
- package/lib/resource/qx/tool/website/build/diagnostics/requiredby.html +20 -23
- package/lib/resource/qx/tool/website/build/diagnostics/requiredby.js +38 -31
- package/lib/resource/qx/tool/website/build/index.html +24 -24
- package/lib/resource/qx/tool/website/build/scripts/serve.js +63 -65
- package/lib/resource/qx/tool/website/partials/footer.html +8 -13
- package/lib/resource/qx/tool/website/partials/head.html +9 -7
- package/lib/resource/qx/tool/website/partials/header.html +3 -3
- package/lib/resource/qx/tool/website/src/assets/common.js +32 -0
- package/lib/resource/qx/tool/website/src/assets/custom.css +290 -0
- package/lib/resource/qx/tool/website/src/assets/qxWeb.js +28 -0
- package/lib/resource/qx/tool/website/src/diagnostics/dependson.js +49 -40
- package/lib/resource/qx/tool/website/src/diagnostics/requiredby.js +38 -31
- package/lib/resource/qx/tool/website/src/index.html +2 -2
- package/lib/resource/qx/tool/website/src/scripts/serve.js +63 -65
- package/package.json +20 -19
- package/source/boot/index.html +2 -2
- package/source/class/qx/Bootstrap.js +931 -705
- package/source/class/qx/Class.js +1476 -1451
- package/source/class/qx/Interface.js +40 -107
- package/source/class/qx/Mixin.js +58 -116
- package/source/class/qx/Promise.js +1 -0
- package/source/class/qx/Theme.js +1 -1
- package/source/class/qx/application/Routing.js +2 -0
- package/source/class/qx/bom/Font.js +3 -0
- package/source/class/qx/bom/client/Locale.js +5 -0
- package/source/class/qx/bom/request/Jsonp.js +5 -13
- package/source/class/qx/bom/request/Script.js +11 -35
- package/source/class/qx/bom/request/SimpleXhr.js +13 -41
- package/source/class/qx/bom/request/Xhr.js +19 -80
- package/source/class/qx/bom/storage/Memory.js +2 -0
- package/source/class/qx/bom/storage/UserData.js +2 -0
- package/source/class/qx/bom/storage/Web.js +2 -0
- package/source/class/qx/bom/webfonts/Validator.js +13 -5
- package/source/class/qx/core/Assert.js +14 -0
- package/source/class/qx/core/BaseInit.js +19 -20
- package/source/class/qx/core/Environment.js +23 -20
- package/source/class/qx/core/MEvent.js +1 -1
- package/source/class/qx/core/MObjectId.js +8 -6
- package/source/class/qx/core/MProperty.js +172 -136
- package/source/class/qx/core/Object.js +88 -102
- package/source/class/qx/core/check/AbstractCheck.js +111 -0
- package/source/class/qx/core/check/Any.js +63 -0
- package/source/class/qx/core/check/CheckFactory.js +151 -0
- package/source/class/qx/core/check/DynamicTypeCheck.js +90 -0
- package/source/class/qx/core/check/ICheck.js +75 -0
- package/source/class/qx/core/check/IsOneOfCheck.js +63 -0
- package/source/class/qx/core/check/JsDocCheck.js +71 -0
- package/source/class/qx/core/check/SimpleCheck.js +42 -0
- package/source/class/qx/core/check/standard/ArrayCheck.js +49 -0
- package/source/class/qx/core/check/standard/BooleanCheck.js +47 -0
- package/source/class/qx/core/check/standard/ClassCheck.js +33 -0
- package/source/class/qx/core/check/standard/ColorCheck.js +33 -0
- package/source/class/qx/core/check/standard/DateCheck.js +49 -0
- package/source/class/qx/core/check/standard/DecoratorCheck.js +33 -0
- package/source/class/qx/core/check/standard/DocumentCheck.js +40 -0
- package/source/class/qx/core/check/standard/ElementCheck.js +40 -0
- package/source/class/qx/core/check/standard/ErrorCheck.js +46 -0
- package/source/class/qx/core/check/standard/EventCheck.js +40 -0
- package/source/class/qx/core/check/standard/FontCheck.js +33 -0
- package/source/class/qx/core/check/standard/FunctionCheck.js +49 -0
- package/source/class/qx/core/check/standard/IntegerCheck.js +54 -0
- package/source/class/qx/core/check/standard/InterfaceCheck.js +33 -0
- package/source/class/qx/core/check/standard/MapCheck.js +33 -0
- package/source/class/qx/core/check/standard/MixinCheck.js +33 -0
- package/source/class/qx/core/check/standard/NodeCheck.js +40 -0
- package/source/class/qx/core/check/standard/NumberCheck.js +48 -0
- package/source/class/qx/core/check/standard/ObjectCheck.js +33 -0
- package/source/class/qx/core/check/standard/PositiveIntegerCheck.js +45 -0
- package/source/class/qx/core/check/standard/PositiveNumberCheck.js +45 -0
- package/source/class/qx/core/check/standard/PromiseCheck.js +33 -0
- package/source/class/qx/core/check/standard/RegExpCheck.js +46 -0
- package/source/class/qx/core/check/standard/StringCheck.js +43 -0
- package/source/class/qx/core/check/standard/ThemeCheck.js +33 -0
- package/source/class/qx/core/check/standard/WindowCheck.js +40 -0
- package/source/class/qx/core/property/ExplicitPropertyStorage.js +87 -0
- package/source/class/qx/core/property/GroupProperty.js +262 -0
- package/source/class/qx/core/property/IProperty.js +46 -0
- package/source/class/qx/core/property/IPropertyStorage.js +83 -0
- package/source/class/qx/core/property/ImmutableArrayStorage.js +38 -0
- package/source/class/qx/core/property/ImmutableDataArrayStorage.js +38 -0
- package/source/class/qx/core/property/ImmutableObjectStorage.js +39 -0
- package/source/class/qx/core/property/Property.js +1481 -0
- package/source/class/qx/core/property/PropertyStorageFactory.js +22 -0
- package/source/class/qx/core/property/SimplePropertyStorage.js +105 -0
- package/source/class/qx/data/Array.js +102 -57
- package/source/class/qx/data/MBinding.js +4 -29
- package/source/class/qx/data/SingleValueBinding.js +596 -1495
- package/source/class/qx/data/binding/AbstractSegment.js +197 -0
- package/source/class/qx/data/binding/ArrayIndexSegment.js +148 -0
- package/source/class/qx/data/binding/IInputReceiver.js +14 -0
- package/source/class/qx/data/binding/PropNameSegment.js +150 -0
- package/source/class/qx/data/controller/CheckedList.js +1 -1
- package/source/class/qx/data/controller/Form.js +78 -8
- package/source/class/qx/data/controller/Tree.js +27 -117
- package/source/class/qx/data/marshal/Json.js +46 -149
- package/source/class/qx/data/store/Json.js +0 -2
- package/source/class/qx/dev/Debug.js +1 -1
- package/source/class/qx/dev/LeakDetector.js +144 -0
- package/source/class/qx/dev/unit/AsyncWrapper.js +1 -0
- package/source/class/qx/dev/unit/MMock.js +7 -2
- package/source/class/qx/dev/unit/Sinon.js +0 -4
- package/source/class/qx/dev/unit/TestClass.js +2 -2
- package/source/class/qx/dev/unit/TestFunction.js +1 -0
- package/source/class/qx/dev/unit/TestLoaderBasic.js +1 -0
- package/source/class/qx/dev/unit/TestRunner.js +106 -0
- package/source/class/qx/event/IEventDispatcher.js +8 -4
- package/source/class/qx/event/Manager.js +4 -0
- package/source/class/qx/event/Messaging.js +2 -0
- package/source/class/qx/event/Pool.js +7 -0
- package/source/class/qx/event/Registration.js +33 -55
- package/source/class/qx/event/Timer.js +2 -0
- package/source/class/qx/event/Utils.js +25 -8
- package/source/class/qx/event/dispatch/AbstractBubbling.js +98 -194
- package/source/class/qx/event/dispatch/Direct.js +18 -13
- package/source/class/qx/event/handler/Appear.js +20 -24
- package/source/class/qx/event/handler/Application.js +4 -0
- package/source/class/qx/event/handler/DragDrop.js +182 -385
- package/source/class/qx/event/handler/Element.js +3 -0
- package/source/class/qx/event/handler/Focus.js +36 -30
- package/source/class/qx/event/handler/Input.js +5 -0
- package/source/class/qx/event/handler/Keyboard.js +107 -165
- package/source/class/qx/event/handler/Pointer.js +39 -68
- package/source/class/qx/event/handler/PointerCore.js +7 -25
- package/source/class/qx/event/handler/Window.js +5 -0
- package/source/class/qx/event/type/Event.js +12 -0
- package/source/class/qx/event/type/KeySequence.js +3 -0
- package/source/class/qx/event/type/Native.js +3 -0
- package/source/class/qx/html/Element.js +26 -91
- package/source/class/qx/io/jsonrpc/Client.js +1 -1
- package/source/class/qx/io/jsonrpc/protocol/Error.js +2 -2
- package/source/class/qx/io/jsonrpc/protocol/Parser.js +1 -0
- package/source/class/qx/io/jsonrpc/protocol/Result.js +2 -2
- package/source/class/qx/io/request/Xhr.js +3 -8
- package/source/class/qx/lang/normalize/Array.js +23 -1
- package/source/class/qx/locale/Date.js +520 -113
- package/source/class/qx/locale/LocalizedString.js +3 -0
- package/source/class/qx/locale/Manager.js +14 -3
- package/source/class/qx/locale/Number.js +60 -7
- package/source/class/qx/log/Logger.js +1 -1
- package/source/class/qx/module/Animation.js +2 -0
- package/source/class/qx/module/Attribute.js +2 -0
- package/source/class/qx/module/Css.js +7 -24
- package/source/class/qx/module/Event.js +2 -0
- package/source/class/qx/module/Manipulating.js +2 -0
- package/source/class/qx/module/Traversing.js +2 -0
- package/source/class/qx/test/Bootstrap.js +68 -53
- package/source/class/qx/test/Class.js +310 -2
- package/source/class/qx/test/Mixin.js +192 -42
- package/source/class/qx/test/Promise.js +129 -331
- package/source/class/qx/test/Theme.js +11 -0
- package/source/class/qx/test/bom/Font.js +2 -5
- package/source/class/qx/test/bom/Template.js +1 -1
- package/source/class/qx/test/compiler/ClassFile.js +14 -0
- package/source/class/qx/test/core/Assert.js +12 -0
- package/source/class/qx/test/core/Environment.js +17 -3
- package/source/class/qx/test/core/InheritanceDummy.js +10 -1
- package/source/class/qx/test/core/Object.js +51 -24
- package/source/class/qx/test/core/ObjectId.js +10 -1
- package/source/class/qx/test/core/Property.js +1338 -121
- package/source/class/qx/test/core/PropertyHelper.js +12 -0
- package/source/class/qx/test/core/Target.js +1 -0
- package/source/class/qx/test/core/Validation.js +2 -0
- package/source/class/qx/test/data/DataArray.js +218 -639
- package/source/class/qx/test/data/DataArrayWithChangeBubble.js +45 -215
- package/source/class/qx/test/data/MultiBinding.js +42 -0
- package/source/class/qx/test/data/async/__init__.js +4 -0
- package/source/class/qx/test/data/controller/Form.js +523 -14
- package/source/class/qx/test/data/controller/List.js +94 -426
- package/source/class/qx/test/data/controller/ListReverse.js +5 -20
- package/source/class/qx/test/data/controller/ListWithObjects.js +49 -225
- package/source/class/qx/test/data/controller/Object.js +54 -222
- package/source/class/qx/test/data/controller/Tree.js +195 -934
- package/source/class/qx/test/data/marshal/Json.js +74 -312
- package/source/class/qx/test/data/singlevalue/Array.js +55 -279
- package/source/class/qx/test/data/singlevalue/Async.js +173 -0
- package/source/class/qx/test/data/singlevalue/Deep.js +148 -327
- package/source/class/qx/test/data/singlevalue/Resolve.js +8 -28
- package/source/class/qx/test/data/singlevalue/Simple.js +124 -359
- package/source/class/qx/test/data/store/Json.js +86 -254
- package/source/class/qx/test/data/store/Jsonp.js +9 -29
- package/source/class/qx/test/data/store/Offline.js +2 -8
- package/source/class/qx/test/data/store/Rest.js +3 -3
- package/source/class/qx/test/dev/unit/Requirements.js +26 -10
- package/source/class/qx/test/event/GlobalError.js +2 -2
- package/source/class/qx/test/html/Iframe.js +1 -1
- package/source/class/qx/test/io/graphql/Client.js +2 -0
- package/source/class/qx/test/io/jsonrpc/Protocol.js +4 -2
- package/source/class/qx/test/io/request/MRequest.js +2 -8
- package/source/class/qx/test/io/request/Xhr.js +27 -117
- package/source/class/qx/test/lang/Function.js +6 -25
- package/source/class/qx/test/lang/Type.js +31 -13
- package/source/class/qx/test/locale/Date.js +173 -2
- package/source/class/qx/test/locale/Locale.js +23 -28
- package/source/class/qx/test/locale/Number.js +71 -0
- package/source/class/qx/test/log/Logger.js +7 -1
- package/source/class/qx/test/log/fixture/ClassA.js +2 -5
- package/source/class/qx/test/mobile/basic/Atom.js +3 -3
- package/source/class/qx/test/mobile/container/Scroll.js +4 -4
- package/source/class/qx/test/mobile/form/CheckBox.js +6 -12
- package/source/class/qx/test/performance/Property.js +5 -4
- package/source/class/qx/test/performance/widget/WidgetWithDecorator.js +2 -0
- package/source/class/qx/test/theme/Simple.js +34 -0
- package/source/class/qx/test/{MAppearance.js → theme/SimpleAppearance.js} +5 -4
- package/source/class/qx/test/{MDecoration.js → theme/SimpleDecoration.js} +6 -4
- package/source/class/qx/test/theme/manager/Color.js +23 -15
- package/source/class/qx/test/theme/manager/Decoration.js +23 -15
- package/source/class/qx/test/theme/manager/Font.js +23 -15
- package/source/class/qx/test/theme/manager/Icon.js +23 -15
- package/source/class/qx/test/theme/manager/Meta.js +33 -20
- package/source/class/qx/test/tool/__init__.js +3 -0
- package/source/class/qx/test/tool/cli/AbstractValue.js +274 -0
- package/source/class/qx/test/tool/cli/Argument.js +384 -0
- package/source/class/qx/test/tool/cli/Command.js +387 -0
- package/source/class/qx/test/tool/cli/Flag.js +413 -0
- package/source/class/qx/test/tool/cli/__init__.js +3 -0
- package/source/class/qx/test/ui/LayoutTestCase.js +1 -14
- package/source/class/qx/test/ui/basic/Label.js +106 -0
- package/source/class/qx/test/ui/core/Blocker.js +125 -3
- package/source/class/qx/test/ui/form/Form.js +106 -0
- package/source/class/qx/test/ui/form/FormManager.js +6 -5
- package/source/class/qx/test/ui/form/SplitButton.js +1 -1
- package/source/class/qx/test/ui/toolbar/OverflowHandling.js +13 -14
- package/source/class/qx/test/ui/toolbar/ToolBar.js +16 -16
- package/source/class/qx/test/ui/tree/TreeFolder.js +5 -7
- package/source/class/qx/test/ui/tree/virtual/AbstractTreeTest.js +2 -0
- package/source/class/qx/test/ui/tree/virtual/Tree.js +36 -0
- package/source/class/qx/test/util/DateFormat.js +1 -1
- package/source/class/qx/test/util/PropertyUtil.js +0 -36
- package/source/class/qx/theme/classic/Appearance.js +1 -1
- package/source/class/qx/theme/indigo/ColorDark.js +2 -0
- package/source/class/qx/theme/manager/Font.js +6 -1
- package/source/class/qx/theme/manager/Meta.js +2 -1
- package/source/class/qx/theme/simple/Appearance.js +31 -95
- package/source/class/qx/theme/simple/Decoration.js +0 -1
- package/source/class/qx/theme/tangible/Appearance.js +1 -1
- package/source/class/qx/tool/cli/AbstractCliApp.js +72 -0
- package/source/class/qx/tool/cli/AbstractValue.js +186 -0
- package/source/class/qx/tool/cli/Argument.js +155 -0
- package/source/class/qx/tool/cli/Command.js +518 -0
- package/source/class/qx/tool/cli/Flag.js +202 -0
- package/source/class/qx/tool/cli/Parser.js +39 -0
- package/source/class/qx/tool/cli/__init__.js +26 -1
- package/source/class/qx/tool/compiler/Analyser.js +41 -13
- package/source/class/qx/tool/compiler/ClassFile.js +37 -9
- package/source/class/qx/tool/compiler/Console.js +2 -0
- package/source/class/qx/tool/compiler/MetaExtraction.js +53 -33
- package/source/class/qx/tool/compiler/app/Library.js +1 -1
- package/source/class/qx/tool/compiler/app/WebFont.js +2 -0
- package/source/class/qx/tool/compiler/cli/Application.js +58 -0
- package/source/class/qx/tool/{cli/commands → compiler/cli}/Command.js +99 -45
- package/source/class/qx/tool/{cli → compiler/cli}/ConfigDb.js +7 -7
- package/source/class/qx/tool/compiler/cli/ConfigLoader.js +272 -0
- package/source/class/qx/tool/{cli → compiler/cli}/LibraryApplication.js +3 -3
- package/source/class/qx/tool/compiler/cli/RootCommand.js +63 -0
- package/source/class/qx/tool/{cli → compiler/cli}/Watch.js +49 -24
- package/source/class/qx/tool/compiler/cli/__init__.js +3 -0
- package/source/class/qx/tool/{cli → compiler/cli}/api/AbstractApi.js +2 -11
- package/source/class/qx/tool/{cli → compiler/cli}/api/CompilerApi.js +11 -10
- package/source/class/qx/tool/{cli → compiler/cli}/api/LibraryApi.js +13 -4
- package/source/class/qx/tool/{cli → compiler/cli}/api/Test.js +1 -1
- package/source/class/qx/tool/compiler/cli/commands/Add.js +49 -0
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Clean.js +12 -25
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Compile.js +524 -615
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Config.js +22 -20
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Create.js +77 -54
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Deploy.js +45 -60
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Es6ify.js +57 -41
- package/source/class/qx/tool/{cli → compiler/cli}/commands/ExportGlyphs.js +26 -7
- package/source/class/qx/tool/compiler/cli/commands/Lint.js +420 -0
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Migrate.js +40 -20
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Package.js +20 -32
- package/source/class/qx/tool/compiler/cli/commands/Pkg.js +36 -0
- package/source/class/qx/tool/compiler/cli/commands/Prettier.js +278 -0
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Run.js +43 -39
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Serve.js +63 -61
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Test.js +49 -52
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Typescript.js +51 -30
- package/source/class/qx/tool/{cli → compiler/cli}/commands/add/Class.js +54 -31
- package/source/class/qx/tool/{cli → compiler/cli}/commands/add/Script.js +56 -32
- package/source/class/qx/tool/{cli → compiler/cli}/commands/config/Delete.js +19 -13
- package/source/class/qx/tool/{cli → compiler/cli}/commands/config/Get.js +19 -13
- package/source/class/qx/tool/{cli → compiler/cli}/commands/config/List.js +20 -20
- package/source/class/qx/tool/{cli → compiler/cli}/commands/config/Set.js +28 -20
- package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Install.js +140 -75
- package/source/class/qx/tool/{cli → compiler/cli}/commands/package/List.js +119 -80
- package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Publish.js +194 -178
- package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Remove.js +18 -21
- package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Update.js +90 -69
- package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Upgrade.js +67 -54
- package/source/class/qx/tool/compiler/makers/AbstractAppMaker.js +2 -1
- package/source/class/qx/tool/compiler/resources/Manager.js +2 -0
- package/source/class/qx/tool/compiler/resources/ScssConverter.js +1 -1
- package/source/class/qx/tool/compiler/resources/ScssFile.js +1 -1
- package/source/class/qx/tool/compiler/targets/Target.js +5 -10
- package/source/class/qx/tool/compiler/targets/TypeScriptWriter.js +6 -2
- package/source/class/qx/tool/compiler/targets/meta/ApplicationMeta.js +2 -4
- package/source/class/qx/tool/compiler/targets/meta/BootJs.js +2 -0
- package/source/class/qx/tool/compiler/targets/meta/PackageJavascript.js +2 -0
- package/source/class/qx/tool/config/Abstract.js +5 -5
- package/source/class/qx/tool/config/Lockfile.js +1 -1
- package/source/class/qx/tool/migration/BaseMigration.js +9 -7
- package/source/class/qx/tool/migration/M6_0_0.js +3 -3
- package/source/class/qx/tool/migration/M8_0_0.js +958 -0
- package/source/class/qx/tool/utils/Debounce.js +0 -1
- package/source/class/qx/tool/utils/Http.js +109 -21
- package/source/class/qx/tool/utils/LogManager.js +7 -0
- package/source/class/qx/tool/utils/Promisify.js +12 -1
- package/source/class/qx/tool/utils/QooxdooVersions.js +193 -0
- package/source/class/qx/tool/utils/Utils.js +8 -5
- package/source/class/qx/tool/utils/Website.js +9 -222
- package/source/class/qx/tool/utils/Zip.js +47 -0
- package/source/class/qx/tool/utils/files/Utils.js +3 -11
- package/source/class/qx/tool/utils/json/Tokenizer.js +5 -0
- package/source/class/qx/ui/basic/Atom.js +8 -8
- package/source/class/qx/ui/core/Blocker.js +17 -4
- package/source/class/qx/ui/core/DragDropCursor.js +2 -1
- package/source/class/qx/ui/core/EventHandler.js +13 -21
- package/source/class/qx/ui/core/LayoutItem.js +8 -31
- package/source/class/qx/ui/core/MExecutable.js +21 -43
- package/source/class/qx/ui/core/MNativeOverflow.js +4 -2
- package/source/class/qx/ui/core/Widget.js +50 -165
- package/source/class/qx/ui/core/scroll/IScrollBar.js +9 -3
- package/source/class/qx/ui/core/scroll/ScrollBar.js +7 -1
- package/source/class/qx/ui/core/scroll/ScrollPane.js +12 -4
- package/source/class/qx/ui/embed/Html.js +6 -2
- package/source/class/qx/ui/form/AbstractField.js +4 -12
- package/source/class/qx/ui/form/Button.js +6 -4
- package/source/class/qx/ui/form/CheckedSelectBox.js +8 -8
- package/source/class/qx/ui/form/FileSelectorButton.js +1 -1
- package/source/class/qx/ui/form/Form.js +3 -0
- package/source/class/qx/ui/form/IListItem.js +3 -1
- package/source/class/qx/ui/form/IRadioItem.js +3 -1
- package/source/class/qx/ui/form/MForm.js +3 -1
- package/source/class/qx/ui/form/Slider.js +6 -2
- package/source/class/qx/ui/form/SplitButton.js +5 -5
- package/source/class/qx/ui/form/TextField.js +1 -2
- package/source/class/qx/ui/form/validation/Manager.js +6 -2
- package/source/class/qx/ui/menubar/Button.js +1 -1
- package/source/class/qx/ui/mobile/basic/Atom.js +5 -5
- package/source/class/qx/ui/mobile/dialog/Menu.js +9 -31
- package/source/class/qx/ui/mobile/dialog/Popup.js +13 -1
- package/source/class/qx/ui/table/pane/FocusIndicator.js +5 -2
- package/source/class/qx/ui/table/pane/Scroller.js +11 -28
- package/source/class/qx/ui/table/selection/Model.js +1 -0
- package/source/class/qx/ui/toolbar/Button.js +1 -1
- package/source/class/qx/ui/toolbar/CheckBox.js +1 -1
- package/source/class/qx/ui/toolbar/FileSelectorButton.js +1 -2
- package/source/class/qx/ui/toolbar/Part.js +2 -2
- package/source/class/qx/ui/toolbar/PartContainer.js +2 -2
- package/source/class/qx/ui/toolbar/ToolBar.js +24 -49
- package/source/class/qx/ui/tree/VirtualTree.js +6 -4
- package/source/class/qx/ui/tree/core/AbstractItem.js +10 -17
- package/source/class/qx/ui/tree/core/IVirtualTree.js +4 -2
- package/source/class/qx/ui/tree/provider/IVirtualTreeProvider.js +20 -10
- package/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js +4 -1
- package/source/class/qx/ui/virtual/cell/Cell.js +20 -48
- package/source/class/qx/ui/virtual/cell/WidgetCell.js +2 -4
- package/source/class/qx/ui/virtual/core/Axis.js +4 -0
- package/source/class/qx/ui/virtual/core/ILayer.js +14 -10
- package/source/class/qx/ui/virtual/core/Scroller.js +4 -4
- package/source/class/qx/ui/virtual/layer/WidgetCell.js +4 -0
- package/source/class/qx/ui/virtual/selection/Abstract.js +3 -0
- package/source/class/qx/ui/virtual/selection/MModel.js +1 -1
- package/source/class/qx/ui/window/IDesktop.js +6 -2
- package/source/class/qx/ui/window/IWindowManager.js +10 -4
- package/source/class/qx/ui/window/MDesktop.js +2 -1
- package/source/class/qx/ui/window/Manager.js +1 -1
- package/source/class/qx/ui/window/Window.js +6 -4
- package/source/class/qx/util/OOUtil.js +8 -9
- package/source/class/qx/util/PropertyUtil.js +34 -154
- package/source/class/qx/util/ResponseParser.js +2 -0
- package/source/class/qx/util/Serializer.js +69 -114
- package/source/class/qx/util/format/DateFormat.js +3 -2
- package/source/global.d.ts +4 -0
- package/source/resource/qx/tool/bin/download-assets +0 -2
- package/source/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-node.tmpl.js +1 -0
- package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/cli/templates/template_vars.js +12 -9
- package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/schema/Manifest-1-0-0.json +2 -2
- package/source/resource/qx/tool/{schema → compiler/schema}/Manifest-2-0-0.json +2 -2
- package/source/resource/qx/tool/{schema → compiler/schema}/compile-1-0-0.json +15 -3
- package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/schema/qooxdoo-1-0-0.json +1 -1
- package/source/resource/qx/tool/website/build/404.html +22 -22
- package/source/resource/qx/tool/website/build/about.html +23 -23
- package/source/resource/qx/tool/website/build/assets/common.js +30 -18
- package/source/resource/qx/tool/website/build/assets/custom.css +290 -0
- package/source/resource/qx/tool/website/build/assets/qxWeb.js +28 -0
- package/source/resource/qx/tool/website/build/diagnostics/dependson.html +30 -30
- package/source/resource/qx/tool/website/build/diagnostics/dependson.js +49 -40
- package/source/resource/qx/tool/website/build/diagnostics/requiredby.html +20 -23
- package/source/resource/qx/tool/website/build/diagnostics/requiredby.js +38 -31
- package/source/resource/qx/tool/website/build/index.html +24 -24
- package/source/resource/qx/tool/website/build/scripts/serve.js +63 -65
- package/source/resource/qx/tool/website/partials/footer.html +8 -13
- package/source/resource/qx/tool/website/partials/head.html +9 -7
- package/source/resource/qx/tool/website/partials/header.html +3 -3
- package/source/resource/qx/tool/website/src/assets/common.js +32 -0
- package/source/resource/qx/tool/website/src/assets/custom.css +290 -0
- package/source/resource/qx/tool/website/src/assets/qxWeb.js +28 -0
- package/source/resource/qx/tool/website/src/diagnostics/dependson.js +49 -40
- package/source/resource/qx/tool/website/src/diagnostics/requiredby.js +38 -31
- package/source/resource/qx/tool/website/src/index.html +2 -2
- package/source/resource/qx/tool/website/src/scripts/serve.js +63 -65
- package/lib/resource/qx/tool/bin/build-devtools +0 -13
- package/lib/resource/qx/tool/bin/build-website +0 -15
- package/lib/resource/qx/tool/bin/download-assets +0 -23
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +0 -1
- package/lib/resource/qx/tool/website/build/assets/bootstrap.css +0 -7
- package/lib/resource/qx/tool/website/build/assets/bootstrap.min.css +0 -7
- package/lib/resource/qx/tool/website/build/assets/bootstrap.min.css.map +0 -1
- package/lib/resource/qx/tool/website/build/assets/jquery.js +0 -5453
- package/lib/resource/qx/tool/website/build/qooxdoo.css +0 -21
- package/lib/resource/qx/tool/website/sass/qooxdoo.css +0 -3
- package/lib/resource/qx/tool/website/sass/qooxdoo.css.map +0 -1
- package/lib/resource/qx/tool/website/src/assets/bootstrap.css +0 -7
- package/lib/resource/qx/tool/website/src/assets/bootstrap.min.css +0 -7
- package/lib/resource/qx/tool/website/src/assets/bootstrap.min.css.map +0 -1
- package/lib/resource/qx/tool/website/src/assets/jquery.js +0 -5453
- package/source/class/qx/core/Property.js +0 -2100
- package/source/class/qx/tool/cli/Application.js +0 -47
- package/source/class/qx/tool/cli/Cli.js +0 -713
- package/source/class/qx/tool/cli/commands/Add.js +0 -46
- package/source/class/qx/tool/cli/commands/Lint.js +0 -255
- package/source/class/qx/tool/cli/commands/Pkg.js +0 -56
- package/source/class/qx/tool/cli/commands/package/Migrate.js +0 -37
- package/source/class/qx/tool/compiler/app/Cldr.js +0 -725
- package/source/resource/qx/tool/bin/build-devtools +0 -13
- package/source/resource/qx/tool/bin/build-website +0 -15
- package/source/resource/qx/tool/website/build/assets/bootstrap.css +0 -7
- package/source/resource/qx/tool/website/build/assets/bootstrap.min.css +0 -7
- package/source/resource/qx/tool/website/build/assets/bootstrap.min.css.map +0 -1
- package/source/resource/qx/tool/website/build/assets/jquery.js +0 -5453
- package/source/resource/qx/tool/website/build/qooxdoo.css +0 -21
- package/source/resource/qx/tool/website/sass/qooxdoo.scss +0 -31
- package/source/resource/qx/tool/website/src/assets/bootstrap.css +0 -7
- package/source/resource/qx/tool/website/src/assets/bootstrap.min.css +0 -7
- package/source/resource/qx/tool/website/src/assets/bootstrap.min.css.map +0 -1
- package/source/resource/qx/tool/website/src/assets/jquery.js +0 -5453
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/TypeScriptWriter-base_declaration.d.ts +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/default.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/header.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/interface.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/mixin.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/singleton.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-browser.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-rhino.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/.gitignore.tmpl +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/Manifest.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/compile.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/readme.tmpl.md +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/index.tmpl.html +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/nojs.tmpl.html +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/Application.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/__init__.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/test/DemoTest.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Appearance.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Color.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Decoration.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Font.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Theme.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/app.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/favicon.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/js_256x256.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/test.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/translation/readme.txt +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/.gitignore.tmpl +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/Manifest.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/compile.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/readme.tmpl.md +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/index.tmpl.html +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/nojs.tmpl.html +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/Application.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/__init__.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Login.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Overview.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/__init__.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/app.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/css/.gitignore.tmpl +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/favicon.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/js_256x256.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/theme/custom/css/custom.css +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/translation/readme.txt +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/.gitignore.tmpl +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/Manifest.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/compile.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/readme.tmpl.md +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/Button.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/__init__.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/demo/Application.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/resource/custom/test.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/test/DemoTest.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Appearance.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Color.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Decoration.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Font.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Theme.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/resource/custom/test.png +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/translation/readme.txt +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/.gitignore.tmpl +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/Manifest.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/compile.tmpl.json +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/readme.tmpl.txt +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/Application.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/__init__.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/test/DemoTest.tmpl.js +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/resource/custom/.gitignore.tmpl +0 -0
- /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/translation/readme.txt +0 -0
- /package/lib/resource/qx/tool/{loadsass.js → compiler/loadsass.js} +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/TypeScriptWriter-base_declaration.d.ts +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/default.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/header.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/interface.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/mixin.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/singleton.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-browser.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-rhino.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/.gitignore.tmpl +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/Manifest.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/compile.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/readme.tmpl.md +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/index.tmpl.html +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/nojs.tmpl.html +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/Application.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/__init__.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/test/DemoTest.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Appearance.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Color.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Decoration.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Font.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Theme.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/app.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/favicon.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/js_256x256.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/test.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/translation/readme.txt +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/.gitignore.tmpl +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/Manifest.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/compile.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/readme.tmpl.md +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/index.tmpl.html +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/nojs.tmpl.html +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/Application.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/__init__.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Login.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Overview.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/__init__.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/app.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/css/.gitignore.tmpl +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/favicon.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/js_256x256.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/theme/custom/scss/_styles.scss +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/theme/custom/scss/custom.scss +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/translation/readme.txt +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/.gitignore.tmpl +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/Manifest.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/compile.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/readme.tmpl.md +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/Button.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/__init__.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/demo/Application.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/resource/custom/test.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/test/DemoTest.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Appearance.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Color.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Decoration.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Font.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Theme.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/resource/custom/test.png +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/translation/readme.txt +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/.gitignore.tmpl +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/Manifest.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/compile.tmpl.json +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/readme.tmpl.txt +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/Application.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/__init__.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/test/DemoTest.tmpl.js +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/resource/custom/.gitignore.tmpl +0 -0
- /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/translation/readme.txt +0 -0
- /package/source/resource/qx/tool/{loadsass.js → compiler/loadsass.js} +0 -0
|
@@ -5,1547 +5,639 @@
|
|
|
5
5
|
http://qooxdoo.org
|
|
6
6
|
|
|
7
7
|
Copyright:
|
|
8
|
-
|
|
8
|
+
2022-2023 Zenesis Limited, https://www.zenesis.com
|
|
9
9
|
|
|
10
10
|
License:
|
|
11
11
|
MIT: https://opensource.org/licenses/MIT
|
|
12
12
|
See the LICENSE file in the project's top-level directory for details.
|
|
13
13
|
|
|
14
14
|
Authors:
|
|
15
|
-
*
|
|
15
|
+
* John Spackman (https://github.com/johnspackman, john.spackman@zenesis.com)
|
|
16
|
+
* Patryk Malinowski (https://github.com/patryk-m-malinowski, pmalinowski@vmn.digital)
|
|
16
17
|
|
|
17
18
|
************************************************************************ */
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
+
* This class implements bindings as a first class object.
|
|
22
|
+
*
|
|
23
|
+
* The Binding has a source, a value, and optional target; the source (and
|
|
24
|
+
* sourcePath) is read and copied into value; the value is copied into the target
|
|
25
|
+
* if there is one.
|
|
26
|
+
*
|
|
27
|
+
* If the sourcePath is null, then the value will be the source object; if the
|
|
28
|
+
* target or the targetPath is null, then the `value` will still update but will
|
|
29
|
+
* not be copied anywhere
|
|
30
|
+
*
|
|
31
|
+
* Arrays are supported by including `[]` in paths, eg `children[2]`, although this
|
|
32
|
+
* only works with `sourcePath` and not in `targetPath`. Arrays can be native or
|
|
33
|
+
* `qx.data.Array`, but changes to native arrays will not be detected because they
|
|
34
|
+
* dont fire events
|
|
35
|
+
*
|
|
36
|
+
* @typedef {[qx.data.SingleValueBinding, qx.core.Object, string, qx.core.Object, string]} BindingRecord Array representation of the binding,
|
|
37
|
+
* containing the binding, source object, source path, target object and target path respectively.
|
|
21
38
|
*/
|
|
22
39
|
qx.Class.define("qx.data.SingleValueBinding", {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
extend: qx.core.Object,
|
|
41
|
+
implement: [qx.data.binding.IInputReceiver],
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The class is responsible for binding a source objects property to
|
|
45
|
+
* a target objects property. Both properties have to have the usual qooxdoo
|
|
46
|
+
* getter and setter. The source property also needs to fire change-events
|
|
47
|
+
* on every change of its value.
|
|
48
|
+
* Please keep in mind, that this binding is unidirectional. If you need
|
|
49
|
+
* a binding in both directions, you have to use two of this bindings.
|
|
50
|
+
*
|
|
51
|
+
* It's also possible to bind some kind of a hierarchy as a source. This
|
|
52
|
+
* means that you can separate the source properties with a dot and bind
|
|
53
|
+
* by that the object referenced to this property chain.
|
|
54
|
+
* Example with an object 'a' which has object 'b' stored in its 'child'
|
|
55
|
+
* property. Object b has a string property named abc:
|
|
56
|
+
* <pre><code>
|
|
57
|
+
* qx.data.SingleValueBinding.bind(a, "child.abc", textfield, "value");
|
|
58
|
+
* </code></pre>
|
|
59
|
+
* In that case, if the property abc of b changes, the textfield will
|
|
60
|
+
* automatically contain the new value. Also if the child of a changes, the
|
|
61
|
+
* new value (abc of the new child) will be in the textfield.
|
|
62
|
+
*
|
|
63
|
+
* There is also a possibility of binding an array. Therefore the array
|
|
64
|
+
* {@link qx.data.IListData} is needed because this array has change events
|
|
65
|
+
* which the native does not. Imagine a qooxdoo object a which has a
|
|
66
|
+
* children property containing an array holding more of its own kind.
|
|
67
|
+
* Every object has a name property as a string.
|
|
68
|
+
* <pre>
|
|
69
|
+
* var svb = qx.data.SingleValueBinding;
|
|
70
|
+
* // bind the first child's name of 'a' to a textfield
|
|
71
|
+
* svb.bind(a, "children[0].name", textfield, "value");
|
|
72
|
+
* // bind the last child's name of 'a' to a textfield
|
|
73
|
+
* svb.bind(a, "children[last].name", textfield2, "value");
|
|
74
|
+
* // also deeper bindings are possible
|
|
75
|
+
* svb.bind(a, "children[0].children[0].name", textfield3, "value");
|
|
76
|
+
* </pre>
|
|
77
|
+
*
|
|
78
|
+
* As you can see in this example, the abc property of a's b will be bound
|
|
79
|
+
* to the textfield. If now the value of b changed or even the a will get a
|
|
80
|
+
* new b, the binding still shows the right value.
|
|
81
|
+
*
|
|
82
|
+
* @param {qx.core.Object?} sourceObject The source of the binding.
|
|
83
|
+
* @param {String} sourcePropertyChain The property chain which represents
|
|
84
|
+
* the source property.
|
|
85
|
+
* @param {qx.core.Object?} targetObject The object which the source should
|
|
86
|
+
* be bound to.
|
|
87
|
+
* @param {String} targetPropertyChain The property chain to the target
|
|
88
|
+
* object.
|
|
89
|
+
* @param {BindingOptions} options A map containing the options.
|
|
90
|
+
*
|
|
91
|
+
* @typedef BindingOptions
|
|
92
|
+
* @property {converter} converter Data converter function. If no conversion has been done, the given value should be returned.
|
|
93
|
+
* e.g. a number to boolean converter
|
|
94
|
+
* <code>function(data, model, source, target) {return data > 100;}</code>
|
|
95
|
+
* @property {onUpdate} onUpdate This callback will be called if the binding was updated successfully.
|
|
96
|
+
* @property {() => void} onSetFail A callback function can be given here. This function will
|
|
97
|
+
* be called if the set of the value fails.
|
|
98
|
+
* @property {string} ignoreConverter A string which will be matched using the current
|
|
99
|
+
* property chain. If it matches, the converter will not be called.
|
|
100
|
+
*
|
|
101
|
+
*
|
|
102
|
+
* @callback converter
|
|
103
|
+
* @param {*} data The data to convert
|
|
104
|
+
* @param {*} model The corresponding model object, which is only set in case of the use of an controller.
|
|
105
|
+
* @param {qx.core.Object} source The source object for the binding
|
|
106
|
+
* @param {qx.core.Object} target The target object
|
|
107
|
+
* @returns {*} The converted data
|
|
108
|
+
*
|
|
109
|
+
* @callback onUpdate
|
|
110
|
+
* @param {qx.core.Object} source The source object for the binding
|
|
111
|
+
* @param {qx.core.Object} target The target object
|
|
112
|
+
* @param {*} data The data
|
|
113
|
+
|
|
114
|
+
*
|
|
115
|
+
* @returns {qx.data.SingleValueBinding} Returns the internal id for that binding. This can be used
|
|
116
|
+
* for referencing the binding or e.g. for removing. This is not an atomic
|
|
117
|
+
* id so you can't you use it as a hash-map index.
|
|
118
|
+
*
|
|
119
|
+
* @throws {qx.core.AssertionError} If the event is no data event or
|
|
120
|
+
* there is no property definition for object and property (source and
|
|
121
|
+
* target).
|
|
122
|
+
*/
|
|
123
|
+
construct(sourcePath, targetPath, source, target, options) {
|
|
124
|
+
super();
|
|
125
|
+
if (!(sourcePath || targetPath)) {
|
|
126
|
+
throw new Error("SourcePath and targetPath must be specified");
|
|
127
|
+
}
|
|
128
|
+
this.__options = options ?? {};
|
|
129
|
+
let tracker = {};
|
|
130
|
+
|
|
131
|
+
const Utils = qx.event.Utils;
|
|
132
|
+
this.setSourcePath(sourcePath);
|
|
133
|
+
this.setTargetPath(targetPath);
|
|
134
|
+
Utils.then(tracker, () => source && this.setSource(source));
|
|
135
|
+
Utils.then(tracker, () => target && this.setTarget(target));
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
destruct() {
|
|
139
|
+
if (this.__sourceSegments) {
|
|
140
|
+
this.__sourceSegments.forEach(segment => segment.dispose());
|
|
141
|
+
this.__sourceSegments = null;
|
|
142
|
+
}
|
|
143
|
+
if (this.__targetSegments) {
|
|
144
|
+
this.__targetSegments.forEach(segment => segment.dispose());
|
|
145
|
+
this.__targetSegments = null;
|
|
146
|
+
}
|
|
147
|
+
this.setSource(null);
|
|
148
|
+
this.setTarget(null);
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
properties: {
|
|
152
|
+
/** The path into the `source` object */
|
|
153
|
+
sourcePath: {
|
|
154
|
+
init: null,
|
|
155
|
+
nullable: true,
|
|
156
|
+
check: "String",
|
|
157
|
+
event: "changeSourcePath",
|
|
158
|
+
apply: "_applySourcePath"
|
|
159
|
+
},
|
|
26
160
|
|
|
27
|
-
/**
|
|
28
|
-
|
|
161
|
+
/** The path into the `target` object */
|
|
162
|
+
targetPath: {
|
|
163
|
+
init: null,
|
|
164
|
+
nullable: true,
|
|
165
|
+
check: "String",
|
|
166
|
+
event: "changeTargetPath",
|
|
167
|
+
apply: "_applyTargetPath"
|
|
168
|
+
}
|
|
169
|
+
},
|
|
29
170
|
|
|
171
|
+
members: {
|
|
30
172
|
/**
|
|
31
|
-
*
|
|
32
|
-
* a target objects property. Both properties have to have the usual qooxdoo
|
|
33
|
-
* getter and setter. The source property also needs to fire change-events
|
|
34
|
-
* on every change of its value.
|
|
35
|
-
* Please keep in mind, that this binding is unidirectional. If you need
|
|
36
|
-
* a binding in both directions, you have to use two of this bindings.
|
|
37
|
-
*
|
|
38
|
-
* It's also possible to bind some kind of a hierarchy as a source. This
|
|
39
|
-
* means that you can separate the source properties with a dot and bind
|
|
40
|
-
* by that the object referenced to this property chain.
|
|
41
|
-
* Example with an object 'a' which has object 'b' stored in its 'child'
|
|
42
|
-
* property. Object b has a string property named abc:
|
|
43
|
-
* <pre><code>
|
|
44
|
-
* qx.data.SingleValueBinding.bind(a, "child.abc", textfield, "value");
|
|
45
|
-
* </code></pre>
|
|
46
|
-
* In that case, if the property abc of b changes, the textfield will
|
|
47
|
-
* automatically contain the new value. Also if the child of a changes, the
|
|
48
|
-
* new value (abc of the new child) will be in the textfield.
|
|
49
|
-
*
|
|
50
|
-
* There is also a possibility of binding an array. Therefore the array
|
|
51
|
-
* {@link qx.data.IListData} is needed because this array has change events
|
|
52
|
-
* which the native does not. Imagine a qooxdoo object a which has a
|
|
53
|
-
* children property containing an array holding more of its own kind.
|
|
54
|
-
* Every object has a name property as a string.
|
|
55
|
-
* <pre>
|
|
56
|
-
* var svb = qx.data.SingleValueBinding;
|
|
57
|
-
* // bind the first child's name of 'a' to a textfield
|
|
58
|
-
* svb.bind(a, "children[0].name", textfield, "value");
|
|
59
|
-
* // bind the last child's name of 'a' to a textfield
|
|
60
|
-
* svb.bind(a, "children[last].name", textfield2, "value");
|
|
61
|
-
* // also deeper bindings are possible
|
|
62
|
-
* svb.bind(a, "children[0].children[0].name", textfield3, "value");
|
|
63
|
-
* </pre>
|
|
64
|
-
*
|
|
65
|
-
* As you can see in this example, the abc property of a's b will be bound
|
|
66
|
-
* to the textfield. If now the value of b changed or even the a will get a
|
|
67
|
-
* new b, the binding still shows the right value.
|
|
68
|
-
*
|
|
69
|
-
* @param sourceObject {qx.core.Object} The source of the binding.
|
|
70
|
-
* @param sourcePropertyChain {String} The property chain which represents
|
|
71
|
-
* the source property.
|
|
72
|
-
* @param targetObject {qx.core.Object} The object which the source should
|
|
73
|
-
* be bind to.
|
|
74
|
-
* @param targetPropertyChain {String} The property chain to the target
|
|
75
|
-
* object.
|
|
76
|
-
* @param options {Map?null} A map containing the options.
|
|
77
|
-
* <li>converter: A converter function which takes four parameters
|
|
78
|
-
* and should return the converted value.
|
|
79
|
-
* <ol>
|
|
80
|
-
* <li>The data to convert</li>
|
|
81
|
-
* <li>The corresponding model object, which is only set in case of the use of an controller.</li>
|
|
82
|
-
* <li>The source object for the binding</li>
|
|
83
|
-
* <li>The target object.</li>
|
|
84
|
-
* </ol>
|
|
85
|
-
* If no conversion has been done, the given value should be returned.
|
|
86
|
-
* e.g. a number to boolean converter
|
|
87
|
-
* <code>function(data, model, source, target) {return data > 100;}</code>
|
|
88
|
-
* </li>
|
|
89
|
-
* <li>onUpdate: A callback function can be given here. This method will be
|
|
90
|
-
* called if the binding was updated successful. There will be
|
|
91
|
-
* three parameter you do get in that method call.
|
|
92
|
-
* <ol>
|
|
93
|
-
* <li>The source object</li>
|
|
94
|
-
* <li>The target object</li>
|
|
95
|
-
* <li>The data</li>
|
|
96
|
-
* </ol>
|
|
97
|
-
* Here is a sample: <code>onUpdate : function(source, target, data) {...}</code>
|
|
98
|
-
* </li>
|
|
99
|
-
* <li>onSetFail: A callback function can be given here. This method will
|
|
100
|
-
* be called if the set of the value fails.
|
|
101
|
-
* </li>
|
|
102
|
-
* <li>ignoreConverter: A string which will be matched using the current
|
|
103
|
-
* property chain. If it matches, the converter will not be called.
|
|
104
|
-
* </li>
|
|
105
|
-
*
|
|
106
|
-
* @return {var} Returns the internal id for that binding. This can be used
|
|
107
|
-
* for referencing the binding or e.g. for removing. This is not an atomic
|
|
108
|
-
* id so you can't you use it as a hash-map index.
|
|
109
|
-
*
|
|
110
|
-
* @throws {qx.core.AssertionError} If the event is no data event or
|
|
111
|
-
* there is no property definition for object and property (source and
|
|
112
|
-
* target).
|
|
173
|
+
* @type {*}
|
|
113
174
|
*/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
options
|
|
120
|
-
) {
|
|
121
|
-
// check for the arguments
|
|
122
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
123
|
-
qx.core.Assert.assertObject(sourceObject, "sourceObject");
|
|
124
|
-
qx.core.Assert.assertString(sourcePropertyChain, "sourcePropertyChain");
|
|
125
|
-
qx.core.Assert.assertObject(targetObject, "targetObject");
|
|
126
|
-
qx.core.Assert.assertString(targetPropertyChain, "targetPropertyChain");
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// set up the target binding
|
|
130
|
-
var targetListenerMap = this.__setUpTargetBinding(
|
|
131
|
-
sourceObject,
|
|
132
|
-
sourcePropertyChain,
|
|
133
|
-
targetObject,
|
|
134
|
-
targetPropertyChain,
|
|
135
|
-
options
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
// get the property names
|
|
139
|
-
var propertyNames = sourcePropertyChain.split(".");
|
|
140
|
-
|
|
141
|
-
// stuff that's needed to store for the listener function
|
|
142
|
-
var arrayIndexValues = this.__checkForArrayInPropertyChain(propertyNames);
|
|
143
|
-
var sources = [];
|
|
144
|
-
var listeners = [];
|
|
145
|
-
var listenerIds = [];
|
|
146
|
-
var eventNames = [];
|
|
147
|
-
var source = sourceObject;
|
|
148
|
-
var initialPromise = null;
|
|
149
|
-
|
|
150
|
-
// add a try catch to make it possible to remove the listeners of the
|
|
151
|
-
// chain in case the loop breaks after some listeners already added.
|
|
152
|
-
try {
|
|
153
|
-
// go through all property names
|
|
154
|
-
for (var i = 0; i < propertyNames.length; i++) {
|
|
155
|
-
var propertyName = propertyNames[i];
|
|
156
|
-
|
|
157
|
-
// check for the array
|
|
158
|
-
if (arrayIndexValues[i] !== "") {
|
|
159
|
-
// push the array change event
|
|
160
|
-
eventNames.push("change");
|
|
161
|
-
} else {
|
|
162
|
-
var eventName = this.__getEventNameForProperty(
|
|
163
|
-
source,
|
|
164
|
-
propertyName
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
if (!eventName) {
|
|
168
|
-
if (i == 0) {
|
|
169
|
-
// the root property can not change --> error
|
|
170
|
-
throw new qx.core.AssertionError(
|
|
171
|
-
"Binding property " +
|
|
172
|
-
propertyName +
|
|
173
|
-
" of object " +
|
|
174
|
-
source +
|
|
175
|
-
" not possible: No event available. Full property chain: " +
|
|
176
|
-
sourcePropertyChain
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (
|
|
181
|
-
source instanceof qx.core.Object &&
|
|
182
|
-
qx.Class.hasProperty(source.constructor, propertyName)
|
|
183
|
-
) {
|
|
184
|
-
qx.log.Logger.warn(
|
|
185
|
-
"Binding property " +
|
|
186
|
-
propertyName +
|
|
187
|
-
" of object " +
|
|
188
|
-
source +
|
|
189
|
-
" not possible: No event available. Full property chain: " +
|
|
190
|
-
sourcePropertyChain
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// call the converter if no event could be found on binding creation
|
|
195
|
-
initialPromise = this.__setInitialValue(
|
|
196
|
-
undefined,
|
|
197
|
-
targetObject,
|
|
198
|
-
targetPropertyChain,
|
|
199
|
-
options,
|
|
200
|
-
sourceObject
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
eventNames.push(eventName);
|
|
206
|
-
}
|
|
175
|
+
__value: null,
|
|
176
|
+
/**
|
|
177
|
+
* @type {qx.core.Object}
|
|
178
|
+
*/
|
|
179
|
+
__source: null,
|
|
207
180
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (i == propertyNames.length - 1) {
|
|
213
|
-
// if it is an array, set the initial value and bind the event
|
|
214
|
-
if (arrayIndexValues[i] !== "") {
|
|
215
|
-
// get the current value
|
|
216
|
-
var itemIndex =
|
|
217
|
-
arrayIndexValues[i] === "last"
|
|
218
|
-
? source.length - 1
|
|
219
|
-
: arrayIndexValues[i];
|
|
220
|
-
var currentValue = source.getItem(itemIndex);
|
|
221
|
-
|
|
222
|
-
// set the initial value
|
|
223
|
-
initialPromise = this.__setInitialValue(
|
|
224
|
-
currentValue,
|
|
225
|
-
targetObject,
|
|
226
|
-
targetPropertyChain,
|
|
227
|
-
options,
|
|
228
|
-
sourceObject
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
// bind the event
|
|
232
|
-
listenerIds[i] = this.__bindEventToProperty(
|
|
233
|
-
source,
|
|
234
|
-
eventNames[i],
|
|
235
|
-
targetObject,
|
|
236
|
-
targetPropertyChain,
|
|
237
|
-
options,
|
|
238
|
-
arrayIndexValues[i]
|
|
239
|
-
);
|
|
240
|
-
} else {
|
|
241
|
-
// try to set the initial value
|
|
242
|
-
if (
|
|
243
|
-
propertyNames[i] != null &&
|
|
244
|
-
source["get" + qx.lang.String.firstUp(propertyNames[i])] != null
|
|
245
|
-
) {
|
|
246
|
-
var currentValue =
|
|
247
|
-
source["get" + qx.lang.String.firstUp(propertyNames[i])]();
|
|
248
|
-
initialPromise = this.__setInitialValue(
|
|
249
|
-
currentValue,
|
|
250
|
-
targetObject,
|
|
251
|
-
targetPropertyChain,
|
|
252
|
-
options,
|
|
253
|
-
sourceObject
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
// bind the property
|
|
257
|
-
listenerIds[i] = this.__bindEventToProperty(
|
|
258
|
-
source,
|
|
259
|
-
eventNames[i],
|
|
260
|
-
targetObject,
|
|
261
|
-
targetPropertyChain,
|
|
262
|
-
options
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// if its not the last property
|
|
267
|
-
} else {
|
|
268
|
-
// create the context for the listener
|
|
269
|
-
var context = {
|
|
270
|
-
index: i,
|
|
271
|
-
propertyNames: propertyNames,
|
|
272
|
-
sources: sources,
|
|
273
|
-
listenerIds: listenerIds,
|
|
274
|
-
arrayIndexValues: arrayIndexValues,
|
|
275
|
-
targetObject: targetObject,
|
|
276
|
-
targetPropertyChain: targetPropertyChain,
|
|
277
|
-
options: options,
|
|
278
|
-
listeners: listeners
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
// create a listener
|
|
282
|
-
var listener = qx.lang.Function.bind(
|
|
283
|
-
this.__chainListener,
|
|
284
|
-
this,
|
|
285
|
-
context
|
|
286
|
-
);
|
|
181
|
+
/**
|
|
182
|
+
* @type {BindingRecord?}
|
|
183
|
+
*/
|
|
184
|
+
__record: null,
|
|
287
185
|
|
|
288
|
-
|
|
289
|
-
|
|
186
|
+
/**
|
|
187
|
+
* @type {qx.core.Object}
|
|
188
|
+
*/
|
|
189
|
+
__target: null,
|
|
290
190
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
191
|
+
/** @type {Promise} initialisation promise */
|
|
192
|
+
__initPromise: null,
|
|
294
193
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
source["get" + qx.lang.String.firstUp(propertyNames[i])] == null
|
|
298
|
-
) {
|
|
299
|
-
source = undefined;
|
|
300
|
-
} else if (arrayIndexValues[i] !== "") {
|
|
301
|
-
var itemIndex =
|
|
302
|
-
arrayIndexValues[i] === "last"
|
|
303
|
-
? source.length - 1
|
|
304
|
-
: arrayIndexValues[i];
|
|
305
|
-
source =
|
|
306
|
-
source["get" + qx.lang.String.firstUp(propertyNames[i])](
|
|
307
|
-
itemIndex
|
|
308
|
-
);
|
|
309
|
-
} else {
|
|
310
|
-
source = source["get" + qx.lang.String.firstUp(propertyNames[i])]();
|
|
311
|
-
// the value should be undefined if we can not find the last part of the property chain
|
|
312
|
-
if (source === null && propertyNames.length - 1 != i) {
|
|
313
|
-
source = undefined;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (!source) {
|
|
317
|
-
// call the converter if no source could be found on binding creation
|
|
318
|
-
this.__setInitialValue(
|
|
319
|
-
source,
|
|
320
|
-
targetObject,
|
|
321
|
-
targetPropertyChain,
|
|
322
|
-
options,
|
|
323
|
-
sourceObject
|
|
324
|
-
);
|
|
194
|
+
/** @type {qx.data.binding.AbstractSegment[]?} list of segments of the source path */
|
|
195
|
+
__sourceSegments: null,
|
|
325
196
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
329
|
-
} catch (ex) {
|
|
330
|
-
// remove the already added listener
|
|
331
|
-
// go through all added listeners (source)
|
|
332
|
-
|
|
333
|
-
for (var i = 0; i < sources.length; i++) {
|
|
334
|
-
// check if a source is available
|
|
335
|
-
if (sources[i] && listenerIds[i]) {
|
|
336
|
-
sources[i].removeListenerById(listenerIds[i]);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
var targets = targetListenerMap.targets;
|
|
340
|
-
var targetIds = targetListenerMap.listenerIds;
|
|
341
|
-
// go through all added listeners (target)
|
|
342
|
-
for (var i = 0; i < targets.length; i++) {
|
|
343
|
-
// check if a target is available
|
|
344
|
-
if (targets[i] && targetIds[i]) {
|
|
345
|
-
targets[i].removeListenerById(targetIds[i]);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
197
|
+
/** @type {qx.data.binding.AbstractSegment[]?} list of segments of the target path */
|
|
198
|
+
__targetSegments: null,
|
|
348
199
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
var id = {
|
|
354
|
-
type: "deepBinding",
|
|
355
|
-
listenerIds: listenerIds,
|
|
356
|
-
sources: sources,
|
|
357
|
-
targetListenerIds: targetListenerMap.listenerIds,
|
|
358
|
-
targets: targetListenerMap.targets,
|
|
359
|
-
initialPromise: initialPromise
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
// store the bindings
|
|
363
|
-
this.__storeBinding(
|
|
364
|
-
id,
|
|
365
|
-
sourceObject,
|
|
366
|
-
sourcePropertyChain,
|
|
367
|
-
targetObject,
|
|
368
|
-
targetPropertyChain
|
|
369
|
-
);
|
|
200
|
+
/**
|
|
201
|
+
* @type {BindingOptions}
|
|
202
|
+
*/
|
|
203
|
+
__options: null,
|
|
370
204
|
|
|
371
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Promises/A+ thenable compliance, this means that you can await the binding for initialisation
|
|
207
|
+
* https://promisesaplus.com/
|
|
208
|
+
* @returns {Promise} the promise
|
|
209
|
+
*/
|
|
210
|
+
then(onFulfilled, onRejected) {
|
|
211
|
+
return Promise.resolve(this.__initPromise).then(onFulfilled, onRejected);
|
|
372
212
|
},
|
|
373
213
|
|
|
374
214
|
/**
|
|
375
|
-
* Event listener for the chaining of the properties.
|
|
376
215
|
*
|
|
377
|
-
* @
|
|
216
|
+
* @returns {BindingRecord} The representation of this binding as record.
|
|
378
217
|
*/
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
context.options.onUpdate(
|
|
383
|
-
context.sources[context.index],
|
|
384
|
-
context.targetObject
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// delete all listener after the current one
|
|
389
|
-
for (var j = context.index + 1; j < context.propertyNames.length; j++) {
|
|
390
|
-
// remove the old sources
|
|
391
|
-
var source = context.sources[j];
|
|
392
|
-
context.sources[j] = null;
|
|
393
|
-
if (!source) {
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// remove the listeners
|
|
398
|
-
source.removeListenerById(context.listenerIds[j]);
|
|
218
|
+
asRecord() {
|
|
219
|
+
if (!this.__record) {
|
|
220
|
+
this.__record = [this, this.getSource(), this.getSourcePath(), this.getTarget(), this.getTargetPath()];
|
|
399
221
|
}
|
|
222
|
+
return this.__record;
|
|
223
|
+
},
|
|
400
224
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
source = source[
|
|
408
|
-
"get" + qx.lang.String.firstUp(context.propertyNames[j - 1])
|
|
409
|
-
](context.arrayIndexValues[j - 1]);
|
|
410
|
-
} else {
|
|
411
|
-
source =
|
|
412
|
-
source[
|
|
413
|
-
"get" + qx.lang.String.firstUp(context.propertyNames[j - 1])
|
|
414
|
-
]();
|
|
415
|
-
}
|
|
416
|
-
context.sources[j] = source;
|
|
417
|
-
// reset the target object if no new source could be found
|
|
418
|
-
if (!source) {
|
|
419
|
-
// use the converter if the property chain breaks [BUG# 6880]
|
|
420
|
-
if (context.options && context.options.converter) {
|
|
421
|
-
var ignoreConverter = false;
|
|
422
|
-
// take care of the ignore pattern used for the controller
|
|
423
|
-
if (context.options.ignoreConverter) {
|
|
424
|
-
// the current property chain as string
|
|
425
|
-
var currentSourceChain = context.propertyNames
|
|
426
|
-
.slice(0, j)
|
|
427
|
-
.join(".");
|
|
428
|
-
// match for the current pattern given in the options
|
|
429
|
-
var match = currentSourceChain.match(
|
|
430
|
-
new RegExp("^" + context.options.ignoreConverter)
|
|
431
|
-
);
|
|
432
|
-
|
|
433
|
-
ignoreConverter = match ? match.length > 0 : false;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
if (!ignoreConverter) {
|
|
437
|
-
this.__setTargetValue(
|
|
438
|
-
context.targetObject,
|
|
439
|
-
context.targetPropertyChain,
|
|
440
|
-
context.options.converter()
|
|
441
|
-
);
|
|
442
|
-
} else {
|
|
443
|
-
this.__resetTargetValue(
|
|
444
|
-
context.targetObject,
|
|
445
|
-
context.targetPropertyChain
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
} else {
|
|
449
|
-
this.__resetTargetValue(
|
|
450
|
-
context.targetObject,
|
|
451
|
-
context.targetPropertyChain
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
break;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// if its the last property
|
|
459
|
-
if (j == context.propertyNames.length - 1) {
|
|
460
|
-
// if its an array
|
|
461
|
-
if (
|
|
462
|
-
qx.Class.implementsInterface(source, qx.data.IListData) &&
|
|
463
|
-
context.arrayIndexValues[j] !== ""
|
|
464
|
-
) {
|
|
465
|
-
// set the initial value
|
|
466
|
-
var itemIndex =
|
|
467
|
-
context.arrayIndexValues[j] === "last"
|
|
468
|
-
? source.length - 1
|
|
469
|
-
: context.arrayIndexValues[j];
|
|
470
|
-
var currentValue = source.getItem(itemIndex);
|
|
471
|
-
this.__setInitialValue(
|
|
472
|
-
currentValue,
|
|
473
|
-
context.targetObject,
|
|
474
|
-
context.targetPropertyChain,
|
|
475
|
-
context.options,
|
|
476
|
-
context.sources[context.index]
|
|
477
|
-
);
|
|
478
|
-
|
|
479
|
-
// bind the item event to the new target
|
|
480
|
-
context.listenerIds[j] = this.__bindEventToProperty(
|
|
481
|
-
source,
|
|
482
|
-
"change",
|
|
483
|
-
context.targetObject,
|
|
484
|
-
context.targetPropertyChain,
|
|
485
|
-
context.options,
|
|
486
|
-
context.arrayIndexValues[j]
|
|
487
|
-
);
|
|
488
|
-
} else {
|
|
489
|
-
if (
|
|
490
|
-
context.propertyNames[j] != null &&
|
|
491
|
-
source[
|
|
492
|
-
"get" + qx.lang.String.firstUp(context.propertyNames[j])
|
|
493
|
-
] != null
|
|
494
|
-
) {
|
|
495
|
-
var currentValue =
|
|
496
|
-
source[
|
|
497
|
-
"get" + qx.lang.String.firstUp(context.propertyNames[j])
|
|
498
|
-
]();
|
|
499
|
-
|
|
500
|
-
this.__setInitialValue(
|
|
501
|
-
currentValue,
|
|
502
|
-
context.targetObject,
|
|
503
|
-
context.targetPropertyChain,
|
|
504
|
-
context.options,
|
|
505
|
-
context.sources[context.index]
|
|
506
|
-
);
|
|
507
|
-
}
|
|
508
|
-
var eventName = this.__getEventNameForProperty(
|
|
509
|
-
source,
|
|
510
|
-
context.propertyNames[j]
|
|
511
|
-
);
|
|
512
|
-
|
|
513
|
-
if (!eventName) {
|
|
514
|
-
context.sources[j] = null;
|
|
515
|
-
this.__resetTargetValue(
|
|
516
|
-
context.targetObject,
|
|
517
|
-
context.targetPropertyChain
|
|
518
|
-
);
|
|
519
|
-
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
// bind the last property to the new target
|
|
523
|
-
context.listenerIds[j] = this.__bindEventToProperty(
|
|
524
|
-
source,
|
|
525
|
-
eventName,
|
|
526
|
-
context.targetObject,
|
|
527
|
-
context.targetPropertyChain,
|
|
528
|
-
context.options
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
} else {
|
|
532
|
-
// check if a listener already created
|
|
533
|
-
if (context.listeners[j] == null) {
|
|
534
|
-
var listener = qx.lang.Function.bind(
|
|
535
|
-
this.__chainListener,
|
|
536
|
-
this,
|
|
537
|
-
context
|
|
538
|
-
);
|
|
539
|
-
|
|
540
|
-
// store the listener for further processing
|
|
541
|
-
context.listeners.push(listener);
|
|
542
|
-
}
|
|
543
|
-
// add a new listener
|
|
544
|
-
if (qx.Class.implementsInterface(source, qx.data.IListData)) {
|
|
545
|
-
var eventName = "change";
|
|
546
|
-
} else {
|
|
547
|
-
var eventName = this.__getEventNameForProperty(
|
|
548
|
-
source,
|
|
549
|
-
context.propertyNames[j]
|
|
550
|
-
);
|
|
551
|
-
}
|
|
225
|
+
/**
|
|
226
|
+
* @override
|
|
227
|
+
*/
|
|
228
|
+
toString() {
|
|
229
|
+
return `${super.toString()}: ${this.getSource()}.${this.getSourcePath()} -> ${this.getTarget()}.${this.getTargetPath()}`;
|
|
230
|
+
},
|
|
552
231
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
232
|
+
/**
|
|
233
|
+
*
|
|
234
|
+
* @returns {Promise} A promise which resolves when the initial value has been copied over from source to target
|
|
235
|
+
*/
|
|
236
|
+
getInitPromise() {
|
|
237
|
+
return this.__initPromise;
|
|
238
|
+
},
|
|
559
239
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
240
|
+
/**
|
|
241
|
+
* Apply for `sourcePath`
|
|
242
|
+
*/
|
|
243
|
+
_applySourcePath(value, oldValue) {
|
|
244
|
+
if (oldValue) {
|
|
245
|
+
throw new Error("Cannot change sourcePath after binding has been created");
|
|
246
|
+
}
|
|
247
|
+
this.__record = null; // invalidate record representation cache
|
|
248
|
+
this.__sourceSegments = qx.data.SingleValueBinding.__parseSegments(this, value);
|
|
249
|
+
let lastSegment = this.__sourceSegments.at(-1);
|
|
250
|
+
lastSegment.setOutputReceiver(this);
|
|
568
251
|
},
|
|
569
252
|
|
|
570
253
|
/**
|
|
571
|
-
*
|
|
572
|
-
* target
|
|
573
|
-
* property chain
|
|
254
|
+
* Sets the source object of this binding.
|
|
255
|
+
* If a target is set, the target will be updated with source's value.
|
|
574
256
|
*
|
|
575
|
-
* @param
|
|
576
|
-
* @
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
* be bind to.
|
|
580
|
-
* @param targetPropertyChain {String} The property name of the target
|
|
581
|
-
* object.
|
|
582
|
-
* @param options {Map} The options map perhaps containing the user defined
|
|
583
|
-
* converter.
|
|
584
|
-
* @return {var} A map containing the listener ids and the targets.
|
|
257
|
+
* @param {qx.core.Object?} value The source object to get the `value` by looking up `sourcePath`
|
|
258
|
+
* @returns {Promise?} A promise if any stage of the process was asynchronous, i.e. we had to get a property asynchronously along the source/target path,
|
|
259
|
+
* or setting the target was asynchronous.
|
|
260
|
+
* If everything was synchronous, then this will return null.
|
|
585
261
|
*/
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
// go through all property names
|
|
604
|
-
for (var i = 0; i < propertyNames.length - 1; i++) {
|
|
605
|
-
// check for the array
|
|
606
|
-
if (arrayIndexValues[i] !== "") {
|
|
607
|
-
// push the array change event
|
|
608
|
-
eventNames.push("change");
|
|
609
|
-
} else {
|
|
610
|
-
var eventName = this.__getEventNameForProperty(
|
|
611
|
-
target,
|
|
612
|
-
propertyNames[i]
|
|
613
|
-
);
|
|
614
|
-
|
|
615
|
-
if (!eventName) {
|
|
616
|
-
// if the event names could not be terminated,
|
|
617
|
-
// just ignore the target chain listening
|
|
618
|
-
break;
|
|
619
|
-
}
|
|
620
|
-
eventNames.push(eventName);
|
|
262
|
+
setSource(value) {
|
|
263
|
+
const SingleValueBinding = qx.data.SingleValueBinding;
|
|
264
|
+
if (this.__source === value) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
this.__record = null; // invalidate record representation cache
|
|
269
|
+
let oldValue = this.__source;
|
|
270
|
+
this.__source = value;
|
|
271
|
+
this.__initPromise = null; // reset the init promise, as the source has changed
|
|
272
|
+
|
|
273
|
+
if (oldValue) {
|
|
274
|
+
//Delete old source's bindings if there was one
|
|
275
|
+
delete SingleValueBinding.__bindingsBySource[oldValue.toHashCode()][this.toHashCode()];
|
|
276
|
+
if (qx.lang.Object.isEmpty(SingleValueBinding.__bindingsBySource[oldValue.toHashCode()])) {
|
|
277
|
+
delete SingleValueBinding.__bindingsBySource[oldValue.toHashCode()];
|
|
621
278
|
}
|
|
279
|
+
}
|
|
622
280
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
var listener = function () {
|
|
628
|
-
// delete all listener after the current one
|
|
629
|
-
for (var j = i + 1; j < propertyNames.length - 1; j++) {
|
|
630
|
-
// remove the old sources
|
|
631
|
-
var target = targets[j];
|
|
632
|
-
targets[j] = null;
|
|
633
|
-
if (!target) {
|
|
634
|
-
continue;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// remove the listeners
|
|
638
|
-
target.removeListenerById(listenerIds[j]);
|
|
639
|
-
}
|
|
281
|
+
if (value) {
|
|
282
|
+
//Store the binding
|
|
283
|
+
SingleValueBinding.__bindingsBySource[value.toHashCode()] ??= {};
|
|
284
|
+
SingleValueBinding.__bindingsBySource[value.toHashCode()][this.toHashCode()] = this;
|
|
640
285
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
arrayIndexValues[j - 1] === "last"
|
|
650
|
-
? target.getLength() - 1
|
|
651
|
-
: arrayIndexValues[j - 1];
|
|
652
|
-
target = target["get" + firstUpPropName](currentIndex);
|
|
653
|
-
} else {
|
|
654
|
-
target = target["get" + firstUpPropName]();
|
|
655
|
-
}
|
|
656
|
-
targets[j] = target;
|
|
657
|
-
if (!target) {
|
|
658
|
-
break;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// check if a listener already created
|
|
662
|
-
if (listeners[j] == null) {
|
|
663
|
-
// store the listener for further processing
|
|
664
|
-
listeners.push(listener);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// add a new listener
|
|
668
|
-
if (qx.Class.implementsInterface(target, qx.data.IListData)) {
|
|
669
|
-
var eventName = "change";
|
|
670
|
-
} else {
|
|
671
|
-
var eventName =
|
|
672
|
-
qx.data.SingleValueBinding.__getEventNameForProperty(
|
|
673
|
-
target,
|
|
674
|
-
propertyNames[j]
|
|
675
|
-
);
|
|
676
|
-
|
|
677
|
-
if (!eventName) {
|
|
678
|
-
// if the event name could not be terminated,
|
|
679
|
-
// ignore the rest
|
|
680
|
-
break;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
listenerIds[j] = target.addListener(eventName, listeners[j]);
|
|
286
|
+
//Set the input on the first segment of the source path
|
|
287
|
+
let promise = this.__sourceSegments[0].setInput(value);
|
|
288
|
+
const cb = () => {
|
|
289
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
290
|
+
this.assertNotNull(
|
|
291
|
+
this.__sourceSegments[0].getEventName(),
|
|
292
|
+
`Binding property ${this.__sourceSegments[0].toString()} of object ${value.classname} not possible. No event available.`
|
|
293
|
+
);
|
|
685
294
|
}
|
|
686
|
-
|
|
687
|
-
qx.data.SingleValueBinding.updateTarget(
|
|
688
|
-
sourceObject,
|
|
689
|
-
sourcePropertyChain,
|
|
690
|
-
targetObject,
|
|
691
|
-
targetPropertyChain,
|
|
692
|
-
options
|
|
693
|
-
);
|
|
694
295
|
};
|
|
695
296
|
|
|
696
|
-
|
|
697
|
-
listeners.push(listener);
|
|
297
|
+
let out;
|
|
698
298
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
var firstUpPropName = qx.lang.String.firstUp(propertyNames[i]);
|
|
703
|
-
// get and store the next target
|
|
704
|
-
if (target["get" + firstUpPropName] == null) {
|
|
705
|
-
target = null;
|
|
706
|
-
} else if (arrayIndexValues[i] !== "") {
|
|
707
|
-
target = target["get" + firstUpPropName](arrayIndexValues[i]);
|
|
299
|
+
if (qx.Promise.isPromise(promise)) {
|
|
300
|
+
out = promise.then(cb);
|
|
708
301
|
} else {
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
if (!target) {
|
|
712
|
-
break;
|
|
302
|
+
out = cb();
|
|
713
303
|
}
|
|
304
|
+
this.__initPromise = Promise.resolve(out);
|
|
305
|
+
return out;
|
|
714
306
|
}
|
|
715
|
-
|
|
716
|
-
return { listenerIds: listenerIds, targets: targets };
|
|
717
307
|
},
|
|
718
308
|
|
|
719
309
|
/**
|
|
720
|
-
*
|
|
721
|
-
* and set that on the target.
|
|
722
|
-
*
|
|
723
|
-
* @param sourceObject {qx.core.Object} The source of the binding.
|
|
724
|
-
* @param sourcePropertyChain {String} The property chain which represents
|
|
725
|
-
* the source property.
|
|
726
|
-
* @param targetObject {qx.core.Object} The object which the source should
|
|
727
|
-
* be bind to.
|
|
728
|
-
* @param targetPropertyChain {String} The property name of the target
|
|
729
|
-
* object.
|
|
730
|
-
* @param options {Map} The options map perhaps containing the user defined
|
|
731
|
-
* converter.
|
|
732
|
-
*
|
|
733
|
-
* @internal
|
|
310
|
+
* @returns {qx.core.Object} the source object
|
|
734
311
|
*/
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
sourcePropertyChain,
|
|
738
|
-
targetObject,
|
|
739
|
-
targetPropertyChain,
|
|
740
|
-
options
|
|
741
|
-
) {
|
|
742
|
-
var value = this.resolvePropertyChain(sourceObject, sourcePropertyChain);
|
|
743
|
-
|
|
744
|
-
// convert the data before setting
|
|
745
|
-
value = qx.data.SingleValueBinding.__convertValue(
|
|
746
|
-
value,
|
|
747
|
-
targetObject,
|
|
748
|
-
targetPropertyChain,
|
|
749
|
-
options,
|
|
750
|
-
sourceObject
|
|
751
|
-
);
|
|
752
|
-
|
|
753
|
-
this.__setTargetValue(targetObject, targetPropertyChain, value);
|
|
312
|
+
getSource() {
|
|
313
|
+
return this.__source;
|
|
754
314
|
},
|
|
755
315
|
|
|
756
316
|
/**
|
|
757
|
-
*
|
|
758
|
-
*
|
|
759
|
-
* @param o {qx.core.Object} The source of the binding.
|
|
760
|
-
* @param propertyChain {String} The property chain which represents
|
|
761
|
-
* the source property.
|
|
762
|
-
* @return {var?undefined} Returns the set value if defined.
|
|
317
|
+
* Apply for `targetPath`
|
|
763
318
|
*/
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
319
|
+
_applyTargetPath(value, oldValue) {
|
|
320
|
+
if (oldValue) {
|
|
321
|
+
throw new Error("Cannot change targetPath after binding has been created");
|
|
322
|
+
}
|
|
323
|
+
this.__record = null; // invalidate record representation cache
|
|
324
|
+
this.__targetSegments = qx.data.SingleValueBinding.__parseSegments(this, value);
|
|
325
|
+
this.__targetSegments.at(-1).addListener("changeInput", this.__updateTarget, this);
|
|
767
326
|
},
|
|
768
327
|
|
|
769
328
|
/**
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
* and therefore it checks the property definition for the event. The second
|
|
773
|
-
* possibility is to check if there is an event with the given name. The
|
|
774
|
-
* third and last possibility checked is if there is an event which is named
|
|
775
|
-
* change + propertyName. If this three possibilities fail, an error will be
|
|
776
|
-
* thrown.
|
|
329
|
+
* Sets the target object of this binding.
|
|
330
|
+
* If a source is set, the target will be updated with source's value.
|
|
777
331
|
*
|
|
778
|
-
* @param
|
|
779
|
-
* @
|
|
780
|
-
*
|
|
332
|
+
* @param {qx.core.Object?} value The source object to get the `value` by looking up `sourcePath`
|
|
333
|
+
* @returns {Promise?} A promise if any stage of the process was asynchronous, i.e. we had to get a property asynchronously along the source/target path,
|
|
334
|
+
* or setting the target was asynchronous.
|
|
335
|
+
* If everything was synchronous, then this will return null.
|
|
781
336
|
*/
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
// if no event name could be found
|
|
786
|
-
if (eventName == null) {
|
|
787
|
-
// check if the propertyName is the event name
|
|
788
|
-
if (qx.Class.supportsEvent(source.constructor, propertyName)) {
|
|
789
|
-
eventName = propertyName;
|
|
790
|
-
// check if the change + propertyName is the event name
|
|
791
|
-
} else if (
|
|
792
|
-
qx.Class.supportsEvent(
|
|
793
|
-
source.constructor,
|
|
794
|
-
"change" + qx.lang.String.firstUp(propertyName)
|
|
795
|
-
)
|
|
796
|
-
) {
|
|
797
|
-
eventName = "change" + qx.lang.String.firstUp(propertyName);
|
|
798
|
-
} else {
|
|
799
|
-
return null;
|
|
800
|
-
}
|
|
337
|
+
setTarget(value) {
|
|
338
|
+
if (this.__target === value) {
|
|
339
|
+
return;
|
|
801
340
|
}
|
|
802
|
-
return eventName;
|
|
803
|
-
},
|
|
804
341
|
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
* starts.
|
|
811
|
-
* @param targetPropertyChain {String} The names of the properties,
|
|
812
|
-
* separated with a dot.
|
|
813
|
-
*/
|
|
814
|
-
__resetTargetValue(targetObject, targetPropertyChain) {
|
|
815
|
-
// get the last target object of the chain
|
|
816
|
-
var properties = this.__getPropertyChainArray(targetPropertyChain);
|
|
817
|
-
var target = this.__getTargetFromChain(targetObject, properties);
|
|
818
|
-
if (target != null) {
|
|
819
|
-
// get the name of the last property
|
|
820
|
-
var lastProperty = properties[properties.length - 1];
|
|
821
|
-
// check for an array and set the value to null
|
|
822
|
-
var index = this.__getArrayIndex(lastProperty);
|
|
823
|
-
if (index) {
|
|
824
|
-
this.__setTargetValue(targetObject, targetPropertyChain, null);
|
|
825
|
-
return;
|
|
826
|
-
}
|
|
342
|
+
this.__record = null; // invalidate record representation cache
|
|
343
|
+
this.__initPromise = null; // reset the init promise, as the target has changed
|
|
344
|
+
let oldValue = this.__target;
|
|
345
|
+
this.__target = value;
|
|
346
|
+
const SingleValueBinding = qx.data.SingleValueBinding;
|
|
827
347
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
target["reset" + qx.lang.String.firstUp(lastProperty)]();
|
|
833
|
-
} else {
|
|
834
|
-
// fallback if no resetter is given (see bug #2456)
|
|
835
|
-
if (
|
|
836
|
-
typeof target["set" + qx.lang.String.firstUp(lastProperty)] !=
|
|
837
|
-
"function"
|
|
838
|
-
) {
|
|
839
|
-
throw new qx.core.AssertionError(
|
|
840
|
-
"No setter for '" + lastProperty + "' on target " + target + "."
|
|
841
|
-
);
|
|
842
|
-
}
|
|
843
|
-
target["set" + qx.lang.String.firstUp(lastProperty)](null);
|
|
348
|
+
if (oldValue) {
|
|
349
|
+
delete SingleValueBinding.__bindingsByTarget[oldValue.toHashCode()][this.toHashCode()];
|
|
350
|
+
if (qx.lang.Object.isEmpty(SingleValueBinding.__bindingsByTarget[oldValue.toHashCode()])) {
|
|
351
|
+
delete SingleValueBinding.__bindingsByTarget[oldValue.toHashCode()];
|
|
844
352
|
}
|
|
845
353
|
}
|
|
846
|
-
},
|
|
847
354
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
* @param value {var} The value to set.
|
|
857
|
-
*/
|
|
858
|
-
__setTargetValue(targetObject, targetPropertyChain, value) {
|
|
859
|
-
// get the last target object of the chain
|
|
860
|
-
var properties = this.__getPropertyChainArray(targetPropertyChain);
|
|
861
|
-
var target = this.__getTargetFromChain(targetObject, properties);
|
|
862
|
-
if (target) {
|
|
863
|
-
// get the name of the last property
|
|
864
|
-
var lastProperty = properties[properties.length - 1];
|
|
865
|
-
|
|
866
|
-
// check for array notation
|
|
867
|
-
var index = this.__getArrayIndex(lastProperty);
|
|
868
|
-
if (index) {
|
|
869
|
-
if (index === "last") {
|
|
870
|
-
// check for the 'last' notation
|
|
871
|
-
index = target.length - 1;
|
|
872
|
-
}
|
|
873
|
-
target.setItem(index, value);
|
|
874
|
-
} else {
|
|
875
|
-
if (
|
|
876
|
-
typeof target["set" + qx.lang.String.firstUp(lastProperty)] !=
|
|
877
|
-
"function"
|
|
878
|
-
) {
|
|
879
|
-
throw new qx.core.AssertionError(
|
|
880
|
-
"No setter for '" + lastProperty + "' on target " + target + "."
|
|
881
|
-
);
|
|
882
|
-
}
|
|
883
|
-
return target["set" + qx.lang.String.firstUp(lastProperty)](value);
|
|
884
|
-
}
|
|
355
|
+
if (value) {
|
|
356
|
+
const SingleValueBinding = qx.data.SingleValueBinding;
|
|
357
|
+
SingleValueBinding.__bindingsByTarget[value.toHashCode()] ??= {};
|
|
358
|
+
SingleValueBinding.__bindingsByTarget[value.toHashCode()][this.toHashCode()] = this;
|
|
359
|
+
|
|
360
|
+
let out = this.__targetSegments[0].setInput(value);
|
|
361
|
+
this.__initPromise = Promise.resolve(out);
|
|
362
|
+
return out;
|
|
885
363
|
}
|
|
886
364
|
},
|
|
887
365
|
|
|
888
366
|
/**
|
|
889
|
-
* Returns the index from a property using bracket notation, e.g.
|
|
890
|
-
* "[42]" returns "42", "[last]" returns "last"
|
|
891
367
|
*
|
|
892
|
-
* @
|
|
893
|
-
* @return {String|null} Array index or null if the property name does
|
|
894
|
-
* not use bracket notation
|
|
368
|
+
* @returns {qx.core.Object} the target object
|
|
895
369
|
*/
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
var arrayMatch = propertyName.match(arrayExp);
|
|
899
|
-
if (arrayMatch) {
|
|
900
|
-
return arrayMatch[1];
|
|
901
|
-
}
|
|
902
|
-
return null;
|
|
370
|
+
getTarget() {
|
|
371
|
+
return this.__target;
|
|
903
372
|
},
|
|
904
373
|
|
|
905
374
|
/**
|
|
906
|
-
*
|
|
907
|
-
*
|
|
908
|
-
* @
|
|
909
|
-
*
|
|
375
|
+
* This method should not be called directly.
|
|
376
|
+
* It is only there to comply with interface `qx.data.binding.IInputReceiver`.
|
|
377
|
+
* @override interface qx.data.binding.IInputReceiver
|
|
378
|
+
*
|
|
379
|
+
* @param {*} input
|
|
910
380
|
*/
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
return targetPropertyChain
|
|
914
|
-
.replace(/\[/g, ".[")
|
|
915
|
-
.split(".")
|
|
916
|
-
.filter(function (prop) {
|
|
917
|
-
return prop !== "";
|
|
918
|
-
});
|
|
381
|
+
setInput(input) {
|
|
382
|
+
return this.__setValue(input);
|
|
919
383
|
},
|
|
920
384
|
|
|
921
385
|
/**
|
|
922
|
-
* Helper-Function resolving the object on which the last property of the
|
|
923
|
-
* chain should be set.
|
|
924
386
|
*
|
|
925
|
-
* @param
|
|
926
|
-
*
|
|
927
|
-
* @param targetProperties {String[]} Array containing the names of the properties
|
|
928
|
-
* @param index {Number?} The array index of the last property to be considered.
|
|
929
|
-
* Default: The last item's index
|
|
930
|
-
* @return {qx.core.Object|null} The object on which the last property
|
|
931
|
-
* should be set.
|
|
387
|
+
* @param {*} value The final value obtained from the sourcePath
|
|
388
|
+
* @returns {Promise?} A promise if setting the target is asynchronous, otherwise null
|
|
932
389
|
*/
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
for (var i = 0; target !== null && i < index; i++) {
|
|
938
|
-
try {
|
|
939
|
-
var property = targetProperties[i];
|
|
940
|
-
|
|
941
|
-
// array notation
|
|
942
|
-
var arrIndex = this.__getArrayIndex(property);
|
|
943
|
-
if (arrIndex) {
|
|
944
|
-
if (arrIndex === "last") {
|
|
945
|
-
// check for the 'last' notation
|
|
946
|
-
arrIndex = target.length - 1;
|
|
947
|
-
}
|
|
948
|
-
target = target.getItem(arrIndex);
|
|
949
|
-
} else {
|
|
950
|
-
target = target["get" + qx.lang.String.firstUp(property)]();
|
|
951
|
-
}
|
|
952
|
-
} catch (ex) {
|
|
953
|
-
return null;
|
|
954
|
-
}
|
|
390
|
+
__setValue(value) {
|
|
391
|
+
if (this.__value === value) {
|
|
392
|
+
return null; // no change
|
|
955
393
|
}
|
|
956
|
-
|
|
394
|
+
this.__value = value;
|
|
395
|
+
return this.__updateTarget();
|
|
957
396
|
},
|
|
958
397
|
|
|
959
398
|
/**
|
|
960
|
-
* Set the given value to the target property. This method is used for
|
|
961
|
-
* initially set the value.
|
|
962
399
|
*
|
|
963
|
-
* @
|
|
964
|
-
* @param targetObject {qx.core.Object} The object which contains the target
|
|
965
|
-
* property.
|
|
966
|
-
* @param targetPropertyChain {String} The name of the target property in the
|
|
967
|
-
* target object.
|
|
968
|
-
* @param options {Map} The options map perhaps containing the user defined
|
|
969
|
-
* converter.
|
|
970
|
-
* @param sourceObject {qx.core.Object} The source object of the binding (
|
|
971
|
-
* used for the onUpdate callback).
|
|
400
|
+
* @returns {*} the value that was set by the sourcePath
|
|
972
401
|
*/
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
targetObject,
|
|
976
|
-
targetPropertyChain,
|
|
977
|
-
options,
|
|
978
|
-
sourceObject
|
|
979
|
-
) {
|
|
980
|
-
// first convert the initial value
|
|
981
|
-
value = this.__convertValue(
|
|
982
|
-
value,
|
|
983
|
-
targetObject,
|
|
984
|
-
targetPropertyChain,
|
|
985
|
-
options,
|
|
986
|
-
sourceObject
|
|
987
|
-
);
|
|
988
|
-
|
|
989
|
-
// check if the converted value is undefined
|
|
990
|
-
if (value === undefined) {
|
|
991
|
-
this.__resetTargetValue(targetObject, targetPropertyChain);
|
|
992
|
-
}
|
|
993
|
-
// only set the initial value if one is given (may be null)
|
|
994
|
-
if (value !== undefined) {
|
|
995
|
-
try {
|
|
996
|
-
var result = this.__setTargetValue(
|
|
997
|
-
targetObject,
|
|
998
|
-
targetPropertyChain,
|
|
999
|
-
value
|
|
1000
|
-
);
|
|
1001
|
-
|
|
1002
|
-
// tell the user that the setter was invoked probably
|
|
1003
|
-
if (options && options.onUpdate) {
|
|
1004
|
-
options.onUpdate(sourceObject, targetObject, value);
|
|
1005
|
-
}
|
|
1006
|
-
return result;
|
|
1007
|
-
} catch (e) {
|
|
1008
|
-
if (!(e instanceof qx.core.ValidationError)) {
|
|
1009
|
-
throw e;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
if (options && options.onSetFail) {
|
|
1013
|
-
options.onSetFail(e);
|
|
1014
|
-
} else {
|
|
1015
|
-
qx.log.Logger.warn(
|
|
1016
|
-
"Failed so set value " +
|
|
1017
|
-
value +
|
|
1018
|
-
" on " +
|
|
1019
|
-
targetObject +
|
|
1020
|
-
". Error message: " +
|
|
1021
|
-
e
|
|
1022
|
-
);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
402
|
+
getValue() {
|
|
403
|
+
return this.__value;
|
|
1026
404
|
},
|
|
1027
405
|
|
|
1028
406
|
/**
|
|
1029
|
-
*
|
|
1030
|
-
* arrays to fit the algorithm.
|
|
1031
|
-
*
|
|
1032
|
-
* @param propertyNames {Array} The array containing the property names.
|
|
1033
|
-
* Attention, this method can change this parameter!!!
|
|
1034
|
-
* @return {Array} An array containing the values of the array properties
|
|
1035
|
-
* corresponding to the property names.
|
|
407
|
+
* Updates the target with the current value
|
|
1036
408
|
*/
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
if (name.endsWith("]")) {
|
|
1046
|
-
// get the inner value of the array notation
|
|
1047
|
-
var arrayIndex = name.substring(
|
|
1048
|
-
name.indexOf("[") + 1,
|
|
1049
|
-
name.indexOf("]")
|
|
1050
|
-
);
|
|
1051
|
-
|
|
1052
|
-
// check the arrayIndex
|
|
1053
|
-
if (name.indexOf("]") != name.length - 1) {
|
|
1054
|
-
throw new Error(
|
|
1055
|
-
"Please use only one array at a time: " + name + " does not work."
|
|
1056
|
-
);
|
|
1057
|
-
}
|
|
1058
|
-
if (arrayIndex !== "last") {
|
|
1059
|
-
if (arrayIndex == "" || isNaN(parseInt(arrayIndex, 10))) {
|
|
1060
|
-
throw new Error(
|
|
1061
|
-
"No number or 'last' value has been given" +
|
|
1062
|
-
" in an array binding: " +
|
|
1063
|
-
name +
|
|
1064
|
-
" does not work."
|
|
1065
|
-
);
|
|
1066
|
-
}
|
|
409
|
+
__updateTarget() {
|
|
410
|
+
if (this.__targetSegments) {
|
|
411
|
+
//We need to make sure the target segments are up to date
|
|
412
|
+
//because the listeners may trigger after this point.
|
|
413
|
+
//This is important in bidirectional bindings.
|
|
414
|
+
for (let segment of this.__targetSegments) {
|
|
415
|
+
if (segment.getOutputReceiver()) {
|
|
416
|
+
segment.updateOutput();
|
|
1067
417
|
}
|
|
1068
|
-
|
|
1069
|
-
// if a property is in front of the array notation
|
|
1070
|
-
if (name.indexOf("[") != 0) {
|
|
1071
|
-
// store the property name without the array notation
|
|
1072
|
-
propertyNames[i] = name.substring(0, name.indexOf("["));
|
|
1073
|
-
// store the values in the array for the current iteration
|
|
1074
|
-
arrayIndexValues[i] = "";
|
|
1075
|
-
// store the properties for the next iteration (the item of the array)
|
|
1076
|
-
arrayIndexValues[i + 1] = arrayIndex;
|
|
1077
|
-
propertyNames.splice(i + 1, 0, "item");
|
|
1078
|
-
// skip the next iteration. its the array item and its already set
|
|
1079
|
-
i++;
|
|
1080
|
-
// it the array notation is the beginning
|
|
1081
|
-
} else {
|
|
1082
|
-
// store the array index and override the entry in the property names
|
|
1083
|
-
arrayIndexValues[i] = arrayIndex;
|
|
1084
|
-
propertyNames.splice(i, 1, "item");
|
|
1085
|
-
}
|
|
1086
|
-
} else {
|
|
1087
|
-
arrayIndexValues[i] = "";
|
|
1088
418
|
}
|
|
1089
419
|
}
|
|
1090
420
|
|
|
1091
|
-
|
|
1092
|
-
},
|
|
1093
|
-
|
|
1094
|
-
/**
|
|
1095
|
-
* Internal helper method which is actually doing all bindings. That means
|
|
1096
|
-
* that an event listener will be added to the source object which listens
|
|
1097
|
-
* to the given event and invokes an set on the target property on the
|
|
1098
|
-
* targetObject.
|
|
1099
|
-
* This method does not store the binding in the internal reference store
|
|
1100
|
-
* so it should NOT be used from outside this class. For an outside usage,
|
|
1101
|
-
* use {@link #bind}.
|
|
1102
|
-
*
|
|
1103
|
-
* @param sourceObject {qx.core.Object} The source of the binding.
|
|
1104
|
-
* @param sourceEvent {String} The event of the source object which could
|
|
1105
|
-
* be the change event in common but has to be an
|
|
1106
|
-
* {@link qx.event.type.Data} event.
|
|
1107
|
-
* @param targetObject {qx.core.Object} The object which the source should
|
|
1108
|
-
* be bind to.
|
|
1109
|
-
* @param targetProperty {String} The property name of the target object.
|
|
1110
|
-
* @param options {Map} A map containing the options. See
|
|
1111
|
-
* {@link #bind} for more information.
|
|
1112
|
-
* @param arrayIndex {String} The index of the given array if its an array
|
|
1113
|
-
* to bind.
|
|
1114
|
-
*
|
|
1115
|
-
* @return {var} Returns the internal id for that binding. This can be used
|
|
1116
|
-
* for referencing the binding or e.g. for removing. This is not an atomic
|
|
1117
|
-
* id so you can't you use it as a hash-map index. It's the id which will
|
|
1118
|
-
* be returned by the {@link qx.core.Object#addListener} method.
|
|
1119
|
-
* @throws {qx.core.AssertionError} If the event is no data event or
|
|
1120
|
-
* there is no property definition for the target object and target
|
|
1121
|
-
* property.
|
|
1122
|
-
*/
|
|
1123
|
-
__bindEventToProperty(
|
|
1124
|
-
sourceObject,
|
|
1125
|
-
sourceEvent,
|
|
1126
|
-
targetObject,
|
|
1127
|
-
targetProperty,
|
|
1128
|
-
options,
|
|
1129
|
-
arrayIndex
|
|
1130
|
-
) {
|
|
1131
|
-
// checks
|
|
1132
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1133
|
-
// check for the data event
|
|
1134
|
-
var eventType = qx.Class.getEventType(
|
|
1135
|
-
sourceObject.constructor,
|
|
1136
|
-
sourceEvent
|
|
1137
|
-
);
|
|
1138
|
-
|
|
1139
|
-
qx.core.Assert.assertEquals(
|
|
1140
|
-
"qx.event.type.Data",
|
|
1141
|
-
eventType,
|
|
1142
|
-
sourceEvent +
|
|
1143
|
-
" is not an data (qx.event.type.Data) event on " +
|
|
1144
|
-
sourceObject +
|
|
1145
|
-
"."
|
|
1146
|
-
);
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
var bindListener = function (arrayIndex, e) {
|
|
1150
|
-
// if an array value is given
|
|
1151
|
-
if (arrayIndex !== "") {
|
|
1152
|
-
//check if its the "last" value
|
|
1153
|
-
if (arrayIndex === "last") {
|
|
1154
|
-
arrayIndex = sourceObject.length - 1;
|
|
1155
|
-
}
|
|
421
|
+
let lastSegment = this.__targetSegments.at(-1);
|
|
1156
422
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
// reset the target if the data is not set
|
|
1161
|
-
if (data === undefined) {
|
|
1162
|
-
qx.data.SingleValueBinding.__resetTargetValue(
|
|
1163
|
-
targetObject,
|
|
1164
|
-
targetProperty
|
|
1165
|
-
);
|
|
1166
|
-
}
|
|
423
|
+
if (this.getTarget() && this.getSource()) {
|
|
424
|
+
let value = this.getValue();
|
|
1167
425
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
var
|
|
1171
|
-
|
|
1172
|
-
return;
|
|
1173
|
-
}
|
|
1174
|
-
} else {
|
|
1175
|
-
// get the data out of the event
|
|
1176
|
-
var data = e.getData();
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
// debug message
|
|
1180
|
-
if (qx.core.Environment.get("qx.debug.databinding")) {
|
|
1181
|
-
qx.log.Logger.debug(
|
|
1182
|
-
"Binding executed from " +
|
|
1183
|
-
sourceObject +
|
|
1184
|
-
" by " +
|
|
1185
|
-
sourceEvent +
|
|
1186
|
-
" to " +
|
|
1187
|
-
targetObject +
|
|
1188
|
-
" (" +
|
|
1189
|
-
targetProperty +
|
|
1190
|
-
")"
|
|
1191
|
-
);
|
|
1192
|
-
|
|
1193
|
-
qx.log.Logger.debug("Data before conversion: " + data);
|
|
426
|
+
let ignoreConverter = false;
|
|
427
|
+
if (this.__options.ignoreConverter) {
|
|
428
|
+
var match = this.getSourcePath().match(new RegExp("^" + this.__options.ignoreConverter));
|
|
429
|
+
ignoreConverter = match ? match.length > 0 : false;
|
|
1194
430
|
}
|
|
1195
431
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
targetObject,
|
|
1200
|
-
targetProperty,
|
|
1201
|
-
options,
|
|
1202
|
-
sourceObject
|
|
1203
|
-
);
|
|
1204
|
-
|
|
1205
|
-
// debug message
|
|
1206
|
-
if (qx.core.Environment.get("qx.debug.databinding")) {
|
|
1207
|
-
qx.log.Logger.debug("Data after conversion: " + data);
|
|
432
|
+
if (this.__options.converter && (value !== undefined || !ignoreConverter)) {
|
|
433
|
+
let model = typeof this.getTarget().getModel == "function" ? this.getTarget().getModel() : null;
|
|
434
|
+
value = this.__options.converter(value, model, this.getSource(), this.getTarget());
|
|
1208
435
|
}
|
|
1209
436
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
if (data !== undefined) {
|
|
1214
|
-
result = qx.data.SingleValueBinding.__setTargetValue(
|
|
1215
|
-
targetObject,
|
|
1216
|
-
targetProperty,
|
|
1217
|
-
data
|
|
1218
|
-
);
|
|
437
|
+
const cb = ex => {
|
|
438
|
+
if (ex) {
|
|
439
|
+
this.__options.onSetFail?.();
|
|
1219
440
|
} else {
|
|
1220
|
-
|
|
1221
|
-
targetObject,
|
|
1222
|
-
targetProperty
|
|
1223
|
-
);
|
|
441
|
+
this.__options.onUpdate?.(this.getSource(), this.getTarget(), value);
|
|
1224
442
|
}
|
|
443
|
+
return null;
|
|
444
|
+
};
|
|
1225
445
|
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
}
|
|
446
|
+
let ret;
|
|
447
|
+
try {
|
|
448
|
+
ret = lastSegment.setTargetValue(value);
|
|
1230
449
|
} catch (ex) {
|
|
1231
|
-
|
|
1232
|
-
throw ex;
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
if (options && options.onSetFail) {
|
|
1236
|
-
options.onSetFail(ex);
|
|
1237
|
-
} else {
|
|
1238
|
-
qx.log.Logger.warn(
|
|
1239
|
-
"Failed so set value " +
|
|
1240
|
-
data +
|
|
1241
|
-
" on " +
|
|
1242
|
-
targetObject +
|
|
1243
|
-
". Error message: " +
|
|
1244
|
-
ex
|
|
1245
|
-
);
|
|
1246
|
-
}
|
|
450
|
+
return cb(ex);
|
|
1247
451
|
}
|
|
1248
|
-
return result;
|
|
1249
|
-
};
|
|
1250
452
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
453
|
+
if (qx.Promise.isPromise(ret)) {
|
|
454
|
+
return ret.then(cb, cb);
|
|
455
|
+
} else {
|
|
456
|
+
cb(null);
|
|
457
|
+
}
|
|
1255
458
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
bindListener,
|
|
1259
|
-
sourceObject,
|
|
1260
|
-
arrayIndex
|
|
1261
|
-
);
|
|
459
|
+
}
|
|
460
|
+
},
|
|
1262
461
|
|
|
1263
|
-
|
|
1264
|
-
|
|
462
|
+
statics: {
|
|
463
|
+
/** @type {Object<String,Object<String,Binding>>} map of maps, outer map is indexed by object hash, inner is indexed by binding hash */
|
|
464
|
+
__bindingsBySource: {},
|
|
1265
465
|
|
|
1266
|
-
|
|
1267
|
-
},
|
|
466
|
+
/** @type {Object<String,Object<String,Binding>>} map of maps, outer map is indexed by object hash, inner is indexed by binding hash */
|
|
467
|
+
__bindingsByTarget: {},
|
|
1268
468
|
|
|
1269
469
|
/**
|
|
1270
|
-
*
|
|
1271
|
-
* of all bindings.
|
|
1272
|
-
*
|
|
1273
|
-
* @param id {var} The listener id of the id for a deeper binding.
|
|
1274
|
-
* @param sourceObject {qx.core.Object} The source Object of the binding.
|
|
1275
|
-
* @param sourceEvent {String} The name of the source event.
|
|
1276
|
-
* @param targetObject {qx.core.Object} The target object.
|
|
1277
|
-
* @param targetProperty {String} The name of the property on the target
|
|
1278
|
-
* object.
|
|
470
|
+
* @see {qx.data.SingleValueBinding#construct}
|
|
1279
471
|
*/
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
var hash;
|
|
1288
|
-
|
|
1289
|
-
// add the listener id to the internal registry
|
|
1290
|
-
hash = sourceObject.toHashCode();
|
|
1291
|
-
if (this.__bindings[hash] === undefined) {
|
|
1292
|
-
this.__bindings[hash] = [];
|
|
472
|
+
bind(sourceObject, sourcePropertyChain, targetObject, targetPropertyChain, options) {
|
|
473
|
+
// check for the arguments
|
|
474
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
475
|
+
qx.core.Assert.assertObject(sourceObject, "sourceObject");
|
|
476
|
+
qx.core.Assert.assertString(sourcePropertyChain, "sourcePropertyChain");
|
|
477
|
+
qx.core.Assert.assertObject(targetObject, "targetObject");
|
|
478
|
+
qx.core.Assert.assertString(targetPropertyChain, "targetPropertyChain");
|
|
1293
479
|
}
|
|
1294
480
|
|
|
1295
|
-
|
|
1296
|
-
id,
|
|
1297
|
-
sourceObject,
|
|
1298
|
-
sourceEvent,
|
|
1299
|
-
targetObject,
|
|
1300
|
-
targetProperty
|
|
1301
|
-
];
|
|
481
|
+
let binding = new qx.data.SingleValueBinding(sourcePropertyChain, targetPropertyChain, sourceObject, targetObject, options);
|
|
1302
482
|
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
// add same binding data indexed by target object
|
|
1306
|
-
hash = targetObject.toHashCode();
|
|
1307
|
-
if (this.__bindingsByTarget[hash] === undefined) {
|
|
1308
|
-
this.__bindingsByTarget[hash] = [];
|
|
1309
|
-
}
|
|
1310
|
-
this.__bindingsByTarget[hash].push(binding);
|
|
483
|
+
return binding;
|
|
1311
484
|
},
|
|
1312
485
|
|
|
1313
486
|
/**
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
* given by the user, the {@link #__defaultConversion} will try to convert
|
|
1317
|
-
* the value.
|
|
1318
|
-
*
|
|
1319
|
-
* @param value {var} The value which possibly should be converted.
|
|
1320
|
-
* @param targetObject {qx.core.Object} The target object.
|
|
1321
|
-
* @param targetPropertyChain {String} The property name of the target object.
|
|
1322
|
-
* @param options {Map} The options map which can includes the converter.
|
|
1323
|
-
* For a detailed information on the map, take a look at
|
|
1324
|
-
* {@link #bind}.
|
|
1325
|
-
* @param sourceObject {qx.core.Object} The source object for the binding.
|
|
487
|
+
* Removes the binding with the given id from the given sourceObject. The
|
|
488
|
+
* id has to be the id returned by any of the bind functions.
|
|
1326
489
|
*
|
|
1327
|
-
* @
|
|
1328
|
-
*
|
|
1329
|
-
* @throws {
|
|
1330
|
-
* of the given target object and target property.
|
|
490
|
+
* @param sourceObject {qx.core.Object} The source object of the binding.
|
|
491
|
+
* @param id {var} The id of the binding.
|
|
492
|
+
* @throws {Error} If the binding could not be found.
|
|
1331
493
|
*/
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
targetObject,
|
|
1335
|
-
targetPropertyChain,
|
|
1336
|
-
options,
|
|
1337
|
-
sourceObject
|
|
1338
|
-
) {
|
|
1339
|
-
// do the conversion given by the user
|
|
1340
|
-
if (options && options.converter) {
|
|
1341
|
-
var model;
|
|
1342
|
-
if (targetObject.getModel) {
|
|
1343
|
-
model = targetObject.getModel();
|
|
1344
|
-
}
|
|
1345
|
-
return options.converter(value, model, sourceObject, targetObject);
|
|
1346
|
-
// try default conversion
|
|
1347
|
-
} else {
|
|
1348
|
-
var properties = this.__getPropertyChainArray(targetPropertyChain);
|
|
1349
|
-
var target = this.__getTargetFromChain(targetObject, properties);
|
|
1350
|
-
var lastProperty = targetPropertyChain.substring(
|
|
1351
|
-
targetPropertyChain.lastIndexOf(".") + 1,
|
|
1352
|
-
targetPropertyChain.length
|
|
1353
|
-
);
|
|
1354
|
-
|
|
1355
|
-
// if no target is currently available, return the original value
|
|
1356
|
-
if (target == null) {
|
|
1357
|
-
return value;
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
var propertieDefinition = qx.Class.getPropertyDefinition(
|
|
1361
|
-
target.constructor,
|
|
1362
|
-
lastProperty
|
|
1363
|
-
);
|
|
1364
|
-
|
|
1365
|
-
var check =
|
|
1366
|
-
propertieDefinition == null ? "" : propertieDefinition.check;
|
|
1367
|
-
return this.__defaultConversion(value, check);
|
|
1368
|
-
}
|
|
494
|
+
removeBindingFromObject(sourceObject, binding) {
|
|
495
|
+
binding.dispose();
|
|
1369
496
|
},
|
|
1370
497
|
|
|
1371
498
|
/**
|
|
1372
|
-
*
|
|
1373
|
-
* given object does have a change event and if returns the name of it.
|
|
499
|
+
* Removes all bindings for the given object.
|
|
1374
500
|
*
|
|
1375
|
-
* @param
|
|
1376
|
-
*
|
|
501
|
+
* @param object {qx.core.Object} The object of which the bindings should be
|
|
502
|
+
* removed.
|
|
503
|
+
* @throws {qx.core.AssertionError} If the object is not in the internal
|
|
504
|
+
* registry of the bindings.
|
|
505
|
+
* @throws {Error} If one of the bindings listed internally can not be
|
|
506
|
+
* removed.
|
|
507
|
+
*/
|
|
508
|
+
removeAllBindingsForObject(object) {
|
|
509
|
+
qx.core.Assert.assertNotNull(object, "Null is not possible!");
|
|
510
|
+
qx.data.SingleValueBinding.getAllBindingsForObject(object).forEach(binding => binding[0].dispose());
|
|
511
|
+
},
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Debug function which shows some valuable information about the given
|
|
515
|
+
* binding in console. For that it uses {@link qx.log.Logger}.
|
|
1377
516
|
*
|
|
1378
|
-
* @
|
|
1379
|
-
* @
|
|
1380
|
-
* the given object property pair.
|
|
517
|
+
* @param object {qx.core.Object} the source of the binding.
|
|
518
|
+
* @param id {var} The id of the binding.
|
|
1381
519
|
*/
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
520
|
+
showBindingInLog(object, binding) {
|
|
521
|
+
qx.log.Logger.debug(
|
|
522
|
+
"Binding from '" +
|
|
523
|
+
binding.getSource() +
|
|
524
|
+
"' (" +
|
|
525
|
+
binding.getSourcePath() +
|
|
526
|
+
") to the object '" +
|
|
527
|
+
binding.getTarget() +
|
|
528
|
+
"' (" +
|
|
529
|
+
binding.getTargetPath() +
|
|
530
|
+
")."
|
|
1387
531
|
);
|
|
1388
|
-
|
|
1389
|
-
if (propertieDefinition == null) {
|
|
1390
|
-
return null;
|
|
1391
|
-
}
|
|
1392
|
-
return propertieDefinition.event;
|
|
1393
532
|
},
|
|
1394
533
|
|
|
1395
534
|
/**
|
|
1396
|
-
*
|
|
535
|
+
* Helper for updating the target. Gets the current set data from the source
|
|
536
|
+
* and set that on the target.
|
|
1397
537
|
*
|
|
1398
|
-
* @param
|
|
1399
|
-
* @param
|
|
1400
|
-
*
|
|
1401
|
-
* @
|
|
538
|
+
* @param sourceObject {qx.core.Object} The source of the binding.
|
|
539
|
+
* @param sourcePropertyChain {String} The property chain which represents
|
|
540
|
+
* the source property.
|
|
541
|
+
* @param targetObject {qx.core.Object} The object which the source should
|
|
542
|
+
* be bind to.
|
|
543
|
+
* @param targetPropertyChain {String} The property name of the target
|
|
544
|
+
* object.
|
|
545
|
+
* @param options {Map} The options map perhaps containing the user defined
|
|
546
|
+
* converter.
|
|
547
|
+
*
|
|
548
|
+
* @internal
|
|
1402
549
|
*/
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
// to integer
|
|
1407
|
-
if (
|
|
1408
|
-
(dataType == "Number" || dataType == "String") &&
|
|
1409
|
-
(targetCheck == "Integer" || targetCheck == "PositiveInteger")
|
|
1410
|
-
) {
|
|
1411
|
-
data = parseInt(data, 10);
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
// to string
|
|
1415
|
-
if (
|
|
1416
|
-
(dataType == "Boolean" || dataType == "Number" || dataType == "Date") &&
|
|
1417
|
-
targetCheck == "String"
|
|
1418
|
-
) {
|
|
1419
|
-
data = data + "";
|
|
1420
|
-
}
|
|
550
|
+
updateTarget(sourceObject, sourcePropertyChain, targetObject, targetPropertyChain, options) {
|
|
551
|
+
options ??= {};
|
|
552
|
+
var value = this.resolvePropertyChain(sourceObject, sourcePropertyChain);
|
|
1421
553
|
|
|
1422
|
-
//
|
|
1423
|
-
if (
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
) {
|
|
1427
|
-
data = parseFloat(data);
|
|
554
|
+
// convert the data before setting
|
|
555
|
+
if (options.converter) {
|
|
556
|
+
let model = typeof targetObject.getModel == "function" ? targetObject.getModel() : null;
|
|
557
|
+
value = options.converter(value, model, sourceObject, targetObject);
|
|
1428
558
|
}
|
|
1429
559
|
|
|
1430
|
-
return
|
|
560
|
+
return this.__setTargetValue(targetObject, targetPropertyChain, value);
|
|
1431
561
|
},
|
|
1432
562
|
|
|
1433
563
|
/**
|
|
1434
|
-
*
|
|
1435
|
-
*
|
|
564
|
+
* Sets the given value to the given target after resolving the
|
|
565
|
+
* target property chain.
|
|
1436
566
|
*
|
|
1437
|
-
* @param
|
|
1438
|
-
*
|
|
1439
|
-
* @
|
|
567
|
+
* @param targetObject {qx.core.Object} The object where the property chain
|
|
568
|
+
* starts.
|
|
569
|
+
* @param targetPropertyChain {String} The names of the properties,
|
|
570
|
+
* separated with a dot.
|
|
571
|
+
* @param value {var} The value to set.
|
|
1440
572
|
*/
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
id.sources[i].removeListenerById(id.listenerIds[i]);
|
|
1450
|
-
}
|
|
1451
|
-
// If the listener id is not available, it is most likely
|
|
1452
|
-
// caused by some hidden error situation.
|
|
1453
|
-
// At least an error message should be displayed
|
|
1454
|
-
else {
|
|
1455
|
-
sourceObject.error(
|
|
1456
|
-
"Could not remove deep bindings. Binding id for " +
|
|
1457
|
-
id.sources[i].classname +
|
|
1458
|
-
" could not be found!"
|
|
1459
|
-
);
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
// go through all added listeners (target)
|
|
1464
|
-
for (var i = 0; i < id.targets.length; i++) {
|
|
1465
|
-
// check if a target is available
|
|
1466
|
-
if (id.targets[i]) {
|
|
1467
|
-
if (id.targetListenerIds[i]) {
|
|
1468
|
-
id.targets[i].removeListenerById(id.targetListenerIds[i]);
|
|
1469
|
-
}
|
|
1470
|
-
// If the target listener id is not available, it is most likely
|
|
1471
|
-
// caused by some hidden error situation.
|
|
1472
|
-
// At least an error message should be displayed
|
|
1473
|
-
else {
|
|
1474
|
-
sourceObject.error(
|
|
1475
|
-
"Could not remove target listener. Listener id for target " +
|
|
1476
|
-
id.targets[i].classname +
|
|
1477
|
-
" could not be found!"
|
|
1478
|
-
);
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
} else {
|
|
1483
|
-
// remove the listener
|
|
1484
|
-
sourceObject.removeListenerById(id);
|
|
1485
|
-
}
|
|
573
|
+
__setTargetValue(targetObject, targetPropertyChain, value) {
|
|
574
|
+
let segments = qx.data.SingleValueBinding.__parseSegments(null, targetPropertyChain);
|
|
575
|
+
let lastSegment = segments[segments.length - 1];
|
|
576
|
+
segments[0].setInput(targetObject);
|
|
577
|
+
let out = lastSegment.setTargetValue(value);
|
|
578
|
+
segments.forEach(segment => segment.dispose());
|
|
579
|
+
return out;
|
|
580
|
+
},
|
|
1486
581
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
var source = bindings[i][1];
|
|
1504
|
-
if (this.__bindings[source.toHashCode()]) {
|
|
1505
|
-
qx.lang.Array.remove(
|
|
1506
|
-
this.__bindings[source.toHashCode()],
|
|
1507
|
-
bindings[i]
|
|
1508
|
-
);
|
|
1509
|
-
}
|
|
1510
|
-
return;
|
|
1511
|
-
}
|
|
582
|
+
/**
|
|
583
|
+
* Splits a property path into segments.
|
|
584
|
+
* @param {string} path
|
|
585
|
+
* @returns {string[]} an array of segments, split by dot and square brackets.
|
|
586
|
+
* For example, splitSegments(`a.b[0].c`) will return `["a", "b", "[0]", "c"]`
|
|
587
|
+
*/
|
|
588
|
+
splitSegments(path) {
|
|
589
|
+
let out = [];
|
|
590
|
+
for (let dotSplit of path.split(".")) {
|
|
591
|
+
let bracketSplits = dotSplit.split("[");
|
|
592
|
+
for (let i = 0; i < bracketSplits.length; i++) {
|
|
593
|
+
let bracketSplit = bracketSplits[i];
|
|
594
|
+
if (i > 0) {
|
|
595
|
+
bracketSplit = "[" + bracketSplit;
|
|
596
|
+
}
|
|
597
|
+
out.push(bracketSplit);
|
|
1512
598
|
}
|
|
1513
599
|
}
|
|
1514
|
-
|
|
600
|
+
return out.filter(s => s.length > 0);
|
|
1515
601
|
},
|
|
1516
602
|
|
|
1517
603
|
/**
|
|
1518
|
-
*
|
|
604
|
+
* Finds all bindings for an object, as either a source or target
|
|
1519
605
|
*
|
|
1520
|
-
* @param
|
|
1521
|
-
*
|
|
1522
|
-
* @throws {qx.core.AssertionError} If the object is not in the internal
|
|
1523
|
-
* registry of the bindings.
|
|
1524
|
-
* @throws {Error} If one of the bindings listed internally can not be
|
|
1525
|
-
* removed.
|
|
606
|
+
* @param {qx.core.Object} object
|
|
607
|
+
* @returns {BindingRecord[]} An array of the bindings represented as records.
|
|
1526
608
|
*/
|
|
1527
|
-
|
|
1528
|
-
|
|
609
|
+
getAllBindingsForObject(object) {
|
|
610
|
+
const SingleValueBinding = qx.data.SingleValueBinding;
|
|
611
|
+
let allBindings = {
|
|
612
|
+
...(SingleValueBinding.__bindingsBySource[object.toHashCode()] ?? {}),
|
|
613
|
+
...(SingleValueBinding.__bindingsByTarget[object.toHashCode()] ?? {})
|
|
614
|
+
};
|
|
615
|
+
return Object.values(allBindings).map(binding => binding.asRecord());
|
|
616
|
+
},
|
|
1529
617
|
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
618
|
+
/**
|
|
619
|
+
* Returns a map containing for every bound object an array of data binding
|
|
620
|
+
* information. The key of the map is the hash code of the bound objects.
|
|
621
|
+
* Every binding is represented by an array containing id, sourceObject,
|
|
622
|
+
* sourceEvent, targetObject and targetProperty.
|
|
623
|
+
*
|
|
624
|
+
* @return {Object<string, BindingInfo>} Map containing all bindings.
|
|
625
|
+
*
|
|
626
|
+
* @typedef {[qx.data.SingleValueBinding, qx.core.Object, string, qx.core.Object, string]} BindingInfo
|
|
627
|
+
* Stores the binding ID, source object, source path, target object and target path respectively.
|
|
628
|
+
*/
|
|
629
|
+
getAllBindings() {
|
|
630
|
+
let bindings = qx.data.SingleValueBinding.__bindingsBySource;
|
|
1536
631
|
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
this.removeBindingFromObject(object, bindings[i][0]);
|
|
632
|
+
let result = {};
|
|
633
|
+
for (let [objectHash, objectBindings] of Object.entries(bindings)) {
|
|
634
|
+
let objectBindingsArray = [];
|
|
635
|
+
for (let [bindingHash, binding] of Object.entries(objectBindings)) {
|
|
636
|
+
objectBindingsArray.push([binding, binding.getSource(), binding.getSourcePath(), binding.getTarget(), binding.getTargetPath()]);
|
|
1543
637
|
}
|
|
638
|
+
result[objectHash] = objectBindingsArray;
|
|
1544
639
|
}
|
|
1545
|
-
|
|
1546
|
-
var hash = object.toHashCode();
|
|
1547
|
-
delete this.__bindings[hash];
|
|
1548
|
-
delete this.__bindingsByTarget[hash];
|
|
640
|
+
return result;
|
|
1549
641
|
},
|
|
1550
642
|
|
|
1551
643
|
/**
|
|
@@ -1561,149 +653,158 @@ qx.Class.define("qx.data.SingleValueBinding", {
|
|
|
1561
653
|
* removed.
|
|
1562
654
|
*/
|
|
1563
655
|
removeRelatedBindings(object, relatedObject) {
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
)
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
);
|
|
656
|
+
const SingleValueBinding = qx.data.SingleValueBinding;
|
|
657
|
+
|
|
658
|
+
let bySourceObject = SingleValueBinding.__bindingsBySource[object.toHashCode()];
|
|
659
|
+
|
|
660
|
+
if (bySourceObject) {
|
|
661
|
+
Object.values(bySourceObject).forEach(binding => {
|
|
662
|
+
if (binding.getTarget() === relatedObject) {
|
|
663
|
+
binding.dispose();
|
|
664
|
+
}
|
|
665
|
+
});
|
|
1575
666
|
}
|
|
1576
667
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
var source = bindings[i][1];
|
|
1583
|
-
var target = bindings[i][3];
|
|
1584
|
-
if (source === relatedObject || target === relatedObject) {
|
|
1585
|
-
this.removeBindingFromObject(object, bindings[i][0]);
|
|
668
|
+
let byRelatedObject = SingleValueBinding.__bindingsBySource[relatedObject.toHashCode()];
|
|
669
|
+
if (byRelatedObject) {
|
|
670
|
+
Object.values(byRelatedObject).forEach(binding => {
|
|
671
|
+
if (binding.getTarget() === object) {
|
|
672
|
+
binding.dispose();
|
|
1586
673
|
}
|
|
1587
|
-
}
|
|
674
|
+
});
|
|
1588
675
|
}
|
|
1589
676
|
},
|
|
1590
677
|
|
|
1591
678
|
/**
|
|
1592
|
-
*
|
|
679
|
+
* Helper method that sets a value for a named property
|
|
1593
680
|
*
|
|
1594
|
-
* @param
|
|
1595
|
-
*
|
|
1596
|
-
*
|
|
1597
|
-
* @return {Array} An array of binding informations. Every binding
|
|
1598
|
-
* information is an array itself containing id, sourceObject,
|
|
1599
|
-
* sourceEvent, targetObject and targetProperty in that order.
|
|
681
|
+
* @param {qx.core.Object} target object to have a property set
|
|
682
|
+
* @param {String} propertyName the name of the property
|
|
683
|
+
* @param {Object?} value the value to set
|
|
1600
684
|
*/
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
if (!sourceBindings && !targetBindings) {
|
|
1611
|
-
return [];
|
|
1612
|
-
}
|
|
1613
|
-
if (!sourceBindings) {
|
|
1614
|
-
return qx.lang.Array.clone(targetBindings);
|
|
1615
|
-
}
|
|
1616
|
-
if (!targetBindings) {
|
|
1617
|
-
return qx.lang.Array.clone(sourceBindings);
|
|
685
|
+
set(target, propertyName, value) {
|
|
686
|
+
let prop = qx.util.PropertyUtil.getProperty(target.constructor, propertyName);
|
|
687
|
+
if (!prop) {
|
|
688
|
+
let setFuncName = "set" + qx.lang.String.firstUp(propertyName);
|
|
689
|
+
if (typeof target[setFuncName] == "function") {
|
|
690
|
+
return target[setFuncName](value);
|
|
691
|
+
} else {
|
|
692
|
+
throw new Error(`Property ${propertyName} not found on ${target.classname}`);
|
|
693
|
+
}
|
|
1618
694
|
}
|
|
1619
695
|
|
|
1620
|
-
|
|
696
|
+
if (prop.isAsync()) {
|
|
697
|
+
return prop.setAsync(target, value);
|
|
698
|
+
} else {
|
|
699
|
+
return prop.set(target, value);
|
|
700
|
+
}
|
|
1621
701
|
},
|
|
1622
702
|
|
|
1623
703
|
/**
|
|
1624
|
-
*
|
|
1625
|
-
*
|
|
1626
|
-
* @
|
|
1627
|
-
*
|
|
704
|
+
* Helper method to get a value of a named property
|
|
705
|
+
*
|
|
706
|
+
* @param {qx.core.Object} target object to have a property get
|
|
707
|
+
* @param {String} propertyName the name of the property
|
|
708
|
+
* @returns {Object?} the property value
|
|
1628
709
|
*/
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
delete this.__bindings[hash];
|
|
1636
|
-
continue;
|
|
1637
|
-
}
|
|
1638
|
-
this.removeAllBindingsForObject(object);
|
|
710
|
+
get(target, propertyName) {
|
|
711
|
+
let prop = qx.util.PropertyUtil.getProperty(target.constructor, propertyName);
|
|
712
|
+
if (prop.isAsync()) {
|
|
713
|
+
return prop.getAsync(target);
|
|
714
|
+
} else {
|
|
715
|
+
return prop.get(target);
|
|
1639
716
|
}
|
|
1640
|
-
// reset the bindings map
|
|
1641
|
-
this.__bindings = {};
|
|
1642
717
|
},
|
|
1643
718
|
|
|
1644
719
|
/**
|
|
1645
|
-
*
|
|
1646
|
-
* information. The key of the map is the hash code of the bound objects.
|
|
1647
|
-
* Every binding is represented by an array containing id, sourceObject,
|
|
1648
|
-
* sourceEvent, targetObject and targetProperty.
|
|
720
|
+
* Helper method that resets a named property
|
|
1649
721
|
*
|
|
1650
|
-
* @
|
|
722
|
+
* @param {qx.core.Object} target object to have a property set
|
|
723
|
+
* @param {String} propertyName the name of the property
|
|
724
|
+
|
|
1651
725
|
*/
|
|
1652
|
-
|
|
1653
|
-
|
|
726
|
+
reset(target, propertyName) {
|
|
727
|
+
let prop = qx.util.PropertyUtil.getProperty(target.constructor, propertyName);
|
|
728
|
+
if (!prop) {
|
|
729
|
+
let setFuncName = "reset" + qx.lang.String.firstUp(propertyName);
|
|
730
|
+
if (typeof target[setFuncName] == "function") {
|
|
731
|
+
return target[setFuncName]();
|
|
732
|
+
} else {
|
|
733
|
+
throw new Error(`Property ${propertyName} not found on ${target.classname}`);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
if (prop.isAsync()) {
|
|
738
|
+
return prop.resetAsync(target);
|
|
739
|
+
} else {
|
|
740
|
+
return prop.reset(target);
|
|
741
|
+
}
|
|
1654
742
|
},
|
|
1655
743
|
|
|
1656
744
|
/**
|
|
1657
|
-
* Debug function which shows some valuable information about the given
|
|
1658
|
-
* binding in console. For that it uses {@link qx.log.Logger}.
|
|
1659
745
|
*
|
|
1660
|
-
*
|
|
1661
|
-
*
|
|
746
|
+
* Internal helper for getting the current set value at the property chain.
|
|
747
|
+
*
|
|
748
|
+
* @param {qx.core.Object} object The source of the binding.
|
|
749
|
+
* @param {String} propertyChain The property chain which represents
|
|
750
|
+
* the source property.
|
|
751
|
+
* @return {var?undefined} Returns the set value if defined.
|
|
1662
752
|
*/
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
binding = this.__bindings[object.toHashCode()][i];
|
|
1670
|
-
break;
|
|
753
|
+
resolvePropertyChain(object, propertyChain) {
|
|
754
|
+
let segments = qx.data.SingleValueBinding.__parseSegments(null, propertyChain);
|
|
755
|
+
let out;
|
|
756
|
+
let receiver = {
|
|
757
|
+
setInput(value) {
|
|
758
|
+
out = value;
|
|
1671
759
|
}
|
|
1672
|
-
}
|
|
760
|
+
};
|
|
761
|
+
segments.at(-1).setOutputReceiver(receiver);
|
|
762
|
+
let promise = segments[0].setInput(object);
|
|
763
|
+
|
|
764
|
+
const cb = () => {
|
|
765
|
+
let first = segments[0];
|
|
766
|
+
if (first instanceof qx.data.binding.PropNameSegment) {
|
|
767
|
+
let property = qx.Class.getByProperty(object.constructor, first.getPropName());
|
|
768
|
+
qx.core.Assert.assertNotNull(property, `Object ${object.classname} does not have property ${first.getPropName()}`);
|
|
769
|
+
}
|
|
770
|
+
segments.forEach(segment => segment.dispose());
|
|
771
|
+
return out;
|
|
772
|
+
};
|
|
1673
773
|
|
|
1674
|
-
if (
|
|
1675
|
-
|
|
774
|
+
if (qx.Promise.isPromise(promise)) {
|
|
775
|
+
return promise.then(cb);
|
|
1676
776
|
} else {
|
|
1677
|
-
|
|
1678
|
-
"Binding from '" +
|
|
1679
|
-
binding[1] +
|
|
1680
|
-
"' (" +
|
|
1681
|
-
binding[2] +
|
|
1682
|
-
") to the object '" +
|
|
1683
|
-
binding[3] +
|
|
1684
|
-
"' (" +
|
|
1685
|
-
binding[4] +
|
|
1686
|
-
").";
|
|
777
|
+
return cb();
|
|
1687
778
|
}
|
|
1688
|
-
|
|
1689
|
-
qx.log.Logger.debug(message);
|
|
1690
779
|
},
|
|
1691
780
|
|
|
1692
781
|
/**
|
|
1693
|
-
*
|
|
1694
|
-
*
|
|
1695
|
-
* @
|
|
782
|
+
* Parses a path and creates an array of `qx.data.binding.AbstractSegment`
|
|
783
|
+
*
|
|
784
|
+
* @param {String} path the path to parse
|
|
785
|
+
* @return {qx.data.binding.AbstractSegment[]?} the new array of segments
|
|
1696
786
|
*/
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
787
|
+
__parseSegments(binding, path) {
|
|
788
|
+
let segsStrings = qx.data.SingleValueBinding.splitSegments(path);
|
|
789
|
+
let segments = [];
|
|
790
|
+
|
|
791
|
+
for (let seg of segsStrings) {
|
|
792
|
+
//if it's an array index:
|
|
793
|
+
if (seg.startsWith("[")) {
|
|
794
|
+
segments.push(new qx.data.binding.ArrayIndexSegment(binding, seg));
|
|
795
|
+
} else {
|
|
796
|
+
//otherwise, it's a normal path
|
|
797
|
+
segments.push(new qx.data.binding.PropNameSegment(binding, seg));
|
|
1705
798
|
}
|
|
1706
799
|
}
|
|
800
|
+
|
|
801
|
+
segments.forEach((seg, index) => {
|
|
802
|
+
if (index < segments.length - 1) {
|
|
803
|
+
seg.setOutputReceiver(segments[index + 1]);
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
return segments;
|
|
1707
808
|
}
|
|
1708
809
|
}
|
|
1709
810
|
});
|