@qooxdoo/framework 7.5.1 → 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 (85) hide show
  1. package/Manifest.json +169 -44
  2. package/lib/compiler/compile-info.json +76 -68
  3. package/lib/compiler/index.js +3683 -2588
  4. package/lib/resource/qx/tool/schema/Manifest-1-0-0.json +79 -26
  5. package/lib/resource/qx/tool/schema/Manifest-2-0-0.json +17 -26
  6. package/lib/resource/qx/tool/schema/compile-1-0-0.json +40 -53
  7. package/package.json +2 -2
  8. package/source/class/qx/bom/Font.js +36 -0
  9. package/source/class/qx/bom/webfonts/Validator.js +31 -6
  10. package/source/class/qx/bom/webfonts/WebFont.js +60 -64
  11. package/source/class/qx/bom/webfonts/WebFontLoader.js +461 -0
  12. package/source/class/qx/core/Object.js +1 -1
  13. package/source/class/qx/data/Array.js +27 -0
  14. package/source/class/qx/dev/FakeServer.js +1 -1
  15. package/source/class/qx/event/handler/Focus.js +2 -1
  16. package/source/class/qx/event/handler/GestureCore.js +1 -1
  17. package/source/class/qx/test/bom/webfonts/Validator.js +0 -6
  18. package/source/class/qx/test/core/Environment.js +8 -8
  19. package/source/class/qx/test/core/Validation.js +2 -2
  20. package/source/class/qx/test/dev/unit/Requirements.js +6 -6
  21. package/source/class/qx/test/ui/basic/Image.js +3 -3
  22. package/source/class/qx/test/ui/basic/Label.js +0 -65
  23. package/source/class/qx/test/ui/form/Field.js +56 -52
  24. package/source/class/qx/theme/classic/Font.js +7 -23
  25. package/source/class/qx/theme/iconfont/LoadMaterialIcons.js +2 -4
  26. package/source/class/qx/theme/iconfont/LoadMaterialIconsOutlined.js +2 -4
  27. package/source/class/qx/theme/iconfont/LoadMaterialIconsRound.js +2 -4
  28. package/source/class/qx/theme/iconfont/LoadMaterialIconsSharp.js +2 -4
  29. package/source/class/qx/theme/iconfont/LoadMaterialIconsTwoTone.js +2 -4
  30. package/source/class/qx/theme/indigo/Font.js +8 -15
  31. package/source/class/qx/theme/manager/Font.js +151 -38
  32. package/source/class/qx/theme/modern/Font.js +1 -0
  33. package/source/class/qx/theme/simple/Font.js +3 -1
  34. package/source/class/qx/theme/tangible/Appearance.js +1 -0
  35. package/source/class/qx/theme/tangible/Font.js +9 -62
  36. package/source/class/qx/theme/tangible/Image.js +1 -4
  37. package/source/class/qx/tool/cli/Cli.js +12 -0
  38. package/source/class/qx/tool/cli/Watch.js +3 -0
  39. package/source/class/qx/tool/cli/api/CompilerApi.js +8 -0
  40. package/source/class/qx/tool/cli/commands/Add.js +1 -1
  41. package/source/class/qx/tool/cli/commands/Compile.js +22 -0
  42. package/source/class/qx/tool/cli/commands/Config.js +16 -141
  43. package/source/class/qx/tool/cli/commands/ExportGlyphs.js +134 -0
  44. package/source/class/qx/tool/cli/commands/Package.js +3 -0
  45. package/source/class/qx/tool/cli/commands/Pkg.js +1 -1
  46. package/source/class/qx/tool/cli/commands/config/Delete.js +47 -0
  47. package/source/class/qx/tool/cli/commands/config/Get.js +52 -0
  48. package/source/class/qx/tool/cli/commands/config/List.js +81 -0
  49. package/source/class/qx/tool/cli/commands/config/Set.js +61 -0
  50. package/source/class/qx/tool/cli/commands/package/Update.js +3 -3
  51. package/source/class/qx/tool/compiler/Analyser.js +45 -0
  52. package/source/class/qx/tool/compiler/ClassFile.js +41 -0
  53. package/source/class/qx/tool/compiler/Console.js +6 -1
  54. package/source/class/qx/tool/compiler/app/Application.js +19 -0
  55. package/source/class/qx/tool/compiler/app/Library.js +51 -2
  56. package/source/class/qx/tool/compiler/app/ManifestFont.js +181 -0
  57. package/source/class/qx/tool/compiler/app/WebFont.js +144 -234
  58. package/source/class/qx/tool/compiler/makers/AppMaker.js +13 -0
  59. package/source/class/qx/tool/compiler/resources/ImageLoader.js +22 -12
  60. package/source/class/qx/tool/compiler/resources/Manager.js +2 -2
  61. package/source/class/qx/tool/compiler/resources/MetaLoader.js +7 -2
  62. package/source/class/qx/tool/compiler/resources/ResourceLoader.js +21 -0
  63. package/source/class/qx/tool/compiler/targets/Target.js +186 -67
  64. package/source/class/qx/tool/migration/M7_5_6.js +75 -0
  65. package/source/class/qx/tool/utils/Http.js +69 -0
  66. package/source/class/qx/ui/basic/Label.js +20 -38
  67. package/source/class/qx/ui/form/AbstractField.js +8 -2
  68. package/source/class/qx/ui/form/FileSelectorButton.js +5 -0
  69. package/source/class/qx/ui/table/pane/FocusIndicator.js +5 -4
  70. package/source/class/qx/ui/table/pane/Pane.js +14 -0
  71. package/source/class/qx/ui/table/pane/Scroller.js +3 -3
  72. package/source/class/qx/ui/virtual/core/Scroller.js +8 -2
  73. package/source/class/qx/ui/window/Window.js +9 -8
  74. package/source/resource/qx/iconfont/MaterialIcons/materialicons.json +10912 -0
  75. package/source/resource/qx/iconfont/MaterialIcons/materialiconsoutlined.json +10967 -0
  76. package/source/resource/qx/iconfont/MaterialIcons/materialiconsround.json +10992 -0
  77. package/source/resource/qx/iconfont/MaterialIcons/materialiconssharp.json +10992 -0
  78. package/source/resource/qx/iconfont/MaterialIcons/materialiconstwotone.json +9947 -0
  79. package/source/resource/qx/iconfont/MaterialIcons/x.json +10967 -0
  80. package/source/resource/qx/iconfont/export-glyphs.sh +22 -0
  81. package/source/resource/qx/tool/schema/Manifest-1-0-0.json +79 -26
  82. package/source/resource/qx/tool/schema/Manifest-2-0-0.json +17 -26
  83. package/source/resource/qx/tool/schema/compile-1-0-0.json +40 -53
  84. package/source/class/qx/bom/webfonts/Manager.js +0 -652
  85. package/source/class/qx/test/bom/webfonts/Manager.js +0 -238
