зеркало из https://github.com/mozilla/pjs.git
Merge backout of changeset 358af1196dc2 (bug 499655) until we get bug 507487 sorted out.
This commit is contained in:
Коммит
794f6341af
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче