@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.
Files changed (600) hide show
  1. package/CHANGELOG.md +224 -33
  2. package/Manifest.json +3 -3
  3. package/bin/tools/utils.js +50 -13
  4. package/lib/compiler/compile-info.json +297 -227
  5. package/lib/compiler/index.js +55319 -47085
  6. package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/default.tmpl.js +6 -7
  7. package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/cli/templates/class/singleton.tmpl.js +5 -6
  8. package/lib/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-node.tmpl.js +1 -0
  9. package/lib/resource/qx/tool/compiler/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -0
  10. package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/cli/templates/template_vars.js +12 -9
  11. package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/schema/Manifest-1-0-0.json +2 -2
  12. package/lib/resource/qx/tool/{schema → compiler/schema}/Manifest-2-0-0.json +2 -2
  13. package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/schema/compile-1-0-0.json +21 -5
  14. package/{source/resource/qx/tool → lib/resource/qx/tool/compiler}/schema/qooxdoo-1-0-0.json +1 -1
  15. package/lib/resource/qx/tool/website/build/404.html +22 -22
  16. package/lib/resource/qx/tool/website/build/about.html +23 -23
  17. package/lib/resource/qx/tool/website/build/assets/common.js +30 -18
  18. package/lib/resource/qx/tool/website/build/assets/custom.css +290 -0
  19. package/lib/resource/qx/tool/website/build/assets/qxWeb.js +28 -0
  20. package/lib/resource/qx/tool/website/build/diagnostics/dependson.html +30 -30
  21. package/lib/resource/qx/tool/website/build/diagnostics/dependson.js +49 -40
  22. package/lib/resource/qx/tool/website/build/diagnostics/requiredby.html +20 -23
  23. package/lib/resource/qx/tool/website/build/diagnostics/requiredby.js +38 -31
  24. package/lib/resource/qx/tool/website/build/index.html +24 -24
  25. package/lib/resource/qx/tool/website/build/scripts/serve.js +63 -65
  26. package/lib/resource/qx/tool/website/partials/footer.html +8 -13
  27. package/lib/resource/qx/tool/website/partials/head.html +9 -7
  28. package/lib/resource/qx/tool/website/partials/header.html +3 -3
  29. package/lib/resource/qx/tool/website/src/assets/common.js +32 -0
  30. package/lib/resource/qx/tool/website/src/assets/custom.css +290 -0
  31. package/lib/resource/qx/tool/website/src/assets/qxWeb.js +28 -0
  32. package/lib/resource/qx/tool/website/src/diagnostics/dependson.js +49 -40
  33. package/lib/resource/qx/tool/website/src/diagnostics/requiredby.js +38 -31
  34. package/lib/resource/qx/tool/website/src/index.html +2 -2
  35. package/lib/resource/qx/tool/website/src/scripts/serve.js +63 -65
  36. package/package.json +23 -24
  37. package/source/boot/index.html +2 -2
  38. package/source/class/qx/Bootstrap.js +931 -705
  39. package/source/class/qx/Class.js +1476 -1451
  40. package/source/class/qx/Interface.js +40 -107
  41. package/source/class/qx/Mixin.js +58 -116
  42. package/source/class/qx/Promise.js +1 -0
  43. package/source/class/qx/Theme.js +1 -1
  44. package/source/class/qx/application/Routing.js +2 -0
  45. package/source/class/qx/bom/Font.js +3 -0
  46. package/source/class/qx/bom/client/Locale.js +5 -0
  47. package/source/class/qx/bom/request/Jsonp.js +5 -13
  48. package/source/class/qx/bom/request/Script.js +11 -35
  49. package/source/class/qx/bom/request/SimpleXhr.js +13 -41
  50. package/source/class/qx/bom/request/Xhr.js +19 -80
  51. package/source/class/qx/bom/storage/Memory.js +2 -0
  52. package/source/class/qx/bom/storage/UserData.js +2 -0
  53. package/source/class/qx/bom/storage/Web.js +2 -0
  54. package/source/class/qx/bom/webfonts/Validator.js +13 -5
  55. package/source/class/qx/core/Assert.js +14 -0
  56. package/source/class/qx/core/BaseInit.js +19 -19
  57. package/source/class/qx/core/Environment.js +23 -20
  58. package/source/class/qx/core/MEvent.js +1 -1
  59. package/source/class/qx/core/MObjectId.js +24 -6
  60. package/source/class/qx/core/MProperty.js +123 -115
  61. package/source/class/qx/core/Object.js +88 -102
  62. package/source/class/qx/core/check/AbstractCheck.js +111 -0
  63. package/source/class/qx/core/check/Any.js +63 -0
  64. package/source/class/qx/core/check/CheckFactory.js +151 -0
  65. package/source/class/qx/core/check/DynamicTypeCheck.js +94 -0
  66. package/source/class/qx/core/check/ICheck.js +75 -0
  67. package/source/class/qx/core/check/IsOneOfCheck.js +63 -0
  68. package/source/class/qx/core/check/JsDocCheck.js +71 -0
  69. package/source/class/qx/core/check/SimpleCheck.js +42 -0
  70. package/source/class/qx/core/check/standard/ArrayCheck.js +49 -0
  71. package/source/class/qx/core/check/standard/BooleanCheck.js +47 -0
  72. package/source/class/qx/core/check/standard/ClassCheck.js +33 -0
  73. package/source/class/qx/core/check/standard/ColorCheck.js +33 -0
  74. package/source/class/qx/core/check/standard/DateCheck.js +49 -0
  75. package/source/class/qx/core/check/standard/DecoratorCheck.js +33 -0
  76. package/source/class/qx/core/check/standard/DocumentCheck.js +40 -0
  77. package/source/class/qx/core/check/standard/ElementCheck.js +40 -0
  78. package/source/class/qx/core/check/standard/ErrorCheck.js +46 -0
  79. package/source/class/qx/core/check/standard/EventCheck.js +40 -0
  80. package/source/class/qx/core/check/standard/FontCheck.js +33 -0
  81. package/source/class/qx/core/check/standard/FunctionCheck.js +49 -0
  82. package/source/class/qx/core/check/standard/IntegerCheck.js +54 -0
  83. package/source/class/qx/core/check/standard/InterfaceCheck.js +33 -0
  84. package/source/class/qx/core/check/standard/MapCheck.js +33 -0
  85. package/source/class/qx/core/check/standard/MixinCheck.js +33 -0
  86. package/source/class/qx/core/check/standard/NodeCheck.js +40 -0
  87. package/source/class/qx/core/check/standard/NumberCheck.js +48 -0
  88. package/source/class/qx/core/check/standard/ObjectCheck.js +33 -0
  89. package/source/class/qx/core/check/standard/PositiveIntegerCheck.js +45 -0
  90. package/source/class/qx/core/check/standard/PositiveNumberCheck.js +45 -0
  91. package/source/class/qx/core/check/standard/PromiseCheck.js +33 -0
  92. package/source/class/qx/core/check/standard/RegExpCheck.js +46 -0
  93. package/source/class/qx/core/check/standard/StringCheck.js +43 -0
  94. package/source/class/qx/core/check/standard/ThemeCheck.js +33 -0
  95. package/source/class/qx/core/check/standard/WindowCheck.js +40 -0
  96. package/source/class/qx/core/property/ExplicitPropertyStorage.js +87 -0
  97. package/source/class/qx/core/property/GroupProperty.js +262 -0
  98. package/source/class/qx/core/property/IProperty.js +46 -0
  99. package/source/class/qx/core/property/IPropertyStorage.js +83 -0
  100. package/source/class/qx/core/property/ImmutableArrayStorage.js +38 -0
  101. package/source/class/qx/core/property/ImmutableDataArrayStorage.js +38 -0
  102. package/source/class/qx/core/property/ImmutableObjectStorage.js +39 -0
  103. package/source/class/qx/core/property/Property.js +1482 -0
  104. package/source/class/qx/core/property/PropertyStorageFactory.js +22 -0
  105. package/source/class/qx/core/property/SimplePropertyStorage.js +105 -0
  106. package/source/class/qx/data/Array.js +102 -57
  107. package/source/class/qx/data/MBinding.js +4 -29
  108. package/source/class/qx/data/SingleValueBinding.js +595 -1496
  109. package/source/class/qx/data/binding/AbstractSegment.js +197 -0
  110. package/source/class/qx/data/binding/ArrayIndexSegment.js +155 -0
  111. package/source/class/qx/data/binding/IInputReceiver.js +14 -0
  112. package/source/class/qx/data/binding/PropNameSegment.js +150 -0
  113. package/source/class/qx/data/controller/CheckedList.js +1 -1
  114. package/source/class/qx/data/controller/Form.js +78 -8
  115. package/source/class/qx/data/controller/Tree.js +27 -117
  116. package/source/class/qx/data/marshal/Json.js +46 -149
  117. package/source/class/qx/data/store/Json.js +0 -2
  118. package/source/class/qx/dev/Debug.js +1 -1
  119. package/source/class/qx/dev/LeakDetector.js +144 -0
  120. package/source/class/qx/dev/unit/AsyncWrapper.js +1 -0
  121. package/source/class/qx/dev/unit/MMock.js +7 -2
  122. package/source/class/qx/dev/unit/Sinon.js +0 -4
  123. package/source/class/qx/dev/unit/TestCase.js +4 -1
  124. package/source/class/qx/dev/unit/TestClass.js +2 -2
  125. package/source/class/qx/dev/unit/TestFunction.js +1 -0
  126. package/source/class/qx/dev/unit/TestLoaderBasic.js +1 -0
  127. package/source/class/qx/dev/unit/TestRunner.js +106 -0
  128. package/source/class/qx/event/IEventDispatcher.js +8 -4
  129. package/source/class/qx/event/Manager.js +4 -0
  130. package/source/class/qx/event/Messaging.js +2 -0
  131. package/source/class/qx/event/Pool.js +7 -0
  132. package/source/class/qx/event/Registration.js +33 -55
  133. package/source/class/qx/event/Timer.js +2 -0
  134. package/source/class/qx/event/Utils.js +25 -8
  135. package/source/class/qx/event/dispatch/AbstractBubbling.js +98 -194
  136. package/source/class/qx/event/dispatch/Direct.js +18 -13
  137. package/source/class/qx/event/handler/Appear.js +20 -24
  138. package/source/class/qx/event/handler/Application.js +4 -0
  139. package/source/class/qx/event/handler/DragDrop.js +182 -385
  140. package/source/class/qx/event/handler/Element.js +3 -0
  141. package/source/class/qx/event/handler/Focus.js +38 -31
  142. package/source/class/qx/event/handler/Input.js +5 -0
  143. package/source/class/qx/event/handler/Keyboard.js +107 -165
  144. package/source/class/qx/event/handler/Pointer.js +39 -68
  145. package/source/class/qx/event/handler/PointerCore.js +7 -25
  146. package/source/class/qx/event/handler/Window.js +5 -0
  147. package/source/class/qx/event/type/Event.js +12 -0
  148. package/source/class/qx/event/type/KeySequence.js +3 -0
  149. package/source/class/qx/event/type/Native.js +3 -0
  150. package/source/class/qx/html/Element.js +26 -91
  151. package/source/class/qx/html/Jsx.js +2 -3
  152. package/source/class/qx/html/Node.js +3 -3
  153. package/source/class/qx/io/jsonrpc/Client.js +2 -2
  154. package/source/class/qx/io/jsonrpc/protocol/Error.js +2 -2
  155. package/source/class/qx/io/jsonrpc/protocol/Parser.js +1 -0
  156. package/source/class/qx/io/jsonrpc/protocol/Result.js +2 -2
  157. package/source/class/qx/io/request/Xhr.js +3 -8
  158. package/source/class/qx/lang/normalize/Array.js +23 -1
  159. package/source/class/qx/locale/Date.js +520 -113
  160. package/source/class/qx/locale/LocalizedString.js +3 -0
  161. package/source/class/qx/locale/Manager.js +14 -3
  162. package/source/class/qx/locale/Number.js +60 -7
  163. package/source/class/qx/log/Logger.js +1 -1
  164. package/source/class/qx/module/Animation.js +2 -0
  165. package/source/class/qx/module/Attribute.js +2 -0
  166. package/source/class/qx/module/Css.js +7 -24
  167. package/source/class/qx/module/Event.js +2 -0
  168. package/source/class/qx/module/Manipulating.js +2 -0
  169. package/source/class/qx/module/Traversing.js +2 -0
  170. package/source/class/qx/promise/NativeWrapper.js +1 -1
  171. package/source/class/qx/test/Bootstrap.js +68 -53
  172. package/source/class/qx/test/Class.js +310 -2
  173. package/source/class/qx/test/Mixin.js +192 -42
  174. package/source/class/qx/test/Promise.js +129 -331
  175. package/source/class/qx/test/Theme.js +11 -0
  176. package/source/class/qx/test/bom/Font.js +2 -5
  177. package/source/class/qx/test/bom/Template.js +1 -1
  178. package/source/class/qx/test/compiler/ClassFile.js +14 -0
  179. package/source/class/qx/test/core/Assert.js +12 -0
  180. package/source/class/qx/test/core/Environment.js +17 -3
  181. package/source/class/qx/test/core/InheritanceDummy.js +10 -1
  182. package/source/class/qx/test/core/Object.js +51 -24
  183. package/source/class/qx/test/core/ObjectId.js +10 -1
  184. package/source/class/qx/test/core/Property.js +1363 -118
  185. package/source/class/qx/test/core/PropertyHelper.js +12 -0
  186. package/source/class/qx/test/core/Target.js +1 -0
  187. package/source/class/qx/test/core/Validation.js +2 -0
  188. package/source/class/qx/test/data/DataArray.js +218 -639
  189. package/source/class/qx/test/data/DataArrayWithChangeBubble.js +45 -215
  190. package/source/class/qx/test/data/MultiBinding.js +42 -0
  191. package/source/class/qx/test/data/async/__init__.js +4 -0
  192. package/source/class/qx/test/data/controller/Form.js +523 -14
  193. package/source/class/qx/test/data/controller/List.js +94 -426
  194. package/source/class/qx/test/data/controller/ListReverse.js +5 -20
  195. package/source/class/qx/test/data/controller/ListWithObjects.js +49 -225
  196. package/source/class/qx/test/data/controller/Object.js +54 -222
  197. package/source/class/qx/test/data/controller/Tree.js +195 -934
  198. package/source/class/qx/test/data/marshal/Json.js +74 -312
  199. package/source/class/qx/test/data/singlevalue/Array.js +55 -279
  200. package/source/class/qx/test/data/singlevalue/Async.js +173 -0
  201. package/source/class/qx/test/data/singlevalue/Deep.js +148 -327
  202. package/source/class/qx/test/data/singlevalue/Resolve.js +8 -28
  203. package/source/class/qx/test/data/singlevalue/Simple.js +130 -359
  204. package/source/class/qx/test/data/store/Json.js +86 -254
  205. package/source/class/qx/test/data/store/Jsonp.js +9 -29
  206. package/source/class/qx/test/data/store/Offline.js +2 -8
  207. package/source/class/qx/test/data/store/Rest.js +3 -3
  208. package/source/class/qx/test/dev/unit/Requirements.js +26 -10
  209. package/source/class/qx/test/event/GlobalError.js +2 -2
  210. package/source/class/qx/test/html/Iframe.js +1 -1
  211. package/source/class/qx/test/io/graphql/Client.js +2 -0
  212. package/source/class/qx/test/io/jsonrpc/Protocol.js +4 -2
  213. package/source/class/qx/test/io/request/MRequest.js +2 -8
  214. package/source/class/qx/test/io/request/Xhr.js +27 -117
  215. package/source/class/qx/test/lang/Function.js +6 -25
  216. package/source/class/qx/test/lang/Type.js +31 -13
  217. package/source/class/qx/test/locale/Date.js +173 -2
  218. package/source/class/qx/test/locale/Locale.js +23 -28
  219. package/source/class/qx/test/locale/Number.js +71 -0
  220. package/source/class/qx/test/log/Logger.js +7 -1
  221. package/source/class/qx/test/log/fixture/ClassA.js +2 -5
  222. package/source/class/qx/test/mobile/basic/Atom.js +3 -3
  223. package/source/class/qx/test/mobile/container/Scroll.js +4 -4
  224. package/source/class/qx/test/mobile/form/CheckBox.js +6 -12
  225. package/source/class/qx/test/performance/Property.js +5 -4
  226. package/source/class/qx/test/performance/widget/WidgetWithDecorator.js +2 -0
  227. package/source/class/qx/test/theme/Simple.js +34 -0
  228. package/source/class/qx/test/{MAppearance.js → theme/SimpleAppearance.js} +5 -4
  229. package/source/class/qx/test/{MDecoration.js → theme/SimpleDecoration.js} +6 -4
  230. package/source/class/qx/test/theme/manager/Meta.js +7 -5
  231. package/source/class/qx/test/tool/__init__.js +3 -0
  232. package/source/class/qx/test/tool/cli/AbstractValue.js +274 -0
  233. package/source/class/qx/test/tool/cli/Argument.js +384 -0
  234. package/source/class/qx/test/tool/cli/Command.js +387 -0
  235. package/source/class/qx/test/tool/cli/Flag.js +413 -0
  236. package/source/class/qx/test/tool/cli/__init__.js +3 -0
  237. package/source/class/qx/test/ui/LayoutTestCase.js +1 -14
  238. package/source/class/qx/test/ui/basic/Label.js +106 -0
  239. package/source/class/qx/test/ui/core/Blocker.js +125 -3
  240. package/source/class/qx/test/ui/form/Form.js +106 -0
  241. package/source/class/qx/test/ui/form/FormManager.js +6 -5
  242. package/source/class/qx/test/ui/form/SplitButton.js +1 -1
  243. package/source/class/qx/test/ui/toolbar/OverflowHandling.js +13 -14
  244. package/source/class/qx/test/ui/toolbar/ToolBar.js +16 -16
  245. package/source/class/qx/test/ui/tree/TreeFolder.js +5 -7
  246. package/source/class/qx/test/ui/tree/virtual/AbstractTreeTest.js +2 -0
  247. package/source/class/qx/test/ui/tree/virtual/Tree.js +36 -0
  248. package/source/class/qx/test/util/DateFormat.js +1 -1
  249. package/source/class/qx/test/util/PropertyUtil.js +0 -36
  250. package/source/class/qx/theme/classic/Appearance.js +22 -1
  251. package/source/class/qx/theme/indigo/ColorDark.js +2 -0
  252. package/source/class/qx/theme/manager/Font.js +6 -1
  253. package/source/class/qx/theme/manager/Meta.js +2 -1
  254. package/source/class/qx/theme/modern/Appearance.js +21 -0
  255. package/source/class/qx/theme/simple/Appearance.js +52 -95
  256. package/source/class/qx/theme/simple/Decoration.js +0 -1
  257. package/source/class/qx/theme/tangible/Appearance.js +3 -1
  258. package/source/class/qx/tool/cli/AbstractCliApp.js +88 -0
  259. package/source/class/qx/tool/cli/AbstractValue.js +186 -0
  260. package/source/class/qx/tool/cli/Argument.js +155 -0
  261. package/source/class/qx/tool/cli/Command.js +518 -0
  262. package/source/class/qx/tool/cli/Flag.js +202 -0
  263. package/source/class/qx/tool/cli/Parser.js +39 -0
  264. package/source/class/qx/tool/cli/__init__.js +26 -1
  265. package/source/class/qx/tool/compiler/Analyser.js +41 -13
  266. package/source/class/qx/tool/compiler/ClassFile.js +37 -13
  267. package/source/class/qx/tool/compiler/Console.js +2 -0
  268. package/source/class/qx/tool/compiler/MetaDatabase.js +47 -0
  269. package/source/class/qx/tool/compiler/MetaExtraction.js +53 -33
  270. package/source/class/qx/tool/compiler/app/Library.js +1 -1
  271. package/source/class/qx/tool/compiler/app/WebFont.js +2 -0
  272. package/source/class/qx/tool/compiler/cli/Application.js +58 -0
  273. package/source/class/qx/tool/{cli/commands → compiler/cli}/Command.js +99 -45
  274. package/source/class/qx/tool/{cli → compiler/cli}/ConfigDb.js +7 -7
  275. package/source/class/qx/tool/compiler/cli/ConfigLoader.js +272 -0
  276. package/source/class/qx/tool/{cli → compiler/cli}/LibraryApplication.js +3 -3
  277. package/source/class/qx/tool/compiler/cli/RootCommand.js +63 -0
  278. package/source/class/qx/tool/{cli → compiler/cli}/Watch.js +49 -24
  279. package/source/class/qx/tool/compiler/cli/__init__.js +3 -0
  280. package/source/class/qx/tool/{cli → compiler/cli}/api/AbstractApi.js +2 -11
  281. package/source/class/qx/tool/{cli → compiler/cli}/api/CompilerApi.js +11 -10
  282. package/source/class/qx/tool/{cli → compiler/cli}/api/LibraryApi.js +13 -4
  283. package/source/class/qx/tool/{cli → compiler/cli}/api/Test.js +1 -1
  284. package/source/class/qx/tool/compiler/cli/commands/Add.js +49 -0
  285. package/source/class/qx/tool/{cli → compiler/cli}/commands/Clean.js +12 -25
  286. package/source/class/qx/tool/{cli → compiler/cli}/commands/Compile.js +630 -590
  287. package/source/class/qx/tool/{cli → compiler/cli}/commands/Config.js +22 -20
  288. package/source/class/qx/tool/{cli → compiler/cli}/commands/Create.js +78 -55
  289. package/source/class/qx/tool/{cli → compiler/cli}/commands/Deploy.js +45 -60
  290. package/source/class/qx/tool/{cli → compiler/cli}/commands/Es6ify.js +57 -41
  291. package/source/class/qx/tool/{cli → compiler/cli}/commands/ExportGlyphs.js +26 -7
  292. package/source/class/qx/tool/compiler/cli/commands/Lint.js +420 -0
  293. package/source/class/qx/tool/{cli → compiler/cli}/commands/Migrate.js +40 -20
  294. package/source/class/qx/tool/{cli → compiler/cli}/commands/Package.js +20 -32
  295. package/source/class/qx/tool/compiler/cli/commands/Pkg.js +36 -0
  296. package/source/class/qx/tool/compiler/cli/commands/Prettier.js +278 -0
  297. package/source/class/qx/tool/{cli → compiler/cli}/commands/Run.js +43 -39
  298. package/source/class/qx/tool/{cli → compiler/cli}/commands/Serve.js +63 -61
  299. package/source/class/qx/tool/{cli → compiler/cli}/commands/Test.js +49 -52
  300. package/source/class/qx/tool/{cli → compiler/cli}/commands/Typescript.js +70 -62
  301. package/source/class/qx/tool/{cli → compiler/cli}/commands/add/Class.js +54 -31
  302. package/source/class/qx/tool/{cli → compiler/cli}/commands/add/Script.js +57 -33
  303. package/source/class/qx/tool/{cli → compiler/cli}/commands/config/Delete.js +19 -13
  304. package/source/class/qx/tool/{cli → compiler/cli}/commands/config/Get.js +19 -13
  305. package/source/class/qx/tool/{cli → compiler/cli}/commands/config/List.js +20 -20
  306. package/source/class/qx/tool/{cli → compiler/cli}/commands/config/Set.js +28 -20
  307. package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Install.js +140 -75
  308. package/source/class/qx/tool/{cli → compiler/cli}/commands/package/List.js +119 -80
  309. package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Publish.js +196 -179
  310. package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Remove.js +18 -21
  311. package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Update.js +92 -71
  312. package/source/class/qx/tool/{cli → compiler/cli}/commands/package/Upgrade.js +67 -54
  313. package/source/class/qx/tool/compiler/makers/AbstractAppMaker.js +2 -1
  314. package/source/class/qx/tool/compiler/resources/Manager.js +2 -0
  315. package/source/class/qx/tool/compiler/resources/ScssConverter.js +1 -1
  316. package/source/class/qx/tool/compiler/resources/ScssFile.js +1 -1
  317. package/source/class/qx/tool/compiler/targets/Target.js +5 -10
  318. package/source/class/qx/tool/compiler/targets/TypeScriptWriter.js +9 -2
  319. package/source/class/qx/tool/compiler/targets/meta/ApplicationMeta.js +2 -4
  320. package/source/class/qx/tool/compiler/targets/meta/BootJs.js +2 -0
  321. package/source/class/qx/tool/compiler/targets/meta/Browserify.js +142 -80
  322. package/source/class/qx/tool/compiler/targets/meta/PackageJavascript.js +2 -0
  323. package/source/class/qx/tool/config/Abstract.js +5 -5
  324. package/source/class/qx/tool/config/Lockfile.js +1 -1
  325. package/source/class/qx/tool/migration/BaseMigration.js +9 -7
  326. package/source/class/qx/tool/migration/M6_0_0.js +3 -3
  327. package/source/class/qx/tool/migration/M8_0_0.js +958 -0
  328. package/source/class/qx/tool/utils/Debounce.js +0 -1
  329. package/source/class/qx/tool/utils/Http.js +109 -21
  330. package/source/class/qx/tool/utils/LogManager.js +7 -0
  331. package/source/class/qx/tool/utils/Promisify.js +12 -1
  332. package/source/class/qx/tool/utils/QooxdooVersions.js +193 -0
  333. package/source/class/qx/tool/utils/Utils.js +8 -5
  334. package/source/class/qx/tool/utils/Website.js +9 -222
  335. package/source/class/qx/tool/utils/Zip.js +47 -0
  336. package/source/class/qx/tool/utils/files/Utils.js +3 -11
  337. package/source/class/qx/tool/utils/json/Tokenizer.js +5 -0
  338. package/source/class/qx/ui/basic/Atom.js +8 -8
  339. package/source/class/qx/ui/core/Blocker.js +17 -4
  340. package/source/class/qx/ui/core/DragDropCursor.js +2 -1
  341. package/source/class/qx/ui/core/EventHandler.js +13 -21
  342. package/source/class/qx/ui/core/LayoutItem.js +8 -31
  343. package/source/class/qx/ui/core/MExecutable.js +7 -31
  344. package/source/class/qx/ui/core/MNativeOverflow.js +4 -2
  345. package/source/class/qx/ui/core/Widget.js +50 -165
  346. package/source/class/qx/ui/core/scroll/IScrollBar.js +9 -3
  347. package/source/class/qx/ui/core/scroll/ScrollBar.js +7 -1
  348. package/source/class/qx/ui/core/scroll/ScrollPane.js +12 -4
  349. package/source/class/qx/ui/embed/Html.js +6 -2
  350. package/source/class/qx/ui/form/AbstractField.js +4 -12
  351. package/source/class/qx/ui/form/Button.js +6 -4
  352. package/source/class/qx/ui/form/CheckedSelectBox.js +8 -8
  353. package/source/class/qx/ui/form/FileSelectorButton.js +1 -1
  354. package/source/class/qx/ui/form/Form.js +3 -0
  355. package/source/class/qx/ui/form/IListItem.js +3 -1
  356. package/source/class/qx/ui/form/IRadioItem.js +3 -1
  357. package/source/class/qx/ui/form/MForm.js +3 -1
  358. package/source/class/qx/ui/form/Slider.js +6 -2
  359. package/source/class/qx/ui/form/SplitButton.js +5 -5
  360. package/source/class/qx/ui/form/TextField.js +1 -2
  361. package/source/class/qx/ui/form/validation/Manager.js +6 -2
  362. package/source/class/qx/ui/menubar/Button.js +1 -1
  363. package/source/class/qx/ui/mobile/basic/Atom.js +5 -5
  364. package/source/class/qx/ui/mobile/dialog/Menu.js +9 -31
  365. package/source/class/qx/ui/mobile/dialog/Popup.js +13 -1
  366. package/source/class/qx/ui/table/pane/FocusIndicator.js +5 -2
  367. package/source/class/qx/ui/table/pane/Scroller.js +5 -20
  368. package/source/class/qx/ui/table/selection/Model.js +1 -0
  369. package/source/class/qx/ui/toolbar/Button.js +1 -1
  370. package/source/class/qx/ui/toolbar/CheckBox.js +1 -1
  371. package/source/class/qx/ui/toolbar/FileSelectorButton.js +1 -2
  372. package/source/class/qx/ui/toolbar/Part.js +2 -2
  373. package/source/class/qx/ui/toolbar/PartContainer.js +2 -2
  374. package/source/class/qx/ui/toolbar/ToolBar.js +24 -49
  375. package/source/class/qx/ui/tree/VirtualTree.js +6 -4
  376. package/source/class/qx/ui/tree/core/AbstractItem.js +10 -17
  377. package/source/class/qx/ui/tree/core/IVirtualTree.js +4 -2
  378. package/source/class/qx/ui/tree/provider/IVirtualTreeProvider.js +20 -10
  379. package/source/class/qx/ui/treevirtual/SimpleTreeDataModel.js +4 -1
  380. package/source/class/qx/ui/virtual/cell/Cell.js +20 -48
  381. package/source/class/qx/ui/virtual/cell/WidgetCell.js +2 -4
  382. package/source/class/qx/ui/virtual/core/Axis.js +4 -0
  383. package/source/class/qx/ui/virtual/core/ILayer.js +14 -10
  384. package/source/class/qx/ui/virtual/core/Scroller.js +4 -4
  385. package/source/class/qx/ui/virtual/layer/WidgetCell.js +4 -0
  386. package/source/class/qx/ui/virtual/selection/Abstract.js +3 -0
  387. package/source/class/qx/ui/virtual/selection/MModel.js +1 -1
  388. package/source/class/qx/ui/window/IDesktop.js +6 -2
  389. package/source/class/qx/ui/window/IWindowManager.js +10 -4
  390. package/source/class/qx/ui/window/MDesktop.js +2 -1
  391. package/source/class/qx/ui/window/Manager.js +1 -1
  392. package/source/class/qx/ui/window/Window.js +6 -4
  393. package/source/class/qx/util/OOUtil.js +8 -9
  394. package/source/class/qx/util/PropertyUtil.js +34 -154
  395. package/source/class/qx/util/ResponseParser.js +2 -0
  396. package/source/class/qx/util/Serializer.js +69 -114
  397. package/source/class/qx/util/format/DateFormat.js +3 -2
  398. package/source/global.d.ts +4 -0
  399. package/source/resource/qx/tool/bin/download-assets +0 -2
  400. package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/default.tmpl.js +6 -7
  401. package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/cli/templates/class/singleton.tmpl.js +5 -6
  402. package/source/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-node.tmpl.js +1 -0
  403. package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/cli/templates/template_vars.js +12 -9
  404. package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/schema/Manifest-1-0-0.json +2 -2
  405. package/source/resource/qx/tool/{schema → compiler/schema}/Manifest-2-0-0.json +2 -2
  406. package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/schema/compile-1-0-0.json +21 -5
  407. package/{lib/resource/qx/tool → source/resource/qx/tool/compiler}/schema/qooxdoo-1-0-0.json +1 -1
  408. package/source/resource/qx/tool/website/build/404.html +22 -22
  409. package/source/resource/qx/tool/website/build/about.html +23 -23
  410. package/source/resource/qx/tool/website/build/assets/common.js +30 -18
  411. package/source/resource/qx/tool/website/build/assets/custom.css +290 -0
  412. package/source/resource/qx/tool/website/build/assets/qxWeb.js +28 -0
  413. package/source/resource/qx/tool/website/build/diagnostics/dependson.html +30 -30
  414. package/source/resource/qx/tool/website/build/diagnostics/dependson.js +49 -40
  415. package/source/resource/qx/tool/website/build/diagnostics/requiredby.html +20 -23
  416. package/source/resource/qx/tool/website/build/diagnostics/requiredby.js +38 -31
  417. package/source/resource/qx/tool/website/build/index.html +24 -24
  418. package/source/resource/qx/tool/website/build/scripts/serve.js +63 -65
  419. package/source/resource/qx/tool/website/partials/footer.html +8 -13
  420. package/source/resource/qx/tool/website/partials/head.html +9 -7
  421. package/source/resource/qx/tool/website/partials/header.html +3 -3
  422. package/source/resource/qx/tool/website/src/assets/common.js +32 -0
  423. package/source/resource/qx/tool/website/src/assets/custom.css +290 -0
  424. package/source/resource/qx/tool/website/src/assets/qxWeb.js +28 -0
  425. package/source/resource/qx/tool/website/src/diagnostics/dependson.js +49 -40
  426. package/source/resource/qx/tool/website/src/diagnostics/requiredby.js +38 -31
  427. package/source/resource/qx/tool/website/src/index.html +2 -2
  428. package/source/resource/qx/tool/website/src/scripts/serve.js +63 -65
  429. package/lib/resource/qx/tool/bin/build-devtools +0 -13
  430. package/lib/resource/qx/tool/bin/build-website +0 -15
  431. package/lib/resource/qx/tool/bin/download-assets +0 -23
  432. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +0 -1
  433. package/lib/resource/qx/tool/website/build/assets/bootstrap.css +0 -7
  434. package/lib/resource/qx/tool/website/build/assets/bootstrap.min.css +0 -7
  435. package/lib/resource/qx/tool/website/build/assets/bootstrap.min.css.map +0 -1
  436. package/lib/resource/qx/tool/website/build/assets/jquery.js +0 -5453
  437. package/lib/resource/qx/tool/website/build/qooxdoo.css +0 -21
  438. package/lib/resource/qx/tool/website/sass/qooxdoo.css +0 -3
  439. package/lib/resource/qx/tool/website/sass/qooxdoo.css.map +0 -1
  440. package/lib/resource/qx/tool/website/src/assets/bootstrap.css +0 -7
  441. package/lib/resource/qx/tool/website/src/assets/bootstrap.min.css +0 -7
  442. package/lib/resource/qx/tool/website/src/assets/bootstrap.min.css.map +0 -1
  443. package/lib/resource/qx/tool/website/src/assets/jquery.js +0 -5453
  444. package/source/class/qx/core/Property.js +0 -2100
  445. package/source/class/qx/tool/cli/Application.js +0 -47
  446. package/source/class/qx/tool/cli/Cli.js +0 -713
  447. package/source/class/qx/tool/cli/commands/Add.js +0 -46
  448. package/source/class/qx/tool/cli/commands/Lint.js +0 -255
  449. package/source/class/qx/tool/cli/commands/Pkg.js +0 -56
  450. package/source/class/qx/tool/cli/commands/package/Migrate.js +0 -37
  451. package/source/class/qx/tool/compiler/app/Cldr.js +0 -725
  452. package/source/resource/qx/tool/bin/build-devtools +0 -13
  453. package/source/resource/qx/tool/bin/build-website +0 -15
  454. package/source/resource/qx/tool/website/build/assets/bootstrap.css +0 -7
  455. package/source/resource/qx/tool/website/build/assets/bootstrap.min.css +0 -7
  456. package/source/resource/qx/tool/website/build/assets/bootstrap.min.css.map +0 -1
  457. package/source/resource/qx/tool/website/build/assets/jquery.js +0 -5453
  458. package/source/resource/qx/tool/website/build/qooxdoo.css +0 -21
  459. package/source/resource/qx/tool/website/sass/qooxdoo.scss +0 -31
  460. package/source/resource/qx/tool/website/src/assets/bootstrap.css +0 -7
  461. package/source/resource/qx/tool/website/src/assets/bootstrap.min.css +0 -7
  462. package/source/resource/qx/tool/website/src/assets/bootstrap.min.css.map +0 -1
  463. package/source/resource/qx/tool/website/src/assets/jquery.js +0 -5453
  464. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/TypeScriptWriter-base_declaration.d.ts +0 -0
  465. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/header.tmpl.js +0 -0
  466. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/interface.tmpl.js +0 -0
  467. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/class/mixin.tmpl.js +0 -0
  468. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-browser.tmpl.js +0 -0
  469. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-rhino.tmpl.js +0 -0
  470. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/.gitignore.tmpl +0 -0
  471. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/Manifest.tmpl.json +0 -0
  472. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/compile.tmpl.json +0 -0
  473. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/readme.tmpl.md +0 -0
  474. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/index.tmpl.html +0 -0
  475. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/nojs.tmpl.html +0 -0
  476. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/Application.tmpl.js +0 -0
  477. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/__init__.tmpl.js +0 -0
  478. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/test/DemoTest.tmpl.js +0 -0
  479. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Appearance.tmpl.js +0 -0
  480. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Color.tmpl.js +0 -0
  481. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Decoration.tmpl.js +0 -0
  482. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Font.tmpl.js +0 -0
  483. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Theme.tmpl.js +0 -0
  484. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/app.png +0 -0
  485. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/favicon.png +0 -0
  486. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/js_256x256.png +0 -0
  487. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/test.png +0 -0
  488. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/translation/readme.txt +0 -0
  489. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/.gitignore.tmpl +0 -0
  490. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/Manifest.tmpl.json +0 -0
  491. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/compile.tmpl.json +0 -0
  492. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/readme.tmpl.md +0 -0
  493. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/index.tmpl.html +0 -0
  494. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/nojs.tmpl.html +0 -0
  495. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/Application.tmpl.js +0 -0
  496. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/__init__.tmpl.js +0 -0
  497. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Login.tmpl.js +0 -0
  498. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Overview.tmpl.js +0 -0
  499. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/__init__.tmpl.js +0 -0
  500. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/app.png +0 -0
  501. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/css/.gitignore.tmpl +0 -0
  502. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/favicon.png +0 -0
  503. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/js_256x256.png +0 -0
  504. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/theme/custom/css/custom.css +0 -0
  505. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/translation/readme.txt +0 -0
  506. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/.gitignore.tmpl +0 -0
  507. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/Manifest.tmpl.json +0 -0
  508. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/compile.tmpl.json +0 -0
  509. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/readme.tmpl.md +0 -0
  510. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/Button.tmpl.js +0 -0
  511. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/__init__.tmpl.js +0 -0
  512. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/demo/Application.tmpl.js +0 -0
  513. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/resource/custom/test.png +0 -0
  514. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/test/DemoTest.tmpl.js +0 -0
  515. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Appearance.tmpl.js +0 -0
  516. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Color.tmpl.js +0 -0
  517. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Decoration.tmpl.js +0 -0
  518. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Font.tmpl.js +0 -0
  519. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Theme.tmpl.js +0 -0
  520. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/resource/custom/test.png +0 -0
  521. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/translation/readme.txt +0 -0
  522. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/.gitignore.tmpl +0 -0
  523. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/Manifest.tmpl.json +0 -0
  524. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/compile.tmpl.json +0 -0
  525. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/readme.tmpl.txt +0 -0
  526. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/Application.tmpl.js +0 -0
  527. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/__init__.tmpl.js +0 -0
  528. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/test/DemoTest.tmpl.js +0 -0
  529. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/resource/custom/.gitignore.tmpl +0 -0
  530. /package/lib/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/translation/readme.txt +0 -0
  531. /package/lib/resource/qx/tool/{loadsass.js → compiler/loadsass.js} +0 -0
  532. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/TypeScriptWriter-base_declaration.d.ts +0 -0
  533. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/header.tmpl.js +0 -0
  534. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/interface.tmpl.js +0 -0
  535. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/class/mixin.tmpl.js +0 -0
  536. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-browser.tmpl.js +0 -0
  537. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/loader/loader-rhino.tmpl.js +0 -0
  538. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/.gitignore.tmpl +0 -0
  539. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/Manifest.tmpl.json +0 -0
  540. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/compile.tmpl.json +0 -0
  541. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/readme.tmpl.md +0 -0
  542. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/index.tmpl.html +0 -0
  543. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/boot/nojs.tmpl.html +0 -0
  544. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/Application.tmpl.js +0 -0
  545. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/__init__.tmpl.js +0 -0
  546. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/test/DemoTest.tmpl.js +0 -0
  547. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Appearance.tmpl.js +0 -0
  548. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Color.tmpl.js +0 -0
  549. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Decoration.tmpl.js +0 -0
  550. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Font.tmpl.js +0 -0
  551. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/class/custom/theme/Theme.tmpl.js +0 -0
  552. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/app.png +0 -0
  553. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/favicon.png +0 -0
  554. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/js_256x256.png +0 -0
  555. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/resource/custom/test.png +0 -0
  556. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/desktop/source/translation/readme.txt +0 -0
  557. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/.gitignore.tmpl +0 -0
  558. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/Manifest.tmpl.json +0 -0
  559. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/compile.tmpl.json +0 -0
  560. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/readme.tmpl.md +0 -0
  561. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/index.tmpl.html +0 -0
  562. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/boot/nojs.tmpl.html +0 -0
  563. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/Application.tmpl.js +0 -0
  564. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/__init__.tmpl.js +0 -0
  565. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Login.tmpl.js +0 -0
  566. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/Overview.tmpl.js +0 -0
  567. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/class/custom/page/__init__.tmpl.js +0 -0
  568. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/app.png +0 -0
  569. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/css/.gitignore.tmpl +0 -0
  570. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/favicon.png +0 -0
  571. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/resource/custom/js_256x256.png +0 -0
  572. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/theme/custom/scss/_styles.scss +0 -0
  573. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/theme/custom/scss/custom.scss +0 -0
  574. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/mobile/source/translation/readme.txt +0 -0
  575. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/.gitignore.tmpl +0 -0
  576. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/Manifest.tmpl.json +0 -0
  577. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/compile.tmpl.json +0 -0
  578. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/readme.tmpl.md +0 -0
  579. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/Button.tmpl.js +0 -0
  580. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/__init__.tmpl.js +0 -0
  581. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/demo/Application.tmpl.js +0 -0
  582. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/resource/custom/test.png +0 -0
  583. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/test/DemoTest.tmpl.js +0 -0
  584. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Appearance.tmpl.js +0 -0
  585. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Color.tmpl.js +0 -0
  586. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Decoration.tmpl.js +0 -0
  587. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Font.tmpl.js +0 -0
  588. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/class/custom/theme/Theme.tmpl.js +0 -0
  589. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/resource/custom/test.png +0 -0
  590. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/package/source/translation/readme.txt +0 -0
  591. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/.gitignore.tmpl +0 -0
  592. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/Manifest.tmpl.json +0 -0
  593. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/compile.tmpl.json +0 -0
  594. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/readme.tmpl.txt +0 -0
  595. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/Application.tmpl.js +0 -0
  596. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/__init__.tmpl.js +0 -0
  597. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/class/custom/test/DemoTest.tmpl.js +0 -0
  598. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/resource/custom/.gitignore.tmpl +0 -0
  599. /package/source/resource/qx/tool/{cli → compiler/cli}/templates/skeleton/server/source/translation/readme.txt +0 -0
  600. /package/source/resource/qx/tool/{loadsass.js → compiler/loadsass.js} +0 -0