@@ -53,6 +53,7 @@ qx.Class.define("qx.bom.webfonts.Validator", {
53
53
  this.setFontFamily(fontFamily);
54
54
  this.__requestedHelpers = this._getRequestedHelpers();
55
55
  }
56
+ this.__promiseValid = new qx.Promise();
56
57
  },
57
58
 
58
59
  /*
@@ -186,6 +187,7 @@ qx.Class.define("qx.bom.webfonts.Validator", {
186
187
  __requestedHelpers: null,
187
188
  __checkTimer: null,
188
189
  __checkStarted: null,
190
+ __promiseValid: null,
189
191
 
190
192
  /*
191
193
  ---------------------------------------------------------------------------
@@ -215,6 +217,15 @@ qx.Class.define("qx.bom.webfonts.Validator", {
215
217
  }
216
218
  },
217
219
 
220
+ /**
221
+ * Waits for the font to become invalid or valid
222
+ *
223
+ * @returns {Boolean} whether valid or not
224
+ */
225
+ async isValid() {
226
+ return await this.__promiseValid;
227
+ },
228
+
218
229
  /*
219
230
  ---------------------------------------------------------------------------
220
231
  PROTECTED API
@@ -380,17 +391,31 @@ qx.Class.define("qx.bom.webfonts.Validator", {
380
391
  */
