@qooxdoo/framework 7.7.2 → 7.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/Manifest.json +1 -1
  2. package/lib/compiler/compile-info.json +63 -63
  3. package/lib/compiler/index.js +513 -353
  4. package/lib/resource/qx/tool/schema/compile-1-0-0.json +13 -0
  5. package/package.json +2 -2
  6. package/source/class/qx/bom/Label.js +82 -2
  7. package/source/class/qx/bom/webfonts/WebFont.js +1 -0
  8. package/source/class/qx/core/Environment.js +82 -1
  9. package/source/class/qx/data/controller/List.js +50 -21
  10. package/source/class/qx/data/controller/MSelection.js +45 -12
  11. package/source/class/qx/dev/unit/AsyncWrapper.js +8 -0
  12. package/source/class/qx/event/Manager.js +163 -124
  13. package/source/class/qx/io/ImageLoader.js +6 -3
  14. package/source/class/qx/io/exception/Transport.js +1 -0
  15. package/source/class/qx/io/jsonrpc/Client.js +64 -8
  16. package/source/class/qx/io/jsonrpc/protocol/Request.js +10 -6
  17. package/source/class/qx/test/bom/client/Pdfjs.js +4 -0
  18. package/source/class/qx/test/bom/element/AnimationJs.js +3 -0
  19. package/source/class/qx/test/bom/element/Style.js +1 -0
  20. package/source/class/qx/test/bom/media/MediaTestCase.js +6 -0
  21. package/source/class/qx/test/core/Environment.js +44 -0
  22. package/source/class/qx/test/io/MAssert.js +94 -0
  23. package/source/class/qx/test/io/TestMAssert.js +47 -0
  24. package/source/class/qx/test/io/jsonrpc/Client.js +79 -19
  25. package/source/class/qx/test/io/jsonrpc/PostMessageClient.js +152 -0
  26. package/source/class/qx/test/io/jsonrpc/Protocol.js +1 -5
  27. package/source/class/qx/test/ui/embed/Iframe.js +1 -1
  28. package/source/class/qx/test/ui/form/TextArea.js +4 -0
  29. package/source/class/qx/test/util/DeferredCall.js +6 -0
  30. package/source/class/qx/test/util/Function.js +2 -2
  31. package/source/class/qx/tool/cli/api/Test.js +22 -0
  32. package/source/class/qx/tool/cli/commands/Compile.js +17 -4
  33. package/source/class/qx/tool/cli/commands/Test.js +7 -1
  34. package/source/class/qx/tool/compiler/Analyser.js +7 -0
  35. package/source/class/qx/tool/compiler/ClassFile.js +3 -2
  36. package/source/class/qx/tool/compiler/MetaExtraction.js +0 -5
  37. package/source/class/qx/tool/compiler/targets/meta/Browserify.js +8 -2
  38. package/source/class/qx/ui/basic/Image.js +72 -8
  39. package/source/class/qx/ui/basic/Label.js +4 -6
  40. package/source/class/qx/ui/control/DateChooser.js +4 -6
  41. package/source/class/qx/ui/core/Blocker.js +4 -6
  42. package/source/class/qx/ui/core/LayoutItem.js +4 -6
  43. package/source/class/qx/ui/core/MPlacement.js +11 -0
  44. package/source/class/qx/ui/core/Widget.js +7 -5
  45. package/source/class/qx/ui/form/AbstractField.js +4 -6
  46. package/source/class/qx/ui/form/MForm.js +4 -6
  47. package/source/class/qx/ui/form/Spinner.js +4 -6
  48. package/source/class/qx/ui/form/renderer/AbstractRenderer.js +4 -6
  49. package/source/class/qx/ui/menu/AbstractButton.js +7 -11
  50. package/source/class/qx/ui/mobile/basic/Label.js +4 -6
  51. package/source/class/qx/ui/mobile/form/Label.js +4 -6
  52. package/source/class/qx/ui/mobile/list/List.js +4 -6
  53. package/source/class/qx/ui/progressive/renderer/table/Row.js +35 -7
  54. package/source/class/qx/ui/progressive/renderer/table/cell/Boolean.js +4 -6
  55. package/source/class/qx/ui/table/Table.js +4 -6
  56. package/source/class/qx/ui/table/cellrenderer/Abstract.js +4 -6
  57. package/source/class/qx/ui/table/cellrenderer/Boolean.js +4 -6
  58. package/source/class/qx/ui/table/rowrenderer/Default.js +4 -6
  59. package/source/resource/qx/tool/schema/compile-1-0-0.json +13 -0
