[webkit-changes] cvs commit: WebCore/khtml/css css_base.cpp
css_base.h cssstyleselector.cpp
Timothy
thatcher at opensource.apple.com
Sun Oct 23 08:12:32 PDT 2005
thatcher 05/10/23 08:12:32
Modified: . ChangeLog
khtml/css css_base.cpp css_base.h cssstyleselector.cpp
Log:
Reviewed by Dave Hyatt.
http://bugzilla.opendarwin.org/show_bug.cgi?id=3442
Adds support for :first-of-type CSS3 pseudo-selectors
And builds foundations for :last-of-type and :only-of-type
* khtml/css/css_base.cpp:
(CSSSelector::extractPseudoType):
* khtml/css/css_base.h:
(DOM::CSSSelector::CSSSelector):
(DOM::CSSSelector::~CSSSelector):
(DOM::CSSSelector::):
(DOM::CSSSelector::pseudoType):
(DOM::StyleBaseImpl::StyleBaseImpl):
(DOM::StyleBaseImpl::~StyleBaseImpl):
(DOM::StyleBaseImpl::isStyleSheet):
(DOM::StyleBaseImpl::isCSSStyleSheet):
(DOM::StyleBaseImpl::isStyleSheetList):
(DOM::StyleBaseImpl::isMediaList):
(DOM::StyleBaseImpl::isRuleList):
(DOM::StyleBaseImpl::isRule):
(DOM::StyleBaseImpl::isStyleRule):
(DOM::StyleBaseImpl::isCharetRule):
(DOM::StyleBaseImpl::isImportRule):
(DOM::StyleBaseImpl::isMediaRule):
(DOM::StyleBaseImpl::isFontFaceRule):
(DOM::StyleBaseImpl::isPageRule):
(DOM::StyleBaseImpl::isUnknownRule):
(DOM::StyleBaseImpl::isStyleDeclaration):
(DOM::StyleBaseImpl::isValue):
(DOM::StyleBaseImpl::isPrimitiveValue):
(DOM::StyleBaseImpl::isValueList):
(DOM::StyleBaseImpl::isValueCustom):
(DOM::StyleBaseImpl::setParent):
(DOM::StyleBaseImpl::parseString):
(DOM::StyleBaseImpl::setStrictParsing):
(DOM::StyleBaseImpl::useStrictParsing):
(DOM::StyleListImpl::StyleListImpl):
(DOM::StyleListImpl::length):
(DOM::StyleListImpl::item):
(DOM::StyleListImpl::append):
* khtml/css/cssstyleselector.cpp:
(khtml::CSSStyleSelector::checkSelector):
(khtml::CSSStyleSelector::checkOneSelector):
Revision Changes Path
1.262 +47 -0 WebCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/WebCore/ChangeLog,v
retrieving revision 1.261
retrieving revision 1.262
diff -u -r1.261 -r1.262
--- ChangeLog 22 Oct 2005 18:19:21 -0000 1.261
+++ ChangeLog 23 Oct 2005 15:12:27 -0000 1.262
@@ -1,3 +1,50 @@
+2005-10-23 Nicholas Shanks <contact at nickshanks.com>
+
+ Reviewed by Dave Hyatt.
+
+ http://bugzilla.opendarwin.org/show_bug.cgi?id=3442
+ Adds support for :first-of-type CSS3 pseudo-selectors
+ And builds foundations for :last-of-type and :only-of-type
+
+ * khtml/css/css_base.cpp:
+ (CSSSelector::extractPseudoType):
+ * khtml/css/css_base.h:
+ (DOM::CSSSelector::CSSSelector):
+ (DOM::CSSSelector::~CSSSelector):
+ (DOM::CSSSelector::):
+ (DOM::CSSSelector::pseudoType):
+ (DOM::StyleBaseImpl::StyleBaseImpl):
+ (DOM::StyleBaseImpl::~StyleBaseImpl):
+ (DOM::StyleBaseImpl::isStyleSheet):
+ (DOM::StyleBaseImpl::isCSSStyleSheet):
+ (DOM::StyleBaseImpl::isStyleSheetList):
+ (DOM::StyleBaseImpl::isMediaList):
+ (DOM::StyleBaseImpl::isRuleList):
+ (DOM::StyleBaseImpl::isRule):
+ (DOM::StyleBaseImpl::isStyleRule):
+ (DOM::StyleBaseImpl::isCharetRule):
+ (DOM::StyleBaseImpl::isImportRule):
+ (DOM::StyleBaseImpl::isMediaRule):
+ (DOM::StyleBaseImpl::isFontFaceRule):
+ (DOM::StyleBaseImpl::isPageRule):
+ (DOM::StyleBaseImpl::isUnknownRule):
+ (DOM::StyleBaseImpl::isStyleDeclaration):
+ (DOM::StyleBaseImpl::isValue):
+ (DOM::StyleBaseImpl::isPrimitiveValue):
+ (DOM::StyleBaseImpl::isValueList):
+ (DOM::StyleBaseImpl::isValueCustom):
+ (DOM::StyleBaseImpl::setParent):
+ (DOM::StyleBaseImpl::parseString):
+ (DOM::StyleBaseImpl::setStrictParsing):
+ (DOM::StyleBaseImpl::useStrictParsing):
+ (DOM::StyleListImpl::StyleListImpl):
+ (DOM::StyleListImpl::length):
+ (DOM::StyleListImpl::item):
+ (DOM::StyleListImpl::append):
+ * khtml/css/cssstyleselector.cpp:
+ (khtml::CSSStyleSelector::checkSelector):
+ (khtml::CSSStyleSelector::checkOneSelector):
+
2005-10-21 David Hyatt <hyatt at apple.com>
Reviewed by darin
1.21 +10 -1 WebCore/khtml/css/css_base.cpp
Index: css_base.cpp
===================================================================
RCS file: /cvs/root/WebCore/khtml/css/css_base.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- css_base.cpp 3 Oct 2005 21:12:06 -0000 1.20
+++ css_base.cpp 23 Oct 2005 15:12:30 -0000 1.21
@@ -150,13 +150,16 @@
static AtomicString firstChild("first-child");
static AtomicString firstLetter("first-letter");
static AtomicString firstLine("first-line");
+ static AtomicString firstOfType("first-of-type");
static AtomicString focus("focus");
static AtomicString hover("hover");
static AtomicString link("link");
static AtomicString lang("lang(");
static AtomicString lastChild("last-child");
+ static AtomicString lastOfType("last-of-type");
static AtomicString notStr("not(");
static AtomicString onlyChild("only-child");
+ static AtomicString onlyOfType("only-of-type");
static AtomicString root("root");
static AtomicString selection("selection");
static AtomicString target("target");
@@ -193,7 +196,9 @@
} else if (value == firstLine) {
_pseudoType = PseudoFirstLine;
element = compat = true;
- } else if (value == focus)
+ } else if (value == firstOfType)
+ _pseudoType = PseudoFirstOfType;
+ else if (value == focus)
_pseudoType = PseudoFocus;
else if (value == hover)
_pseudoType = PseudoHover;
@@ -203,10 +208,14 @@
_pseudoType = PseudoLang;
else if (value == lastChild)
_pseudoType = PseudoLastChild;
+ else if (value == lastOfType)
+ _pseudoType = PseudoLastOfType;
else if (value == notStr)
_pseudoType = PseudoNot;
else if (value == onlyChild)
_pseudoType = PseudoOnlyChild;
+ else if (value == onlyOfType)
+ _pseudoType = PseudoOnlyOfType;
else if (value == root)
_pseudoType = PseudoRoot;
else if (value == selection) {
1.19 +115 -112 WebCore/khtml/css/css_base.h
Index: css_base.h
===================================================================
RCS file: /cvs/root/WebCore/khtml/css/css_base.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- css_base.h 3 Oct 2005 21:12:06 -0000 1.18
+++ css_base.h 23 Oct 2005 15:12:30 -0000 1.19
@@ -77,97 +77,100 @@
pseudoId( 0 ), _pseudoType(PseudoNotParsed)
{}
- CSSSelector(const QualifiedName& qName)
- : tagHistory(0), simpleSelector(0), nextSelector(0), attr(anyQName()), tag(qName),
+ CSSSelector(const QualifiedName& qName)
+ : tagHistory(0), simpleSelector(0), nextSelector(0), attr(anyQName()), tag(qName),
relation( Descendant ), match( None ),
pseudoId( 0 ), _pseudoType(PseudoNotParsed)
{}
- ~CSSSelector() {
- delete tagHistory;
+ ~CSSSelector() {
+ delete tagHistory;
delete simpleSelector;
delete nextSelector;
- }
+ }
void append(CSSSelector* n) {
if (!nextSelector) nextSelector = n; else nextSelector->append(n);
}
CSSSelector* next() { return nextSelector; }
- /**
- * Print debug output for this selector
- */
- void print();
-
- /**
- * Re-create selector text from selector's data
- */
- DOMString selectorText() const;
-
- // checks if the 2 selectors (including sub selectors) agree.
- bool operator == ( const CSSSelector &other );
-
- // tag == -1 means apply to all elements (Selector = *)
-
- unsigned int specificity();
-
- /* how the attribute value has to match.... Default is Exact */
- enum Match
- {
- None = 0,
- Id,
+ /**
+ * Print debug output for this selector
+ */
+ void print();
+
+ /**
+ * Re-create selector text from selector's data
+ */
+ DOMString selectorText() const;
+
+ // checks if the 2 selectors (including sub selectors) agree.
+ bool operator == ( const CSSSelector &other );
+
+ // tag == -1 means apply to all elements (Selector = *)
+
+ unsigned int specificity();
+
+ /* how the attribute value has to match.... Default is Exact */
+ enum Match
+ {
+ None = 0,
+ Id,
Class,
- Exact,
- Set,
- List,
- Hyphen,
- PseudoClass,
- PseudoElement,
- Contain, // css3: E[foo*="bar"]
- Begin, // css3: E[foo^="bar"]
- End // css3: E[foo$="bar"]
- };
-
- enum Relation
- {
- Descendant = 0,
- Child,
- DirectAdjacent,
+ Exact,
+ Set,
+ List,
+ Hyphen,
+ PseudoClass,
+ PseudoElement,
+ Contain, // css3: E[foo*="bar"]
+ Begin, // css3: E[foo^="bar"]
+ End // css3: E[foo$="bar"]
+ };
+
+ enum Relation
+ {
+ Descendant = 0,
+ Child,
+ DirectAdjacent,
IndirectAdjacent,
SubSelector
- };
+ };
- enum PseudoType
- {
- PseudoNotParsed = 0,
- PseudoOther,
- PseudoEmpty,
+ enum PseudoType
+ {
+ PseudoNotParsed = 0,
+ PseudoOther,
+ PseudoEmpty,
PseudoFirstChild,
+ PseudoFirstOfType,
PseudoLastChild,
+ PseudoLastOfType,
PseudoOnlyChild,
- PseudoFirstLine,
- PseudoFirstLetter,
- PseudoLink,
- PseudoVisited,
+ PseudoOnlyOfType,
+ PseudoFirstLine,
+ PseudoFirstLetter,
+ PseudoLink,
+ PseudoVisited,
PseudoAnyLink,
- PseudoHover,
- PseudoDrag,
- PseudoFocus,
- PseudoActive,
+ PseudoHover,
+ PseudoDrag,
+ PseudoFocus,
+ PseudoActive,
PseudoChecked,
PseudoEnabled,
PseudoDisabled,
PseudoTarget,
- PseudoBefore,
- PseudoAfter,
+ PseudoBefore,
+ PseudoAfter,
PseudoLang,
PseudoNot,
PseudoRoot,
PseudoSelection
- };
+ };
- inline PseudoType pseudoType() const
- {
+ inline PseudoType pseudoType() const
+ {
if (_pseudoType == PseudoNotParsed)
extractPseudoType();
return _pseudoType;
@@ -176,91 +179,91 @@
bool hasTag() const { return tag != anyQName(); }
bool hasAttribute() const { return attr != anyQName(); }
- mutable DOM::AtomicString value;
- CSSSelector* tagHistory;
+ mutable DOM::AtomicString value;
+ CSSSelector* tagHistory;
CSSSelector* simpleSelector; // Used for :not.
CSSSelector* nextSelector; // used for ,-chained selectors
-
+
QualifiedName attr;
QualifiedName tag;
Relation relation : 3;
- mutable Match match : 4;
- unsigned int pseudoId : 3;
- mutable PseudoType _pseudoType : 5;
+ mutable Match match : 4;
+ unsigned int pseudoId : 3;
+ mutable PseudoType _pseudoType : 5;
private:
- void extractPseudoType() const;
+ void extractPseudoType() const;
};
// a style class which has a parent (almost all have)
class StyleBaseImpl : public khtml::TreeShared<StyleBaseImpl>
{
public:
- StyleBaseImpl() { m_parent = 0; strictParsing = true; multiLength = false; }
- StyleBaseImpl(StyleBaseImpl *p) {
- m_parent = p;
- strictParsing = (m_parent ? m_parent->useStrictParsing() : true);
- multiLength = false;
- }
+ StyleBaseImpl() { m_parent = 0; strictParsing = true; multiLength = false; }
+ StyleBaseImpl(StyleBaseImpl *p) {
+ m_parent = p;
+ strictParsing = (m_parent ? m_parent->useStrictParsing() : true);
+ multiLength = false;
+ }
- virtual ~StyleBaseImpl() {}
+ virtual ~StyleBaseImpl() {}
- // returns the url of the style sheet this object belongs to
- DOMString baseURL();
+ // returns the url of the style sheet this object belongs to
+ DOMString baseURL();
- virtual bool isStyleSheet() const { return false; }
- virtual bool isCSSStyleSheet() const { return false; }
+ virtual bool isStyleSheet() const { return false; }
+ virtual bool isCSSStyleSheet() const { return false; }
virtual bool isXSLStyleSheet() const { return false; }
- virtual bool isStyleSheetList() const { return false; }
- virtual bool isMediaList() { return false; }
- virtual bool isRuleList() { return false; }
- virtual bool isRule() { return false; }
- virtual bool isStyleRule() { return false; }
- virtual bool isCharetRule() { return false; }
- virtual bool isImportRule() { return false; }
- virtual bool isMediaRule() { return false; }
- virtual bool isFontFaceRule() { return false; }
- virtual bool isPageRule() { return false; }
- virtual bool isUnknownRule() { return false; }
- virtual bool isStyleDeclaration() { return false; }
- virtual bool isValue() { return false; }
- virtual bool isPrimitiveValue() const { return false; }
- virtual bool isValueList() { return false; }
- virtual bool isValueCustom() { return false; }
-
- void setParent(StyleBaseImpl *parent) { m_parent = parent; }
+ virtual bool isStyleSheetList() const { return false; }
+ virtual bool isMediaList() { return false; }
+ virtual bool isRuleList() { return false; }
+ virtual bool isRule() { return false; }
+ virtual bool isStyleRule() { return false; }
+ virtual bool isCharetRule() { return false; }
+ virtual bool isImportRule() { return false; }
+ virtual bool isMediaRule() { return false; }
+ virtual bool isFontFaceRule() { return false; }
+ virtual bool isPageRule() { return false; }
+ virtual bool isUnknownRule() { return false; }
+ virtual bool isStyleDeclaration() { return false; }
+ virtual bool isValue() { return false; }
+ virtual bool isPrimitiveValue() const { return false; }
+ virtual bool isValueList() { return false; }
+ virtual bool isValueCustom() { return false; }
+
+ void setParent(StyleBaseImpl *parent) { m_parent = parent; }
- virtual bool parseString(const DOMString &/*cssString*/, bool = false) { return false; }
+ virtual bool parseString(const DOMString &/*cssString*/, bool = false) { return false; }
- virtual void checkLoaded();
+ virtual void checkLoaded();
- void setStrictParsing( bool b ) { strictParsing = b; }
- bool useStrictParsing() const { return strictParsing; }
+ void setStrictParsing( bool b ) { strictParsing = b; }
+ bool useStrictParsing() const { return strictParsing; }
- StyleSheetImpl* stylesheet();
+ StyleSheetImpl* stylesheet();
protected:
- bool strictParsing : 1;
- bool multiLength : 1;
+ bool strictParsing : 1;
+ bool multiLength : 1;
};
// a style class which has a list of children (StyleSheets for example)
class StyleListImpl : public StyleBaseImpl
{
public:
- StyleListImpl() : StyleBaseImpl() { m_lstChildren = 0; }
- StyleListImpl(StyleBaseImpl *parent) : StyleBaseImpl(parent) { m_lstChildren = 0; }
+ StyleListImpl() : StyleBaseImpl() { m_lstChildren = 0; }
+ StyleListImpl(StyleBaseImpl *parent) : StyleBaseImpl(parent) { m_lstChildren = 0; }
- virtual ~StyleListImpl();
+ virtual ~StyleListImpl();
- unsigned length() { return m_lstChildren->count(); }
- StyleBaseImpl *item(unsigned num) { return m_lstChildren->at(num); }
+ unsigned length() { return m_lstChildren->count(); }
+ StyleBaseImpl *item(unsigned num) { return m_lstChildren->at(num); }
- void append(StyleBaseImpl *item) { m_lstChildren->append(item); }
+ void append(StyleBaseImpl *item) { m_lstChildren->append(item); }
protected:
- QPtrList<StyleBaseImpl> *m_lstChildren;
+ QPtrList<StyleBaseImpl> *m_lstChildren;
};
int getPropertyID(const char *tagStr, int len);
1.213 +76 -29 WebCore/khtml/css/cssstyleselector.cpp
Index: cssstyleselector.cpp
===================================================================
RCS file: /cvs/root/WebCore/khtml/css/cssstyleselector.cpp,v
retrieving revision 1.212
retrieving revision 1.213
diff -u -r1.212 -r1.213
--- cssstyleselector.cpp 22 Oct 2005 18:19:24 -0000 1.212
+++ cssstyleselector.cpp 23 Oct 2005 15:12:31 -0000 1.213
@@ -1048,7 +1048,7 @@
bool found = false;
while(!found)
{
- n = n->parentNode();
+ n = n->parentNode();
if(!n || !n->isElementNode()) return false;
ElementImpl *elem = static_cast<ElementImpl *>(n);
if (checkOneSelector(sel, elem)) found = true;
@@ -1091,7 +1091,7 @@
break;
}
case CSSSelector::SubSelector:
- {
+ {
if (onlyHoverActive)
onlyHoverActive = (sel->match == CSSSelector::PseudoClass &&
(sel->pseudoType() == CSSSelector::PseudoHover ||
@@ -1105,7 +1105,7 @@
if (!checkOneSelector(sel, elem)) return false;
//kdDebug() << "CSSOrderedRule::checkSelector: passed" << endl;
break;
- }
+ }
}
relation = sel->relation;
}
@@ -1259,46 +1259,93 @@
{
// Pseudo elements. We need to check first child here. No dynamic pseudo
// elements for the moment
-// kdDebug() << "CSSOrderedRule::pseudo " << value << endl;
- switch (sel->pseudoType()) {
- // Pseudo classes:
+// kdDebug() << "CSSOrderedRule::pseudo " << value << endl;
+ switch (sel->pseudoType()) {
+ // Pseudo classes:
case CSSSelector::PseudoEmpty:
if (!e->firstChild())
return true;
break;
case CSSSelector::PseudoFirstChild: {
// first-child matches the first child that is an element!
- if (e->parentNode()) {
- NodeImpl* n = e->previousSibling();
- while ( n && !n->isElementNode() )
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ NodeImpl *n = e->previousSibling();
+ while (n && !n->isElementNode())
n = n->previousSibling();
- if ( !n )
+ if (!n)
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoFirstOfType: {
+ // first-of-type matches the first element of its type!
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ const QualifiedName& type = e->tagName();
+ NodeImpl *n = e->previousSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<ElementImpl*>(n)->hasTagName(type))
+ break;
+ n = n->previousSibling();
+ }
+ if (!n)
return true;
}
break;
}
case CSSSelector::PseudoLastChild: {
// last-child matches the last child that is an element!
- if (e->parentNode()) {
- NodeImpl* n = e->nextSibling();
- while ( n && !n->isElementNode() )
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ NodeImpl *n = e->nextSibling();
+ while (n && !n->isElementNode())
n = n->nextSibling();
- if ( !n )
+ if (!n)
+ return true;
+ }
+ break;
+ }
+ case CSSSelector::PseudoLastOfType: {
+ // last-of-type matches the last element of its type!
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ const QualifiedName& type = e->tagName();
+ NodeImpl *n = e->nextSibling();
+ while (n) {
+ if (n->isElementNode() && static_cast<ElementImpl*>(n)->hasTagName(type))
+ break;
+ n = n->nextSibling();
+ }
+ if (!n)
return true;
}
break;
}
case CSSSelector::PseudoOnlyChild: {
// If both first-child and last-child apply, then only-child applies.
- if (e->parentNode()) {
- NodeImpl* n = e->previousSibling();
- while ( n && !n->isElementNode() )
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ NodeImpl *n = e->previousSibling();
+ while (n && !n->isElementNode())
+ n = n->previousSibling();
+ if (!n) {
+ n = e->nextSibling();
+ while (n && !n->isElementNode())
+ n = n->nextSibling();
+ if (!n)
+ return true;
+ }
+ }
+ break;
+ }
+ case CSSSelector::PseudoOnlyOfType: {
+ // If both first-of-type and last-of-type apply, then only-of-type applies.
+ if (e->parentNode() && e->parentNode()->isElementNode()) {
+ const QualifiedName& type = e->tagName();
+ NodeImpl *n = e->previousSibling();
+ while (n && !static_cast<ElementImpl*>(n)->hasTagName(type))
n = n->previousSibling();
- if ( !n ) {
+ if (!n) {
n = e->nextSibling();
- while ( n && !n->isElementNode() )
+ while (n && !static_cast<ElementImpl*>(n)->hasTagName(type))
n = n->nextSibling();
- if ( !n )
+ if (!n)
return true;
}
}
@@ -1315,15 +1362,15 @@
return true;
break;
case CSSSelector::PseudoLink:
- if ( pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink )
- checkPseudoState( e );
- if ( pseudoState == PseudoLink )
+ if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
+ checkPseudoState(e);
+ if (pseudoState == PseudoLink)
return true;
break;
case CSSSelector::PseudoVisited:
- if ( pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink )
- checkPseudoState( e );
- if ( pseudoState == PseudoVisited )
+ if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
+ checkPseudoState(e);
+ if (pseudoState == PseudoVisited)
return true;
break;
case CSSSelector::PseudoHover: {
@@ -1411,13 +1458,13 @@
// Pseudo-elements:
case CSSSelector::PseudoFirstLine:
- if ( subject ) {
+ if (subject) {
dynamicPseudo=RenderStyle::FIRST_LINE;
return true;
}
break;
case CSSSelector::PseudoFirstLetter:
- if ( subject ) {
+ if (subject) {
dynamicPseudo=RenderStyle::FIRST_LETTER;
return true;
}
@@ -1436,7 +1483,7 @@
assert(false);
break;
}
- return false;
+ return false;
}
// ### add the rest of the checks...
return true;
More information about the webkit-changes
mailing list