@qooxdoo/framework 7.9.1 → 7.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Manifest.json +1 -1
- package/lib/compiler/compile-info.json +54 -54
- package/lib/compiler/index.js +249 -216
- package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -1
- package/package.json +2 -2
- package/source/class/qx/locale/Manager.js +13 -0
- package/source/class/qx/test/compiler/ClassFile.js +13 -0
- package/source/class/qx/test/theme/manager/Color.js +23 -15
- package/source/class/qx/test/theme/manager/Decoration.js +23 -15
- package/source/class/qx/test/theme/manager/Font.js +23 -15
- package/source/class/qx/test/theme/manager/Icon.js +23 -15
- package/source/class/qx/test/theme/manager/Meta.js +26 -15
- package/source/class/qx/test/ui/basic/Label.js +106 -0
- package/source/class/qx/test/ui/core/Blocker.js +121 -0
- package/source/class/qx/test/ui/tree/virtual/Tree.js +36 -0
- package/source/class/qx/test/util/DateFormat.js +1 -1
- package/source/class/qx/theme/classic/Appearance.js +21 -0
- package/source/class/qx/theme/indigo/ColorDark.js +2 -0
- package/source/class/qx/theme/modern/Appearance.js +21 -0
- package/source/class/qx/theme/simple/Appearance.js +27 -5
- package/source/class/qx/theme/tangible/Appearance.js +2 -0
- package/source/class/qx/tool/compiler/ClassFile.js +18 -6
- package/source/class/qx/tool/compiler/resources/Asset.js +1 -1
- package/source/class/qx/tool/compiler/targets/meta/PackageJavascript.js +6 -2
- package/source/class/qx/ui/core/Blocker.js +16 -3
- package/source/class/qx/ui/core/MExecutable.js +14 -12
- package/source/class/qx/ui/form/validation/Manager.js +1 -1
- package/source/class/qx/ui/mobile/dialog/Popup.js +13 -1
- package/source/class/qx/ui/table/Table.js +5 -4
- package/source/class/qx/ui/table/pane/Scroller.js +6 -8
- package/source/class/qx/ui/tree/VirtualTree.js +4 -1
- package/source/class/qx/util/format/DateFormat.js +3 -2
- package/source/resource/qx/decoration/Modern/table/boolean-false.png +0 -0
- package/source/resource/qx/decoration/Modern/table/boolean-true.png +0 -0
|
@@ -235,6 +235,127 @@ qx.Class.define("qx.test.ui.core.Blocker", {
|
|
|
235
235
|
|
|
236
236
|
txt.destroy();
|
|
237
237
|
this.flush();
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
testBlockContent() {
|
|
241
|
+
// Create a container widget with specific position
|
|
242
|
+
var container = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
|
|
243
|
+
this.getRoot().add(container, { left: 100, top: 50 });
|
|
244
|
+
container.setWidth(200);
|
|
245
|
+
container.setHeight(150);
|
|
246
|
+
this.flush();
|
|
247
|
+
|
|
248
|
+
// Create blocker for the container
|
|
249
|
+
var blocker = new qx.ui.core.Blocker(container);
|
|
250
|
+
var blockerElement = blocker.getBlockerElement();
|
|
251
|
+
|
|
252
|
+
// Block content
|
|
253
|
+
blocker.blockContent(10);
|
|
254
|
+
this.flush();
|
|
255
|
+
|
|
256
|
+
this.assertTrue(blocker.isBlocked(), "blocker should be blocked");
|
|
257
|
+
this.assertTrue(blockerElement.isIncluded(), "blocker element should be included");
|
|
258
|
+
|
|
259
|
+
// Verify blocker dimensions match container
|
|
260
|
+
var styles = blockerElement.getAllStyles();
|
|
261
|
+
this.assertEquals("200px", styles.width, "blocker width should match container width");
|
|
262
|
+
this.assertEquals("150px", styles.height, "blocker height should match container height");
|
|
263
|
+
|
|
264
|
+
// Verify blocker position is 0,0 (relative to container, not layout parent)
|
|
265
|
+
// This is the fix for issue #10411
|
|
266
|
+
this.assertEquals("0px", styles.left, "blocker left should be 0 when blocking content");
|
|
267
|
+
this.assertEquals("0px", styles.top, "blocker top should be 0 when blocking content");
|
|
268
|
+
|
|
269
|
+
// Cleanup
|
|
270
|
+
blocker.unblock();
|
|
271
|
+
blocker.dispose();
|
|
272
|
+
container.destroy();
|
|
273
|
+
this.flush();
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
testBlockContentPositioning() {
|
|
277
|
+
// Create a container at a non-zero position
|
|
278
|
+
var container = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
|
|
279
|
+
this.getRoot().add(container, { left: 150, top: 100 });
|
|
280
|
+
container.setWidth(300);
|
|
281
|
+
container.setHeight(200);
|
|
282
|
+
this.flush();
|
|
283
|
+
|
|
284
|
+
var blocker = new qx.ui.core.Blocker(container);
|
|
285
|
+
var blockerElement = blocker.getBlockerElement();
|
|
286
|
+
|
|
287
|
+
// Block the content
|
|
288
|
+
blocker.blockContent(5);
|
|
289
|
+
this.flush();
|
|
290
|
+
|
|
291
|
+
var styles = blockerElement.getAllStyles();
|
|
292
|
+
|
|
293
|
+
// The blocker should be positioned at 0,0 relative to the container
|
|
294
|
+
// NOT at the container's position (150, 100)
|
|
295
|
+
this.assertEquals("0px", styles.left, "blocker should be at left: 0");
|
|
296
|
+
this.assertEquals("0px", styles.top, "blocker should be at top: 0");
|
|
297
|
+
this.assertEquals("300px", styles.width, "blocker width should match container");
|
|
298
|
+
this.assertEquals("200px", styles.height, "blocker height should match container");
|
|
299
|
+
|
|
300
|
+
// Cleanup
|
|
301
|
+
blocker.unblock();
|
|
302
|
+
blocker.dispose();
|
|
303
|
+
container.destroy();
|
|
304
|
+
this.flush();
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
testNormalBlockVsBlockContent() {
|
|
308
|
+
// Create two containers to compare normal block vs blockContent
|
|
309
|
+
var container1 = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
|
|
310
|
+
var container2 = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
|
|
311
|
+
|
|
312
|
+
this.getRoot().add(container1, { left: 50, top: 50 });
|
|
313
|
+
this.getRoot().add(container2, { left: 300, top: 50 });
|
|
314
|
+
|
|
315
|
+
container1.setWidth(100);
|
|
316
|
+
container1.setHeight(100);
|
|
317
|
+
container2.setWidth(100);
|
|
318
|
+
container2.setHeight(100);
|
|
319
|
+
|
|
320
|
+
this.flush();
|
|
321
|
+
|
|
322
|
+
var blocker1 = new qx.ui.core.Blocker(container1);
|
|
323
|
+
var blocker2 = new qx.ui.core.Blocker(container2);
|
|
324
|
+
|
|
325
|
+
// Normal block - blocker is added to layout parent
|
|
326
|
+
blocker1.block();
|
|
327
|
+
this.flush();
|
|
328
|
+
|
|
329
|
+
var styles1 = blocker1.getBlockerElement().getAllStyles();
|
|
330
|
+
|
|
331
|
+
// BlockContent - blocker is added to the widget itself
|
|
332
|
+
blocker2.blockContent(5);
|
|
333
|
+
this.flush();
|
|
334
|
+
|
|
335
|
+
var styles2 = blocker2.getBlockerElement().getAllStyles();
|
|
336
|
+
|
|
337
|
+
// Normal block: blocker positioned at container's position in layout parent
|
|
338
|
+
this.assertEquals("50px", styles1.left, "normal block uses container's left position");
|
|
339
|
+
this.assertEquals("50px", styles1.top, "normal block uses container's top position");
|
|
340
|
+
|
|
341
|
+
// BlockContent: blocker positioned at 0,0 relative to container
|
|
342
|
+
this.assertEquals("0px", styles2.left, "blockContent uses 0 for left position");
|
|
343
|
+
this.assertEquals("0px", styles2.top, "blockContent uses 0 for top position");
|
|
344
|
+
|
|
345
|
+
// Both should have same dimensions as their containers
|
|
346
|
+
this.assertEquals("100px", styles1.width);
|
|
347
|
+
this.assertEquals("100px", styles1.height);
|
|
348
|
+
this.assertEquals("100px", styles2.width);
|
|
349
|
+
this.assertEquals("100px", styles2.height);
|
|
350
|
+
|
|
351
|
+
// Cleanup
|
|
352
|
+
blocker1.unblock();
|
|
353
|
+
blocker2.unblock();
|
|
354
|
+
blocker1.dispose();
|
|
355
|
+
blocker2.dispose();
|
|
356
|
+
container1.destroy();
|
|
357
|
+
container2.destroy();
|
|
358
|
+
this.flush();
|
|
238
359
|
}
|
|
239
360
|
}
|
|
240
361
|
});
|
|
@@ -260,6 +260,42 @@ qx.Class.define("qx.test.ui.tree.virtual.Tree", {
|
|
|
260
260
|
this.__testBuildLookupTable(expected);
|
|
261
261
|
},
|
|
262
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Test for issue #9390: VirtualTree doesn't render if hideRoot is true
|
|
265
|
+
* when adding nodes dynamically
|
|
266
|
+
*/
|
|
267
|
+
testDynamicNodesWithHiddenRoot() {
|
|
268
|
+
// Create initial model
|
|
269
|
+
var root = this.createModelAndSetModel(1);
|
|
270
|
+
|
|
271
|
+
// Set hideRoot before adding nodes
|
|
272
|
+
this.tree.setHideRoot(true);
|
|
273
|
+
|
|
274
|
+
// Flush to ensure initial rendering
|
|
275
|
+
this.flush();
|
|
276
|
+
|
|
277
|
+
// Get initial visible items (should be root's children)
|
|
278
|
+
var expectedBefore = this.getVisibleItemsFrom(root, [root]);
|
|
279
|
+
this.__testBuildLookupTable(expectedBefore);
|
|
280
|
+
|
|
281
|
+
// Dynamically add a new branch to the root
|
|
282
|
+
var newBranch = new qx.test.ui.tree.virtual.Node("Dynamic Branch");
|
|
283
|
+
this._createNodes(newBranch, 1);
|
|
284
|
+
root.getChildren().push(newBranch);
|
|
285
|
+
|
|
286
|
+
// The tree should automatically update without calling refresh()
|
|
287
|
+
// Expected items should now include the new branch
|
|
288
|
+
var expectedAfter = this.getVisibleItemsFrom(root, [root]);
|
|
289
|
+
this.__testBuildLookupTable(expectedAfter);
|
|
290
|
+
|
|
291
|
+
// Verify the new branch is in the lookup table
|
|
292
|
+
var lookupTable = this.tree.getLookupTable();
|
|
293
|
+
this.assertTrue(
|
|
294
|
+
lookupTable.contains(newBranch),
|
|
295
|
+
"New dynamically added branch should be visible in tree with hidden root"
|
|
296
|
+
);
|
|
297
|
+
},
|
|
298
|
+
|
|
263
299
|
testBuildLookupWithoutLeafs() {
|
|
264
300
|
var root = this.createModelAndSetModel(2);
|
|
265
301
|
|
|
@@ -969,7 +969,7 @@ qx.Class.define("qx.test.util.DateFormat", {
|
|
|
969
969
|
var timezoneOffset = date.getTimezoneOffset();
|
|
970
970
|
var timezoneSign = timezoneOffset > 0 ? 1 : -1;
|
|
971
971
|
var timezoneHours = Math.floor(Math.abs(timezoneOffset) / 60);
|
|
972
|
-
var timezoneMinutes = Math.abs(timezoneOffset) % 60;
|
|
972
|
+
var timezoneMinutes = Math.trunc(Math.abs(timezoneOffset)) % 60;
|
|
973
973
|
|
|
974
974
|
var localTimeZone =
|
|
975
975
|
"GMT" +
|
|
@@ -1465,6 +1465,27 @@ qx.Theme.define("qx.theme.classic.Appearance", {
|
|
|
1465
1465
|
}
|
|
1466
1466
|
},
|
|
1467
1467
|
|
|
1468
|
+
"selectbox-arrow-button": "widget",
|
|
1469
|
+
|
|
1470
|
+
/*
|
|
1471
|
+
---------------------------------------------------------------------------
|
|
1472
|
+
CHECKED SELECT BOX
|
|
1473
|
+
---------------------------------------------------------------------------
|
|
1474
|
+
*/
|
|
1475
|
+
|
|
1476
|
+
"checked-selectbox": "selectbox",
|
|
1477
|
+
|
|
1478
|
+
"checked-selectbox/allNone": {
|
|
1479
|
+
include: "button"
|
|
1480
|
+
},
|
|
1481
|
+
|
|
1482
|
+
"checked-selectbox/tag": "tag",
|
|
1483
|
+
|
|
1484
|
+
tag: {
|
|
1485
|
+
alias: "button",
|
|
1486
|
+
include: "button"
|
|
1487
|
+
},
|
|
1488
|
+
|
|
1468
1489
|
/*
|
|
1469
1490
|
---------------------------------------------------------------------------
|
|
1470
1491
|
DATE CHOOSER
|
|
@@ -28,6 +28,8 @@ qx.Theme.define("qx.theme.indigo.ColorDark", {
|
|
|
28
28
|
"highlight-shade": "#dddddd",
|
|
29
29
|
|
|
30
30
|
// backgrounds
|
|
31
|
+
"datechooser-background-selected-dark": "#333",
|
|
32
|
+
"datechooser-background": "#666",
|
|
31
33
|
"background-selected": "#666666",
|
|
32
34
|
"background-selected-disabled": "#777777",
|
|
33
35
|
"background-selected-dark": "#333333",
|
|
@@ -1728,6 +1728,27 @@ qx.Theme.define("qx.theme.modern.Appearance", {
|
|
|
1728
1728
|
}
|
|
1729
1729
|
},
|
|
1730
1730
|
|
|
1731
|
+
"selectbox-arrow-button": "widget",
|
|
1732
|
+
|
|
1733
|
+
/*
|
|
1734
|
+
---------------------------------------------------------------------------
|
|
1735
|
+
CHECKED SELECT BOX
|
|
1736
|
+
---------------------------------------------------------------------------
|
|
1737
|
+
*/
|
|
1738
|
+
|
|
1739
|
+
"checked-selectbox": "selectbox",
|
|
1740
|
+
|
|
1741
|
+
"checked-selectbox/allNone": {
|
|
1742
|
+
include: "button"
|
|
1743
|
+
},
|
|
1744
|
+
|
|
1745
|
+
"checked-selectbox/tag": "tag",
|
|
1746
|
+
|
|
1747
|
+
tag: {
|
|
1748
|
+
alias: "button",
|
|
1749
|
+
include: "button"
|
|
1750
|
+
},
|
|
1751
|
+
|
|
1731
1752
|
/*
|
|
1732
1753
|
---------------------------------------------------------------------------
|
|
1733
1754
|
DATE CHOOSER
|
|
@@ -1238,6 +1238,27 @@ qx.Theme.define("qx.theme.simple.Appearance", {
|
|
|
1238
1238
|
}
|
|
1239
1239
|
},
|
|
1240
1240
|
|
|
1241
|
+
"selectbox-arrow-button": "widget",
|
|
1242
|
+
|
|
1243
|
+
/*
|
|
1244
|
+
---------------------------------------------------------------------------
|
|
1245
|
+
CHECKED SELECT BOX
|
|
1246
|
+
---------------------------------------------------------------------------
|
|
1247
|
+
*/
|
|
1248
|
+
|
|
1249
|
+
"checked-selectbox": "selectbox",
|
|
1250
|
+
|
|
1251
|
+
"checked-selectbox/allNone": {
|
|
1252
|
+
include: "button"
|
|
1253
|
+
},
|
|
1254
|
+
|
|
1255
|
+
"checked-selectbox/tag": "tag",
|
|
1256
|
+
|
|
1257
|
+
tag: {
|
|
1258
|
+
alias: "button",
|
|
1259
|
+
include: "button"
|
|
1260
|
+
},
|
|
1261
|
+
|
|
1241
1262
|
/*
|
|
1242
1263
|
---------------------------------------------------------------------------
|
|
1243
1264
|
COMBO BOX
|
|
@@ -1911,11 +1932,11 @@ qx.Theme.define("qx.theme.simple.Appearance", {
|
|
|
1911
1932
|
textColor: states.disabled
|
|
1912
1933
|
? "text-disabled"
|
|
1913
1934
|
: states.weekend
|
|
1914
|
-
? "background-selected-dark"
|
|
1915
|
-
: "background",
|
|
1935
|
+
? "datechooser-background-selected-dark"
|
|
1936
|
+
: "datechooser-background",
|
|
1916
1937
|
backgroundColor: states.weekend
|
|
1917
|
-
? "background"
|
|
1918
|
-
: "background-selected-dark",
|
|
1938
|
+
? "datechooser-background"
|
|
1939
|
+
: "datechooser-background-selected-dark",
|
|
1919
1940
|
paddingTop: 2
|
|
1920
1941
|
};
|
|
1921
1942
|
}
|
|
@@ -1947,7 +1968,8 @@ qx.Theme.define("qx.theme.simple.Appearance", {
|
|
|
1947
1968
|
style(states) {
|
|
1948
1969
|
return {
|
|
1949
1970
|
textAlign: "center",
|
|
1950
|
-
textColor: "background
|
|
1971
|
+
textColor: "datechooser-background",
|
|
1972
|
+
backgroundColor: "datechooser-background-selected-dark",
|
|
1951
1973
|
padding: [2, 4],
|
|
1952
1974
|
decorator: states.header
|
|
1953
1975
|
? "datechooser-week-header"
|
|
@@ -810,7 +810,13 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
810
810
|
} else if (param.type == "ArrayPattern") {
|
|
811
811
|
param.elements.forEach(elem => addDecl(elem));
|
|
812
812
|
} else if (param.type == "ObjectPattern") {
|
|
813
|
-
param.properties.forEach(prop =>
|
|
813
|
+
param.properties.forEach(prop => {
|
|
814
|
+
if (prop.type == "RestElement") {
|
|
815
|
+
addDecl(prop);
|
|
816
|
+
} else {
|
|
817
|
+
addDecl(prop.value);
|
|
818
|
+
}
|
|
819
|
+
});
|
|
814
820
|
} else {
|
|
815
821
|
t.addMarker("testForFunctionParameterType", node.loc, param.type);
|
|
816
822
|
}
|
|
@@ -1516,6 +1522,9 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1516
1522
|
});
|
|
1517
1523
|
}
|
|
1518
1524
|
path.traverse(VISITOR);
|
|
1525
|
+
} else if (keyName == "delegate") {
|
|
1526
|
+
path.skip();
|
|
1527
|
+
path.traverse(VISITOR);
|
|
1519
1528
|
} else if (keyName == "aliases") {
|
|
1520
1529
|
path.skip();
|
|
1521
1530
|
if (!prop.value.properties) {
|
|
@@ -1703,7 +1712,8 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
1703
1712
|
ClassDeclaration: 1,
|
|
1704
1713
|
ClassMethod: 1,
|
|
1705
1714
|
LabeledStatement: 1,
|
|
1706
|
-
BreakStatement: 1
|
|
1715
|
+
BreakStatement: 1,
|
|
1716
|
+
ContinueStatement: 1
|
|
1707
1717
|
};
|
|
1708
1718
|
|
|
1709
1719
|
// These are AST node types we expect to find at the root of the identifier, and which will
|
|
@@ -2149,7 +2159,7 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
2149
2159
|
t.addMarker(
|
|
2150
2160
|
"translate.invalidMessageId",
|
|
2151
2161
|
path.node.loc,
|
|
2152
|
-
arg0
|
|
2162
|
+
arg0 ?? ""
|
|
2153
2163
|
);
|
|
2154
2164
|
} else {
|
|
2155
2165
|
addTranslation({ msgid: arg0 });
|
|
@@ -2164,8 +2174,8 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
2164
2174
|
t.addMarker(
|
|
2165
2175
|
"translate.invalidMessageIds",
|
|
2166
2176
|
path.node.loc,
|
|
2167
|
-
arg0,
|
|
2168
|
-
arg1
|
|
2177
|
+
arg0 ?? "",
|
|
2178
|
+
arg1 ?? ""
|
|
2169
2179
|
);
|
|
2170
2180
|
} else {
|
|
2171
2181
|
addTranslation({ msgid: arg0, msgid_plural: arg1 });
|
|
@@ -2387,7 +2397,9 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
|
|
|
2387
2397
|
// Object destructuring `var {a,b} = {...}`
|
|
2388
2398
|
} else if (decl.id.type == "ObjectPattern") {
|
|
2389
2399
|
decl.id.properties.forEach(prop => {
|
|
2390
|
-
if (prop.
|
|
2400
|
+
if (prop.type == "RestElement") {
|
|
2401
|
+
t.addDeclaration(prop.argument.name);
|
|
2402
|
+
} else if (prop.value.type == "AssignmentPattern") {
|
|
2391
2403
|
t.addDeclaration(prop.value.left.name);
|
|
2392
2404
|
} else {
|
|
2393
2405
|
t.addDeclaration(prop.value.name);
|
|
@@ -85,12 +85,16 @@ qx.Class.define("qx.tool.compiler.targets.meta.PackageJavascript", {
|
|
|
85
85
|
|
|
86
86
|
if (pkg.isEmbedAllJavascript()) {
|
|
87
87
|
this.__sourceMapOffsets = [];
|
|
88
|
+
let packageWs = new qx.tool.utils.Utils.LineCountingTransform();
|
|
88
89
|
let strip = new qx.tool.utils.Utils.StripSourceMapTransform();
|
|
89
|
-
strip.pipe(
|
|
90
|
+
strip.pipe(packageWs);
|
|
91
|
+
packageWs.pipe(ws, {
|
|
92
|
+
end: false
|
|
93
|
+
});
|
|
90
94
|
await new Promise(async resolve => {
|
|
91
95
|
for (let i = 0; i < pkg.getJavascriptMetas().length; i++) {
|
|
92
96
|
let js = pkg.getJavascriptMetas()[i];
|
|
93
|
-
this.__sourceMapOffsets.push(
|
|
97
|
+
this.__sourceMapOffsets.push(packageWs.getLineNumber());
|
|
94
98
|
await js.unwrap().writeSourceCodeToStream(strip);
|
|
95
99
|
strip.write("\n");
|
|
96
100
|
}
|
|
@@ -132,6 +132,7 @@ qx.Class.define("qx.ui.core.Blocker", {
|
|
|
132
132
|
members: {
|
|
133
133
|
__blocker: null,
|
|
134
134
|
__blockerCount: 0,
|
|
135
|
+
__blockingContent: false,
|
|
135
136
|
|
|
136
137
|
__activeElements: null,
|
|
137
138
|
__focusElements: null,
|
|
@@ -186,11 +187,17 @@ qx.Class.define("qx.ui.core.Blocker", {
|
|
|
186
187
|
* @param bounds {Map} Map with the new width, height, left and top values
|
|
187
188
|
*/
|
|
188
189
|
_updateBlockerBounds(bounds) {
|
|
190
|
+
// When blocking content, the blocker is a child of the widget itself,
|
|
191
|
+
// so it should be positioned at 0,0 relative to the widget.
|
|
192
|
+
// Otherwise, it's positioned relative to the layout parent.
|
|
193
|
+
var left = this.__blockingContent ? 0 : bounds.left;
|
|
194
|
+
var top = this.__blockingContent ? 0 : bounds.top;
|
|
195
|
+
|
|
189
196
|
this.getBlockerElement().setStyles({
|
|
190
197
|
width: bounds.width + "px",
|
|
191
198
|
height: bounds.height + "px",
|
|
192
|
-
left:
|
|
193
|
-
top:
|
|
199
|
+
left: left + "px",
|
|
200
|
+
top: top + "px"
|
|
194
201
|
});
|
|
195
202
|
},
|
|
196
203
|
|
|
@@ -338,7 +345,7 @@ qx.Class.define("qx.ui.core.Blocker", {
|
|
|
338
345
|
if (!this.__appearListener) {
|
|
339
346
|
this.__appearListener = this._widget.addListenerOnce(
|
|
340
347
|
"appear",
|
|
341
|
-
this._block.bind(this, zIndex)
|
|
348
|
+
this._block.bind(this, zIndex, blockContent)
|
|
342
349
|
);
|
|
343
350
|
}
|
|
344
351
|
return;
|
|
@@ -358,6 +365,9 @@ qx.Class.define("qx.ui.core.Blocker", {
|
|
|
358
365
|
|
|
359
366
|
this.__blockerCount++;
|
|
360
367
|
if (this.__blockerCount < 2) {
|
|
368
|
+
// Track if we're blocking content (blocker is child of widget)
|
|
369
|
+
this.__blockingContent = blockContent === true;
|
|
370
|
+
|
|
361
371
|
this._backupActiveWidget();
|
|
362
372
|
|
|
363
373
|
var bounds = this._widget.getBounds();
|
|
@@ -442,6 +452,9 @@ qx.Class.define("qx.ui.core.Blocker", {
|
|
|
442
452
|
blocker.removeListener("keyup", this.__stopTabEvent, this);
|
|
443
453
|
blocker.exclude();
|
|
444
454
|
|
|
455
|
+
// Reset blocking content state
|
|
456
|
+
this.__blockingContent = false;
|
|
457
|
+
|
|
445
458
|
this.fireEvent("unblocked", qx.event.type.Event);
|
|
446
459
|
},
|
|
447
460
|
|
|
@@ -61,7 +61,11 @@ qx.Mixin.define("qx.ui.core.MExecutable", {
|
|
|
61
61
|
|
|
62
62
|
members: {
|
|
63
63
|
__executableBindingIds: null,
|
|
64
|
-
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @type {Boolean} Whether the command already executed. The protection flag to stop the second command execution.
|
|
67
|
+
*/
|
|
68
|
+
__commandExecuted: false,
|
|
65
69
|
__executeListenerId: null,
|
|
66
70
|
|
|
67
71
|
/**
|
|
@@ -83,10 +87,10 @@ qx.Mixin.define("qx.ui.core.MExecutable", {
|
|
|
83
87
|
var cmd = this.getCommand();
|
|
84
88
|
|
|
85
89
|
if (cmd) {
|
|
86
|
-
if (this.
|
|
87
|
-
this.
|
|
90
|
+
if (this.__commandExecuted) {
|
|
91
|
+
this.__commandExecuted = false;
|
|
88
92
|
} else {
|
|
89
|
-
this.
|
|
93
|
+
this.__commandExecuted = true;
|
|
90
94
|
cmd.execute(this);
|
|
91
95
|
}
|
|
92
96
|
}
|
|
@@ -100,15 +104,13 @@ qx.Mixin.define("qx.ui.core.MExecutable", {
|
|
|
100
104
|
* @param e {qx.event.type.Event} The execute event of the command.
|
|
101
105
|
*/
|
|
102
106
|
__onCommandExecute(e) {
|
|
107
|
+
if (this.__commandExecuted) {
|
|
108
|
+
this.__commandExecuted = false;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
this.__commandExecuted = true;
|
|
103
112
|
if (this.isEnabled()) {
|
|
104
|
-
|
|
105
|
-
this.__semaphore = false;
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
if (this.isEnabled()) {
|
|
109
|
-
this.__semaphore = true;
|
|
110
|
-
this.execute();
|
|
111
|
-
}
|
|
113
|
+
this.execute();
|
|
112
114
|
}
|
|
113
115
|
},
|
|
114
116
|
|
|
@@ -140,11 +140,16 @@ qx.Class.define("qx.ui.mobile.dialog.Popup", {
|
|
|
140
140
|
__widget: null,
|
|
141
141
|
__titleWidget: null,
|
|
142
142
|
__lastPopupDimension: null,
|
|
143
|
+
/**
|
|
144
|
+
* Flag which ignores event domupdated caused by this widget and stopps infinite recursive `_updatePosition` calls
|
|
145
|
+
*/
|
|
146
|
+
__updatePositionStarted: false,
|
|
143
147
|
|
|
144
148
|
/**
|
|
145
149
|
* Event handler. Called whenever the position of the popup should be updated.
|
|
146
150
|
*/
|
|
147
151
|
_updatePosition() {
|
|
152
|
+
this.__updatePositionStarted = true;
|
|
148
153
|
// Traverse single anchor classes for removal, for preventing 'domupdated' event if no CSS classes changed.
|
|
149
154
|
var anchorClasses = ["top", "bottom", "left", "right", "anchor"];
|
|
150
155
|
for (var i = 0; i < anchorClasses.length; i++) {
|
|
@@ -446,7 +451,14 @@ qx.Class.define("qx.ui.mobile.dialog.Popup", {
|
|
|
446
451
|
flex: 1
|
|
447
452
|
});
|
|
448
453
|
|
|
449
|
-
widget.addListener("domupdated",
|
|
454
|
+
widget.addListener("domupdated", () => {
|
|
455
|
+
if (!this.__updatePositionStarted){
|
|
456
|
+
this._updatePosition();
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
this.__updatePositionStarted = false;
|
|
460
|
+
}
|
|
461
|
+
}, this);
|
|
450
462
|
|
|
451
463
|
this.__widget = widget;
|
|
452
464
|
},
|
|
@@ -1570,10 +1570,11 @@ qx.Class.define("qx.ui.table.Table", {
|
|
|
1570
1570
|
* visible.
|
|
1571
1571
|
*/
|
|
1572
1572
|
setFocusedCell(col, row, scrollVisible) {
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1573
|
+
let cellChanged = col != this.__focusedCol || row != this.__focusedRow;
|
|
1574
|
+
if (this.isEditing() && cellChanged) {
|
|
1575
|
+
this.stopEditing();
|
|
1576
|
+
}
|
|
1577
|
+
if (!this.isEditing() && cellChanged) {
|
|
1577
1578
|
if (col === null) {
|
|
1578
1579
|
col = 0;
|
|
1579
1580
|
}
|
|
@@ -1973,16 +1973,14 @@ qx.Class.define("qx.ui.table.pane.Scroller", {
|
|
|
1973
1973
|
_onFocusinCellEditorAddBlurListener(e) {
|
|
1974
1974
|
this.debug("executed FOCUSIN event listener for hash: " + e.getTarget().$$hash);
|
|
1975
1975
|
qx.event.Timer.once(function() {
|
|
1976
|
-
this._cellEditor.
|
|
1977
|
-
this.debug('added
|
|
1976
|
+
this._cellEditor.addListener('focusout', this._onFocusoutCellEditorStopEditing, this);
|
|
1977
|
+
this.debug('added FOCUSOUT listener to hash: ' + this._cellEditor.$$hash);
|
|
1978
1978
|
}, this, 1);
|
|
1979
1979
|
},
|
|
1980
1980
|
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
_onBlurCellEditorStopEditing(e) {
|
|
1985
|
-
this.debug("executed BLUR listener for hash " + e.getTarget().$$hash);
|
|
1981
|
+
|
|
1982
|
+
_onFocusoutCellEditorStopEditing(e) {
|
|
1983
|
+
this.debug("executed FOCUSOUT listener for hash " + e.getTarget().$$hash);
|
|
1986
1984
|
if (this._cellEditor === e.getTarget()) {
|
|
1987
1985
|
this.debug('hash: ' + this._cellEditor.$$hash);
|
|
1988
1986
|
switch (this.getTable().getCellEditorBlurAction()) {
|
|
@@ -2408,4 +2406,4 @@ qx.Class.define("qx.ui.table.pane.Scroller", {
|
|
|
2408
2406
|
"__clipperContainer"
|
|
2409
2407
|
);
|
|
2410
2408
|
}
|
|
2411
|
-
});
|
|
2409
|
+
});
|
|
@@ -761,7 +761,10 @@ qx.Class.define("qx.ui.tree.VirtualTree", {
|
|
|
761
761
|
}
|
|
762
762
|
}
|
|
763
763
|
|
|
764
|
-
|
|
764
|
+
// Issue #9390: When hideRoot is true, the root is not in the lookup table,
|
|
765
|
+
// but we still need to update when its children change
|
|
766
|
+
var isRootAndHidden = this.isHideRoot() && item === this.getModel();
|
|
767
|
+
if (this.__lookupTable.indexOf(item) != -1 || isRootAndHidden) {
|
|
765
768
|
this.__applyModelChanges();
|
|
766
769
|
}
|
|
767
770
|
}
|
|
@@ -476,8 +476,9 @@ qx.Class.define("qx.util.format.DateFormat", {
|
|
|
476
476
|
|
|
477
477
|
var timezoneOffset = date.getTimezoneOffset();
|
|
478
478
|
var timezoneSign = timezoneOffset > 0 ? 1 : -1;
|
|
479
|
-
var
|
|
480
|
-
var
|
|
479
|
+
var absTimezoneOffset = Math.abs(timezoneOffset);
|
|
480
|
+
var timezoneHours = Math.floor(absTimezoneOffset / 60);
|
|
481
|
+
var timezoneMinutes = Math.trunc(absTimezoneOffset) % 60;
|
|
481
482
|
|
|
482
483
|
// Create the output
|
|
483
484
|
this.__initFormatTree();
|
|
Binary file
|
|
Binary file
|