@qooxdoo/framework 7.5.0 → 7.6.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 (120) hide show
  1. package/Manifest.json +169 -44
  2. package/bin/deploy/qx +7 -5
  3. package/lib/compiler/compile-info.json +70 -62
  4. package/lib/compiler/index.js +3809 -2695
  5. package/lib/resource/qx/tool/cli/templates/skeleton/desktop/source/class/custom/Application.tmpl.js +7 -7
  6. package/lib/resource/qx/tool/cli/templates/skeleton/desktop/source/class/custom/test/DemoTest.tmpl.js +10 -10
  7. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/class/custom/Application.tmpl.js +6 -6
  8. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/class/custom/page/Login.tmpl.js +9 -9
  9. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/class/custom/page/Overview.tmpl.js +5 -5
  10. package/lib/resource/qx/tool/cli/templates/skeleton/package/source/class/custom/demo/Application.tmpl.js +7 -7
  11. package/lib/resource/qx/tool/cli/templates/skeleton/package/source/class/custom/test/DemoTest.tmpl.js +10 -10
  12. package/lib/resource/qx/tool/cli/templates/skeleton/server/source/class/custom/Application.tmpl.js +6 -6
  13. package/lib/resource/qx/tool/cli/templates/skeleton/server/source/class/custom/test/DemoTest.tmpl.js +12 -12
  14. package/lib/resource/qx/tool/schema/Manifest-1-0-0.json +79 -26
  15. package/lib/resource/qx/tool/schema/Manifest-2-0-0.json +17 -26
  16. package/lib/resource/qx/tool/schema/compile-1-0-0.json +40 -53
  17. package/lib/resource/qx/tool/website/src/about.md +1 -1
  18. package/package.json +3 -3
  19. package/source/class/qx/bom/Font.js +36 -0
  20. package/source/class/qx/bom/webfonts/Validator.js +31 -6
  21. package/source/class/qx/bom/webfonts/WebFont.js +60 -64
  22. package/source/class/qx/bom/webfonts/WebFontLoader.js +461 -0
  23. package/source/class/qx/core/Object.js +1 -1
  24. package/source/class/qx/data/Array.js +27 -0
  25. package/source/class/qx/dev/FakeServer.js +1 -1
  26. package/source/class/qx/event/handler/Focus.js +2 -1
  27. package/source/class/qx/event/handler/GestureCore.js +1 -1
  28. package/source/class/qx/test/bom/webfonts/Validator.js +0 -6
  29. package/source/class/qx/test/core/Environment.js +8 -8
  30. package/source/class/qx/test/core/Validation.js +2 -2
  31. package/source/class/qx/test/dev/unit/Requirements.js +6 -6
  32. package/source/class/qx/test/io/transport/Websocket.js +1 -1
  33. package/source/class/qx/test/ui/basic/Image.js +3 -3
  34. package/source/class/qx/test/ui/basic/Label.js +0 -65
  35. package/source/class/qx/test/ui/form/Field.js +56 -52
  36. package/source/class/qx/theme/IndigoDark.js +1 -1
  37. package/source/class/qx/theme/classic/Font.js +7 -23
  38. package/source/class/qx/theme/iconfont/LoadMaterialIcons.js +2 -4
  39. package/source/class/qx/theme/iconfont/LoadMaterialIconsOutlined.js +2 -4
  40. package/source/class/qx/theme/iconfont/LoadMaterialIconsRound.js +2 -4
  41. package/source/class/qx/theme/iconfont/LoadMaterialIconsSharp.js +2 -4
  42. package/source/class/qx/theme/iconfont/LoadMaterialIconsTwoTone.js +2 -4
  43. package/source/class/qx/theme/indigo/DecorationDark.js +30 -0
  44. package/source/class/qx/theme/indigo/Font.js +8 -15
  45. package/source/class/qx/theme/manager/Font.js +151 -38
  46. package/source/class/qx/theme/modern/Font.js +1 -0
  47. package/source/class/qx/theme/simple/Font.js +3 -1
  48. package/source/class/qx/theme/tangible/Appearance.js +1 -0
  49. package/source/class/qx/theme/tangible/Font.js +9 -62
  50. package/source/class/qx/theme/tangible/Image.js +1 -4
  51. package/source/class/qx/tool/cli/Application.js +4 -1
  52. package/source/class/qx/tool/cli/Cli.js +34 -23
  53. package/source/class/qx/tool/cli/Watch.js +8 -6
  54. package/source/class/qx/tool/cli/api/CompilerApi.js +8 -0
  55. package/source/class/qx/tool/cli/commands/Add.js +1 -1
  56. package/source/class/qx/tool/cli/commands/Compile.js +24 -1
  57. package/source/class/qx/tool/cli/commands/Config.js +16 -141
  58. package/source/class/qx/tool/cli/commands/ExportGlyphs.js +134 -0
  59. package/source/class/qx/tool/cli/commands/Lint.js +1 -1
  60. package/source/class/qx/tool/cli/commands/Package.js +3 -0
  61. package/source/class/qx/tool/cli/commands/Pkg.js +1 -1
  62. package/source/class/qx/tool/cli/commands/Run.js +6 -7
  63. package/source/class/qx/tool/cli/commands/Serve.js +29 -36
  64. package/source/class/qx/tool/cli/commands/Test.js +3 -2
  65. package/source/class/qx/tool/cli/commands/add/Script.js +3 -1
  66. package/source/class/qx/tool/cli/commands/config/Delete.js +47 -0
  67. package/source/class/qx/tool/cli/commands/config/Get.js +52 -0
  68. package/source/class/qx/tool/cli/commands/config/List.js +81 -0
  69. package/source/class/qx/tool/cli/commands/config/Set.js +61 -0
  70. package/source/class/qx/tool/cli/commands/package/Install.js +3 -0
  71. package/source/class/qx/tool/cli/commands/package/Update.js +3 -3
  72. package/source/class/qx/tool/compiler/Analyser.js +45 -0
  73. package/source/class/qx/tool/compiler/ClassFile.js +43 -1
  74. package/source/class/qx/tool/compiler/Console.js +6 -1
  75. package/source/class/qx/tool/compiler/app/Application.js +19 -0
  76. package/source/class/qx/tool/compiler/app/Cldr.js +63 -26
  77. package/source/class/qx/tool/compiler/app/Library.js +51 -2
  78. package/source/class/qx/tool/compiler/app/ManifestFont.js +181 -0
  79. package/source/class/qx/tool/compiler/app/WebFont.js +144 -234
  80. package/source/class/qx/tool/compiler/makers/AppMaker.js +13 -0
  81. package/source/class/qx/tool/compiler/resources/ImageLoader.js +22 -12
  82. package/source/class/qx/tool/compiler/resources/Manager.js +2 -2
  83. package/source/class/qx/tool/compiler/resources/MetaLoader.js +7 -2
  84. package/source/class/qx/tool/compiler/resources/ResourceLoader.js +21 -0
  85. package/source/class/qx/tool/compiler/targets/Target.js +186 -67
  86. package/source/class/qx/tool/migration/M7_5_6.js +75 -0
  87. package/source/class/qx/tool/utils/Http.js +69 -0
  88. package/source/class/qx/ui/basic/Image.js +6 -2
  89. package/source/class/qx/ui/basic/Label.js +20 -38
  90. package/source/class/qx/ui/core/Widget.js +13 -42
  91. package/source/class/qx/ui/form/AbstractField.js +8 -2
  92. package/source/class/qx/ui/form/FileSelectorButton.js +5 -0
  93. package/source/class/qx/ui/table/pane/FocusIndicator.js +5 -4
  94. package/source/class/qx/ui/table/pane/Pane.js +14 -0
  95. package/source/class/qx/ui/table/pane/Scroller.js +3 -3
  96. package/source/class/qx/ui/virtual/core/Scroller.js +8 -2
  97. package/source/class/qx/ui/window/Window.js +9 -8
  98. package/source/resource/qx/iconfont/MaterialIcons/materialicons.json +10912 -0
  99. package/source/resource/qx/iconfont/MaterialIcons/materialiconsoutlined.json +10967 -0
  100. package/source/resource/qx/iconfont/MaterialIcons/materialiconsround.json +10992 -0
  101. package/source/resource/qx/iconfont/MaterialIcons/materialiconssharp.json +10992 -0
  102. package/source/resource/qx/iconfont/MaterialIcons/materialiconstwotone.json +9947 -0
  103. package/source/resource/qx/iconfont/MaterialIcons/x.json +10967 -0
  104. package/source/resource/qx/iconfont/export-glyphs.sh +22 -0
  105. package/source/resource/qx/mobile/scss/common/_gradients.scss +1 -1
  106. package/source/resource/qx/tool/cli/templates/skeleton/desktop/source/class/custom/Application.tmpl.js +7 -7
  107. package/source/resource/qx/tool/cli/templates/skeleton/desktop/source/class/custom/test/DemoTest.tmpl.js +10 -10
  108. package/source/resource/qx/tool/cli/templates/skeleton/mobile/source/class/custom/Application.tmpl.js +6 -6
  109. package/source/resource/qx/tool/cli/templates/skeleton/mobile/source/class/custom/page/Login.tmpl.js +9 -9
  110. package/source/resource/qx/tool/cli/templates/skeleton/mobile/source/class/custom/page/Overview.tmpl.js +5 -5
  111. package/source/resource/qx/tool/cli/templates/skeleton/package/source/class/custom/demo/Application.tmpl.js +7 -7
  112. package/source/resource/qx/tool/cli/templates/skeleton/package/source/class/custom/test/DemoTest.tmpl.js +10 -10
  113. package/source/resource/qx/tool/cli/templates/skeleton/server/source/class/custom/Application.tmpl.js +6 -6
  114. package/source/resource/qx/tool/cli/templates/skeleton/server/source/class/custom/test/DemoTest.tmpl.js +12 -12
  115. package/source/resource/qx/tool/schema/Manifest-1-0-0.json +79 -26
  116. package/source/resource/qx/tool/schema/Manifest-2-0-0.json +17 -26
  117. package/source/resource/qx/tool/schema/compile-1-0-0.json +40 -53
  118. package/source/resource/qx/tool/website/src/about.md +1 -1
  119. package/source/class/qx/bom/webfonts/Manager.js +0 -652
  120. package/source/class/qx/test/bom/webfonts/Manager.js +0 -238
