diff --git a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
index 022c9baaf7..35804de82a 100644
--- a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
+++ b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js
@@ -22,23 +22,23 @@ describe('emoji', () => {
it('does unicode', () => {
expect(emojify('\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66')).toEqual(
- '');
+ '');
expect(emojify('๐จโ๐ฉโ๐งโ๐ง')).toEqual(
- '');
- expect(emojify('๐ฉโ๐ฉโ๐ฆ')).toEqual('');
+ '');
+ expect(emojify('๐ฉโ๐ฉโ๐ฆ')).toEqual('');
expect(emojify('\u2757')).toEqual(
- '');
+ '');
});
it('does multiple unicode', () => {
expect(emojify('\u2757 #\uFE0F\u20E3')).toEqual(
- ' ');
+ ' ');
expect(emojify('\u2757#\uFE0F\u20E3')).toEqual(
- '');
+ '');
expect(emojify('\u2757 #\uFE0F\u20E3 \u2757')).toEqual(
- ' ');
+ ' ');
expect(emojify('foo \u2757 #\uFE0F\u20E3 bar')).toEqual(
- 'foo bar');
+ 'foo bar');
});
it('ignores unicode inside of tags', () => {
@@ -46,16 +46,16 @@ describe('emoji', () => {
});
it('does multiple emoji properly (issue 5188)', () => {
- expect(emojify('๐๐๐')).toEqual('');
- expect(emojify('๐ ๐ ๐')).toEqual(' ');
+ expect(emojify('๐๐๐')).toEqual('');
+ expect(emojify('๐ ๐ ๐')).toEqual(' ');
});
it('does an emoji that has no shortcode', () => {
- expect(emojify('๐โ๐จ')).toEqual('');
+ expect(emojify('๐โ๐จ')).toEqual('');
});
it('does an emoji whose filename is irregular', () => {
- expect(emojify('โ๏ธ')).toEqual('');
+ expect(emojify('โ๏ธ')).toEqual('');
});
it('avoid emojifying on invisible text', () => {
@@ -67,11 +67,11 @@ describe('emoji', () => {
it('avoid emojifying on invisible text with nested tags', () => {
expect(emojify('๐bar๐ด๐'))
- .toEqual('๐bar๐ด');
+ .toEqual('๐bar๐ด');
expect(emojify('๐๐๐ด๐'))
- .toEqual('๐๐๐ด');
+ .toEqual('๐๐๐ด');
expect(emojify('๐
๐ด๐'))
- .toEqual('๐
๐ด');
+ .toEqual('๐
๐ด');
});
it('does not emojify emojis with textual presentation VS15 character', () => {
@@ -81,17 +81,17 @@ describe('emoji', () => {
it('does a simple emoji properly', () => {
expect(emojify('โโ'))
- .toEqual('');
+ .toEqual('');
});
it('does an emoji containing ZWJ properly', () => {
expect(emojify('๐โโ๏ธ๐โโ๏ธ'))
- .toEqual('');
+ .toEqual('');
});
it('keeps ordering as expected (issue fixed by PR 20677)', () => {
expect(emojify('
๐ #foo test: foo.
')) - .toEqual('#foo test: foo.
'); + .toEqual('#foo test: foo.
'); }); }); }); diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js index e4aad302f6..d1843c33bd 100644 --- a/app/javascript/mastodon/features/emoji/emoji.js +++ b/app/javascript/mastodon/features/emoji/emoji.js @@ -97,30 +97,30 @@ const emojifyTextNode = (node, customEmojis) => { const { filename, shortCode } = unicodeMapping[unicode_emoji]; const title = shortCode ? `:${shortCode}:` : ''; - replacement = document.createElement('picture'); - const isSystemTheme = !!document.body?.classList.contains('theme-system'); - if(isSystemTheme) { - let source = document.createElement('source'); - source.setAttribute('media', '(prefers-color-scheme: dark)'); - source.setAttribute('srcset', `${assetHost}/emoji/${emojiFilename(filename, "dark")}.svg`); - replacement.appendChild(source); - } + const theme = (isSystemTheme || document.body?.classList.contains('theme-mastodon-light')) ? 'light' : 'dark'; - let img = document.createElement('img'); + const imageFilename = emojiFilename(filename, theme); + + const img = document.createElement('img'); img.setAttribute('draggable', 'false'); img.setAttribute('class', 'emojione'); img.setAttribute('alt', unicode_emoji); img.setAttribute('title', title); + img.setAttribute('src', `${assetHost}/emoji/${imageFilename}.svg`); - let theme = "light"; + if (isSystemTheme && imageFilename !== emojiFilename(filename, 'dark')) { + replacement = document.createElement('picture'); - if(!isSystemTheme && !document.body?.classList.contains('theme-mastodon-light')) - theme = "dark"; - - img.setAttribute('src', `${assetHost}/emoji/${emojiFilename(filename, theme)}.svg`); - replacement.appendChild(img); + const source = document.createElement('source'); + source.setAttribute('media', '(prefers-color-scheme: dark)'); + source.setAttribute('srcset', `${assetHost}/emoji/${emojiFilename(filename, 'dark')}.svg`); + replacement.appendChild(source); + replacement.appendChild(img); + } else { + replacement = img; + } } // Add the processed-up-to-now string and the emoji replacement @@ -135,7 +135,7 @@ const emojifyTextNode = (node, customEmojis) => { }; const emojifyNode = (node, customEmojis) => { - for (const child of node.childNodes) { + for (const child of Array.from(node.childNodes)) { switch(child.nodeType) { case Node.TEXT_NODE: emojifyTextNode(child, customEmojis);