Bug 578714: Stop doing Unicode-aware case-folding inside layout/style. r=zwol sr=bz

--HG--
extra : rebase_source : 7d5f43bf8d7d109c9669db68589e26554df9a250
This commit is contained in:
Kyle Huey 2010-07-29 12:41:04 -07:00
parent de6f5d1296
commit 330a1072b2
18 changed files with 235 additions and 17 deletions

View File

@ -1493,12 +1493,14 @@ public:
/**
* Convert ASCII A-Z to a-z.
*/
static void ASCIIToLower(nsAString& aStr);
static void ASCIIToLower(const nsAString& aSource, nsAString& aDest);
/**
* Convert ASCII a-z to A-Z.
*/
static void ASCIIToUpper(nsAString& aStr);
static void ASCIIToUpper(const nsAString& aSource, nsAString& aDest);
static nsIInterfaceRequestor* GetSameOriginChecker();

View File

@ -4948,6 +4948,21 @@ nsContentUtils::GetCurrentJSContext()
return cx;
}
/* static */
void
nsContentUtils::ASCIIToLower(nsAString& aStr)
{
PRUnichar* iter = aStr.BeginWriting();
PRUnichar* end = aStr.EndWriting();
while (iter != end) {
PRUnichar c = *iter;
if (c >= 'A' && c <= 'Z') {
*iter = c + ('a' - 'A');
}
++iter;
}
}
/* static */
void
nsContentUtils::ASCIIToLower(const nsAString& aSource, nsAString& aDest)
@ -4983,6 +4998,26 @@ nsContentUtils::ASCIIToUpper(nsAString& aStr)
}
}
/* static */
void
nsContentUtils::ASCIIToUpper(const nsAString& aSource, nsAString& aDest)
{
PRUint32 len = aSource.Length();
aDest.SetLength(len);
if (aDest.Length() == len) {
PRUnichar* dest = aDest.BeginWriting();
const PRUnichar* iter = aSource.BeginReading();
const PRUnichar* end = aSource.EndReading();
while (iter != end) {
PRUnichar c = *iter;
*dest = (c >= 'a' && c <= 'z') ?
c + ('A' - 'a') : c;
++iter;
++dest;
}
}
}
PRBool
nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
const nsAString& aStr2)

View File

