@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.
- package/Manifest.json +169 -44
- package/lib/compiler/compile-info.json +76 -68
- package/lib/compiler/index.js +3683 -2588
- package/lib/resource/qx/tool/schema/Manifest-1-0-0.json +79 -26
- package/lib/resource/qx/tool/schema/Manifest-2-0-0.json +17 -26
- package/lib/resource/qx/tool/schema/compile-1-0-0.json +40 -53
- package/package.json +2 -2
- package/source/class/qx/bom/Font.js +36 -0
- package/source/class/qx/bom/webfonts/Validator.js +31 -6
- package/source/class/qx/bom/webfonts/WebFont.js +60 -64
- package/source/class/qx/bom/webfonts/WebFontLoader.js +461 -0
- package/source/class/qx/core/Object.js +1 -1
- package/source/class/qx/data/Array.js +27 -0
- package/source/class/qx/dev/FakeServer.js +1 -1
- package/source/class/qx/event/handler/Focus.js +2 -1
- package/source/class/qx/event/handler/GestureCore.js +1 -1
- package/source/class/qx/test/bom/webfonts/Validator.js +0 -6
- package/source/class/qx/test/core/Environment.js +8 -8
- package/source/class/qx/test/core/Validation.js +2 -2
- package/source/class/qx/test/dev/unit/Requirements.js +6 -6
- package/source/class/qx/test/ui/basic/Image.js +3 -3
- package/source/class/qx/test/ui/basic/Label.js +0 -65
- package/source/class/qx/test/ui/form/Field.js +56 -52
- package/source/class/qx/theme/classic/Font.js +7 -23
- package/source/class/qx/theme/iconfont/LoadMaterialIcons.js +2 -4
- package/source/class/qx/theme/iconfont/LoadMaterialIconsOutlined.js +2 -4
- package/source/class/qx/theme/iconfont/LoadMaterialIconsRound.js +2 -4
- package/source/class/qx/theme/iconfont/LoadMaterialIconsSharp.js +2 -4
- package/source/class/qx/theme/iconfont/LoadMaterialIconsTwoTone.js +2 -4
- package/source/class/qx/theme/indigo/Font.js +8 -15
- package/source/class/qx/theme/manager/Font.js +151 -38
- package/source/class/qx/theme/modern/Font.js +1 -0
- package/source/class/qx/theme/simple/Font.js +3 -1
- package/source/class/qx/theme/tangible/Appearance.js +1 -0
- package/source/class/qx/theme/tangible/Font.js +9 -62
- package/source/class/qx/theme/tangible/Image.js +1 -4
- package/source/class/qx/tool/cli/Cli.js +12 -0
- package/source/class/qx/tool/cli/Watch.js +3 -0
- package/source/class/qx/tool/cli/api/CompilerApi.js +8 -0
- package/source/class/qx/tool/cli/commands/Add.js +1 -1
- package/source/class/qx/tool/cli/commands/Compile.js +22 -0
- package/source/class/qx/tool/cli/commands/Config.js +16 -141
- package/source/class/qx/tool/cli/commands/ExportGlyphs.js +134 -0
- package/source/class/qx/tool/cli/commands/Package.js +3 -0
- package/source/class/qx/tool/cli/commands/Pkg.js +1 -1
- package/source/class/qx/tool/cli/commands/config/Delete.js +47 -0
- package/source/class/qx/tool/cli/commands/config/Get.js +52 -0
- package/source/class/qx/tool/cli/commands/config/List.js +81 -0
- package/source/class/qx/tool/cli/commands/config/Set.js +61 -0
- package/source/class/qx/tool/cli/commands/package/Update.js +3 -3
- package/source/class/qx/tool/compiler/Analyser.js +45 -0
- package/source/class/qx/tool/compiler/ClassFile.js +41 -0
- package/source/class/qx/tool/compiler/Console.js +6 -1
- package/source/class/qx/tool/compiler/app/Application.js +19 -0
- package/source/class/qx/tool/compiler/app/Library.js +51 -2
- package/source/class/qx/tool/compiler/app/ManifestFont.js +181 -0
- package/source/class/qx/tool/compiler/app/WebFont.js +144 -234
- package/source/class/qx/tool/compiler/makers/AppMaker.js +13 -0
- package/source/class/qx/tool/compiler/resources/ImageLoader.js +22 -12
- package/source/class/qx/tool/compiler/resources/Manager.js +2 -2
- package/source/class/qx/tool/compiler/resources/MetaLoader.js +7 -2
- package/source/class/qx/tool/compiler/resources/ResourceLoader.js +21 -0
- package/source/class/qx/tool/compiler/targets/Target.js +186 -67
- package/source/class/qx/tool/migration/M7_5_6.js +75 -0
- package/source/class/qx/tool/utils/Http.js +69 -0
- package/source/class/qx/ui/basic/Label.js +20 -38
- package/source/class/qx/ui/form/AbstractField.js +8 -2
- package/source/class/qx/ui/form/FileSelectorButton.js +5 -0
- package/source/class/qx/ui/table/pane/FocusIndicator.js +5 -4
- package/source/class/qx/ui/table/pane/Pane.js +14 -0
- package/source/class/qx/ui/table/pane/Scroller.js +3 -3
- package/source/class/qx/ui/virtual/core/Scroller.js +8 -2
- package/source/class/qx/ui/window/Window.js +9 -8
- package/source/resource/qx/iconfont/MaterialIcons/materialicons.json +10912 -0
- package/source/resource/qx/iconfont/MaterialIcons/materialiconsoutlined.json +10967 -0
- package/source/resource/qx/iconfont/MaterialIcons/materialiconsround.json +10992 -0
- package/source/resource/qx/iconfont/MaterialIcons/materialiconssharp.json +10992 -0
- package/source/resource/qx/iconfont/MaterialIcons/materialiconstwotone.json +9947 -0
- package/source/resource/qx/iconfont/MaterialIcons/x.json +10967 -0
- package/source/resource/qx/iconfont/export-glyphs.sh +22 -0
- package/source/resource/qx/tool/schema/Manifest-1-0-0.json +79 -26
- package/source/resource/qx/tool/schema/Manifest-2-0-0.json +17 -26
- package/source/resource/qx/tool/schema/compile-1-0-0.json +40 -53
- package/source/class/qx/bom/webfonts/Manager.js +0 -652
- package/source/class/qx/test/bom/webfonts/Manager.js +0 -238
|
@@ -88,236 +88,166 @@ qx.Class.define("qx.tool.compiler.app.WebFont", {
|
|
|
88
88
|
* Helper which triggers a local font analyze run.
|
|
89
89
|
*
|
|
90
90
|
* @param filename {String} Filename for the local font
|
|
91
|
-
* @return {
|
|
91
|
+
* @return {Map<String,String>} mapping of glyphs to codepoints
|
|
92
92
|
*/
|
|
93
|
-
_loadLocalFont(filename) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
);
|
|
93
|
+
async _loadLocalFont(filename) {
|
|
94
|
+
let fontpath = path.join(
|
|
95
|
+
this.__library.getRootDir(),
|
|
96
|
+
path.join(this.__library.getResourcePath(), filename)
|
|
97
|
+
);
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
});
|
|
99
|
+
return await this.__processFontFile(fontpath);
|
|
102
100
|
},
|
|
103
101
|
|
|
104
102
|
/**
|
|
105
103
|
* Helper which loads a remote font to analyze the result.
|
|
106
104
|
*
|
|
107
105
|
* @param url {String} URL for the font download
|
|
108
|
-
* @return {
|
|
106
|
+
* @return {Map<String,String>} mapping of glyphs to codepoints
|
|
109
107
|
*/
|
|
110
|
-
_loadRemoteFont(url) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
.get(
|
|
115
|
-
url,
|
|
116
|
-
function (res) {
|
|
117
|
-
let error;
|
|
118
|
-
const { statusCode } = res;
|
|
119
|
-
const contentType = res.headers["content-type"];
|
|
120
|
-
|
|
121
|
-
if (statusCode !== 200) {
|
|
122
|
-
error = new Error(
|
|
123
|
-
`Request Failed.\nStatus Code: ${statusCode}`
|
|
124
|
-
);
|
|
125
|
-
} else if (
|
|
126
|
-
!/^font\/(ttf|svg|eot|woff|woff2)$/.test(contentType)
|
|
127
|
-
) {
|
|
128
|
-
error = new Error(
|
|
129
|
-
"Invalid content-type.\n" +
|
|
130
|
-
`Expected font/ttf, font/svg, font/eot, font/woff or font/woff2 but received ${contentType}`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (error) {
|
|
135
|
-
res.resume();
|
|
136
|
-
reject(error);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
tmp.tmpName(
|
|
141
|
-
function _tempNameGenerated(err, tmpFilename) {
|
|
142
|
-
if (err) {
|
|
143
|
-
reject(err);
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
let outFile = fs.createWriteStream(tmpFilename);
|
|
148
|
-
outFile.on(
|
|
149
|
-
"close",
|
|
150
|
-
function () {
|
|
151
|
-
this.__processFontFile(tmpFilename, resolve, reject);
|
|
152
|
-
fs.unlink(tmpFilename);
|
|
153
|
-
}.bind(this)
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
res.on("data", chunk => {
|
|
157
|
-
outFile.write(chunk);
|
|
158
|
-
});
|
|
159
|
-
res.on("end", function () {
|
|
160
|
-
outFile.end();
|
|
161
|
-
});
|
|
162
|
-
}.bind(this)
|
|
163
|
-
);
|
|
164
|
-
}.bind(this)
|
|
165
|
-
)
|
|
166
|
-
.on("error", e => {
|
|
167
|
-
reject(e);
|
|
168
|
-
});
|
|
169
|
-
}.bind(this)
|
|
108
|
+
async _loadRemoteFont(url) {
|
|
109
|
+
let tmpFilename = await qx.tool.utils.Http.downloadToTempFile(
|
|
110
|
+
url,
|
|
111
|
+
/^font\/(ttf|svg|eot|woff|woff2)$/
|
|
170
112
|
);
|
|
113
|
+
|
|
114
|
+
let result = await this.__processFontFile(tmpFilename);
|
|
115
|
+
fs.unlink(tmpFilename);
|
|
116
|
+
return result;
|
|
171
117
|
},
|
|
172
118
|
|
|
173
119
|
/**
|
|
174
120
|
* Common code to extract the desired font information from a font file
|
|
175
|
-
* on disk.
|
|
176
|
-
* local font retrieval).
|
|
121
|
+
* on disk.
|
|
177
122
|
*
|
|
178
123
|
* @param filename {String} Path to font file
|
|
179
|
-
* @
|
|
180
|
-
* @param reject {Function} External promise reject
|
|
124
|
+
* @return {Map<String,String>} mapping of glyphs to codepoints
|
|
181
125
|
*/
|
|
182
|
-
__processFontFile(filename
|
|
183
|
-
|
|
184
|
-
filename,
|
|
185
|
-
|
|
186
|
-
function (err, font) {
|
|
187
|
-
if (err) {
|
|
188
|
-
reject(err);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
let resources = {};
|
|
126
|
+
async __processFontFile(filename) {
|
|
127
|
+
let fn = qx.tool.utils.Promisify.promisify(cb =>
|
|
128
|
+
fontkit.open(filename, null, cb)
|
|
129
|
+
);
|
|
193
130
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (this.getMapping()) {
|
|
197
|
-
let mapPath = path.join(
|
|
198
|
-
this.__library.getRootDir(),
|
|
199
|
-
path.join(this.__library.getResourcePath(), this.getMapping())
|
|
200
|
-
);
|
|
131
|
+
let font = await fn();
|
|
132
|
+
let resources = {};
|
|
201
133
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
let map = JSON.parse(data);
|
|
210
|
-
Object.keys(map).forEach(key => {
|
|
211
|
-
let codePoint = parseInt(map[key], 16);
|
|
212
|
-
let glyph = font.glyphForCodePoint(codePoint);
|
|
213
|
-
if (!glyph.id) {
|
|
214
|
-
qx.tool.compiler.Console.trace(
|
|
215
|
-
`WARN: no glyph found in ${filename} ${key}: ${codePoint}`
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
resources["@" + this.getName() + "/" + key] = [
|
|
221
|
-
Math.ceil(
|
|
222
|
-
(this.getDefaultSize() * glyph.advanceWidth) /
|
|
223
|
-
glyph.advanceHeight
|
|
224
|
-
),
|
|
225
|
-
|
|
226
|
-
// width
|
|
227
|
-
this.getDefaultSize(), // height
|
|
228
|
-
codePoint
|
|
229
|
-
];
|
|
230
|
-
}, this);
|
|
231
|
-
|
|
232
|
-
resolve(resources);
|
|
233
|
-
return;
|
|
234
|
-
});
|
|
134
|
+
// If we have a mapping file, take qx.tool.compiler.Console.information instead
|
|
135
|
+
// of anaylzing the font.
|
|
136
|
+
if (this.getMapping()) {
|
|
137
|
+
let mapPath = path.join(
|
|
138
|
+
this.__library.getRootDir(),
|
|
139
|
+
path.join(this.__library.getResourcePath(), this.getMapping())
|
|
140
|
+
);
|
|
235
141
|
|
|
236
|
-
|
|
237
|
-
|
|
142
|
+
let data;
|
|
143
|
+
try {
|
|
144
|
+
data = await fs.promises.readFile(mapPath, { encoding: "utf-8" });
|
|
145
|
+
} catch (err) {
|
|
146
|
+
log.error(`Cannot read mapping file '${mapPath}': ${err.code}`);
|
|
147
|
+
throw err;
|
|
148
|
+
}
|
|
238
149
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
150
|
+
let map = JSON.parse(data);
|
|
151
|
+
Object.keys(map).forEach(key => {
|
|
152
|
+
let codePoint = parseInt(map[key], 16);
|
|
153
|
+
let glyph = font.glyphForCodePoint(codePoint);
|
|
154
|
+
if (!glyph.id) {
|
|
155
|
+
qx.tool.compiler.Console.trace(
|
|
156
|
+
`WARN: no glyph found in ${filename} ${key}: ${codePoint}`
|
|
242
157
|
);
|
|
243
158
|
|
|
244
|
-
resolve(resources);
|
|
245
159
|
return;
|
|
246
160
|
}
|
|
161
|
+
resources["@" + this.getName() + "/" + key] = [
|
|
162
|
+
Math.ceil(
|
|
163
|
+
(this.getDefaultSize() * glyph.advanceWidth) / glyph.advanceHeight
|
|
164
|
+
),
|
|
165
|
+
|
|
166
|
+
// width
|
|
167
|
+
this.getDefaultSize(), // height
|
|
168
|
+
codePoint
|
|
169
|
+
];
|
|
170
|
+
}, this);
|
|
171
|
+
|
|
172
|
+
return resources;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!font.GSUB) {
|
|
176
|
+
qx.tool.compiler.Console.error(
|
|
177
|
+
`The webfont in ${filename} does not have any ligatures`
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return resources;
|
|
181
|
+
}
|
|
247
182
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
});
|
|
183
|
+
// some IconFonts (MaterialIcons for example) use ligatures
|
|
184
|
+
// to name their icons. This code extracts the ligatures
|
|
185
|
+
// hat tip to Jossef Harush https://stackoverflow.com/questions/54721774/extracting-ttf-font-ligature-mappings/54728584
|
|
186
|
+
let ligatureName = {};
|
|
187
|
+
let lookupList = font.GSUB.lookupList.toArray();
|
|
188
|
+
let lookupListIndexes =
|
|
189
|
+
font.GSUB.featureList[0].feature.lookupListIndexes;
|
|
190
|
+
lookupListIndexes.forEach(index => {
|
|
191
|
+
let subTable = lookupList[index].subTables[0];
|
|
192
|
+
let leadingCharacters = [];
|
|
193
|
+
if (subTable.coverage.rangeRecords) {
|
|
194
|
+
subTable.coverage.rangeRecords.forEach(coverage => {
|
|
195
|
+
for (let i = coverage.start; i <= coverage.end; i++) {
|
|
196
|
+
let character = font.stringsForGlyph(i)[0];
|
|
197
|
+
leadingCharacters.push(character);
|
|
265
198
|
}
|
|
266
|
-
let ligatureSets = subTable.ligatureSets.toArray();
|
|
267
|
-
ligatureSets.forEach((ligatureSet, ligatureSetIndex) => {
|
|
268
|
-
let leadingCharacter = leadingCharacters[ligatureSetIndex];
|
|
269
|
-
ligatureSet.forEach(ligature => {
|
|
270
|
-
let character = font.stringsForGlyph(ligature.glyph)[0];
|
|
271
|
-
if (!character) {
|
|
272
|
-
// qx.tool.compiler.Console.log(`WARN: ${this.getName()} no character ${ligature}`);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
let ligatureText =
|
|
276
|
-
leadingCharacter +
|
|
277
|
-
ligature.components
|
|
278
|
-
.map(x => font.stringsForGlyph(x)[0])
|
|
279
|
-
.join("");
|
|
280
|
-
var hexId = character.charCodeAt(0).toString(16);
|
|
281
|
-
if (ligatureName[hexId] == undefined) {
|
|
282
|
-
ligatureName[hexId] = [ligatureText];
|
|
283
|
-
} else {
|
|
284
|
-
ligatureName[hexId].push(ligatureText);
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
199
|
});
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
200
|
+
}
|
|
201
|
+
let ligatureSets = subTable.ligatureSets.toArray();
|
|
202
|
+
ligatureSets.forEach((ligatureSet, ligatureSetIndex) => {
|
|
203
|
+
let leadingCharacter = leadingCharacters[ligatureSetIndex];
|
|
204
|
+
ligatureSet.forEach(ligature => {
|
|
205
|
+
let character = font.stringsForGlyph(ligature.glyph)[0];
|
|
206
|
+
if (!character) {
|
|
207
|
+
// qx.tool.compiler.Console.log(`WARN: ${this.getName()} no character ${ligature}`);
|
|
294
208
|
return;
|
|
295
209
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
// width
|
|
305
|
-
defaultSize, // height
|
|
306
|
-
codePoint
|
|
307
|
-
];
|
|
308
|
-
};
|
|
309
|
-
if (glyph.name) {
|
|
310
|
-
found(glyph.name);
|
|
311
|
-
}
|
|
312
|
-
var names = ligatureName[codePoint.toString(16)];
|
|
313
|
-
if (names) {
|
|
314
|
-
names.forEach(found);
|
|
210
|
+
let ligatureText =
|
|
211
|
+
leadingCharacter +
|
|
212
|
+
ligature.components.map(x => font.stringsForGlyph(x)[0]).join("");
|
|
213
|
+
var hexId = character.charCodeAt(0).toString(16);
|
|
214
|
+
if (ligatureName[hexId] == undefined) {
|
|
215
|
+
ligatureName[hexId] = [ligatureText];
|
|
216
|
+
} else {
|
|
217
|
+
ligatureName[hexId].push(ligatureText);
|
|
315
218
|
}
|
|
316
|
-
}
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
317
222
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
223
|
+
let defaultSize = this.getDefaultSize();
|
|
224
|
+
font.characterSet.forEach(codePoint => {
|
|
225
|
+
let glyph = font.glyphForCodePoint(codePoint);
|
|
226
|
+
if (glyph.path.commands.length < 1 && !glyph.layers) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const found = gName => {
|
|
231
|
+
resources["@" + this.getName() + "/" + gName] = [
|
|
232
|
+
Math.ceil(
|
|
233
|
+
(this.getDefaultSize() * glyph.advanceWidth) / glyph.advanceHeight
|
|
234
|
+
),
|
|
235
|
+
|
|
236
|
+
// width
|
|
237
|
+
defaultSize, // height
|
|
238
|
+
codePoint
|
|
239
|
+
];
|
|
240
|
+
};
|
|
241
|
+
if (glyph.name) {
|
|
242
|
+
found(glyph.name);
|
|
243
|
+
}
|
|
244
|
+
var names = ligatureName[codePoint.toString(16)];
|
|
245
|
+
if (names) {
|
|
246
|
+
names.forEach(found);
|
|
247
|
+
}
|
|
248
|
+
}, this);
|
|
249
|
+
|
|
250
|
+
return resources;
|
|
321
251
|
},
|
|
322
252
|
|
|
323
253
|
/**
|
|
@@ -325,24 +255,17 @@ qx.Class.define("qx.tool.compiler.app.WebFont", {
|
|
|
325
255
|
*
|
|
326
256
|
* @param target {qx.tool.compiler.targets.Target} the target
|
|
327
257
|
* @param application {qx.tool.compiler.app.Application} the application being built
|
|
328
|
-
* @param initial {Boolean} true if this is the first pass
|
|
329
258
|
* @return {String}
|
|
330
259
|
*/
|
|
331
|
-
getBootstrapCode(target, application
|
|
260
|
+
getBootstrapCode(target, application) {
|
|
332
261
|
let res = "";
|
|
333
|
-
|
|
334
|
-
if (initial) {
|
|
335
|
-
res = "qx.$$fontBootstrap={};\n";
|
|
336
|
-
}
|
|
337
|
-
|
|
338
262
|
let font = {
|
|
339
|
-
|
|
263
|
+
defaultSize: this.getDefaultSize(),
|
|
340
264
|
lineHeight: 1,
|
|
341
265
|
family: [this.getName()],
|
|
342
|
-
|
|
266
|
+
fontFaces: [
|
|
343
267
|
{
|
|
344
|
-
|
|
345
|
-
source: this.getResources()
|
|
268
|
+
paths: this.getResources()
|
|
346
269
|
}
|
|
347
270
|
]
|
|
348
271
|
};
|
|
@@ -355,7 +278,7 @@ qx.Class.define("qx.tool.compiler.app.WebFont", {
|
|
|
355
278
|
"qx.$$fontBootstrap['" +
|
|
356
279
|
this.getName() +
|
|
357
280
|
"']=" +
|
|
358
|
-
JSON.stringify(font) +
|
|
281
|
+
JSON.stringify(font, null, 2) +
|
|
359
282
|
";");
|
|
360
283
|
},
|
|
361
284
|
|
|
@@ -371,7 +294,7 @@ qx.Class.define("qx.tool.compiler.app.WebFont", {
|
|
|
371
294
|
return this.__generateForTargetPromise;
|
|
372
295
|
}
|
|
373
296
|
|
|
374
|
-
|
|
297
|
+
const generate = async () => {
|
|
375
298
|
for (let resource of this.getResources()) {
|
|
376
299
|
// Search for the first supported extension
|
|
377
300
|
let basename = resource.match(/^.*[/\\]([^/\\\?#]+).*$/)[1];
|
|
@@ -379,35 +302,22 @@ qx.Class.define("qx.tool.compiler.app.WebFont", {
|
|
|
379
302
|
if (!basename.match(/\.(ttf|otf|woff|woff2)$/)) {
|
|
380
303
|
continue;
|
|
381
304
|
}
|
|
382
|
-
|
|
383
|
-
// first.
|
|
305
|
+
|
|
384
306
|
if (resource.match(/^https?:\/\//)) {
|
|
385
|
-
this._loadRemoteFont(resource)
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
resolve();
|
|
389
|
-
})
|
|
390
|
-
.catch(err => {
|
|
391
|
-
reject(err);
|
|
392
|
-
});
|
|
393
|
-
return;
|
|
307
|
+
this.__fontData = await this._loadRemoteFont(resource);
|
|
308
|
+
} else {
|
|
309
|
+
this.__fontData = await this._loadLocalFont(resource);
|
|
394
310
|
}
|
|
395
|
-
|
|
396
|
-
this.
|
|
397
|
-
.then(data => {
|
|
398
|
-
this.__fontData = data;
|
|
399
|
-
resolve();
|
|
400
|
-
})
|
|
401
|
-
.catch(err => {
|
|
402
|
-
reject(err);
|
|
403
|
-
});
|
|
404
|
-
return;
|
|
311
|
+
|
|
312
|
+
return this.__fontData;
|
|
405
313
|
}
|
|
406
|
-
|
|
314
|
+
|
|
315
|
+
throw new Error(
|
|
407
316
|
`Failed to load/validate FontMap for webfont (expected ttf, otf, woff or woff2) ${this.getName()}`
|
|
408
317
|
);
|
|
409
|
-
}
|
|
318
|
+
};
|
|
410
319
|
|
|
320
|
+
this.__generateForTargetPromise = generate();
|
|
411
321
|
return this.__generateForTargetPromise;
|
|
412
322
|
},
|
|
413
323
|
|
|
@@ -165,6 +165,18 @@ qx.Class.define("qx.tool.compiler.makers.AppMaker", {
|
|
|
165
165
|
this.__applications.forEach(app => app.setAnalyser(analyser));
|
|
166
166
|
await target.open();
|
|
167
167
|
|
|
168
|
+
for (let library of analyser.getLibraries()) {
|
|
169
|
+
let fontsData = library.getFontsData();
|
|
170
|
+
for (let fontName in fontsData) {
|
|
171
|
+
let fontData = fontsData[fontName];
|
|
172
|
+
let font = analyser.getFont(fontName);
|
|
173
|
+
if (!font) {
|
|
174
|
+
font = analyser.getFont(fontName, true);
|
|
175
|
+
await font.updateFromManifest(fontData, library);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
168
180
|
if (this.isOutputTypescript()) {
|
|
169
181
|
analyser.getLibraries().forEach(library => {
|
|
170
182
|
var symbols = library.getKnownSymbols();
|
|
@@ -208,6 +220,7 @@ qx.Class.define("qx.tool.compiler.makers.AppMaker", {
|
|
|
208
220
|
let stat = await qx.tool.utils.files.Utils.safeStat(
|
|
209
221
|
localModules[requireName]
|
|
210
222
|
);
|
|
223
|
+
|
|
211
224
|
res ||=
|
|
212
225
|
stat.mtime.getTime() >
|
|
213
226
|
(db?.modulesInfo?.localModules[requireName] || 0);
|
|
@@ -27,8 +27,13 @@ var log = qx.tool.utils.LogManager.createLog("resource-manager");
|
|
|
27
27
|
qx.Class.define("qx.tool.compiler.resources.ImageLoader", {
|
|
28
28
|
extend: qx.tool.compiler.resources.ResourceLoader,
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Constructor
|
|
32
|
+
*
|
|
33
|
+
* @param {qx.tool.compiler.resources.Manager} manager resource manager
|
|
34
|
+
*/
|
|
35
|
+
construct(manager) {
|
|
36
|
+
super([".png", ".gif", ".jpg", ".jpeg", ".svg"], manager);
|
|
32
37
|
},
|
|
33
38
|
|
|
34
39
|
members: {
|
|
@@ -50,16 +55,18 @@ qx.Class.define("qx.tool.compiler.resources.ImageLoader", {
|
|
|
50
55
|
* @Override
|
|
51
56
|
*/
|
|
52
57
|
matches(filename, library) {
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
library
|
|
57
|
-
.getWebFonts()
|
|
58
|
-
.find(webFont =>
|
|
59
|
-
webFont.getResources().find(resource => resource == filename)
|
|
60
|
-
);
|
|
58
|
+
if (library.isFontAsset(filename)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
if (filename.endsWith(".svg")) {
|
|
63
|
+
let withoutExt = filename.substring(0, filename.length - 3);
|
|
64
|
+
let manager = this.getManager();
|
|
65
|
+
if (
|
|
66
|
+
["eot", "woff2", "woff", "ttf"].find(
|
|
67
|
+
ext => !!manager.findLibraryForResource(withoutExt + ext)
|
|
68
|
+
)
|
|
69
|
+
) {
|
|
63
70
|
return false;
|
|
64
71
|
}
|
|
65
72
|
}
|
|
@@ -79,7 +86,10 @@ qx.Class.define("qx.tool.compiler.resources.ImageLoader", {
|
|
|
79
86
|
fileInfo.width = dimensions.width;
|
|
80
87
|
fileInfo.height = dimensions.height;
|
|
81
88
|
} catch (ex) {
|
|
82
|
-
|
|
89
|
+
// When we can't get the image size, we don't report it because there are SVG types
|
|
90
|
+
// that have no size (eg fonts) and it's proved quite hard (or impossible) to
|
|
91
|
+
// suppress the warning accurately in those cases. Ultimately, if the image is
|
|
92
|
+
// corrupt it will be found.
|
|
83
93
|
delete fileInfo.width;
|
|
84
94
|
delete fileInfo.height;
|
|
85
95
|
}
|
|
@@ -43,8 +43,8 @@ qx.Class.define("qx.tool.compiler.resources.Manager", {
|
|
|
43
43
|
this.__analyser = analyser;
|
|
44
44
|
this.__dbFilename = analyser.getResDbFilename() || "resource-db.json";
|
|
45
45
|
this.__loaders = [
|
|
46
|
-
new qx.tool.compiler.resources.ImageLoader(),
|
|
47
|
-
new qx.tool.compiler.resources.MetaLoader()
|
|
46
|
+
new qx.tool.compiler.resources.ImageLoader(this),
|
|
47
|
+
new qx.tool.compiler.resources.MetaLoader(this)
|
|
48
48
|
];
|
|
49
49
|
|
|
50
50
|
this.__converters = [
|
|
@@ -23,8 +23,13 @@
|
|
|
23
23
|
qx.Class.define("qx.tool.compiler.resources.MetaLoader", {
|
|
24
24
|
extend: qx.tool.compiler.resources.ResourceLoader,
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Constructor
|
|
28
|
+
*
|
|
29
|
+
* @param {qx.tool.compiler.resources.Manager} manager resource manager
|
|
30
|
+
*/
|
|
31
|
+
construct(manager) {
|
|
32
|
+
super(".meta", manager);
|
|
28
33
|
},
|
|
29
34
|
|
|
30
35
|
members: {
|
|
@@ -28,7 +28,21 @@ qx.Class.define("qx.tool.compiler.resources.ResourceLoader", {
|
|
|
28
28
|
extend: qx.tool.compiler.resources.AbstractMatcher,
|
|
29
29
|
type: "abstract",
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Constructor
|
|
33
|
+
*
|
|
34
|
+
* @param {String} match the match for the filename
|
|
35
|
+
* @param {qx.tool.compiler.resources.Manager} manager resource manager
|
|
36
|
+
*/
|
|
37
|
+
construct(match, manager) {
|
|
38
|
+
super(match);
|
|
39
|
+
this.__manager = manager;
|
|
40
|
+
},
|
|
41
|
+
|
|
31
42
|
members: {
|
|
43
|
+
/** @type{qx.tool.compiler.resources.Manager} the resource manager this loader belongs to */
|
|
44
|
+
__manager: null,
|
|
45
|
+
|
|
32
46
|
/**
|
|
33
47
|
* Detects whether the file needs to be recompiled/coverted/analysed/ etc; this should
|
|
34
48
|
* not take any time or be asynchronous, if you need to do any real work it should be
|
|
@@ -56,6 +70,13 @@ qx.Class.define("qx.tool.compiler.resources.ResourceLoader", {
|
|
|
56
70
|
*/
|
|
57
71
|
async load(asset) {
|
|
58
72
|
throw new Error("No implementation for " + this.classname + ".compile");
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @return {qx.tool.compiler.resources.Manager} the manager
|
|
77
|
+
*/
|
|
78
|
+
getManager() {
|
|
79
|
+
return this.__manager;
|
|
59
80
|
}
|
|
60
81
|
}
|
|
61
82
|
});
|