Open MuTsunTsai opened 1 week ago
@MuTsunTsai good catch! I will implement a solution for this. If you have any ideas of how to go about checking dynamically via regex or even a non regex solution (that doesn't use a table) would be much appreciated. Hope you are having a great weekend!
@MuTsunTsai - just to clarify too. Can you confirm on your browser (Windows 10) when ONLY using a national flag that the fallback support does NOT work on your device via a picture / screenshot? And if confirmed, do you know any other emojis that are not support in Windows? (Unicode 14 - etc...)
If you have any ideas of how to go about checking dynamically via regex
For the latest browsers, it will be /\p{RGI_Emoji_Flag_Sequence}/v
, but the support is limited (see caniuse). For better browser compatibility, use /[\u{1f1e6}-\u{1f1ff}]{2}/u
, or even /(?:\ud83c[\udde6-\uddff]){2}/
.
Can you confirm on your browser (Windows 10) when ONLY using a national flag that the fallback support does NOT work on your device via a picture / screenshot?
Do you know any other emojis that are not support in Windows?
I just checked the list here, and the followings also are not rendered as emoji, but only as ugly Unicode characters.
โบ โ โ โ โ ยฉ ยฎ โข โซ โช
While the followings get rendered sometimes, but not always. (I don't know why. Maybe it depends on the context.)
โ ๏ธ โฅ๏ธ โฆ๏ธ โฃ๏ธ โ โ ใฐ
@MuTsunTsai - thank you very much.
Can I get you to possibly test this?
/*
Notes to self:
imageData = imageData[0] !== 0; // Check if there's any color
imageData = imageData[3] !== 0; // Check transparency (alpha channel)
*/
export const emojisSupported = () => {
const emojiList = [
'\ud83d\ude03', // ๐ Grinning Face with Smiling Eyes
'\u1f1fa\u1f1f8', // ๐บ๐ธ United States Flag
'๐ฉโ๐ฆฐ', // Woman with red hair
'๐จโ๐ฉโ๐งโ๐ฆ', // Family emoji
'๐ฉ', // Single character (woman)
'๐ซฃ' // Face with peeking eye
];
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Check if canvas and fillText method are available
if (!ctx || typeof ctx.fillText !== 'function') {
canvas.remove();
return false;
}
ctx.textBaseline = 'top';
ctx.font = '32px Arial';
// Loop through the emojiList and check each emoji
for (let emoji of emojiList) {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas before each test
ctx.fillText(emoji, 0, 0);
// Get the pixel data from the canvas at position (0, 0)
let imageData = ctx.getImageData(0, 0, 1, 1).data;
// Check if any pixels
if (imageData[0] !== 0) {
// Emoji is supported
canvas.remove();
return true;
}
}
// No emoji in the list was supported
canvas.remove();
return false;
};
console.log(emojiSupported2())
@MarketingPip There are several issues with this code (other than the obvious typo of function name).
'\u{1f1fa}\u{1f1f8}'
instead, as \uXXXX
format only takes 4 characters that follows.Also, when it comes to cross-platform testing, I'd highly recommend BrowserStack. As an open-source project author, you can apply for their free plan here.
@MuTsunTsai - you do NOT need to draw ALL of them.. (this only draws 1 emoji and tests if it was rendered). Which that code above should cover newer version of emojis.
Please do verify with the function I gave you if you return a true statement...
@MarketingPip The function as it is, it returns false
(especially because of point 3 I mentioned).
Now assuming that you changed it to test (16,16) instead. Then the very first emoji "๐" already makes the function returning true
inside the loop, so the rest of the checks are pointless. Get it?
@MuTsunTsai - yo my bad, I sent you wrong code ๐คฆ (Thank you for bearing with me too)
/*
Notes to self:
imageData = imageData[0] !== 0; // Check if there's any color
imageData = imageData[3] !== 0; // Check transparency (alpha channel)
*/
export const emojiSupported2 = () => {
const emojiList = [
'\ud83d\ude03', // ๐ Grinning Face with Smiling Eyes
'\u1f1fa\u1f1f8', // ๐บ๐ธ United States Flag
'๐ฉโ๐ฆฐ', // Woman with red hair
'๐จโ๐ฉโ๐งโ๐ฆ', // Family emoji
'๐ฉ', // Single character (woman)
'๐ซฃ' // Face with peeking eye
];
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Check if canvas and fillText method are available
if (!ctx || typeof ctx.fillText !== 'function') {
canvas.remove();
return false;
}
ctx.textBaseline = 'top';
ctx.font = '32px Arial';
// Loop through the emojiList and check each emoji
for (let emoji of emojiList) {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas before each test
ctx.fillText(emoji, 0, 0);
// Get the pixel data from the canvas at position (0, 0)
let imageData = ctx.getImageData(16, 16, 1, 1).data;
// Check if any pixels
if (imageData[0] !== 0) {
// Emoji is supported
canvas.remove();
return true;
}
}
// No emoji in the list was supported
canvas.remove();
return false;
};
console.log(emojiSupported2())
\u{1f1fa}\u{1f1f8}
for proper ES6 syntax. And I didn't catch what you were saying but I get what you mean now.
Would you prefer the code do a check like this?
export const emojiSupported2 = () => {
const emojiList = [
'\ud83d\ude03', // ๐ Grinning Face with Smiling Eyes
'\u1f1fa\u1f1f8', // ๐บ๐ธ United States Flag
'๐ฉโ๐ฆฐ', // Woman with red hair
'๐จโ๐ฉโ๐งโ๐ฆ', // Family emoji
'๐ฉ', // Single character (woman)
'๐ซฃ' // Face with peeking eye
];
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Check if canvas and fillText method are available
if (!ctx || typeof ctx.fillText !== 'function') {
canvas.remove();
return false;
}
ctx.textBaseline = 'top';
ctx.font = '32px Arial';
// Loop through the emojiList and check each emoji
for (let emoji of emojiList) {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas before each test
ctx.fillText(emoji, 0, 0);
// Get the pixel data from the canvas at position (0, 0)
let imageData = ctx.getImageData(16, 16, 1, 1).data;
// Check if any pixels
if (imageData[0] === 0) {
// Emoji is NOT supported
canvas.remove();
return false
}
}
// All emoji in the list were supported
canvas.remove();
return true
};
@MuTsunTsai - see the above comment (we posted at same minute / second lol!)
@MarketingPip Yeah, the logic of the last version makes much more sense.
@MuTsunTsai - thank you! (my apologizes too for not understanding off first bat - and replying sounding like an assh*le above! - 2AM here lol).
Very good catch. I can gladly implement this or I more than welcome you too being you did help solve this issue. (If you would like to earn a PR etc - I just ask you to follow my style of commit messages / changes etc).
Feel free to let me know - if you're not interested, I can wrap this up by tomorrow ๐
@MarketingPip It's OK. Sure, I can certainly make a PR, but before that, I have one more suggestion.
Basically, as it is right now, it checks "whether any of the listed emojis is not supported", and if so, it will call the underlying twemoji and replace ALL emojis on the page. This seems overkill, however, for the present issue here. For Windows, it suffices to replace just the flags, as almost all the rest are supported. If you agree, this can be implemented as follows:
twemoji.parse
with the options object instead, which one can assign a callback function to filter out those emojis that are not flags (see here for example), so that only flags are replaced.Let me know if this sounds right, and then I will make the PR.
@MuTsunTsai - this seems more then reasonable to me! Please do verify on your system before making the PR that certain emojis are being parsed / replaced.
And please do use this commit message for changes to the source code:
Updated emoji-fallback.js ๐ฅ
@MarketingPip Done. Meanwhile, one more minor thing. According to the docs, the method twemoji.parse
always runs synchronously, so there's no need to await
it. (This is irrelevant to the present issue, so I didn't touch that part.)
@MuTsunTsai - parseEmoji() allows it to be awaited / tho is not needed. Reason why it allows to be awaited so developers can add support for example awaiting for emojis to render while loading screen etc... (OR if they prefer not too - simply just not use await infront)
Describe the bug On Windows 10+, although there is native support for most of the emoji, the national flags such as ๐น๐ผ are not really "supported" and one will only see two characters instead of the actual flag. For the moment Emoji-Fallback doesn't handle that, as it only checks whether "๐" is rendered correctly. It will be good if Emoji-Fallback can handle the flags separately.