Merge pull request #3034 from matrix-org/bwindels/colr-check-race
fix COLR font check being racy
This commit is contained in:
commit
f61e771f7a
1 changed files with 38 additions and 17 deletions
|
@ -21,21 +21,43 @@ limitations under the License.
|
||||||
* MIT license
|
* MIT license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let colrFontSupported = undefined;
|
function safariVersionCheck(ua) {
|
||||||
|
try {
|
||||||
|
const safariVersionMatch = ua.match(/Mac OS X ([\d|_]+).*Version\/([\d|.]+).*Safari/);
|
||||||
|
if (safariVersionMatch) {
|
||||||
|
const macOSVersionStr = safariVersionMatch[1];
|
||||||
|
const safariVersionStr = safariVersionMatch[2];
|
||||||
|
const macOSVersion = macOSVersionStr.split("_").map(n => parseInt(n, 10));
|
||||||
|
const safariVersion = safariVersionStr.split(".").map(n => parseInt(n, 10));
|
||||||
|
const colrFontSupported = macOSVersion[0] >= 10 && macOSVersion[1] >= 14 && safariVersion[0] >= 12;
|
||||||
|
// https://www.colorfonts.wtf/ states safari supports COLR fonts from this version on
|
||||||
|
console.log(`Browser is Safari - requiring macOS 10.14 and Safari 12, ` +
|
||||||
|
`detected Safari ${safariVersionStr} on macOS ${macOSVersionStr}, ` +
|
||||||
|
`COLR supported: ${colrFontSupported}`);
|
||||||
|
return colrFontSupported;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Couldn't determine Safari version to check COLR font support, assuming no.", err);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
async function isColrFontSupported() {
|
async function isColrFontSupported() {
|
||||||
if (colrFontSupported !== undefined) {
|
|
||||||
return colrFontSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Checking for COLR support");
|
console.log("Checking for COLR support");
|
||||||
|
|
||||||
// Firefox has supported COLR fonts since version 26
|
// Firefox has supported COLR fonts since version 26
|
||||||
// but doesn't support the check below with content blocking enabled.
|
// but doesn't support the check below without
|
||||||
|
// "Extract canvas data" permissions
|
||||||
|
// when content blocking is enabled.
|
||||||
if (navigator.userAgent.includes("Firefox")) {
|
if (navigator.userAgent.includes("Firefox")) {
|
||||||
colrFontSupported = true;
|
|
||||||
console.log("Browser is Firefox - assuming COLR is supported");
|
console.log("Browser is Firefox - assuming COLR is supported");
|
||||||
return colrFontSupported;
|
return true;
|
||||||
|
}
|
||||||
|
// Safari doesn't wait for the font to load (if it doesn't have it in cache)
|
||||||
|
// to emit the load event on the image, so there is no way to not make the check
|
||||||
|
// reliable. Instead sniff the version.
|
||||||
|
if (navigator.userAgent.includes("Safari")) {
|
||||||
|
return safariVersionCheck(navigator.userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -61,26 +83,25 @@ async function isColrFontSupported() {
|
||||||
|
|
||||||
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
|
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
|
||||||
|
|
||||||
// FIXME wait for safari load our colr font
|
console.log("Waiting for COLR SVG to load");
|
||||||
const wait = ms => new Promise((r, j)=>setTimeout(r, ms));
|
await new Promise(resolve => img.onload = resolve);
|
||||||
await wait(500);
|
|
||||||
|
|
||||||
console.log("Drawing canvas to detect COLR support");
|
console.log("Drawing canvas to detect COLR support");
|
||||||
context.drawImage(img, 0, 0);
|
context.drawImage(img, 0, 0);
|
||||||
colrFontSupported = (context.getImageData(10, 10, 1, 1).data[0] === 200);
|
const colrFontSupported = (context.getImageData(10, 10, 1, 1).data[0] === 200);
|
||||||
console.log("Canvas check revealed COLR is supported? " + colrFontSupported);
|
console.log("Canvas check revealed COLR is supported? " + colrFontSupported);
|
||||||
|
return colrFontSupported;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Couldn't load COLR font", e);
|
console.error("Couldn't load COLR font", e);
|
||||||
colrFontSupported = false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return colrFontSupported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let colrFontCheckStarted = false;
|
||||||
export async function fixupColorFonts() {
|
export async function fixupColorFonts() {
|
||||||
if (colrFontSupported !== undefined) {
|
if (colrFontCheckStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
colrFontCheckStarted = true;
|
||||||
|
|
||||||
if (await isColrFontSupported()) {
|
if (await isColrFontSupported()) {
|
||||||
const path = `url('${require("../../res/fonts/Twemoji_Mozilla/TwemojiMozilla-colr.woff2")}')`;
|
const path = `url('${require("../../res/fonts/Twemoji_Mozilla/TwemojiMozilla-colr.woff2")}')`;
|
||||||
|
|
Loading…
Reference in a new issue