Fixes FOO-2330
flag=none
Canvas supports locales that not all browsers support, so we have
to check for those cases and pull in a polyfilled version of the
Intl functions that we use (DateTimeFormat, NumberFormat, and
RelativeTimeFormat) when a locale is called for that the browser
does not support.
The first time the locale polyfiller was implemented, a lot of
tests had to be done to see if there was an available polyfill for
the given locale; this somehow broke Chrome after Version 92 so it
was disabled for Chrome. However, latest versions of the @formatjs
polyfillers are much smarter and can perform those checks and
fallbacks themselves, which makes the Canvas polyfiller code way
simpler and more stable.
An additional issue was uncovered: when the locale is being polyfilled,
NONE of the native locales can be accessed any more, so code relying on
being able to get at, say, 'en-US' to do date arithmetic was failing.
So when a polyfill loads, we save the browser's version as Native*
(so Intl.DateTimeFormat --> Intl.NativeDateTimeFormat) so it can
be accessed if needed (shouldn't be anywhere except in the ui/shared
datetime support code).
Another issue uncovered is that when a polyfill is necessary, it
seems to take a long time... it can be SECONDS before it is fully
loaded and its Promises resolve, at least in dev. Unfortunately a
lot of front-end code can start up and begin to use Intl functions
during that time, possibly with unpredictable results. The only real
answer is to make the execution of immediate bundles, and the call
to ready() to finish front-end initialization, wait pending the
resolution of the Promise indicating that the locales have loaded.
This is a bit unfortunate as it delays the execution of front-end
code, but will only be noticeable in locales that need polyfilling
because if a native locale is detected, the bundle loading and
call to ready() will happen immediately as before.
This commit does the following:
- changes the Rails js_env to include LOCALES instead of LOCALE.
LOCALES is a full list of locale strings in fallback order, so
that if `sv-SE-x-k12` isn't found, it will try `sv-SE` and
`sv-x-k12` and `sv` before finally falling back to `en`.
The front-end startup code backfills ENV.LOCALE to ENV.LOCALES[0]
for backward compatibility.
- up-revs @formatjs to a more recent version that implements the
check if a polyfill is available and leverages the LOCALES list
to find an available polyfill.
- Rewrites intl-polyfills to be smarter about detecting when a
polyfill is necessary and whether it is possible.
- Makes it easier to add new Intl subsystems to the polyfill code
should they start getting used in the Canvas code somewhere.
- Fixes up the helpers that relied upon the 'en-US' locale
specifically. They now specifically check for the Native version
of an Intl subsystem first.
- Fixes up the changeTimezone helpers in ui/shared/datetime because
they relied on the `en-US` locale always being available, which
is not true when the locale has been polyfilled. That was kind of
sketchy anyway because it relied on new Date() parsing a fairly
free-form English date and time string; it now constructs an
ISO8601 string which is much more supported as an argument to
new Date().
Test plan:
* Try some different locale scenarios and observe the behavior of
Canvas in that language in general, and also specifically how it
formats dates and times (this may be faster to do in console).
* Pay particular attention to places where datepickers are used,
specifically, create a new assignment and fiddle with the due
dates down near the bottom.
* Locale scenarios to try:
a native locale like de or es
-should just work
a native locale with an extension like sv-x-k12
-should just work
a polyfillable locale like cy or nn
-should work with a console message saying it is polyfilled
the one non-polyfillable locale: Kreyòl Ayisyen
-should work via a fallback all the way to 'en' on console
Change-Id: I93a1f2c3f0b3002747f564aba24c93d77244383e
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/284509
Reviewed-by: Ahmad Amireh <ahmad@instructure.com>
QA-Review: Charley Kline <ckline@instructure.com>
Product-Review: Charley Kline <ckline@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>