@@ -1,3 +1,16 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2020 Henner Kollmann
9
+
10
+ License:
11
+ MIT: https://opensource.org/licenses/MIT
12
+ See the LICENSE file in the project"s top-level directory for details.
13
+ ************************************************************************ */
1
14
  /**
2
15
  * This is used to add an test case for qx test
3
16
  */
@@ -47,6 +60,15 @@ qx.Class.define("qx.tool.cli.api.Test", {
47
60
  init: true
48
61
  },
49
62
 
63
+ /**
64
+ * If this special test fails exit process
65
+ */
66
+ failFast: {
67
+ check: "Boolean",
68
+ nullable: false,
69
+ init: false
70
+ },
71
+
50
72
  /**
51
73
  * The test function called by qx test
52
74
  *
@@ -1345,6 +1345,15 @@ Framework: v${await this.getQxVersion()} in ${await this.getQxPath()}`);
1345
1345
  if (data.environment) {
1346
1346
  maker.setEnvironment(data.environment);
1347
1347
  }
1348
+
1349
+ /*
1350
+ Libraries have to be added first because there is qx library
1351
+ which includes a framework version
1352
+ */
1353
+ for (let library of librariesArray) {
1354
+ maker.getAnalyser().addLibrary(library);
1355
+ }
1356
+
1348
1357
  let targetEnvironment = {
1349
1358
  "qx.version": maker.getAnalyser().getQooxdooVersion(),
1350
1359
  "qx.compiler.targetType": target.getType(),
@@ -1395,6 +1404,14 @@ Framework: v${await this.getQxVersion()} in ${await this.getQxPath()}`);
1395
1404
 
1396
1405
  maker.getAnalyser().setBabelConfig(babelConfig);
1397
1406
 
1407
+ let browserifyConfig = qx.lang.Object.clone(data.browserify || {}, true);
1408
+ browserifyConfig.options = browserifyConfig.options || {};
1409
+ qx.lang.Object.mergeWith(
1410
+ browserifyConfig.options,
1411
+ targetConfig.browserifyOptions || {}
1412
+ );
1413
+ maker.getAnalyser().setBrowserifyConfig(browserifyConfig);
1414
+
1398
1415
  var addCreatedAt =
1399
1416
  targetConfig["addCreatedAt"] || t.argv["addCreatedAt"];
1400
1417
  if (addCreatedAt) {
@@ -1406,10 +1423,6 @@ Framework: v${await this.getQxVersion()} in ${await this.getQxPath()}`);
1406
1423
  maker.getAnalyser().setVerboseCreatedAt(true);
1407
1424
  }
1408
1425
 
1409
- for (let library of librariesArray) {
1410
- maker.getAnalyser().addLibrary(library);
1411
- }
1412
-
1413
1426
  let allApplicationTypes = {};
