diff --git a/packages/base/src/locale/getLocale.js b/packages/base/src/locale/getLocale.js index d80470fd36eb..cb53e89ba24e 100644 --- a/packages/base/src/locale/getLocale.js +++ b/packages/base/src/locale/getLocale.js @@ -2,10 +2,20 @@ import detectNavigatorLanguage from "../util/detectNavigatorLanguage.js"; import { getLanguage as getConfigLanguage } from "../config/Language.js"; import Locale from "./Locale.js"; +const cache = new Map(); + +const getLocaleInstance = lang => { + if (!cache.has(lang)) { + cache.set(lang, new Locale(lang)); + } + + return cache.get(lang); +}; + const convertToLocaleOrNull = lang => { try { if (lang && typeof lang === "string") { - return new Locale(lang); + return getLocaleInstance(lang); } } catch (e) { // ignore @@ -22,7 +32,7 @@ const getLocale = lang => { } if (getConfigLanguage()) { - return new Locale(getConfigLanguage()); + return getLocaleInstance(getConfigLanguage()); } return convertToLocaleOrNull(detectNavigatorLanguage()); diff --git a/packages/localization/src/getCachedLocaleDataInstance.js b/packages/localization/src/getCachedLocaleDataInstance.js new file mode 100644 index 000000000000..007488b9db03 --- /dev/null +++ b/packages/localization/src/getCachedLocaleDataInstance.js @@ -0,0 +1,13 @@ +import LocaleData from "./LocaleData.js"; + +const cache = new Map(); + +const getCachedLocaleDataInstance = locale => { + if (!cache.has(locale)) { + cache.set(locale, LocaleData.getInstance(locale)); + } + + return cache.get(locale); +}; + +export default getCachedLocaleDataInstance; diff --git a/packages/main/src/Calendar.js b/packages/main/src/Calendar.js index e42b4a9c2c52..d181c3541f8b 100644 --- a/packages/main/src/Calendar.js +++ b/packages/main/src/Calendar.js @@ -4,7 +4,7 @@ import { fetchCldr } from "@ui5/webcomponents-base/dist/asset-registries/LocaleD import { getCalendarType } from "@ui5/webcomponents-base/dist/config/CalendarType.js"; import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; -import LocaleData from "@ui5/webcomponents-localization/dist/LocaleData.js"; +import getCachedLocaleDataInstance from "@ui5/webcomponents-localization/dist/getCachedLocaleDataInstance.js"; import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js"; import CalendarType from "@ui5/webcomponents-base/dist/types/CalendarType.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; @@ -209,8 +209,6 @@ class Calendar extends UI5Element { constructor() { super(); - this._oLocale = getLocale(); - this._oLocaleData = new LocaleData(this._oLocale); this._header = {}; this._header.onPressPrevious = this._handlePrevious.bind(this); this._header.onPressNext = this._handleNext.bind(this); @@ -235,6 +233,7 @@ class Calendar extends UI5Element { } onBeforeRendering() { + const localeData = getCachedLocaleDataInstance(getLocale()); const oYearFormat = DateFormat.getDateInstance({ format: "y", calendarType: this._primaryCalendarType }); const firstDayOfCalendarTimeStamp = this._getMinCalendarDate(); @@ -252,7 +251,7 @@ class Calendar extends UI5Element { this._oMonth.primaryCalendarType = this._primaryCalendarType; this._oMonth.minDate = this.minDate; this._oMonth.maxDate = this.maxDate; - this._header.monthText = this._oLocaleData.getMonths("wide", this._primaryCalendarType)[this._month]; + this._header.monthText = localeData.getMonths("wide", this._primaryCalendarType)[this._month]; this._header.yearText = oYearFormat.format(this._localDate, true); // month picker @@ -352,7 +351,8 @@ class Calendar extends UI5Element { } get _primaryCalendarType() { - return this.primaryCalendarType || getCalendarType() || LocaleData.getInstance(getLocale()).getPreferredCalendarType(); + const localeData = getCachedLocaleDataInstance(getLocale()); + return this.primaryCalendarType || getCalendarType() || localeData.getPreferredCalendarType(); } get _formatPattern() { diff --git a/packages/main/src/DatePicker.js b/packages/main/src/DatePicker.js index f412825a6460..60f6d4c3106f 100644 --- a/packages/main/src/DatePicker.js +++ b/packages/main/src/DatePicker.js @@ -4,7 +4,7 @@ import { fetchCldr } from "@ui5/webcomponents-base/dist/asset-registries/LocaleD import { getCalendarType } from "@ui5/webcomponents-base/dist/config/CalendarType.js"; import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; -import LocaleData from "@ui5/webcomponents-localization/dist/LocaleData.js"; +import getCachedLocaleDataInstance from "@ui5/webcomponents-localization/dist/getCachedLocaleDataInstance.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; import CalendarType from "@ui5/webcomponents-base/dist/types/CalendarType.js"; import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js"; @@ -761,7 +761,8 @@ class DatePicker extends UI5Element { } get _primaryCalendarType() { - return this.primaryCalendarType || getCalendarType() || LocaleData.getInstance(getLocale()).getPreferredCalendarType(); + const localeData = getCachedLocaleDataInstance(getLocale()); + return this.primaryCalendarType || getCalendarType() || localeData.getPreferredCalendarType(); } get _formatPattern() { diff --git a/packages/main/src/DateTimePicker.js b/packages/main/src/DateTimePicker.js index c3548661f55f..aee390969d7b 100644 --- a/packages/main/src/DateTimePicker.js +++ b/packages/main/src/DateTimePicker.js @@ -1,6 +1,6 @@ import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; -import LocaleData from "@ui5/webcomponents-localization/dist/LocaleData.js"; +import getCachedLocaleDataInstance from "@ui5/webcomponents-localization/dist/getCachedLocaleDataInstance.js"; import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js"; import "@ui5/webcomponents-icons/dist/date-time.js"; import { @@ -532,7 +532,8 @@ class DateTimePicker extends DatePicker { const hasHours = !!pattern.match(/H/i); const fallback = !pattern || !hasHours; - return fallback ? LocaleData.getInstance(getLocale()).getCombinedDateTimePattern("medium", "medium", this._primaryCalendarType) : pattern; + const localeData = getCachedLocaleDataInstance(getLocale()); + return fallback ? localeData.getCombinedDateTimePattern("medium", "medium", this._primaryCalendarType) : pattern; } /** diff --git a/packages/main/src/DayPicker.js b/packages/main/src/DayPicker.js index eab2b87d98e7..b4f7d77fabb1 100644 --- a/packages/main/src/DayPicker.js +++ b/packages/main/src/DayPicker.js @@ -4,7 +4,7 @@ import { fetchCldr } from "@ui5/webcomponents-base/dist/asset-registries/LocaleD import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; import { getFirstDayOfWeek } from "@ui5/webcomponents-base/dist/config/FormatSettings.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; -import LocaleData from "@ui5/webcomponents-localization/dist/LocaleData.js"; +import getCachedLocaleDataInstance from "@ui5/webcomponents-localization/dist/getCachedLocaleDataInstance.js"; import { getCalendarType } from "@ui5/webcomponents-base/dist/config/CalendarType.js"; import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import { @@ -56,6 +56,7 @@ const monthDiff = (startDate, endDate) => { */ const metadata = { tag: "ui5-daypicker", + languageAware: true, properties: /** @lends sap.ui.webcomponents.main.DayPicker.prototype */ { /** * A UNIX timestamp - seconds since 00:00:00 UTC on Jan 1, 1970. @@ -212,8 +213,6 @@ class DayPicker extends UI5Element { constructor() { super(); - this._oLocale = getLocale(); - this._oLocaleData = new LocaleData(this._oLocale); this._itemNav = new ItemNavigation(this, { rowSize: 7, @@ -249,6 +248,8 @@ class DayPicker extends UI5Element { } onBeforeRendering() { + const localeData = getCachedLocaleDataInstance(getLocale()); + let oCalDate, day, timestamp, @@ -261,7 +262,7 @@ class DayPicker extends UI5Element { let week = []; this._weekNumbers = []; let weekday; - const _monthsNameWide = this._oLocaleData.getMonths("wide", this._calendarDate._oUDate.sCalendarType); + const _monthsNameWide = localeData.getMonths("wide", this._calendarDate._oUDate.sCalendarType); this._minDateObject = new Date(this._minDate); this._maxDateObject = new Date(this._maxDate); @@ -335,7 +336,7 @@ class DayPicker extends UI5Element { if (day.classes.indexOf("ui5-dp-wday6") !== -1 || _aVisibleDays.length - 1 === i) { - const weekNumber = calculateWeekNumber(getFirstDayOfWeek(), oCalDate.toUTCJSDate(), oCalDate.getYear(), this._oLocale, this._oLocaleData); + const weekNumber = calculateWeekNumber(getFirstDayOfWeek(), oCalDate.toUTCJSDate(), oCalDate.getYear(), getLocale(), localeData); if (lastWeekNumber !== weekNumber) { const weekNum = { weekNum: weekNumber, @@ -358,8 +359,8 @@ class DayPicker extends UI5Element { this._itemNav.current = todayIndex; } - const aDayNamesWide = this._oLocaleData.getDays("wide", this._primaryCalendarType); - const aDayNamesAbbreviated = this._oLocaleData.getDays("abbreviated", this._primaryCalendarType); + const aDayNamesWide = localeData.getDays("wide", this._primaryCalendarType); + const aDayNamesAbbreviated = localeData.getDays("abbreviated", this._primaryCalendarType); const aUltraShortNames = aDayNamesAbbreviated.map(n => n); let dayName; @@ -607,7 +608,8 @@ class DayPicker extends UI5Element { } get _primaryCalendarType() { - return this.primaryCalendarType || getCalendarType() || LocaleData.getInstance(getLocale()).getPreferredCalendarType(); + const localeData = getCachedLocaleDataInstance(getLocale()); + return this.primaryCalendarType || getCalendarType() || localeData.getPreferredCalendarType(); } get focusableDays() { @@ -793,9 +795,11 @@ class DayPicker extends UI5Element { } _isWeekend(oDate) { + const localeData = getCachedLocaleDataInstance(getLocale()); + const iWeekDay = oDate.getDay(), - iWeekendStart = this._oLocaleData.getWeekendStart(), - iWeekendEnd = this._oLocaleData.getWeekendEnd(); + iWeekendStart = localeData.getWeekendStart(), + iWeekendEnd = localeData.getWeekendEnd(); return (iWeekDay >= iWeekendStart && iWeekDay <= iWeekendEnd) || (iWeekendEnd < iWeekendStart && (iWeekDay >= iWeekendStart || iWeekDay <= iWeekendEnd)); @@ -926,8 +930,9 @@ class DayPicker extends UI5Element { } _getFirstDayOfWeek() { + const localeData = getCachedLocaleDataInstance(getLocale()); const confFirstDayOfWeek = getFirstDayOfWeek(); - return Number.isInteger(confFirstDayOfWeek) ? confFirstDayOfWeek : this._oLocaleData.getFirstDayOfWeek(); + return Number.isInteger(confFirstDayOfWeek) ? confFirstDayOfWeek : localeData.getFirstDayOfWeek(); } get styles() { diff --git a/packages/main/src/MonthPicker.js b/packages/main/src/MonthPicker.js index 4d51d8ec6d9b..6cf5b5198f8e 100644 --- a/packages/main/src/MonthPicker.js +++ b/packages/main/src/MonthPicker.js @@ -2,7 +2,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import { getCalendarType } from "@ui5/webcomponents-base/dist/config/CalendarType.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; -import LocaleData from "@ui5/webcomponents-localization/dist/LocaleData.js"; +import getCachedLocaleDataInstance from "@ui5/webcomponents-localization/dist/getCachedLocaleDataInstance.js"; import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; @@ -19,6 +19,7 @@ import styles from "./generated/themes/MonthPicker.css.js"; */ const metadata = { tag: "ui5-monthpicker", + languageAware: true, properties: /** @lends sap.ui.webcomponents.main.MonthPicker.prototype */ { /** * A UNIX timestamp - seconds since 00:00:00 UTC on Jan 1, 1970. @@ -133,8 +134,6 @@ class MonthPicker extends UI5Element { constructor() { super(); - this._oLocale = getLocale(); - this._oLocaleData = new LocaleData(this._oLocale); this._itemNav = new ItemNavigation(this, { pageSize: 12, @@ -164,6 +163,8 @@ class MonthPicker extends UI5Element { } onBeforeRendering() { + const localeData = getCachedLocaleDataInstance(getLocale()); + const quarters = []; const oCalDate = CalendarDate.fromTimestamp(new Date().getTime(), this._primaryCalendarType); let timestamp; @@ -175,7 +176,7 @@ class MonthPicker extends UI5Element { const month = { timestamp: timestamp.toString(), id: `${this._id}-m${i}`, - name: this._oLocaleData.getMonths("wide", this._primaryCalendarType)[i], + name: localeData.getMonths("wide", this._primaryCalendarType)[i], classes: "ui5-mp-item", }; @@ -221,7 +222,8 @@ class MonthPicker extends UI5Element { } get _primaryCalendarType() { - return this.primaryCalendarType || getCalendarType() || LocaleData.getInstance(getLocale()).getPreferredCalendarType(); + const localeData = getCachedLocaleDataInstance(getLocale()); + return this.primaryCalendarType || getCalendarType() || localeData.getPreferredCalendarType(); } get _isPattern() { diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index fb9f7aa9ae6e..c6a6bfb878dd 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -4,7 +4,7 @@ import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18 import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; -import LocaleData from "@ui5/webcomponents-localization/dist/LocaleData.js"; +import getCachedLocaleDataInstance from "@ui5/webcomponents-localization/dist/getCachedLocaleDataInstance.js"; import "@ui5/webcomponents-localization/dist/features/calendar/Gregorian.js"; // default calendar for bundling import { fetchCldr } from "@ui5/webcomponents-base/dist/asset-registries/LocaleData.js"; import { isPhone } from "@ui5/webcomponents-base/dist/Device.js"; @@ -345,7 +345,8 @@ class TimePicker extends UI5Element { onBeforeRendering() { if (!this.formatPattern) { - this.formatPattern = LocaleData.getInstance(getLocale()).getTimePattern(this.getFormat().oFormatOptions.style); + const localeData = getCachedLocaleDataInstance(getLocale()); + this.formatPattern = localeData.getTimePattern(this.getFormat().oFormatOptions.style); } if (this.value === undefined) { diff --git a/packages/main/src/YearPicker.js b/packages/main/src/YearPicker.js index 55b1f6f1974e..2a6774479208 100644 --- a/packages/main/src/YearPicker.js +++ b/packages/main/src/YearPicker.js @@ -1,6 +1,6 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; -import LocaleData from "@ui5/webcomponents-localization/dist/LocaleData.js"; +import getCachedLocaleDataInstance from "@ui5/webcomponents-localization/dist/getCachedLocaleDataInstance.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; import { getCalendarType } from "@ui5/webcomponents-base/dist/config/CalendarType.js"; import { isEnter, isSpace } from "@ui5/webcomponents-base/dist/Keys.js"; @@ -20,6 +20,7 @@ import styles from "./generated/themes/YearPicker.css.js"; */ const metadata = { tag: "ui5-yearpicker", + languageAware: true, properties: /** @lends sap.ui.webcomponents.main.YearPicker.prototype */ { /** * A UNIX timestamp - seconds since 00:00:00 UTC on Jan 1, 1970. @@ -244,7 +245,8 @@ class YearPicker extends UI5Element { } get _primaryCalendarType() { - return this.primaryCalendarType || getCalendarType() || LocaleData.getInstance(getLocale()).getPreferredCalendarType(); + const localeData = getCachedLocaleDataInstance(getLocale()); + return this.primaryCalendarType || getCalendarType() || localeData.getPreferredCalendarType(); } get _isPattern() { diff --git a/packages/main/test/pages/Simple.html b/packages/main/test/pages/Simple.html index 22c679393e4f..4267bb4b36f9 100644 --- a/packages/main/test/pages/Simple.html +++ b/packages/main/test/pages/Simple.html @@ -7,15 +7,7 @@