@@ -5,94 +5,106 @@
5
5
  http://qooxdoo.org
6
6
 
7
7
  Copyright:
8
- 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de
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
- * Sebastian Werner (wpbasti)
16
- * Andreas Ecker (ecker)
17
- * John Spackman (john.spackman@zenesis.com)
16
+ * Derrell Lipman (derrell)
17
+ * John Spackman (johnspackman)
18
18
 
19
19
  ************************************************************************ */
20
20
 
21
- /**
22
- * This class is one of the most important parts of qooxdoo's
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
- * A static reference to the property implementation in the case it
81
- * should be included.
32
+ * Options configured mostly by unit tests
33
+ *
34
+ * @internal
82
35
  */
83
- __Property: qx.core.Environment.get("module.property")
84
- ? qx.core.Property
85
- : null,
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
- PUBLIC METHODS
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 up the
95
- * namespace for the class and generates the class from the definition map.
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 {String} name @see `define()`
175
- * @param {*} config @see `define()`
176
- * @returns @see `define()`
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(name, config) {
179
- if (!config) {
180
- config = {};
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
- // Normalize type
200
- var implicitType = false;
201
- if (!config.hasOwnProperty("extend") && !config.type) {
202
- config.type = "static";
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
- this.__validateConfig(name, config);
210
- } catch (ex) {
389
+ qx.Class._validateConfig(className, config);
390
+ } catch (e) {
211
391
  if (implicitType) {
212
- ex.message =
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 ex;
394
+ throw e;
217
395
  }
396
+
397
+ qx.Class._validatePropertyDefinitions(className, config);
218
398
  }
219
399
 
220
- // Create the class
221
- var clazz = this.__createClass(
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(function (id) {
233
- this.__attachAnno(clazz, id, null, config[id]);
234
- }, this);
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
- // Members, properties, events and mixins are only allowed for non-static classes
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
- // Attach properties
239
- if (config.properties) {
240
- this.__addProperties(clazz, config.properties, true);
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
- // Attach members
501
+ // Add members
244
502
  if (config.members) {
245
- this.__addMembers(clazz, config.members, true, true, false);
503
+ qx.Class.addMembers(clazz, config.members, config.events, false);
246
504
  }
247
505
 
248
- // Process events
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
- this.__addEvents(clazz, config.events, true);
513
+ qx.Class.addEvents(clazz, config.events, false);
251
514
  }
252
515
 
253
- //Process cached objects
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 the last here to detect conflicts
522
+ // Must be here, after members and properties, to detect conflicts
260
523
  if (config.include) {
261
- for (var i = 0, l = config.include.length; i < l; i++) {
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
- // Process environment
275
- if (config.environment) {
276
- for (var key in config.environment) {
277
- qx.core.Environment.add(key, config.environment[key]);
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
- // Interface support for non-static classes
282
- if (config.implement) {
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
- if (qx.core.Environment.get("qx.debug")) {
289
- this.__validateAbstractInterfaces(clazz);
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
- // Process defer
589
+ // Now that the class has been defined, arrange to call its
590
+ // (optional) defer function
293
591
  if (config.defer) {
294
- config.defer.self = clazz;
295
- qx.Bootstrap.addPendingDefer(clazz, function () {
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
- // build pseudo properties map
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
- * Removes a class from qooxdoo defined by {@link #define}
315
- *
316
- * @param name {String} Name of the class
317
- */
318
- undefine(name) {
319
- // first, delete the class from the registry
320
- delete this.$$registry[name];
321
- // delete the class reference from the namespaces and all empty namespaces
322
- var ns = name.split(".");
323
- // build up an array containing all namespace objects including window
324
- var objects = [window];
325
- for (var i = 0; i < ns.length; i++) {
326
- objects.push(objects[i][ns[i]]);
327
- }
328
-
329
- // go through all objects and check for the constructor or empty namespaces
330
- for (var i = objects.length - 1; i >= 1; i--) {
331
- var last = objects[i];
332
- var parent = objects[i - 1];
333
- if (
334
- // The class being undefined, but parent classes in case it is a nested class that is being undefined
335
- (i == objects.length - 1 && qx.Bootstrap.isFunction(last)) ||
336
- qx.Bootstrap.objectGetLength(last) === 0
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
- * Whether the given class exists
347
- *
348
- * @signature function(name)
349
- * @param name {String} class name to check
350
- * @return {Boolean} true if class exists
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
- * Determine the total number of classes
356
- *
357
- * @return {Number} the total number of classes
358
- */
359
- getTotalNumber() {
360
- return qx.Bootstrap.objectGetLength(this.$$registry);
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
- * Find a class by its name
365
- *
366
- * @signature function(name)
367
- * @param name {String} class name to resolve
368
- * @return {Class} the class
369
- */
370
- getByName: qx.Bootstrap.getByName,
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
- * Include all features of the given mixin into the class. The mixin must
374
- * not include any methods or properties that are already available in the
375
- * class. This would only be possible using the {@link #patch} method.
376
- *
377
- * @param clazz {Class} An existing class which should be augmented by including a mixin.
378
- * @param mixin {Mixin} The mixin to be included.
379
- */
380
- include(clazz, mixin) {
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
- qx.Mixin.isCompatible(mixin, clazz);
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
- * Include all features of the given mixin into the class. The mixin may
398
- * include features, which are already defined in the target class. Existing
399
- * features of equal name will be overwritten.
400
- * Please keep in mind that this functionality is not intended for regular
401
- * use, but as a formalized way (and a last resort) in order to patch
402
- * existing classes.
403
- *
404
- * <b>WARNING</b>: You may break working classes and features.
405
- *
406
- * @param clazz {Class} An existing class which should be modified by including a mixin.
407
- * @param mixin {Mixin} The mixin to be included.
408
- * @return {Class} the new class definition
409
- */
410
- patch(clazz, mixin) {
411
- if (qx.core.Environment.get("qx.debug")) {
412
- if (!mixin) {
413
- throw new Error(
414
- "The mixin to patch class '" +
415
- clazz.classname +
416
- "' is undefined/null!"
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
- qx.Mixin.isCompatible(mixin, clazz);
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
- qx.Class.__addMixin(clazz, mixin, true);
424
- return qx.Class.getByName(clazz.classname);
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
- * Detects whether the object is a Class (and not an instance of a class)
429
- *
430
- * @param obj {Object?} the object to inspect
431
- * @return {Boolean} true if it is a class, false if it is anything else
432
- */
433
- isClass(obj) {
434
- return obj && obj.$$type === "Class" && obj.constructor === obj;
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
- * Whether a class is a direct or indirect sub class of another class,
439
- * or both classes coincide.
440
- *
441
- * @param clazz {Class} the class to check.
442
- * @param superClass {Class} the potential super class
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
- if (clazz == superClass) {
451
- return true;
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
- if (clazz.prototype instanceof superClass) {
455
- return true;
741
+ // Ensure there's something unique to compare constructors to.
742
+ if (!config.construct) {
743
+ config.construct = function () {};
456
744
  }
457
745
 
458
- return false;
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
- * Returns the definition of the given property. Returns null
463
- * if the property does not exist.
790
+ * Removes a class from qooxdoo defined by {@link #define}
464
791
  *
465
- * @signature function(clazz, name)
466
- * @param clazz {Class} class to check
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
- getPropertyDefinition: qx.util.OOUtil.getPropertyDefinition,
795
+ undefine: qx.Bootstrap.undefine,
471
796
 
472
797
  /**
473
- * Returns a list of all properties supported by the given class
798
+ * Attach members to a class
474
799
  *
475
- * @param clazz {Class} Class to query
476
- * @return {String[]} List of all property names
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
- getProperties(clazz) {
479
- var list = [];
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
- while (clazz) {
482
- if (clazz.$$properties) {
483
- list.push.apply(list, Object.keys(clazz.$$properties));
484
- }
813
+ for (let key in members) {
814
+ let member = members[key];
485
815
 
486
- clazz = clazz.superclass;
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
- return list;
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
- * Returns the class or one of its superclasses which contains the
494
- * declaration for the given property in its class definition. Returns null
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
- clazz = clazz.superclass;
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
- return null;
511
- },
512
-
513
- /**
514
- * Whether a class has the given property
515
- *
516
- * @signature function(clazz, name)
517
- * @param clazz {Class} class to check
518
- * @param name {String} name of the property to check for
519
- * @return {Boolean} whether the class includes the given property.
520
- */
521
- hasProperty: qx.util.OOUtil.hasProperty,
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
- * Returns the event type of the given event. Returns null if
525
- * the event does not exist.
526
- *
527
- * @signature function(clazz, name)
528
- * @param clazz {Class} class to check
529
- * @param name {String} name of the event
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
- * Whether a class supports the given event type
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
- * Whether a class directly includes a mixin.
546
- *
547
- * @param clazz {Class} class to check
548
- * @param mixin {Mixin} the mixin to check for
549
- * @return {Boolean} whether the class includes the mixin directly.
550
- */
551
- hasOwnMixin(clazz, mixin) {
552
- return clazz.$$includes && clazz.$$includes.indexOf(mixin) !== -1;
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
- * Returns the class or one of its superclasses which contains the
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
- while (clazz) {
568
- if (clazz.$$includes) {
569
- list = clazz.$$flatIncludes;
899
+ if (qx.core.Environment.get("qx.aspects")) {
900
+ member = qx.core.Aspect.wrap(clazz.classname, member, key);
901
+ }
570
902
 
571
- for (i = 0, l = list.length; i < l; i++) {
572
- if (list[i] === mixin) {
573
- return clazz;
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
- clazz = clazz.superclass;
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
- return null;
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
- * Returns a list of all mixins available in a given class.
983
+ * Attach properties to classes
586
984
  *
587
- * @signature function(clazz)
588
- * @param clazz {Class} class which should be inspected
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 clazz {Class} class to check
597
- * @param mixin {Mixin} the mixin to check for
598
- * @return {Boolean} whether the class includes the mixin.
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
- hasMixin(clazz, mixin) {
601
- return !!this.getByMixin(clazz, mixin);
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
- * Whether a given class directly includes an interface.
1043
+ * Attach events to the class
606
1044
  *
607
- * This function will only return "true" if the interface was defined
608
- * in the class declaration ({@link qx.Class#define}) using the "implement"
609
- * key.
1045
+ * @param clazz {Class}
1046
+ * Class to add the events to
610
1047
  *
611
- * @param clazz {Class} class or instance to check
612
- * @param iface {Interface} the interface to check for
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
- * @signature function(clazz, iface)
625
- * @param clazz {Class} class to look for the interface
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
- getByInterface: qx.util.OOUtil.getByInterface,
1054
+ addEvents(clazz, events, patch) {
1055
+ let key;
630
1056
 
631
- /**
632
- * Returns a list of all interfaces a given class has to implement.
633
- *
634
- * @param clazz {Class} class which should be inspected
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
- while (clazz) {
641
- if (clazz.$$implements) {
642
- list.push.apply(list, clazz.$$flatImplements);
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
- clazz = clazz.superclass;
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
- return list;
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
- * Whether a given class or any of its super classes includes a given interface.
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
- * @signature function(clazz, iface)
660
- * @param clazz {Class} class to check
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
- * Checks whether all methods defined in the interface are
670
- * implemented. The class does not need to implement
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 obj {Object} class to check
674
- * @param iface {Interface} the interface to check for
675
- * @return {Boolean} whether the class conforms to the interface.
1106
+ * @param patch {Boolean}
1107
+ * Overwrite existing fields, functions and properties
676
1108
  */
677
- implementsInterface(obj, iface) {
678
- var clazz = obj.constructor;
679
-
680
- if (this.hasInterface(clazz, iface)) {
681
- return true;
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 (qx.Interface.objectImplements(obj, iface)) {
685
- return true;
1116
+ if (this.hasMixin(clazz, mixin)) {
1117
+ return;
686
1118
  }
687
1119
 
688
- if (qx.Interface.classImplements(clazz, iface)) {
689
- return true;
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
- return false;
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
- * Helper method to handle singletons
1150
+ * Add a single interface to a class
697
1151
  *
698
- * @internal
699
- * @return {Object} The singleton instance
1152
+ * @param clazz {Class} class to add interface to
1153
+ * @param iface {Interface} the Interface to add
700
1154
  */
701
- getInstance() {
702
- if (this.$$instance === null) {
703
- throw new Error(
704
- "Singleton instance of " +
705
- this +
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
- if (!this.$$instance) {
711
- this.$$allowconstruct = true;
712
- this.$$instance = null; // null means "object is being created"; needed for another call of getInstance() during instantiation
713
- this.$$instance = new this();
714
- delete this.$$allowconstruct;
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
- return this.$$instance;
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
- * Retreive all subclasses of a given class
1187
+ * Adds the objects definition to the class
722
1188
  *
723
- * @param clazz {Class} the class which should be inspected
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
- getSubclasses(clazz) {
728
- if (!clazz) {
729
- return null;
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
- var subclasses = {};
733
- var registry = qx.Class.$$registry;
1203
+ if (!(objects instanceof Object)) {
1204
+ throw new Error("Invalid objects definition for " + clazz.classname);
1205
+ }
734
1206
 
735
- for (var name in registry) {
736
- if (registry[name].superclass && registry[name].superclass == clazz) {
737
- subclasses[name] = registry[name];
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
- return subclasses;
1213
+ clazz.$$objects = objects;
742
1214
  },
743
1215
 
744
- /*
745
- ---------------------------------------------------------------------------
746
- PRIVATE/INTERNAL BASICS
747
- ---------------------------------------------------------------------------
748
- */
749
-
750
1216
  /**
751
- * This method will be attached to all classes to return
752
- * a nice identifier for them.
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
- * @internal
755
- * @return {String} The class identifier
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
- genericToString() {
758
- return "[Class " + this.classname + "]";
759
- },
760
-
761
- /** Stores all defined classes */
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
- /** @type {Map} allowed keys in static class definition */
789
- __staticAllowedKeys: qx.core.Environment.select("qx.debug", {
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
- default: null
799
- }),
1237
+ qx.Class.addMixin(clazz, mixin, false);
1238
+ },
800
1239
 
801
1240
  /**
802
- * Validates an incoming configuration and checks for proper keys and values
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
- * @signature function(name, config)
805
- * @param name {String} The name of the class
806
- * @param config {Map} Configuration map
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
- __validateConfig: qx.core.Environment.select("qx.debug", {
809
- true(name, config) {
810
- // Validate type
811
- if (
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
- // Validate non-static class on the "extend" key
829
- if (config.type && config.type !== "static" && !config.extend) {
830
- throw new Error(
831
- 'Invalid config in class "' +
832
- name +
833
- '"! Every non-static class has to extend at least the "qx.core.Object" class.'
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
- // Validate keys
838
- var allowed =
839
- config.type === "static"
840
- ? this.__staticAllowedKeys
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
- if (config[key] == null) {
854
- throw new Error(
855
- 'Invalid key "' +
856
- key +
857
- '" in class "' +
858
- name +
859
- '"! The value is undefined/null!'
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
- if (typeof config[key] !== allowed[key]) {
864
- throw new Error(
865
- 'Invalid type of key "' +
866
- key +
867
- '" in class "' +
868
- name +
869
- '"! The type of the key must be "' +
870
- allowed[key] +
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
- var maps = [
878
- "statics",
879
- "properties",
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 (var i = 0, a = config.include, l = a.length; i < l; i++) {
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
- 'Invalid include definition in class "' +
923
- name +
924
- '"! Only mixins and arrays of mixins are allowed!'
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 (var i = 0, a = config.implement, l = a.length; i < l; i++) {
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 (var key in config.environment) {
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 (var key in config.settings) {
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 an external namespace!'
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 (var key in config.variants) {
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 an external namespace!'
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(name, config) {}
1460
+ default() {
1461
+ // do nothing when debug is disabled
1462
+ }
1024
1463
  }),
1025
1464
 
1026
- /**
1027
- * Validates the interfaces required by abstract base classes
1028
- *
1029
- * @signature function(clazz)
1030
- * @param clazz {Class} The configured class.
1031
- */
1032
- __validateAbstractInterfaces: qx.core.Environment.select("qx.debug", {
1033
- true(clazz) {
1034
- var superclass = clazz.superclass;
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
- var interfaces = superclass.$$implements;
1041
- if (interfaces) {
1042
- for (var i = 0; i < interfaces.length; i++) {
1043
- qx.Interface.assert(clazz, interfaces[i], true);
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
- superclass = superclass.superclass;
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(clazz) {}
1525
+ default(className, config) {
1526
+ // do nothing when debug is disabled
1527
+ }
1051
1528
  }),
1052
1529
 
1053
1530
  /**
1054
- * Attaches an annotation to a class
1531
+ * Find a class by its name
1055
1532
  *
1056
- * @param clazz {Map} Static methods or fields
1057
- * @param group {String} Group name
1058
- * @param key {String} Name of the annotated item
1059
- * @param anno {Object} Annotation object
1533
+ * @signature function(name)
1534
+ *
1535
+ * @param name {String}
1536
+ * Class name to resolve
1537
+ *
1538
+ * @return {Class}
1539
+ * The class
1060
1540
  */
1061
- __attachAnno(clazz, group, key, anno) {
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
- if (!qx.lang.Type.isArray(anno)) {
1071
- anno = [anno];
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
- if (key) {
1075
- clazz.$$annotations[group][key] = anno;
1076
- } else {
1077
- clazz.$$annotations[group] = anno;
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
- * Creates a class by type. Supports modern inheritance etc.
1084
- *
1085
- * @param name {String} Full name of the class
1086
- * @param type {String} type of the class, i.e. "static", "abstract" or "singleton"
1087
- * @param extend {Class} Superclass to inherit from
1088
- * @param statics {Map} Static methods or fields
1089
- * @param construct {Function} Constructor of the class
1090
- * @param destruct {Function} Destructor of the class
1091
- * @param mixins {Mixin[]} array of mixins of the class
1092
- * @return {Class} The generated class
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
- __createClass(name, type, extend, statics, construct, destruct, mixins) {
1095
- var isStrictMode = function () {
1096
- return typeof this == "undefined";
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
- if (extend) {
1109
- // Create default constructor
1110
- if (!construct) {
1111
- construct = this.__createDefaultConstructor();
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
- clazz = this.__wrapConstructor(construct, name, type);
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
- // Add singleton getInstance()
1117
- if (type === "singleton") {
1118
- clazz.getInstance = this.getInstance;
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
- qx.Bootstrap.setDisplayName(construct, name, "constructor");
1641
+ while (clazz) {
1642
+ if (clazz.$$implements) {
1643
+ list.push.apply(list, clazz.$$flatImplements);
1122
1644
  }
1123
1645
 
1124
- // Copy statics
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
- // Create namespace
1180
- var basename = name ? qx.Bootstrap.createNamespace(name, clazz) : "";
1649
+ return list;
1650
+ },
1181
1651
 
1182
- // Store names in constructor/object
1183
- clazz.classname = name;
1184
- if (!isStrictMode()) {
1185
- try {
1186
- clazz.name = name;
1187
- } catch (ex) {
1188
- // Nothing
1189
- }
1190
- }
1191
- clazz.basename = basename;
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
- // Store type info
1194
- clazz.$$type = "Class";
1195
- if (type) {
1196
- clazz.$$classtype = type;
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
- // Attach toString
1200
- if (!clazz.hasOwnProperty("toString")) {
1201
- clazz.toString = this.genericToString;
1692
+ if (this.hasInterface(clazz, iface)) {
1693
+ return true;
1202
1694
  }
1203
1695
 
1204
- if (extend) {
1205
- qx.Bootstrap.extendClass(clazz, construct, extend, name, basename);
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
- // Store class reference in global class registry
1219
- this.$$registry[name] = clazz;
1700
+ if (qx.Interface.classImplements(clazz, iface)) {
1701
+ return true;
1702
+ }
1220
1703
 
1221
- // Return final class object
1222
- return clazz;
1704
+ return false;
1223
1705
  },
1224
1706
 
1225
- /*
1226
- ---------------------------------------------------------------------------
1227
- PRIVATE ADD HELPERS
1228
- ---------------------------------------------------------------------------
1229
- */
1230
-
1231
1707
  /**
1232
- * Attach events to the class
1708
+ * Whether the given class exists
1233
1709
  *
1234
- * @param clazz {Class} class to add the events to
1235
- * @param events {Map} map of event names the class fires.
1236
- * @param patch {Boolean ? false} Enable redefinition of event type?
1710
+ * @signature function(name)
1711
+ * @param name {String} class name to check
1712
+ * @return {Boolean} true if class exists
1237
1713
  */
1238
- __addEvents(clazz, events, patch) {
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
- for (var key in events) {
1250
- if (typeof events[key] !== "string") {
1251
- throw new Error(
1252
- clazz.classname +
1253
- "/" +
1254
- key +
1255
- ": the event value needs to be a string with the class name of the event object which will be fired."
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
- __addObjects(clazz, objects) {
1291
- function validateCachedObject(key, value) {
1292
- if (typeof value !== "function") {
1293
- throw new Error(
1294
- "Invalid cached object definition for " +
1295
- key +
1296
- " in " +
1297
- clazz.classname
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 (!(objects instanceof Object)) {
1309
- throw new Error("Invalid objects definition for " + clazz.classname);
1739
+ if (clazz == superClass) {
1740
+ return true;
1310
1741
  }
1311
1742
 
1312
- if (qx.core.Environment.get("qx.debug")) {
1313
- for (const key in objects) {
1314
- validateCachedObject(key, objects[key]);
1315
- }
1743
+ if (clazz.prototype instanceof superClass) {
1744
+ return true;
1316
1745
  }
1317
1746
 
1318
- clazz.$$objects = objects;
1747
+ return false;
1319
1748
  },
1320
1749
 
1321
1750
  /**
1322
- * Attach properties to classes
1751
+ * Retreive all subclasses of a given class
1752
+ *
1753
+ * @param clazz {Class}
1754
+ * The class which should be inspected
1323
1755
  *
1324
- * @param clazz {Class} class to add the properties to
1325
- * @param properties {Map} map of properties
1326
- * @param patch {Boolean ? false} Overwrite property with the limitations of a property
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
- __addProperties(clazz, properties, patch) {
1330
- // check for the property module
1331
- if (!qx.core.Environment.get("module.property")) {
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
- var proto = clazz.prototype;
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
- // Remember inheritable properties
1390
- if (config.inheritable) {
1391
- this.__Property.$$inheritable[name] = true;
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
- * Validates the given property
1778
+ * Returns the definition of the given property. Returns null
1779
+ * if the property does not exist.
1408
1780
  *
1409
- * @signature function(clazz, name, config, patch)
1410
- * @param clazz {Class} class to add property to
1411
- * @param name {String} name of the property
1412
- * @param config {Map} configuration map
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
- __validateProperty: qx.core.Environment.select("qx.debug", {
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
- * Attach members to a class
1789
+ * Returns a list of all properties supported by the given class
1569
1790
  *
1570
- * @param clazz {Class} clazz to add members to
1571
- * @param members {Map} The map of members to attach
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
- __addMembers(clazz, members, patch, base, wrap) {
1579
- var proto = clazz.prototype;
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
- * Add a single interface to a class
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 add interface to
1697
- * @param iface {Interface} the Interface to add
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
- __addInterface(clazz, iface) {
1700
- if (qx.core.Environment.get("qx.debug")) {
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
- * Include all features of the mixin into the given class, recursively.
1812
+ * Returns the property descriptor (Property object) of the given property.
1813
+ * Returns null if the property does not exist.
1737
1814
  *
1738
- * @param clazz {Class} The class onto which the mixin should be attached.
1739
- * @param mixin {Mixin} Include all features of this mixin
1740
- * @param patch {Boolean} Overwrite existing fields, functions and properties
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
- __addMixin(clazz, mixin, patch) {
1743
- if (qx.core.Environment.get("qx.debug")) {
1744
- if (!clazz || !mixin) {
1745
- throw new Error("Incomplete parameters!");
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
- // Attach content
1754
- var list = qx.Mixin.flatten([mixin]);
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
- // Attach members (Respect patch setting, but dont apply base variables)
1771
- if (entry.$$members) {
1772
- this.__addMembers(clazz, entry.$$members, patch, patch, patch);
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
- // Store mixin reference
1777
- if (clazz.$$includes) {
1778
- clazz.$$includes.push(mixin);
1779
- clazz.$$flatIncludes.push.apply(clazz.$$flatIncludes, list);
1842
+ descriptor.get = function() {
1843
+ return property.get(instance);
1844
+ };
1780
1845
  } else {
1781
- clazz.$$includes = [mixin];
1782
- clazz.$$flatIncludes = list;
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
- * Returns the default constructor.
1794
- * This constructor just calls the constructor of the base class.
1860
+ * Whether a class has the given property
1795
1861
  *
1796
- * @return {Function} The default constructor.
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
- __createDefaultConstructor() {
1799
- function defaultConstructor() {
1800
- defaultConstructor.base.apply(this, arguments);
1801
- }
1867
+ hasProperty: qx.util.OOUtil.hasProperty,
1802
1868
 
1803
- return defaultConstructor;
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
- * Generate a wrapper of the original class constructor in order to enable
1808
- * some of the advanced OO features (e.g. abstract class, singleton, mixins)
1882
+ * Returns the event type of the given event. Returns null if
1883
+ * the event does not exist.
1809
1884
  *
1810
- * @param construct {Function} the original constructor
1811
- * @param name {String} name of the class
1812
- * @param type {String} the user specified class type
1813
- * @return {Function} The wrapped constructor
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
- __wrapConstructor(construct, name, type) {
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
- // Store wrapper into constructor (needed for base calls etc.)
1882
- construct.wrapper = wrapper;
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
- // Return generated wrapper
1885
- return wrapper;
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
- defer() {
1890
- // Binding of already loaded bootstrap classes
1891
- if (qx.core.Environment.get("qx.aspects")) {
1892
- for (var classname in qx.Bootstrap.$$registry) {
1893
- var statics = qx.Bootstrap.$$registry[classname];
1894
-
1895
- for (var key in statics) {
1896
- // only functions, no regexps
1897
- if (statics[key] instanceof Function) {
1898
- statics[key] = qx.core.Aspect.wrap(
1899
- classname + "." + key,
1900
- statics[key],
1901
- "static"
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
  });