@ -186,6 +186,14 @@ ToLowerCase(const nsAString& aSource,
ToLowerCase(in, out, len);
}
PRUnichar
ToLowerCaseASCII(const PRUnichar aChar)
{
if (IS_ASCII_UPPER(aChar))
return aChar + 0x0020;
return aChar;
}
void
ToUpperCase(nsAString& aString)
{
@ -234,6 +242,49 @@ nsCaseInsensitiveStringComparator::operator()(PRUnichar lhs,
return 1;
}
PRInt32
nsASCIICaseInsensitiveStringComparator::operator()(const PRUnichar* lhs,
const PRUnichar* rhs,
PRUint32 aLength) const
{
while (aLength) {
PRUnichar l = *lhs++;
PRUnichar r = *lhs++;
if (l != r) {
l = ToLowerCaseASCII(l);
r = ToLowerCaseASCII(r);
if (l > r)
return 1;
else if (r > l)
return -1;
}
aLength--;
}
return 0;
}
PRInt32
nsASCIICaseInsensitiveStringComparator::operator()(PRUnichar lhs,
PRUnichar rhs) const
{
// see if they're an exact match first
if (lhs == rhs)
return 0;
lhs = ToLowerCaseASCII(lhs);
rhs = ToLowerCaseASCII(rhs);
if (lhs == rhs)
return 0;
else if (lhs < rhs)
return -1;
else
return 1;
}
#endif // MOZILLA_INTERNAL_API
PRInt32

View File

@ -92,6 +92,16 @@ public:
}
};
class nsASCIICaseInsensitiveStringComparator : public nsStringComparator
{
public:
virtual int operator() (const PRUnichar*,
const PRUnichar*,
PRUint32 aLength) const;
virtual int operator() (PRUnichar,
PRUnichar) const;
};
inline PRBool
CaseInsensitiveFindInReadable(const nsAString& aPattern,
nsAString::const_iterator& aSearchStart,

View File

@ -217,6 +217,9 @@ include text-transform/reftest.list
# -moz-transform/
include transform/reftest.list
# unicode/ (verify that we don't do expend effort doing unicode-aware case checks)
include unicode/reftest.list
# widget/
include ../../widget/reftests/reftest.list

View File

@ -0,0 +1,6 @@
== unicode-attribute-selector.html unicode-ref.html
== unicode-element-selector.html unicode-ref.html
== unicode-lang.html unicode-ref.html
== unicode-media-query-media-type.html unicode-ref-print.html
== unicode-media-query-query.html unicode-ref-print.html
== unicode-pseudo-selector.html unicode-ref.html

View File

@ -0,0 +1,19 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - attribute selectors</title>
<style>
div[dİr] {color: red;}
div[dİr="ltr"] {text-indent: 30px;}
input[dİsabled] {display: none;}
//input[dİsabled="disabled"] {display: inline;}
</style>
</head>
<body>
<div dir='ltr'><p lang="hi">स्टार</p></div>
<input disabled>
<input dİsabled="DİSABLED">
<input dİsabled="disabled">
</body>
</html>

View File

@ -0,0 +1,14 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - element selectors</title>
<style>
dİv {color: red}
</style>
</head>
<body>
<div><p lang="hi">स्टार</p></div>
<input disabled>
</body>
</html>

View File

@ -0,0 +1,15 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - language selector</title>
<style>
p:lang(hİ) {color: red}
//p[lang="hİ"] {text-indent:30px} Disabled until Bug 492431 is fixed
</style>
</head>
<body>
<div><p lang="hi">स्टार</p></div>
<input disabled>
</body>
</html>

View File

@ -0,0 +1,15 @@
<html class="reftest-print">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - media query - media type selector</title>
<style>
@media prİnt {
p { color: red }
}
</style>
</head>
<body>
<div><p lang="hi">स्टार</p></div>
</body>
</html>

View File

@ -0,0 +1,13 @@
<html class="reftest-print">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - media query - media query text</title>
<style>
@media print and (mİn-wİdth: 5in) { p {color: red; } }
</style>
</head>
<body>
<div><p lang="hi">स्टार</p></div>
</body>
</html>

View File

@ -0,0 +1,14 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - pseudo element selectors</title>
<style>
p:fİrst-letter {color: red}
</style>
</head>
<body>
<div><p lang="hi">स्टार</p></div>
<input disabled>
</body>
</html>

View File

@ -0,0 +1,10 @@
<html class="reftest-print">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - media query - reference</title>
</head>
<body>
<div><p lang="hi">स्टार</p></div>
</body>
</html>

View File

@ -0,0 +1,11 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unicode tests - reference rending</title>
</head>
<body>
<div><p lang="hi">स्टार</p></div>
<input disabled>
</body>
</html>

View File

@ -1645,7 +1645,7 @@ CSSParserImpl::ParseMediaQuery(PRUnichar aStopSymbol,
return PR_FALSE;
}
// case insensitive from CSS - must be lower cased
ToLowerCase(mToken.mIdent);
nsContentUtils::ASCIIToLower(mToken.mIdent);
mediaType = do_GetAtom(mToken.mIdent);
if (gotNotOrOnly ||
(mediaType != nsGkAtoms::_not && mediaType != nsGkAtoms::only))
@ -1763,7 +1763,7 @@ CSSParserImpl::ParseMediaQueryExpression(nsMediaQuery* aQuery)
}
// case insensitive from CSS - must be lower cased
ToLowerCase(mToken.mIdent);
nsContentUtils::ASCIIToLower(mToken.mIdent);
const PRUnichar *featureString;
if (StringBeginsWith(mToken.mIdent, NS_LITERAL_STRING("min-"))) {
expr->mRange = nsMediaExpression::eMin;
@ -2922,7 +2922,7 @@ CSSParserImpl::ParseAttributeSelector(PRInt32& aDataMask,
short i = 0;
const char* htmlAttr;
while ((htmlAttr = caseInsensitiveHTMLAttribute[i++])) {
if (attr.EqualsIgnoreCase(htmlAttr)) {
if (attr.LowerCaseEqualsASCII(htmlAttr)) {
isCaseSensitive = PR_FALSE;
break;
}
@ -2996,7 +2996,7 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
nsAutoString buffer;
buffer.Append(PRUnichar(':'));
buffer.Append(mToken.mIdent);
ToLowerCase(buffer);
nsContentUtils::ASCIIToLower(buffer);
nsCOMPtr<nsIAtom> pseudo = do_GetAtom(buffer);
if (!pseudo) {
mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
@ -3331,20 +3331,20 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector,
}
if (eCSSToken_Ident == mToken.mType) {
if (mToken.mIdent.EqualsIgnoreCase("odd")) {
if (mToken.mIdent.LowerCaseEqualsLiteral("odd")) {
numbers[0] = 2;
numbers[1] = 1;
lookForB = PR_FALSE;
}
else if (mToken.mIdent.EqualsIgnoreCase("even")) {
else if (mToken.mIdent.LowerCaseEqualsLiteral("even")) {
numbers[0] = 2;
numbers[1] = 0;
lookForB = PR_FALSE;
}
else if (mToken.mIdent.EqualsIgnoreCase("n")) {
else if (mToken.mIdent.LowerCaseEqualsLiteral("n")) {
numbers[0] = 1;
}
else if (mToken.mIdent.EqualsIgnoreCase("-n")) {
else if (mToken.mIdent.LowerCaseEqualsLiteral("-n")) {
numbers[0] = -1;
}
else {
@ -3361,7 +3361,7 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector,
lookForB = PR_FALSE;
}
else if (eCSSToken_Dimension == mToken.mType) {
if (!mToken.mIntegerValid || !mToken.mIdent.EqualsIgnoreCase("n")) {
if (!mToken.mIntegerValid || !mToken.mIdent.LowerCaseEqualsLiteral("n")) {
REPORT_UNEXPECTED_TOKEN(PEPseudoClassArgNotNth);
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
}

View File

@ -147,7 +147,7 @@ RuleHash_CIHashKey(PLDHashTable *table, const void *key)
nsAutoString str;
atom->ToString(str);
ToUpperCase(str);
nsContentUtils::ASCIIToLower(str);
return HashString(str);
}
@ -1461,7 +1461,7 @@ static PRBool AttrMatchesValue(const nsAttrSelector* aAttrSelector,
return PR_FALSE;
const nsDefaultStringComparator defaultComparator;
const nsCaseInsensitiveStringComparator ciComparator;
const nsASCIICaseInsensitiveStringComparator ciComparator;
const nsStringComparator& comparator =
(aAttrSelector->mCaseSensitive || !isHTML)
? static_cast<const nsStringComparator&>(defaultComparator)
@ -1762,7 +1762,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
if (lang && !lang->IsEmpty()) { // null check for out-of-memory
if (!nsStyleUtil::DashMatchCompare(*lang,
nsDependentString(pseudoClass->u.mString),
nsCaseInsensitiveStringComparator())) {
nsASCIICaseInsensitiveStringComparator())) {
return PR_FALSE;
}
// This pseudo-class matched; move on to the next thing
@ -1790,7 +1790,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
if (nsStyleUtil::DashMatchCompare(Substring(language, begin,
end-begin),
langString,
nsCaseInsensitiveStringComparator())) {
nsASCIICaseInsensitiveStringComparator())) {
break;
}
begin = end + 1;

View File

@ -240,7 +240,7 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr)
MOZ_COUNT_CTOR(nsAttrSelector);
nsAutoString lowercase;
ToLowerCase(aAttr, lowercase);
nsContentUtils::ASCIIToLower(aAttr, lowercase);
mCasedAttr = do_GetAtom(aAttr);
mLowercaseAttr = do_GetAtom(lowercase);
@ -259,7 +259,7 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr, PRUint
MOZ_COUNT_CTOR(nsAttrSelector);
nsAutoString lowercase;
ToLowerCase(aAttr, lowercase);
nsContentUtils::ASCIIToLower(aAttr, lowercase);
mCasedAttr = do_GetAtom(aAttr);
mLowercaseAttr = do_GetAtom(lowercase);
@ -395,7 +395,7 @@ void nsCSSSelector::SetTag(const nsString& aTag)
mCasedTag = do_GetAtom(aTag);
nsAutoString lowercase;
ToLowerCase(aTag, lowercase);
nsContentUtils::ASCIIToLower(aTag, lowercase);
mLowercaseTag = do_GetAtom(lowercase);
}

View File

@ -4569,7 +4569,7 @@ nsRuleNode::ComputeVisibilityData(void* aStartStruct,
nsAutoString lang;
displayData.mLang.GetStringValue(lang);
ToLowerCase(lang);
nsContentUtils::ASCIIToLower(lang);
visibility->mLanguage = do_GetAtom(lang);
}
}