blob: 9fdf96a761f0bf9533eaf381a76b34ed0ee6dccb [file]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:js/js.dart';
import 'package:js/js_util.dart';
import '../locale.dart';
import '../options.dart';
import 'collation_impl.dart';
import 'collation_options.dart';
CollationImpl? getCollatorECMA(
Locale locale,
LocaleMatcher localeMatcher,
) =>
CollationECMA.tryToBuild(locale, localeMatcher);
@JS('Intl.Collator')
class CollatorJS {
external factory CollatorJS([List<String> locale, Object options]);
external int compare(String a, String b);
}
@JS('Intl.Collator.supportedLocalesOf')
external List<String> supportedLocalesOfJS(
List<String> listOfLocales, [
Object options,
]);
class CollationECMA extends CollationImpl {
CollationECMA(super.locale);
static CollationImpl? tryToBuild(
Locale locale,
LocaleMatcher localeMatcher,
) {
final supportedLocales = supportedLocalesOf(localeMatcher, locale);
return supportedLocales.isNotEmpty
? CollationECMA(supportedLocales.first)
: null;
}
static List<Locale> supportedLocalesOf(
LocaleMatcher localeMatcher,
Locale locale,
) {
final o = newObject<Object>();
setProperty(o, 'localeMatcher', localeMatcher.jsName);
return List.from(supportedLocalesOfJS([locale.toLanguageTag()], o))
.whereType<String>()
.map(Locale.parse)
.toList();
}
@override
int compareImpl(String a, String b, CollationOptions options) {
final collatorJS = CollatorJS(
[locale.toLanguageTag()],
options.toJsOptions(),
);
return collatorJS.compare(a, b);
}
}
extension on CollationOptions {
Object toJsOptions() {
final o = newObject<Object>();
setProperty(o, 'localeMatcher', localeMatcher.jsName);
setProperty(o, 'usage', usage.name);
if (sensitivity != null) {
setProperty(o, 'sensitivity', sensitivity!.jsName);
}
setProperty(o, 'ignorePunctuation', ignorePunctuation);
setProperty(o, 'numeric', numeric);
if (caseFirst != null) {
setProperty(o, 'caseFirst', caseFirst!.jsName);
}
if (collation != null) {
setProperty(o, 'collation', collation);
}
return o;
}
}