mirror of
https://github.com/mastodon/mastodon.git
synced 2025-09-06 18:01:05 +00:00
Provides legacy fallback for browser that don't support regex flag v (#35659)
This commit is contained in:
parent
cb0b608fa7
commit
28b0e5ee78
|
@ -15,17 +15,6 @@ export const SKIN_TONE_CODES = [
|
|||
0x1f3ff, // Dark skin tone
|
||||
] as const;
|
||||
|
||||
// TODO: Test and create fallback for browsers that do not handle the /v flag.
|
||||
export const UNICODE_EMOJI_REGEX = /\p{RGI_Emoji}/v;
|
||||
// See: https://www.unicode.org/reports/tr51/#valid-emoji-tag-sequences
|
||||
export const UNICODE_FLAG_EMOJI_REGEX =
|
||||
/\p{RGI_Emoji_Flag_Sequence}|\p{RGI_Emoji_Tag_Sequence}/v;
|
||||
export const CUSTOM_EMOJI_REGEX = /:([a-z0-9_]+):/i;
|
||||
export const ANY_EMOJI_REGEX = new RegExp(
|
||||
`(${UNICODE_EMOJI_REGEX.source}|${CUSTOM_EMOJI_REGEX.source})`,
|
||||
'gv',
|
||||
);
|
||||
|
||||
// Emoji rendering modes. A mode is what we are using to render emojis, a style is what the user has selected.
|
||||
export const EMOJI_MODE_NATIVE = 'native';
|
||||
export const EMOJI_MODE_NATIVE_WITH_FLAGS = 'native-flags';
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
EMOJI_TYPE_UNICODE,
|
||||
EMOJI_TYPE_CUSTOM,
|
||||
EMOJI_STATE_MISSING,
|
||||
ANY_EMOJI_REGEX,
|
||||
} from './constants';
|
||||
import {
|
||||
searchCustomEmojisByShortcodes,
|
||||
|
@ -32,7 +31,12 @@ import type {
|
|||
LocaleOrCustom,
|
||||
UnicodeEmojiToken,
|
||||
} from './types';
|
||||
import { emojiLogger, stringHasAnyEmoji, stringHasUnicodeFlags } from './utils';
|
||||
import {
|
||||
anyEmojiRegex,
|
||||
emojiLogger,
|
||||
stringHasAnyEmoji,
|
||||
stringHasUnicodeFlags,
|
||||
} from './utils';
|
||||
|
||||
const log = emojiLogger('render');
|
||||
|
||||
|
@ -207,7 +211,7 @@ export function tokenizeText(text: string): TokenizedText {
|
|||
|
||||
const tokens = [];
|
||||
let lastIndex = 0;
|
||||
for (const match of text.matchAll(ANY_EMOJI_REGEX)) {
|
||||
for (const match of text.matchAll(anyEmojiRegex())) {
|
||||
if (match.index > lastIndex) {
|
||||
tokens.push(text.slice(lastIndex, match.index));
|
||||
}
|
||||
|
|
|
@ -1,23 +1,32 @@
|
|||
import debug from 'debug';
|
||||
|
||||
import {
|
||||
CUSTOM_EMOJI_REGEX,
|
||||
UNICODE_EMOJI_REGEX,
|
||||
UNICODE_FLAG_EMOJI_REGEX,
|
||||
} from './constants';
|
||||
import { emojiRegexPolyfill } from '@/mastodon/polyfills';
|
||||
|
||||
export function emojiLogger(segment: string) {
|
||||
return debug(`emojis:${segment}`);
|
||||
}
|
||||
|
||||
export function stringHasUnicodeEmoji(input: string): boolean {
|
||||
return UNICODE_EMOJI_REGEX.test(input);
|
||||
return new RegExp(EMOJI_REGEX, supportedFlags()).test(input);
|
||||
}
|
||||
|
||||
export function stringHasUnicodeFlags(input: string): boolean {
|
||||
return UNICODE_FLAG_EMOJI_REGEX.test(input);
|
||||
if (supportsRegExpSets()) {
|
||||
return new RegExp(
|
||||
'\\p{RGI_Emoji_Flag_Sequence}|\\p{RGI_Emoji_Tag_Sequence}',
|
||||
'v',
|
||||
).test(input);
|
||||
}
|
||||
return new RegExp(
|
||||
// First range is regional indicator symbols,
|
||||
// Second is a black flag + 0-9|a-z tag chars + cancel tag.
|
||||
// See: https://en.wikipedia.org/wiki/Regional_indicator_symbol
|
||||
'(?:\uD83C[\uDDE6-\uDDFF]){2}|\uD83C\uDFF4(?:\uDB40[\uDC30-\uDC7A])+\uDB40\uDC7F',
|
||||
).test(input);
|
||||
}
|
||||
|
||||
// Constant as this is supported by all browsers.
|
||||
const CUSTOM_EMOJI_REGEX = /:([a-z0-9_]+):/i;
|
||||
export function stringHasCustomEmoji(input: string) {
|
||||
return CUSTOM_EMOJI_REGEX.test(input);
|
||||
}
|
||||
|
@ -25,3 +34,23 @@ export function stringHasCustomEmoji(input: string) {
|
|||
export function stringHasAnyEmoji(input: string) {
|
||||
return stringHasUnicodeEmoji(input) || stringHasCustomEmoji(input);
|
||||
}
|
||||
|
||||
export function anyEmojiRegex() {
|
||||
return new RegExp(
|
||||
`${EMOJI_REGEX}|${CUSTOM_EMOJI_REGEX.source}`,
|
||||
supportedFlags('gi'),
|
||||
);
|
||||
}
|
||||
|
||||
function supportsRegExpSets() {
|
||||
return 'unicodeSets' in RegExp.prototype;
|
||||
}
|
||||
|
||||
function supportedFlags(flags = '') {
|
||||
if (supportsRegExpSets()) {
|
||||
return `${flags}v`;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
const EMOJI_REGEX = emojiRegexPolyfill?.source ?? '\\p{RGI_Emoji}';
|
||||
|
|
|
@ -20,5 +20,16 @@ export function loadPolyfills() {
|
|||
loadIntlPolyfills(),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- those properties might not exist in old browsers, even if they are always here in types
|
||||
needsExtraPolyfills && importExtraPolyfills(),
|
||||
loadEmojiPolyfills(),
|
||||
]);
|
||||
}
|
||||
|
||||
// In the case of no /v support, rely on the emojibase data.
|
||||
async function loadEmojiPolyfills() {
|
||||
if (!('unicodeSets' in RegExp.prototype)) {
|
||||
emojiRegexPolyfill = (await import('emojibase-regex/emoji')).default;
|
||||
}
|
||||
}
|
||||
|
||||
// Null unless polyfill is needed.
|
||||
export let emojiRegexPolyfill: RegExp | null = null;
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"emoji-mart": "npm:emoji-mart-lazyload@latest",
|
||||
"emojibase": "^16.0.0",
|
||||
"emojibase-data": "^16.0.3",
|
||||
"emojibase-regex": "^16.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"fast-glob": "^3.3.3",
|
||||
"fuzzysort": "^3.0.0",
|
||||
|
|
|
@ -2659,6 +2659,7 @@ __metadata:
|
|||
emoji-mart: "npm:emoji-mart-lazyload@latest"
|
||||
emojibase: "npm:^16.0.0"
|
||||
emojibase-data: "npm:^16.0.3"
|
||||
emojibase-regex: "npm:^16.0.0"
|
||||
escape-html: "npm:^1.0.3"
|
||||
eslint: "npm:^9.23.0"
|
||||
eslint-import-resolver-typescript: "npm:^4.2.5"
|
||||
|
@ -6565,6 +6566,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"emojibase-regex@npm:^16.0.0":
|
||||
version: 16.0.0
|
||||
resolution: "emojibase-regex@npm:16.0.0"
|
||||
checksum: 10c0/8ee5ff798e51caa581434b1cb2f9737e50195093c4efa1739df21a50a5496f80517924787d865e8cf7d6a0b4c90dbedc04bdc506dcbcc582e14cdf0bb47af0f0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"emojibase@npm:^16.0.0":
|
||||
version: 16.0.0
|
||||
resolution: "emojibase@npm:16.0.0"
|
||||
|
|
Loading…
Reference in New Issue
Block a user