notion-enhancer/repo/emoji-sets/client.mjs

72 lines
2.7 KiB
JavaScript

/**
* notion-enhancer: emoji sets
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (https://notion-enhancer.github.io/) under the MIT license
*/
export default async function ({ web, env }, db) {
const style = await db.get(['style']),
// real emojis are used on macos instead of the twitter set
nativeEmojiSelector = `[aria-label][role="image"][style*="Apple Color Emoji"]:not([data-emoji-sets-unsupported])`,
imgEmojiSelector = '.notion-emoji:not([data-emoji-sets-unsupported])',
imgEmojiOverlaySelector = `${imgEmojiSelector} + [src*="notion-emojis"]`;
await Promise.any([web.whenReady([nativeEmojiSelector]), web.whenReady([imgEmojiSelector])]);
const nativeEmojis = document.querySelectorAll(nativeEmojiSelector).length,
imgEmojis = document.querySelectorAll(imgEmojiSelector).length;
const unsupportedEmojis = [],
emojiReqs = new Map(),
getEmoji = async (emoji) => {
emoji = encodeURIComponent(emoji);
if (unsupportedEmojis.includes(emoji)) return undefined;
try {
if (!emojiReqs.get(emoji)) {
emojiReqs.set(emoji, fetch(`https://emojicdn.elk.sh/${emoji}?style=${style}`));
}
const res = await emojiReqs.get(emoji);
if (!res.ok) throw new Error();
return `url("https://emojicdn.elk.sh/${emoji}?style=${style}") 100% 100% / 100%`;
} catch {
unsupportedEmojis.push(emoji);
return undefined;
}
};
if (nativeEmojis) {
const updateEmojis = async () => {
const $emojis = document.querySelectorAll(nativeEmojiSelector);
for (const $emoji of $emojis) {
const emojiSrc = await getEmoji($emoji.ariaLabel);
if (emojiSrc) {
$emoji.style.background = emojiSrc;
$emoji.style.width = '1em';
$emoji.style.height = '1em';
$emoji.style.display = 'inline-block';
$emoji.innerText = '';
} else $emoji.dataset.emojiSetsUnsupported = true;
}
};
web.addDocumentObserver(updateEmojis, [nativeEmojiSelector]);
}
if (style !== 'twitter' && imgEmojis) {
const updateEmojis = async () => {
const $emojis = document.querySelectorAll(imgEmojiSelector);
for (const $emoji of $emojis) {
const emojiSrc = await getEmoji($emoji.ariaLabel);
if (emojiSrc) {
$emoji.style.background = emojiSrc;
$emoji.style.opacity = 1;
if ($emoji.nextElementSibling?.matches?.(imgEmojiOverlaySelector)) {
$emoji.nextElementSibling.style.opacity = 0;
}
} else $emoji.dataset.emojiSetsUnsupported = true;
}
};
updateEmojis();
web.addDocumentObserver(updateEmojis, [imgEmojiSelector, imgEmojiOverlaySelector]);
}
}