1414
1427
  appConfigs.forEach(appConfig => {
1415
1428
  var app = (appConfig.app = new qx.tool.compiler.app.Application(
@@ -99,7 +99,7 @@ qx.Class.define("qx.tool.cli.commands.Test", {
99
99
  let exitCode = evt.getData();
100
100
  // overwrite error code only in case of errors
101
101
  if (exitCode !== 0 && argv.failFast) {
102
- process.exit(exitCode);
102
+ process.exit(Math.min(255, exitCode));
103
103
  }
104
104
  });
105
105
  },
@@ -152,6 +152,9 @@ qx.Class.define("qx.tool.cli.commands.Test", {
152
152
  }
153
153
  // overwrite error code only in case of errors
154
154
  if (exitCode !== 0) {
155
+ if (test.getFailFast()) {
156
+ this.argv.failFast = true;
157
+ }
155
158
  this.setExitCode(exitCode);
156
159
  }
157
160
  });
@@ -194,6 +197,9 @@ qx.Class.define("qx.tool.cli.commands.Test", {
194
197
 
195
198
  this.addListener("afterStart", async () => {
196
199
  qx.tool.compiler.Console.info(`Running unit tests`);
200
+ if (this.argv.verbose) {
201
+ console.log(this.argv);
202
+ }
197
203
  await this.fireDataEventAsync("runTests", this);
198
204
  if (
199
205
  this.getCompilerApi() &&
@@ -126,6 +126,13 @@ qx.Class.define("qx.tool.compiler.Analyser", {
126
126
  check: "Object"
127
127
  },
128
128
 
129
+ /** configuration of browserify */
130
+ browserifyConfig: {
131
+ init: null,
132
+ nullable: true,
133
+ check: "Object"
134
+ },
135
+
129
136
  /** list of global ignores */
130
137
  ignores: {
131
138
  init: [],
@@ -962,14 +962,15 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
962
962
 
963
963
  CallExpression(path) {
964
964
  const name = collapseMemberExpression(path.node.callee);
965
+ const env = t.__analyser.getEnvironment();
965
966
 
966
967
  if (
968
+ env["qx.environment.allowRuntimeMutations"] !== true &&
967
969
  (name === "qx.core.Environment.select" ||
968
970
  name === "qx.core.Environment.get") &&
969
- types.isLiteral(path.node.arguments[0])
971
+ types.isLiteral(path.node.arguments[0])
970
972
  ) {
971
973
  const arg = path.node.arguments[0];
972
- const env = t.__analyser.getEnvironment();
973
974
  const envValue = env[arg.value];
974
975
 
975
976
  if (envValue !== undefined) {
@@ -109,11 +109,6 @@ qx.Class.define("qx.tool.compiler.MetaExtraction", {
109
109
 
110
110
  const babelCore = require("@babel/core");
111
111
  let src = await fs.promises.readFile(classFilename, "utf8");
112
- let babelConfig = {
113
- options: {
114
- modules: false
115
- }
116
- };
117
112
 
118
113
  let plugins = [require("@babel/plugin-syntax-jsx"), this.__plugin()];
119
114
 
@@ -158,12 +158,18 @@ qx.Class.define("qx.tool.compiler.targets.meta.Browserify", {
158
158
  builtins.process = builtins._process;
159
159
 
160
160
  return new Promise((resolve, reject) => {
161
- let b = browserify([], {
161
+ const options = {
162
162
  builtins: builtins,
163
163
  ignoreMissing: true,
164
164
  insertGlobals: true,
165
165
  detectGlobals: true
166
- });
166
+ };
167
+ qx.lang.Object.mergeWith(
168
+ options,
169
+ this.getAppMeta().getAnalyser().getBrowserifyConfig()?.options || {},
170
+ false
171
+ );
172
+ let b = browserify([], options);
167
173
 
168
174
  b._mdeps.on("missing", (id, parent) => {
169
175
  let message = [];
@@ -144,6 +144,16 @@ qx.Class.define("qx.ui.basic.Image", {
144
144
  allowGrowY: {
145
145
  refine: true,
146
146
  init: false
147
+ },
148
+
149
+ /**
150
+ * Source of image to display if the image in the `source` property fails to load.
151
+ */
152
+ fallbackSource: {
153
+ check: "String",
154
+ init: null,
155
+ nullable: true,
156
+ event: "changeFallbackSource"
147
157
  }
148
158
  },
149
159
 
@@ -189,6 +199,19 @@ qx.Class.define("qx.ui.basic.Image", {
189
199
  __currentContentElement: null,
190
200
  __wrapper: null,
191
201
  __requestId: 0,
202
+ /**
203
+ * If the image in the `source` property failed to load.
204
+ */
205
+ __failedToLoad: false,
206
+
207
+ /**
208
+ * @type {string} The actual source of the image that we display.
209
+ * While the `source` property is what we want to display,
210
+ * this property is what we are actually showing.
211
+ * This can be the `source` property but it can also be the `fallbackSource` property
212
+ * if the image in the `source` property failed to load.
213
+ */
214
+ __sourceToDisplay: null,
192
215
 
193
216
  // overridden
194
217
  _onChangeTheme() {
@@ -225,7 +248,7 @@ qx.Class.define("qx.ui.basic.Image", {
225
248
  _applyDecorator(value, old) {
226
249
  super._applyDecorator(value, old);
227
250
 
228
- var source = this.getSource();
251
+ var source = this.__sourceToDisplay;
229
252
  source = qx.util.AliasManager.getInstance().resolve(source);
230
253
  var el = this.getContentElement();
231
254
  if (this.__wrapper) {
@@ -307,7 +330,7 @@ qx.Class.define("qx.ui.basic.Image", {
307
330
  _applyEnabled(value, old) {
308
331
  super._applyEnabled(value, old);
309
332
 
310
- if (this.getSource()) {
333
+ if (this.__sourceToDisplay) {
311
334
  this._styleSource();
312
335
  }
313
336
  },
@@ -321,6 +344,8 @@ qx.Class.define("qx.ui.basic.Image", {
321
344
  }
322
345
  }
323
346
 
347
+ this.__failedToLoad = false;
348
+ this.__sourceToDisplay = value;
324
349
  this._styleSource();
325
350
  },
326
351
 
@@ -345,7 +370,7 @@ qx.Class.define("qx.ui.basic.Image", {
345
370
  */
346
371
  __getMode() {
347
372
  if (this.__mode == null) {
348
- var source = this.getSource();
373
+ var source = this.__sourceToDisplay;
349
374
 
350
375
  if (source && qx.lang.String.startsWith(source, "@")) {
351
376
  this.__mode = "font";
@@ -458,13 +483,12 @@ qx.Class.define("qx.ui.basic.Image", {
458
483
  /**
459
484
  * Applies the source to the clipped image instance or preload
460
485
  * an image to detect sizes and apply it afterwards.
461
- *
462
486
  */
463
487
  _styleSource() {
464
488
  var AliasManager = qx.util.AliasManager.getInstance();
465
489
  var ResourceManager = qx.util.ResourceManager.getInstance();
466
490
 
467
- var source = AliasManager.resolve(this.getSource());
491
+ var source = AliasManager.resolve(this.__sourceToDisplay);
468
492
 
469
493
  var element = this.getContentElement();
470
494
  if (this.__wrapper) {
@@ -791,7 +815,7 @@ qx.Class.define("qx.ui.basic.Image", {
791
815
  el.setStyle("fontSize", (width > height ? height : width) + "px");
792
816
  } else {
793
817
  var source = qx.util.AliasManager.getInstance().resolve(
794
- this.getSource()
818
+ this.__sourceToDisplay
795
819
  );
796
820
 
797
821
  var sparts = source.split("/");
@@ -805,7 +829,8 @@ qx.Class.define("qx.ui.basic.Image", {
805
829
  super._applyDimension();
806
830
 
807
831
  var isFont =
808
- this.getSource() && qx.lang.String.startsWith(this.getSource(), "@");
832
+ this.__sourceToDisplay &&
833
+ qx.lang.String.startsWith(this.__sourceToDisplay, "@");
809
834
  if (isFont) {
810
835
  var el = this.getContentElement();
811
836
  if (el) {
@@ -872,6 +897,11 @@ qx.Class.define("qx.ui.basic.Image", {
872
897
  ImageLoader.load(source, this.__loaderCallback, this);
873
898
  } else {
874
899
  this.__resetSource(el);
900
+ if (!this.__failedToLoad && this.getFallbackSource()) {
901
+ this.__failedToLoad = true;
902
+ this.__sourceToDisplay = this.getFallbackSource();
903
+ this._styleSource();
904
+ }
875
905
  }
876
906
  },
877
907
 
@@ -904,6 +934,7 @@ qx.Class.define("qx.ui.basic.Image", {
904
934
  },
905
935
 
906
936
  /**
937
+ * Sets image source on the DOM element
907
938
  * Combines the decorator's image styles with our own image to make sure
908
939
  * gradient and backgroundImage decorators work on Images.
909
940
  *
@@ -991,6 +1022,32 @@ qx.Class.define("qx.ui.basic.Image", {
991
1022
  }
992
1023
  },
993
1024
 
1025
+ /**
1026
+ * Tries to display the image in the `source` property again if it has failed to load.
1027
+ */
1028
+ tryReload() {
1029
+ if (!this.__failedToLoad) {
1030
+ return;
1031
+ }
1032
+ this.__failedToLoad = false;
1033
+ this.__sourceToDisplay = this.getSource();
1034
+ qx.io.ImageLoader.load(
1035
+ this.getSource(),
1036
+ () => this._styleSource(),
1037
+ undefined,
1038
+ {
1039
+ retryFailed: true
1040
+ }
1041
+ );
1042
+ },
1043
+
1044
+ /**
1045
+ * @returns {boolean} If the image in the `source` property failed to load.
1046
+ */
1047
+ hasFailedToLoad() {
1048
+ return this.__failedToLoad;
1049
+ },
1050
+
994
1051
  /**
995
1052
  * Event handler fired after the preloader has finished loading the icon
996
1053
  *
@@ -1005,7 +1062,8 @@ qx.Class.define("qx.ui.basic.Image", {
1005
1062
 
1006
1063
  // Ignore when the source has already been modified
1007
1064
  if (
1008
- source !== qx.util.AliasManager.getInstance().resolve(this.getSource())
1065
+ source !==
1066
+ qx.util.AliasManager.getInstance().resolve(this.__sourceToDisplay)
1009
1067
  ) {
1010
1068
  this.fireEvent("aborted");
1011
1069
  return;
@@ -1015,6 +1073,12 @@ qx.Class.define("qx.ui.basic.Image", {
1015
1073
  if (imageInfo.failed) {
1016
1074
  this.warn("Image could not be loaded: " + source);
1017
1075
  this.fireEvent("loadingFailed");
1076
+ if (!this.__failedToLoad && this.getFallbackSource()) {
1077
+ this.__failedToLoad = true;
1078
+ this.__sourceToDisplay = this.getFallbackSource();
1079
+ this._styleSource();
1080
+ return;
1081
+ }
1018
1082
  } else if (imageInfo.aborted) {
1019
1083
  this.fireEvent("aborted");
1020
1084
  return;
@@ -79,7 +79,7 @@ qx.Class.define("qx.ui.basic.Label", {
79
79
  }
80
80
 
81
81
  if (qx.core.Environment.get("qx.dynlocale")) {
82
- qx.locale.Manager.getInstance().addListener(
82
+ this.__changeLocaleLabelListenerId = qx.locale.Manager.getInstance().addListener(
83
83
  "changeLocale",
84
84
  this._onChangeLocale,
85
85
  this
@@ -529,11 +529,9 @@ qx.Class.define("qx.ui.basic.Label", {
529
529
  */
530
530
 
531
531
  destruct() {
532
- if (qx.core.Environment.get("qx.dynlocale")) {
533
- qx.locale.Manager.getInstance().removeListener(
534
- "changeLocale",
535
- this._onChangeLocale,
536
- this
532
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleLabelListenerId) {
533
+ qx.locale.Manager.getInstance().removeListenerById(
534
+ this.__changeLocaleLabelListenerId
537
535
  );
538
536
  }
539
537
 
@@ -102,7 +102,7 @@ qx.Class.define("qx.ui.control.DateChooser", {
102
102
 
103
103
  // listen for locale changes
104
104
  if (qx.core.Environment.get("qx.dynlocale")) {
105
- qx.locale.Manager.getInstance().addListener(
105
+ this.__changeLocaleDatePaneListenerId = qx.locale.Manager.getInstance().addListener(
106
106
  "changeLocale",
107
107
  this._updateDatePane,
108
108
  this
@@ -782,11 +782,9 @@ qx.Class.define("qx.ui.control.DateChooser", {
782
782
  */
783
783
 
784
784
  destruct() {
785
- if (qx.core.Environment.get("qx.dynlocale")) {
786
- qx.locale.Manager.getInstance().removeListener(
787
- "changeLocale",
788
- this._updateDatePane,
789
- this
785
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleDatePaneListenerId) {
786
+ qx.locale.Manager.getInstance().removeListenerById(
787
+ this.__changeLocaleDatePaneListenerId
790
788
  );
791
789
  }
792
790
 
@@ -63,7 +63,7 @@ qx.Class.define("qx.ui.core.Blocker", {
63
63
 
64
64
  // dynamic theme switch
65
65
  if (qx.core.Environment.get("qx.dyntheme")) {
66
- qx.theme.manager.Meta.getInstance().addListener(
66
+ this.__changeThemeBlockerListenerId = qx.theme.manager.Meta.getInstance().addListener(
67
67
  "changeTheme",
68
68
  this._onChangeTheme,
69
69
  this
@@ -499,11 +499,9 @@ qx.Class.define("qx.ui.core.Blocker", {
499
499
 
500
500
  destruct() {
501
501
  // remove dynamic theme listener
502
- if (qx.core.Environment.get("qx.dyntheme")) {
503
- qx.theme.manager.Meta.getInstance().removeListener(
504
- "changeTheme",
505
- this._onChangeTheme,
506
- this
502
+ if (qx.core.Environment.get("qx.dyntheme") && this.__changeThemeBlockerListenerId) {
503
+ qx.theme.manager.Meta.getInstance().removeListenerById(
504
+ this.__changeThemeBlockerListenerId
507
505
  );
508
506
  }
509
507
 
@@ -30,7 +30,7 @@ qx.Class.define("qx.ui.core.LayoutItem", {
30
30
 
31
31
  // dynamic theme switch
32
32
  if (qx.core.Environment.get("qx.dyntheme")) {
33
- qx.theme.manager.Meta.getInstance().addListener(
33
+ this.__changeThemeLayoutItemListenerId = qx.theme.manager.Meta.getInstance().addListener(
34
34
  "changeTheme",
35
35
  this._onChangeTheme,
36
36
  this
@@ -933,11 +933,9 @@ qx.Class.define("qx.ui.core.LayoutItem", {
933
933
 
934
934
  destruct() {
935
935
  // remove dynamic theme listener
936
- if (qx.core.Environment.get("qx.dyntheme")) {
937
- qx.theme.manager.Meta.getInstance().removeListener(
938
- "changeTheme",
939
- this._onChangeTheme,
940
- this
936
+ if (qx.core.Environment.get("qx.dyntheme") && this.__changeThemeLayoutItemListenerId) {
937
+ qx.theme.manager.Meta.getInstance().removeListenerById(
938
+ this.__changeThemeLayoutItemListenerId
941
939
  );
942
940
  }
943
941
  this.$$parent =
@@ -203,6 +203,8 @@ qx.Mixin.define("qx.ui.core.MPlacement", {
203
203
  __ptwLiveUpdater: null,
204
204
  __ptwLiveDisappearListener: null,
205
205
  __ptwLiveUpdateDisappearListener: null,
206
+ /**@type {Record<"top" | "right" | "bottom" | "left", number> | null}*/
207
+ __lastKnownCoords: null,
206
208
 
207
209
  /**
208
210
  * Returns the location data like {qx.bom.element.Location#get} does,
@@ -378,6 +380,15 @@ qx.Mixin.define("qx.ui.core.MPlacement", {
378
380
  target.getContentLocation() || this.getLayoutLocation(target);
379
381
 
380
382
  if (coords != null) {
383
+ if (
384
+ coords.top === this.__lastKnownCoords?.top &&
385
+ coords.right === this.__lastKnownCoords?.right &&
386
+ coords.bottom === this.__lastKnownCoords?.bottom &&
387
+ coords.left === this.__lastKnownCoords?.left
388
+ ) {
389
+ return true;
390
+ }
391
+ this.__lastKnownCoords = coords;
381
392
  this._place(coords);
382
393
  return true;
383
394
  } else {
@@ -2128,11 +2128,13 @@ qx.Class.define("qx.ui.core.Widget", {
2128
2128
  }, // property apply
2129
2129
  _applyVisibility(value, old) {
2130
2130
  var content = this.getContentElement();
2131
- if (value === "visible") {
2132
- content.show();
2133
- } else {
2134
- content.hide();
2135
- } // only force a layout update if visibility change from/to "exclude"
2131
+ if (content) {
2132
+ if (value === "visible") {
2133
+ content.show();
2134
+ } else {
2135
+ content.hide();
2136
+ } // only force a layout update if visibility change from/to "exclude"
2137
+ }
2136
2138
  var parent = this.$$parent;
2137
2139
  if (
2138
2140
  parent &&
@@ -144,7 +144,7 @@ qx.Class.define("qx.ui.form.AbstractField", {
144
144
 
145
145
  // translation support
146
146
  if (qx.core.Environment.get("qx.dynlocale")) {
147
- qx.locale.Manager.getInstance().addListener(
147
+ this.__changeLocaleAbstractFieldListenerId = qx.locale.Manager.getInstance().addListener(
148
148
  "changeLocale",
149
149
  this._onChangeLocale,
150
150
  this
@@ -1074,11 +1074,9 @@ qx.Class.define("qx.ui.form.AbstractField", {
1074
1074
 
1075
1075
  this._placeholder = this.__font = null;
1076
1076
 
1077
- if (qx.core.Environment.get("qx.dynlocale")) {
1078
- qx.locale.Manager.getInstance().removeListener(
1079
- "changeLocale",
1080
- this._onChangeLocale,
1081
- this
1077
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleAbstractFieldListenerId) {
1078
+ qx.locale.Manager.getInstance().removeListenerById(
1079
+ this.__changeLocaleAbstractFieldListenerId
1082
1080
  );
1083
1081
  }
1084
1082
 
@@ -22,7 +22,7 @@
22
22
  qx.Mixin.define("qx.ui.form.MForm", {
23
23
  construct() {
24
24
  if (qx.core.Environment.get("qx.dynlocale")) {
25
- qx.locale.Manager.getInstance().addListener(
25
+ this.__changeLocaleMFormListenerId = qx.locale.Manager.getInstance().addListener(
26
26
  "changeLocale",
27
27
  this.__onChangeLocale,
28
28
  this
@@ -103,11 +103,9 @@ qx.Mixin.define("qx.ui.form.MForm", {
103
103
  },
104
104
 
105
105
  destruct() {
106
- if (qx.core.Environment.get("qx.dynlocale")) {
107
- qx.locale.Manager.getInstance().removeListener(
108
- "changeLocale",
109
- this.__onChangeLocale,
110
- this
106
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleMFormListenerId) {
107
+ qx.locale.Manager.getInstance().removeListenerById(
108
+ this.__changeLocaleMFormListenerId
111
109
  );
112
110
  }
113
111
  }
@@ -87,7 +87,7 @@ qx.Class.define("qx.ui.form.Spinner", {
87
87
  this.addListener("roll", this._onRoll, this);
88
88
 
89
89
  if (qx.core.Environment.get("qx.dynlocale")) {
90
- qx.locale.Manager.getInstance().addListener(
90
+ this.__changeLocaleSpinnerListenerId = qx.locale.Manager.getInstance().addListener(
91
91
  "changeLocale",
92
92
  this._onChangeLocale,
93
93
  this
@@ -800,11 +800,9 @@ qx.Class.define("qx.ui.form.Spinner", {
800
800
  nf.removeListener("changeNumberFormat", this._onChangeNumberFormat, this);
801
801
  }
802
802
 
803
- if (qx.core.Environment.get("qx.dynlocale")) {
804
- qx.locale.Manager.getInstance().removeListener(
805
- "changeLocale",
806
- this._onChangeLocale,
807
- this
803
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleSpinnerListenerId) {
804
+ qx.locale.Manager.getInstance().removeListenerById(
805
+ this.__changeLocaleSpinnerListenerId
808
806
  );
809
807
  }
810
808
  }
@@ -38,7 +38,7 @@ qx.Class.define("qx.ui.form.renderer.AbstractRenderer", {
38
38
 
39
39
  // translation support
40
40
  if (qx.core.Environment.get("qx.dynlocale")) {
41
- qx.locale.Manager.getInstance().addListener(
41
+ this.__changeLocaleRendererListenerId = qx.locale.Manager.getInstance().addListener(
42
42
  "changeLocale",
43
43
  this._onChangeLocale,
44
44
  this
@@ -190,11 +190,9 @@ qx.Class.define("qx.ui.form.renderer.AbstractRenderer", {
190
190
  */
191
191
 
192
192
  destruct() {
193
- if (qx.core.Environment.get("qx.dynlocale")) {
194
- qx.locale.Manager.getInstance().removeListener(
195
- "changeLocale",
196
- this._onChangeLocale,
197
- this
193
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleRendererListenerId) {
194
+ qx.locale.Manager.getInstance().removeListenerById(
195
+ this.__changeLocaleRendererListenerId
198
196
  );
199
197
  }
200
198
  this._names = null;
@@ -265,17 +265,15 @@ qx.Class.define("qx.ui.menu.AbstractButton", {
265
265
  if (qx.core.Environment.get("qx.dynlocale")) {
266
266
  var oldCommand = e.getOldData();
267
267
  if (!oldCommand) {
268
- qx.locale.Manager.getInstance().addListener(
268
+ this.__changeLocaleCommandListenerId = qx.locale.Manager.getInstance().addListener(
269
269
  "changeLocale",
270
270
  this._onChangeLocale,
271
271
  this
272
272
  );
273
273
  }
274
- if (!command) {
275
- qx.locale.Manager.getInstance().removeListener(
276
- "changeLocale",
277
- this._onChangeLocale,
278
- this
274
+ if (!command && this.__changeLocaleCommandListenerId) {
275
+ qx.locale.Manager.getInstance().removeListenerById(
276
+ this.__changeLocaleCommandListenerId
279
277
  );
280
278
  }
281
279
  }
@@ -397,11 +395,9 @@ qx.Class.define("qx.ui.menu.AbstractButton", {
397
395
  }
398
396
  }
399
397
 
400
- if (qx.core.Environment.get("qx.dynlocale")) {
401
- qx.locale.Manager.getInstance().removeListener(
402
- "changeLocale",
403
- this._onChangeLocale,
404
- this
398
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleCommandListenerId) {
399
+ qx.locale.Manager.getInstance().removeListenerById(
400
+ this.__changeLocaleCommandListenerId
405
401
  );
406
402
  }
407
403
  }
@@ -51,7 +51,7 @@ qx.Class.define("qx.ui.mobile.basic.Label", {
51
51
  this.initWrap();
52
52
 
53
53
  if (qx.core.Environment.get("qx.dynlocale")) {
54
- qx.locale.Manager.getInstance().addListener(
54
+ this.__changeLocaleLabelListenerId = qx.locale.Manager.getInstance().addListener(
55
55
  "changeLocale",
56
56
  this._onChangeLocale,
57
57
  this
@@ -145,11 +145,9 @@ qx.Class.define("qx.ui.mobile.basic.Label", {
145
145
  */
146
146
 
147
147
  destruct() {
148
- if (qx.core.Environment.get("qx.dynlocale")) {
149
- qx.locale.Manager.getInstance().removeListener(
150
- "changeLocale",
151
- this._onChangeLocale,
152
- this
148
+ if (qx.core.Environment.get("qx.dynlocale") && this.__changeLocaleLabelListenerId) {
149
+ qx.locale.Manager.getInstance().removeListenerById(
150
+ this.__changeLocaleLabelListenerId
153
151
  );
154
152
  }
155
153
  }