@qooxdoo/framework 7.9.2 → 8.0.0-beta.2
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 +224 -33
- package/Manifest.json +3 -3
- package/bin/tools/utils.js +50 -13
- package/lib/compiler/compile-info.json +297 -227
- package/lib/compiler/index.js +55319 -47085
- package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/default.tmpl.js +6 -7
- package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/cli/templates/class/singleton.tmpl.js +5 -6
- 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/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/schema/compile-1-0-0.json +21 -5
- 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 +23 -24
- 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 -19
- 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 +24 -6
- package/source/class/qx/core/MProperty.js +123 -115
- 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 +94 -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 +1482 -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 +595 -1496
- package/source/class/qx/data/binding/AbstractSegment.js +197 -0
- package/source/class/qx/data/binding/ArrayIndexSegment.js +155 -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/TestCase.js +4 -1
- 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 +38 -31
- 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/html/Jsx.js +2 -3
- package/source/class/qx/html/Node.js +3 -3
- package/source/class/qx/io/jsonrpc/Client.js +2 -2
- 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/promise/NativeWrapper.js +1 -1
- 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 +1363 -118
- 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 +130 -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/Meta.js +7 -5
- 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 +22 -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/modern/Appearance.js +21 -0
- package/source/class/qx/theme/simple/Appearance.js +52 -95
- package/source/class/qx/theme/simple/Decoration.js +0 -1
- package/source/class/qx/theme/tangible/Appearance.js +3 -1
- package/source/class/qx/tool/cli/AbstractCliApp.js +88 -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 -13
- package/source/class/qx/tool/compiler/Console.js +2 -0
- package/source/class/qx/tool/compiler/MetaDatabase.js +47 -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 +630 -590
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Config.js +22 -20
- package/source/class/qx/tool/{cli → compiler/cli}/commands/Create.js +78 -55
- 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 +70 -62
- 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 +57 -33
- 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 +196 -179
- 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 +92 -71
- 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 +9 -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/Browserify.js +142 -80
- 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 +7 -31
- 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 +5 -20
- 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/class/default.tmpl.js +6 -7
- package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/cli/templates/class/singleton.tmpl.js +5 -6
- 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/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/schema/compile-1-0-0.json +21 -5
- 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/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/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/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/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
package/source/class/qx/Class.js
CHANGED
|
@@ -5,94 +5,106 @@
|
|
|
5
5
|
http://qooxdoo.org
|
|
6
6
|
|
|
7
7
|
Copyright:
|
|
8
|
-
|
|
8
|
+
2022 Derrell Lipman
|
|
9
|
+
2023-24 John Spackman, Zenesis Ltd (johnspackman, https://www.zenesis.com)
|
|
9
10
|
|
|
10
11
|
License:
|
|
11
12
|
MIT: https://opensource.org/licenses/MIT
|
|
12
13
|
See the LICENSE file in the project's top-level directory for details.
|
|
13
14
|
|
|
14
15
|
Authors:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* John Spackman (john.spackman@zenesis.com)
|
|
16
|
+
* Derrell Lipman (derrell)
|
|
17
|
+
* John Spackman (johnspackman)
|
|
18
18
|
|
|
19
19
|
************************************************************************ */
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* object-oriented features.
|
|
24
|
-
*
|
|
25
|
-
* Its {@link #define} method is used to create qooxdoo classes.
|
|
26
|
-
*
|
|
27
|
-
* Each instance of a class defined by {@link #define} has
|
|
28
|
-
* the following keys attached to the constructor and the prototype:
|
|
29
|
-
*
|
|
30
|
-
* <table>
|
|
31
|
-
* <tr><th><code>classname</code></th><td>The fully-qualified name of the class (e.g. <code>"qx.ui.core.Widget"</code>).</td></tr>
|
|
32
|
-
* <tr><th><code>basename</code></th><td>The namespace part of the class name (e.g. <code>"qx.ui.core"</code>).</td></tr>
|
|
33
|
-
* <tr><th><code>constructor</code></th><td>A reference to the constructor of the class.</td></tr>
|
|
34
|
-
* <tr><th><code>superclass</code></th><td>A reference to the constructor of the super class.</td></tr>
|
|
35
|
-
* </table>
|
|
36
|
-
*
|
|
37
|
-
* Each method may access static members of the same class by using
|
|
38
|
-
* <code>this.self(arguments)</code> ({@link qx.core.Object#self}):
|
|
39
|
-
* <pre class='javascript'>
|
|
40
|
-
* statics : { FOO : "bar" },
|
|
41
|
-
* members: {
|
|
42
|
-
* baz: function(x) {
|
|
43
|
-
* this.self(arguments).FOO;
|
|
44
|
-
* ...
|
|
45
|
-
* }
|
|
46
|
-
* }
|
|
47
|
-
* </pre>
|
|
48
|
-
*
|
|
49
|
-
* Each overriding method may call the overridden method by using
|
|
50
|
-
* <code>this.base(arguments [, ...])</code> ({@link qx.core.Object#base}). This is also true for calling
|
|
51
|
-
* the constructor of the superclass.
|
|
52
|
-
* <pre class='javascript'>
|
|
53
|
-
* members: {
|
|
54
|
-
* foo: function(x) {
|
|
55
|
-
* this.base(arguments, x);
|
|
56
|
-
* ...
|
|
57
|
-
* }
|
|
58
|
-
* }
|
|
59
|
-
* </pre>
|
|
60
|
-
*
|
|
61
|
-
* By using <code>qx.Class</code> within an app, the native JS data types are
|
|
62
|
-
* conveniently polyfilled according to {@link qx.lang.normalize}.
|
|
63
|
-
*
|
|
64
|
-
* Annotations can be added to classes, constructors, destructors, and methods, properties, and statics -
|
|
65
|
-
* see <code>qx.Annotation</code> for examples and means access annotations at runtime.
|
|
66
|
-
*
|
|
67
|
-
* @require(qx.Interface)
|
|
68
|
-
* @require(qx.Mixin)
|
|
69
|
-
* @require(qx.lang.normalize.Array)
|
|
70
|
-
* @require(qx.lang.normalize.Date)
|
|
71
|
-
* @require(qx.lang.normalize.Error)
|
|
72
|
-
* @require(qx.lang.normalize.Function)
|
|
73
|
-
* @require(qx.lang.normalize.String)
|
|
74
|
-
* @require(qx.lang.normalize.Object)
|
|
75
|
-
* @require(qx.lang.normalize.Number)
|
|
76
|
-
*/
|
|
21
|
+
let BROKEN = false;
|
|
22
|
+
|
|
77
23
|
qx.Bootstrap.define("qx.Class", {
|
|
24
|
+
type: "static",
|
|
25
|
+
|
|
26
|
+
environment: {
|
|
27
|
+
"qx.Class.futureCheckJsDoc": false
|
|
28
|
+
},
|
|
29
|
+
|
|
78
30
|
statics: {
|
|
79
31
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
32
|
+
* Options configured mostly by unit tests
|
|
33
|
+
*
|
|
34
|
+
* @internal
|
|
82
35
|
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
36
|
+
$$options: {
|
|
37
|
+
/**
|
|
38
|
+
* Whether to warn if a member variable is assigned without
|
|
39
|
+
* being declared in the "members" section
|
|
40
|
+
*/
|
|
41
|
+
"Warn member not declared": false,
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Allow all private and internal-use properties methods -- e.g.,
|
|
45
|
+
* those beginning with `$$`, setX, getX, resetX, etc. -- to be
|
|
46
|
+
* enumerated, configured, and written to. Ideally, this is set to
|
|
47
|
+
* `false`, so that those private properties don't get mucked with.
|
|
48
|
+
* The unit tests, though, require that they be enumerable,
|
|
49
|
+
* configurable and writable. Setting this to `false` breaks those
|
|
50
|
+
* tests, and although we could set it to 'true' only for the tests,
|
|
51
|
+
* we'd then be testing different behavior than what normal apps would
|
|
52
|
+
* use. I think we'll just live with all properties being enumerable,
|
|
53
|
+
* configurable, and writable for the time being.
|
|
54
|
+
*/
|
|
55
|
+
propsAccessible: true
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/** Properties that are predefined in Object */
|
|
59
|
+
objectProperties: new Set(["hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"]),
|
|
86
60
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
61
|
+
/** The global object registry */
|
|
62
|
+
$$registry: qx.Bootstrap.$$registry,
|
|
63
|
+
|
|
64
|
+
/** Supported keys for property definitions */
|
|
65
|
+
_allowedPropKeys: {
|
|
66
|
+
"@": null, // Anything
|
|
67
|
+
name: "string", // String
|
|
68
|
+
dereference: "boolean", // Boolean
|
|
69
|
+
inheritable: "boolean", // Boolean
|
|
70
|
+
nullable: "boolean", // Boolean
|
|
71
|
+
themeable: "boolean", // Boolean
|
|
72
|
+
refine: "boolean", // Boolean
|
|
73
|
+
init: null, // var
|
|
74
|
+
apply: ["string", "function"], // String, Function
|
|
75
|
+
event: ["string", "object"], // String or null
|
|
76
|
+
check: null, // Array, String, Function
|
|
77
|
+
transform: null, // String, Function
|
|
78
|
+
async: "boolean", // Boolean
|
|
79
|
+
deferredInit: "boolean", // Boolean
|
|
80
|
+
validate: ["string", "function"], // String, Function
|
|
81
|
+
isEqual: ["string", "function"], // String, Function
|
|
82
|
+
autoApply: "boolean", // Boolean
|
|
83
|
+
get: ["string", "function"], // String, Function
|
|
84
|
+
set: ["string", "function"], // String, Function
|
|
85
|
+
getAsync: ["string", "function"], // String, Function
|
|
86
|
+
setAsync: ["string", "function"], // String, Function
|
|
87
|
+
initFunction: "function", // Function
|
|
88
|
+
storage: "function", // implements qx.core.propertystorage.IStorage
|
|
89
|
+
immutable: "string" // String
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
/** Supported keys for property group definitions */
|
|
93
|
+
_allowedPropGroupKeys: {
|
|
94
|
+
"@": null, // Anything
|
|
95
|
+
name: "string", // String
|
|
96
|
+
group: "object", // Array
|
|
97
|
+
mode: "string", // String
|
|
98
|
+
themeable: "boolean" // Boolean
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/** Deprecated keys for properties, that we want to warn about */
|
|
102
|
+
$$deprecatedPropKeys: {},
|
|
92
103
|
|
|
93
104
|
/**
|
|
94
|
-
* Define a new class using the qooxdoo class system. This sets
|
|
95
|
-
* namespace for the class and generates the class from
|
|
105
|
+
* Define a new class using the qooxdoo class system. This sets
|
|
106
|
+
* up the namespace for the class and generates the class from
|
|
107
|
+
* the definition map.
|
|
96
108
|
*
|
|
97
109
|
* Example:
|
|
98
110
|
* <pre class='javascript'>
|
|
@@ -171,137 +183,417 @@ qx.Bootstrap.define("qx.Class", {
|
|
|
171
183
|
* Implementation behind `define` - this exists just for the simplicity of wrapping an exception
|
|
172
184
|
* handler around the code
|
|
173
185
|
*
|
|
174
|
-
* @param {
|
|
175
|
-
*
|
|
176
|
-
*
|
|
186
|
+
* @param config {Map ? null}
|
|
187
|
+
* Class definition structure. The configuration map has the following
|
|
188
|
+
* keys:
|
|
189
|
+
* <table>
|
|
190
|
+
* <tr>
|
|
191
|
+
* <th>Name</th>
|
|
192
|
+
* <th>Type</th>
|
|
193
|
+
* <th>Description</th>
|
|
194
|
+
* </tr>
|
|
195
|
+
* <tr>
|
|
196
|
+
* <th>type</th>
|
|
197
|
+
* <td>String</td>
|
|
198
|
+
* <td>
|
|
199
|
+
* Type of the class. Valid types are "abstract",
|
|
200
|
+
* "static" and "singleton". If unset it defaults to a
|
|
201
|
+
* regular non-static class if an `extend` key is
|
|
202
|
+
* provided; otherwise, to a static class.
|
|
203
|
+
* </td>
|
|
204
|
+
* </tr>
|
|
205
|
+
* <tr>
|
|
206
|
+
* <th>extend</th>
|
|
207
|
+
* <td>Class</td>
|
|
208
|
+
* <td>The super class the current class inherits from.</td>
|
|
209
|
+
* </tr>
|
|
210
|
+
* <tr>
|
|
211
|
+
* <th>implement</th>
|
|
212
|
+
* <td>Interface | Interface[]</td>
|
|
213
|
+
* <td>Single interface or array of interfaces the class implements.</td>
|
|
214
|
+
* </tr>
|
|
215
|
+
* <tr>
|
|
216
|
+
* <th>include</th>
|
|
217
|
+
* <td>Mixin | Mixin[]</td>
|
|
218
|
+
* <td>
|
|
219
|
+
* Single mixin or array of mixins, which will be merged into
|
|
220
|
+
* the class.
|
|
221
|
+
* </td>
|
|
222
|
+
* </tr>
|
|
223
|
+
* <tr>
|
|
224
|
+
* <th>construct</th>
|
|
225
|
+
* <td>Function</td>
|
|
226
|
+
* <td>The constructor of the class.</td>
|
|
227
|
+
* </tr>
|
|
228
|
+
* <tr>
|
|
229
|
+
* <th>statics</th>
|
|
230
|
+
* <td>Map</td>
|
|
231
|
+
* <td>Map of static members of the class.</td>
|
|
232
|
+
* </tr>
|
|
233
|
+
* <tr>
|
|
234
|
+
* <th>properties</th>
|
|
235
|
+
* <td>Map</td>
|
|
236
|
+
* <td>
|
|
237
|
+
* Map of property definitions. For a description of the
|
|
238
|
+
* format of a property definition see {@link
|
|
239
|
+
* qx.core.Property}.
|
|
240
|
+
* </td>
|
|
241
|
+
* </tr>
|
|
242
|
+
* <tr>
|
|
243
|
+
* <th>members</th>
|
|
244
|
+
* <td>Map</td>
|
|
245
|
+
* <td>Map of instance members of the class.</td>
|
|
246
|
+
* </tr>
|
|
247
|
+
* <tr>
|
|
248
|
+
* <th>environment</th>
|
|
249
|
+
* <td>Map</td>
|
|
250
|
+
* <td>
|
|
251
|
+
* Map of environment settings for this class. For a
|
|
252
|
+
* description of the format of a setting see {@link
|
|
253
|
+
* qx.core.Environment}.
|
|
254
|
+
* </td>
|
|
255
|
+
* </tr>
|
|
256
|
+
* <tr>
|
|
257
|
+
* <th>events</th>
|
|
258
|
+
* <td>Map</td>
|
|
259
|
+
* <td>
|
|
260
|
+
* Map of events the class fires. The keys are the names of
|
|
261
|
+
* the events and the values are the corresponding event type
|
|
262
|
+
* class names.
|
|
263
|
+
* </td>
|
|
264
|
+
* </tr>
|
|
265
|
+
* <tr>
|
|
266
|
+
* <th>defer</th>
|
|
267
|
+
* <td>Function</td>
|
|
268
|
+
* <td>
|
|
269
|
+
* Function that is called at the end of processing the class
|
|
270
|
+
* declaration. It allows access to the declared statics,
|
|
271
|
+
* members and properties.
|
|
272
|
+
* </td>
|
|
273
|
+
* </tr>
|
|
274
|
+
* <tr>
|
|
275
|
+
* <th>destruct</th>
|
|
276
|
+
* <td>Function</td>
|
|
277
|
+
* <td>The destructor of the class.</td>
|
|
278
|
+
* </tr>
|
|
279
|
+
* <tr>
|
|
280
|
+
* <th>delegate</th>
|
|
281
|
+
* <td>Map</td>
|
|
282
|
+
* <td>
|
|
283
|
+
* EXPERIMENTAL: Special-use-case handling of storage
|
|
284
|
+
* setters/getters for non-properties. See the developer
|
|
285
|
+
* documentation.
|
|
286
|
+
* </td>
|
|
287
|
+
* </tr>
|
|
288
|
+
* </table>
|
|
289
|
+
*
|
|
290
|
+
* @return {Class}
|
|
291
|
+
* The defined class
|
|
177
292
|
*/
|
|
178
|
-
__defineImpl(
|
|
179
|
-
|
|
180
|
-
|
|
293
|
+
__defineImpl(className, config) {
|
|
294
|
+
let clazz;
|
|
295
|
+
let proxy;
|
|
296
|
+
let handler;
|
|
297
|
+
let path;
|
|
298
|
+
let classnameComponents;
|
|
299
|
+
let implicitType = false;
|
|
300
|
+
|
|
301
|
+
// Ensure the desginated class has not already been defined
|
|
302
|
+
if (className && qx.Bootstrap.$$registry[className]) {
|
|
303
|
+
throw new Error(`${className} is already defined; cannot redefine a class`);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Process environment
|
|
307
|
+
let environment = config.environment || {};
|
|
308
|
+
for (let key in environment) {
|
|
309
|
+
qx.core.Environment.add(key, environment[key]);
|
|
181
310
|
}
|
|
182
311
|
|
|
183
312
|
// Normalize include to array
|
|
184
|
-
if (
|
|
185
|
-
config.include &&
|
|
186
|
-
!(qx.Bootstrap.getClass(config.include) === "Array")
|
|
187
|
-
) {
|
|
313
|
+
if (config.include && qx.Bootstrap.getClass(config.include) != "Array") {
|
|
188
314
|
config.include = [config.include];
|
|
189
315
|
}
|
|
190
316
|
|
|
191
317
|
// Normalize implement to array
|
|
192
|
-
if (
|
|
193
|
-
config.implement &&
|
|
194
|
-
!(qx.Bootstrap.getClass(config.implement) === "Array")
|
|
195
|
-
) {
|
|
318
|
+
if (config.implement && qx.Bootstrap.getClass(config.implement) != "Array") {
|
|
196
319
|
config.implement = [config.implement];
|
|
197
320
|
}
|
|
198
321
|
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
if (
|
|
202
|
-
config.
|
|
322
|
+
// Explicit null `extend` key means extend from Object. Otherwise,
|
|
323
|
+
// falsy `extend` means it's a static class.
|
|
324
|
+
if (config.extend === null) {
|
|
325
|
+
config.extend = Object;
|
|
326
|
+
} else if (!config.extend) {
|
|
327
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
328
|
+
if (config.type && config.type != "static") {
|
|
329
|
+
throw new Error(`${className}: ` + `No 'extend' key, but 'type' is not 'static' ` + `(found ${config.type})`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
203
333
|
implicitType = true;
|
|
334
|
+
config.type = "static";
|
|
335
|
+
} else if (config.extendNativeClass) {
|
|
336
|
+
// They're extending a native `class`. We need ability to call
|
|
337
|
+
// its constructor. That is supposed to work only via the
|
|
338
|
+
// `new` keyword; there's no way I've found yet to call a
|
|
339
|
+
// native lass (superclass) constructor from a qooxdoo class'
|
|
340
|
+
// constructor, so the native class must be enhanced. We need
|
|
341
|
+
// the new `extendNativeClass` config key because there's
|
|
342
|
+
// otherwise no way to know that it's a native class without
|
|
343
|
+
// inspecting the transpiled code (`config.extend.toString()`)
|
|
344
|
+
// to see if it contains `"_classCallCheck(this"`, and that's
|
|
345
|
+
// not reliable because someone could use that function name
|
|
346
|
+
// in their own, non-native class. Note that the native class
|
|
347
|
+
// is munged: its 'constructor' method is altered.
|
|
348
|
+
//
|
|
349
|
+
// THIS IS NOT YET FUNCTIONAL. Until we get it working,
|
|
350
|
+
// `extendNativeClass` is commented out in
|
|
351
|
+
// qx.Bootstrap._allowedNonStaticKeys, so we can't get here.
|
|
352
|
+
let orig = config.extend;
|
|
353
|
+
config.extend.constructor = function (...args) {
|
|
354
|
+
return Reflect.construct(orig, ...args, this);
|
|
355
|
+
};
|
|
356
|
+
} else if (qx.core.Environment.get("qx.debug") && config.extend.toString()?.includes("_classCallCheck(this")) {
|
|
357
|
+
console.warn(
|
|
358
|
+
`${className}: ` +
|
|
359
|
+
"It looks like you may be extending a native JavaScript class " +
|
|
360
|
+
"but you neglected to add `extendNativeClass : true` to your " +
|
|
361
|
+
"configuration. Calling the native class (superclass) constructor " +
|
|
362
|
+
"and methods may not work reliably. " +
|
|
363
|
+
"If you are not extending a native JavaScript class, you are " +
|
|
364
|
+
"seeing this warning because your superclass constructor " +
|
|
365
|
+
"references the function `_classCallCheck`."
|
|
366
|
+
);
|
|
204
367
|
}
|
|
205
368
|
|
|
206
|
-
// Validate incoming data
|
|
207
369
|
if (qx.core.Environment.get("qx.debug")) {
|
|
370
|
+
Object.keys(config).forEach(key => {
|
|
371
|
+
let allowedKeys = config.type == "static" ? qx.Bootstrap._allowedStaticKeys : qx.Bootstrap._allowedNonStaticKeys;
|
|
372
|
+
|
|
373
|
+
// Ensure this key is allowed
|
|
374
|
+
if (!(key in allowedKeys)) {
|
|
375
|
+
if (config.type == "static") {
|
|
376
|
+
throw new Error(`${className}: ` + `disallowed key in static class configuration: ${key}`);
|
|
377
|
+
} else {
|
|
378
|
+
throw new Error(`${className}: ` + `unrecognized key in class configuration: ${key}`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Ensure its value is of the correct type
|
|
383
|
+
if (typeof config[key] != allowedKeys[key]) {
|
|
384
|
+
throw new Error(`${className}: ` + `typeof value for key ${key} must be ${allowedKeys[key]}; ` + `found ${typeof config[key]}`);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
|
|
208
388
|
try {
|
|
209
|
-
|
|
210
|
-
} catch (
|
|
389
|
+
qx.Class._validateConfig(className, config);
|
|
390
|
+
} catch (e) {
|
|
211
391
|
if (implicitType) {
|
|
212
|
-
|
|
213
|
-
'Assumed static class because no "extend" key was found. ' +
|
|
214
|
-
ex.message;
|
|
392
|
+
e.message = 'Assumed static class because no "extend" key was found. ' + e.message;
|
|
215
393
|
}
|
|
216
|
-
throw
|
|
394
|
+
throw e;
|
|
217
395
|
}
|
|
396
|
+
|
|
397
|
+
qx.Class._validatePropertyDefinitions(className, config);
|
|
218
398
|
}
|
|
219
399
|
|
|
220
|
-
// Create the class
|
|
221
|
-
|
|
222
|
-
name,
|
|
223
|
-
config.type,
|
|
224
|
-
config.extend,
|
|
225
|
-
config.statics,
|
|
226
|
-
config.construct,
|
|
227
|
-
config.destruct,
|
|
228
|
-
config.include
|
|
229
|
-
);
|
|
400
|
+
// Create the new class
|
|
401
|
+
clazz = qx.Class._extend(className, config);
|
|
230
402
|
|
|
231
403
|
// Initialise class and constructor/destructor annotations
|
|
232
|
-
["@", "@construct", "@destruct"].forEach(
|
|
233
|
-
|
|
234
|
-
}
|
|
404
|
+
["@", "@construct", "@destruct"].forEach(id => {
|
|
405
|
+
qx.Class._attachAnno(clazz, id, null, config[id]);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Add singleton getInstance()
|
|
409
|
+
if (config.type === "singleton") {
|
|
410
|
+
clazz.getInstance = qx.Bootstrap.getInstance;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
clazz.classname = className;
|
|
414
|
+
qx.Bootstrap.setDisplayName(clazz, className, "constructor");
|
|
415
|
+
|
|
416
|
+
// Attach toString
|
|
417
|
+
if (!clazz.hasOwnProperty("toString")) {
|
|
418
|
+
clazz.toString = qx.Bootstrap.genericToString;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Add statics
|
|
422
|
+
for (let key in config.statics || {}) {
|
|
423
|
+
let staticFuncOrVar;
|
|
424
|
+
|
|
425
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
426
|
+
if (key.charAt(0) === "@") {
|
|
427
|
+
if (config.statics[key.substring(1)] === undefined) {
|
|
428
|
+
throw new Error('Annonation for static "' + key.substring(1) + '" of Class "' + clazz.classname + '" does not exist!');
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (key.charAt(1) === "_" && key.charAt(2) === "_") {
|
|
432
|
+
throw new Error('Cannot annotate private static "' + key.substring(1) + '" of Class "' + clazz.classname);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Do not add annotations as class properties
|
|
438
|
+
if (key.charAt(0) === "@") {
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
staticFuncOrVar = config.statics[key];
|
|
443
|
+
|
|
444
|
+
if (typeof staticFuncOrVar == "function") {
|
|
445
|
+
if (qx.core.Environment.get("qx.aspects")) {
|
|
446
|
+
staticFuncOrVar = qx.core.Aspect.wrap(className, staticFuncOrVar, "static");
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Allow easily identifying this method
|
|
450
|
+
qx.Bootstrap.setDisplayName(staticFuncOrVar, className, key);
|
|
451
|
+
}
|
|
235
452
|
|
|
236
|
-
|
|
453
|
+
// Add this static as a class property
|
|
454
|
+
Object.defineProperty(clazz, key, {
|
|
455
|
+
value: staticFuncOrVar,
|
|
456
|
+
writable: qx.Class.$$options.propsAccessible || true,
|
|
457
|
+
configurable: qx.Class.$$options.propsAccessible || true,
|
|
458
|
+
enumerable: qx.Class.$$options.propsAccessible || true
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// Attach annotations
|
|
462
|
+
qx.Class._attachAnno(clazz, "statics", key, config.statics["@" + key]);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Add a method to refresh all inheritable properties
|
|
466
|
+
Object.defineProperty(clazz.prototype, "$$refreshInheritables", {
|
|
467
|
+
value() {
|
|
468
|
+
let allProperties = this.constructor.prototype.$$allProperties;
|
|
469
|
+
|
|
470
|
+
// Call the refresh method of each inheritable property
|
|
471
|
+
for (let prop in allProperties) {
|
|
472
|
+
let property = allProperties[prop];
|
|
473
|
+
|
|
474
|
+
if (property.isInheritable()) {
|
|
475
|
+
let propertyFirstUp = qx.Bootstrap.firstUp(prop);
|
|
476
|
+
|
|
477
|
+
// Call this property's refresh method
|
|
478
|
+
this[`refresh${propertyFirstUp}`]();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
writable: qx.Class.$$options.propsAccessible || false,
|
|
483
|
+
configurable: qx.Class.$$options.propsAccessible || false,
|
|
484
|
+
enumerable: qx.Class.$$options.propsAccessible || false
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// Members, properties, events, and mixins are only allowed for
|
|
488
|
+
// non-static classes.
|
|
237
489
|
if (config.extend) {
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
|
|
490
|
+
// Track members defined by the class itself (not from mixins)
|
|
491
|
+
// This allows class members to override mixin members
|
|
492
|
+
if (config.members) {
|
|
493
|
+
if (!clazz.prototype.$$ownMembers) {
|
|
494
|
+
clazz.prototype.$$ownMembers = {};
|
|
495
|
+
}
|
|
496
|
+
for (let key in config.members) {
|
|
497
|
+
clazz.prototype.$$ownMembers[key] = true;
|
|
498
|
+
}
|
|
241
499
|
}
|
|
242
500
|
|
|
243
|
-
//
|
|
501
|
+
// Add members
|
|
244
502
|
if (config.members) {
|
|
245
|
-
|
|
503
|
+
qx.Class.addMembers(clazz, config.members, config.events, false);
|
|
246
504
|
}
|
|
247
505
|
|
|
248
|
-
//
|
|
506
|
+
// Add properties
|
|
507
|
+
if (config.properties) {
|
|
508
|
+
qx.Class.addProperties(clazz, config.properties, false);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Add events
|
|
249
512
|
if (config.events) {
|
|
250
|
-
|
|
513
|
+
qx.Class.addEvents(clazz, config.events, false);
|
|
251
514
|
}
|
|
252
515
|
|
|
253
|
-
//
|
|
516
|
+
// Add objects
|
|
254
517
|
if (config.objects) {
|
|
255
518
|
this.__addObjects(clazz, config.objects);
|
|
256
519
|
}
|
|
257
520
|
|
|
258
521
|
// Include mixins
|
|
259
|
-
// Must be
|
|
522
|
+
// Must be here, after members and properties, to detect conflicts
|
|
260
523
|
if (config.include) {
|
|
261
|
-
|
|
262
|
-
this.__addMixin(clazz, config.include[i], false);
|
|
263
|
-
}
|
|
524
|
+
config.include.forEach(mixin => this.addMixin(clazz, mixin, false));
|
|
264
525
|
}
|
|
265
526
|
}
|
|
266
|
-
// If config has a 'extend' key but it's null or undefined
|
|
267
|
-
else if (
|
|
268
|
-
config.hasOwnProperty("extend") &&
|
|
269
|
-
qx.core.Environment.get("qx.debug")
|
|
270
|
-
) {
|
|
271
|
-
throw new Error('"extend" parameter is null or undefined');
|
|
272
|
-
}
|
|
273
527
|
|
|
274
|
-
//
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
528
|
+
// Add interfaces
|
|
529
|
+
// We ensure that `this.addInterface` exists, because the default
|
|
530
|
+
// property storage implements an interface and during bootstrap
|
|
531
|
+
// time, we want to ignore that.
|
|
532
|
+
if (this.addInterface) {
|
|
533
|
+
if (config.implement) {
|
|
534
|
+
config.implement.forEach(iface => this.addInterface(clazz, iface));
|
|
278
535
|
}
|
|
279
|
-
}
|
|
280
536
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
for (var i = 0, l = config.implement.length; i < l; i++) {
|
|
284
|
-
this.__addInterface(clazz, config.implement[i]);
|
|
537
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
538
|
+
this.validateAbstractInterfaces(clazz);
|
|
285
539
|
}
|
|
286
540
|
}
|
|
287
541
|
|
|
288
|
-
|
|
289
|
-
|
|
542
|
+
//
|
|
543
|
+
// Store destruct onto class. We wrap their function (or an empty
|
|
544
|
+
// function) in code that also handles any properties that
|
|
545
|
+
// require `dereference : true`
|
|
546
|
+
//
|
|
547
|
+
let destruct = config.destruct || function () {};
|
|
548
|
+
|
|
549
|
+
if (qx.core.Environment.get("qx.aspects")) {
|
|
550
|
+
destruct = qx.core.Aspect.wrap(className, destruct, "destructor");
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Wrap the destructor in a function that calls the original
|
|
554
|
+
// destructor and then deletes any property remnants for
|
|
555
|
+
// properties that are marked as `dereference : true`.
|
|
556
|
+
let destructDereferencer = function () {
|
|
557
|
+
let properties = this.constructor.prototype.$$allProperties;
|
|
558
|
+
|
|
559
|
+
// First call the original or aspect-wrapped destruct method
|
|
560
|
+
destruct.call(this);
|
|
561
|
+
|
|
562
|
+
// Now ensure all properties marked with `derefrence : true`
|
|
563
|
+
// have their saved values removed from this object.
|
|
564
|
+
for (let prop in properties) {
|
|
565
|
+
let property = properties[prop];
|
|
566
|
+
if (property instanceof qx.core.property.Property && property.needsDereference()) {
|
|
567
|
+
property.dereference(this);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
clazz.$$destructor = destructDereferencer;
|
|
573
|
+
qx.Bootstrap.setDisplayName(destructDereferencer, className, "destruct");
|
|
574
|
+
|
|
575
|
+
// If there's a specified classname...
|
|
576
|
+
let basename;
|
|
577
|
+
if (className) {
|
|
578
|
+
// Create that namespace
|
|
579
|
+
basename = qx.Bootstrap.createNamespace(className, clazz);
|
|
580
|
+
|
|
581
|
+
// Store class reference in global class registry
|
|
582
|
+
qx.Bootstrap.$$registry[className] = clazz;
|
|
583
|
+
}
|
|
584
|
+
clazz.basename = basename || "";
|
|
585
|
+
if (clazz.prototype) {
|
|
586
|
+
clazz.prototype.basename = clazz.basename;
|
|
290
587
|
}
|
|
291
588
|
|
|
292
|
-
//
|
|
589
|
+
// Now that the class has been defined, arrange to call its
|
|
590
|
+
// (optional) defer function
|
|
293
591
|
if (config.defer) {
|
|
294
|
-
|
|
295
|
-
qx.Bootstrap.addPendingDefer(clazz,
|
|
296
|
-
clazz = qx.Class.getByName(clazz.classname);
|
|
592
|
+
// Execute defer section
|
|
593
|
+
qx.Bootstrap.addPendingDefer(clazz, () => {
|
|
297
594
|
config.defer(clazz, clazz.prototype, {
|
|
298
595
|
add(name, config) {
|
|
299
|
-
|
|
300
|
-
var properties = {};
|
|
301
|
-
properties[name] = config;
|
|
302
|
-
|
|
303
|
-
// execute generic property handler
|
|
304
|
-
qx.Class.__addProperties(clazz, properties, true);
|
|
596
|
+
qx.Class.addProperties(clazz, { [name]: config }, true);
|
|
305
597
|
}
|
|
306
598
|
});
|
|
307
599
|
});
|
|
@@ -310,643 +602,800 @@ qx.Bootstrap.define("qx.Class", {
|
|
|
310
602
|
return clazz;
|
|
311
603
|
},
|
|
312
604
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
delete parent[ns[i - 1]];
|
|
339
|
-
} else {
|
|
340
|
-
break;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
},
|
|
605
|
+
_extend(classname, config) {
|
|
606
|
+
let type = config.type || "class";
|
|
607
|
+
let superclass = config.extend || Object;
|
|
608
|
+
let subclass;
|
|
609
|
+
let initialConstruct = config.construct;
|
|
610
|
+
|
|
611
|
+
if (config.type != "static") {
|
|
612
|
+
// If the constructor function is defined as a "method" using
|
|
613
|
+
// shorthand syntax, e.g.,
|
|
614
|
+
// qx.Class.define("myApp.X",
|
|
615
|
+
// {
|
|
616
|
+
// construct(x) {}
|
|
617
|
+
// });
|
|
618
|
+
//
|
|
619
|
+
// rather than as an actual function, e.g.,
|
|
620
|
+
// qx.Class.define("myApp.X",
|
|
621
|
+
// {
|
|
622
|
+
// construct : function(x) {}
|
|
623
|
+
// });
|
|
624
|
+
//
|
|
625
|
+
// then it's not allowed by the spec to be a constructor. We
|
|
626
|
+
// must wrap it.
|
|
627
|
+
//
|
|
628
|
+
subclass = function (...args) {
|
|
629
|
+
let ret;
|
|
344
630
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
*/
|
|
352
|
-
isDefined: qx.util.OOUtil.classIsDefined,
|
|
631
|
+
// add abstract and singleton checks
|
|
632
|
+
if (type === "abstract") {
|
|
633
|
+
if (this.classname === classname) {
|
|
634
|
+
throw new Error("The class '," + classname + "' is abstract! It is not possible to instantiate it.");
|
|
635
|
+
}
|
|
636
|
+
}
|
|
353
637
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
638
|
+
if (type === "singleton") {
|
|
639
|
+
if (!this.constructor.$$allowconstruct) {
|
|
640
|
+
throw new Error(
|
|
641
|
+
"The class '" +
|
|
642
|
+
classname +
|
|
643
|
+
"' is a singleton! It is not possible to instantiate it " +
|
|
644
|
+
"directly. Use the static getInstance() method instead."
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
362
648
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
649
|
+
// At the time this function is called, config.construct, even
|
|
650
|
+
// if undefined in the configuration, will have been set to a
|
|
651
|
+
// trivial function. We therefore look at its initial value to
|
|
652
|
+
// decide whether to call it, or the superclass constructor.
|
|
653
|
+
if (initialConstruct) {
|
|
654
|
+
ret = initialConstruct.apply(this, args);
|
|
655
|
+
} else {
|
|
656
|
+
ret = superclass.apply(this, args);
|
|
657
|
+
}
|
|
371
658
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
382
|
-
if (!mixin) {
|
|
383
|
-
throw new Error(
|
|
384
|
-
"The mixin to include into class '" +
|
|
385
|
-
clazz.classname +
|
|
386
|
-
"' is undefined/null!"
|
|
387
|
-
);
|
|
388
|
-
}
|
|
659
|
+
// Call any mixins' constructors and those mixins'
|
|
660
|
+
// dependency mixins' constructors
|
|
661
|
+
if (subclass.constructor.$$flatIncludes) {
|
|
662
|
+
subclass.constructor.$$flatIncludes.forEach(mixin => {
|
|
663
|
+
if (mixin.$$constructor) {
|
|
664
|
+
mixin.$$constructor.apply(this, args);
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
}
|
|
389
668
|
|
|
390
|
-
|
|
391
|
-
|
|
669
|
+
let initDuringConstruct = qx.core.Environment.get("qx.core.property.Property.applyDuringConstruct");
|
|
670
|
+
let excludeAutoApply = qx.core.Environment.get("qx.core.property.Property.excludeAutoApply") || [];
|
|
392
671
|
|
|
393
|
-
qx.Class.__addMixin(clazz, mixin, false);
|
|
394
|
-
},
|
|
395
672
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
}
|
|
673
|
+
//Init properties
|
|
674
|
+
//Call apply function for properties of this class which have an init value and which haven't been initialized yet.
|
|
675
|
+
//This must be done once per instantiation, after the constructor of the concrete class has finished.
|
|
676
|
+
if (this.constructor === subclass) {
|
|
677
|
+
for (let property of Object.values(subclass.prototype.$$allProperties)) {
|
|
678
|
+
if (!(property instanceof qx.core.property.Property)) {
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
let def = property.getDefinition();
|
|
682
|
+
let modernFeatures = def && (def.autoApply || def.initFunction);
|
|
683
|
+
let excluded = property.getClass().classname ? excludeAutoApply.find(match => property.getClass().classname.match(match)) : !modernFeatures;
|
|
684
|
+
if (
|
|
685
|
+
!property.isPseudoProperty() &&
|
|
686
|
+
def.autoApply !== false &&
|
|
687
|
+
property.hasInitValue() &&
|
|
688
|
+
!property.getPropertyState(this).initMethodCalled &&
|
|
689
|
+
((initDuringConstruct === true && !excluded) || modernFeatures)
|
|
690
|
+
) {
|
|
691
|
+
property.init(this);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
419
695
|
|
|
420
|
-
|
|
421
|
-
|
|
696
|
+
if (config.delegate) {
|
|
697
|
+
return new Proxy(this, {
|
|
698
|
+
get(target, propertyName, receiver) {
|
|
699
|
+
if (typeof config.delegate.get == "function") {
|
|
700
|
+
return config.delegate.get.call(target, propertyName);
|
|
701
|
+
}
|
|
702
|
+
let value = Reflect.get(target, propertyName, receiver);
|
|
703
|
+
return value;
|
|
704
|
+
},
|
|
422
705
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
706
|
+
set(target, propertyName, value) {
|
|
707
|
+
if (typeof config.delegate.set == "function") {
|
|
708
|
+
return config.delegate.set.call(target, propertyName, value);
|
|
709
|
+
}
|
|
710
|
+
return Reflect.set(target, propertyName, value);
|
|
711
|
+
},
|
|
426
712
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
},
|
|
713
|
+
deleteProperty(target, propertyName) {
|
|
714
|
+
if (typeof config.delegate.delete == "function") {
|
|
715
|
+
return config.delegate.delete.call(target, propertyName);
|
|
716
|
+
}
|
|
717
|
+
return Reflect.deleteProperty(target, propertyName);
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
}
|
|
436
721
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
* @return {Boolean} whether clazz is a sub class of superClass.
|
|
444
|
-
*/
|
|
445
|
-
isSubClassOf(clazz, superClass) {
|
|
446
|
-
if (!clazz) {
|
|
447
|
-
return false;
|
|
722
|
+
return this;
|
|
723
|
+
};
|
|
724
|
+
} else {
|
|
725
|
+
subclass = function () {
|
|
726
|
+
throw new Error(`${classname}: can not instantiate a static class`);
|
|
727
|
+
};
|
|
448
728
|
}
|
|
449
729
|
|
|
450
|
-
|
|
451
|
-
|
|
730
|
+
// Allow easily identifying this class
|
|
731
|
+
qx.Bootstrap.setDisplayName(subclass, classname);
|
|
732
|
+
|
|
733
|
+
// This is a class
|
|
734
|
+
subclass.$$type = "Class";
|
|
735
|
+
|
|
736
|
+
// If its class type was specified, save it
|
|
737
|
+
if (config.type) {
|
|
738
|
+
subclass.$$classtype = config.type;
|
|
452
739
|
}
|
|
453
740
|
|
|
454
|
-
|
|
455
|
-
|
|
741
|
+
// Ensure there's something unique to compare constructors to.
|
|
742
|
+
if (!config.construct) {
|
|
743
|
+
config.construct = function () {};
|
|
456
744
|
}
|
|
457
745
|
|
|
458
|
-
|
|
746
|
+
// Keep track of the original constructor so we know when to
|
|
747
|
+
// construct mixins
|
|
748
|
+
subclass.$$originalConstructor = config.construct;
|
|
749
|
+
|
|
750
|
+
qx.Bootstrap.extendClass(subclass, config.construct, superclass, classname);
|
|
751
|
+
|
|
752
|
+
let superProperties = superclass.prototype.$$allProperties || {};
|
|
753
|
+
|
|
754
|
+
// Save this object's properties
|
|
755
|
+
Object.defineProperty(subclass.prototype, "$$properties", {
|
|
756
|
+
value: {},
|
|
757
|
+
writable: qx.Class.$$options.propsAccessible || false,
|
|
758
|
+
configurable: qx.Class.$$options.propsAccessible || false,
|
|
759
|
+
enumerable: qx.Class.$$options.propsAccessible || false
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
// Save the super properties for this class
|
|
763
|
+
Object.defineProperty(subclass.prototype, "$$superProperties", {
|
|
764
|
+
value: superProperties,
|
|
765
|
+
writable: qx.Class.$$options.propsAccessible || false,
|
|
766
|
+
configurable: qx.Class.$$options.propsAccessible || false,
|
|
767
|
+
enumerable: qx.Class.$$options.propsAccessible || false
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
// Save the full chain of properties for this class
|
|
771
|
+
Object.defineProperty(subclass.prototype, "$$allProperties", {
|
|
772
|
+
value: Object.assign({}, superProperties),
|
|
773
|
+
writable: qx.Class.$$options.propsAccessible || false,
|
|
774
|
+
configurable: qx.Class.$$options.propsAccessible || false,
|
|
775
|
+
enumerable: qx.Class.$$options.propsAccessible || false
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
// Save any init functions that need to be called upon instantiation
|
|
779
|
+
Object.defineProperty(subclass.prototype, "$$initFunctions", {
|
|
780
|
+
value: [],
|
|
781
|
+
writable: qx.Class.$$options.propsAccessible || false,
|
|
782
|
+
configurable: qx.Class.$$options.propsAccessible || false,
|
|
783
|
+
enumerable: qx.Class.$$options.propsAccessible || false
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
return subclass;
|
|
459
787
|
},
|
|
460
788
|
|
|
461
789
|
/**
|
|
462
|
-
*
|
|
463
|
-
* if the property does not exist.
|
|
790
|
+
* Removes a class from qooxdoo defined by {@link #define}
|
|
464
791
|
*
|
|
465
|
-
* @
|
|
466
|
-
*
|
|
467
|
-
* @param name {String} name of the class to check for
|
|
468
|
-
* @return {Map|null} whether the object support the given event.
|
|
792
|
+
* @param name {String}
|
|
793
|
+
* Name of the class
|
|
469
794
|
*/
|
|
470
|
-
|
|
795
|
+
undefine: qx.Bootstrap.undefine,
|
|
471
796
|
|
|
472
797
|
/**
|
|
473
|
-
*
|
|
798
|
+
* Attach members to a class
|
|
474
799
|
*
|
|
475
|
-
* @param clazz {Class}
|
|
476
|
-
*
|
|
800
|
+
* @param clazz {Class}
|
|
801
|
+
* Class to add members to
|
|
802
|
+
*
|
|
803
|
+
* @param members {Map}
|
|
804
|
+
* The map of members to attach
|
|
805
|
+
*
|
|
806
|
+
* @param patch {Boolean ? false}
|
|
807
|
+
* Enable patching
|
|
477
808
|
*/
|
|
478
|
-
|
|
479
|
-
|
|
809
|
+
addMembers(clazz, members, events, patch) {
|
|
810
|
+
let proto = clazz.prototype;
|
|
811
|
+
let classOwnMembers = {}; // Track class members to restore after mixin addition
|
|
480
812
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
list.push.apply(list, Object.keys(clazz.$$properties));
|
|
484
|
-
}
|
|
813
|
+
for (let key in members) {
|
|
814
|
+
let member = members[key];
|
|
485
815
|
|
|
486
|
-
|
|
487
|
-
|
|
816
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
817
|
+
if (key.charAt(0) === "@") {
|
|
818
|
+
var annoKey = key.substring(1);
|
|
819
|
+
if (members[annoKey] === undefined && proto[annoKey] === undefined) {
|
|
820
|
+
throw new Error(`Annotation for ${annoKey} of Class ${clazz.classname} does not exist`);
|
|
821
|
+
}
|
|
488
822
|
|
|
489
|
-
|
|
490
|
-
|
|
823
|
+
if (key.charAt(1) === "_" && key.charAt(2) === "_") {
|
|
824
|
+
throw new Error(`Cannot annotate private member ${key.substring(1)} ` + `of Class ${clazz.classname}`);
|
|
825
|
+
}
|
|
826
|
+
} else {
|
|
827
|
+
// Check if we're trying to overwrite an existing member
|
|
828
|
+
let isOverwriting = (proto.$$allProperties.hasOwnProperty(key) || proto.hasOwnProperty(key)) &&
|
|
829
|
+
key != "_createQxObjectImpl";
|
|
491
830
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
* if the property is not specified anywhere.
|
|
496
|
-
*
|
|
497
|
-
* @param clazz {Class} class to look for the property
|
|
498
|
-
* @param name {String} name of the property
|
|
499
|
-
* @return {Class|null} The class which includes the property
|
|
500
|
-
*/
|
|
501
|
-
getByProperty(clazz, name) {
|
|
502
|
-
while (clazz) {
|
|
503
|
-
if (clazz.$$properties && clazz.$$properties[name]) {
|
|
504
|
-
return clazz;
|
|
505
|
-
}
|
|
831
|
+
if (isOverwriting && patch !== true) {
|
|
832
|
+
// Check if conflicting with a property - this is never allowed
|
|
833
|
+
let isProperty = proto.$$allProperties.hasOwnProperty(key);
|
|
506
834
|
|
|
507
|
-
|
|
508
|
-
|
|
835
|
+
if (isProperty) {
|
|
836
|
+
// Conflicting with a property - always throw error
|
|
837
|
+
throw new Error(
|
|
838
|
+
clazz.classname +
|
|
839
|
+
': Overwriting member or property "' +
|
|
840
|
+
key +
|
|
841
|
+
'" of Class "' +
|
|
842
|
+
clazz.classname +
|
|
843
|
+
'" is not allowed! (Members and properties are in the same namespace.)'
|
|
844
|
+
);
|
|
845
|
+
}
|
|
509
846
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
847
|
+
// Check if this is a class-defined member overriding a mixin method (issue #9142)
|
|
848
|
+
// Classes should be able to override mixin methods
|
|
849
|
+
let isOwnMember = proto.$$ownMembers && proto.$$ownMembers.hasOwnProperty(key);
|
|
850
|
+
|
|
851
|
+
if (isOwnMember) {
|
|
852
|
+
// Save the class member to restore it after the mixin member is added
|
|
853
|
+
// This allows super to work: mixin member is added, then class member
|
|
854
|
+
// overwrites it but can call super.method() to access the mixin version
|
|
855
|
+
classOwnMembers[key] = proto[key];
|
|
856
|
+
// Don't skip - let the mixin member be added, then we'll restore the class member
|
|
857
|
+
} else {
|
|
858
|
+
// Not an own member and not a property, so this is a mixin-to-mixin conflict
|
|
859
|
+
throw new Error(
|
|
860
|
+
clazz.classname +
|
|
861
|
+
': Overwriting member or property "' +
|
|
862
|
+
key +
|
|
863
|
+
'" of Class "' +
|
|
864
|
+
clazz.classname +
|
|
865
|
+
'" is not allowed! (Members and properties are in the same namespace.)'
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
} else if (proto[key] !== undefined && key.charAt(0) === "_" && key.charAt(1) === "_") {
|
|
869
|
+
throw new Error(`Overwriting private member "${key}" ` + `of Class "${clazz.classname}" ` + "is not allowed");
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
522
873
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
* @return {String|null} Event type of the given event.
|
|
531
|
-
*/
|
|
532
|
-
getEventType: qx.util.OOUtil.getEventType,
|
|
874
|
+
// Annotations are not members
|
|
875
|
+
if (key.charAt(0) === "@") {
|
|
876
|
+
let annoKey = key.substring(1);
|
|
877
|
+
if (members[annoKey] === undefined) {
|
|
878
|
+
// An annotation for a superclass' member
|
|
879
|
+
qx.Class._attachAnno(clazz, "members", annoKey, member);
|
|
880
|
+
}
|
|
533
881
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
*
|
|
537
|
-
* @signature function(clazz, name)
|
|
538
|
-
* @param clazz {Class} class to check
|
|
539
|
-
* @param name {String} name of the event to check for
|
|
540
|
-
* @return {Boolean} whether the class supports the given event.
|
|
541
|
-
*/
|
|
542
|
-
supportsEvent: qx.util.OOUtil.supportsEvent,
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
543
884
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
885
|
+
if (typeof member == "function") {
|
|
886
|
+
// If patching, we need to wrap the member function so that
|
|
887
|
+
// `member.base` is unique when a mixin is added to more than
|
|
888
|
+
// one class
|
|
889
|
+
if (patch) {
|
|
890
|
+
let f = member;
|
|
891
|
+
member = function (...args) {
|
|
892
|
+
return f.apply(this, args);
|
|
893
|
+
};
|
|
894
|
+
}
|
|
554
895
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
* declaration for the given mixin. Returns null if the mixin is not
|
|
558
|
-
* specified anywhere.
|
|
559
|
-
*
|
|
560
|
-
* @param clazz {Class} class to look for the mixin
|
|
561
|
-
* @param mixin {Mixin} mixin to look for
|
|
562
|
-
* @return {Class|null} The class which directly includes the given mixin
|
|
563
|
-
*/
|
|
564
|
-
getByMixin(clazz, mixin) {
|
|
565
|
-
var list, i, l;
|
|
896
|
+
// Allow easily identifying this method
|
|
897
|
+
qx.Bootstrap.setDisplayName(member, clazz.classname, `prototype.${key}`);
|
|
566
898
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
899
|
+
if (qx.core.Environment.get("qx.aspects")) {
|
|
900
|
+
member = qx.core.Aspect.wrap(clazz.classname, member, key);
|
|
901
|
+
}
|
|
570
902
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
903
|
+
// Allow base calls
|
|
904
|
+
if (key in clazz.prototype) {
|
|
905
|
+
if (patch && typeof member == "function") {
|
|
906
|
+
member.self = clazz;
|
|
574
907
|
}
|
|
908
|
+
member.base = clazz.prototype[key];
|
|
575
909
|
}
|
|
910
|
+
|
|
911
|
+
// Create the storage for this member
|
|
912
|
+
patch && delete clazz.prototype[key];
|
|
913
|
+
Object.defineProperty(clazz.prototype, key, {
|
|
914
|
+
value: member,
|
|
915
|
+
writable: qx.Class.$$options.propsAccessible || true,
|
|
916
|
+
configurable: qx.Class.$$options.propsAccessible || true,
|
|
917
|
+
enumerable: qx.Class.$$options.propsAccessible || true
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
// Attach annotations
|
|
921
|
+
qx.Class._attachAnno(clazz, "members", key, members["@" + key]);
|
|
922
|
+
} else {
|
|
923
|
+
Object.defineProperty(clazz.prototype, key, {
|
|
924
|
+
value: member,
|
|
925
|
+
writable: qx.Class.$$options.propsAccessible || true,
|
|
926
|
+
configurable: qx.Class.$$options.propsAccessible || true,
|
|
927
|
+
enumerable: qx.Class.$$options.propsAccessible || true
|
|
928
|
+
});
|
|
576
929
|
}
|
|
930
|
+
}
|
|
577
931
|
|
|
578
|
-
|
|
932
|
+
// Restore class-defined members that were overridden by mixin members (issue #9142)
|
|
933
|
+
// This allows classes to override mixin methods while still supporting base calls
|
|
934
|
+
for (let key in classOwnMembers) {
|
|
935
|
+
let classMember = classOwnMembers[key];
|
|
936
|
+
|
|
937
|
+
// Re-add the class member, which will now have member.base set to the mixin version
|
|
938
|
+
if (typeof classMember == "function") {
|
|
939
|
+
// Save the mixin member that's currently in the prototype
|
|
940
|
+
let mixinMember = proto[key];
|
|
941
|
+
|
|
942
|
+
// Set up base call: the class member's base should point to the mixin member
|
|
943
|
+
// This is crucial for this.base(arguments) to work correctly
|
|
944
|
+
classMember.base = mixinMember;
|
|
945
|
+
|
|
946
|
+
// Also set member.self for proper context (similar to patch behavior)
|
|
947
|
+
classMember.self = clazz;
|
|
948
|
+
|
|
949
|
+
// Delete the mixin member and replace with the class member
|
|
950
|
+
delete proto[key];
|
|
951
|
+
Object.defineProperty(proto, key, {
|
|
952
|
+
value: classMember,
|
|
953
|
+
writable: qx.Class.$$options.propsAccessible || true,
|
|
954
|
+
configurable: qx.Class.$$options.propsAccessible || true,
|
|
955
|
+
enumerable: qx.Class.$$options.propsAccessible || true
|
|
956
|
+
});
|
|
957
|
+
}
|
|
579
958
|
}
|
|
580
959
|
|
|
581
|
-
|
|
960
|
+
for (let key in members) {
|
|
961
|
+
if ((key.length > 3) & key.startsWith("get") && key.charAt(3) === key.charAt(3).toUpperCase()) {
|
|
962
|
+
let propertyName = key.charAt(3).toLowerCase() + key.substr(4);
|
|
963
|
+
if (clazz.prototype.$$allProperties[propertyName]) {
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
let eventName = "change" + key.substr(3);
|
|
967
|
+
if (events && events[eventName]) {
|
|
968
|
+
let superProperty = clazz.prototype.$$superProperties ? clazz.prototype.$$superProperties[propertyName] : null;
|
|
969
|
+
if (superProperty) {
|
|
970
|
+
throw new Error(`${clazz.classname}: ` + `Overwriting property "${propertyName}" with a pseudo-property is not allowed`);
|
|
971
|
+
}
|
|
972
|
+
let property = new qx.core.property.Property(propertyName, clazz);
|
|
973
|
+
property.configurePseudoProperty();
|
|
974
|
+
clazz.prototype.$$properties[propertyName] = property;
|
|
975
|
+
clazz.prototype.$$allProperties[propertyName] = property;
|
|
976
|
+
property.defineProperty(clazz, patch);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
582
980
|
},
|
|
583
981
|
|
|
584
982
|
/**
|
|
585
|
-
*
|
|
983
|
+
* Attach properties to classes
|
|
586
984
|
*
|
|
587
|
-
* @
|
|
588
|
-
*
|
|
589
|
-
* @return {Mixin[]} array of mixins this class uses
|
|
590
|
-
*/
|
|
591
|
-
getMixins: qx.util.OOUtil.getMixins,
|
|
592
|
-
|
|
593
|
-
/**
|
|
594
|
-
* Whether a given class or any of its superclasses includes a given mixin.
|
|
985
|
+
* @param clazz {Class}
|
|
986
|
+
* Class to add the properties to
|
|
595
987
|
*
|
|
596
|
-
* @param
|
|
597
|
-
*
|
|
598
|
-
*
|
|
988
|
+
* @param properties {Map}
|
|
989
|
+
* Map of properties
|
|
990
|
+
*
|
|
991
|
+
* @param patch {Boolean ? false}
|
|
992
|
+
* Overwrite property with the limitations of a property which
|
|
993
|
+
* means you are able to refine but not to replace (esp. for
|
|
994
|
+
* new properties)
|
|
599
995
|
*/
|
|
600
|
-
|
|
601
|
-
|
|
996
|
+
addProperties(clazz, properties, patch) {
|
|
997
|
+
let addImpl = groupProperties => {
|
|
998
|
+
for (let propertyName in properties) {
|
|
999
|
+
let def = properties[propertyName];
|
|
1000
|
+
if ((groupProperties && !def.group) || (!groupProperties && def.group)) {
|
|
1001
|
+
continue;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
let superProperty =
|
|
1005
|
+
clazz.prototype.$$superProperties &&
|
|
1006
|
+
clazz.prototype.$$superProperties.hasOwnProperty(propertyName) &&
|
|
1007
|
+
clazz.prototype.$$superProperties[propertyName];
|
|
1008
|
+
let property;
|
|
1009
|
+
if (superProperty) {
|
|
1010
|
+
if (!def.refine) {
|
|
1011
|
+
throw new Error(`${clazz.classname}: ` + `Overwriting property "${propertyName}" without "refine: true"`);
|
|
1012
|
+
}
|
|
1013
|
+
property = superProperty.clone(clazz);
|
|
1014
|
+
} else if (def.group) {
|
|
1015
|
+
property = new qx.core.property.GroupProperty(propertyName, clazz);
|
|
1016
|
+
} else {
|
|
1017
|
+
property = new qx.core.property.Property(propertyName, clazz);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
clazz.prototype.$$properties[propertyName] = property;
|
|
1021
|
+
clazz.prototype.$$allProperties[propertyName] = property;
|
|
1022
|
+
property.configure(def);
|
|
1023
|
+
|
|
1024
|
+
property.defineProperty(clazz, patch);
|
|
1025
|
+
let eventName = property.getEventName();
|
|
1026
|
+
if (eventName) {
|
|
1027
|
+
let events = {
|
|
1028
|
+
[eventName]: "qx.event.type.Data"
|
|
1029
|
+
};
|
|
1030
|
+
|
|
1031
|
+
qx.Class.addEvents(clazz, events, true);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
// Add annotations
|
|
1035
|
+
qx.Class._attachAnno(clazz, "properties", propertyName, def["@"]);
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
addImpl(false);
|
|
1039
|
+
addImpl(true);
|
|
602
1040
|
},
|
|
603
1041
|
|
|
604
1042
|
/**
|
|
605
|
-
*
|
|
1043
|
+
* Attach events to the class
|
|
606
1044
|
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
* key.
|
|
1045
|
+
* @param clazz {Class}
|
|
1046
|
+
* Class to add the events to
|
|
610
1047
|
*
|
|
611
|
-
* @param
|
|
612
|
-
*
|
|
613
|
-
* @return {Boolean} whether the class includes the mixin directly.
|
|
614
|
-
*/
|
|
615
|
-
hasOwnInterface(clazz, iface) {
|
|
616
|
-
return clazz.$$implements && clazz.$$implements.indexOf(iface) !== -1;
|
|
617
|
-
},
|
|
618
|
-
|
|
619
|
-
/**
|
|
620
|
-
* Returns the class or one of its super classes which contains the
|
|
621
|
-
* declaration of the given interface. Returns null if the interface is not
|
|
622
|
-
* specified anywhere.
|
|
1048
|
+
* @param events {Map}
|
|
1049
|
+
* Map of event names the class fires
|
|
623
1050
|
*
|
|
624
|
-
* @
|
|
625
|
-
*
|
|
626
|
-
* @param iface {Interface} interface to look for
|
|
627
|
-
* @return {Class|null} the class which directly implements the given interface
|
|
1051
|
+
* @param patch {Boolean ? false}
|
|
1052
|
+
* Enable redefinition of event type?
|
|
628
1053
|
*/
|
|
629
|
-
|
|
1054
|
+
addEvents(clazz, events, patch) {
|
|
1055
|
+
let key;
|
|
630
1056
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
* @return {Interface[]} array of interfaces this class implements
|
|
636
|
-
*/
|
|
637
|
-
getInterfaces(clazz) {
|
|
638
|
-
var list = [];
|
|
1057
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1058
|
+
if (typeof events !== "object" || qx.Bootstrap.getClass(events) === "Array") {
|
|
1059
|
+
throw new Error(clazz.classname + ": the events must be defined as map!");
|
|
1060
|
+
}
|
|
639
1061
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
1062
|
+
for (key in events) {
|
|
1063
|
+
let type = events[key];
|
|
1064
|
+
|
|
1065
|
+
if (type !== undefined && typeof type !== "string") {
|
|
1066
|
+
throw new Error(
|
|
1067
|
+
clazz.classname +
|
|
1068
|
+
"/" +
|
|
1069
|
+
key +
|
|
1070
|
+
": the event value needs to be a string with the class name " +
|
|
1071
|
+
"of the event object which will be fired."
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
643
1074
|
}
|
|
644
1075
|
|
|
645
|
-
|
|
1076
|
+
// Compare old and new event type/value if patching is disabled
|
|
1077
|
+
if (clazz.$$events && patch !== true) {
|
|
1078
|
+
for (key in events) {
|
|
1079
|
+
if (clazz.$$events[key] !== undefined && clazz.$$events[key] !== events[key]) {
|
|
1080
|
+
throw new Error(
|
|
1081
|
+
clazz.classname + "/" + key + ": the event value/type cannot be changed from " + clazz.$$events[key] + " to " + events[key]
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
646
1086
|
}
|
|
647
1087
|
|
|
648
|
-
|
|
1088
|
+
if (clazz.$$events) {
|
|
1089
|
+
for (key in events) {
|
|
1090
|
+
clazz.$$events[key] = events[key];
|
|
1091
|
+
}
|
|
1092
|
+
} else {
|
|
1093
|
+
clazz.$$events = events;
|
|
1094
|
+
}
|
|
649
1095
|
},
|
|
650
1096
|
|
|
651
1097
|
/**
|
|
652
|
-
*
|
|
653
|
-
*
|
|
654
|
-
* This function will return "true" if the interface was defined
|
|
655
|
-
* in the class declaration ({@link qx.Class#define}) of the class
|
|
656
|
-
* or any of its super classes using the "implement"
|
|
657
|
-
* key.
|
|
1098
|
+
* Include all features of the mixin into the given class, recursively.
|
|
658
1099
|
*
|
|
659
|
-
* @
|
|
660
|
-
*
|
|
661
|
-
* @param iface {Interface} the interface to check for
|
|
662
|
-
* @return {Boolean} whether the class includes the interface.
|
|
663
|
-
*/
|
|
664
|
-
hasInterface: qx.util.OOUtil.hasInterface,
|
|
665
|
-
|
|
666
|
-
/**
|
|
667
|
-
* Whether a given class complies to an interface.
|
|
1100
|
+
* @param clazz {Class}
|
|
1101
|
+
* The class onto which the mixin should be attached
|
|
668
1102
|
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
* the interface explicitly in the <code>extend</code> key.
|
|
1103
|
+
* @param mixin {Mixin}
|
|
1104
|
+
* Include all features of this mixin
|
|
672
1105
|
*
|
|
673
|
-
* @param
|
|
674
|
-
*
|
|
675
|
-
* @return {Boolean} whether the class conforms to the interface.
|
|
1106
|
+
* @param patch {Boolean}
|
|
1107
|
+
* Overwrite existing fields, functions and properties
|
|
676
1108
|
*/
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1109
|
+
addMixin(clazz, mixin, patch) {
|
|
1110
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1111
|
+
if (!clazz || !mixin) {
|
|
1112
|
+
throw new Error("Incomplete parameters!");
|
|
1113
|
+
}
|
|
682
1114
|
}
|
|
683
1115
|
|
|
684
|
-
if (
|
|
685
|
-
return
|
|
1116
|
+
if (this.hasMixin(clazz, mixin)) {
|
|
1117
|
+
return;
|
|
686
1118
|
}
|
|
687
1119
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
1120
|
+
// Attach content
|
|
1121
|
+
let list = qx.Mixin.flatten([mixin]);
|
|
1122
|
+
list.forEach(entry => {
|
|
1123
|
+
// Attach events
|
|
1124
|
+
if (entry.$$events) {
|
|
1125
|
+
qx.Class.addEvents(clazz, entry.$$events, patch);
|
|
1126
|
+
}
|
|
691
1127
|
|
|
692
|
-
|
|
1128
|
+
// Attach members
|
|
1129
|
+
if (entry.$$members) {
|
|
1130
|
+
qx.Class.addMembers(clazz, entry.$$members, entry.$$events, patch);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
// Attach properties
|
|
1134
|
+
if (entry.$$properties) {
|
|
1135
|
+
qx.Class.addProperties(clazz, entry.$$properties, patch);
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
// Store mixin reference
|
|
1140
|
+
if (clazz.$$includes) {
|
|
1141
|
+
clazz.$$includes.push(mixin);
|
|
1142
|
+
clazz.$$flatIncludes.push.apply(clazz.$$flatIncludes, list);
|
|
1143
|
+
} else {
|
|
1144
|
+
clazz.$$includes = [mixin];
|
|
1145
|
+
clazz.$$flatIncludes = list;
|
|
1146
|
+
}
|
|
693
1147
|
},
|
|
694
1148
|
|
|
695
1149
|
/**
|
|
696
|
-
*
|
|
1150
|
+
* Add a single interface to a class
|
|
697
1151
|
*
|
|
698
|
-
* @
|
|
699
|
-
* @
|
|
1152
|
+
* @param clazz {Class} class to add interface to
|
|
1153
|
+
* @param iface {Interface} the Interface to add
|
|
700
1154
|
*/
|
|
701
|
-
|
|
702
|
-
if (
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
" is requested, but not ready yet. This is most likely due to a recursive call in the constructor path."
|
|
707
|
-
);
|
|
708
|
-
}
|
|
1155
|
+
addInterface(clazz, iface) {
|
|
1156
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1157
|
+
if (!clazz || !iface) {
|
|
1158
|
+
throw new Error("Incomplete parameters");
|
|
1159
|
+
}
|
|
709
1160
|
|
|
710
|
-
|
|
711
|
-
this
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
1161
|
+
// This differs from mixins, we only check if the interface
|
|
1162
|
+
// is already directly used by this class. It is allowed
|
|
1163
|
+
// however, to have an interface included multiple times by
|
|
1164
|
+
// extends in the interfaces etc.
|
|
1165
|
+
if (this.hasOwnInterface(clazz, iface)) {
|
|
1166
|
+
throw new Error(`Interface ${iface.name} is already used by ` + `Class ${clazz.classname}`);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// Check interface and wrap members
|
|
1170
|
+
if (clazz.$$classtype !== "abstract") {
|
|
1171
|
+
qx.Interface.assert(clazz, iface, true);
|
|
1172
|
+
}
|
|
715
1173
|
}
|
|
716
1174
|
|
|
717
|
-
|
|
1175
|
+
// Store interface reference
|
|
1176
|
+
let list = qx.Interface.flatten([iface]);
|
|
1177
|
+
if (clazz.$$implements) {
|
|
1178
|
+
clazz.$$implements.push(iface);
|
|
1179
|
+
clazz.$$flatImplements.push.apply(clazz.$$flatImplements, list);
|
|
1180
|
+
} else {
|
|
1181
|
+
clazz.$$implements = [iface];
|
|
1182
|
+
clazz.$$flatImplements = list;
|
|
1183
|
+
}
|
|
718
1184
|
},
|
|
719
1185
|
|
|
720
1186
|
/**
|
|
721
|
-
*
|
|
1187
|
+
* Adds the objects definition to the class
|
|
722
1188
|
*
|
|
723
|
-
* @param
|
|
724
|
-
*
|
|
725
|
-
* @return {Object} class name hash holding the references to the subclasses or null if the class does not exist.
|
|
1189
|
+
* @param {qx.Class} clazz class which is being defined
|
|
1190
|
+
* @param {*} objects the `object` property in the definition
|
|
726
1191
|
*/
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
1192
|
+
__addObjects(clazz, objects) {
|
|
1193
|
+
function validateCachedObject(key, value) {
|
|
1194
|
+
if (typeof value !== "function") {
|
|
1195
|
+
throw new Error("Invalid cached object definition for " + key + " in " + clazz.classname);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
if (typeof key != "string") {
|
|
1199
|
+
throw new Error("Invalid cached object key for " + key + " in " + clazz.classname);
|
|
1200
|
+
}
|
|
730
1201
|
}
|
|
731
1202
|
|
|
732
|
-
|
|
733
|
-
|
|
1203
|
+
if (!(objects instanceof Object)) {
|
|
1204
|
+
throw new Error("Invalid objects definition for " + clazz.classname);
|
|
1205
|
+
}
|
|
734
1206
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
1207
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1208
|
+
for (let key in objects) {
|
|
1209
|
+
validateCachedObject(key, objects[key]);
|
|
738
1210
|
}
|
|
739
1211
|
}
|
|
740
1212
|
|
|
741
|
-
|
|
1213
|
+
clazz.$$objects = objects;
|
|
742
1214
|
},
|
|
743
1215
|
|
|
744
|
-
/*
|
|
745
|
-
---------------------------------------------------------------------------
|
|
746
|
-
PRIVATE/INTERNAL BASICS
|
|
747
|
-
---------------------------------------------------------------------------
|
|
748
|
-
*/
|
|
749
|
-
|
|
750
1216
|
/**
|
|
751
|
-
*
|
|
752
|
-
*
|
|
1217
|
+
* Include all features of the given mixin into the class. The
|
|
1218
|
+
* mixin must not include any methods or properties that are
|
|
1219
|
+
* already available in the class. This would only be possible
|
|
1220
|
+
* using the {@link #patch} method.
|
|
753
1221
|
*
|
|
754
|
-
* @
|
|
755
|
-
*
|
|
1222
|
+
* @param clazz {Class}
|
|
1223
|
+
* An existing class which should be augmented by including a mixin.
|
|
1224
|
+
*
|
|
1225
|
+
* @param mixin {Mixin}
|
|
1226
|
+
* The mixin to be included.
|
|
756
1227
|
*/
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
$$registry: qx.Bootstrap.$$registry,
|
|
763
|
-
|
|
764
|
-
/** @type {Map} allowed keys in non-static class definition */
|
|
765
|
-
__allowedKeys: qx.core.Environment.select("qx.debug", {
|
|
766
|
-
true: {
|
|
767
|
-
"@": "object",
|
|
768
|
-
"@construct": "object",
|
|
769
|
-
"@destruct": "object",
|
|
770
|
-
type: "string", // String
|
|
771
|
-
extend: "function", // Function
|
|
772
|
-
implement: "object", // Interface[]
|
|
773
|
-
include: "object", // Mixin[]
|
|
774
|
-
construct: "function", // Function
|
|
775
|
-
statics: "object", // Map
|
|
776
|
-
properties: "object", // Map
|
|
777
|
-
members: "object", // Map
|
|
778
|
-
environment: "object", // Map
|
|
779
|
-
events: "object", // Map
|
|
780
|
-
defer: "function", // Function
|
|
781
|
-
destruct: "function", // Function
|
|
782
|
-
objects: "object" // Map
|
|
783
|
-
},
|
|
784
|
-
|
|
785
|
-
default: null
|
|
786
|
-
}),
|
|
1228
|
+
include(clazz, mixin) {
|
|
1229
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1230
|
+
if (!mixin) {
|
|
1231
|
+
throw new Error(`The mixin to include into class ${clazz.classname} ` + "is undefined or null");
|
|
1232
|
+
}
|
|
787
1233
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
true: {
|
|
791
|
-
"@": "object",
|
|
792
|
-
type: "string", // String
|
|
793
|
-
statics: "object", // Map
|
|
794
|
-
environment: "object", // Map
|
|
795
|
-
defer: "function" // Function
|
|
796
|
-
},
|
|
1234
|
+
qx.Mixin.isCompatible(mixin, clazz);
|
|
1235
|
+
}
|
|
797
1236
|
|
|
798
|
-
|
|
799
|
-
}
|
|
1237
|
+
qx.Class.addMixin(clazz, mixin, false);
|
|
1238
|
+
},
|
|
800
1239
|
|
|
801
1240
|
/**
|
|
802
|
-
*
|
|
1241
|
+
* Include all features of the given mixin into the class. The
|
|
1242
|
+
* mixin may include features, which are already defined in the
|
|
1243
|
+
* target class. Existing features of equal name will be
|
|
1244
|
+
* overwritten. Please keep in mind that this functionality is
|
|
1245
|
+
* not intended for regular use, but as a formalized way (and a
|
|
1246
|
+
* last resort) in order to patch existing classes.
|
|
803
1247
|
*
|
|
804
|
-
*
|
|
805
|
-
*
|
|
806
|
-
* @param
|
|
1248
|
+
* <b>WARNING</b>: You may break working classes and features.
|
|
1249
|
+
*
|
|
1250
|
+
* @param clazz {Class}
|
|
1251
|
+
* An existing class which should be modified by including a mixin.
|
|
1252
|
+
*
|
|
1253
|
+
* @param mixin {Mixin}
|
|
1254
|
+
* The mixin to be included.
|
|
1255
|
+
*
|
|
1256
|
+
* @return {Class}
|
|
1257
|
+
* The new class definition
|
|
807
1258
|
*/
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
config.type &&
|
|
813
|
-
!(
|
|
814
|
-
config.type === "static" ||
|
|
815
|
-
config.type === "abstract" ||
|
|
816
|
-
config.type === "singleton"
|
|
817
|
-
)
|
|
818
|
-
) {
|
|
819
|
-
throw new Error(
|
|
820
|
-
'Invalid type "' +
|
|
821
|
-
config.type +
|
|
822
|
-
'" definition for class "' +
|
|
823
|
-
name +
|
|
824
|
-
'"!'
|
|
825
|
-
);
|
|
1259
|
+
patch(clazz, mixin) {
|
|
1260
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1261
|
+
if (!mixin) {
|
|
1262
|
+
throw new Error(`The mixin to patch class ${clazz.classname} ` + "is undefined or null");
|
|
826
1263
|
}
|
|
827
1264
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
1265
|
+
qx.Mixin.isCompatible(mixin, clazz);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
qx.Class.addMixin(clazz, mixin, true);
|
|
1269
|
+
return qx.Class.getByName(clazz.classname);
|
|
1270
|
+
},
|
|
1271
|
+
|
|
1272
|
+
/**
|
|
1273
|
+
* Validates the interfaces required by abstract base classes
|
|
1274
|
+
*
|
|
1275
|
+
* @signature function(clazz)
|
|
1276
|
+
*
|
|
1277
|
+
* @param clazz {Class}
|
|
1278
|
+
* The configured class.
|
|
1279
|
+
*/
|
|
1280
|
+
validateAbstractInterfaces(clazz) {
|
|
1281
|
+
let superclass = clazz.superclass;
|
|
1282
|
+
while (superclass) {
|
|
1283
|
+
if (superclass.$$classtype !== "abstract") {
|
|
1284
|
+
break;
|
|
835
1285
|
}
|
|
836
1286
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
: this.__allowedKeys;
|
|
842
|
-
for (var key in config) {
|
|
843
|
-
if (!(key in allowed)) {
|
|
844
|
-
throw new Error(
|
|
845
|
-
'The configuration key "' +
|
|
846
|
-
key +
|
|
847
|
-
'" in class "' +
|
|
848
|
-
name +
|
|
849
|
-
'" is not allowed!'
|
|
850
|
-
);
|
|
1287
|
+
var interfaces = superclass.$$implements;
|
|
1288
|
+
if (interfaces) {
|
|
1289
|
+
for (let i = 0; i < interfaces.length; i++) {
|
|
1290
|
+
qx.Interface.assert(clazz, interfaces[i], true);
|
|
851
1291
|
}
|
|
1292
|
+
}
|
|
1293
|
+
superclass = superclass.superclass;
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
852
1296
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1297
|
+
/**
|
|
1298
|
+
* Attaches an annotation to a class
|
|
1299
|
+
*
|
|
1300
|
+
* @param clazz {Map} Static methods or fields
|
|
1301
|
+
* @param group {String} Group name
|
|
1302
|
+
* @param key {String} Name of the annotated item
|
|
1303
|
+
* @param anno {Object} Annotation object
|
|
1304
|
+
*/
|
|
1305
|
+
_attachAnno(clazz, group, key, anno) {
|
|
1306
|
+
// If there's no annotation, we have nothing to do
|
|
1307
|
+
if (anno === undefined) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
862
1310
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
1311
|
+
if (clazz.$$annotations === undefined) {
|
|
1312
|
+
clazz.$$annotations = {};
|
|
1313
|
+
clazz.$$annotations[group] = {};
|
|
1314
|
+
} else if (clazz.$$annotations[group] === undefined) {
|
|
1315
|
+
clazz.$$annotations[group] = {};
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
if (!Array.isArray(anno)) {
|
|
1319
|
+
anno = [anno];
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
if (key) {
|
|
1323
|
+
clazz.$$annotations[group][key] = anno;
|
|
1324
|
+
} else {
|
|
1325
|
+
clazz.$$annotations[group] = anno;
|
|
1326
|
+
}
|
|
1327
|
+
},
|
|
1328
|
+
|
|
1329
|
+
/**
|
|
1330
|
+
* Validates an incoming configuration and checks for proper keys and values
|
|
1331
|
+
*
|
|
1332
|
+
* @signature function(name, config)
|
|
1333
|
+
*
|
|
1334
|
+
* @param name {String}
|
|
1335
|
+
* The name of the class
|
|
1336
|
+
*
|
|
1337
|
+
* @param config {Map}
|
|
1338
|
+
* Configuration map
|
|
1339
|
+
*/
|
|
1340
|
+
_validateConfig: qx.core.Environment.select("qx.debug", {
|
|
1341
|
+
true(name, config) {
|
|
1342
|
+
// Validate type
|
|
1343
|
+
if (config.type && !(config.type === "static" || config.type === "abstract" || config.type === "singleton")) {
|
|
1344
|
+
throw new Error('Invalid type "' + config.type + '" definition for class "' + name + '"!');
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
// Validate non-static class on the "extend" key
|
|
1348
|
+
if (config.type && config.type !== "static" && !config.extend) {
|
|
1349
|
+
throw new Error(`${name}: invalid config. ` + "Non-static class must extend at least the `qx.core.Object` class");
|
|
874
1350
|
}
|
|
875
1351
|
|
|
876
1352
|
// Validate maps
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
"members",
|
|
881
|
-
"environment",
|
|
882
|
-
"settings",
|
|
883
|
-
"variants",
|
|
884
|
-
"events"
|
|
885
|
-
];
|
|
886
|
-
|
|
887
|
-
for (var i = 0, l = maps.length; i < l; i++) {
|
|
1353
|
+
let maps = ["statics", "properties", "members", "environment", "settings", "variants", "events"];
|
|
1354
|
+
|
|
1355
|
+
for (let i = 0, l = maps.length; i < l; i++) {
|
|
888
1356
|
var key = maps[i];
|
|
889
1357
|
|
|
890
1358
|
if (
|
|
891
1359
|
config[key] !== undefined &&
|
|
892
|
-
(config[key].$$hash !== undefined ||
|
|
893
|
-
!qx.Bootstrap.isObject(config[key]))
|
|
1360
|
+
(config[key] === null || config[key].$$hash !== undefined || !qx.Bootstrap.isObject(config[key]))
|
|
894
1361
|
) {
|
|
895
|
-
throw new Error(
|
|
896
|
-
'Invalid key "' +
|
|
897
|
-
key +
|
|
898
|
-
'" in class "' +
|
|
899
|
-
name +
|
|
900
|
-
'"! The value needs to be a map!'
|
|
901
|
-
);
|
|
1362
|
+
throw new Error('Invalid key "' + key + '" in class "' + name + '". The value needs to be a map.');
|
|
902
1363
|
}
|
|
903
1364
|
}
|
|
904
1365
|
|
|
905
1366
|
// Validate include definition
|
|
906
1367
|
if (config.include) {
|
|
907
1368
|
if (qx.Bootstrap.getClass(config.include) === "Array") {
|
|
908
|
-
for (
|
|
1369
|
+
for (let i = 0, a = config.include, l = a.length; i < l; i++) {
|
|
909
1370
|
if (a[i] == null || a[i].$$type !== "Mixin") {
|
|
910
|
-
throw new Error(
|
|
911
|
-
'The include definition in class "' +
|
|
912
|
-
name +
|
|
913
|
-
'" contains an invalid mixin at position ' +
|
|
914
|
-
i +
|
|
915
|
-
": " +
|
|
916
|
-
a[i]
|
|
917
|
-
);
|
|
1371
|
+
throw new Error('The include definition in class "' + name + '" contains an invalid mixin at position ' + i + ": " + a[i]);
|
|
918
1372
|
}
|
|
919
1373
|
}
|
|
920
1374
|
} else {
|
|
921
|
-
throw new Error(
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
1375
|
+
throw new Error('Invalid include definition in class "' + name + '"! Only mixins and arrays of mixins are allowed!');
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
if (config.type == "static") {
|
|
1379
|
+
config.include.forEach(mixin => {
|
|
1380
|
+
if (mixin.$$members) {
|
|
1381
|
+
throw new Error(`Mixin ${mixin.mixinName} applied to class ${name}: ` + "class is static, but mixin has members");
|
|
1382
|
+
}
|
|
1383
|
+
});
|
|
926
1384
|
}
|
|
927
1385
|
}
|
|
928
1386
|
|
|
929
1387
|
// Validate implement definition
|
|
930
1388
|
if (config.implement) {
|
|
931
1389
|
if (qx.Bootstrap.getClass(config.implement) === "Array") {
|
|
932
|
-
for (
|
|
1390
|
+
for (let i = 0, a = config.implement, l = a.length; i < l; i++) {
|
|
933
1391
|
if (a[i] == null || a[i].$$type !== "Interface") {
|
|
934
1392
|
throw new Error(
|
|
935
|
-
'The implement definition in class "' +
|
|
936
|
-
name +
|
|
937
|
-
'" contains an invalid interface at position ' +
|
|
938
|
-
i +
|
|
939
|
-
": " +
|
|
940
|
-
a[i]
|
|
1393
|
+
'The implement definition in class "' + name + '" contains an invalid interface at position ' + i + ": " + a[i]
|
|
941
1394
|
);
|
|
942
1395
|
}
|
|
943
1396
|
}
|
|
944
1397
|
} else {
|
|
945
|
-
throw new Error(
|
|
946
|
-
'Invalid implement definition in class "' +
|
|
947
|
-
name +
|
|
948
|
-
'"! Only interfaces and arrays of interfaces are allowed!'
|
|
949
|
-
);
|
|
1398
|
+
throw new Error('Invalid implement definition in class "' + name + '"! Only interfaces and arrays of interfaces are allowed!');
|
|
950
1399
|
}
|
|
951
1400
|
}
|
|
952
1401
|
|
|
@@ -955,22 +1404,14 @@ qx.Bootstrap.define("qx.Class", {
|
|
|
955
1404
|
try {
|
|
956
1405
|
qx.Mixin.checkCompatibility(config.include);
|
|
957
1406
|
} catch (ex) {
|
|
958
|
-
throw new Error(
|
|
959
|
-
'Error in include definition of class "' +
|
|
960
|
-
name +
|
|
961
|
-
'"! ' +
|
|
962
|
-
ex.message
|
|
963
|
-
);
|
|
1407
|
+
throw new Error('Error in include definition of class "' + name + '"! ' + ex.message);
|
|
964
1408
|
}
|
|
965
1409
|
}
|
|
966
1410
|
|
|
967
1411
|
// Validate environment
|
|
968
1412
|
if (config.environment) {
|
|
969
|
-
for (
|
|
970
|
-
if (
|
|
971
|
-
key.substr(0, key.indexOf(".")) !=
|
|
972
|
-
name.substr(0, name.indexOf("."))
|
|
973
|
-
) {
|
|
1413
|
+
for (let key in config.environment) {
|
|
1414
|
+
if (key.substr(0, key.indexOf(".")) != name.substr(0, name.indexOf("."))) {
|
|
974
1415
|
throw new Error(
|
|
975
1416
|
'Forbidden environment setting "' +
|
|
976
1417
|
key +
|
|
@@ -985,17 +1426,15 @@ qx.Bootstrap.define("qx.Class", {
|
|
|
985
1426
|
|
|
986
1427
|
// Validate settings
|
|
987
1428
|
if (config.settings) {
|
|
988
|
-
for (
|
|
989
|
-
if (
|
|
990
|
-
key.substr(0, key.indexOf(".")) !=
|
|
991
|
-
name.substr(0, name.indexOf("."))
|
|
992
|
-
) {
|
|
1429
|
+
for (let key in config.settings) {
|
|
1430
|
+
if (key.substr(0, key.indexOf(".")) != name.substr(0, name.indexOf("."))) {
|
|
993
1431
|
throw new Error(
|
|
994
1432
|
'Forbidden setting "' +
|
|
995
1433
|
key +
|
|
996
1434
|
'" found in "' +
|
|
997
1435
|
name +
|
|
998
|
-
'". It is forbidden to define a default setting for
|
|
1436
|
+
'". It is forbidden to define a default setting for ' +
|
|
1437
|
+
"an external namespace!"
|
|
999
1438
|
);
|
|
1000
1439
|
}
|
|
1001
1440
|
}
|
|
@@ -1003,906 +1442,492 @@ qx.Bootstrap.define("qx.Class", {
|
|
|
1003
1442
|
|
|
1004
1443
|
// Validate variants
|
|
1005
1444
|
if (config.variants) {
|
|
1006
|
-
for (
|
|
1007
|
-
if (
|
|
1008
|
-
key.substr(0, key.indexOf(".")) !=
|
|
1009
|
-
name.substr(0, name.indexOf("."))
|
|
1010
|
-
) {
|
|
1445
|
+
for (let key in config.variants) {
|
|
1446
|
+
if (key.substr(0, key.indexOf(".")) != name.substr(0, name.indexOf("."))) {
|
|
1011
1447
|
throw new Error(
|
|
1012
1448
|
'Forbidden variant "' +
|
|
1013
1449
|
key +
|
|
1014
1450
|
'" found in "' +
|
|
1015
1451
|
name +
|
|
1016
|
-
'". It is forbidden to define a variant for
|
|
1452
|
+
'". It is forbidden to define a variant for ' +
|
|
1453
|
+
"an external namespace!"
|
|
1017
1454
|
);
|
|
1018
1455
|
}
|
|
1019
1456
|
}
|
|
1020
1457
|
}
|
|
1021
1458
|
},
|
|
1022
1459
|
|
|
1023
|
-
default(
|
|
1460
|
+
default() {
|
|
1461
|
+
// do nothing when debug is disabled
|
|
1462
|
+
}
|
|
1024
1463
|
}),
|
|
1025
1464
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
while (superclass) {
|
|
1036
|
-
if (superclass.$$classtype !== "abstract") {
|
|
1037
|
-
break;
|
|
1465
|
+
_validatePropertyDefinitions: qx.core.Environment.select("qx.debug", {
|
|
1466
|
+
true(className, config) {
|
|
1467
|
+
let allowedKeys;
|
|
1468
|
+
let properties = config.properties || {};
|
|
1469
|
+
|
|
1470
|
+
// Ensure they're not passing a qx.core.Object descendent as property map
|
|
1471
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1472
|
+
if (config.properties !== undefined && qx.Bootstrap.isQxCoreObject(config.properties)) {
|
|
1473
|
+
throw new Error(`${className}: ` + "Can't use qx.core.Object descendent as property map");
|
|
1038
1474
|
}
|
|
1475
|
+
}
|
|
1039
1476
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1477
|
+
for (let prop in properties) {
|
|
1478
|
+
let property = properties[prop];
|
|
1479
|
+
|
|
1480
|
+
// Ensure they're not passing a qx.core.Object descendent as a property
|
|
1481
|
+
if (qx.core.Environment.get("qx.debug")) {
|
|
1482
|
+
if (qx.Bootstrap.isQxCoreObject(property)) {
|
|
1483
|
+
throw new Error(`${prop} in ${className}: ` + "Can't use qx.core.Object descendent as property");
|
|
1044
1484
|
}
|
|
1045
1485
|
}
|
|
1046
|
-
|
|
1486
|
+
|
|
1487
|
+
// Set allowed keys based on whether this is a grouped
|
|
1488
|
+
// property or not
|
|
1489
|
+
allowedKeys = property.group ? qx.Class._allowedPropGroupKeys : qx.Class._allowedPropKeys;
|
|
1490
|
+
|
|
1491
|
+
// Ensure only allowed keys were provided
|
|
1492
|
+
Object.keys(property).forEach(key => {
|
|
1493
|
+
let allowed = allowedKeys[key];
|
|
1494
|
+
|
|
1495
|
+
if (!(key in allowedKeys)) {
|
|
1496
|
+
throw new Error(
|
|
1497
|
+
`${className}: ` + (property.group ? "group " : "") + `property '${prop}' defined with unrecognized key '${key}'`
|
|
1498
|
+
);
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// Flag any deprecated keys
|
|
1502
|
+
if (key in qx.Class.$$deprecatedPropKeys) {
|
|
1503
|
+
console.warn(`Property '${prop}': ` + `${qx.Class.$$deprecatedPropKeys[key]}`);
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
if (allowed !== null) {
|
|
1507
|
+
// Convert non-array 'allowed' values to an array
|
|
1508
|
+
if (!Array.isArray(allowed)) {
|
|
1509
|
+
allowed = [allowed];
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
if (!allowed.includes(typeof property[key])) {
|
|
1513
|
+
throw new Error(
|
|
1514
|
+
`${className}: ` +
|
|
1515
|
+
(property.group ? "group " : "") +
|
|
1516
|
+
`property '${prop}' defined with wrong value type ` +
|
|
1517
|
+
`for key '${key}' (found ${typeof property[key]})`
|
|
1518
|
+
);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
});
|
|
1047
1522
|
}
|
|
1048
1523
|
},
|
|
1049
1524
|
|
|
1050
|
-
default(
|
|
1525
|
+
default(className, config) {
|
|
1526
|
+
// do nothing when debug is disabled
|
|
1527
|
+
}
|
|
1051
1528
|
}),
|
|
1052
1529
|
|
|
1053
1530
|
/**
|
|
1054
|
-
*
|
|
1531
|
+
* Find a class by its name
|
|
1055
1532
|
*
|
|
1056
|
-
* @
|
|
1057
|
-
*
|
|
1058
|
-
* @param
|
|
1059
|
-
*
|
|
1533
|
+
* @signature function(name)
|
|
1534
|
+
*
|
|
1535
|
+
* @param name {String}
|
|
1536
|
+
* Class name to resolve
|
|
1537
|
+
*
|
|
1538
|
+
* @return {Class}
|
|
1539
|
+
* The class
|
|
1060
1540
|
*/
|
|
1061
|
-
|
|
1062
|
-
if (anno !== undefined) {
|
|
1063
|
-
if (clazz.$$annotations === undefined) {
|
|
1064
|
-
clazz.$$annotations = {};
|
|
1065
|
-
clazz.$$annotations[group] = {};
|
|
1066
|
-
} else if (clazz.$$annotations[group] === undefined) {
|
|
1067
|
-
clazz.$$annotations[group] = {};
|
|
1068
|
-
}
|
|
1541
|
+
getByName: qx.Bootstrap.getByName,
|
|
1069
1542
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1543
|
+
/**
|
|
1544
|
+
* Returns the class or one of its superclasses which contains the
|
|
1545
|
+
* declaration for the given mixin. Returns null if the mixin is not
|
|
1546
|
+
* specified anywhere.
|
|
1547
|
+
*
|
|
1548
|
+
* @param clazz {Class}
|
|
1549
|
+
* Class to look for the mixin
|
|
1550
|
+
*
|
|
1551
|
+
* @param mixin {Mixin}
|
|
1552
|
+
* Mixin to look for
|
|
1553
|
+
*
|
|
1554
|
+
* @return {Class | null}
|
|
1555
|
+
* The class which directly includes the given mixin
|
|
1556
|
+
*/
|
|
1557
|
+
getByMixin(clazz, mixin) {
|
|
1558
|
+
while (clazz) {
|
|
1559
|
+
if (clazz.$$includes) {
|
|
1560
|
+
let list = clazz.$$flatIncludes;
|
|
1073
1561
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1562
|
+
for (let i = 0, l = list.length; i < l; i++) {
|
|
1563
|
+
if (list[i] === mixin) {
|
|
1564
|
+
return clazz;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1078
1567
|
}
|
|
1568
|
+
|
|
1569
|
+
clazz = clazz.superclass;
|
|
1079
1570
|
}
|
|
1571
|
+
|
|
1572
|
+
return null;
|
|
1080
1573
|
},
|
|
1081
1574
|
|
|
1082
1575
|
/**
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1085
|
-
* @param
|
|
1086
|
-
*
|
|
1087
|
-
*
|
|
1088
|
-
* @param
|
|
1089
|
-
*
|
|
1090
|
-
*
|
|
1091
|
-
* @
|
|
1092
|
-
*
|
|
1576
|
+
* Whether a given class or any of its superclasses includes a given mixin.
|
|
1577
|
+
*
|
|
1578
|
+
* @param clazz {Class}
|
|
1579
|
+
* Class to check
|
|
1580
|
+
*
|
|
1581
|
+
* @param mixin {Mixin}
|
|
1582
|
+
* The mixin to check for
|
|
1583
|
+
*
|
|
1584
|
+
* @return {Boolean}
|
|
1585
|
+
* Whether the class includes the mixin.
|
|
1093
1586
|
*/
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
};
|
|
1098
|
-
|
|
1099
|
-
var clazz;
|
|
1100
|
-
|
|
1101
|
-
if (!extend && qx.core.Environment.get("qx.aspects") == false) {
|
|
1102
|
-
// Create empty/non-empty class
|
|
1103
|
-
clazz = statics || {};
|
|
1104
|
-
qx.Bootstrap.setDisplayNames(clazz, name);
|
|
1105
|
-
} else {
|
|
1106
|
-
clazz = {};
|
|
1587
|
+
hasMixin(clazz, mixin) {
|
|
1588
|
+
return !!this.getByMixin(clazz, mixin);
|
|
1589
|
+
},
|
|
1107
1590
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1591
|
+
/**
|
|
1592
|
+
* Whether a given class directly includes an interface.
|
|
1593
|
+
*
|
|
1594
|
+
* This function will only return "true" if the interface was
|
|
1595
|
+
* defined in the class declaration ({@link qx.Class#define})
|
|
1596
|
+
* using the "implement" key.
|
|
1597
|
+
*
|
|
1598
|
+
* @param clazz {Class}
|
|
1599
|
+
* Class or instance to check
|
|
1600
|
+
*
|
|
1601
|
+
* @param iface {Interface}
|
|
1602
|
+
* The interface to check for
|
|
1603
|
+
*
|
|
1604
|
+
* @return {Boolean}
|
|
1605
|
+
* Whether the class includes the mixin directly.
|
|
1606
|
+
*/
|
|
1607
|
+
hasOwnInterface(clazz, iface) {
|
|
1608
|
+
return clazz.$$implements && clazz.$$implements.includes(iface);
|
|
1609
|
+
},
|
|
1113
1610
|
|
|
1114
|
-
|
|
1611
|
+
/**
|
|
1612
|
+
* Returns the class or one of its super classes which contains the
|
|
1613
|
+
* declaration of the given interface. Returns null if the interface is
|
|
1614
|
+
* not specified anywhere.
|
|
1615
|
+
*
|
|
1616
|
+
* @signature function(clazz, iface)
|
|
1617
|
+
*
|
|
1618
|
+
* @param clazz {Class}
|
|
1619
|
+
* Class to look for the interface
|
|
1620
|
+
*
|
|
1621
|
+
* @param iface {Interface}
|
|
1622
|
+
* Interface to look for
|
|
1623
|
+
*
|
|
1624
|
+
* @return {Class | null}
|
|
1625
|
+
* The class which directly implements the given interface
|
|
1626
|
+
*/
|
|
1627
|
+
getByInterface: qx.util.OOUtil.getByInterface,
|
|
1115
1628
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1629
|
+
/**
|
|
1630
|
+
* Returns a list of all interfaces a given class has to implement.
|
|
1631
|
+
*
|
|
1632
|
+
* @param clazz {Class}
|
|
1633
|
+
* Class which should be inspected
|
|
1634
|
+
*
|
|
1635
|
+
* @return {Interface[]}
|
|
1636
|
+
* Array of interfaces this class implements
|
|
1637
|
+
*/
|
|
1638
|
+
getInterfaces(clazz) {
|
|
1639
|
+
let list = [];
|
|
1120
1640
|
|
|
1121
|
-
|
|
1641
|
+
while (clazz) {
|
|
1642
|
+
if (clazz.$$implements) {
|
|
1643
|
+
list.push.apply(list, clazz.$$flatImplements);
|
|
1122
1644
|
}
|
|
1123
1645
|
|
|
1124
|
-
|
|
1125
|
-
if (statics) {
|
|
1126
|
-
qx.Bootstrap.setDisplayNames(statics, name);
|
|
1127
|
-
|
|
1128
|
-
var key;
|
|
1129
|
-
|
|
1130
|
-
for (var i = 0, a = Object.keys(statics), l = a.length; i < l; i++) {
|
|
1131
|
-
key = a[i];
|
|
1132
|
-
var staticValue = statics[key];
|
|
1133
|
-
|
|
1134
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1135
|
-
if (key.charAt(0) === "@") {
|
|
1136
|
-
if (statics[key.substring(1)] === undefined) {
|
|
1137
|
-
throw new Error(
|
|
1138
|
-
'Annonation for static "' +
|
|
1139
|
-
key.substring(1) +
|
|
1140
|
-
'" of Class "' +
|
|
1141
|
-
clazz.classname +
|
|
1142
|
-
'" does not exist!'
|
|
1143
|
-
);
|
|
1144
|
-
}
|
|
1145
|
-
if (key.charAt(1) === "_" && key.charAt(2) === "_") {
|
|
1146
|
-
throw new Error(
|
|
1147
|
-
'Cannot annotate private static "' +
|
|
1148
|
-
key.substring(1) +
|
|
1149
|
-
'" of Class "' +
|
|
1150
|
-
clazz.classname
|
|
1151
|
-
);
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
if (key.charAt(0) === "@") {
|
|
1156
|
-
continue;
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
if (qx.core.Environment.get("qx.aspects")) {
|
|
1160
|
-
if (staticValue instanceof Function) {
|
|
1161
|
-
staticValue = qx.core.Aspect.wrap(
|
|
1162
|
-
name + "." + key,
|
|
1163
|
-
staticValue,
|
|
1164
|
-
"static"
|
|
1165
|
-
);
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
clazz[key] = staticValue;
|
|
1169
|
-
} else {
|
|
1170
|
-
clazz[key] = staticValue;
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
// Attach annotations
|
|
1174
|
-
this.__attachAnno(clazz, "statics", key, statics["@" + key]);
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1646
|
+
clazz = clazz.superclass;
|
|
1177
1647
|
}
|
|
1178
1648
|
|
|
1179
|
-
|
|
1180
|
-
|
|
1649
|
+
return list;
|
|
1650
|
+
},
|
|
1181
1651
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1652
|
+
/**
|
|
1653
|
+
* Whether a given class or any of its super classes includes a
|
|
1654
|
+
* given interface.
|
|
1655
|
+
*
|
|
1656
|
+
* This function will return "true" if the interface was defined
|
|
1657
|
+
* in the class declaration ({@link qx.Class#define}) of the
|
|
1658
|
+
* class or any of its super classes using the "implement" key.
|
|
1659
|
+
*
|
|
1660
|
+
* @signature function(clazz, iface)
|
|
1661
|
+
*
|
|
1662
|
+
* @param clazz {Class}
|
|
1663
|
+
* Class to check
|
|
1664
|
+
*
|
|
1665
|
+
* @param iface {Interface}
|
|
1666
|
+
* The interface to check for
|
|
1667
|
+
*
|
|
1668
|
+
* @return {Boolean}
|
|
1669
|
+
* Whether the class includes the interface.
|
|
1670
|
+
*/
|
|
1671
|
+
hasInterface: qx.util.OOUtil.hasInterface,
|
|
1192
1672
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1673
|
+
/**
|
|
1674
|
+
* Whether a given class complies to an interface.
|
|
1675
|
+
*
|
|
1676
|
+
* Checks whether all methods defined in the interface are
|
|
1677
|
+
* implemented. The class does not need to implement
|
|
1678
|
+
* the interface explicitly in the <code>extend</code> key.
|
|
1679
|
+
*
|
|
1680
|
+
* @param obj {Object}
|
|
1681
|
+
* Class to check
|
|
1682
|
+
*
|
|
1683
|
+
* @param iface {Interface}
|
|
1684
|
+
* The interface to check for
|
|
1685
|
+
*
|
|
1686
|
+
* @return {Boolean}
|
|
1687
|
+
* Whether the class conforms to the interface.
|
|
1688
|
+
*/
|
|
1689
|
+
implementsInterface(obj, iface) {
|
|
1690
|
+
let clazz = obj.constructor;
|
|
1198
1691
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
clazz.toString = this.genericToString;
|
|
1692
|
+
if (this.hasInterface(clazz, iface)) {
|
|
1693
|
+
return true;
|
|
1202
1694
|
}
|
|
1203
1695
|
|
|
1204
|
-
if (
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
// Store destruct onto class
|
|
1208
|
-
if (destruct) {
|
|
1209
|
-
if (qx.core.Environment.get("qx.aspects")) {
|
|
1210
|
-
destruct = qx.core.Aspect.wrap(name, destruct, "destructor");
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
clazz.$$destructor = destruct;
|
|
1214
|
-
qx.Bootstrap.setDisplayName(destruct, name, "destruct");
|
|
1215
|
-
}
|
|
1696
|
+
if (qx.Interface.objectImplements(obj, iface)) {
|
|
1697
|
+
return true;
|
|
1216
1698
|
}
|
|
1217
1699
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1700
|
+
if (qx.Interface.classImplements(clazz, iface)) {
|
|
1701
|
+
return true;
|
|
1702
|
+
}
|
|
1220
1703
|
|
|
1221
|
-
|
|
1222
|
-
return clazz;
|
|
1704
|
+
return false;
|
|
1223
1705
|
},
|
|
1224
1706
|
|
|
1225
|
-
/*
|
|
1226
|
-
---------------------------------------------------------------------------
|
|
1227
|
-
PRIVATE ADD HELPERS
|
|
1228
|
-
---------------------------------------------------------------------------
|
|
1229
|
-
*/
|
|
1230
|
-
|
|
1231
1707
|
/**
|
|
1232
|
-
*
|
|
1708
|
+
* Whether the given class exists
|
|
1233
1709
|
*
|
|
1234
|
-
* @
|
|
1235
|
-
* @param
|
|
1236
|
-
* @
|
|
1710
|
+
* @signature function(name)
|
|
1711
|
+
* @param name {String} class name to check
|
|
1712
|
+
* @return {Boolean} true if class exists
|
|
1237
1713
|
*/
|
|
1238
|
-
|
|
1239
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1240
|
-
if (
|
|
1241
|
-
typeof events !== "object" ||
|
|
1242
|
-
qx.Bootstrap.getClass(events) === "Array"
|
|
1243
|
-
) {
|
|
1244
|
-
throw new Error(
|
|
1245
|
-
clazz.classname + ": the events must be defined as map!"
|
|
1246
|
-
);
|
|
1247
|
-
}
|
|
1714
|
+
isDefined: qx.util.OOUtil.classIsDefined,
|
|
1248
1715
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
// Compare old and new event type/value if patching is disabled
|
|
1261
|
-
if (clazz.$$events && patch !== true) {
|
|
1262
|
-
for (var key in events) {
|
|
1263
|
-
if (
|
|
1264
|
-
clazz.$$events[key] !== undefined &&
|
|
1265
|
-
clazz.$$events[key] !== events[key]
|
|
1266
|
-
) {
|
|
1267
|
-
throw new Error(
|
|
1268
|
-
clazz.classname +
|
|
1269
|
-
"/" +
|
|
1270
|
-
key +
|
|
1271
|
-
": the event value/type cannot be changed from " +
|
|
1272
|
-
clazz.$$events[key] +
|
|
1273
|
-
" to " +
|
|
1274
|
-
events[key]
|
|
1275
|
-
);
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
if (clazz.$$events) {
|
|
1282
|
-
for (var key in events) {
|
|
1283
|
-
clazz.$$events[key] = events[key];
|
|
1284
|
-
}
|
|
1285
|
-
} else {
|
|
1286
|
-
clazz.$$events = events;
|
|
1287
|
-
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Detects whether the object is a Class (and not an instance of a class)
|
|
1718
|
+
*
|
|
1719
|
+
* @param obj {Object?} the object to inspect
|
|
1720
|
+
* @return {Boolean} true if it is a class, false if it is anything else
|
|
1721
|
+
*/
|
|
1722
|
+
isClass(obj) {
|
|
1723
|
+
return obj && obj.$$type === "Class" && obj.constructor === obj;
|
|
1288
1724
|
},
|
|
1289
1725
|
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
if (typeof key != "string") {
|
|
1302
|
-
throw new Error(
|
|
1303
|
-
"Invalid cached object key for " + key + " in " + clazz.classname
|
|
1304
|
-
);
|
|
1305
|
-
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Whether a class is a direct or indirect sub class of another class,
|
|
1728
|
+
* or both classes coincide.
|
|
1729
|
+
*
|
|
1730
|
+
* @param clazz {Class} the class to check.
|
|
1731
|
+
* @param superClass {Class} the potential super class
|
|
1732
|
+
* @return {Boolean} whether clazz is a sub class of superClass.
|
|
1733
|
+
*/
|
|
1734
|
+
isSubClassOf(clazz, superClass) {
|
|
1735
|
+
if (!clazz) {
|
|
1736
|
+
return false;
|
|
1306
1737
|
}
|
|
1307
1738
|
|
|
1308
|
-
if (
|
|
1309
|
-
|
|
1739
|
+
if (clazz == superClass) {
|
|
1740
|
+
return true;
|
|
1310
1741
|
}
|
|
1311
1742
|
|
|
1312
|
-
if (
|
|
1313
|
-
|
|
1314
|
-
validateCachedObject(key, objects[key]);
|
|
1315
|
-
}
|
|
1743
|
+
if (clazz.prototype instanceof superClass) {
|
|
1744
|
+
return true;
|
|
1316
1745
|
}
|
|
1317
1746
|
|
|
1318
|
-
|
|
1747
|
+
return false;
|
|
1319
1748
|
},
|
|
1320
1749
|
|
|
1321
1750
|
/**
|
|
1322
|
-
*
|
|
1751
|
+
* Retreive all subclasses of a given class
|
|
1752
|
+
*
|
|
1753
|
+
* @param clazz {Class}
|
|
1754
|
+
* The class which should be inspected
|
|
1323
1755
|
*
|
|
1324
|
-
* @
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
which means you are able to refine but not to replace (esp. for new properties)
|
|
1756
|
+
* @return {Object}
|
|
1757
|
+
* Class name hash holding the references to the subclasses or
|
|
1758
|
+
* null if the class does not exist.
|
|
1328
1759
|
*/
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
throw new Error("Property module disabled.");
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1336
|
-
if (qx.Bootstrap.isQxCoreObject(properties)) {
|
|
1337
|
-
throw new Error("Invalid 'properties' for " + clazz.classname);
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
var config;
|
|
1342
|
-
|
|
1343
|
-
if (patch === undefined) {
|
|
1344
|
-
patch = false;
|
|
1760
|
+
getSubclasses(clazz) {
|
|
1761
|
+
if (!clazz) {
|
|
1762
|
+
return null;
|
|
1345
1763
|
}
|
|
1346
1764
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
for (var name in properties) {
|
|
1350
|
-
config = properties[name];
|
|
1351
|
-
|
|
1352
|
-
// Check incoming configuration
|
|
1353
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1354
|
-
this.__validateProperty(clazz, name, config, patch);
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
|
-
// Store name into configuration
|
|
1358
|
-
config.name = name;
|
|
1359
|
-
|
|
1360
|
-
// Add config to local registry
|
|
1361
|
-
if (!config.refine) {
|
|
1362
|
-
if (clazz.$$properties === undefined) {
|
|
1363
|
-
clazz.$$properties = {};
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
clazz.$$properties[name] = config;
|
|
1367
|
-
}
|
|
1368
|
-
|
|
1369
|
-
// Store init value to prototype. This makes it possible to
|
|
1370
|
-
// overwrite this value in derived classes.
|
|
1371
|
-
if (config.init !== undefined) {
|
|
1372
|
-
clazz.prototype["$$init_" + name] = config.init;
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
// register event name
|
|
1376
|
-
if (config.event !== undefined) {
|
|
1377
|
-
// break if no events layer loaded
|
|
1378
|
-
if (!qx.core.Environment.get("module.events")) {
|
|
1379
|
-
throw new Error("Events module not enabled.");
|
|
1380
|
-
}
|
|
1381
|
-
var event = {};
|
|
1382
|
-
event[config.event] = "qx.event.type.Data";
|
|
1383
|
-
if (config.async) {
|
|
1384
|
-
event[config.event + "Async"] = "qx.event.type.Data";
|
|
1385
|
-
}
|
|
1386
|
-
this.__addEvents(clazz, event, patch);
|
|
1387
|
-
}
|
|
1765
|
+
let subclasses = {};
|
|
1766
|
+
let registry = qx.Bootstrap.$$registry;
|
|
1388
1767
|
|
|
1389
|
-
|
|
1390
|
-
if (
|
|
1391
|
-
|
|
1392
|
-
if (!proto.$$refreshInheritables) {
|
|
1393
|
-
this.__Property.attachRefreshInheritables(clazz);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
if (!config.refine) {
|
|
1398
|
-
this.__Property.attachMethods(clazz, name, config);
|
|
1768
|
+
for (let name in registry) {
|
|
1769
|
+
if (registry[name].superclass && registry[name].superclass == clazz) {
|
|
1770
|
+
subclasses[name] = registry[name];
|
|
1399
1771
|
}
|
|
1400
|
-
|
|
1401
|
-
// Add annotations
|
|
1402
|
-
this.__attachAnno(clazz, "properties", name, config["@"]);
|
|
1403
1772
|
}
|
|
1773
|
+
|
|
1774
|
+
return subclasses;
|
|
1404
1775
|
},
|
|
1405
1776
|
|
|
1406
1777
|
/**
|
|
1407
|
-
*
|
|
1778
|
+
* Returns the definition of the given property. Returns null
|
|
1779
|
+
* if the property does not exist.
|
|
1408
1780
|
*
|
|
1409
|
-
* @signature function(clazz, name
|
|
1410
|
-
* @param clazz {Class} class to
|
|
1411
|
-
* @param name {String} name of the
|
|
1412
|
-
* @
|
|
1413
|
-
* @param patch {Boolean ? false} enable refine/patch?
|
|
1781
|
+
* @signature function(clazz, name)
|
|
1782
|
+
* @param clazz {Class} class to check
|
|
1783
|
+
* @param name {String} name of the class to check for
|
|
1784
|
+
* @return {Map|null} whether the object support the given event.
|
|
1414
1785
|
*/
|
|
1415
|
-
|
|
1416
|
-
true(clazz, name, config, patch) {
|
|
1417
|
-
// check for properties
|
|
1418
|
-
if (!qx.core.Environment.get("module.property")) {
|
|
1419
|
-
throw new Error("Property module disabled.");
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
var has = this.hasProperty(clazz, name);
|
|
1423
|
-
|
|
1424
|
-
if (has) {
|
|
1425
|
-
var existingProperty = this.getPropertyDefinition(clazz, name);
|
|
1426
|
-
|
|
1427
|
-
if (
|
|
1428
|
-
config.refine &&
|
|
1429
|
-
existingProperty.init === undefined &&
|
|
1430
|
-
existingProperty["@"] === undefined
|
|
1431
|
-
) {
|
|
1432
|
-
this.warn(
|
|
1433
|
-
"Refine a property when there is previously no init or annotations defined. Property '" +
|
|
1434
|
-
name +
|
|
1435
|
-
"' of class '" +
|
|
1436
|
-
clazz.classname +
|
|
1437
|
-
"'."
|
|
1438
|
-
);
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
|
|
1442
|
-
if (!has && config.refine) {
|
|
1443
|
-
throw new Error(
|
|
1444
|
-
"Could not refine non-existent property: '" +
|
|
1445
|
-
name +
|
|
1446
|
-
"' of class: '" +
|
|
1447
|
-
clazz.classname +
|
|
1448
|
-
"'!"
|
|
1449
|
-
);
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1452
|
-
if (has && !patch) {
|
|
1453
|
-
throw new Error(
|
|
1454
|
-
"Class " +
|
|
1455
|
-
clazz.classname +
|
|
1456
|
-
" already has a property: " +
|
|
1457
|
-
name +
|
|
1458
|
-
"!"
|
|
1459
|
-
);
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
if (has && patch) {
|
|
1463
|
-
if (!config.refine) {
|
|
1464
|
-
throw new Error(
|
|
1465
|
-
'Could not refine property "' +
|
|
1466
|
-
name +
|
|
1467
|
-
'" without a "refine" flag in the property definition! This class: ' +
|
|
1468
|
-
clazz.classname +
|
|
1469
|
-
", original class: " +
|
|
1470
|
-
this.getByProperty(clazz, name).classname +
|
|
1471
|
-
"."
|
|
1472
|
-
);
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
|
-
for (var key in config) {
|
|
1476
|
-
if (key !== "init" && key !== "refine" && key !== "@") {
|
|
1477
|
-
throw new Error(
|
|
1478
|
-
"Class " +
|
|
1479
|
-
clazz.classname +
|
|
1480
|
-
" could not refine property: " +
|
|
1481
|
-
name +
|
|
1482
|
-
"! Key: " +
|
|
1483
|
-
key +
|
|
1484
|
-
" could not be refined!"
|
|
1485
|
-
);
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
// Check 0.7 keys
|
|
1491
|
-
var allowed = config.group
|
|
1492
|
-
? this.__Property.$$allowedGroupKeys
|
|
1493
|
-
: this.__Property.$$allowedKeys;
|
|
1494
|
-
for (var key in config) {
|
|
1495
|
-
if (allowed[key] === undefined) {
|
|
1496
|
-
throw new Error(
|
|
1497
|
-
'The configuration key "' +
|
|
1498
|
-
key +
|
|
1499
|
-
'" of property "' +
|
|
1500
|
-
name +
|
|
1501
|
-
'" in class "' +
|
|
1502
|
-
clazz.classname +
|
|
1503
|
-
'" is not allowed!'
|
|
1504
|
-
);
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
if (config[key] === undefined) {
|
|
1508
|
-
throw new Error(
|
|
1509
|
-
'Invalid key "' +
|
|
1510
|
-
key +
|
|
1511
|
-
'" of property "' +
|
|
1512
|
-
name +
|
|
1513
|
-
'" in class "' +
|
|
1514
|
-
clazz.classname +
|
|
1515
|
-
'"! The value is undefined: ' +
|
|
1516
|
-
config[key]
|
|
1517
|
-
);
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
if (allowed[key] !== null && typeof config[key] !== allowed[key]) {
|
|
1521
|
-
throw new Error(
|
|
1522
|
-
'Invalid type of key "' +
|
|
1523
|
-
key +
|
|
1524
|
-
'" of property "' +
|
|
1525
|
-
name +
|
|
1526
|
-
'" in class "' +
|
|
1527
|
-
clazz.classname +
|
|
1528
|
-
'"! The type of the key must be "' +
|
|
1529
|
-
allowed[key] +
|
|
1530
|
-
'"!'
|
|
1531
|
-
);
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
if (config.transform != null) {
|
|
1536
|
-
if (!(typeof config.transform === "string")) {
|
|
1537
|
-
throw new Error(
|
|
1538
|
-
'Invalid transform definition of property "' +
|
|
1539
|
-
name +
|
|
1540
|
-
'" in class "' +
|
|
1541
|
-
clazz.classname +
|
|
1542
|
-
'"! Needs to be a String.'
|
|
1543
|
-
);
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
if (config.check != null) {
|
|
1548
|
-
if (
|
|
1549
|
-
!qx.Bootstrap.isString(config.check) &&
|
|
1550
|
-
!qx.Bootstrap.isArray(config.check) &&
|
|
1551
|
-
!qx.Bootstrap.isFunction(config.check)
|
|
1552
|
-
) {
|
|
1553
|
-
throw new Error(
|
|
1554
|
-
'Invalid check definition of property "' +
|
|
1555
|
-
name +
|
|
1556
|
-
'" in class "' +
|
|
1557
|
-
clazz.classname +
|
|
1558
|
-
'"! Needs to be a String, Array or Function.'
|
|
1559
|
-
);
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
},
|
|
1563
|
-
|
|
1564
|
-
default: null
|
|
1565
|
-
}),
|
|
1786
|
+
getPropertyDefinition: qx.util.OOUtil.getPropertyDefinition,
|
|
1566
1787
|
|
|
1567
1788
|
/**
|
|
1568
|
-
*
|
|
1789
|
+
* Returns a list of all properties supported by the given class
|
|
1569
1790
|
*
|
|
1570
|
-
* @param clazz {Class}
|
|
1571
|
-
* @
|
|
1572
|
-
* @param patch {Boolean ? false} Enable patching of
|
|
1573
|
-
* @param base {Boolean ? true} Attach base flag to mark function as members
|
|
1574
|
-
* of this class
|
|
1575
|
-
* @param wrap {Boolean ? false} Whether the member method should be wrapped.
|
|
1576
|
-
* this is needed to allow base calls in patched mixin members.
|
|
1791
|
+
* @param clazz {Class} Class to query
|
|
1792
|
+
* @return {String[]} List of all property names
|
|
1577
1793
|
*/
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
var key, member;
|
|
1581
|
-
qx.Bootstrap.setDisplayNames(members, clazz.classname + ".prototype");
|
|
1582
|
-
|
|
1583
|
-
for (var i = 0, a = Object.keys(members), l = a.length; i < l; i++) {
|
|
1584
|
-
key = a[i];
|
|
1585
|
-
member = members[key];
|
|
1586
|
-
|
|
1587
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1588
|
-
if (key.charAt(0) === "@") {
|
|
1589
|
-
var annoKey = key.substring(1);
|
|
1590
|
-
if (
|
|
1591
|
-
members[annoKey] === undefined &&
|
|
1592
|
-
proto[annoKey] === undefined
|
|
1593
|
-
) {
|
|
1594
|
-
throw new Error(
|
|
1595
|
-
'Annonation for "' +
|
|
1596
|
-
annoKey +
|
|
1597
|
-
'" of Class "' +
|
|
1598
|
-
clazz.classname +
|
|
1599
|
-
'" does not exist!'
|
|
1600
|
-
);
|
|
1601
|
-
}
|
|
1602
|
-
if (key.charAt(1) === "_" && key.charAt(2) === "_") {
|
|
1603
|
-
throw new Error(
|
|
1604
|
-
'Cannot annotate private member "' +
|
|
1605
|
-
key.substring(1) +
|
|
1606
|
-
'" of Class "' +
|
|
1607
|
-
clazz.classname
|
|
1608
|
-
);
|
|
1609
|
-
}
|
|
1610
|
-
} else {
|
|
1611
|
-
if (
|
|
1612
|
-
proto[key] !== undefined &&
|
|
1613
|
-
key.charAt(0) === "_" &&
|
|
1614
|
-
key.charAt(1) === "_"
|
|
1615
|
-
) {
|
|
1616
|
-
throw new Error(
|
|
1617
|
-
'Overwriting private member "' +
|
|
1618
|
-
key +
|
|
1619
|
-
'" of Class "' +
|
|
1620
|
-
clazz.classname +
|
|
1621
|
-
'" is not allowed!'
|
|
1622
|
-
);
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1625
|
-
if (
|
|
1626
|
-
patch !== true &&
|
|
1627
|
-
proto.hasOwnProperty(key) &&
|
|
1628
|
-
key != "_createQxObjectImpl"
|
|
1629
|
-
) {
|
|
1630
|
-
throw new Error(
|
|
1631
|
-
'Overwriting member "' +
|
|
1632
|
-
key +
|
|
1633
|
-
'" of Class "' +
|
|
1634
|
-
clazz.classname +
|
|
1635
|
-
'" is not allowed!'
|
|
1636
|
-
);
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
|
|
1641
|
-
// Annotations are not members
|
|
1642
|
-
if (key.charAt(0) === "@") {
|
|
1643
|
-
var annoKey = key.substring(1);
|
|
1644
|
-
if (members[annoKey] === undefined) {
|
|
1645
|
-
this.__attachAnno(clazz, "members", annoKey, members[key]);
|
|
1646
|
-
}
|
|
1647
|
-
continue;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
// If it's a property accessor, we need to install it now so that this.base can refer to it
|
|
1651
|
-
if (proto[key] != undefined && proto[key].$$install) {
|
|
1652
|
-
proto[key].$$install();
|
|
1653
|
-
}
|
|
1654
|
-
|
|
1655
|
-
// Added helper stuff to functions
|
|
1656
|
-
// Hint: Could not use typeof function because RegExp objects are functions, too
|
|
1657
|
-
// Protect to apply base property and aspect support on special attributes e.g.
|
|
1658
|
-
// classes which are function like as well.
|
|
1659
|
-
if (
|
|
1660
|
-
base !== false &&
|
|
1661
|
-
member instanceof Function &&
|
|
1662
|
-
member.$$type == null
|
|
1663
|
-
) {
|
|
1664
|
-
// If the class has it's own implementation, we need to remember that method in the
|
|
1665
|
-
// mixed-in method's `.base`; wrap the method with a closure so that it can have a
|
|
1666
|
-
// `.base` set, if we were to set `member.base` it would mean that the mixin can
|
|
1667
|
-
// only be added into one class
|
|
1668
|
-
if (wrap) {
|
|
1669
|
-
if (proto[key]) {
|
|
1670
|
-
member = qx.lang.Function.create(member, { always: true });
|
|
1671
|
-
}
|
|
1672
|
-
member.self = clazz;
|
|
1673
|
-
}
|
|
1674
|
-
member.base = proto[key];
|
|
1675
|
-
|
|
1676
|
-
if (qx.core.Environment.get("qx.aspects")) {
|
|
1677
|
-
member = qx.core.Aspect.wrap(
|
|
1678
|
-
clazz.classname + "." + key,
|
|
1679
|
-
member,
|
|
1680
|
-
"member"
|
|
1681
|
-
);
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
|
-
// Attach member
|
|
1686
|
-
proto[key] = member;
|
|
1687
|
-
|
|
1688
|
-
// Attach annotations
|
|
1689
|
-
this.__attachAnno(clazz, "members", key, members["@" + key]);
|
|
1690
|
-
}
|
|
1794
|
+
getProperties(clazz) {
|
|
1795
|
+
return Object.keys(clazz.prototype.$$allProperties);
|
|
1691
1796
|
},
|
|
1692
1797
|
|
|
1693
1798
|
/**
|
|
1694
|
-
*
|
|
1799
|
+
* Returns the class or one of its superclasses which contains the
|
|
1800
|
+
* declaration for the given property in its class definition. Returns null
|
|
1801
|
+
* if the property is not specified anywhere.
|
|
1695
1802
|
*
|
|
1696
|
-
* @param clazz {Class} class to
|
|
1697
|
-
* @param
|
|
1803
|
+
* @param clazz {Class} class to look for the property
|
|
1804
|
+
* @param name {String} name of the property
|
|
1805
|
+
* @return {Class | null} The class which includes the property
|
|
1698
1806
|
*/
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
if (!clazz || !iface) {
|
|
1702
|
-
throw new Error("Incomplete parameters!");
|
|
1703
|
-
}
|
|
1704
|
-
|
|
1705
|
-
// This differs from mixins, we only check if the interface is already
|
|
1706
|
-
// directly used by this class. It is allowed however, to have an interface
|
|
1707
|
-
// included multiple times by extends in the interfaces etc.
|
|
1708
|
-
if (this.hasOwnInterface(clazz, iface)) {
|
|
1709
|
-
throw new Error(
|
|
1710
|
-
'Interface "' +
|
|
1711
|
-
iface.name +
|
|
1712
|
-
'" is already used by Class "' +
|
|
1713
|
-
clazz.classname +
|
|
1714
|
-
"!"
|
|
1715
|
-
);
|
|
1716
|
-
}
|
|
1717
|
-
|
|
1718
|
-
// Check interface and wrap members
|
|
1719
|
-
if (clazz.$$classtype !== "abstract") {
|
|
1720
|
-
qx.Interface.assert(clazz, iface, true);
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
|
|
1724
|
-
// Store interface reference
|
|
1725
|
-
var list = qx.Interface.flatten([iface]);
|
|
1726
|
-
if (clazz.$$implements) {
|
|
1727
|
-
clazz.$$implements.push(iface);
|
|
1728
|
-
clazz.$$flatImplements.push.apply(clazz.$$flatImplements, list);
|
|
1729
|
-
} else {
|
|
1730
|
-
clazz.$$implements = [iface];
|
|
1731
|
-
clazz.$$flatImplements = list;
|
|
1732
|
-
}
|
|
1807
|
+
getByProperty(clazz, name) {
|
|
1808
|
+
return clazz.prototype.$$allProperties?.[name] ?? null;
|
|
1733
1809
|
},
|
|
1734
1810
|
|
|
1735
1811
|
/**
|
|
1736
|
-
*
|
|
1812
|
+
* Returns the property descriptor (Property object) of the given property.
|
|
1813
|
+
* Returns null if the property does not exist.
|
|
1737
1814
|
*
|
|
1738
|
-
*
|
|
1739
|
-
*
|
|
1740
|
-
*
|
|
1815
|
+
* This provides access to the first-class Property object in qooxdoo v8,
|
|
1816
|
+
* which contains the property configuration and metadata.
|
|
1817
|
+
*
|
|
1818
|
+
* When an instance is provided, the returned descriptor's set() and get() methods
|
|
1819
|
+
* are bound to that instance, allowing direct calls like descriptor.set(value).
|
|
1820
|
+
*
|
|
1821
|
+
* @param clazz {Class} class to check
|
|
1822
|
+
* @param name {String} name of the property to check for
|
|
1823
|
+
* @param instance {qx.core.Object?} optional instance to bind the descriptor to
|
|
1824
|
+
* @return {qx.core.property.Property|null} Property object or null if not found
|
|
1741
1825
|
*/
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
if (this.hasMixin(clazz, mixin)) {
|
|
1750
|
-
return;
|
|
1826
|
+
getPropertyDescriptor(clazz, name, instance) {
|
|
1827
|
+
let property = this.getByProperty(clazz, name);
|
|
1828
|
+
if (!property) {
|
|
1829
|
+
return null;
|
|
1751
1830
|
}
|
|
1752
1831
|
|
|
1753
|
-
//
|
|
1754
|
-
|
|
1755
|
-
var entry;
|
|
1756
|
-
|
|
1757
|
-
for (var i = 0, l = list.length; i < l; i++) {
|
|
1758
|
-
entry = list[i];
|
|
1759
|
-
|
|
1760
|
-
// Attach events
|
|
1761
|
-
if (entry.$$events) {
|
|
1762
|
-
this.__addEvents(clazz, entry.$$events, patch);
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
// Attach properties (Properties are already readonly themselves, no patch handling needed)
|
|
1766
|
-
if (entry.$$properties) {
|
|
1767
|
-
this.__addProperties(clazz, entry.$$properties, patch);
|
|
1768
|
-
}
|
|
1832
|
+
// Create a wrapper that delegates to the property
|
|
1833
|
+
let descriptor = Object.create(property);
|
|
1769
1834
|
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1835
|
+
if (instance) {
|
|
1836
|
+
// If instance is provided, bind set/get methods to the instance
|
|
1837
|
+
// This allows descriptor.set(value) instead of descriptor.set.call(instance, value)
|
|
1838
|
+
descriptor.set = function(value) {
|
|
1839
|
+
property.set(instance, value);
|
|
1840
|
+
};
|
|
1775
1841
|
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
clazz.$$flatIncludes.push.apply(clazz.$$flatIncludes, list);
|
|
1842
|
+
descriptor.get = function() {
|
|
1843
|
+
return property.get(instance);
|
|
1844
|
+
};
|
|
1780
1845
|
} else {
|
|
1781
|
-
|
|
1782
|
-
|
|
1846
|
+
// Without instance, provide unbound methods that work with .call()
|
|
1847
|
+
descriptor.set = function(value) {
|
|
1848
|
+
property.set(this, value);
|
|
1849
|
+
};
|
|
1850
|
+
|
|
1851
|
+
descriptor.get = function() {
|
|
1852
|
+
return property.get(this);
|
|
1853
|
+
};
|
|
1783
1854
|
}
|
|
1784
|
-
},
|
|
1785
1855
|
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
PRIVATE FUNCTION HELPERS
|
|
1789
|
-
---------------------------------------------------------------------------
|
|
1790
|
-
*/
|
|
1856
|
+
return descriptor;
|
|
1857
|
+
},
|
|
1791
1858
|
|
|
1792
1859
|
/**
|
|
1793
|
-
*
|
|
1794
|
-
* This constructor just calls the constructor of the base class.
|
|
1860
|
+
* Whether a class has the given property
|
|
1795
1861
|
*
|
|
1796
|
-
* @
|
|
1862
|
+
* @signature function(clazz, name)
|
|
1863
|
+
* @param clazz {Class} class to check
|
|
1864
|
+
* @param name {String} name of the property to check for
|
|
1865
|
+
* @return {Boolean} whether the class includes the given property.
|
|
1797
1866
|
*/
|
|
1798
|
-
|
|
1799
|
-
function defaultConstructor() {
|
|
1800
|
-
defaultConstructor.base.apply(this, arguments);
|
|
1801
|
-
}
|
|
1867
|
+
hasProperty: qx.util.OOUtil.hasProperty,
|
|
1802
1868
|
|
|
1803
|
-
|
|
1869
|
+
/**
|
|
1870
|
+
* Detects whether a property has been initialized
|
|
1871
|
+
*
|
|
1872
|
+
* @param {qx.core.Object} object
|
|
1873
|
+
* @param {String} name
|
|
1874
|
+
* @returns {Boolean}
|
|
1875
|
+
*/
|
|
1876
|
+
isPropertyInitialized(object, name) {
|
|
1877
|
+
let property = object.constructor.prototype.$$allProperties[name];
|
|
1878
|
+
return !!(property && property.isInitialized(object));
|
|
1804
1879
|
},
|
|
1805
1880
|
|
|
1806
1881
|
/**
|
|
1807
|
-
*
|
|
1808
|
-
*
|
|
1882
|
+
* Returns the event type of the given event. Returns null if
|
|
1883
|
+
* the event does not exist.
|
|
1809
1884
|
*
|
|
1810
|
-
* @
|
|
1811
|
-
* @param
|
|
1812
|
-
* @param
|
|
1813
|
-
* @return {
|
|
1885
|
+
* @signature function(clazz, name)
|
|
1886
|
+
* @param clazz {Class} class to check
|
|
1887
|
+
* @param name {String} name of the event
|
|
1888
|
+
* @return {String|null} Event type of the given event.
|
|
1814
1889
|
*/
|
|
1815
|
-
|
|
1816
|
-
var wrapper = function () {
|
|
1817
|
-
var clazz = wrapper;
|
|
1818
|
-
|
|
1819
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1820
|
-
// new keyword check
|
|
1821
|
-
if (!(this instanceof clazz)) {
|
|
1822
|
-
throw new Error(
|
|
1823
|
-
"Please initialize '" + name + "' objects using the new keyword!"
|
|
1824
|
-
);
|
|
1825
|
-
}
|
|
1826
|
-
|
|
1827
|
-
// add abstract and singleton checks
|
|
1828
|
-
if (type === "abstract") {
|
|
1829
|
-
if (this.classname === name) {
|
|
1830
|
-
throw new Error(
|
|
1831
|
-
"The class '," +
|
|
1832
|
-
name +
|
|
1833
|
-
"' is abstract! It is not possible to instantiate it."
|
|
1834
|
-
);
|
|
1835
|
-
}
|
|
1836
|
-
} else if (type === "singleton") {
|
|
1837
|
-
if (!clazz.$$allowconstruct) {
|
|
1838
|
-
throw new Error(
|
|
1839
|
-
"The class '" +
|
|
1840
|
-
name +
|
|
1841
|
-
"' is a singleton! It is not possible to instantiate it directly. Use the static getInstance() method instead."
|
|
1842
|
-
);
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
|
-
// Execute default constructor
|
|
1848
|
-
var retval = clazz.$$original.apply(this, arguments);
|
|
1849
|
-
|
|
1850
|
-
// Initialize local mixins
|
|
1851
|
-
if (clazz.$$includes) {
|
|
1852
|
-
var mixins = clazz.$$flatIncludes;
|
|
1853
|
-
for (var i = 0, l = mixins.length; i < l; i++) {
|
|
1854
|
-
if (mixins[i].$$constructor) {
|
|
1855
|
-
mixins[i].$$constructor.apply(this, arguments);
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
if (qx.core.Environment.get("qx.debug")) {
|
|
1861
|
-
// Mark instance as initialized
|
|
1862
|
-
if (this.classname === name) {
|
|
1863
|
-
this.$$initialized = true;
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
// Return optional return value
|
|
1868
|
-
return retval;
|
|
1869
|
-
};
|
|
1870
|
-
|
|
1871
|
-
if (qx.core.Environment.get("qx.aspects")) {
|
|
1872
|
-
var aspectWrapper = qx.core.Aspect.wrap(name, wrapper, "constructor");
|
|
1873
|
-
wrapper.$$original = construct;
|
|
1874
|
-
wrapper.constructor = aspectWrapper;
|
|
1875
|
-
wrapper = aspectWrapper;
|
|
1876
|
-
}
|
|
1877
|
-
|
|
1878
|
-
// Store original constructor
|
|
1879
|
-
wrapper.$$original = construct;
|
|
1890
|
+
getEventType: qx.util.OOUtil.getEventType,
|
|
1880
1891
|
|
|
1881
|
-
|
|
1882
|
-
|
|
1892
|
+
/**
|
|
1893
|
+
* Whether a class supports the given event type
|
|
1894
|
+
*
|
|
1895
|
+
* @signature function(clazz, name)
|
|
1896
|
+
* @param clazz {Class} class to check
|
|
1897
|
+
* @param name {String} name of the event to check for
|
|
1898
|
+
* @return {Boolean} whether the class supports the given event.
|
|
1899
|
+
*/
|
|
1900
|
+
supportsEvent: qx.util.OOUtil.supportsEvent,
|
|
1883
1901
|
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1902
|
+
/**
|
|
1903
|
+
* Determine the total number of classes
|
|
1904
|
+
*
|
|
1905
|
+
* @return {Number} the total number of classes
|
|
1906
|
+
*/
|
|
1907
|
+
getTotalNumber() {
|
|
1908
|
+
return qx.Bootstrap.objectGetLength(qx.Bootstrap.$$registry);
|
|
1909
|
+
},
|
|
1888
1910
|
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1911
|
+
/**
|
|
1912
|
+
* Whether the value is an array.
|
|
1913
|
+
*
|
|
1914
|
+
* @param value {var} Value to check.
|
|
1915
|
+
* @return {Boolean} Whether the value is an array.
|
|
1916
|
+
*/
|
|
1917
|
+
isArray(value) {
|
|
1918
|
+
// Added "value !== null" because IE throws an exception
|
|
1919
|
+
// "Object expected" by executing "value instanceof Array" if
|
|
1920
|
+
// value is a DOM element that doesn't exist. It seems that
|
|
1921
|
+
// there is an internal difference between a JavaScript null
|
|
1922
|
+
// and a null returned from calling DOM. e.q. by
|
|
1923
|
+
// document.getElementById("ReturnedNull").
|
|
1924
|
+
return (
|
|
1925
|
+
value !== null &&
|
|
1926
|
+
(value instanceof Array ||
|
|
1927
|
+
(value && qx.data && qx.data.IListData && qx.util.OOUtil.hasInterface(value.constructor, qx.data.IListData)) ||
|
|
1928
|
+
qx.Bootstrap.getClass(value) === "Array" ||
|
|
1929
|
+
(!!value && !!value.$$isArray))
|
|
1930
|
+
);
|
|
1906
1931
|
}
|
|
1907
1932
|
}
|
|
1908
1933
|
});
|