feat(web): translations containing html (#10491)

* feat(web): translations containing html

* add tests and more translations

* more translations

* rename FormatTags --> FormatMessage

* update version_announcement_message
This commit is contained in:
Michel Heusschen 2024-06-21 22:08:36 +02:00 committed by GitHub
parent 1129020159
commit b3252ffdac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 313 additions and 101 deletions

View file

@ -0,0 +1,57 @@
<script lang="ts">
import { IntlMessageFormat, type FormatXMLElementFn, type PrimitiveType } from 'intl-messageformat';
import { TYPE, type MessageFormatElement } from '@formatjs/icu-messageformat-parser';
import { locale as i18nLocale } from 'svelte-i18n';
type InterpolationValues = Record<string, PrimitiveType | FormatXMLElementFn<unknown>>;
export let message: unknown;
export let values: InterpolationValues = {};
const getLocale = (locale?: string | null) => {
if (locale == null) {
throw new Error('Cannot format a message without first setting the initial locale.');
}
return locale;
};
const getElements = (message: unknown, locale: string): MessageFormatElement[] => {
return new IntlMessageFormat(message as string, locale, undefined, {
ignoreTag: false,
}).getAst();
};
const getParts = (message: unknown, locale: string) => {
try {
const elements = getElements(message, locale);
return elements.map((element) => {
const isTag = element.type === TYPE.tag;
return {
tag: isTag ? element.value : undefined,
message: new IntlMessageFormat(isTag ? element.children : [element], locale, undefined, {
ignoreTag: true,
}).format(values) as string,
};
});
} catch (error) {
if (error instanceof Error) {
console.warn(`Message "${message}" has syntax error:`, error.message);
}
return [{ message: message as string, tag: undefined }];
}
};
$: locale = getLocale($i18nLocale);
$: parts = getParts(message, locale);
</script>
{#each parts as { tag, message }}
{#if tag}
<slot {tag} {message}>{message}</slot>
{:else}
{message}
{/if}
{/each}