mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-11 10:41:30 +00:00
LibJS+LibUnicode: Make the collation punctation default locale-aware
This commit is contained in:
parent
eb8e516ed3
commit
78625c746d
Notes:
github-actions[bot]
2024-08-15 11:45:33 +00:00
Author: https://github.com/trflynn89
Commit: 78625c746d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1078
Reviewed-by: https://github.com/awesomekling
4 changed files with 40 additions and 9 deletions
|
@ -171,14 +171,16 @@ ThrowCompletionOr<NonnullGCPtr<Object>> CollatorConstructor::construct(FunctionO
|
||||||
// 34. Set collator.[[Sensitivity]] to sensitivity.
|
// 34. Set collator.[[Sensitivity]] to sensitivity.
|
||||||
collator->set_sensitivity(sensitivity.as_string().utf8_string_view());
|
collator->set_sensitivity(sensitivity.as_string().utf8_string_view());
|
||||||
|
|
||||||
// FIXME: 35. Let defaultIgnorePunctuation be resolvedLocaleData.[[ignorePunctuation]].
|
// 35. Let defaultIgnorePunctuation be resolvedLocaleData.[[ignorePunctuation]].
|
||||||
auto default_ignore_punctuation = false;
|
// NOTE: We do not acquire the default [[ignorePunctuation]] here. Instead, we default the option to null,
|
||||||
|
// and let LibUnicode fill in the default value if an override was not provided here.
|
||||||
|
|
||||||
// 36. Let ignorePunctuation be ? GetOption(options, "ignorePunctuation", boolean, empty, defaultIgnorePunctuation).
|
// 36. Let ignorePunctuation be ? GetOption(options, "ignorePunctuation", boolean, empty, defaultIgnorePunctuation).
|
||||||
auto ignore_punctuation = TRY(get_option(vm, *options, vm.names.ignorePunctuation, OptionType::Boolean, {}, default_ignore_punctuation));
|
auto ignore_punctuation_value = TRY(get_option(vm, *options, vm.names.ignorePunctuation, OptionType::Boolean, {}, Empty {}));
|
||||||
|
|
||||||
// 37. Set collator.[[IgnorePunctuation]] to ignorePunctuation.
|
Optional<bool> ignore_punctuation;
|
||||||
collator->set_ignore_punctuation(ignore_punctuation.as_bool());
|
if (!ignore_punctuation_value.is_undefined())
|
||||||
|
ignore_punctuation = ignore_punctuation_value.as_bool();
|
||||||
|
|
||||||
// Non-standard, create an ICU collator for this Intl object.
|
// Non-standard, create an ICU collator for this Intl object.
|
||||||
auto icu_collator = Unicode::Collator::create(
|
auto icu_collator = Unicode::Collator::create(
|
||||||
|
@ -188,9 +190,12 @@ ThrowCompletionOr<NonnullGCPtr<Object>> CollatorConstructor::construct(FunctionO
|
||||||
collator->sensitivity(),
|
collator->sensitivity(),
|
||||||
collator->case_first(),
|
collator->case_first(),
|
||||||
collator->numeric(),
|
collator->numeric(),
|
||||||
collator->ignore_punctuation());
|
ignore_punctuation);
|
||||||
collator->set_collator(move(icu_collator));
|
collator->set_collator(move(icu_collator));
|
||||||
|
|
||||||
|
// 37. Set collator.[[IgnorePunctuation]] to ignorePunctuation.
|
||||||
|
collator->set_ignore_punctuation(collator->collator().ignore_punctuation());
|
||||||
|
|
||||||
// 38. Return collator.
|
// 38. Return collator.
|
||||||
return collator;
|
return collator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,15 @@ describe("correct behavior", () => {
|
||||||
const en1 = new Intl.Collator("en");
|
const en1 = new Intl.Collator("en");
|
||||||
expect(en1.resolvedOptions().ignorePunctuation).toBeFalse();
|
expect(en1.resolvedOptions().ignorePunctuation).toBeFalse();
|
||||||
|
|
||||||
|
const th1 = new Intl.Collator("th");
|
||||||
|
expect(th1.resolvedOptions().ignorePunctuation).toBeTrue();
|
||||||
|
|
||||||
[true, false].forEach(ignorePunctuation => {
|
[true, false].forEach(ignorePunctuation => {
|
||||||
const en2 = new Intl.Collator("en", { ignorePunctuation: ignorePunctuation });
|
const en2 = new Intl.Collator("en", { ignorePunctuation: ignorePunctuation });
|
||||||
expect(en2.resolvedOptions().ignorePunctuation).toBe(ignorePunctuation);
|
expect(en2.resolvedOptions().ignorePunctuation).toBe(ignorePunctuation);
|
||||||
|
|
||||||
|
const th2 = new Intl.Collator("th", { ignorePunctuation: ignorePunctuation });
|
||||||
|
expect(th2.resolvedOptions().ignorePunctuation).toBe(ignorePunctuation);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,16 @@ static constexpr UColAttributeValue icu_case_first(CaseFirst case_first)
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ignore_punctuation_for_collator(icu::Collator const& collator)
|
||||||
|
{
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
|
||||||
|
auto attribute = collator.getAttribute(UCOL_ALTERNATE_HANDLING, status);
|
||||||
|
VERIFY(icu_success(status));
|
||||||
|
|
||||||
|
return attribute == UCOL_SHIFTED;
|
||||||
|
}
|
||||||
|
|
||||||
class CollatorImpl : public Collator {
|
class CollatorImpl : public Collator {
|
||||||
public:
|
public:
|
||||||
explicit CollatorImpl(NonnullOwnPtr<icu::Collator> collator)
|
explicit CollatorImpl(NonnullOwnPtr<icu::Collator> collator)
|
||||||
|
@ -155,6 +165,11 @@ public:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool ignore_punctuation() const override
|
||||||
|
{
|
||||||
|
return ignore_punctuation_for_collator(*m_collator);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NonnullOwnPtr<icu::Collator> m_collator;
|
NonnullOwnPtr<icu::Collator> m_collator;
|
||||||
};
|
};
|
||||||
|
@ -166,7 +181,7 @@ NonnullOwnPtr<Collator> Collator::create(
|
||||||
Sensitivity sensitivity,
|
Sensitivity sensitivity,
|
||||||
CaseFirst case_first,
|
CaseFirst case_first,
|
||||||
bool numeric,
|
bool numeric,
|
||||||
bool ignore_punctuation)
|
Optional<bool> ignore_punctuation)
|
||||||
{
|
{
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
|
||||||
|
@ -183,11 +198,14 @@ NonnullOwnPtr<Collator> Collator::create(
|
||||||
VERIFY(icu_success(status));
|
VERIFY(icu_success(status));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!ignore_punctuation.has_value())
|
||||||
|
ignore_punctuation = ignore_punctuation_for_collator(*collator);
|
||||||
|
|
||||||
set_attribute(UCOL_STRENGTH, icu_sensitivity(sensitivity));
|
set_attribute(UCOL_STRENGTH, icu_sensitivity(sensitivity));
|
||||||
set_attribute(UCOL_CASE_LEVEL, sensitivity == Sensitivity::Case ? UCOL_ON : UCOL_OFF);
|
set_attribute(UCOL_CASE_LEVEL, sensitivity == Sensitivity::Case ? UCOL_ON : UCOL_OFF);
|
||||||
set_attribute(UCOL_CASE_FIRST, icu_case_first(case_first));
|
set_attribute(UCOL_CASE_FIRST, icu_case_first(case_first));
|
||||||
set_attribute(UCOL_NUMERIC_COLLATION, numeric ? UCOL_ON : UCOL_OFF);
|
set_attribute(UCOL_NUMERIC_COLLATION, numeric ? UCOL_ON : UCOL_OFF);
|
||||||
set_attribute(UCOL_ALTERNATE_HANDLING, ignore_punctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE);
|
set_attribute(UCOL_ALTERNATE_HANDLING, *ignore_punctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE);
|
||||||
set_attribute(UCOL_NORMALIZATION_MODE, UCOL_ON);
|
set_attribute(UCOL_NORMALIZATION_MODE, UCOL_ON);
|
||||||
|
|
||||||
return adopt_own(*new CollatorImpl(move(collator)));
|
return adopt_own(*new CollatorImpl(move(collator)));
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
Sensitivity,
|
Sensitivity,
|
||||||
CaseFirst,
|
CaseFirst,
|
||||||
bool numeric,
|
bool numeric,
|
||||||
bool ignore_punctuation);
|
Optional<bool> ignore_punctuation);
|
||||||
|
|
||||||
virtual ~Collator() = default;
|
virtual ~Collator() = default;
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@ public:
|
||||||
};
|
};
|
||||||
virtual Order compare(StringView, StringView) const = 0;
|
virtual Order compare(StringView, StringView) const = 0;
|
||||||
|
|
||||||
|
virtual bool ignore_punctuation() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Collator() = default;
|
Collator() = default;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue