90 isolate->factory()->NewJSObject(isolate->object_function());
92 icu::Collator* icu_collator = collator->icu_collator()->raw();
95 UErrorCode status = U_ZERO_ERROR;
97 icu_collator->getAttribute(UCOL_NUMERIC_COLLATION, status) == UCOL_ON;
100 const char* case_first =
nullptr;
101 status = U_ZERO_ERROR;
102 switch (icu_collator->getAttribute(UCOL_CASE_FIRST, status)) {
103 case UCOL_LOWER_FIRST:
104 case_first =
"lower";
106 case UCOL_UPPER_FIRST:
107 case_first =
"upper";
110 case_first =
"false";
112 DCHECK(U_SUCCESS(status));
114 const char* sensitivity =
nullptr;
115 status = U_ZERO_ERROR;
116 switch (icu_collator->getAttribute(UCOL_STRENGTH, status)) {
118 DCHECK(U_SUCCESS(status));
119 status = U_ZERO_ERROR;
121 if (UCOL_ON == icu_collator->getAttribute(UCOL_CASE_LEVEL, status)) {
122 sensitivity =
"case";
124 sensitivity =
"base";
126 DCHECK(U_SUCCESS(status));
130 sensitivity =
"accent";
133 sensitivity =
"variant";
135 case UCOL_QUATERNARY:
138 sensitivity =
"variant";
141 sensitivity =
"variant";
143 DCHECK(U_SUCCESS(status));
145 status = U_ZERO_ERROR;
146 bool ignore_punctuation = icu_collator->getAttribute(UCOL_ALTERNATE_HANDLING,
147 status) == UCOL_SHIFTED;
148 DCHECK(U_SUCCESS(status));
150 status = U_ZERO_ERROR;
152 icu::Locale icu_locale(icu_collator->getLocale(ULOC_VALID_LOCALE, status));
153 DCHECK(U_SUCCESS(status));
155 const char* collation =
"default";
156 const char* usage =
"sort";
157 const char* collation_key =
"co";
158 status = U_ZERO_ERROR;
159 std::string collation_value =
160 icu_locale.getUnicodeKeywordValue<std::string>(collation_key,
status);
163 if (U_SUCCESS(status)) {
164 if (collation_value ==
"search") {
171 collation =
"default";
176 icu::Locale new_icu_locale = icu_locale;
180 status = U_ZERO_ERROR;
181 new_icu_locale.setUnicodeKeywordValue(collation_key,
nullptr, status);
182 DCHECK(U_SUCCESS(status));
186 collation = collation_value.c_str();
208 if (collator->locale()->length() != 0) {
213 isolate, options, isolate->factory()->locale_string(),
220 CreateDataPropertyForOptions(
221 isolate, options, isolate->factory()->locale_string(), locale.c_str());
224 CreateDataPropertyForOptions(isolate, options,
225 isolate->factory()->usage_string(), usage);
226 CreateDataPropertyForOptions(
227 isolate, options, isolate->factory()->sensitivity_string(), sensitivity);
228 CreateDataPropertyForOptions(isolate, options,
229 isolate->factory()->ignorePunctuation_string(),
231 CreateDataPropertyForOptions(
232 isolate, options, isolate->factory()->collation_string(), collation);
233 CreateDataPropertyForOptions(isolate, options,
234 isolate->factory()->numeric_string(), numeric);
235 CreateDataPropertyForOptions(
236 isolate, options, isolate->factory()->caseFirst_string(), case_first);
283 const char* service) {
288 std::vector<std::string> requested_locales =
299 isolate, options,
"usage", service, {
"sort",
"search"},
300 {Usage::SORT, Usage::SEARCH}, Usage::SORT);
302 Usage usage = maybe_usage.
FromJust();
314 std::unique_ptr<char[]> collation_str =
nullptr;
315 const std::vector<const char*> empty_values = {};
317 isolate, options,
"collation", empty_values, service, &collation_str);
320 if (maybe_collation.
FromJust() && collation_str !=
nullptr) {
326 NewRangeError(MessageTemplate::kInvalid,
327 isolate->factory()->collation_string(),
328 isolate->factory()->NewStringFromAsciiChecked(
329 collation_str.get())),
347 GetBoolOption(isolate, options,
"numeric", service, &numeric);
352 Maybe<CaseFirst> maybe_case_first = GetCaseFirst(isolate, options, service);
354 CaseFirst case_first = maybe_case_first.
FromJust();
360 std::set<std::string> relevant_extension_keys{
"co",
"kn",
"kf"};
367 requested_locales, matcher, relevant_extension_keys);
374 icu::Locale icu_locale =
r.icu_locale;
375 DCHECK(!icu_locale.isBogus());
378 UErrorCode status = U_ZERO_ERROR;
379 if (collation_str !=
nullptr) {
380 auto co_extension_it =
r.extensions.find(
"co");
381 if (co_extension_it !=
r.extensions.end() &&
382 co_extension_it->second != collation_str.get()) {
383 icu_locale.setUnicodeKeywordValue(
"co",
nullptr, status);
384 DCHECK(U_SUCCESS(status));
404 if (usage == Usage::SEARCH) {
405 UErrorCode set_status = U_ZERO_ERROR;
406 icu_locale.setUnicodeKeywordValue(
"co",
"search", set_status);
407 DCHECK(U_SUCCESS(set_status));
409 if (collation_str !=
nullptr &&
411 icu_locale.setUnicodeKeywordValue(
"co", collation_str.get(), status);
412 DCHECK(U_SUCCESS(status));
423 std::unique_ptr<icu::Collator> icu_collator(
424 icu::Collator::createInstance(icu_locale, status));
425 if (U_FAILURE(status) || icu_collator ==
nullptr) {
426 status = U_ZERO_ERROR;
428 icu::Locale no_extension_locale(icu_locale.getBaseName());
430 icu::Collator::createInstance(no_extension_locale, status));
432 if (U_FAILURE(status) || icu_collator ==
nullptr) {
436 DCHECK(U_SUCCESS(status));
438 icu::Locale collator_locale(
439 icu_collator->getLocale(ULOC_VALID_LOCALE, status));
447 status = U_ZERO_ERROR;
449 SetNumericOption(icu_collator.get(), numeric);
451 auto kn_extension_it =
r.extensions.find(
"kn");
452 if (kn_extension_it !=
r.extensions.end()) {
453 SetNumericOption(icu_collator.get(), (kn_extension_it->second ==
"true"));
463 if (case_first != CaseFirst::kUndefined) {
464 SetCaseFirstOption(icu_collator.get(), case_first);
466 auto kf_extension_it =
r.extensions.find(
"kf");
467 if (kf_extension_it !=
r.extensions.end()) {
468 SetCaseFirstOption(icu_collator.get(),
469 ToCaseFirst(kf_extension_it->second.c_str()));
476 status = U_ZERO_ERROR;
477 icu_collator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
478 DCHECK(U_SUCCESS(status));
484 {
"base",
"accent",
"case",
"variant"},
485 {Sensitivity::kBase, Sensitivity::kAccent,
486 Sensitivity::kCase, Sensitivity::kVariant},
487 Sensitivity::kUndefined);
489 Sensitivity sensitivity = maybe_sensitivity.
FromJust();
492 if (sensitivity == Sensitivity::kUndefined) {
494 if (usage == Usage::SORT) {
496 sensitivity = Sensitivity::kVariant;
500 switch (sensitivity) {
501 case Sensitivity::kBase:
502 icu_collator->setStrength(icu::Collator::PRIMARY);
504 case Sensitivity::kAccent:
505 icu_collator->setStrength(icu::Collator::SECONDARY);
507 case Sensitivity::kCase:
508 icu_collator->setStrength(icu::Collator::PRIMARY);
509 status = U_ZERO_ERROR;
510 icu_collator->setAttribute(UCOL_CASE_LEVEL, UCOL_ON, status);
511 DCHECK(U_SUCCESS(status));
513 case Sensitivity::kVariant:
514 icu_collator->setStrength(icu::Collator::TERTIARY);
516 case Sensitivity::kUndefined:
522 bool ignore_punctuation =
false;
524 isolate, options,
"ignorePunctuation", service, &ignore_punctuation);
535 if (found_ignore_punctuation.
FromJust()) {
536 status = U_ZERO_ERROR;
537 icu_collator->setAttribute(
538 UCOL_ALTERNATE_HANDLING,
539 ignore_punctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE, status);
540 DCHECK(U_SUCCESS(status));
548 isolate->factory()->NewStringFromAsciiChecked(
549 (collator_locale != icu_locale) ?
r.locale.c_str() :
"");
554 collator->set_icu_collator(*managed_collator);
555 collator->set_locale(*locale_str);