Cache the last locale tested when checking for RTL locales
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=146506486
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f4a5ac..3f235df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
* Fix compactCurrency to correctly use passed-in symbol.
* A tweak to the way we retry on DateTime.asDate to compensate for a VM bug.
* Update CLDR version to 30.
+ * Cache the last result of isRtlLanguage
## 0.14.0
* MAJOR BREAKING CHANGE! Remove message extraction and code generation into a
diff --git a/lib/src/intl/bidi_utils.dart b/lib/src/intl/bidi_utils.dart
index 0a00ad3..438ef29 100644
--- a/lib/src/intl/bidi_utils.dart
+++ b/lib/src/intl/bidi_utils.dart
@@ -47,7 +47,6 @@
/// of the methods are static, and are organized into a class primarily to
/// group them together for documentation and discoverability.
class Bidi {
-
/// Unicode "Left-To-Right Embedding" (LRE) character.
static const LRE = '\u202A';
@@ -134,6 +133,15 @@
.hasMatch(isHtml ? stripHtmlIfNeeded(text) : text);
}
+ static final _rtlLocaleRegex = new RegExp(
+ r'^(ar|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_]'
+ r'(Arab|Hebr|Thaa|Nkoo|Tfng))(?!.*[-_](Latn|Cyrl)($|-|_))'
+ r'($|-|_)',
+ caseSensitive: false);
+
+ static String _lastLocaleCheckedForRtl;
+ static bool _lastRtlCheck;
+
/// Check if a BCP 47 / III [languageString] indicates an RTL language.
///
/// i.e. either:
@@ -155,10 +163,13 @@
/// http://www.iana.org/assignments/language-subtag-registry, as well as
/// Sindhi (sd) and Uyghur (ug). The presence of other subtags of the
/// language code, e.g. regions like EG (Egypt), is ignored.
- static bool isRtlLanguage(String languageString) {
- return new RegExp(r'^(ar|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_]'
- r'(Arab|Hebr|Thaa|Nkoo|Tfng))(?!.*[-_](Latn|Cyrl)($|-|_))'
- r'($|-|_)', caseSensitive: false).hasMatch(languageString);
+ static bool isRtlLanguage([String languageString]) {
+ var language = languageString ?? Intl.getCurrentLocale();
+ if (_lastLocaleCheckedForRtl != language) {
+ _lastLocaleCheckedForRtl = language;
+ _lastRtlCheck = _rtlLocaleRegex.hasMatch(language);
+ }
+ return _lastRtlCheck;
}
/// Enforce the [html] snippet in RTL directionality regardless of overall
diff --git a/test/bidi_utils_test.dart b/test/bidi_utils_test.dart
index c9c1aaf..bd89f92 100644
--- a/test/bidi_utils_test.dart
+++ b/test/bidi_utils_test.dart
@@ -31,6 +31,15 @@
expect(Bidi.isRtlLanguage('az-Arab'), isTrue);
expect(Bidi.isRtlLanguage('az-ARAB-IR'), isTrue);
expect(Bidi.isRtlLanguage('az_arab_IR'), isTrue);
+ Intl.withLocale('en_US', () {
+ expect(Bidi.isRtlLanguage(), isFalse);
+ });
+ Intl.withLocale('ar', () {
+ expect(Bidi.isRtlLanguage(), isTrue);
+ });
+ Intl.withLocale(null, () {
+ expect(Bidi.isRtlLanguage(), Bidi.isRtlLanguage(Intl.systemLocale));
+ });
});
test('hasAnyLtr', () {
@@ -190,67 +199,116 @@
equals(TextDirection.LTR.value));
expect(Bidi.estimateDirectionOfText('http://foo/bar/', isHtml: false).value,
equals(TextDirection.LTR.value));
- expect(Bidi.estimateDirectionOfText(
- 'http://foo/bar/?s=\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0'
- '\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0'
- '\u05d0\u05d0\u05d0\u05d0\u05d0').value,
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ 'http://foo/bar/?s=\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0'
+ '\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0\u05d0'
+ '\u05d0\u05d0\u05d0\u05d0\u05d0')
+ .value,
equals(TextDirection.LTR.value));
expect(Bidi.estimateDirectionOfText('\u05d0', isHtml: false).value,
equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText('9 \u05d0 -> 17.5, 23, 45, 19',
- isHtml: false).value, equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- 'http://foo/bar/ \u05d0 http://foo2/bar2/ http://foo3/bar3/').value,
+ expect(
+ Bidi
+ .estimateDirectionOfText('9 \u05d0 -> 17.5, 23, 45, 19',
+ isHtml: false)
+ .value,
equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- '\u05d0\u05d9\u05df \u05de\u05de\u05e9 \u05de\u05d4 \u05dc\u05e8\u05d0'
- '\u05d5\u05ea: \u05dc\u05d0 \u05e6\u05d9\u05dc\u05de\u05ea\u05d9 \u05d4'
- '\u05e8\u05d1\u05d4 \u05d5\u05d2\u05dd \u05d0\u05dd \u05d4\u05d9\u05d9'
- '\u05ea\u05d9 \u05de\u05e6\u05dc\u05dd, \u05d4\u05d9\u05d4 \u05e9'
- '\u05dd').value, equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- '\u05db\u05d0 - http://geek.co.il/gallery/v/2007-06 - \u05d0\u05d9'
- '\u05df \u05de\u05de\u05e9 \u05de\u05d4 \u05dc\u05e8\u05d0\u05d5\u05ea:'
- ' \u05dc\u05d0 \u05e6\u05d9\u05dc\u05de\u05ea\u05d9 \u05d4\u05e8\u05d1 '
- '\u05d5\u05d2\u05dd \u05d0\u05dd \u05d4\u05d9\u05d9\u05d9 \u05de\u05e6'
- '\u05dc\u05dd, \u05d4\u05d9\u05d4 \u05e9\u05dd \u05d1\u05e2\u05d9\u05e7'
- ' \u05d4\u05e8\u05d1\u05d4 \u05d0\u05e0\u05e9\u05d9\u05dd. \u05de\u05d4'
- ' \u05e9\u05db\u05df - \u05d0\u05e4\u05e9\u05e8 \u05dc\u05e0\u05e6'
- '\u05dc \u05d0\u05ea \u05d4\u05d4 \u05d3\u05d6\u05de\u05e0\u05d5 '
- '\u05dc\u05d4\u05e1\u05ea\u05db\u05dc \u05e2\u05dc \u05db\u05de\u05d4 '
- '\u05ea\u05de\u05d5\u05e0\u05d5\u05ea \u05de\u05e9\u05e9\u05e2\u05d5'
- '\u05ea \u05d9\u05e9\u05e0\u05d5 \u05d9\u05d5\u05ea\u05e8 \u05e9\u05d9'
- '\u05e9 \u05dc\u05d9 \u05d1\u05d0\u05ea\u05e8',
- isHtml: false).value, equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- 'CAPTCHA \u05de\u05e9\u05d5\u05db\u05dc\u05dc '
- '\u05de\u05d3\u05d9?').value, equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- 'Yes Prime Minister \u05e2\u05d3\u05db\u05d5\u05df. \u05e9\u05d0\u05dc'
- '\u05d5 \u05d0\u05d5\u05ea\u05d9 \u05de\u05d4 \u05d0\u05e0\u05d9 '
- '\u05e8\u05d5\u05e6\u05d4 \u05de\u05ea\u05e0\u05d4 \u05dc\u05d7'
- '\u05d2').value, equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- '17.4.02 \u05e9\u05e2\u05d4:13-20 .15-00 .\u05dc\u05d0 \u05d4\u05d9'
- '\u05d9\u05ea\u05d9 \u05db\u05d0\u05df.').value,
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ 'http://foo/bar/ \u05d0 http://foo2/bar2/ http://foo3/bar3/')
+ .value,
equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- '5710 5720 5730. \u05d4\u05d3\u05dc\u05ea. \u05d4\u05e0\u05e9\u05d9'
- '\u05e7\u05d4', isHtml: false).value, equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- '\u05d4\u05d3\u05dc\u05ea http://www.google.com '
- 'http://www.gmail.com').value, equals(TextDirection.RTL.value));
- expect(Bidi.estimateDirectionOfText(
- '\u05d4\u05d3\u05dc <some quite nasty html mark up>').value,
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ '\u05d0\u05d9\u05df \u05de\u05de\u05e9 \u05de\u05d4 \u05dc\u05e8\u05d0'
+ '\u05d5\u05ea: \u05dc\u05d0 \u05e6\u05d9\u05dc\u05de\u05ea\u05d9 \u05d4'
+ '\u05e8\u05d1\u05d4 \u05d5\u05d2\u05dd \u05d0\u05dd \u05d4\u05d9\u05d9'
+ '\u05ea\u05d9 \u05de\u05e6\u05dc\u05dd, \u05d4\u05d9\u05d4 \u05e9'
+ '\u05dd')
+ .value,
+ equals(TextDirection.RTL.value));
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ '\u05db\u05d0 - http://geek.co.il/gallery/v/2007-06 - \u05d0\u05d9'
+ '\u05df \u05de\u05de\u05e9 \u05de\u05d4 \u05dc\u05e8\u05d0\u05d5\u05ea:'
+ ' \u05dc\u05d0 \u05e6\u05d9\u05dc\u05de\u05ea\u05d9 \u05d4\u05e8\u05d1 '
+ '\u05d5\u05d2\u05dd \u05d0\u05dd \u05d4\u05d9\u05d9\u05d9 \u05de\u05e6'
+ '\u05dc\u05dd, \u05d4\u05d9\u05d4 \u05e9\u05dd \u05d1\u05e2\u05d9\u05e7'
+ ' \u05d4\u05e8\u05d1\u05d4 \u05d0\u05e0\u05e9\u05d9\u05dd. \u05de\u05d4'
+ ' \u05e9\u05db\u05df - \u05d0\u05e4\u05e9\u05e8 \u05dc\u05e0\u05e6'
+ '\u05dc \u05d0\u05ea \u05d4\u05d4 \u05d3\u05d6\u05de\u05e0\u05d5 '
+ '\u05dc\u05d4\u05e1\u05ea\u05db\u05dc \u05e2\u05dc \u05db\u05de\u05d4 '
+ '\u05ea\u05de\u05d5\u05e0\u05d5\u05ea \u05de\u05e9\u05e9\u05e2\u05d5'
+ '\u05ea \u05d9\u05e9\u05e0\u05d5 \u05d9\u05d5\u05ea\u05e8 \u05e9\u05d9'
+ '\u05e9 \u05dc\u05d9 \u05d1\u05d0\u05ea\u05e8',
+ isHtml: false)
+ .value,
+ equals(TextDirection.RTL.value));
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ 'CAPTCHA \u05de\u05e9\u05d5\u05db\u05dc\u05dc '
+ '\u05de\u05d3\u05d9?')
+ .value,
+ equals(TextDirection.RTL.value));
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ 'Yes Prime Minister \u05e2\u05d3\u05db\u05d5\u05df. \u05e9\u05d0\u05dc'
+ '\u05d5 \u05d0\u05d5\u05ea\u05d9 \u05de\u05d4 \u05d0\u05e0\u05d9 '
+ '\u05e8\u05d5\u05e6\u05d4 \u05de\u05ea\u05e0\u05d4 \u05dc\u05d7'
+ '\u05d2')
+ .value,
+ equals(TextDirection.RTL.value));
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ '17.4.02 \u05e9\u05e2\u05d4:13-20 .15-00 .\u05dc\u05d0 \u05d4\u05d9'
+ '\u05d9\u05ea\u05d9 \u05db\u05d0\u05df.')
+ .value,
+ equals(TextDirection.RTL.value));
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ '5710 5720 5730. \u05d4\u05d3\u05dc\u05ea. \u05d4\u05e0\u05e9\u05d9'
+ '\u05e7\u05d4',
+ isHtml: false)
+ .value,
+ equals(TextDirection.RTL.value));
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ '\u05d4\u05d3\u05dc\u05ea http://www.google.com '
+ 'http://www.gmail.com')
+ .value,
+ equals(TextDirection.RTL.value));
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ '\u05d4\u05d3\u05dc <some quite nasty html mark up>')
+ .value,
equals(TextDirection.LTR.value));
- expect(Bidi.estimateDirectionOfText(
- '\u05d4\u05d3\u05dc <some quite nasty html mark up>').value,
+ expect(
+ Bidi
+ .estimateDirectionOfText(
+ '\u05d4\u05d3\u05dc <some quite nasty html mark up>')
+ .value,
equals(TextDirection.LTR.value));
- expect(Bidi.estimateDirectionOfText(
- '\u05d4\u05d3\u05dc\u05ea & < >').value,
+ expect(
+ Bidi
+ .estimateDirectionOfText('\u05d4\u05d3\u05dc\u05ea & < >')
+ .value,
equals(TextDirection.LTR.value));
- expect(Bidi.estimateDirectionOfText(
- '\u05d4\u05d3\u05dc\u05ea & < >', isHtml: true).value,
+ expect(
+ Bidi
+ .estimateDirectionOfText('\u05d4\u05d3\u05dc\u05ea & < >',
+ isHtml: true)
+ .value,
equals(TextDirection.RTL.value));
});
@@ -259,14 +317,17 @@
var item = new SampleItem('Pure Ascii content');
bidiText.add(item);
- item = new SampleItem('\u05d0\u05d9\u05df \u05de\u05de\u05e9 \u05de\u05d4'
+ item = new SampleItem(
+ '\u05d0\u05d9\u05df \u05de\u05de\u05e9 \u05de\u05d4'
' \u05dc\u05e8\u05d0\u05d5\u05ea: \u05dc\u05d0 \u05e6\u05d9\u05dc'
'\u05de\u05ea\u05d9 \u05d4\u05e8\u05d1\u05d4 \u05d5\u05d2\u05dd '
'\u05d0\u05dd \u05d4\u05d9\u05d9\u05ea\u05d9 \u05de\u05e6\u05dc\u05dd, '
- '\u05d4\u05d9\u05d4 \u05e9\u05dd', true);
+ '\u05d4\u05d9\u05d4 \u05e9\u05dd',
+ true);
bidiText.add(item);
- item = new SampleItem('\u05db\u05d0\u05df - http://geek.co.il/gallery/v/'
+ item = new SampleItem(
+ '\u05db\u05d0\u05df - http://geek.co.il/gallery/v/'
'2007-06 - \u05d0\u05d9\u05df \u05de\u05de\u05e9 \u05de\u05d4 \u05dc'
'\u05e8\u05d0\u05d5\u05ea: \u05dc\u05d0 \u05e6\u05d9\u05dc\u05de\u05ea'
'\u05d9 \u05d4\u05e8\u05d1\u05d4 \u05d5\u05d2\u05dd \u05d0\u05dd \u05d4'
@@ -278,29 +339,40 @@
'\u05db\u05dc \u05e2\u05dc \u05db\u05de\u05d4 \u05ea\u05de\u05d5\u05e0'
'\u05d5\u05ea \u05de\u05e9\u05e2\u05e9\u05e2\u05d5\u05ea \u05d9\u05e9'
'\u05e0\u05d5\u05ea \u05d9\u05d5\u05ea\u05e8 \u05e9\u05d9\u05e9 \u05dc'
- '\u05d9 \u05d1\u05d0\u05ea\u05e8', true);
+ '\u05d9 \u05d1\u05d0\u05ea\u05e8',
+ true);
bidiText.add(item);
- item = new SampleItem('CAPTCHA \u05de\u05e9\u05d5\u05db\u05dc\u05dc '
- '\u05de\u05d3\u05d9?', true);
+ item = new SampleItem(
+ 'CAPTCHA \u05de\u05e9\u05d5\u05db\u05dc\u05dc '
+ '\u05de\u05d3\u05d9?',
+ true);
bidiText.add(item);
- item = new SampleItem('Yes Prime Minister \u05e2\u05d3\u05db\u05d5\u05df. '
+ item = new SampleItem(
+ 'Yes Prime Minister \u05e2\u05d3\u05db\u05d5\u05df. '
'\u05e9\u05d0\u05dc\u05d5 \u05d0\u05d5\u05ea\u05d9 \u05de\u05d4 \u05d0'
'\u05e0\u05d9 \u05e8\u05d5\u05e6\u05d4 \u05de\u05ea\u05e0\u05d4 '
- '\u05dc\u05d7\u05d2', true);
+ '\u05dc\u05d7\u05d2',
+ true);
bidiText.add(item);
- item = new SampleItem('17.4.02 \u05e9\u05e2\u05d4:13-20 .15-00 .\u05dc'
- '\u05d0 \u05d4\u05d9\u05d9\u05ea\u05d9 \u05db\u05d0\u05df.', true);
+ item = new SampleItem(
+ '17.4.02 \u05e9\u05e2\u05d4:13-20 .15-00 .\u05dc'
+ '\u05d0 \u05d4\u05d9\u05d9\u05ea\u05d9 \u05db\u05d0\u05df.',
+ true);
bidiText.add(item);
- item = new SampleItem('5710 5720 5730. \u05d4\u05d3\u05dc\u05ea. \u05d4'
- '\u05e0\u05e9\u05d9\u05e7\u05d4', true);
+ item = new SampleItem(
+ '5710 5720 5730. \u05d4\u05d3\u05dc\u05ea. \u05d4'
+ '\u05e0\u05e9\u05d9\u05e7\u05d4',
+ true);
bidiText.add(item);
- item = new SampleItem('\u05d4\u05d3\u05dc\u05ea http://www.google.com '
- 'http://www.gmail.com', true);
+ item = new SampleItem(
+ '\u05d4\u05d3\u05dc\u05ea http://www.google.com '
+ 'http://www.gmail.com',
+ true);
bidiText.add(item);
item = new SampleItem('>\u05d4<', true, true);