Merge backout of changeset 358af1196dc2 (bug 499655) until we get bug 507487 sorted out.

This commit is contained in:
L. David Baron 2009-07-31 09:40:17 -07:00
Родитель b3edbb264e 389de5e6db
Коммит d823ebd44b
8 изменённых файлов: 87 добавлений и 190 удалений

Просмотреть файл

@ -2452,7 +2452,7 @@ CSSParserImpl::ParseSelectorList(nsCSSSelectorList*& aListHead,
static PRBool IsSinglePseudoClass(const nsCSSSelector& aSelector)
{
return PRBool((aSelector.mNameSpace == kNameSpaceID_Unknown) &&
(aSelector.mLowercaseTag == nsnull) &&
(aSelector.mTag == nsnull) &&
(aSelector.mIDList == nsnull) &&
(aSelector.mClassList == nsnull) &&
(aSelector.mAttrList == nsnull) &&
@ -2527,7 +2527,7 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList)
list->AddSelector(empty); // leave a blank (universal) selector in the middle
listSel = list->mSelectors; // use the new one for the pseudo
}
listSel->mLowercaseTag = pseudoElement;
listSel->mTag = pseudoElement;
}
else { // append new pseudo element selector
nsAutoPtr<nsCSSSelector> pseudoTagSelector(new nsCSSSelector());
@ -2535,9 +2535,9 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList)
mScanner.SetLowLevelError(NS_ERROR_OUT_OF_MEMORY);
return PR_FALSE;
}
pseudoTagSelector->mLowercaseTag = pseudoClassList->mAtom; // steal ref count
pseudoTagSelector->mTag = pseudoClassList->mAtom; // steal ref count
#ifdef MOZ_XUL
if (IsTreePseudoElement(pseudoTagSelector->mLowercaseTag)) {
if (IsTreePseudoElement(pseudoTagSelector->mTag)) {
// Take the remaining "pseudoclasses" that we parsed
// inside the tree pseudoelement's ()-list, and
// make our new selector have these pseudoclasses
@ -2684,8 +2684,13 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
}
if (eCSSToken_Ident == mToken.mType) { // element name
aDataMask |= SEL_MASK_ELEM;
aSelector.SetTag(mToken.mIdent, mCaseSensitive);
if (mCaseSensitive) {
aSelector.SetTag(mToken.mIdent);
}
else {
ToLowerCase(mToken.mIdent, buffer);
aSelector.SetTag(buffer);
}
}
else if (mToken.IsSymbol('*')) { // universal selector
aDataMask |= SEL_MASK_ELEM;
@ -2723,8 +2728,13 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
}
if (eCSSToken_Ident == mToken.mType) { // element name
aDataMask |= SEL_MASK_ELEM;
aSelector.SetTag(mToken.mIdent, mCaseSensitive);
if (mCaseSensitive) {
aSelector.SetTag(mToken.mIdent);
}
else {
ToLowerCase(mToken.mIdent, buffer);
aSelector.SetTag(buffer);
}
}
else if (mToken.IsSymbol('*')) { // universal selector
aDataMask |= SEL_MASK_ELEM;
@ -2738,8 +2748,13 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
}
else { // was element name
SetDefaultNamespaceOnSelector(aSelector);
aSelector.SetTag(buffer, mCaseSensitive);
if (mCaseSensitive) {
aSelector.SetTag(buffer);
}
else {
ToLowerCase(buffer);
aSelector.SetTag(buffer);
}
aDataMask |= SEL_MASK_ELEM;
}
if (! GetToken(PR_FALSE)) { // premature eof is ok (here!)
@ -2757,7 +2772,13 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
}
if (eCSSToken_Ident == mToken.mType) { // element name
aDataMask |= SEL_MASK_ELEM;
aSelector.SetTag(mToken.mIdent, mCaseSensitive);
if (mCaseSensitive) {
aSelector.SetTag(mToken.mIdent);
}
else {
ToLowerCase(mToken.mIdent, buffer);
aSelector.SetTag(buffer);
}
}
else if (mToken.IsSymbol('*')) { // universal selector
aDataMask |= SEL_MASK_ELEM;

Просмотреть файл

@ -210,7 +210,7 @@ RuleHash_TagTable_GetKey(PLDHashTable *table, const PLDHashEntryHdr *hdr)
{
const RuleHashTableEntry *entry =
static_cast<const RuleHashTableEntry*>(hdr);
return entry->mRules->mSelector->mLowercaseTag;
return entry->mRules->mSelector->mTag;
}
static nsIAtom*
@ -513,8 +513,8 @@ void RuleHash::PrependRule(RuleValue *aRuleInfo)
PrependRuleToTable(&mClassTable, selector->mClassList->mAtom, aRuleInfo);
RULE_HASH_STAT_INCREMENT(mClassSelectors);
}
else if (nsnull != selector->mLowercaseTag) {
PrependRuleToTable(&mTagTable, selector->mLowercaseTag, aRuleInfo);
else if (nsnull != selector->mTag) {
PrependRuleToTable(&mTagTable, selector->mTag, aRuleInfo);
RULE_HASH_STAT_INCREMENT(mTagSelectors);
}
else if (kNameSpaceID_Unknown != selector->mNameSpace) {
@ -1191,23 +1191,11 @@ static PRBool SelectorMatches(RuleProcessorData &data,
{
// namespace/tag match
// optimization : bail out early if we can
if ((kNameSpaceID_Unknown != aSelector->mNameSpace &&
data.mNameSpaceID != aSelector->mNameSpace))
data.mNameSpaceID != aSelector->mNameSpace) ||
(aSelector->mTag && aSelector->mTag != data.mContentTag)) {
// optimization : bail out early if we can
return PR_FALSE;
if (aSelector->mLowercaseTag) {
//If we tested that this is an HTML node in a text/html document and
//had some tweaks in RuleHash, we could remove case-sensitivity from
//style sheets.
if (data.mIsHTMLContent) {
if (data.mContentTag != aSelector->mLowercaseTag)
return PR_FALSE;
}
else {
if (data.mContentTag != aSelector->mCasedTag)
return PR_FALSE;
}
}
PRBool result = PR_TRUE;
@ -1605,8 +1593,7 @@ static PRBool SelectorMatches(RuleProcessorData &data,
if ((stateToCheck & (NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE)) &&
data.mCompatMode == eCompatibility_NavQuirks &&
// global selector (but don't check .class):
!aSelector->HasTagSelector() && !aSelector->mIDList &&
!aSelector->mAttrList &&
!aSelector->mTag && !aSelector->mIDList && !aSelector->mAttrList &&
// This (or the other way around) both make :not() asymmetric
// in quirks mode (and it's hard to work around since we're
// testing the current mNegations, not the first
@ -1942,10 +1929,7 @@ static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
{
PseudoRuleProcessorData* data = (PseudoRuleProcessorData*)aData;
if (!aSelector->IsPseudoElement())
return;
NS_ASSERTION(aSelector->mLowercaseTag == data->mPseudoTag, "RuleHash failure");
NS_ASSERTION(aSelector->mTag == data->mPseudoTag, "RuleHash failure");
PRBool matches = PR_TRUE;
if (data->mComparator)
data->mComparator->PseudoMatches(data->mPseudoTag, aSelector, &matches);

Просмотреть файл

@ -258,8 +258,7 @@ nsAttrSelector::~nsAttrSelector(void)
// -- nsCSSSelector -------------------------------
nsCSSSelector::nsCSSSelector(void)
: mLowercaseTag(nsnull),
mCasedTag(nsnull),
: mTag(nsnull),
mIDList(nsnull),
mClassList(nsnull),
mPseudoClassList(nsnull),
@ -280,8 +279,7 @@ nsCSSSelector::Clone(PRBool aDeepNext, PRBool aDeepNegations) const
return nsnull;
result->mNameSpace = mNameSpace;
result->mLowercaseTag = mLowercaseTag;
result->mCasedTag = mCasedTag;
result->mTag = mTag;
result->mOperator = mOperator;
NS_IF_CLONE(mIDList);
@ -318,8 +316,7 @@ nsCSSSelector::~nsCSSSelector(void)
void nsCSSSelector::Reset(void)
{
mNameSpace = kNameSpaceID_Unknown;
mLowercaseTag = nsnull;
mCasedTag = nsnull;
mTag = nsnull;
NS_IF_DELETE(mIDList);
NS_IF_DELETE(mClassList);
NS_IF_DELETE(mPseudoClassList);
@ -337,23 +334,12 @@ void nsCSSSelector::SetNameSpace(PRInt32 aNameSpace)
mNameSpace = aNameSpace;
}
void nsCSSSelector::SetTag(const nsString& aTag, PRBool aCaseMatters)
void nsCSSSelector::SetTag(const nsString& aTag)
{
if (aTag.IsEmpty()) {
mLowercaseTag = mCasedTag = nsnull;
return;
}
mCasedTag = do_GetAtom(aTag);
if (aCaseMatters) {
mLowercaseTag = mCasedTag;
}
else {
nsAutoString lowercase(aTag);
ToLowerCase(lowercase);
mLowercaseTag = do_GetAtom(lowercase);
}
if (aTag.IsEmpty())
mTag = nsnull;
else
mTag = do_GetAtom(aTag);
}
void nsCSSSelector::AddID(const nsString& aID)
@ -436,7 +422,7 @@ PRInt32 nsCSSSelector::CalcWeightWithoutNegations() const
{
PRInt32 weight = 0;
if (nsnull != mLowercaseTag) {
if (nsnull != mTag) {
weight += 0x000001;
}
nsAtomList* list = mIDList;
@ -472,6 +458,19 @@ PRInt32 nsCSSSelector::CalcWeight() const
return weight;
}
// pseudo-elements are stored in the selectors' chain using fictional elements;
// these fictional elements have mTag starting with a colon
static PRBool IsPseudoElement(nsIAtom* aAtom)
{
if (aAtom) {
const char* str;
aAtom->GetUTF8String(&str);
return str && (*str == ':');
}
return PR_FALSE;
}
//
// Builds the textual representation of a selector. Called by DOM 2 CSS
// StyleRule:selectorText
@ -500,7 +499,7 @@ nsCSSSelector::ToString(nsAString& aString, nsICSSStyleSheet* aSheet,
// Append the combinator, if needed.
if (!stack.IsEmpty()) {
const nsCSSSelector *next = stack.ElementAt(index - 1);
if (!next->IsPseudoElement()) {
if (!IsPseudoElement(next->mTag)) {
aString.Append(PRUnichar(' '));
PRUnichar oper = s->mOperator;
if (oper != PRUnichar(0)) {
@ -533,7 +532,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
PRBool aIsNegated) const
{
nsAutoString temp;
PRBool isPseudoElement = IsPseudoElement();
PRBool isPseudoElement = IsPseudoElement(mTag);
// For non-pseudo-element selectors or for lone pseudo-elements, deal with
// namespace prefixes.
@ -589,7 +588,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
}
}
if (!mLowercaseTag) {
if (!mTag) {
// Universal selector: avoid writing the universal selector when we
// can avoid it, especially since we're required to avoid it for the
// inside of :not()
@ -606,12 +605,12 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
// XXXldb Why?
aString.Append(PRUnichar('*'));
}
if (!nsCSSPseudoElements::IsCSS2PseudoElement(mLowercaseTag)) {
if (!nsCSSPseudoElements::IsCSS2PseudoElement(mTag)) {
aString.Append(PRUnichar(':'));
}
}
nsAutoString prefix;
mLowercaseTag->ToString(prefix);
mTag->ToString(prefix);
aString.Append(prefix);
}

Просмотреть файл

@ -152,7 +152,7 @@ public:
void Reset(void);
void SetNameSpace(PRInt32 aNameSpace);
void SetTag(const nsString& aTag, PRBool aCaseSensitive);
void SetTag(const nsString& aTag);
void AddID(const nsString& aID);
void AddClass(const nsString& aClass);
void AddPseudoClass(nsIAtom* aPseudoClass);
@ -163,14 +163,6 @@ public:
const nsString& aValue, PRBool aCaseSensitive);
void SetOperator(PRUnichar aOperator);
inline PRBool HasTagSelector() const {
return !!mCasedTag;
}
inline PRBool IsPseudoElement() const {
return mLowercaseTag && !mCasedTag;
}
// Calculate the specificity of this selector (not including its mNext!).
PRInt32 CalcWeight() const;
@ -196,12 +188,7 @@ private:
PRInt32 CalcWeightWithoutNegations() const;
public:
// For case-sensitive documents, mLowercaseTag is the same as mCasedTag,
// but in case-insensitive documents (HTML) mLowercaseTag is lowercase.
// Also, for pseudo-elements mCasedTag will be null but mLowercaseTag
// contains their name.
nsCOMPtr<nsIAtom> mLowercaseTag;
nsCOMPtr<nsIAtom> mCasedTag;
nsCOMPtr<nsIAtom> mTag;
nsAtomList* mIDList;
nsAtomList* mClassList;
nsPseudoClassList* mPseudoClassList; // atom for the pseudo, string for

Просмотреть файл

@ -101,8 +101,6 @@ _TEST_FILES = test_acid3_test46.html \
test_bug450191.html \
test_bug453896_deck.html \
test_bug470769.html \
test_bug499655.html \
test_bug499655.xhtml \
test_cascade.html \
test_compute_data_with_start_struct.html \
test_css_eof_handling.html \

Просмотреть файл

@ -1,46 +0,0 @@
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=499655
-->
<head>
<title>Test for Bug 499655</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=499655">Mozilla Bug 499655</a>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 499655 **/
test1 = document.createElementNS("http://www.w3.org/1999/xhtml","test");
test2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst");
test3 = document.createElementNS("test","test");
test4 = document.createElementNS("test","TEst");
content = document.getElementById("content");
content.appendChild(test1);
content.appendChild(test2);
content.appendChild(test3);
content.appendChild(test4);
list = document.querySelectorAll('test');
is(list.length, 2, "Number of elements found");
is(list[0], test1, "First element didn't match");
is(list[1], test3, "Third element didn't match");
list = document.querySelectorAll('TEst');
is(list.length, 2, "Wrong number of elements found");
is(list[0], test1, "First element didn't match");
is(list[1], test4, "Fourth element didn't match");
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,49 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=499655
-->
<head>
<title>Test for Bug 499655</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=499655">Mozilla Bug 499655</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
<![CDATA[
test1 = document.createElementNS("http://www.w3.org/1999/xhtml","test");
test2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst");
test3 = document.createElementNS("test","test");
test4 = document.createElementNS("test","TEst");
content = document.getElementById("content");
content.appendChild(test1);
content.appendChild(test2);
content.appendChild(test3);
content.appendChild(test4);
list = document.querySelectorAll('test');
is(list.length, 2, "Number of elements found");
is(list[0], test1, "First element didn't match");
is(list[1] , test3, "Third element didn't match");
list = document.querySelectorAll('TEst');
is(list.length, 2, "Number of elements found");
is(list[0], test2, "Second element didn't match");
is(list[1], test4, "Fourth element didn't match");
]]>
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -4267,23 +4267,26 @@ nsTreeBodyFrame::GetPseudoStyleContext(nsIAtom* aPseudoElement)
NS_IMETHODIMP
nsTreeBodyFrame::PseudoMatches(nsIAtom* aTag, nsCSSSelector* aSelector, PRBool* aResult)
{
NS_ABORT_IF_FALSE(aSelector->mLowercaseTag == aTag,
"should not have been called");
// Iterate the pseudoclass list. For each item in the list, see if
// it is contained in our scratch array. If we have a miss, then
// we aren't a match. If all items in the pseudoclass list are
// present in the scratch array, then we have a match.
nsPseudoClassList* curr = aSelector->mPseudoClassList;
while (curr) {
PRInt32 index;
mScratchArray->GetIndexOf(curr->mAtom, &index);
if (index == -1) {
*aResult = PR_FALSE;
return NS_OK;
if (aSelector->mTag == aTag) {
// Iterate the pseudoclass list. For each item in the list, see if
// it is contained in our scratch array. If we have a miss, then
// we aren't a match. If all items in the pseudoclass list are
// present in the scratch array, then we have a match.
nsPseudoClassList* curr = aSelector->mPseudoClassList;
while (curr) {
PRInt32 index;
mScratchArray->GetIndexOf(curr->mAtom, &index);
if (index == -1) {
*aResult = PR_FALSE;
return NS_OK;
}
curr = curr->mNext;
}
curr = curr->mNext;
*aResult = PR_TRUE;
}
*aResult = PR_TRUE;
else
*aResult = PR_FALSE;
return NS_OK;
}