381
392
  __onTimerInterval() {
382
393
  if (this._isFontValid()) {
383
- this.__checkTimer.stop();
384
- this._reset();
385
- this.fireDataEvent("changeStatus", {
386
- family: this.getFontFamily(),
387
- valid: true
388
- });
394
+ const setValidImpl = () => {
395
+ this.__checkTimer.stop();
396
+ this._reset();
397
+ this.__promiseValid.resolve(true);
398
+ this.fireDataEvent("changeStatus", {
399
+ family: this.getFontFamily(),
400
+ valid: true
401
+ });
402
+ };
403
+
404
+ // safari has trouble resizing, adding it again fixed the issue [BUG #8786]
405
+ if (
406
+ qx.core.Environment.get("browser.name") == "safari" &&
407
+ parseFloat(qx.core.Environment.get("browser.version")) >= 8
408
+ ) {
409
+ setTimeout(setValidImpl, 100);
410
+ } else {
411
+ setValidImpl();
412
+ }
389
413
  } else {
390
414
  var now = new Date().getTime();
391
415
  if (now - this.__checkStarted >= this.getTimeout()) {
392
416
  this.__checkTimer.stop();
393
417
  this._reset();
418
+ this.__promiseValid.resolve(false);
394
419
  this.fireDataEvent("changeStatus", {
395
420
  family: this.getFontFamily(),
396
421
  valid: false
@@ -14,7 +14,7 @@
14
14
  ************************************************************************ */
15
15
 
16
16
  /**
17
- * Requests web fonts from {@link qx.bom.webfonts.Manager} and fires events
17
+ * Requests web fonts via {@link qx.bom.webfonts.WebFontLoader} and fires events
18
18
  * when their loading status is known.
19
19
  */
20
20
  qx.Class.define("qx.bom.webfonts.WebFont", {
@@ -22,42 +22,35 @@ qx.Class.define("qx.bom.webfonts.WebFont", {
22
22
 
23
23
  /*
24
24
  *****************************************************************************
25
- EVENTS
25
+ PROPERTIES
26
26
  *****************************************************************************
27
27
  */
28
28
 
29
- events: {
29
+ properties: {
30
30
  /**
31
- * Fired when the status of a web font has been determined. The event data
32
- * is a map with the keys "family" (the font-family name) and "valid"
33
- * (Boolean).
31
+ * Indicates that the font has loaded successfully
34
32
  */
35
- changeStatus: "qx.event.type.Data"
33
+ valid: {
34
+ init: false,
35
+ check: "Boolean",
36
+ event: "changeValid",
37
+ apply: "__applyValid"
38
+ }
36
39
  },
37
40
 
38
41
  /*
39
42
  *****************************************************************************
40
- PROPERTIES
43
+ EVENTS
41
44
  *****************************************************************************
42
45
  */
43
46
 
44
- properties: {
45
- /**
46
- * The source of the webfont.
47
- */
48
- sources: {
49
- nullable: true,
50
- apply: "_applySources"
51
- },
52
-
47
+ events: {
53
48
  /**
54
- * Indicates that the font has loaded successfully
49
+ * Fired when the status of a web font has been determined. The event data
50
+ * is a map with the keys "family" (the font-family name) and "valid"
51
+ * (Boolean).
55
52
  */
56
- valid: {
57
- init: false,
58
- check: "Boolean",
59
- event: "changeValid"
60
- }
53
+ changeStatus: "qx.event.type.Data"
61
54
  },
62
55
 
63
56
  /*
@@ -68,56 +61,59 @@ qx.Class.define("qx.bom.webfonts.WebFont", {
68
61
 
69
62
  members: {
70
63
  __families: null,
71
-
72
- // property apply
73
- _applySources(value, old) {
74
- var families = [];
75
-
76
- for (var i = 0, l = value.length; i < l; i++) {
77
- var familyName = this._quoteFontFamily(value[i].family);
78
- families.push(familyName);
79
- var sourcesList = value[i];
80
- sourcesList.comparisonString = this.getComparisonString();
81
- sourcesList.version = this.getVersion();
82
- qx.bom.webfonts.Manager.getInstance().require(
83
- familyName,
84
- sourcesList,
85
- this._onWebFontChangeStatus,
86
- this
87
- );
88
- }
89
-
90
- this.setFamily(families.concat(this.getFamily()));
91
- },
64
+ __allValidPromise: null,
92
65
 
93
66
  /**
94
- * Propagates web font status changes
95
- *
96
- * @param ev {qx.event.type.Data} "changeStatus"
67
+ * @override
97
68
  */
98
- _onWebFontChangeStatus(ev) {
99
- var result = ev.getData();
100
- this.setValid(!!result.valid);
101
- this.fireDataEvent("changeStatus", result);
102
- if (qx.core.Environment.get("qx.debug")) {
103
- if (result.valid === false) {
104
- this.warn(
105
- "WebFont " +
106
- result.family +
107
- " was not applied, perhaps the source file could not be loaded."
69
+ loadComplete() {
70
+ let promises = [];
71
+ for (let fontFamily of this.getFamily()) {
72
+ let loader = qx.bom.webfonts.WebFontLoader.getLoader(fontFamily);
73
+ if (loader) {
74
+ let fontWeight = this.isBold() ? "bold" : "normal";
75
+ if (this.getWeight() !== null) {
76
+ fontWeight = this.getWeight();
77
+ }
78
+ let fontStyle = this.isItalic() ? "italic" : "normal";
79
+
80
+ let validator = new qx.bom.webfonts.Validator(
81
+ fontFamily,
82
+ this.getComparisonString(),
83
+ fontWeight,
84
+ fontStyle
108
85
  );
86
+
87
+ validator.setTimeout(qx.bom.webfonts.WebFont.VALIDATION_TIMEOUT);
88
+ validator.validate();
89
+ promises.push(validator.isValid());
109
90
  }
110
91
  }
92
+ this.__allValidPromise = qx.Promise.all(promises).then(results => {
93
+ if (results.length == 0 || results.indexOf(true) > -1) {
94
+ this.setValid(true);
95
+ } else {
96
+ this.setValid(false);
97
+ }
98
+ });
99
+ },
100
+
101
+ async checkValid() {
102
+ await this.__allValidPromise;
111
103
  },
112
104
 
105
+ __applyValid(value) {
106
+ this.fireDataEvent("changeStatus", {
107
+ family: this.getFamily(),
108
+ valid: value
109
+ });
110
+ }
111
+ },
112
+
113
+ statics: {
113
114
  /**
114
- * Makes sure font-family names containing spaces are properly quoted
115
- *
116
- * @param familyName {String} A font-family CSS value
117
- * @return {String} The quoted family name
115
+ * Timeout (in ms) to wait before deciding that a web font was not loaded.
118
116
  */
119
- _quoteFontFamily(familyName) {
120
- return familyName.replace(/["']/g, "");
121
- }
117
+ VALIDATION_TIMEOUT: 5000
122
118
  }
123
119
  });
@@ -0,0 +1,461 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2004-2011 1&1 Internet AG, Germany, http://www.1und1.de
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
+ ************************************************************************ */
15
+
16
+ /**
17
+ * Loads web fonts
18
+ */
19
+ qx.Class.define("qx.bom.webfonts.WebFontLoader", {
20
+ extend: qx.core.Object,
21
+
22
+ construct(fontFamily) {
23
+ super();
24
+ this.setFontFamily(fontFamily);
25
+ },
26
+
27
+ properties: {
28
+ /** The font name that this font is known by */
29
+ fontFamily: {
30
+ check: "String"
31
+ },
32
+
33
+ /** The fontFaces which need to be defined */
34
+ fontFaces: {
35
+ nullable: true,
36
+ apply: "_applyFontFaces"
37
+ },
38
+
39
+ /** CSS urls or paths which need to be loaded */
40
+ css: {
41
+ nullable: true,
42
+ check: "Array"
43
+ },
44
+
45
+ /**
46
+ * Characters that are used to test if the font has loaded properly. These
47
+ * default to "WEei" in `qx.bom.webfont.Validator` and can be overridden
48
+ * for certain cases like icon fonts that do not provide the predefined
49
+ * characters.
50
+ */
51
+ comparisonString: {
52
+ check: "String",
53
+ init: null,
54
+ nullable: true
55
+ },
56
+
57
+ /**
58
+ * Version identifier that is appended to the URL to be loaded. Fonts
59
+ * that are defined thru themes may be managed by the resource manager.
60
+ * In this case updated fonts persist due to aggressive fontface caching
61
+ * of some browsers. To get around this, set the `version` property to
62
+ * the version of your font. It will be appended to the CSS URL and forces
63
+ * the browser to re-validate.
64
+ *
65
+ * The version needs to be URL friendly, so only characters, numbers,
66
+ * dash and dots are allowed here.
67
+ */
68
+ version: {
69
+ check(value) {
70
+ return (
71
+ value === null ||
72
+ (typeof value === "string" && /^[a-zA-Z0-9.-]+$/.test(value))
73
+ );
74
+ },
75
+ init: null,
76
+ nullable: true
77
+ }
78
+ },
79
+
80
+ /*
81
+ *****************************************************************************
82
+ MEMBERS
83
+ *****************************************************************************
84
+ */
85
+
86
+ members: {
87
+ __fontFacesQueue: null,
88
+ __fontFacesCreatedPromise: null,
89
+
90
+ /**
91
+ * Called to load the font details into the browser
92
+ */
93
+ async load() {
94
+ (this.getCss() || []).forEach(url => {
95
+ if (!url.match(/^https?:/)) {
96
+ url = qx.util.ResourceManager.getInstance().toUri(url);
97
+ }
98
+ if (this.getVersion()) {
99
+ url += url.indexOf("?") < 0 ? "?" : "&";
100
+ url += this.getVersion();
101
+ }
102
+ qx.bom.webfonts.WebFontLoader.__loadStylesheet(url);
103
+ });
104
+ let fontFaces = this.getFontFaces();
105
+ if (fontFaces) {
106
+ fontFaces.forEach(fontFace => {
107
+ if (fontFace.paths) {
108
+ fontFace.paths = fontFace.paths.map(path => {
109
+ if (!path.match(/^https?:/)) {
110
+ path = qx.util.ResourceManager.getInstance().toUri(path);
111
+ }
112
+ if (this.getVersion()) {
113
+ path += path.indexOf("?") < 0 ? "?" : "&";
114
+ path += this.getVersion();
115
+ }
116
+ return path;
117
+ });
118
+ }
119
+ });
120
+ this.__fontFacesQueue = qx.lang.Array.clone(fontFaces);
121
+ this.__fontFacesCreatedPromise = new qx.Promise();
122
+ }
123
+ this.__dequeueFontFaces();
124
+ },
125
+
126
+ async promiseLoaded() {
127
+ return await this.__fontFacesCreatedPromise;
128
+ },
129
+
130
+ /**
131
+ * Adds the font faces in __fontFacesQueue
132
+ */
133
+ __dequeueFontFaces() {
134
+ if (this.__fontFacesQueue == null) {
135
+ return;
136
+ }
137
+ let fontFace = this.__fontFacesQueue.pop();
138
+
139
+ this.__addFontFace(fontFace);
140
+
141
+ if (this.__fontFacesQueue.length == 0) {
142
+ this.__fontFacesQueue = null;
143
+ this.__fontFacesCreatedPromise.resolve(true);
144
+ }
145
+
146
+ if (
147
+ qx.core.Environment.get("engine.name") == "mshtml" &&
148
+ (parseInt(qx.core.Environment.get("engine.version")) < 9 ||
149
+ qx.core.Environment.get("browser.documentmode") < 9)
150
+ ) {
151
+ // old IEs need a break in between adding @font-face rules
152
+ setTimeout(() => this.__dequeueFontFaces(), 100);
153
+ } else {
154
+ this.__dequeueFontFaces();
155
+ }
156
+ },
157
+
158
+ /**
159
+ * Adds a font face definition to the browser
160
+ *
161
+ * @param {*} fontFace - POJO of from the array in Manifest.json
162
+ * @returns
163
+ */
164
+ __addFontFace(fontFace) {
165
+ let fontFamily = fontFace.fontFamily || this.getFontFamily();
166
+ let fontLookupKey = qx.bom.webfonts.WebFontLoader.createFontLookupKey(
167
+ fontFamily,
168
+ fontFace.fontWeight || "normal",
169
+ fontFace.fontStyle || "normal"
170
+ );
171
+
172
+ if (qx.bom.webfonts.WebFontLoader.__addedFontFaces[fontLookupKey]) {
173
+ return;
174
+ }
175
+
176
+ if (!qx.bom.webfonts.WebFontLoader.__styleSheet) {
177
+ let styleSheet = qx.bom.Stylesheet.createElement();
178
+ qx.bom.webfonts.WebFontLoader.__styleSheet = styleSheet;
179
+ if (qx.core.Environment.get("qx.debug")) {
180
+ styleSheet.ownerNode.setAttribute(
181
+ "data-qx-created-by",
182
+ qx.bom.webfonts.WebFontLoader.classname
183
+ );
184
+ }
185
+ }
186
+
187
+ let sourcesMap = {};
188
+ const MATCH_FORMAT = new RegExp(
189
+ ".(" +
190
+ qx.bom.webfonts.WebFontLoader.getPreferredFormats().join("|") +
191
+ ")"
192
+ );
193
+
194
+ /*
195
+ * When compiling a `@font-face` rule, note that the first "src:" must never specify a format
196
+ * and that EOT must go first if there is one
197
+ */
198
+
199
+ let fontFaceSrcRules = [];
200
+ for (let i = 0; i < fontFace.paths.length; i++) {
201
+ let match = MATCH_FORMAT.exec(fontFace.paths[i]);
202
+ if (!match) {
203
+ continue;
204
+ }
205
+
206
+ let fontFormat = match[1];
207
+ let url = fontFace.paths[i];
208
+ if (this.getVersion()) {
209
+ url += "?" + this.getVersion();
210
+ }
211
+
212
+ fontFaceSrcRules.push({
213
+ url: url,
214
+ format: fontFormat
215
+ });
216
+
217
+ if (fontFormat == "eot") {
218
+ fontFaceSrcRules.push({
219
+ url: url + "?#iefix'",
220
+ format: "embedded-opentype"
221
+ });
222
+ }
223
+ }
224
+ fontFaceSrcRules = fontFaceSrcRules.sort((a, b) => {
225
+ a.fontFormat == "embedded-opentype" ? -1 : 0;
226
+ });
227
+
228
+ let strSources = "";
229
+ for (let i = 0; i < fontFaceSrcRules.length; i++) {
230
+ strSources += "src: url('" + fontFaceSrcRules[i].url + "')";
231
+ if (i > 0) {
232
+ strSources += " format('" + fontFaceSrcRules[i].format + "')";
233
+ }
234
+ strSources += ";";
235
+ }
236
+
237
+ let rule = "font-family: " + fontFamily + ";\n";
238
+ rule += strSources + "\n";
239
+ rule += "font-style: " + (fontFace.fontStyle || "normal") + ";\n";
240
+ rule += "font-weight: " + (fontFace.fontWeight || "normal") + ";\n";
241
+
242
+ rule = "@font-face {\n" + rule + "}\n";
243
+
244
+ let styleSheet = qx.bom.webfonts.WebFontLoader.__styleSheet;
245
+ try {
246
+ if (
247
+ qx.core.Environment.get("browser.name") == "ie" &&
248
+ qx.core.Environment.get("browser.documentmode") < 9
249
+ ) {
250
+ let cssText = qx.bom.webfonts.WebFontLoader.__fixCssText(
251
+ styleSheet.cssText
252
+ );
253
+
254
+ cssText += rule;
255
+ styleSheet.cssText = cssText;
256
+ } else {
257
+ styleSheet.insertRule(rule, styleSheet.cssRules.length);
258
+ }
259
+ } catch (ex) {
260
+ if (qx.core.Environment.get("qx.debug")) {
261
+ this.warn("Error while adding @font-face rule:", ex.message);
262
+ return;
263
+ }
264
+ }
265
+
266
+ qx.bom.webfonts.WebFontLoader.__addedFontFaces[fontLookupKey] = true;
267
+ },
268
+
269
+ // property apply
270
+ _applyFontFaces(fontFaces, old) {
271
+ var families = [];
272
+
273
+ for (var i = 0, l = fontFaces.length; i < l; i++) {
274
+ let fontFace = fontFaces[i];
275
+ var familyName = this._quoteFontFamily(
276
+ fontFace.family || this.getFontFamily()
277
+ );
278
+
279
+ if (families.indexOf(familyName) < 0) {
280
+ families.push(familyName);
281
+ }
282
+ }
283
+ },
284
+
285
+ /**
286
+ * Makes sure font-family names containing spaces are properly quoted
287
+ *
288
+ * @param familyName {String} A font-family CSS value
289
+ * @return {String} The quoted family name
290
+ */
291
+ _quoteFontFamily(familyName) {
292
+ return familyName.replace(/["']/g, "");
293
+ }
294
+ },
295
+
296
+ statics: {
297
+ /**
298
+ * List of known font definition formats (i.e. file extensions). Used to
299
+ * identify the type of each font file configured for a web font.
300
+ */
301
+ FONT_FORMATS: ["eot", "woff2", "woff", "ttf", "svg"],
302
+
303
+ /**
304
+ * Timeout (in ms) to wait before deciding that a web font was not loaded.
305
+ */
306
+ VALIDATION_TIMEOUT: 5000,
307
+
308
+ /** @type{String[]} array of supported font formats, most preferred first */
309
+ __preferredFormats: null,
310
+
311
+ /** */
312
+ __loadedStylesheets: {},
313
+ __addedFontFaces: {},
314
+
315
+ /** Loader instances indexed by font family name */
316
+ __loaders: {},
317
+
318
+ /**
319
+ * Gets/creates a loader
320
+ *
321
+ * @param {String} name font family name
322
+ * @param {Boolean?} create whether to create one if one does not exist (default to false)
323
+ * @returns
324
+ */
325
+ getLoader(name, create) {
326
+ let loader = qx.bom.webfonts.WebFontLoader.__loaders[name];
327
+ if (!loader && create) {
328
+ loader = qx.bom.webfonts.WebFontLoader.__loaders[name] =
329
+ new qx.bom.webfonts.WebFontLoader(name);
330
+ }
331
+ return loader;
332
+ },
333
+
334
+ /**
335
+ * Adds a stylesheet, once per url
336
+ *
337
+ * @param {String} url
338
+ */
339
+ __loadStylesheet(url) {
340
+ if (qx.bom.webfonts.WebFontLoader.__loadedStylesheets[url]) {
341
+ return;
342
+ }
343
+
344
+ qx.bom.Stylesheet.includeFile(url);
345
+ qx.bom.webfonts.WebFontLoader.__loadedStylesheets[url] = true;
346
+ },
347
+
348
+ /**
349
+ * Creates a lookup key to index the created fonts.
350
+ * @param familyName {String} font-family name
351
+ * @param fontWeight {String} the font-weight.
352
+ * @param fontStyle {String} the font-style.
353
+ * @return {string} the font lookup key
354
+ */
355
+ createFontLookupKey(familyName, fontWeight, fontStyle) {
356
+ var lookupKey =
357
+ familyName +
358
+ "_" +
359
+ (fontWeight ? fontWeight : "normal") +
360
+ "_" +
361
+ (fontStyle ? fontStyle : "normal");
362
+ return lookupKey;
363
+ },
364
+
365
+ /**
366
+ * Uses a naive regExp match to determine the format of each defined source
367
+ * file for a webFont. Returns a map with the format names as keys and the
368
+ * corresponding source URLs as values.
369
+ *
370
+ * @param sources {String[]} Array of source URLs
371
+ * @return {Map} Map of formats and URLs
372
+ */
373
+ __getSourcesMap(sources) {
374
+ var formats = qx.bom.webfonts.WebFontLoader.FONT_FORMATS;
375
+ var sourcesMap = {};
376
+ var reg = new RegExp(".(" + formats.join("|") + ")");
377
+ for (var i = 0, l = sources.length; i < l; i++) {
378
+ var match = reg.exec(sources[i]);
379
+ if (match) {
380
+ var type = match[1];
381
+ sourcesMap[type] = sources[i];
382
+ }
383
+ }
384
+ return sourcesMap;
385
+ },
386
+
387
+ /**
388
+ * Returns the preferred font format(s) for the currently used browser. Some
389
+ * browsers support multiple formats, e.g. WOFF and TTF or WOFF and EOT. In
390
+ * those cases, WOFF is considered the preferred format.
391
+ *
392
+ * @return {String[]} List of supported font formats ordered by preference
393
+ * or empty Array if none could be determined
394
+ */
395
+ getPreferredFormats() {
396
+ if (qx.bom.webfonts.WebFontLoader.__preferredFormats) {
397
+ return qx.bom.webfonts.WebFontLoader.__preferredFormats;
398
+ }
399
+
400
+ var preferredFormats = [];
401
+ var browser = qx.core.Environment.get("browser.name");
402
+ var browserVersion = qx.core.Environment.get("browser.version");
403
+ var os = qx.core.Environment.get("os.name");
404
+ var osVersion = qx.core.Environment.get("os.version");
405
+
406
+ if (
407
+ (browser == "edge" && browserVersion >= 14) ||
408
+ (browser == "firefox" && browserVersion >= 69) ||
409
+ (browser == "chrome" && browserVersion >= 36)
410
+ ) {
411
+ preferredFormats.push("woff2");
412
+ }
413
+
414
+ if (
415
+ (browser == "ie" &&
416
+ qx.core.Environment.get("browser.documentmode") >= 9) ||
417
+ (browser == "edge" && browserVersion >= 12) ||
418
+ (browser == "firefox" && browserVersion >= 3.6) ||
419
+ (browser == "chrome" && browserVersion >= 6)
420
+ ) {
421
+ preferredFormats.push("woff");
422
+ }
423
+
424
+ if (
425
+ (browser == "edge" && browserVersion >= 12) ||
426
+ (browser == "opera" && browserVersion >= 10) ||
427
+ (browser == "safari" && browserVersion >= 3.1) ||
428
+ (browser == "firefox" && browserVersion >= 3.5) ||
429
+ (browser == "chrome" && browserVersion >= 4) ||
430
+ (browser == "mobile safari" && os == "ios" && osVersion >= 4.2)
431
+ ) {
432
+ preferredFormats.push("ttf");
433
+ }
434
+
435
+ if (browser == "ie" && browserVersion >= 4) {
436
+ preferredFormats.push("eot");
437
+ }
438
+
439
+ if (browser == "mobileSafari" && os == "ios" && osVersion >= 4.1) {
440
+ preferredFormats.push("svg");
441
+ }
442
+
443
+ return (qx.bom.webfonts.WebFontLoader.__preferredFormats =
444
+ preferredFormats);
445
+ },
446
+
447
+ /**
448
+ * IE 6 and 7 omit the trailing quote after the format name when
449
+ * querying cssText. This needs to be fixed before cssText is replaced
450
+ * or all rules will be invalid and no web fonts will work any more.
451
+ *
452
+ * @param cssText {String} CSS text
453
+ * @return {String} Fixed CSS text
454
+ */
455
+ __fixCssText(cssText) {
456
+ return cssText
457
+ .replace("'eot)", "'eot')")
458
+ .replace("('embedded-opentype)", "('embedded-opentype')");
459
+ }
460
+ }
461
+ });
@@ -353,7 +353,7 @@ qx.Class.define("qx.core.Object", {
353
353
 
354
354
  // Additional checks
355
355
  if (qx.core.Environment.get("qx.debug")) {
356
- if (qx.core.Environment.get("qx.debug.dispose.level") > 0) {
356
+ if (qx.core.Environment.get("qx.debug.dispose.level") > 0 && qx.Class.hasOwnInterface(this.constructor, qx.core.IDisposable)) {
357
357
  var key, value;
358
358
  for (key in this) {
359
359
  value = this[key];