[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198
antti at apple.com
antti at apple.com
Sun Feb 20 23:51:30 UTC 2011
The following commit has been merged in the webkit-1.3 branch:
commit 3c9313022c8ae99d2591a9993258016e0a5e24b6
Author: antti at apple.com <antti at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Jan 25 23:31:18 2011 +0000
https://bugs.webkit.org/show_bug.cgi?id=52983
Eliminate m_tagHistory pointer from CSSSelector
Reviewed by Darin Adler.
Keep the component selectors in the array in CSSSelectorList instead
of maintaining a linked list between them. This allows eliminating
m_tagHistory pointer, shrinking CSSSelector by 25% (selection performance
seems to improve some too due to better locality).
* WebCore.xcodeproj/project.pbxproj:
Make CSSSelector.h a private header.
* css/CSSGrammar.y:
Use CSSParserSelector during parsing to keep the tag history in
a linked list. This is flattened to an array after parsing.
Use accessors for setting selector values.
Use OwnPtr in selector vector.
* css/CSSPageRule.cpp:
(WebCore::CSSPageRule::CSSPageRule):
* css/CSSPageRule.h:
(WebCore::CSSPageRule::create):
Simplify.
* css/CSSParser.cpp:
(WebCore::CSSParser::~CSSParser):
(WebCore::CSSParser::createFloatingSelector):
(WebCore::CSSParser::sinkFloatingSelector):
(WebCore::CSSParser::createStyleRule):
(WebCore::CSSParser::updateSpecifiersWithElementName):
(WebCore::CSSParser::createPageRule):
* css/CSSParser.h:
(WebCore::CSSParser::reusableSelectorVector):
CSSSelector -> CSSParserSelector.
Use OwnPtr in selector vector.
* css/CSSParserValues.cpp:
(WebCore::CSSParserSelector::CSSParserSelector):
(WebCore::CSSParserSelector::~CSSParserSelector):
* css/CSSParserValues.h:
(WebCore::CSSParserSelector::releaseSelector):
(WebCore::CSSParserSelector::setTag):
(WebCore::CSSParserSelector::setValue):
(WebCore::CSSParserSelector::setAttribute):
(WebCore::CSSParserSelector::setArgument):
(WebCore::CSSParserSelector::setSimpleSelector):
(WebCore::CSSParserSelector::setMatch):
(WebCore::CSSParserSelector::setRelation):
(WebCore::CSSParserSelector::setForPage):
(WebCore::CSSParserSelector::pseudoType):
(WebCore::CSSParserSelector::isUnknownPseudoElement):
(WebCore::CSSParserSelector::isSimple):
(WebCore::CSSParserSelector::tagHistory):
(WebCore::CSSParserSelector::setTagHistory):
Linked list used during parsing.
Avoid recursive destruction.
* css/CSSSelector.cpp:
(WebCore::CSSSelector::extractPseudoType):
(WebCore::CSSSelector::operator==):
(WebCore::CSSSelector::selectorText):
(WebCore::CSSSelector::setSimpleSelector):
* css/CSSSelector.h:
(WebCore::CSSSelector::CSSSelector):
(WebCore::CSSSelector::~CSSSelector):
(WebCore::CSSSelector::tagHistory):
(WebCore::CSSSelector::tag):
(WebCore::CSSSelector::value):
(WebCore::CSSSelector::setTag):
(WebCore::CSSSelector::isLastInTagHistory):
(WebCore::CSSSelector::setNotLastInTagHistory):
(WebCore::CSSSelector::RareData::RareData):
(WebCore::CSSSelector::RareData::~RareData):
(WebCore::CSSSelector::createRareData):
(WebCore::CSSSelector::setValue):
Remove m_tagHistory.
Keep m_value in the union with the rare data pointer instead.
Make m_value and m_tag private, implement accessors.
Add a new bit to indicate end of the tag history (multipart selector).
Eliminate complex destruction. Selectors are now deleted as an array or by a CSSParserSelector chain.
* css/CSSSelectorList.cpp:
(WebCore::CSSSelectorList::adoptSelectorVector):
Flatten everything to an array.
(WebCore::SelectorNeedsNamespaceResolutionFunctor::operator()):
* css/CSSSelectorList.h:
(WebCore::CSSSelectorList::hasOneSelector):
(WebCore::CSSSelectorList::next):
Skip over the subparts of multipart selectors to find the next selector.
* css/CSSStyleRule.h:
(WebCore::CSSStyleRule::adoptSelectorVector):
CSSSelector -> CSSParserSelector.
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
(WebCore::CSSRuleSet::addRule):
(WebCore::collectIdsAndSiblingRulesFromList):
(WebCore::CSSStyleSelector::matchPageRulesForList):
* dom/Node.cpp:
(WebCore::Node::querySelector):
* dom/SelectorNodeList.cpp:
(WebCore::createSelectorNodeList):
Use accessors.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76648 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 383ce37..f3c1248 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,122 @@
+2011-01-23 Antti Koivisto <antti at apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=52983
+ Eliminate m_tagHistory pointer from CSSSelector
+
+ Keep the component selectors in the array in CSSSelectorList instead
+ of maintaining a linked list between them. This allows eliminating
+ m_tagHistory pointer, shrinking CSSSelector by 25% (selection performance
+ seems to improve some too due to better locality).
+
+ * WebCore.xcodeproj/project.pbxproj:
+
+ Make CSSSelector.h a private header.
+
+ * css/CSSGrammar.y:
+
+ Use CSSParserSelector during parsing to keep the tag history in
+ a linked list. This is flattened to an array after parsing.
+ Use accessors for setting selector values.
+ Use OwnPtr in selector vector.
+
+ * css/CSSPageRule.cpp:
+ (WebCore::CSSPageRule::CSSPageRule):
+ * css/CSSPageRule.h:
+ (WebCore::CSSPageRule::create):
+
+ Simplify.
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::~CSSParser):
+ (WebCore::CSSParser::createFloatingSelector):
+ (WebCore::CSSParser::sinkFloatingSelector):
+ (WebCore::CSSParser::createStyleRule):
+ (WebCore::CSSParser::updateSpecifiersWithElementName):
+ (WebCore::CSSParser::createPageRule):
+ * css/CSSParser.h:
+ (WebCore::CSSParser::reusableSelectorVector):
+
+ CSSSelector -> CSSParserSelector.
+ Use OwnPtr in selector vector.
+
+ * css/CSSParserValues.cpp:
+ (WebCore::CSSParserSelector::CSSParserSelector):
+ (WebCore::CSSParserSelector::~CSSParserSelector):
+ * css/CSSParserValues.h:
+ (WebCore::CSSParserSelector::releaseSelector):
+ (WebCore::CSSParserSelector::setTag):
+ (WebCore::CSSParserSelector::setValue):
+ (WebCore::CSSParserSelector::setAttribute):
+ (WebCore::CSSParserSelector::setArgument):
+ (WebCore::CSSParserSelector::setSimpleSelector):
+ (WebCore::CSSParserSelector::setMatch):
+ (WebCore::CSSParserSelector::setRelation):
+ (WebCore::CSSParserSelector::setForPage):
+ (WebCore::CSSParserSelector::pseudoType):
+ (WebCore::CSSParserSelector::isUnknownPseudoElement):
+ (WebCore::CSSParserSelector::isSimple):
+ (WebCore::CSSParserSelector::tagHistory):
+ (WebCore::CSSParserSelector::setTagHistory):
+
+ Linked list used during parsing.
+ Avoid recursive destruction.
+
+ * css/CSSSelector.cpp:
+ (WebCore::CSSSelector::extractPseudoType):
+ (WebCore::CSSSelector::operator==):
+ (WebCore::CSSSelector::selectorText):
+ (WebCore::CSSSelector::setSimpleSelector):
+ * css/CSSSelector.h:
+ (WebCore::CSSSelector::CSSSelector):
+ (WebCore::CSSSelector::~CSSSelector):
+ (WebCore::CSSSelector::tagHistory):
+ (WebCore::CSSSelector::tag):
+ (WebCore::CSSSelector::value):
+ (WebCore::CSSSelector::setTag):
+ (WebCore::CSSSelector::isLastInTagHistory):
+ (WebCore::CSSSelector::setNotLastInTagHistory):
+ (WebCore::CSSSelector::RareData::RareData):
+ (WebCore::CSSSelector::RareData::~RareData):
+ (WebCore::CSSSelector::createRareData):
+ (WebCore::CSSSelector::setValue):
+
+ Remove m_tagHistory.
+ Keep m_value in the union with the rare data pointer instead.
+ Make m_value and m_tag private, implement accessors.
+ Add a new bit to indicate end of the tag history (multipart selector).
+ Eliminate complex destruction. Selectors are now deleted as an array or by a CSSParserSelector chain.
+
+ * css/CSSSelectorList.cpp:
+ (WebCore::CSSSelectorList::adoptSelectorVector):
+
+ Flatten everything to an array.
+
+ (WebCore::SelectorNeedsNamespaceResolutionFunctor::operator()):
+ * css/CSSSelectorList.h:
+ (WebCore::CSSSelectorList::hasOneSelector):
+ (WebCore::CSSSelectorList::next):
+
+ Skip over the subparts of multipart selectors to find the next selector.
+
+ * css/CSSStyleRule.h:
+ (WebCore::CSSStyleRule::adoptSelectorVector):
+
+ CSSSelector -> CSSParserSelector.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+ (WebCore::CSSRuleSet::addRule):
+ (WebCore::collectIdsAndSiblingRulesFromList):
+ (WebCore::CSSStyleSelector::matchPageRulesForList):
+ * dom/Node.cpp:
+ (WebCore::Node::querySelector):
+ * dom/SelectorNodeList.cpp:
+ (WebCore::createSelectorNodeList):
+
+ Use accessors.
+
2011-01-25 James Simonsen <simonjam at chromium.org>
Reviewed by Tony Chang.
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index ab1a38d..3c7def3 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -3273,7 +3273,7 @@
A80E734F0A199C77007FB8C5 /* CSSSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A80E73480A199C77007FB8C5 /* CSSSelector.cpp */; };
A80E73500A199C77007FB8C5 /* StyleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E73490A199C77007FB8C5 /* StyleBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
A80E73510A199C77007FB8C5 /* StyleList.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E734A0A199C77007FB8C5 /* StyleList.h */; };
- A80E73520A199C77007FB8C5 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E734B0A199C77007FB8C5 /* CSSSelector.h */; };
+ A80E73520A199C77007FB8C5 /* CSSSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E734B0A199C77007FB8C5 /* CSSSelector.h */; settings = {ATTRIBUTES = (Private, ); }; };
A80E73530A199C77007FB8C5 /* StyleBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A80E734C0A199C77007FB8C5 /* StyleBase.cpp */; };
A80E7A170A19C3D6007FB8C5 /* JSHTMLMetaElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A80E7A150A19C3D6007FB8C5 /* JSHTMLMetaElement.cpp */; };
A80E7A180A19C3D6007FB8C5 /* JSHTMLMetaElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A80E7A160A19C3D6007FB8C5 /* JSHTMLMetaElement.h */; };
diff --git a/Source/WebCore/css/CSSGrammar.y b/Source/WebCore/css/CSSGrammar.y
index a5fe795..03d25d9 100644
--- a/Source/WebCore/css/CSSGrammar.y
+++ b/Source/WebCore/css/CSSGrammar.y
@@ -69,8 +69,8 @@ using namespace HTMLNames;
CSSRule* rule;
CSSRuleList* ruleList;
- CSSSelector* selector;
- Vector<CSSSelector*>* selectorList;
+ CSSParserSelector* selector;
+ Vector<OwnPtr<CSSParserSelector> >* selectorList;
CSSSelector::MarginBoxType marginBox;
CSSSelector::Relation relation;
MediaList* mediaList;
@@ -663,14 +663,14 @@ page_selector:
IDENT {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+ $$->setTag(QualifiedName(nullAtom, $1, p->m_defaultNamespace));
$$->setForPage();
}
| IDENT pseudo_page {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = $2;
if ($$) {
- $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+ $$->setTag(QualifiedName(nullAtom, $1, p->m_defaultNamespace));
$$->setForPage();
}
}
@@ -812,7 +812,6 @@ selector_list:
if ($1) {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->reusableSelectorVector();
- deleteAllValues(*$$);
$$->shrink(0);
$$->append(p->sinkFloatingSelector($1));
p->updateLastSelectorLineAndPosition();
@@ -853,10 +852,10 @@ selector:
$$ = 0;
else if ($$) {
CSSParser* p = static_cast<CSSParser*>(parser);
- CSSSelector* end = $$;
+ CSSParserSelector* end = $$;
while (end->tagHistory())
end = end->tagHistory();
- end->m_relation = CSSSelector::Descendant;
+ end->setRelation(CSSSelector::Descendant);
end->setTagHistory(p->sinkFloatingSelector($1));
if (Document* doc = p->document())
doc->setUsesDescendantRules(true);
@@ -868,10 +867,10 @@ selector:
$$ = 0;
else if ($$) {
CSSParser* p = static_cast<CSSParser*>(parser);
- CSSSelector* end = $$;
+ CSSParserSelector* end = $$;
while (end->tagHistory())
end = end->tagHistory();
- end->m_relation = $2;
+ end->setRelation($2);
end->setTagHistory(p->sinkFloatingSelector($1));
if ($2 == CSSSelector::Child) {
if (Document* doc = p->document())
@@ -897,7 +896,7 @@ simple_selector:
element_name {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_tag = QualifiedName(nullAtom, $1, p->m_defaultNamespace);
+ $$->setTag(QualifiedName(nullAtom, $1, p->m_defaultNamespace));
}
| element_name specifier_list {
$$ = $2;
@@ -914,10 +913,10 @@ simple_selector:
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
if (p->m_styleSheet)
- $$->m_tag = QualifiedName(namespacePrefix, $2,
- p->m_styleSheet->determineNamespace(namespacePrefix));
+ $$->setTag(QualifiedName(namespacePrefix, $2,
+ p->m_styleSheet->determineNamespace(namespacePrefix)));
else // FIXME: Shouldn't this case be an error?
- $$->m_tag = QualifiedName(nullAtom, $2, p->m_defaultNamespace);
+ $$->setTag(QualifiedName(nullAtom, $2, p->m_defaultNamespace));
}
| namespace_selector element_name specifier_list {
$$ = $3;
@@ -956,8 +955,8 @@ specifier_list:
$$ = 0;
else if ($1) {
CSSParser* p = static_cast<CSSParser*>(parser);
- CSSSelector* end;
- CSSSelector* history;
+ CSSParserSelector* end;
+ CSSParserSelector* history;
// Ensure that unknown pseudo element always stays at the top of selector chain.
if ($2->isUnknownPseudoElement()) {
end = $2;
@@ -969,7 +968,7 @@ specifier_list:
$$ = end;
while(end->tagHistory())
end = end->tagHistory();
- end->m_relation = CSSSelector::SubSelector;
+ end->setRelation(CSSSelector::SubSelector);
end->setTagHistory(p->sinkFloatingSelector(history));
}
}
@@ -982,10 +981,10 @@ specifier:
IDSEL {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_match = CSSSelector::Id;
+ $$->setMatch(CSSSelector::Id);
if (!p->m_strict)
$1.lower();
- $$->m_value = $1;
+ $$->setValue($1);
}
| HEX {
if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
@@ -993,10 +992,10 @@ specifier:
} else {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_match = CSSSelector::Id;
+ $$->setMatch(CSSSelector::Id);
if (!p->m_strict)
$1.lower();
- $$->m_value = $1;
+ $$->setValue($1);
}
}
| class
@@ -1008,10 +1007,10 @@ class:
'.' IDENT {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_match = CSSSelector::Class;
+ $$->setMatch(CSSSelector::Class);
if (!p->m_strict)
$2.lower();
- $$->m_value = $2;
+ $$->setValue($2);
}
;
@@ -1030,13 +1029,13 @@ attrib:
'[' maybe_space attr_name ']' {
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
$$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
- $$->m_match = CSSSelector::Set;
+ $$->setMatch(CSSSelector::Set);
}
| '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
$$->setAttribute(QualifiedName(nullAtom, $3, nullAtom));
- $$->m_match = (CSSSelector::Match)$4;
- $$->m_value = $6;
+ $$->setMatch((CSSSelector::Match)$4);
+ $$->setValue($6);
}
| '[' maybe_space namespace_selector attr_name ']' {
AtomicString namespacePrefix = $3;
@@ -1044,7 +1043,7 @@ attrib:
$$ = p->createFloatingSelector();
$$->setAttribute(QualifiedName(namespacePrefix, $4,
p->m_styleSheet->determineNamespace(namespacePrefix)));
- $$->m_match = CSSSelector::Set;
+ $$->setMatch(CSSSelector::Set);
}
| '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
AtomicString namespacePrefix = $3;
@@ -1052,8 +1051,8 @@ attrib:
$$ = p->createFloatingSelector();
$$->setAttribute(QualifiedName(namespacePrefix, $4,
p->m_styleSheet->determineNamespace(namespacePrefix)));
- $$->m_match = (CSSSelector::Match)$5;
- $$->m_value = $7;
+ $$->setMatch((CSSSelector::Match)$5);
+ $$->setValue($7);
}
;
@@ -1086,9 +1085,9 @@ ident_or_string:
pseudo_page:
':' IDENT {
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
- $$->m_match = CSSSelector::PagePseudoClass;
+ $$->setMatch(CSSSelector::PagePseudoClass);
$2.lower();
- $$->m_value = $2;
+ $$->setValue($2);
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown)
$$ = 0;
@@ -1097,9 +1096,9 @@ pseudo_page:
pseudo:
':' IDENT {
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
- $$->m_match = CSSSelector::PseudoClass;
+ $$->setMatch(CSSSelector::PseudoClass);
$2.lower();
- $$->m_value = $2;
+ $$->setValue($2);
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown)
$$ = 0;
@@ -1131,9 +1130,9 @@ pseudo:
}
| ':' ':' IDENT {
$$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
- $$->m_match = CSSSelector::PseudoElement;
+ $$->setMatch(CSSSelector::PseudoElement);
$3.lower();
- $$->m_value = $3;
+ $$->setValue($3);
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoFirstLine) {
CSSParser* p = static_cast<CSSParser*>(parser);
@@ -1150,9 +1149,9 @@ pseudo:
| ':' FUNCTION maybe_space NTH maybe_space ')' {
CSSParser *p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_match = CSSSelector::PseudoClass;
+ $$->setMatch(CSSSelector::PseudoClass);
$$->setArgument($4);
- $$->m_value = $2;
+ $$->setValue($2);
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown)
$$ = 0;
@@ -1168,9 +1167,9 @@ pseudo:
| ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space ')' {
CSSParser *p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_match = CSSSelector::PseudoClass;
+ $$->setMatch(CSSSelector::PseudoClass);
$$->setArgument(String::number($4 * $5));
- $$->m_value = $2;
+ $$->setValue($2);
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown)
$$ = 0;
@@ -1186,10 +1185,10 @@ pseudo:
| ':' FUNCTION maybe_space IDENT maybe_space ')' {
CSSParser *p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_match = CSSSelector::PseudoClass;
+ $$->setMatch(CSSSelector::PseudoClass);
$$->setArgument($4);
$2.lower();
- $$->m_value = $2;
+ $$->setValue($2);
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown)
$$ = 0;
@@ -1211,10 +1210,10 @@ pseudo:
else {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingSelector();
- $$->m_match = CSSSelector::PseudoClass;
- $$->setSimpleSelector(p->sinkFloatingSelector($4));
+ $$->setMatch(CSSSelector::PseudoClass);
+ $$->setSimpleSelector(p->sinkFloatingSelector($4)->releaseSelector());
$2.lower();
- $$->m_value = $2;
+ $$->setValue($2);
}
}
;
diff --git a/Source/WebCore/css/CSSPageRule.cpp b/Source/WebCore/css/CSSPageRule.cpp
index c85c1aa..c3dbcaa 100644
--- a/Source/WebCore/css/CSSPageRule.cpp
+++ b/Source/WebCore/css/CSSPageRule.cpp
@@ -27,12 +27,9 @@
namespace WebCore {
-CSSPageRule::CSSPageRule(CSSStyleSheet* parent, CSSSelector* selector, int sourceLine)
+CSSPageRule::CSSPageRule(CSSStyleSheet* parent, int sourceLine)
: CSSStyleRule(parent, sourceLine)
{
- Vector<CSSSelector*> selectors;
- selectors.append(selector);
- adoptSelectorVector(selectors);
}
CSSPageRule::~CSSPageRule()
diff --git a/Source/WebCore/css/CSSPageRule.h b/Source/WebCore/css/CSSPageRule.h
index bdfb751..9c1c41f 100644
--- a/Source/WebCore/css/CSSPageRule.h
+++ b/Source/WebCore/css/CSSPageRule.h
@@ -34,9 +34,9 @@ class CSSSelectorList;
class CSSPageRule : public CSSStyleRule {
public:
- static PassRefPtr<CSSPageRule> create(CSSStyleSheet* parent, CSSSelector* selector, int sourceLine)
+ static PassRefPtr<CSSPageRule> create(CSSStyleSheet* parent, int sourceLine)
{
- return adoptRef(new CSSPageRule(parent, selector, sourceLine));
+ return adoptRef(new CSSPageRule(parent, sourceLine));
}
virtual ~CSSPageRule();
@@ -44,7 +44,7 @@ public:
virtual String selectorText() const;
private:
- CSSPageRule(CSSStyleSheet* parent, CSSSelector* selector, int sourceLine);
+ CSSPageRule(CSSStyleSheet* parent, int sourceLine);
virtual bool isPageRule() { return true; }
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index 89220cd..817d46c 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -179,7 +179,6 @@ CSSParser::~CSSParser()
fastDeleteAllValues(m_floatingSelectors);
deleteAllValues(m_floatingValueLists);
deleteAllValues(m_floatingFunctions);
- deleteAllValues(m_reusableSelectorVector);
}
void CSSParserString::lower()
@@ -5700,20 +5699,20 @@ void CSSParser::countLines()
}
}
-CSSSelector* CSSParser::createFloatingSelector()
+CSSParserSelector* CSSParser::createFloatingSelector()
{
- CSSSelector* selector = fastNew<CSSSelector>();
+ CSSParserSelector* selector = new CSSParserSelector;
m_floatingSelectors.add(selector);
return selector;
}
-CSSSelector* CSSParser::sinkFloatingSelector(CSSSelector* selector)
+PassOwnPtr<CSSParserSelector> CSSParser::sinkFloatingSelector(CSSParserSelector* selector)
{
if (selector) {
ASSERT(m_floatingSelectors.contains(selector));
m_floatingSelectors.remove(selector);
}
- return selector;
+ return adoptPtr(selector);
}
CSSParserValueList* CSSParser::createFloatingValueList()
@@ -5855,7 +5854,7 @@ WebKitCSSKeyframesRule* CSSParser::createKeyframesRule()
return rulePtr;
}
-CSSRule* CSSParser::createStyleRule(Vector<CSSSelector*>* selectors)
+CSSRule* CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors)
{
CSSStyleRule* result = 0;
markRuleBodyEnd();
@@ -5917,21 +5916,21 @@ void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri
m_styleSheet->addNamespace(this, prefix, uri);
}
-void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSSelector* specifiers)
+void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers)
{
AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace;
QualifiedName tag = QualifiedName(namespacePrefix, elementName, determinedNamespace);
if (!specifiers->isUnknownPseudoElement()) {
- specifiers->m_tag = tag;
+ specifiers->setTag(tag);
return;
}
if (Document* doc = document())
doc->setUsesDescendantRules(true);
- specifiers->m_relation = CSSSelector::ShadowDescendant;
- if (CSSSelector* history = specifiers->tagHistory()) {
- history->m_tag = tag;
+ specifiers->setRelation(CSSSelector::ShadowDescendant);
+ if (CSSParserSelector* history = specifiers->tagHistory()) {
+ history->setTag(tag);
return;
}
@@ -5940,19 +5939,22 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
if (elementName == starAtom && m_defaultNamespace == starAtom)
return;
- CSSSelector* elementNameSelector = fastNew<CSSSelector>();
- elementNameSelector->m_tag = tag;
+ CSSParserSelector* elementNameSelector = new CSSParserSelector;
+ elementNameSelector->setTag(tag);
specifiers->setTagHistory(elementNameSelector);
}
-CSSRule* CSSParser::createPageRule(CSSSelector* pageSelector)
+CSSRule* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector)
{
// FIXME: Margin at-rules are ignored.
m_allowImportRules = m_allowNamespaceDeclarations = false;
CSSPageRule* pageRule = 0;
if (pageSelector) {
- RefPtr<CSSPageRule> rule = CSSPageRule::create(m_styleSheet, pageSelector, m_lastSelectorLineNumber);
+ RefPtr<CSSPageRule> rule = CSSPageRule::create(m_styleSheet, m_lastSelectorLineNumber);
+ Vector<OwnPtr<CSSParserSelector> > selectorVector;
+ selectorVector.append(pageSelector);
+ rule->adoptSelectorVector(selectorVector);
rule->setDeclaration(CSSMutableStyleDeclaration::create(rule.get(), m_parsedProperties, m_numParsedProperties));
pageRule = rule.get();
m_parsedStyleObjects.append(rule.release());
diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h
index d326812..d1b2061 100644
--- a/Source/WebCore/css/CSSParser.h
+++ b/Source/WebCore/css/CSSParser.h
@@ -170,8 +170,8 @@ namespace WebCore {
int yyparse();
- CSSSelector* createFloatingSelector();
- CSSSelector* sinkFloatingSelector(CSSSelector*);
+ CSSParserSelector* createFloatingSelector();
+ PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
CSSParserValueList* createFloatingValueList();
CSSParserValueList* sinkFloatingValueList(CSSParserValueList*);
@@ -188,9 +188,9 @@ namespace WebCore {
WebKitCSSKeyframesRule* createKeyframesRule();
CSSRule* createMediaRule(MediaList*, CSSRuleList*);
CSSRuleList* createRuleList();
- CSSRule* createStyleRule(Vector<CSSSelector*>* selectors);
+ CSSRule* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
CSSRule* createFontFaceRule();
- CSSRule* createPageRule(CSSSelector* pageSelector);
+ CSSRule* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
CSSRule* createMarginAtRule(CSSSelector::MarginBoxType marginBox);
void startDeclarationsForMarginBox();
void endDeclarationsForMarginBox();
@@ -204,11 +204,11 @@ namespace WebCore {
PassOwnPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
void addNamespace(const AtomicString& prefix, const AtomicString& uri);
- void updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSSelector*);
+ void updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*);
void invalidBlockHit();
- Vector<CSSSelector*>* reusableSelectorVector() { return &m_reusableSelectorVector; }
+ Vector<OwnPtr<CSSParserSelector> >* reusableSelectorVector() { return &m_reusableSelectorVector; }
void updateLastSelectorLineAndPosition();
@@ -302,7 +302,7 @@ namespace WebCore {
Vector<RefPtr<StyleBase> > m_parsedStyleObjects;
Vector<RefPtr<CSSRuleList> > m_parsedRuleLists;
- HashSet<CSSSelector*> m_floatingSelectors;
+ HashSet<CSSParserSelector*> m_floatingSelectors;
HashSet<CSSParserValueList*> m_floatingValueLists;
HashSet<CSSParserFunction*> m_floatingFunctions;
@@ -310,7 +310,7 @@ namespace WebCore {
OwnPtr<MediaQueryExp> m_floatingMediaQueryExp;
OwnPtr<Vector<OwnPtr<MediaQueryExp> > > m_floatingMediaQueryExpList;
- Vector<CSSSelector*> m_reusableSelectorVector;
+ Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
// defines units allowed for a certain property, used in parseUnit
enum Units {
diff --git a/Source/WebCore/css/CSSParserValues.cpp b/Source/WebCore/css/CSSParserValues.cpp
index 06651f1..dc0e82b 100644
--- a/Source/WebCore/css/CSSParserValues.cpp
+++ b/Source/WebCore/css/CSSParserValues.cpp
@@ -20,11 +20,15 @@
#include "config.h"
#include "CSSParserValues.h"
+
#include "CSSPrimitiveValue.h"
#include "CSSFunctionValue.h"
#include "CSSQuirkPrimitiveValue.h"
+#include "CSSSelector.h"
namespace WebCore {
+
+using namespace WTF;
CSSParserValueList::~CSSParserValueList()
{
@@ -70,6 +74,27 @@ PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
parsedValue = CSSQuirkPrimitiveValue::create(fValue, CSSPrimitiveValue::CSS_EMS);
return parsedValue;
}
+
+CSSParserSelector::CSSParserSelector()
+ : m_selector(adoptPtr(fastNew<CSSSelector>()))
+{
+}
+
+CSSParserSelector::~CSSParserSelector()
+{
+ if (!m_tagHistory)
+ return;
+ Vector<CSSParserSelector*, 16> toDelete;
+ CSSParserSelector* selector = m_tagHistory.leakPtr();
+ while (true) {
+ toDelete.append(selector);
+ CSSParserSelector* next = selector->m_tagHistory.leakPtr();
+ if (!next)
+ break;
+ selector = next;
+ }
+ deleteAllValues(toDelete);
+}
}
diff --git a/Source/WebCore/css/CSSParserValues.h b/Source/WebCore/css/CSSParserValues.h
index 996e783..d084091 100644
--- a/Source/WebCore/css/CSSParserValues.h
+++ b/Source/WebCore/css/CSSParserValues.h
@@ -21,11 +21,13 @@
#ifndef CSSParserValues_h
#define CSSParserValues_h
+#include "CSSSelector.h"
#include <wtf/text/AtomicString.h>
namespace WebCore {
class CSSValue;
+class QualifiedName;
struct CSSParserString {
UChar* characters;
@@ -91,6 +93,35 @@ public:
OwnPtr<CSSParserValueList> args;
};
+class CSSParserSelector {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ CSSParserSelector();
+ ~CSSParserSelector();
+
+ PassOwnPtr<CSSSelector> releaseSelector() { return m_selector.release(); }
+
+ void setTag(const QualifiedName& value) { m_selector->setTag(value); }
+ void setValue(const AtomicString& value) { m_selector->setValue(value); }
+ void setAttribute(const QualifiedName& value) { m_selector->setAttribute(value); }
+ void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
+ void setSimpleSelector(PassOwnPtr<CSSSelector> value) { m_selector->setSimpleSelector(value); }
+ void setMatch(CSSSelector::Match value) { m_selector->m_match = value; }
+ void setRelation(CSSSelector::Relation value) { m_selector->m_relation = value; }
+ void setForPage() { m_selector->setForPage(); }
+
+ CSSSelector::PseudoType pseudoType() const { return m_selector->pseudoType(); }
+ bool isUnknownPseudoElement() const { return m_selector->isUnknownPseudoElement(); }
+ bool isSimple() const { return !m_tagHistory && m_selector->isSimple(); }
+
+ CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
+ void setTagHistory(PassOwnPtr<CSSParserSelector> selector) { m_tagHistory = selector; }
+
+private:
+ OwnPtr<CSSSelector> m_selector;
+ OwnPtr<CSSParserSelector> m_tagHistory;
+};
+
}
#endif
diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp
index ca3814a..8ff3859 100644
--- a/Source/WebCore/css/CSSSelector.cpp
+++ b/Source/WebCore/css/CSSSelector.cpp
@@ -36,38 +36,15 @@
namespace WebCore {
using namespace HTMLNames;
-
-class CSSSelectorBag {
- WTF_MAKE_NONCOPYABLE(CSSSelectorBag);
-public:
- CSSSelectorBag() { }
- ~CSSSelectorBag()
- {
- ASSERT(isEmpty());
- }
-
- bool isEmpty() const
- {
- return m_stack.isEmpty();
- }
-
- void add(PassOwnPtr<CSSSelector> selector)
- {
- if (selector)
- m_stack.append(selector.leakPtr());
- }
-
- PassOwnPtr<CSSSelector> takeAny()
- {
- ASSERT(!isEmpty());
- OwnPtr<CSSSelector> selector = adoptPtr(m_stack.last());
- m_stack.removeLast();
- return selector.release();
- }
-
-private:
- Vector<CSSSelector*, 16> m_stack;
-};
+
+void CSSSelector::createRareData()
+{
+ if (m_hasRareData)
+ return;
+ // Move the value to the rare data stucture.
+ m_data.m_rareData = new RareData(adoptRef(m_data.m_value));
+ m_hasRareData = true;
+}
unsigned CSSSelector::specificity() const
{
@@ -577,7 +554,7 @@ void CSSSelector::extractPseudoType() const
if (m_match != PseudoClass && m_match != PseudoElement && m_match != PagePseudoClass)
return;
- m_pseudoType = parsePseudoType(m_value);
+ m_pseudoType = parsePseudoType(value());
bool element = false; // pseudo-element
bool compat = false; // single colon compatbility mode
@@ -721,7 +698,7 @@ bool CSSSelector::operator==(const CSSSelector& other)
while (sel1 && sel2) {
if (sel1->m_tag != sel2->m_tag || sel1->attribute() != sel2->attribute() ||
sel1->relation() != sel2->relation() || sel1->m_match != sel2->m_match ||
- sel1->m_value != sel2->m_value ||
+ sel1->value() != sel2->value() ||
sel1->pseudoType() != sel2->pseudoType() ||
sel1->argument() != sel2->argument())
return false;
@@ -755,13 +732,13 @@ String CSSSelector::selectorText() const
while (true) {
if (cs->m_match == CSSSelector::Id) {
str += "#";
- serializeIdentifier(cs->m_value, str);
+ serializeIdentifier(cs->value(), str);
} else if (cs->m_match == CSSSelector::Class) {
str += ".";
- serializeIdentifier(cs->m_value, str);
+ serializeIdentifier(cs->value(), str);
} else if (cs->m_match == CSSSelector::PseudoClass || cs->m_match == CSSSelector::PagePseudoClass) {
str += ":";
- str += cs->m_value;
+ str += cs->value();
if (cs->pseudoType() == PseudoNot) {
if (CSSSelector* subSel = cs->simpleSelector())
str += subSel->selectorText();
@@ -776,7 +753,7 @@ String CSSSelector::selectorText() const
}
} else if (cs->m_match == CSSSelector::PseudoElement) {
str += "::";
- str += cs->m_value;
+ str += cs->value();
} else if (cs->hasAttribute()) {
str += "[";
const AtomicString& prefix = cs->attribute().prefix();
@@ -812,7 +789,7 @@ String CSSSelector::selectorText() const
break;
}
if (cs->m_match != CSSSelector::Set) {
- serializeString(cs->m_value, str);
+ serializeString(cs->value(), str);
str += "]";
}
}
@@ -836,14 +813,6 @@ String CSSSelector::selectorText() const
return str;
}
-
-void CSSSelector::setTagHistory(CSSSelector* tagHistory)
-{
- if (m_hasRareData)
- m_data.m_rareData->m_tagHistory.set(tagHistory);
- else
- m_data.m_tagHistory = tagHistory;
-}
const QualifiedName& CSSSelector::attribute() const
{
@@ -869,10 +838,10 @@ void CSSSelector::setArgument(const AtomicString& value)
m_data.m_rareData->m_argument = value;
}
-void CSSSelector::setSimpleSelector(CSSSelector* value)
+void CSSSelector::setSimpleSelector(PassOwnPtr<CSSSelector> value)
{
createRareData();
- m_data.m_rareData->m_simpleSelector.set(value);
+ m_data.m_rareData->m_simpleSelector = value;
}
bool CSSSelector::parseNth()
@@ -975,33 +944,4 @@ bool CSSSelector::RareData::matchNth(int count)
}
}
-inline void CSSSelector::releaseOwnedSelectorsToBag(CSSSelectorBag& bag)
-{
- if (m_hasRareData) {
- ASSERT(m_data.m_rareData);
- bag.add(m_data.m_rareData->m_tagHistory.release());
- bag.add(m_data.m_rareData->m_simpleSelector.release());
- delete m_data.m_rareData;
- // Clear the pointer so that a destructor of this selector will not
- // traverse this chain.
- m_data.m_rareData = 0;
- } else {
- bag.add(adoptPtr(m_data.m_tagHistory));
- // Clear the pointer for the same reason.
- m_data.m_tagHistory = 0;
- }
-}
-
-void CSSSelector::deleteReachableSelectors()
-{
- // Traverse the chain of selectors and delete each iteratively.
- CSSSelectorBag selectorsToBeDeleted;
- releaseOwnedSelectorsToBag(selectorsToBeDeleted);
- while (!selectorsToBeDeleted.isEmpty()) {
- OwnPtr<CSSSelector> selector(selectorsToBeDeleted.takeAny());
- ASSERT(selector);
- selector->releaseOwnedSelectorsToBag(selectorsToBeDeleted);
- }
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h
index b930353..66c94f3 100644
--- a/Source/WebCore/css/CSSSelector.h
+++ b/Source/WebCore/css/CSSSelector.h
@@ -30,8 +30,6 @@
namespace WebCore {
- class CSSSelectorBag;
-
// this class represents a selector for a StyleRule
class CSSSelector {
WTF_MAKE_NONCOPYABLE(CSSSelector); WTF_MAKE_FAST_ALLOCATED;
@@ -42,6 +40,7 @@ namespace WebCore {
, m_pseudoType(PseudoNotParsed)
, m_parsedNth(false)
, m_isLastInSelectorList(false)
+ , m_isLastInTagHistory(true)
, m_hasRareData(false)
, m_isForPage(false)
, m_tag(anyQName())
@@ -54,6 +53,7 @@ namespace WebCore {
, m_pseudoType(PseudoNotParsed)
, m_parsedNth(false)
, m_isLastInSelectorList(false)
+ , m_isLastInTagHistory(true)
, m_hasRareData(false)
, m_isForPage(false)
, m_tag(qName)
@@ -62,18 +62,10 @@ namespace WebCore {
~CSSSelector()
{
- // Exit if this selector does not own any objects to be deleted.
- if (m_hasRareData) {
- if (!m_data.m_rareData)
- return;
- } else if (!m_data.m_tagHistory)
- return;
-
- // We can not delete the owned object(s) by simply calling delete
- // directly on them. That would lead to recursive destructor calls
- // which might cause stack overflow. We have to delete them
- // iteratively.
- deleteReachableSelectors();
+ if (m_hasRareData)
+ delete m_data.m_rareData;
+ else if (m_data.m_value)
+ m_data.m_value->deref();
}
/**
@@ -255,29 +247,31 @@ namespace WebCore {
static PseudoType parsePseudoType(const AtomicString&);
static PseudoId pseudoId(PseudoType);
- CSSSelector* tagHistory() const { return m_hasRareData ? m_data.m_rareData->m_tagHistory.get() : m_data.m_tagHistory; }
- void setTagHistory(CSSSelector* tagHistory);
+ // Selectors are kept in an array by CSSSelectorList. The next component of the selector is
+ // the next item in the array.
+ CSSSelector* tagHistory() const { return m_isLastInTagHistory ? 0 : const_cast<CSSSelector*>(this + 1); }
bool hasTag() const { return m_tag != anyQName(); }
bool hasAttribute() const { return m_match == Id || m_match == Class || (m_hasRareData && m_data.m_rareData->m_attribute != anyQName()); }
+ const QualifiedName& tag() const { return m_tag; }
+ // AtomicString is really just an AtomicStringImpl* so the cast below is safe.
+ // FIXME: Perhaps call sites could be changed to accept AtomicStringImpl?
+ const AtomicString& value() const { return *reinterpret_cast<const AtomicString*>(m_hasRareData ? &m_data.m_rareData->m_value : &m_data.m_value); }
const QualifiedName& attribute() const;
const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; }
CSSSelector* simpleSelector() const { return m_hasRareData ? m_data.m_rareData->m_simpleSelector.get() : 0; }
- void setAttribute(const QualifiedName& value);
- void setArgument(const AtomicString& value);
- void setSimpleSelector(CSSSelector* value);
+ void setTag(const QualifiedName& value) { m_tag = value; }
+ void setValue(const AtomicString&);
+ void setAttribute(const QualifiedName&);
+ void setArgument(const AtomicString&);
+ void setSimpleSelector(PassOwnPtr<CSSSelector>);
bool parseNth();
bool matchNth(int count);
- bool matchesPseudoElement() const
- {
- if (m_pseudoType == PseudoUnknown)
- extractPseudoType();
- return m_match == PseudoElement;
- }
+ bool matchesPseudoElement() const;
bool isUnknownPseudoElement() const;
bool isSiblingSelector() const;
@@ -285,6 +279,9 @@ namespace WebCore {
bool isLastInSelectorList() const { return m_isLastInSelectorList; }
void setLastInSelectorList() { m_isLastInSelectorList = true; }
+ bool isLastInTagHistory() const { return m_isLastInTagHistory; }
+ void setNotLastInTagHistory() { m_isLastInTagHistory = false; }
+
bool isSimple() const;
bool isForPage() const { return m_isForPage; }
@@ -297,12 +294,10 @@ namespace WebCore {
private:
bool m_parsedNth : 1; // Used for :nth-*
bool m_isLastInSelectorList : 1;
+ bool m_isLastInTagHistory : 1;
bool m_hasRareData : 1;
bool m_isForPage : 1;
- void releaseOwnedSelectorsToBag(CSSSelectorBag&);
- void deleteReachableSelectors();
-
unsigned specificityForOneSelector() const;
unsigned specificityForPage() const;
void extractPseudoType() const;
@@ -310,44 +305,47 @@ namespace WebCore {
struct RareData {
WTF_MAKE_NONCOPYABLE(RareData); WTF_MAKE_FAST_ALLOCATED;
public:
- RareData(PassOwnPtr<CSSSelector> tagHistory)
- : m_a(0)
+ RareData(PassRefPtr<AtomicStringImpl> value)
+ : m_value(value.leakRef())
+ , m_a(0)
, m_b(0)
- , m_tagHistory(tagHistory)
, m_attribute(anyQName())
, m_argument(nullAtom)
{
}
+ ~RareData()
+ {
+ if (m_value)
+ m_value->deref();
+ }
bool parseNth();
bool matchNth(int count);
+ AtomicStringImpl* m_value; // Plain pointer to keep things uniform with the union.
int m_a; // Used for :nth-*
int m_b; // Used for :nth-*
- OwnPtr<CSSSelector> m_tagHistory;
OwnPtr<CSSSelector> m_simpleSelector; // Used for :not.
QualifiedName m_attribute; // used for attribute selector
AtomicString m_argument; // Used for :contains, :lang and :nth-*
};
-
- void createRareData()
- {
- if (m_hasRareData)
- return;
- m_data.m_rareData = new RareData(adoptPtr(m_data.m_tagHistory));
- m_hasRareData = true;
- }
+ void createRareData();
union DataUnion {
- DataUnion() : m_tagHistory(0) { }
- CSSSelector* m_tagHistory;
+ DataUnion() : m_value(0) { }
+ AtomicStringImpl* m_value;
RareData* m_rareData;
} m_data;
- public:
- mutable AtomicString m_value;
QualifiedName m_tag;
};
+
+inline bool CSSSelector::matchesPseudoElement() const
+{
+ if (m_pseudoType == PseudoUnknown)
+ extractPseudoType();
+ return m_match == PseudoElement;
+}
inline bool CSSSelector::isUnknownPseudoElement() const
{
@@ -371,6 +369,26 @@ inline bool CSSSelector::isSiblingSelector() const
|| type == PseudoNthLastChild
|| type == PseudoNthLastOfType;
}
+
+inline void CSSSelector::setValue(const AtomicString& value)
+{
+ // Need to do ref counting manually for the union.
+ if (m_hasRareData) {
+ m_data.m_rareData->m_value = value.impl();
+ m_data.m_rareData->m_value->ref();
+ return;
+ }
+ m_data.m_value = value.impl();
+ m_data.m_value->ref();
+}
+
+inline void move(PassOwnPtr<CSSSelector> from, CSSSelector* to)
+{
+ memcpy(to, from.get(), sizeof(CSSSelector));
+ // We want to free the memory (which was allocated with fastNew), but we
+ // don't want the destructor to run since it will affect the copy we've just made.
+ fastDeleteSkippingDestructor(from.leakPtr());
+}
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSSelectorList.cpp b/Source/WebCore/css/CSSSelectorList.cpp
index 7cb4df4..f4a8165 100644
--- a/Source/WebCore/css/CSSSelectorList.cpp
+++ b/Source/WebCore/css/CSSSelectorList.cpp
@@ -27,6 +27,8 @@
#include "config.h"
#include "CSSSelectorList.h"
+#include "CSSParserValues.h"
+
namespace WebCore {
CSSSelectorList::~CSSSelectorList()
@@ -41,26 +43,40 @@ void CSSSelectorList::adopt(CSSSelectorList& list)
list.m_selectorArray = 0;
}
-void CSSSelectorList::adoptSelectorVector(Vector<CSSSelector*>& selectorVector)
+void CSSSelectorList::adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector)
{
deleteSelectors();
- const size_t size = selectorVector.size();
- ASSERT(size);
- if (size == 1) {
- m_selectorArray = selectorVector[0];
+ const size_t vectorSize = selectorVector.size();
+ size_t flattenedSize = 0;
+ for (size_t i = 0; i < vectorSize; ++i) {
+ for (CSSParserSelector* selector = selectorVector[i].get(); selector; selector = selector->tagHistory())
+ ++flattenedSize;
+ }
+ ASSERT(flattenedSize);
+ if (flattenedSize == 1) {
+ m_selectorArray = selectorVector[0]->releaseSelector().leakPtr();
m_selectorArray->setLastInSelectorList();
+ ASSERT(m_selectorArray->isLastInTagHistory());
selectorVector.shrink(0);
return;
}
- m_selectorArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * selectorVector.size()));
- for (size_t i = 0; i < size; ++i) {
- memcpy(&m_selectorArray[i], selectorVector[i], sizeof(CSSSelector));
- // We want to free the memory (which was allocated with fastNew), but we
- // don't want the destructor to run since it will affect the copy we've just made.
- fastDeleteSkippingDestructor(selectorVector[i]);
- ASSERT(!m_selectorArray[i].isLastInSelectorList());
+ m_selectorArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * flattenedSize));
+ size_t arrayIndex = 0;
+ for (size_t i = 0; i < vectorSize; ++i) {
+ CSSParserSelector* current = selectorVector[i].get();
+ while (current) {
+ OwnPtr<CSSSelector> selector = current->releaseSelector();
+ current = current->tagHistory();
+ move(selector.release(), &m_selectorArray[arrayIndex]);
+ ASSERT(!m_selectorArray[arrayIndex].isLastInSelectorList());
+ if (current)
+ m_selectorArray[arrayIndex].setNotLastInTagHistory();
+ ++arrayIndex;
+ }
+ ASSERT(m_selectorArray[arrayIndex - 1].isLastInTagHistory());
}
- m_selectorArray[size - 1].setLastInSelectorList();
+ ASSERT(flattenedSize == arrayIndex);
+ m_selectorArray[arrayIndex - 1].setLastInSelectorList();
selectorVector.shrink(0);
}
@@ -122,7 +138,7 @@ class SelectorNeedsNamespaceResolutionFunctor {
public:
bool operator()(CSSSelector* selector)
{
- if (selector->hasTag() && selector->m_tag.prefix() != nullAtom && selector->m_tag.prefix() != starAtom)
+ if (selector->hasTag() && selector->tag().prefix() != nullAtom && selector->tag().prefix() != starAtom)
return true;
if (selector->hasAttribute() && selector->attribute().prefix() != nullAtom && selector->attribute().prefix() != starAtom)
return true;
diff --git a/Source/WebCore/css/CSSSelectorList.h b/Source/WebCore/css/CSSSelectorList.h
index abd9bc8..b3c4c03 100644
--- a/Source/WebCore/css/CSSSelectorList.h
+++ b/Source/WebCore/css/CSSSelectorList.h
@@ -30,6 +30,8 @@
namespace WebCore {
+class CSSParserSelector;
+
class CSSSelectorList {
WTF_MAKE_NONCOPYABLE(CSSSelectorList); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -37,11 +39,11 @@ public:
~CSSSelectorList();
void adopt(CSSSelectorList& list);
- void adoptSelectorVector(Vector<CSSSelector*>& selectorVector);
+ void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector);
CSSSelector* first() const { return m_selectorArray ? m_selectorArray : 0; }
- static CSSSelector* next(CSSSelector* previous) { return previous->isLastInSelectorList() ? 0 : previous + 1; }
- bool hasOneSelector() const { return m_selectorArray ? m_selectorArray->isLastInSelectorList() : false; }
+ static CSSSelector* next(CSSSelector*);
+ bool hasOneSelector() const { return m_selectorArray && !next(m_selectorArray); }
bool selectorsNeedNamespaceResolution();
bool hasUnknownPseudoElements() const;
@@ -49,10 +51,19 @@ public:
private:
void deleteSelectors();
+ // End of a multipart selector is indicated by m_isLastInTagHistory bit in the last item.
// End of the array is indicated by m_isLastInSelectorList bit in the last item.
CSSSelector* m_selectorArray;
};
+inline CSSSelector* CSSSelectorList::next(CSSSelector* current)
+{
+ // Skip subparts of combound selectors.
+ while (!current->isLastInTagHistory())
+ current++;
+ return current->isLastInSelectorList() ? 0 : current + 1;
+}
+
} // namespace WebCore
#endif // CSSSelectorList_h
diff --git a/Source/WebCore/css/CSSStyleRule.h b/Source/WebCore/css/CSSStyleRule.h
index 171b636..2d35043 100644
--- a/Source/WebCore/css/CSSStyleRule.h
+++ b/Source/WebCore/css/CSSStyleRule.h
@@ -50,7 +50,7 @@ public:
// Not part of the CSSOM
virtual bool parseString(const String&, bool = false);
- void adoptSelectorVector(Vector<CSSSelector*>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
+ void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
void setDeclaration(PassRefPtr<CSSMutableStyleDeclaration>);
const CSSSelectorList& selectorList() const { return m_selectorList; }
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index 54ae413..6536193 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -2217,20 +2217,20 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
return false;
if (sel->hasTag()) {
- const AtomicString& selLocalName = sel->m_tag.localName();
+ const AtomicString& selLocalName = sel->tag().localName();
if (selLocalName != starAtom && selLocalName != e->localName())
return false;
- const AtomicString& selNS = sel->m_tag.namespaceURI();
+ const AtomicString& selNS = sel->tag().namespaceURI();
if (selNS != starAtom && selNS != e->namespaceURI())
return false;
}
if (sel->hasAttribute()) {
if (sel->m_match == CSSSelector::Class)
- return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->m_value);
+ return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->value());
if (sel->m_match == CSSSelector::Id)
- return e->hasID() && e->idForStyleResolution() == sel->m_value;
+ return e->hasID() && e->idForStyleResolution() == sel->value();
const QualifiedName& attr = sel->attribute();
@@ -2249,22 +2249,22 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
switch (sel->m_match) {
case CSSSelector::Exact:
- if (caseSensitive ? sel->m_value != value : !equalIgnoringCase(sel->m_value, value))
+ if (caseSensitive ? sel->value() != value : !equalIgnoringCase(sel->value(), value))
return false;
break;
case CSSSelector::List:
{
// Ignore empty selectors or selectors containing spaces
- if (sel->m_value.contains(' ') || sel->m_value.isEmpty())
+ if (sel->value().contains(' ') || sel->value().isEmpty())
return false;
unsigned startSearchAt = 0;
while (true) {
- size_t foundPos = value.find(sel->m_value, startSearchAt, caseSensitive);
+ size_t foundPos = value.find(sel->value(), startSearchAt, caseSensitive);
if (foundPos == notFound)
return false;
if (foundPos == 0 || value[foundPos - 1] == ' ') {
- unsigned endStr = foundPos + sel->m_value.length();
+ unsigned endStr = foundPos + sel->value().length();
if (endStr == value.length() || value[endStr] == ' ')
break; // We found a match.
}
@@ -2275,24 +2275,24 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
break;
}
case CSSSelector::Contain:
- if (!value.contains(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
+ if (!value.contains(sel->value(), caseSensitive) || sel->value().isEmpty())
return false;
break;
case CSSSelector::Begin:
- if (!value.startsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
+ if (!value.startsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
return false;
break;
case CSSSelector::End:
- if (!value.endsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
+ if (!value.endsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
return false;
break;
case CSSSelector::Hyphen:
- if (value.length() < sel->m_value.length())
+ if (value.length() < sel->value().length())
return false;
- if (!value.startsWith(sel->m_value, caseSensitive))
+ if (!value.startsWith(sel->value(), caseSensitive))
return false;
// It they start the same, check for exact match or following '-':
- if (value.length() != sel->m_value.length() && value[sel->m_value.length()] != '-')
+ if (value.length() != sel->value().length() && value[sel->value().length()] != '-')
return false;
break;
case CSSSelector::PseudoClass:
@@ -2905,20 +2905,20 @@ void CSSRuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
void CSSRuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
{
if (sel->m_match == CSSSelector::Id) {
- addToRuleSet(sel->m_value.impl(), m_idRules, rule, sel);
+ addToRuleSet(sel->value().impl(), m_idRules, rule, sel);
return;
}
if (sel->m_match == CSSSelector::Class) {
- addToRuleSet(sel->m_value.impl(), m_classRules, rule, sel);
+ addToRuleSet(sel->value().impl(), m_classRules, rule, sel);
return;
}
if (sel->isUnknownPseudoElement()) {
- addToRuleSet(sel->m_value.impl(), m_pseudoRules, rule, sel);
+ addToRuleSet(sel->value().impl(), m_pseudoRules, rule, sel);
return;
}
- const AtomicString& localName = sel->m_tag.localName();
+ const AtomicString& localName = sel->tag().localName();
if (localName != starAtom) {
addToRuleSet(localName.impl(), m_tagRules, rule, sel);
return;
@@ -3006,12 +3006,12 @@ static void collectIdsAndSiblingRulesFromList(HashSet<AtomicStringImpl*>& ids, O
for (CSSRuleData* data = rules->first(); data; data = data->next()) {
bool foundSiblingSelector = false;
for (CSSSelector* selector = data->selector(); selector; selector = selector->tagHistory()) {
- if (selector->m_match == CSSSelector::Id && !selector->m_value.isEmpty())
- ids.add(selector->m_value.impl());
+ if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty())
+ ids.add(selector->value().impl());
if (CSSSelector* simpleSelector = selector->simpleSelector()) {
ASSERT(!simpleSelector->simpleSelector());
- if (simpleSelector->m_match == CSSSelector::Id && !simpleSelector->m_value.isEmpty())
- ids.add(simpleSelector->m_value.impl());
+ if (simpleSelector->m_match == CSSSelector::Id && !simpleSelector->value().isEmpty())
+ ids.add(simpleSelector->value().impl());
}
if (selector->isSiblingSelector())
foundSiblingSelector = true;
@@ -3136,7 +3136,7 @@ void CSSStyleSelector::matchPageRulesForList(CSSRuleDataList* rules, bool isLeft
for (CSSRuleData* d = rules->first(); d; d = d->next()) {
CSSStyleRule* rule = d->rule();
- const AtomicString& selectorLocalName = d->selector()->m_tag.localName();
+ const AtomicString& selectorLocalName = d->selector()->tag().localName();
if (selectorLocalName != starAtom && selectorLocalName != pageName)
continue;
CSSSelector::PseudoType pseudoType = d->selector()->pseudoType();
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index cd72662..fec2cff 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -1636,7 +1636,7 @@ PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode&
// FIXME: we could also optimize for the the [id="foo"] case
if (strictParsing && inDocument() && querySelectorList.hasOneSelector() && querySelectorList.first()->m_match == CSSSelector::Id) {
- Element* element = document()->getElementById(querySelectorList.first()->m_value);
+ Element* element = document()->getElementById(querySelectorList.first()->value());
if (element && (isDocumentNode() || element->isDescendantOf(this)) && selectorChecker.checkSelector(querySelectorList.first(), element))
return element;
return 0;
diff --git a/Source/WebCore/dom/SelectorNodeList.cpp b/Source/WebCore/dom/SelectorNodeList.cpp
index 039a29f..7611488 100644
--- a/Source/WebCore/dom/SelectorNodeList.cpp
+++ b/Source/WebCore/dom/SelectorNodeList.cpp
@@ -50,8 +50,8 @@ PassRefPtr<StaticNodeList> createSelectorNodeList(Node* rootNode, const CSSSelec
CSSStyleSelector::SelectorChecker selectorChecker(document, strictParsing);
- if (strictParsing && rootNode->inDocument() && onlySelector && onlySelector->m_match == CSSSelector::Id && !document->containsMultipleElementsWithId(onlySelector->m_value)) {
- Element* element = document->getElementById(onlySelector->m_value);
+ if (strictParsing && rootNode->inDocument() && onlySelector && onlySelector->m_match == CSSSelector::Id && !document->containsMultipleElementsWithId(onlySelector->value())) {
+ Element* element = document->getElementById(onlySelector->value());
if (element && (rootNode->isDocumentNode() || element->isDescendantOf(rootNode)) && selectorChecker.checkSelector(onlySelector, element))
nodes.append(element);
} else {
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list