@@ -0,0 +1,52 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2017 Christian Boulanger
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
+
14
+ Authors:
15
+ * Christian Boulanger (info@bibliograph.org, @cboulanger)
16
+ * Henner Kollmann (Henner.Kollmann@gmx.de, @hkollmann)
17
+
18
+ ************************************************************************ */
19
+ qx.Class.define("qx.tool.cli.commands.config.Get", {
20
+ extend: qx.tool.cli.commands.Config,
21
+ statics: {
22
+ /**
23
+ * Returns the yargs command data
24
+ * @return {Object}
25
+ */
26
+ getYargsCommand() {
27
+ return {
28
+ command: "get <key> [options]",
29
+ describe: "Gets a configuration value"
30
+ };
31
+ }
32
+ },
33
+
34
+ members: {
35
+ /**
36
+ * Lists library packages compatible with the current project
37
+ */
38
+ async process() {
39
+ await super.process();
40
+ this._checkKey(this.argv);
41
+ let cfg = await qx.tool.cli.ConfigDb.getInstance();
42
+ let value = cfg.db(this.argv.key);
43
+ if (this.argv.bare) {
44
+ qx.tool.compiler.Console.info(value || "");
45
+ } else if (value !== undefined) {
46
+ qx.tool.compiler.Console.info(this.argv.key + "=" + value);
47
+ } else {
48
+ qx.tool.compiler.Console.info(this.argv.key + " is not set");
49
+ }
50
+ }
51
+ }
52
+ });
@@ -0,0 +1,81 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2017 Christian Boulanger
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
+
14
+ Authors:
15
+ * Christian Boulanger (info@bibliograph.org, @cboulanger)
16
+ * Henner Kollmann (Henner.Kollmann@gmx.de, @hkollmann)
17
+
18
+ ************************************************************************ */
19
+ const columnify = require("columnify");
20
+
21
+ /**
22
+ * Lists compatible packages
23
+ */
24
+ qx.Class.define("qx.tool.cli.commands.config.List", {
25
+ extend: qx.tool.cli.commands.Config,
26
+ statics: {
27
+ /**
28
+ * Returns the yargs command data
29
+ * @return {Object}
30
+ */
31
+ getYargsCommand() {
32
+ return {
33
+ command: "list",
34
+ describe: "Lists all known configuration values",
35
+ builder: {
36
+ all: {
37
+ type: "boolean",
38
+ describe: "Shows all keys, including unset"
39
+ }
40
+ }
41
+ };
42
+ }
43
+ },
44
+
45
+ members: {
46
+ async process() {
47
+ await super.process();
48
+ let cfg = await qx.tool.cli.ConfigDb.getInstance();
49
+
50
+ let keys = {};
51
+ function scan(obj, parentKey) {
52
+ for (let [key, value] of Object.entries(obj)) {
53
+ let fullKey = parentKey + (parentKey.length ? "." : "") + key;
54
+ if (qx.tool.utils.Utils.isPlainObject(value)) {
55
+ scan(value, fullKey);
56
+ continue;
57
+ }
58
+ keys[fullKey] = true;
59
+ }
60
+ }
61
+ if (this.argv.all) {
62
+ for (let key in qx.tool.cli.commands.Config.KNOWN_VALUES) {
63
+ keys[key] = true;
64
+ }
65
+ }
66
+
67
+ // Recursively get a list of all known keys
68
+ scan(cfg.db(), "");
69
+ keys = Object.keys(keys);
70
+ keys.sort();
71
+ keys = keys.map(key => ({
72
+ key: key,
73
+ value: cfg.db(key),
74
+ description: this._describe(key) || "Unrecognised key"
75
+ }));
76
+
77
+ // Display each value
78
+ qx.tool.compiler.Console.info(columnify(keys));
79
+ }
80
+ }
81
+ });
@@ -0,0 +1,61 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2017 Christian Boulanger
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
+
14
+ Authors:
15
+ * Christian Boulanger (info@bibliograph.org, @cboulanger)
16
+ * Henner Kollmann (Henner.Kollmann@gmx.de, @hkollmann)
17
+
18
+ ************************************************************************ */
19
+ qx.Class.define("qx.tool.cli.commands.config.Set", {
20
+ extend: qx.tool.cli.commands.Config,
21
+ statics: {
22
+ /**
23
+ * Returns the yargs command data
24
+ * @return {Object}
25
+ */
26
+ getYargsCommand() {
27
+ return {
28
+ command: "set <key> <value>",
29
+ describe: "Sets a configuration value",
30
+ builder: {
31
+ all: {
32
+ type: "boolean",
33
+ describe: "Shows all keys, including unset"
34
+ }
35
+ }
36
+ };
37
+ }
38
+ },
39
+
40
+ members: {
41
+ async process() {
42
+ await super.process();
43
+ this._checkKey(this.argv);
44
+ let cfg = await qx.tool.cli.ConfigDb.getInstance();
45
+ let setting = qx.tool.cli.commands.Config.KNOWN_VALUES[this.argv.key];
46
+ let value = this.argv.value;
47
+ if (setting && typeof setting.set == "function") {
48
+ value = await setting.set(value);
49
+ }
50
+
51
+ let keyInfo = this._breakout(this.argv.key);
52
+ let parent = cfg.db(keyInfo.parentKey, {});
53
+ if (value === undefined) {
54
+ delete parent[keyInfo.childKey];
55
+ } else {
56
+ parent[keyInfo.childKey] = value;
57
+ }
58
+ await cfg.save();
59
+ }
60
+ }
61
+ });
@@ -677,6 +677,9 @@ qx.Class.define("qx.tool.cli.commands.package.Install", {
677
677
 
678
678
  return false;
679
679
  }
680
+ // relaod config. We need a fresh model here because data will be verified.
681
+ // The original model is enriched during parsing so validate will fail.
682
+ compileConfigModel.setLoaded(false);
680
683
  await compileConfigModel.load();
681
684
  let app = compileConfigModel.getValue("applications").find(app => {
682
685
  if (manifestApp.name && app.name) {
@@ -325,10 +325,10 @@ qx.Class.define("qx.tool.cli.commands.package.Update", {
325
325
  }
326
326
 
327
327
  // create a list of libraries via their manifests
328
- for (let [index, { path: manifest_path }] of manifests.entries()) {
328
+ for (let [index, manifest] of manifests.entries()) {
329
329
  let manifest_data;
330
- manifest_path = path.join(
331
- manifest_path,
330
+ const manifest_path = path.join(
331
+ manifest.path,
332
332
  qx.tool.config.Manifest.config.fileName
333
333
  );
334
334
 
@@ -61,6 +61,7 @@ qx.Class.define("qx.tool.compiler.Analyser", {
61
61
  this.__translations = {};
62
62
  this.__classFiles = {};
63
63
  this.__environmentChecks = {};
64
+ this.__fonts = {};
64
65
  },
65
66
 
66
67
  properties: {
@@ -194,6 +195,9 @@ qx.Class.define("qx.tool.compiler.Analyser", {
194
195
  __cldrs: null,
195
196
  __translations: null,
196
197
 
198
+ /** @type{qx.tool.compiler.app.ManifestFont[]} list of fonts in provides.fonts */
199
+ __fonts: null,
200
+
197
201
  __classFiles: null,
198
202
  __environmentChecks: null,
199
203
  __inDefer: false,
@@ -1415,6 +1419,47 @@ qx.Class.define("qx.tool.compiler.Analyser", {
1415
1419
  this.__librariesByNamespace[library.getNamespace()] = library;
1416
1420
  },
1417
1421
 
1422
+ /**
1423
+ * Returns a font by name
1424
+ *
1425
+ * @param {String} name
1426
+ * @param {Boolean?} create whether to create the font if it does not exist (default is false)
1427
+ * @returns {qx.tool.app.ManifestFont?} null if it does not exist and `create` is falsey
1428
+ */
1429
+ getFont(name, create) {
1430
+ let font = this.__fonts[name] || null;
1431
+ if (!font && create) {
1432
+ font = this.__fonts[name] = new qx.tool.compiler.app.ManifestFont(name);
1433
+ }
1434
+ return font;
1435
+ },
1436
+
1437
+ /**
1438
+ * Detects whether the filename is one of the fonts
1439
+ *
1440
+ * @param {String} filename
1441
+ * @returns {Boolean} whether the filename is a font asset
1442
+ */
1443
+ isFontAsset(filename) {
1444
+ let isFont = false;
1445
+ if (filename.endsWith("svg")) {
1446
+ for (let fontName in this.__fonts) {
1447
+ let font = this.__fonts[fontName];
1448
+ let sources = font.getSources() || [];
1449
+ isFont = sources.find(source => source == filename);
1450
+ }
1451
+ }
1452
+ return isFont;
1453
+ },
1454
+ /**
1455
+ * Returns the map of all fonts, indexed by name
1456
+ *
1457
+ * @returns {Map<String,qx.tool.app.ManifestFont>}
1458
+ */
1459
+ getFonts() {
1460
+ return this.__fonts;
1461
+ },
1462
+
1418
1463
  /**
1419
1464
  * Adds a required class to be analysed by analyseClasses()
1420
1465
  *
@@ -208,6 +208,7 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
208
208
  };
209
209
 
210
210
  this.__requiredAssets = [];
211
+ this.__requiredFonts = {};
211
212
  this.__translations = [];
212
213
  this.__markers = [];
213
214
  this.__haveMarkersFor = {};
@@ -256,6 +257,10 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
256
257
  __requiredClasses: null,
257
258
  __environmentChecks: null,
258
259
  __requiredAssets: null,
260
+
261
+ /** @type{Map<String,Object>} list of fonts indexed by name; the value is an object with `name` and `loc` */
262
+ __requiredFonts: null,
263
+
259
264
  __translateMessageIds: null,
260
265
  __scope: null,
261
266
  __inDefer: false,
@@ -631,6 +636,22 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
631
636
  if (assets.length) {
632
637
  dbClassInfo.assets = assets;
633
638
  }
639
+
640
+ // Fonts
641
+ var fontNames = Object.keys(this.__requiredFonts);
642
+ if (fontNames.length) {
643
+ dbClassInfo.fonts = fontNames;
644
+ for (let fontName in this.__requiredFonts) {
645
+ if (!this.__analyser.getFont(fontName)) {
646
+ t.addMarker(
647
+ "fonts.unresolved#" + fontName,
648
+ this.__requiredFonts[fontName].loc.start,
649
+ fontName
650
+ );
651
+ }
652
+ }
653
+ }
654
+
634
655
  if (meta) {
635
656
  if (meta.aliases) {
636
657
  dbClassInfo.aliases = {};
@@ -754,6 +775,11 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
754
775
  t._requireAsset(elem.body);
755
776
  });
756
777
  }
778
+ if (jsdoc["@usefont"]) {
779
+ jsdoc["@usefont"].forEach(function (elem) {
780
+ t._requireFont(elem.body, loc);
781
+ });
782
+ }
757
783
  return jsdoc;
758
784
  }
759
785
 
@@ -854,12 +880,16 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
854
880
  if (sectionName === "members" || sectionName === "statics") {
855
881
  if (
856
882
  node.type == "ObjectMethod" ||
857
- node.value.type === "FunctionExpression"
883
+ node.value.type === "FunctionExpression" ||
884
+ node.value.type === "MemberExpression"
858
885
  ) {
859
886
  meta.type = "function";
860
887
  } else {
861
888
  meta.type = "variable";
862
889
  }
890
+ if (node.async) {
891
+ meta.async = true;
892
+ }
863
893
  if (functionName.startsWith("__")) {
864
894
  meta.access = "private";
865
895
  } else if (functionName.startsWith("_")) {
@@ -2895,6 +2925,18 @@ qx.Class.define("qx.tool.compiler.ClassFile", {
2895
2925
  return this.__requiredAssets;
2896
2926
  },
2897
2927
 
2928
+ /**
2929
+ * Adds a required font
2930
+ * @param {String} name name of the font
2931
+ * @param {Location} the Babel location
2932
+ */
2933
+ _requireFont(name, loc) {
2934
+ this.__requiredFonts[name] = {
2935
+ name,
2936
+ loc
2937
+ };
2938
+ },
2939
+
2898
2940
  /**
2899
2941
  * Finds an object property in a node tree (not a Qooxdoo property, an
2900
2942
  * object property)
@@ -267,7 +267,12 @@ qx.Class.define("qx.tool.compiler.Console", {
267
267
  /* eslint-enable no-template-curly-in-string */
268
268
 
269
269
  "qx.tool.compiler.maker.appNotHeadless":
270
- "Compiling application '%1' but the target supports non-headless output, you may find unwanted dependencies are loaded during startup"
270
+ "Compiling application '%1' but the target supports non-headless output, you may find unwanted dependencies are loaded during startup",
271
+
272
+ // Fonts
273
+ "qx.tool.compiler.webfonts.deprecated":
274
+ "Manifest uses deprecated provides.webfonts, consider switching to provides.font",
275
+ "qx.tool.compiler.fonts.unresolved": "Cannot find font with name %1"
271
276
  },
272
277
 
273
278
  "warning"
@@ -833,6 +833,25 @@ qx.Class.define("qx.tool.compiler.app.Application", {
833
833
  return assets;
834
834
  },
835
835
 
836
+ /**
837
+ * Returns a list of fonts required by the application, where the font is detailed in Manifest.json
838
+ * in `provides.fonts`
839
+ *
840
+ * @returns {String[]}
841
+ */
842
+ getFonts() {
843
+ var fonts = {};
844
+ var analyser = this.getAnalyser();
845
+ var db = analyser.getDatabase();
846
+ this.__loadDeps.forEach(classname => {
847
+ var classInfo = db.classInfo[classname];
848
+ if (classInfo.fonts) {
849
+ classInfo.fonts.forEach(fontName => (fonts[fontName] = true));
850
+ }
851
+ });
852
+ return Object.keys(fonts);
853
+ },
854
+
836
855
  /**
837
856
  * Returns the class name for the application
838
857
  * @returns {String}
@@ -28,7 +28,9 @@ var path = require("path");
28
28
  var xml2js = require("xml2js");
29
29
  const CLDR = require("cldr");
30
30
  const { promisify } = require("util");
31
+ const process = require("process");
31
32
  const readFile = promisify(fs.readFile);
33
+ const readDir = promisify(fs.readdir);
32
34
 
33
35
  var log = qx.tool.utils.LogManager.createLog("cldr");
34
36
 
@@ -59,9 +61,39 @@ qx.Class.define("qx.tool.compiler.app.Cldr", {
59
61
  }
60
62
  log.debug("Loading CLDR " + cldrPath);
61
63
 
62
- return readFile(path.join(cldrPath, data_path, locale + ".xml"), {
63
- encoding: "utf-8"
64
- })
64
+ const fullDir = path.join(cldrPath, data_path);
65
+
66
+ return readDir(fullDir)
67
+ .then(
68
+ names =>
69
+ new Promise((resolve, reject) => {
70
+ const searchedName = locale.toLowerCase() + ".xml";
71
+ const realName = names.find(
72
+ name => name.toLowerCase() === searchedName
73
+ );
74
+
75
+ if (realName) {
76
+ resolve(realName);
77
+ } else {
78
+ reject(
79
+ new Error(
80
+ 'Cannot find XML file for locale "' +
81
+ locale +
82
+ '" in CLDR folder'
83
+ )
84
+ );
85
+ }
86
+ })
87
+ )
88
+ .then(fileName =>
89
+ readFile(path.join(fullDir, fileName), {
90
+ encoding: "utf-8"
91
+ })
92
+ )
93
+ .catch(err => {
94
+ qx.tool.compiler.Console.error(err);
95
+ process.exit(1);
96
+ })
65
97
  .then(data =>
66
98
  qx.tool.utils.Utils.promisifyThis(parser.parseString, parser, data)
67
99
  )
@@ -564,30 +596,35 @@ qx.Class.define("qx.tool.compiler.app.Cldr", {
564
596
  });
565
597
 
566
598
  var monthContext = get("months[0].monthContext", cal);
567
- find(monthContext, "type", "format", function (row) {
568
- find(row.monthWidth, "type", "abbreviated", function (row) {
569
- for (var i = 0; i < row.month.length; i++) {
570
- var m = row.month[i];
571
- cldr["cldr_month_format_abbreviated_" + m["$"].type] =
572
- getText(m);
573
- }
574
- });
575
- });
576
- find(monthContext, "type", "format", function (row) {
577
- find(row.monthWidth, "type", "wide", function (row) {
578
- for (var i = 0; i < row.month.length; i++) {
579
- var m = row.month[i];
580
- cldr["cldr_month_format_wide_" + m["$"].type] = getText(m);
581
- }
582
- });
583
- });
584
- find(monthContext, "type", "stand-alone", function (row) {
585
- for (var i = 0; i < row.monthWidth[0].month.length; i++) {
586
- var m = row.monthWidth[0].month[i];
587
- cldr["cldr_month_stand-alone_narrow_" + m["$"].type] =
588
- getText(m);
599
+
600
+ const parseMonth = (months, cldrProperty) => {
601
+ if (!months) {
602
+ return;
589
603
  }
590
- });
604
+ months.forEach(month => {
605
+ cldr[cldrProperty + "_" + month["$"].type] = getText(month);
606
+ });
607
+ };
608
+
609
+ const parseMonthContext = sectionNameInLocaleFile => {
610
+ find(monthContext, "type", "format", row =>
611
+ find(row.monthWidth, "type", sectionNameInLocaleFile, row =>
612
+ parseMonth(
613
+ row.month,
614
+ "cldr_month_format_" + sectionNameInLocaleFile
615
+ )
616
+ )
617
+ );
618
+ };
619
+
620
+ parseMonthContext("abbreviated");
621
+ parseMonthContext("wide");
622
+ find(monthContext, "type", "stand-alone", row =>
623
+ parseMonth(
624
+ row.monthWidth[0].month,
625
+ "cldr_month_stand-alone_narrow"
626
+ )
627
+ );
591
628
 
592
629
  function getTimeFormatPattern(row) {
593
630
  return row.timeFormat.pattern;
@@ -93,7 +93,10 @@ qx.Class.define("qx.tool.compiler.app.Library", {
93
93
  check: "String"
94
94
  },
95
95
 
96
- /** {WebFont[]} List of webfonts provided */
96
+ /**
97
+ * {WebFont[]} List of webfonts provided
98
+ * @deprecated
99
+ */
97
100
  webFonts: {
98
101
  init: null,
99
102
  nullable: true,
@@ -121,6 +124,7 @@ qx.Class.define("qx.tool.compiler.app.Library", {
121
124
  __sourceFileExtensions: null,
122
125
  __promiseLoadManifest: null,
123
126
  __environmentChecks: null,
127
+ __fontsData: null,
124
128
 
125
129
  /**
126
130
  * Transform for rootDir; converts it to an absolute path
@@ -238,13 +242,19 @@ qx.Class.define("qx.tool.compiler.app.Library", {
238
242
  this.setTranslationPath(data.provides.translation);
239
243
  }
240
244
  if (data.provides.webfonts) {
241
- var fonts = [];
245
+ let fonts = [];
246
+ if (data.provides.webfonts.length) {
247
+ qx.tool.compiler.Console.print(
248
+ "qx.tool.compiler.webfonts.deprecated"
249
+ );
250
+ }
242
251
  data.provides.webfonts.forEach(wf => {
243
252
  var font = new qx.tool.compiler.app.WebFont(this).set(wf);
244
253
  fonts.push(font);
245
254
  });
246
255
  this.setWebFonts(fonts);
247
256
  }
257
+ this.__fontsData = data.provides.fonts || {};
248
258
  if (data.externalResources) {
249
259
  if (data.externalResources.script) {
250
260
  this.setAddScript(data.externalResources.script);
@@ -264,6 +274,15 @@ qx.Class.define("qx.tool.compiler.app.Library", {
264
274
  }
265
275
  },
266
276
 
277
+ /**
278
+ * Returns the provides.fonts data from the manifest
279
+ *
280
+ * @returns {Array}
281
+ */
282
+ getFontsData() {
283
+ return this.__fontsData;
284
+ },
285
+
267
286
  /**
268
287
  * Scans the filing system looking for classes; there are occasions (ie Qooxdoo's qxWeb module)
269
288
  * where the class name does not comply with the namespace, this method is used to find those
@@ -366,6 +385,36 @@ qx.Class.define("qx.tool.compiler.app.Library", {
366
385
  });
367
386
  },
368
387
 
388
+ /**
389
+ * Detects whether the filename is one of the library's fonts
390
+ *
391
+ * @param {String} filename
392
+ * @returns {Boolean}
393
+ */
394
+ isFontAsset(filename) {
395
+ let isWebFont = false;
396
+ if (filename.endsWith("svg")) {
397
+ let fonts = this.getWebFonts() || [];
398
+ isWebFont = fonts.find(webFont =>
399
+ webFont.getResources().find(resource => resource == filename)
400
+ );
401
+
402
+ if (!isWebFont) {
403
+ for (let fontId in this.__fontsData) {
404
+ let fontData = this.__fontsData[fontId];
405
+ isWebFont = (fontData.fontFaces || []).find(fontFace =>
406
+ (fontFace.paths || []).find(resource => resource == filename)
407
+ );
408
+
409
+ if (isWebFont) {
410
+ break;
411
+ }
412
+ }
413
+ }
414
+ }
415
+ return isWebFont;
416
+ },
417
+
369
418
  /**
370
419
  * Detects the type of a symbol, "class", "resource", "package", "environment", or null if not found
371
420
  *