Bug 969980 - Use case folding for case-insensitive searches. r=Ehsan

Differential Revision: https://phabricator.services.mozilla.com/D50940

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alex Henrie 2019-10-29 19:56:56 +00:00
parent 04dddd2796
commit 4e325c4480
5 changed files with 46 additions and 3 deletions

View File

@ -138,6 +138,30 @@ void ToUpperCase(const nsAString& aSource, nsAString& aDest) {
#ifdef MOZILLA_INTERNAL_API
uint32_t ToFoldedCase(uint32_t aChar) {
if (IS_ASCII(aChar)) return gASCIIToLower[aChar];
return mozilla::unicode::GetFoldedcase(aChar);
}
void ToFoldedCase(nsAString& aString) {
char16_t* buf = aString.BeginWriting();
ToFoldedCase(buf, buf, aString.Length());
}
void ToFoldedCase(const char16_t* aIn, char16_t* aOut, uint32_t aLen) {
for (uint32_t i = 0; i < aLen; i++) {
uint32_t ch = aIn[i];
if (i < aLen - 1 && NS_IS_SURROGATE_PAIR(ch, aIn[i + 1])) {
ch = mozilla::unicode::GetFoldedcase(SURROGATE_TO_UCS4(ch, aIn[i + 1]));
NS_ASSERTION(!IS_IN_BMP(ch), "case mapping crossed BMP/SMP boundary!");
aOut[i++] = H_SURROGATE(ch);
aOut[i] = L_SURROGATE(ch);
continue;
}
aOut[i] = ToFoldedCase(ch);
}
}
int32_t nsCaseInsensitiveStringComparator::operator()(const char16_t* lhs,
const char16_t* rhs,
uint32_t lLength,

View File

@ -52,6 +52,10 @@ inline bool IsLowerCase(uint32_t c) { return ToUpperCase(c) != c; }
#ifdef MOZILLA_INTERNAL_API
uint32_t ToFoldedCase(uint32_t aChar);
void ToFoldedCase(nsAString& aString);
void ToFoldedCase(const char16_t* aIn, char16_t* aOut, uint32_t aLen);
class nsCaseInsensitiveStringComparator : public nsStringComparator {
public:
nsCaseInsensitiveStringComparator() = default;

View File

@ -124,6 +124,10 @@ inline uint32_t GetTitlecaseForAll(
return u_totitle(aCh);
}
inline uint32_t GetFoldedcase(uint32_t aCh) {
return u_foldCase(aCh, U_FOLD_CASE_DEFAULT);
}
inline bool IsEastAsianWidthFHWexcludingEmoji(uint32_t aCh) {
switch (u_getIntPropertyValue(aCh, UCHAR_EAST_ASIAN_WIDTH)) {
case U_EA_FULLWIDTH:

View File

@ -511,7 +511,7 @@ nsFind::Find(const nsAString& aPatText, nsRange* aSearchRange,
nsAutoString patAutoStr(aPatText);
if (!mCaseSensitive) {
ToLowerCase(patAutoStr);
ToFoldedCase(patAutoStr);
}
// Ignore soft hyphens in the pattern
@ -691,8 +691,8 @@ nsFind::Find(const nsAString& aPatText, nsRange* aSearchRange,
}
if (!inWhitespace && IsSpace(patc)) {
inWhitespace = true;
} else if (!inWhitespace && !mCaseSensitive && IsUpperCase(c)) {
c = ToLowerCase(c);
} else if (!inWhitespace && !mCaseSensitive) {
c = ToFoldedCase(c);
}
if (c == CH_SHY) {

View File

@ -2,6 +2,7 @@
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=450048
https://bugzilla.mozilla.org/show_bug.cgi?id=969980
https://bugzilla.mozilla.org/show_bug.cgi?id=1589786
-->
<head>
@ -51,6 +52,14 @@ async function runTests() {
retRange = rf.Find(searchValue, searchRange, startPt, endPt);
ok(retRange, "\"" + searchValue + "\" not found (not caseSensitive)");
searchValue = "λόγος";
retRange = rf.Find(searchValue, searchRange, startPt, endPt);
ok(retRange, "\"" + searchValue + "\" not found (not caseSensitive)");
searchValue = "degrees k";
retRange = rf.Find(searchValue, searchRange, startPt, endPt);
ok(retRange, "\"" + searchValue + "\" not found (not caseSensitive)");
searchValue = "𐐸𐐯𐑊𐐬";
retRange = rf.Find(searchValue, searchRange, startPt, endPt);
ok(retRange, "\"" + searchValue + "\" not found (not caseSensitive)");
@ -257,6 +266,8 @@ async function runTests() {
<p id="quotes">"straight" and &ldquo;curly&rdquo; and &lsquo;didn't&rsquo; and 'doesn&rsquo;t'</p>
<p id="nullcharsnative">native null&#0;</p>
<p id="nullcharsinjected"></p>
<p id="greek">ΛΌΓΟΣ</p>
<p id="kelvin">degrees &#x212A;</p>
<p id="deseret">𐐐𐐯𐑊𐐬 𐐶𐐯𐑉𐑊𐐼!</p>
<div id="content" style="display: none">