зеркало из https://github.com/mozilla/pjs.git
prep work for fixing bug 180379 - stop creating extra nsCSSSelectors - instead of creating them on the stack then copying them to the heap, start with them newly on the heap.
r=bzbarsky, sr=dbaron
This commit is contained in:
Родитель
aa24697417
Коммит
3dc37760d5
|
@ -89,7 +89,7 @@ struct SelectorList {
|
||||||
SelectorList(void);
|
SelectorList(void);
|
||||||
~SelectorList(void);
|
~SelectorList(void);
|
||||||
|
|
||||||
void AddSelector(const nsCSSSelector& aSelector);
|
void AddSelector(nsCSSSelector* aSelector);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
void Dump(void);
|
void Dump(void);
|
||||||
|
@ -121,13 +121,13 @@ SelectorList::~SelectorList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectorList::AddSelector(const nsCSSSelector& aSelector)
|
// assumes ownership of the selector!
|
||||||
|
// Do not add stack-based nsCSSSelector here!
|
||||||
|
void SelectorList::AddSelector(nsCSSSelector* aSelector)
|
||||||
{ // prepend to list
|
{ // prepend to list
|
||||||
nsCSSSelector* newSel = new nsCSSSelector(aSelector);
|
NS_ASSERTION(aSelector->mNext == nsnull, "are you sure this is a fresh selector?");
|
||||||
if (nsnull != newSel) {
|
aSelector->mNext = mSelectors;
|
||||||
newSel->mNext = mSelectors;
|
mSelectors = aSelector;
|
||||||
mSelectors = newSel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1619,8 +1619,12 @@ PRBool CSSParserImpl::ParseSelectorGroup(PRInt32& aErrorCode,
|
||||||
PRInt32 weight = 0;
|
PRInt32 weight = 0;
|
||||||
PRBool havePseudoElement = PR_FALSE;
|
PRBool havePseudoElement = PR_FALSE;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nsCSSSelector selector;
|
nsCSSSelector* headSelector = new nsCSSSelector;
|
||||||
if (! ParseSelector(aErrorCode, selector)) {
|
if (!headSelector) {
|
||||||
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
if (! ParseSelector(aErrorCode, *headSelector)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nsnull == list) {
|
if (nsnull == list) {
|
||||||
|
@ -1630,52 +1634,66 @@ PRBool CSSParserImpl::ParseSelectorGroup(PRInt32& aErrorCode,
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list->AddSelector(selector);
|
|
||||||
nsCSSSelector* listSel = list->mSelectors;
|
list->AddSelector(headSelector);
|
||||||
|
|
||||||
|
// from here on out, we maintain headSelector as the first
|
||||||
|
// non-pseudo element
|
||||||
|
|
||||||
// pull out pseudo elements here
|
// pull out pseudo elements here
|
||||||
nsAtomStringList* prevList = nsnull;
|
nsAtomStringList* prevList = nsnull;
|
||||||
nsAtomStringList* pseudoClassList = listSel->mPseudoClassList;
|
nsAtomStringList* pseudoClassList = headSelector->mPseudoClassList;
|
||||||
while (nsnull != pseudoClassList) {
|
while (nsnull != pseudoClassList) {
|
||||||
if (! IsPseudoClass(pseudoClassList->mAtom)) {
|
if (! IsPseudoClass(pseudoClassList->mAtom)) {
|
||||||
havePseudoElement = PR_TRUE;
|
havePseudoElement = PR_TRUE;
|
||||||
if (IsSinglePseudoClass(*listSel)) { // convert to pseudo element selector
|
if (IsSinglePseudoClass(*headSelector)) { // convert to pseudo element selector
|
||||||
nsIAtom* pseudoElement = pseudoClassList->mAtom; // steal ref count
|
nsIAtom* pseudoElement = pseudoClassList->mAtom; // steal ref count
|
||||||
pseudoClassList->mAtom = nsnull;
|
pseudoClassList->mAtom = nsnull;
|
||||||
listSel->Reset();
|
headSelector->Reset();
|
||||||
if (listSel->mNext) {// more to the selector
|
if (headSelector->mNext) {// more to the selector
|
||||||
listSel->mOperator = PRUnichar('>');
|
headSelector->mOperator = PRUnichar('>');
|
||||||
nsCSSSelector empty;
|
headSelector = new nsCSSSelector;
|
||||||
list->AddSelector(empty); // leave a blank (universal) selector in the middle
|
if (!headSelector) {
|
||||||
listSel = list->mSelectors; // use the new one for the pseudo
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// leave a blank (universal) selector in the middle
|
||||||
|
list->AddSelector(headSelector);
|
||||||
}
|
}
|
||||||
listSel->mTag = pseudoElement;
|
headSelector->mTag = pseudoElement;
|
||||||
}
|
}
|
||||||
else { // append new pseudo element selector
|
else { // append new pseudo element selector
|
||||||
selector.Reset();
|
nsCSSSelector *pseudoElement = new nsCSSSelector;
|
||||||
selector.mTag = pseudoClassList->mAtom; // steal ref count
|
if (!pseudoElement) {
|
||||||
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
pseudoElement->mTag = pseudoClassList->mAtom; // steal ref count
|
||||||
#ifdef INCLUDE_XUL
|
#ifdef INCLUDE_XUL
|
||||||
if (IsTreePseudoElement(selector.mTag)) {
|
if (IsTreePseudoElement(pseudoElement->mTag)) {
|
||||||
// Take the remaining "pseudoclasses" that we parsed
|
// Take the remaining "pseudoclasses" that we parsed
|
||||||
// inside the tree pseudoelement's ()-list, and
|
// inside the tree pseudoelement's ()-list, and
|
||||||
// make our new selector have these pseudoclasses
|
// make our new selector have these pseudoclasses
|
||||||
// in its pseudoclass list.
|
// in its pseudoclass list.
|
||||||
selector.mPseudoClassList = pseudoClassList->mNext;
|
pseudoElement->mPseudoClassList = pseudoClassList->mNext;
|
||||||
pseudoClassList->mNext = nsnull;
|
pseudoClassList->mNext = nsnull;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
list->AddSelector(selector);
|
list->AddSelector(pseudoElement);
|
||||||
|
|
||||||
|
// remember, headSelector is the first non-pseudo element
|
||||||
pseudoClassList->mAtom = nsnull;
|
pseudoClassList->mAtom = nsnull;
|
||||||
listSel->mOperator = PRUnichar('>');
|
headSelector->mOperator = PRUnichar('>');
|
||||||
if (nsnull == prevList) { // delete list entry
|
if (nsnull == prevList) { // delete list entry
|
||||||
listSel->mPseudoClassList = pseudoClassList->mNext;
|
headSelector->mPseudoClassList = pseudoClassList->mNext;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prevList->mNext = pseudoClassList->mNext;
|
prevList->mNext = pseudoClassList->mNext;
|
||||||
}
|
}
|
||||||
pseudoClassList->mNext = nsnull;
|
pseudoClassList->mNext = nsnull;
|
||||||
delete pseudoClassList;
|
delete pseudoClassList;
|
||||||
weight += listSel->CalcWeight(); // capture weight from remainder
|
weight += headSelector->CalcWeight(); // capture weight from remainder
|
||||||
}
|
}
|
||||||
break; // only one pseudo element per selector
|
break; // only one pseudo element per selector
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1717,7 @@ PRBool CSSParserImpl::ParseSelectorGroup(PRInt32& aErrorCode,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
weight += selector.CalcWeight();
|
weight += headSelector->CalcWeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!list) {
|
if (!list) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct SelectorList {
|
||||||
SelectorList(void);
|
SelectorList(void);
|
||||||
~SelectorList(void);
|
~SelectorList(void);
|
||||||
|
|
||||||
void AddSelector(const nsCSSSelector& aSelector);
|
void AddSelector(nsCSSSelector* aSelector);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
void Dump(void);
|
void Dump(void);
|
||||||
|
@ -121,13 +121,13 @@ SelectorList::~SelectorList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectorList::AddSelector(const nsCSSSelector& aSelector)
|
// assumes ownership of the selector!
|
||||||
|
// Do not add stack-based nsCSSSelector here!
|
||||||
|
void SelectorList::AddSelector(nsCSSSelector* aSelector)
|
||||||
{ // prepend to list
|
{ // prepend to list
|
||||||
nsCSSSelector* newSel = new nsCSSSelector(aSelector);
|
NS_ASSERTION(aSelector->mNext == nsnull, "are you sure this is a fresh selector?");
|
||||||
if (nsnull != newSel) {
|
aSelector->mNext = mSelectors;
|
||||||
newSel->mNext = mSelectors;
|
mSelectors = aSelector;
|
||||||
mSelectors = newSel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1619,8 +1619,12 @@ PRBool CSSParserImpl::ParseSelectorGroup(PRInt32& aErrorCode,
|
||||||
PRInt32 weight = 0;
|
PRInt32 weight = 0;
|
||||||
PRBool havePseudoElement = PR_FALSE;
|
PRBool havePseudoElement = PR_FALSE;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nsCSSSelector selector;
|
nsCSSSelector* headSelector = new nsCSSSelector;
|
||||||
if (! ParseSelector(aErrorCode, selector)) {
|
if (!headSelector) {
|
||||||
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
if (! ParseSelector(aErrorCode, *headSelector)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nsnull == list) {
|
if (nsnull == list) {
|
||||||
|
@ -1630,52 +1634,66 @@ PRBool CSSParserImpl::ParseSelectorGroup(PRInt32& aErrorCode,
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list->AddSelector(selector);
|
|
||||||
nsCSSSelector* listSel = list->mSelectors;
|
list->AddSelector(headSelector);
|
||||||
|
|
||||||
|
// from here on out, we maintain headSelector as the first
|
||||||
|
// non-pseudo element
|
||||||
|
|
||||||
// pull out pseudo elements here
|
// pull out pseudo elements here
|
||||||
nsAtomStringList* prevList = nsnull;
|
nsAtomStringList* prevList = nsnull;
|
||||||
nsAtomStringList* pseudoClassList = listSel->mPseudoClassList;
|
nsAtomStringList* pseudoClassList = headSelector->mPseudoClassList;
|
||||||
while (nsnull != pseudoClassList) {
|
while (nsnull != pseudoClassList) {
|
||||||
if (! IsPseudoClass(pseudoClassList->mAtom)) {
|
if (! IsPseudoClass(pseudoClassList->mAtom)) {
|
||||||
havePseudoElement = PR_TRUE;
|
havePseudoElement = PR_TRUE;
|
||||||
if (IsSinglePseudoClass(*listSel)) { // convert to pseudo element selector
|
if (IsSinglePseudoClass(*headSelector)) { // convert to pseudo element selector
|
||||||
nsIAtom* pseudoElement = pseudoClassList->mAtom; // steal ref count
|
nsIAtom* pseudoElement = pseudoClassList->mAtom; // steal ref count
|
||||||
pseudoClassList->mAtom = nsnull;
|
pseudoClassList->mAtom = nsnull;
|
||||||
listSel->Reset();
|
headSelector->Reset();
|
||||||
if (listSel->mNext) {// more to the selector
|
if (headSelector->mNext) {// more to the selector
|
||||||
listSel->mOperator = PRUnichar('>');
|
headSelector->mOperator = PRUnichar('>');
|
||||||
nsCSSSelector empty;
|
headSelector = new nsCSSSelector;
|
||||||
list->AddSelector(empty); // leave a blank (universal) selector in the middle
|
if (!headSelector) {
|
||||||
listSel = list->mSelectors; // use the new one for the pseudo
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// leave a blank (universal) selector in the middle
|
||||||
|
list->AddSelector(headSelector);
|
||||||
}
|
}
|
||||||
listSel->mTag = pseudoElement;
|
headSelector->mTag = pseudoElement;
|
||||||
}
|
}
|
||||||
else { // append new pseudo element selector
|
else { // append new pseudo element selector
|
||||||
selector.Reset();
|
nsCSSSelector *pseudoElement = new nsCSSSelector;
|
||||||
selector.mTag = pseudoClassList->mAtom; // steal ref count
|
if (!pseudoElement) {
|
||||||
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
pseudoElement->mTag = pseudoClassList->mAtom; // steal ref count
|
||||||
#ifdef INCLUDE_XUL
|
#ifdef INCLUDE_XUL
|
||||||
if (IsTreePseudoElement(selector.mTag)) {
|
if (IsTreePseudoElement(pseudoElement->mTag)) {
|
||||||
// Take the remaining "pseudoclasses" that we parsed
|
// Take the remaining "pseudoclasses" that we parsed
|
||||||
// inside the tree pseudoelement's ()-list, and
|
// inside the tree pseudoelement's ()-list, and
|
||||||
// make our new selector have these pseudoclasses
|
// make our new selector have these pseudoclasses
|
||||||
// in its pseudoclass list.
|
// in its pseudoclass list.
|
||||||
selector.mPseudoClassList = pseudoClassList->mNext;
|
pseudoElement->mPseudoClassList = pseudoClassList->mNext;
|
||||||
pseudoClassList->mNext = nsnull;
|
pseudoClassList->mNext = nsnull;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
list->AddSelector(selector);
|
list->AddSelector(pseudoElement);
|
||||||
|
|
||||||
|
// remember, headSelector is the first non-pseudo element
|
||||||
pseudoClassList->mAtom = nsnull;
|
pseudoClassList->mAtom = nsnull;
|
||||||
listSel->mOperator = PRUnichar('>');
|
headSelector->mOperator = PRUnichar('>');
|
||||||
if (nsnull == prevList) { // delete list entry
|
if (nsnull == prevList) { // delete list entry
|
||||||
listSel->mPseudoClassList = pseudoClassList->mNext;
|
headSelector->mPseudoClassList = pseudoClassList->mNext;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prevList->mNext = pseudoClassList->mNext;
|
prevList->mNext = pseudoClassList->mNext;
|
||||||
}
|
}
|
||||||
pseudoClassList->mNext = nsnull;
|
pseudoClassList->mNext = nsnull;
|
||||||
delete pseudoClassList;
|
delete pseudoClassList;
|
||||||
weight += listSel->CalcWeight(); // capture weight from remainder
|
weight += headSelector->CalcWeight(); // capture weight from remainder
|
||||||
}
|
}
|
||||||
break; // only one pseudo element per selector
|
break; // only one pseudo element per selector
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1717,7 @@ PRBool CSSParserImpl::ParseSelectorGroup(PRInt32& aErrorCode,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
weight += selector.CalcWeight();
|
weight += headSelector->CalcWeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!list) {
|
if (!list) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче