diff --git a/.github/workflows/intl.yml b/.github/workflows/intl.yml index e18e4aa5..c834fb0c 100644 --- a/.github/workflows/intl.yml +++ b/.github/workflows/intl.yml @@ -42,3 +42,7 @@ jobs: - run: dart test if: ${{matrix.run-tests}} + + - name: Run Chrome tests - wasm + run: dart test --platform chrome --compiler dart2wasm + if: always() && matrix.sdk == 'dev' diff --git a/pkgs/intl/CHANGELOG.md b/pkgs/intl/CHANGELOG.md index bbb9208c..30f46ce1 100644 --- a/pkgs/intl/CHANGELOG.md +++ b/pkgs/intl/CHANGELOG.md @@ -5,6 +5,9 @@ * Add example for pub.dev. * Fix issues with AM/PM markers. * Update to CLDR v44.1. + * Require Dart `^3.3` + * Require `package:web` `^0.5.0`. + * Support compiling to WASM ## 0.19.0 * Update to CLDR v44. diff --git a/pkgs/intl/lib/find_locale.dart b/pkgs/intl/lib/find_locale.dart index 7e5688cc..15b0e505 100644 --- a/pkgs/intl/lib/find_locale.dart +++ b/pkgs/intl/lib/find_locale.dart @@ -4,6 +4,6 @@ export 'src/intl_default.dart' // Stub implementation // Browser implementation - if (dart.library.html) 'intl_browser.dart' + if (dart.library.js_interop) 'intl_browser.dart' // Native implementation if (dart.library.io) 'intl_standalone.dart'; diff --git a/pkgs/intl/lib/intl_browser.dart b/pkgs/intl/lib/intl_browser.dart index 9a09ec57..e14d7995 100644 --- a/pkgs/intl/lib/intl_browser.dart +++ b/pkgs/intl/lib/intl_browser.dart @@ -9,7 +9,7 @@ library intl_browser; -import 'dart:html'; +import 'package:web/web.dart'; import 'intl.dart'; // TODO(alanknight): The need to do this by forcing the user to specially diff --git a/pkgs/intl/lib/src/http_request_data_reader.dart b/pkgs/intl/lib/src/http_request_data_reader.dart index 66ea7099..edff5c39 100644 --- a/pkgs/intl/lib/src/http_request_data_reader.dart +++ b/pkgs/intl/lib/src/http_request_data_reader.dart @@ -8,41 +8,36 @@ library http_request_data_reader; import 'dart:async'; -import 'dart:html'; +import 'package:http/http.dart'; import 'intl_helpers.dart'; class HttpRequestDataReader implements LocaleDataReader { /// The base url from which we read the data. String url; + HttpRequestDataReader(this.url); @override Future read(String locale) { - var request = HttpRequest(); - request.timeout = 5000; - return _getString('$url$locale.json', request).then((r) => r.responseText!); + final Client client = Client(); + return _getString('$url$locale.json', client).timeout( + Duration(seconds: 5), + onTimeout: () { + client.close(); + throw TimeoutException('Timeout while reading $locale'); + }, + ); } - /// Read a string with the given request. This is a stripped down copy - /// of HttpRequest getString, but was the simplest way I could find to - /// issue a request with a timeout. - Future _getString(String url, HttpRequest xhr) { - var completer = Completer(); - xhr.open('GET', url, async: true); - xhr.onLoad.listen((e) { - // Note: file:// URIs have status of 0. - if ((xhr.status! >= 200 && xhr.status! < 300) || - xhr.status == 0 || - xhr.status == 304) { - completer.complete(xhr); - } else { - completer.completeError(e); - } - }); - - xhr.onError.listen(completer.completeError); - xhr.send(); - - return completer.future; + Future _getString(String url, Client client) async { + final response = await client.get(Uri.parse(url)); + + if ((response.statusCode >= 200 && response.statusCode < 300) || + response.statusCode == 0 || + response.statusCode == 304) { + return response.body; + } else { + throw Exception('Failed to load $url'); + } } } diff --git a/pkgs/intl/lib/src/locale/locale_extensions.dart b/pkgs/intl/lib/src/locale/locale_extensions.dart index c04937dc..a4fdd49e 100644 --- a/pkgs/intl/lib/src/locale/locale_extensions.dart +++ b/pkgs/intl/lib/src/locale/locale_extensions.dart @@ -70,7 +70,7 @@ class LocaleExtensions { 'RegExp/${_otherExtensionsValidValuesRE.pattern}. ' 'Entries: ${otherExtensions.entries}.'); assert( - _xExtensions == null || _validXExtensionsRE.hasMatch(_xExtensions!), + _xExtensions == null || _validXExtensionsRE.hasMatch(_xExtensions), '_xExtensions must match RegExp/${_validXExtensionsRE.pattern}/ ' 'but is "$_xExtensions".'); } diff --git a/pkgs/intl/lib/src/locale/locale_implementation.dart b/pkgs/intl/lib/src/locale/locale_implementation.dart index 65cc282b..c8d2972b 100644 --- a/pkgs/intl/lib/src/locale/locale_implementation.dart +++ b/pkgs/intl/lib/src/locale/locale_implementation.dart @@ -182,7 +182,7 @@ class LocaleImplementation extends Locale { if (scriptCode != null) out.add(scriptCode!); if (countryCode != null) out.add(countryCode!); out.addAll(variants); - if (_extensions != null) out.addAll(_extensions!.subtags); + if (_extensions != null) out.addAll(_extensions.subtags); _languageTag = out.join('-'); } return _languageTag!; diff --git a/pkgs/intl/pubspec.yaml b/pkgs/intl/pubspec.yaml index 61cbef4f..7756d22a 100644 --- a/pkgs/intl/pubspec.yaml +++ b/pkgs/intl/pubspec.yaml @@ -7,17 +7,18 @@ description: >- repository: https://github.com/dart-lang/i18n/tree/main/pkgs/intl environment: - sdk: ^3.0.0 + sdk: ^3.3.0 dependencies: clock: ^1.1.0 + http: ^1.0.0 meta: ^1.0.2 path: ^1.8.0 + web: ^0.5.0 dev_dependencies: benchmark_harness: ^2.2.0 ffi: ^1.0.0 fixnum: ^1.0.0 - js: ^0.6.3 lints: '>=1.0.0 <3.0.0' test: ^1.16.0 diff --git a/pkgs/intl/test/number_format_compact_web_test.dart b/pkgs/intl/test/number_format_compact_web_test.dart index ea245981..b18d50c1 100644 --- a/pkgs/intl/test/number_format_compact_web_test.dart +++ b/pkgs/intl/test/number_format_compact_web_test.dart @@ -9,13 +9,18 @@ // consistency when the bug is fixed. Also fix documentation and perhaps // merge tests: these tests currently also touch non-compact currency // formatting. +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:intl/intl.dart' as intl; -import 'package:js/js_util.dart' as js; import 'package:test/test.dart'; import 'compact_number_test_data.dart' as testdata; import 'more_compact_number_test_data.dart' as more_testdata; +extension on JSNumber { + external String toLocaleString(String locale, [JSObject? options]); +} + void main() { testdata.compactNumberTestData.forEach(_validate); more_testdata.cldr35CompactNumTests.forEach(_validateMore); @@ -65,19 +70,20 @@ String _ecmaFormatNumber(String locale, num number, String? compactDisplay, int? maximumSignificantDigits, bool? useGrouping}) { - var options = js.newObject(); - if (notation != null) js.setProperty(options, 'notation', notation); + final options = JSObject(); + if (notation != null) options['notation'] = notation.toJS; if (compactDisplay != null) { - js.setProperty(options, 'compactDisplay', compactDisplay); + options['compactDisplay'] = compactDisplay.toJS; } - if (style != null) js.setProperty(options, 'style', style); - if (currency != null) js.setProperty(options, 'currency', currency); + if (style != null) options['style'] = style.toJS; + if (currency != null) options['currency'] = currency.toJS; if (maximumSignificantDigits != null) { - js.setProperty( - options, 'maximumSignificantDigits', maximumSignificantDigits); + options['maximumSignificantDigits'] = maximumSignificantDigits.toJS; } - if (useGrouping != null) js.setProperty(options, 'useGrouping', useGrouping); - return js.callMethod(number, 'toLocaleString', [locale, options]); + if (useGrouping != null) { + options['useGrouping'] = useGrouping.toJS; + } + return number.toJS.toLocaleString(locale, options); } var _unsupportedChromeLocales = [ @@ -152,40 +158,40 @@ void _validateLong(String locale, List> expected) { } void _validateMore(more_testdata.CompactRoundingTestCase t) { - var options = js.newObject(); - js.setProperty(options, 'notation', 'compact'); + final options = JSObject(); + options['notation'] = 'compact'.toJS; if (t.maximumIntegerDigits != null) { - js.setProperty(options, 'maximumIntegerDigits', t.maximumIntegerDigits); + options['maximumIntegerDigits'] = t.maximumIntegerDigits!.toJS; } if (t.minimumIntegerDigits != null) { - js.setProperty(options, 'minimumIntegerDigits', t.minimumIntegerDigits); + options['minimumIntegerDigits'] = t.minimumIntegerDigits!.toJS; } if (t.maximumFractionDigits != null) { - js.setProperty(options, 'maximumFractionDigits', t.maximumFractionDigits); + options['maximumFractionDigits'] = t.maximumFractionDigits!.toJS; } if (t.minimumFractionDigits != null) { - js.setProperty(options, 'minimumFractionDigits', t.minimumFractionDigits); + options['minimumFractionDigits'] = t.minimumFractionDigits!.toJS; } if (t.minimumExponentDigits != null) { - js.setProperty(options, 'minimumExponentDigits', t.minimumExponentDigits); + options['minimumExponentDigits'] = t.minimumExponentDigits!.toJS; } if (t.maximumSignificantDigits != null) { - js.setProperty( - options, 'maximumSignificantDigits', t.maximumSignificantDigits); + options['maximumSignificantDigits'] = t.maximumSignificantDigits!.toJS; } if (t.minimumSignificantDigits != null) { - js.setProperty( - options, 'minimumSignificantDigits', t.minimumSignificantDigits); + options['minimumSignificantDigits'] = t.minimumSignificantDigits!.toJS; } test(t.toString(), () { - expect(js.callMethod(t.number, 'toLocaleString', ['en-US', options]), - t.expected); + expect( + t.number.toJS.toLocaleString('en-US', options), + t.expected, + ); }); }