Skip to content

Commit

Permalink
fix: Several date/time components use locales correctly (#2440)
Browse files Browse the repository at this point in the history
  • Loading branch information
vladitasev authored and ilhan007 committed Nov 19, 2020
1 parent 85d7629 commit 6e83e2e
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 40 deletions.
14 changes: 12 additions & 2 deletions packages/base/src/locale/getLocale.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -22,7 +32,7 @@ const getLocale = lang => {
}

if (getConfigLanguage()) {
return new Locale(getConfigLanguage());
return getLocaleInstance(getConfigLanguage());
}

return convertToLocaleOrNull(detectNavigatorLanguage());
Expand Down
13 changes: 13 additions & 0 deletions packages/localization/src/getCachedLocaleDataInstance.js
Original file line number Diff line number Diff line change
@@ -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;
10 changes: 5 additions & 5 deletions packages/main/src/Calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);
Expand All @@ -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();

Expand All @@ -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
Expand Down Expand Up @@ -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() {
Expand Down
5 changes: 3 additions & 2 deletions packages/main/src/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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() {
Expand Down
5 changes: 3 additions & 2 deletions packages/main/src/DateTimePicker.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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;
}

/**
Expand Down
27 changes: 16 additions & 11 deletions packages/main/src/DayPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -249,6 +248,8 @@ class DayPicker extends UI5Element {
}

onBeforeRendering() {
const localeData = getCachedLocaleDataInstance(getLocale());

let oCalDate,
day,
timestamp,
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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;

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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() {
Expand Down
12 changes: 7 additions & 5 deletions packages/main/src/MonthPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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",
};

Expand Down Expand Up @@ -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() {
Expand Down
5 changes: 3 additions & 2 deletions packages/main/src/TimePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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) {
Expand Down
6 changes: 4 additions & 2 deletions packages/main/src/YearPicker.js
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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.
Expand Down Expand Up @@ -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() {
Expand Down
11 changes: 2 additions & 9 deletions packages/main/test/pages/Simple.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,7 @@

<title>Button</title>

<script data-ui5-config type="application/json">
{
"language": "EN",
"noConflict": {
"events": ["click"]
},
"calendarType": "Islamic"
}
</script>


<script src="../../webcomponentsjs/webcomponents-loader.js"></script>
<script src="../../resources/bundle.esm.js" type="module"></script>
Expand All @@ -26,6 +18,7 @@
<body style="background-color: var(--sapBackgroundColor);">

<ui5-button icon="download"></ui5-button>
<ui5-datepicker></ui5-datepicker>

</body>
</html>
2 changes: 2 additions & 0 deletions packages/main/test/specs/MultiComboBox.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ describe("MultiComboBox general interaction", () => {
assert.ok(mcb.getProperty("focused"), "MultiComboBox should be focused.");

input.keys("ArrowLeft");
browser.pause(100);

assert.notOk(mcb.getProperty("focused"), "MultiComboBox should no longer be focused.");

input.keys("ArrowRight");
browser.pause(100);

assert.ok(mcb.getProperty("focused"), "MultiComboBox should be focused again.");
});
Expand Down

0 comments on commit 6e83e2e

Please sign in to comment.