From cf704fd2f143dc016db315257c6101594aa10db3 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 29 May 2019 10:11:14 +0200 Subject: [PATCH 1/7] fix COLR font check being racy also make sure it doesn't run more than once. keeping the FF sniffing because missing "extract canvas data" permissions would still break the check. --- src/utils/FontManager.js | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/utils/FontManager.js b/src/utils/FontManager.js index 7e8fc9d67e..bf47bcd7d2 100644 --- a/src/utils/FontManager.js +++ b/src/utils/FontManager.js @@ -21,21 +21,16 @@ limitations under the License. * MIT license */ -let colrFontSupported = undefined; - async function isColrFontSupported() { - if (colrFontSupported !== undefined) { - return colrFontSupported; - } - console.log("Checking for COLR support"); // 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")) { - colrFontSupported = true; console.log("Browser is Firefox - assuming COLR is supported"); - return colrFontSupported; + return true; } try { @@ -61,26 +56,25 @@ async function isColrFontSupported() { img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg); - // FIXME wait for safari load our colr font - const wait = ms => new Promise((r, j)=>setTimeout(r, ms)); - await wait(500); - + console.log("Waiting for COLR SVG to load"); + await new Promise(resolve => img.onload = resolve); console.log("Drawing canvas to detect COLR support"); 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); + return colrFontSupported; } catch (e) { console.error("Couldn't load COLR font", e); - colrFontSupported = false; + return false; } - - return colrFontSupported; } +let colrFontCheckStarted = false; export async function fixupColorFonts() { - if (colrFontSupported !== undefined) { + if (colrFontCheckStarted) { return; } + colrFontCheckStarted = true; if (await isColrFontSupported()) { const path = `url('${require("../../res/fonts/Twemoji_Mozilla/TwemojiMozilla-colr.woff2")}')`; From ba54b16275e6a3d9c57a0ca4b9050bc5c71799db Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 29 May 2019 11:59:50 +0200 Subject: [PATCH 2/7] sniff safari 12, macos 10.14 to support COLR, as safari doesn't wait for the font to load to emit load --- src/utils/FontManager.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/utils/FontManager.js b/src/utils/FontManager.js index bf47bcd7d2..2d5f7c5dc0 100644 --- a/src/utils/FontManager.js +++ b/src/utils/FontManager.js @@ -21,6 +21,23 @@ limitations under the License. * MIT license */ +function safariVersionCheck(ua) { + 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},` + + `supported: ${colrFontSupported}`); + return colrFontSupported; + } + return false; +} + async function isColrFontSupported() { console.log("Checking for COLR support"); @@ -32,6 +49,12 @@ async function isColrFontSupported() { console.log("Browser is Firefox - assuming COLR is supported"); 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 { const canvas = document.createElement('canvas'); From 5c8e280a45169590d5fa9de6a8f281878a729463 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 29 May 2019 12:03:38 +0200 Subject: [PATCH 3/7] make sure the check doesn't blow up --- src/utils/FontManager.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/utils/FontManager.js b/src/utils/FontManager.js index 2d5f7c5dc0..7fb14b56fd 100644 --- a/src/utils/FontManager.js +++ b/src/utils/FontManager.js @@ -22,18 +22,22 @@ limitations under the License. */ function safariVersionCheck(ua) { - 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},` + - `supported: ${colrFontSupported}`); - return colrFontSupported; + 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},` + + `supported: ${colrFontSupported}`); + return colrFontSupported; + } + } catch (err) { + console.error("Couldn't determine Safari version to check COLR font support, assuming no.", err); } return false; } From 66738e2284ab61c76a1fb46d06656db4f2092f93 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 29 May 2019 10:08:59 +0000 Subject: [PATCH 4/7] Update src/utils/FontManager.js Co-Authored-By: J. Ryan Stinnett --- src/utils/FontManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/FontManager.js b/src/utils/FontManager.js index 7fb14b56fd..29789b90f2 100644 --- a/src/utils/FontManager.js +++ b/src/utils/FontManager.js @@ -33,7 +33,7 @@ function safariVersionCheck(ua) { // 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},` + - `supported: ${colrFontSupported}`); + `COLR supported: ${colrFontSupported}`); return colrFontSupported; } } catch (err) { From 50f477dcd04e371100541d8edebaa8191df4c4c5 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 29 May 2019 10:09:10 +0000 Subject: [PATCH 5/7] Update src/utils/FontManager.js Co-Authored-By: J. Ryan Stinnett --- src/utils/FontManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/FontManager.js b/src/utils/FontManager.js index 29789b90f2..462ac94580 100644 --- a/src/utils/FontManager.js +++ b/src/utils/FontManager.js @@ -32,7 +32,7 @@ function safariVersionCheck(ua) { 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},` + + `detected Safari ${safariVersionStr} on macOS ${macOSVersionStr}, ` + `COLR supported: ${colrFontSupported}`); return colrFontSupported; } From 18697d8ee73e9ce2c236b43cd6d3bd6fe69b2f67 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 29 May 2019 10:10:18 +0000 Subject: [PATCH 6/7] Update src/utils/FontManager.js Co-Authored-By: J. Ryan Stinnett --- src/utils/FontManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/FontManager.js b/src/utils/FontManager.js index 462ac94580..e51efb8a2c 100644 --- a/src/utils/FontManager.js +++ b/src/utils/FontManager.js @@ -31,7 +31,7 @@ function safariVersionCheck(ua) { 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,` + + console.log(`Browser is Safari - requiring macOS 10.14 and Safari 12, ` + `detected Safari ${safariVersionStr} on macOS ${macOSVersionStr}, ` + `COLR supported: ${colrFontSupported}`); return colrFontSupported; From 3014180762be6464d67c60281698efb6f2325ffe Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 29 May 2019 12:16:40 +0200 Subject: [PATCH 7/7] fix lint & make regex more robust --- src/utils/FontManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/FontManager.js b/src/utils/FontManager.js index e51efb8a2c..c7a1f5e0b6 100644 --- a/src/utils/FontManager.js +++ b/src/utils/FontManager.js @@ -23,7 +23,7 @@ limitations under the License. function safariVersionCheck(ua) { try { - const safariVersionMatch = ua.match(/Mac OS X ([\d|_]+).*Version\/([\d|\.]+) Safari/); + const safariVersionMatch = ua.match(/Mac OS X ([\d|_]+).*Version\/([\d|.]+).*Safari/); if (safariVersionMatch) { const macOSVersionStr = safariVersionMatch[1]; const safariVersionStr = safariVersionMatch[2];