mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Refactor Intl polyfills and remove from ES5 entrypoints (#16349)
This commit is contained in:
parent
f185e886c3
commit
d2321b535c
@ -132,6 +132,17 @@ const createWebpackConfig = ({
|
|||||||
),
|
),
|
||||||
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
||||||
),
|
),
|
||||||
|
// See `src/resources/intl-polyfill-legacy.ts` for explanation
|
||||||
|
!latestBuild &&
|
||||||
|
new webpack.NormalModuleReplacementPlugin(
|
||||||
|
new RegExp(
|
||||||
|
path.resolve(paths.polymer_dir, "src/resources/intl-polyfill.ts")
|
||||||
|
),
|
||||||
|
path.resolve(
|
||||||
|
paths.polymer_dir,
|
||||||
|
"src/resources/intl-polyfill-legacy.ts"
|
||||||
|
)
|
||||||
|
),
|
||||||
!isProdBuild && new LogStartCompilePlugin(),
|
!isProdBuild && new LogStartCompilePlugin(),
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
resolve: {
|
resolve: {
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import { getWeekStartByLocale } from "weekstart";
|
import { getWeekStartByLocale } from "weekstart";
|
||||||
import { FrontendLocaleData, FirstWeekday } from "../../data/translation";
|
import { FrontendLocaleData, FirstWeekday } from "../../data/translation";
|
||||||
|
|
||||||
import { polyfillsLoaded } from "../translations/localize";
|
import "../../resources/intl-polyfill";
|
||||||
|
|
||||||
if (__BUILD__ === "latest" && polyfillsLoaded) {
|
|
||||||
await polyfillsLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const weekdays = [
|
export const weekdays = [
|
||||||
"sunday",
|
"sunday",
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { FrontendLocaleData } from "../../data/translation";
|
import { FrontendLocaleData } from "../../data/translation";
|
||||||
import { polyfillsLoaded } from "../translations/localize";
|
import "../../resources/intl-polyfill";
|
||||||
|
|
||||||
if (__BUILD__ === "latest" && polyfillsLoaded) {
|
|
||||||
await polyfillsLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tuesday, August 10
|
// Tuesday, August 10
|
||||||
export const formatDateWeekdayDay = (
|
export const formatDateWeekdayDay = (
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { FrontendLocaleData } from "../../data/translation";
|
import { FrontendLocaleData } from "../../data/translation";
|
||||||
import { polyfillsLoaded } from "../translations/localize";
|
import "../../resources/intl-polyfill";
|
||||||
import { useAmPm } from "./use_am_pm";
|
import { useAmPm } from "./use_am_pm";
|
||||||
|
|
||||||
if (__BUILD__ === "latest" && polyfillsLoaded) {
|
|
||||||
await polyfillsLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
// August 9, 2021, 8:23 AM
|
// August 9, 2021, 8:23 AM
|
||||||
export const formatDateTime = (dateObj: Date, locale: FrontendLocaleData) =>
|
export const formatDateTime = (dateObj: Date, locale: FrontendLocaleData) =>
|
||||||
formatDateTimeMem(locale).format(dateObj);
|
formatDateTimeMem(locale).format(dateObj);
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { FrontendLocaleData } from "../../data/translation";
|
import { FrontendLocaleData } from "../../data/translation";
|
||||||
import { polyfillsLoaded } from "../translations/localize";
|
import "../../resources/intl-polyfill";
|
||||||
import { useAmPm } from "./use_am_pm";
|
import { useAmPm } from "./use_am_pm";
|
||||||
|
|
||||||
if (__BUILD__ === "latest" && polyfillsLoaded) {
|
|
||||||
await polyfillsLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 9:15 PM || 21:15
|
// 9:15 PM || 21:15
|
||||||
export const formatTime = (dateObj: Date, locale: FrontendLocaleData) =>
|
export const formatTime = (dateObj: Date, locale: FrontendLocaleData) =>
|
||||||
formatTimeMem(locale).format(dateObj);
|
formatTimeMem(locale).format(dateObj);
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { FrontendLocaleData } from "../../data/translation";
|
import { FrontendLocaleData } from "../../data/translation";
|
||||||
import { polyfillsLoaded } from "../translations/localize";
|
import "../../resources/intl-polyfill";
|
||||||
import { selectUnit } from "../util/select-unit";
|
import { selectUnit } from "../util/select-unit";
|
||||||
|
|
||||||
if (__BUILD__ === "latest" && polyfillsLoaded) {
|
|
||||||
await polyfillsLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatRelTimeMem = memoizeOne(
|
const formatRelTimeMem = memoizeOne(
|
||||||
(locale: FrontendLocaleData) =>
|
(locale: FrontendLocaleData) =>
|
||||||
new Intl.RelativeTimeFormat(locale.language, { numeric: "auto" })
|
new Intl.RelativeTimeFormat(locale.language, { numeric: "auto" })
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
import { shouldPolyfill as shouldPolyfillLocale } from "@formatjs/intl-locale/lib/should-polyfill";
|
|
||||||
import { shouldPolyfill as shouldPolyfillPluralRules } from "@formatjs/intl-pluralrules/lib/should-polyfill";
|
|
||||||
import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-relativetimeformat/lib/should-polyfill";
|
|
||||||
import { shouldPolyfill as shouldPolyfillDateTime } from "@formatjs/intl-datetimeformat/lib/should-polyfill";
|
|
||||||
import { shouldPolyfill as shouldPolyfillDisplayName } from "@formatjs/intl-displaynames/lib/should-polyfill";
|
|
||||||
import IntlMessageFormat from "intl-messageformat";
|
import IntlMessageFormat from "intl-messageformat";
|
||||||
|
import { polyfillLocaleData } from "../../resources/locale-data-polyfill";
|
||||||
import { Resources, TranslationDict } from "../../types";
|
import { Resources, TranslationDict } from "../../types";
|
||||||
import { getLocalLanguage } from "../../util/common-translation";
|
|
||||||
|
|
||||||
// Exclude some patterns from key type checking for now
|
// Exclude some patterns from key type checking for now
|
||||||
// These are intended to be removed as errors are fixed
|
// These are intended to be removed as errors are fixed
|
||||||
@ -64,40 +59,6 @@ export interface FormatsType {
|
|||||||
time: FormatType;
|
time: FormatType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadedPolyfillLocale = new Set();
|
|
||||||
|
|
||||||
const locale = getLocalLanguage();
|
|
||||||
|
|
||||||
const polyfills: Promise<any>[] = [];
|
|
||||||
if (__BUILD__ === "latest") {
|
|
||||||
if (shouldPolyfillLocale()) {
|
|
||||||
await import("@formatjs/intl-locale/polyfill");
|
|
||||||
}
|
|
||||||
if (shouldPolyfillPluralRules(locale)) {
|
|
||||||
polyfills.push(import("@formatjs/intl-pluralrules/polyfill"));
|
|
||||||
polyfills.push(import("@formatjs/intl-pluralrules/locale-data/en"));
|
|
||||||
}
|
|
||||||
if (shouldPolyfillRelativeTime(locale)) {
|
|
||||||
polyfills.push(import("@formatjs/intl-relativetimeformat/polyfill"));
|
|
||||||
}
|
|
||||||
if (shouldPolyfillDateTime(locale)) {
|
|
||||||
polyfills.push(import("@formatjs/intl-datetimeformat/polyfill"));
|
|
||||||
polyfills.push(import("@formatjs/intl-datetimeformat/add-all-tz"));
|
|
||||||
}
|
|
||||||
if (shouldPolyfillDisplayName(locale)) {
|
|
||||||
polyfills.push(import("@formatjs/intl-displaynames/polyfill"));
|
|
||||||
polyfills.push(import("@formatjs/intl-displaynames/locale-data/en"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const polyfillsLoaded =
|
|
||||||
polyfills.length === 0
|
|
||||||
? undefined
|
|
||||||
: Promise.all(polyfills).then(() =>
|
|
||||||
// Load the default language
|
|
||||||
loadPolyfillLocales(locale)
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapted from Polymer app-localize-behavior.
|
* Adapted from Polymer app-localize-behavior.
|
||||||
*
|
*
|
||||||
@ -125,11 +86,9 @@ export const computeLocalize = async <Keys extends string = LocalizeKeys>(
|
|||||||
resources: Resources,
|
resources: Resources,
|
||||||
formats?: FormatsType
|
formats?: FormatsType
|
||||||
): Promise<LocalizeFunc<Keys>> => {
|
): Promise<LocalizeFunc<Keys>> => {
|
||||||
if (polyfillsLoaded) {
|
await import("../../resources/intl-polyfill").then(() =>
|
||||||
await polyfillsLoaded;
|
polyfillLocaleData(language)
|
||||||
}
|
);
|
||||||
|
|
||||||
await loadPolyfillLocales(language);
|
|
||||||
|
|
||||||
// Every time any of the parameters change, invalidate the strings cache.
|
// Every time any of the parameters change, invalidate the strings cache.
|
||||||
cache._localizationCache = {};
|
cache._localizationCache = {};
|
||||||
@ -181,58 +140,3 @@ export const computeLocalize = async <Keys extends string = LocalizeKeys>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadPolyfillLocales = async (language: string) => {
|
|
||||||
if (loadedPolyfillLocale.has(language)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
loadedPolyfillLocale.add(language);
|
|
||||||
try {
|
|
||||||
if (
|
|
||||||
Intl.NumberFormat &&
|
|
||||||
// @ts-ignore
|
|
||||||
typeof Intl.NumberFormat.__addLocaleData === "function"
|
|
||||||
) {
|
|
||||||
const result = await fetch(
|
|
||||||
`/static/locale-data/intl-numberformat/${language}.json`
|
|
||||||
);
|
|
||||||
// @ts-ignore
|
|
||||||
Intl.NumberFormat.__addLocaleData(await result.json());
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
Intl.RelativeTimeFormat &&
|
|
||||||
// @ts-ignore
|
|
||||||
typeof Intl.RelativeTimeFormat.__addLocaleData === "function"
|
|
||||||
) {
|
|
||||||
const result = await fetch(
|
|
||||||
`/static/locale-data/intl-relativetimeformat/${language}.json`
|
|
||||||
);
|
|
||||||
// @ts-ignore
|
|
||||||
Intl.RelativeTimeFormat.__addLocaleData(await result.json());
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
Intl.DateTimeFormat &&
|
|
||||||
// @ts-ignore
|
|
||||||
typeof Intl.DateTimeFormat.__addLocaleData === "function"
|
|
||||||
) {
|
|
||||||
const result = await fetch(
|
|
||||||
`/static/locale-data/intl-datetimeformat/${language}.json`
|
|
||||||
);
|
|
||||||
// @ts-ignore
|
|
||||||
Intl.DateTimeFormat.__addLocaleData(await result.json());
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
Intl.DisplayNames &&
|
|
||||||
// @ts-ignore
|
|
||||||
typeof Intl.DisplayNames.__addLocaleData === "function"
|
|
||||||
) {
|
|
||||||
const result = await fetch(
|
|
||||||
`/static/locale-data/intl-displaynames/${language}.json`
|
|
||||||
);
|
|
||||||
// @ts-ignore
|
|
||||||
Intl.DisplayNames.__addLocaleData(await result.json());
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
@ -3,21 +3,6 @@ import "core-js";
|
|||||||
import "regenerator-runtime/runtime";
|
import "regenerator-runtime/runtime";
|
||||||
import "lit/polyfill-support";
|
import "lit/polyfill-support";
|
||||||
|
|
||||||
// For localize & formatting
|
|
||||||
import "@formatjs/intl-getcanonicallocales/polyfill";
|
|
||||||
import "@formatjs/intl-locale/polyfill";
|
|
||||||
import "@formatjs/intl-pluralrules/polyfill";
|
|
||||||
import "@formatjs/intl-pluralrules/locale-data/en";
|
|
||||||
import "@formatjs/intl-numberformat/polyfill";
|
|
||||||
import "@formatjs/intl-numberformat/locale-data/en";
|
|
||||||
import "@formatjs/intl-relativetimeformat/polyfill";
|
|
||||||
import "@formatjs/intl-relativetimeformat/locale-data/en";
|
|
||||||
import "@formatjs/intl-datetimeformat/polyfill";
|
|
||||||
import "@formatjs/intl-datetimeformat/locale-data/en";
|
|
||||||
import "@formatjs/intl-datetimeformat/add-all-tz";
|
|
||||||
import "@formatjs/intl-displaynames/polyfill";
|
|
||||||
import "@formatjs/intl-displaynames/locale-data/en";
|
|
||||||
|
|
||||||
// To use comlink under ES5
|
// To use comlink under ES5
|
||||||
import "proxy-polyfill";
|
import "proxy-polyfill";
|
||||||
import "unfetch/polyfill";
|
import "unfetch/polyfill";
|
||||||
|
17
src/resources/intl-polyfill-legacy.ts
Normal file
17
src/resources/intl-polyfill-legacy.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// This module is a simpler version of `intl-polyfill` without top level await, and replaces it for legacy builds.
|
||||||
|
// Babel cannot transform TLA, and Webpack uses an async function to support it,
|
||||||
|
// so builds with browser targets without async support will be broken.
|
||||||
|
|
||||||
|
import "@formatjs/intl-getcanonicallocales/polyfill";
|
||||||
|
import "@formatjs/intl-locale/polyfill";
|
||||||
|
import "@formatjs/intl-pluralrules/polyfill";
|
||||||
|
import "@formatjs/intl-pluralrules/locale-data/en";
|
||||||
|
import "@formatjs/intl-numberformat/polyfill";
|
||||||
|
import "@formatjs/intl-numberformat/locale-data/en";
|
||||||
|
import "@formatjs/intl-relativetimeformat/polyfill";
|
||||||
|
import "@formatjs/intl-relativetimeformat/locale-data/en";
|
||||||
|
import "@formatjs/intl-datetimeformat/polyfill";
|
||||||
|
import "@formatjs/intl-datetimeformat/locale-data/en";
|
||||||
|
import "@formatjs/intl-datetimeformat/add-all-tz";
|
||||||
|
import "@formatjs/intl-displaynames/polyfill";
|
||||||
|
import "@formatjs/intl-displaynames/locale-data/en";
|
46
src/resources/intl-polyfill.ts
Normal file
46
src/resources/intl-polyfill.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { shouldPolyfill as shouldPolyfillDateTime } from "@formatjs/intl-datetimeformat/lib/should-polyfill";
|
||||||
|
import { shouldPolyfill as shouldPolyfillDisplayName } from "@formatjs/intl-displaynames/lib/should-polyfill";
|
||||||
|
import { shouldPolyfill as shouldPolyfillLocale } from "@formatjs/intl-locale/lib/should-polyfill";
|
||||||
|
import { shouldPolyfill as shouldPolyfillPluralRules } from "@formatjs/intl-pluralrules/lib/should-polyfill";
|
||||||
|
import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-relativetimeformat/lib/should-polyfill";
|
||||||
|
import { getLocalLanguage } from "../util/common-translation";
|
||||||
|
import { polyfillLocaleData } from "./locale-data-polyfill";
|
||||||
|
|
||||||
|
const polyfillIntl = async () => {
|
||||||
|
const locale = getLocalLanguage();
|
||||||
|
const polyfills: Promise<unknown>[] = [];
|
||||||
|
|
||||||
|
if (shouldPolyfillLocale()) {
|
||||||
|
await import("@formatjs/intl-locale/polyfill-force");
|
||||||
|
}
|
||||||
|
if (shouldPolyfillPluralRules(locale)) {
|
||||||
|
polyfills.push(
|
||||||
|
import("@formatjs/intl-pluralrules/polyfill-force").then(
|
||||||
|
() => import("@formatjs/intl-pluralrules/locale-data/en")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (shouldPolyfillRelativeTime(locale)) {
|
||||||
|
polyfills.push(import("@formatjs/intl-relativetimeformat/polyfill-force"));
|
||||||
|
}
|
||||||
|
if (shouldPolyfillDateTime(locale)) {
|
||||||
|
polyfills.push(
|
||||||
|
import("@formatjs/intl-datetimeformat/polyfill-force").then(
|
||||||
|
() => import("@formatjs/intl-datetimeformat/add-all-tz")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (shouldPolyfillDisplayName(locale)) {
|
||||||
|
polyfills.push(
|
||||||
|
import("@formatjs/intl-displaynames/polyfill-force").then(
|
||||||
|
() => import("@formatjs/intl-displaynames/locale-data/en")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await Promise.all(polyfills).then(() =>
|
||||||
|
// Load the default language
|
||||||
|
polyfillLocaleData(locale)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
await polyfillIntl();
|
59
src/resources/locale-data-polyfill.ts
Normal file
59
src/resources/locale-data-polyfill.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Loads the static locale data for a given language from FormatJS
|
||||||
|
// Parents need to load polyfills first; they are not imported here to avoid a circular reference
|
||||||
|
|
||||||
|
const loadedPolyfillLocale = new Set();
|
||||||
|
|
||||||
|
export const polyfillLocaleData = async (language: string) => {
|
||||||
|
if (loadedPolyfillLocale.has(language)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadedPolyfillLocale.add(language);
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
Intl.NumberFormat &&
|
||||||
|
// @ts-ignore
|
||||||
|
typeof Intl.NumberFormat.__addLocaleData === "function"
|
||||||
|
) {
|
||||||
|
const result = await fetch(
|
||||||
|
`/static/locale-data/intl-numberformat/${language}.json`
|
||||||
|
);
|
||||||
|
// @ts-ignore
|
||||||
|
Intl.NumberFormat.__addLocaleData(await result.json());
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Intl.RelativeTimeFormat &&
|
||||||
|
// @ts-ignore
|
||||||
|
typeof Intl.RelativeTimeFormat.__addLocaleData === "function"
|
||||||
|
) {
|
||||||
|
const result = await fetch(
|
||||||
|
`/static/locale-data/intl-relativetimeformat/${language}.json`
|
||||||
|
);
|
||||||
|
// @ts-ignore
|
||||||
|
Intl.RelativeTimeFormat.__addLocaleData(await result.json());
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Intl.DateTimeFormat &&
|
||||||
|
// @ts-ignore
|
||||||
|
typeof Intl.DateTimeFormat.__addLocaleData === "function"
|
||||||
|
) {
|
||||||
|
const result = await fetch(
|
||||||
|
`/static/locale-data/intl-datetimeformat/${language}.json`
|
||||||
|
);
|
||||||
|
// @ts-ignore
|
||||||
|
Intl.DateTimeFormat.__addLocaleData(await result.json());
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Intl.DisplayNames &&
|
||||||
|
// @ts-ignore
|
||||||
|
typeof Intl.DisplayNames.__addLocaleData === "function"
|
||||||
|
) {
|
||||||
|
const result = await fetch(
|
||||||
|
`/static/locale-data/intl-displaynames/${language}.json`
|
||||||
|
);
|
||||||
|
// @ts-ignore
|
||||||
|
Intl.DisplayNames.__addLocaleData(await result.json());
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
};
|
@ -10,7 +10,6 @@ import {
|
|||||||
subscribeServices,
|
subscribeServices,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { polyfillsLoaded } from "../common/translations/localize";
|
|
||||||
import { subscribeAreaRegistry } from "../data/area_registry";
|
import { subscribeAreaRegistry } from "../data/area_registry";
|
||||||
import { broadcastConnectionStatus } from "../data/connection-status";
|
import { broadcastConnectionStatus } from "../data/connection-status";
|
||||||
import { subscribeDeviceRegistry } from "../data/device_registry";
|
import { subscribeDeviceRegistry } from "../data/device_registry";
|
||||||
@ -224,17 +223,12 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
});
|
});
|
||||||
subscribeConfig(conn, (config) => {
|
subscribeConfig(conn, (config) => {
|
||||||
if (this.hass?.config?.time_zone !== config.time_zone) {
|
if (this.hass?.config?.time_zone !== config.time_zone) {
|
||||||
if (__BUILD__ === "latest" && polyfillsLoaded) {
|
import("../resources/intl-polyfill").then(() => {
|
||||||
polyfillsLoaded.then(() => {
|
if ("__setDefaultTimeZone" in Intl.DateTimeFormat) {
|
||||||
if ("__setDefaultTimeZone" in Intl.DateTimeFormat) {
|
// @ts-ignore
|
||||||
// @ts-ignore
|
Intl.DateTimeFormat.__setDefaultTimeZone(config.time_zone);
|
||||||
Intl.DateTimeFormat.__setDefaultTimeZone(config.time_zone);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
} else if ("__setDefaultTimeZone" in Intl.DateTimeFormat) {
|
|
||||||
// @ts-ignore
|
|
||||||
Intl.DateTimeFormat.__setDefaultTimeZone(config.time_zone);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this._updateHass({ config });
|
this._updateHass({ config });
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user