Rule matching
David Hyatt
hyatt at apple.com
Thu Feb 5 02:44:48 CET 2004
This patch rewrites rule matching in the style system for a fairly
significant 4-5% perf gain (much more on large CSS pages like the CSS
pencils page).
This code is new and likely to cause a regression or two, so you may
want to hold off merging if you're worried about stability at the
moment.
dave
-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/ChangeLog,v
retrieving revision 1.2495
diff -u -p -r1.2495 ChangeLog
--- ChangeLog 2004/02/04 22:22:13 1.2495
+++ ChangeLog 2004/02/05 01:40:11
@@ -1,5 +1,180 @@
2004-02-04 David Hyatt <hyatt at apple.com>
+ Improve rule matching in the style system. Filter out most rules up front, so that only a small
+ number of rules need to be walked for any given element. Yields a ~4-5% improvement on the PLT.
+
+ Reviewed by kocienda
+
+ * khtml/css/css_base.cpp:
+ (StyleBaseImpl::setParsedValue):
+ (CSSSelector::specificity):
+ (CSSSelector::extractPseudoType):
+ (CSSSelector::operator == ):
+ * khtml/css/css_base.h:
+ (DOM::CSSSelector::CSSSelector):
+ (DOM::CSSSelector::~CSSSelector):
+ (DOM::CSSSelector::append):
+ (DOM::CSSSelector::next):
+ (DOM::CSSSelector::):
+ (DOM::StyleBaseImpl::StyleBaseImpl):
+ * khtml/css/css_ruleimpl.cpp:
+ (CSSStyleRuleImpl::selectorText):
+ (CSSRuleListImpl::insertRule):
+ * khtml/css/css_ruleimpl.h:
+ (DOM::CSSStyleRuleImpl::setSelector):
+ (DOM::CSSStyleRuleImpl::selector):
+ * khtml/css/css_stylesheetimpl.cpp:
+ * khtml/css/css_stylesheetimpl.h:
+ * khtml/css/css_valueimpl.cpp:
+ (CSSStyleDeclarationImpl::getPropertyCSSValue):
+ (CSSStyleDeclarationImpl::removeProperty):
+ (CSSStyleDeclarationImpl::setProperty):
+ (CSSStyleDeclarationImpl::setStringProperty):
+ (CSSStyleDeclarationImpl::setImageProperty):
+ (CSSStyleDeclarationImpl::setLengthProperty):
+ (CSSStyleDeclarationImpl::cssText):
+ (CSSStyleDeclarationImpl::setCssText):
+ * khtml/css/css_valueimpl.h:
+ (DOM::CSSStyleDeclarationImpl::node):
+ (DOM::CSSProperty::CSSProperty):
+ (DOM::CSSProperty::id):
+ (DOM::CSSProperty::isImportant):
+ * khtml/css/cssparser.cpp:
+ (CSSParser::CSSParser):
+ (ParseString::lower):
+ (CSSParser::parseValue):
+ (CSSParser::parseDeclaration):
+ (CSSParser::addProperty):
+ (CSSParser::parseShadow):
+ * khtml/css/cssparser.h:
+ * khtml/css/cssstyleselector.cpp:
+ (khtml::):
+ (khtml::CSSStyleSelector::CSSStyleSelector):
+ (khtml::CSSStyleSelector::init):
+ (khtml::CSSStyleSelector::~CSSStyleSelector):
+ (khtml::CSSStyleSelector::loadDefaultStyle):
+ (khtml::CSSStyleSelector::addMatchedRule):
+ (khtml::CSSStyleSelector::addMatchedDeclaration):
+ (khtml::CSSStyleSelector::matchRules):
+ (khtml::CSSStyleSelector::matchRulesForList):
+ (khtml::operator >):
+ (khtml::operator <=):
+ (khtml::CSSStyleSelector::sortMatchedRules):
+ (khtml::CSSStyleSelector::initForStyleResolve):
+ (khtml::CSSStyleSelector::styleForElement):
+ (khtml::CSSStyleSelector::pseudoStyleForElement):
+ (khtml::checkPseudoState):
+ (khtml::CSSStyleSelector::checkSelector):
+ (khtml::CSSStyleSelector::checkOneSelector):
+ (khtml::CSSRuleSet::CSSRuleSet):
+ (khtml::CSSRuleSet::addToRuleSet):
+ (khtml::CSSRuleSet::addRule):
+ (khtml::CSSRuleSet::addRulesFromSheet):
+ (khtml::CSSStyleSelector::applyDeclarations):
+ (khtml::CSSStyleSelector::applyProperty):
+ (khtml::CSSStyleSelector::smallerFontSize):
+ (khtml::CSSStyleSelector::getColorFromPrimitiveValue):
+ * khtml/css/cssstyleselector.h:
+ (khtml::):
+ (khtml::CSSRuleData::m_next):
+ (khtml::CSSRuleData::~CSSRuleData):
+ (khtml::CSSRuleData::position):
+ (khtml::CSSRuleData::rule):
+ (khtml::CSSRuleData::selector):
+ (khtml::CSSRuleData::next):
+ (khtml::CSSRuleDataList::CSSRuleDataList):
+ (khtml::CSSRuleDataList::~CSSRuleDataList):
+ (khtml::CSSRuleDataList::first):
+ (khtml::CSSRuleDataList::last):
+ (khtml::CSSRuleDataList::append):
+ (khtml::CSSRuleSet::~CSSRuleSet):
+ (khtml::CSSRuleSet::getIDRules):
+ (khtml::CSSRuleSet::getClassRules):
+ (khtml::CSSRuleSet::getTagRules):
+ (khtml::CSSRuleSet::getUniversalRules):
+ * khtml/css/cssvalues.c:
+ (hash_val):
+ (findValue):
+ * khtml/css/cssvalues.h:
+ * khtml/css/cssvalues.in:
+ * khtml/css/html4.css:
+ * khtml/css/parser.cpp:
+ * khtml/css/parser.h:
+ * khtml/css/parser.y:
+ * khtml/dom/dom_element.cpp:
+ (Element::style):
+ * khtml/html/html_baseimpl.cpp:
+ (HTMLBodyElementImpl::HTMLBodyElementImpl):
+ (HTMLBodyElementImpl::~HTMLBodyElementImpl):
+ (HTMLBodyElementImpl::createLinkDecl):
+ (HTMLBodyElementImpl::parseAttribute):
+ * khtml/html/html_baseimpl.h:
+ * khtml/html/html_elementimpl.cpp:
+ (HTMLNamedAttrMapImpl::parseClassAttribute):
+ (HTMLElementImpl::HTMLElementImpl):
+ (HTMLElementImpl::~HTMLElementImpl):
+ (HTMLElementImpl::createInlineStyleDecl):
+ (HTMLElementImpl::createMappedAttributeDecl):
+ (HTMLElementImpl::parseAttribute):
+ (HTMLElementImpl::getClassList):
+ (HTMLElementImpl::addCSSProperty):
+ (HTMLElementImpl::addCSSStringProperty):
+ (HTMLElementImpl::addCSSImageProperty):
+ (HTMLElementImpl::addCSSLength):
+ (HTMLElementImpl::addHTMLColor):
+ (HTMLElementImpl::removeCSSProperty):
+ * khtml/html/html_elementimpl.h:
+ (DOM::HTMLNamedAttrMapImpl::getClassList):
+ (DOM::HTMLElementImpl::inlineStyleDecl):
+ (DOM::HTMLElementImpl::attributeStyleDecl):
+ (DOM::HTMLElementImpl::getInlineStyleDecl):
+ * khtml/html/html_tableimpl.cpp:
+ (HTMLTableElementImpl::createSharedCellDecls):
+ (HTMLTableCellElementImpl::additionalAttributeStyleDecl):
+ * khtml/html/html_tableimpl.h:
+ * khtml/xml/dom_atomicstring.cpp:
+ (DOM::AtomicString::add):
+ (DOM::AtomicString::remove):
+ * khtml/xml/dom_docimpl.cpp:
+ (DocumentImpl::DocumentImpl):
+ (DocumentImpl::resetLinkColor):
+ (DocumentImpl::resetVisitedLinkColor):
+ (DocumentImpl::resetActiveLinkColor):
+ (DocumentImpl::recalcStyleSelector):
+ * khtml/xml/dom_docimpl.h:
+ (DOM::DocumentImpl::linkColor):
+ (DOM::DocumentImpl::visitedLinkColor):
+ (DOM::DocumentImpl::activeLinkColor):
+ (DOM::DocumentImpl::setLinkColor):
+ (DOM::DocumentImpl::setVisitedLinkColor):
+ (DOM::DocumentImpl::setActiveLinkColor):
+ * khtml/xml/dom_elementimpl.cpp:
+ (ElementImpl::ElementImpl):
+ (ElementImpl::~ElementImpl):
+ (ElementImpl::getClassList):
+ (ElementImpl::getIDAttribute):
+ (ElementImpl::cloneNode):
+ (XMLElementImpl::cloneNode):
+ * khtml/xml/dom_elementimpl.h:
+ (DOM::ElementImpl::inlineStyleDecl):
+ (DOM::ElementImpl::attributeStyleDecl):
+ (DOM::ElementImpl::getInlineStyleDecl):
+ (DOM::ElementImpl::additionalAttributeStyleDecl):
+ (DOM::NamedAttrMapImpl::id):
+ (DOM::NamedAttrMapImpl::setID):
+ * khtml/xml/dom_stringimpl.cpp:
+ (DOM::DOMStringImpl::DOMStringImpl):
+ (DOM::DOMStringImpl::~DOMStringImpl):
+ (DOM::DOMStringImpl::append):
+ (DOM::DOMStringImpl::insert):
+ (DOM::DOMStringImpl::truncate):
+ (DOM::DOMStringImpl::remove):
+ (DOM::DOMStringImpl::split):
+ * khtml/xml/dom_stringimpl.h:
+ (DOM::DOMStringImpl::DOMStringImpl):
+
+2004-02-04 David Hyatt <hyatt at apple.com>
+
Fix line-height regression on altavista.
* khtml/rendering/render_br.cpp:
Index: khtml/css/css_base.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_base.cpp,v
retrieving revision 1.7
diff -u -p -r1.7 khtml/css/css_base.cpp
--- khtml/css/css_base.cpp 2004/01/30 07:44:44 1.7
+++ khtml/css/css_base.cpp 2004/02/05 01:40:11
@@ -76,12 +76,12 @@ DOMString StyleBaseImpl::baseURL()
}
void StyleBaseImpl::setParsedValue(int propId, const CSSValueImpl *parsedValue,
- bool important, bool nonCSSHint, QPtrList<CSSProperty> *propList)
+ bool important, QPtrList<CSSProperty> *propList)
{
QPtrListIterator<CSSProperty> propIt(*propList);
propIt.toLast(); // just remove the top one - not sure what should happen if we have multiple instances of the property
while (propIt.current() &&
- ( propIt.current()->m_id != propId || propIt.current()->nonCSSHint != nonCSSHint ||
+ ( propIt.current()->m_id != propId ||
propIt.current()->m_bImportant != important) )
--propIt;
if (propIt.current())
@@ -91,8 +91,7 @@ void StyleBaseImpl::setParsedValue(int p
prop->m_id = propId;
prop->setValue((CSSValueImpl *) parsedValue);
prop->m_bImportant = important;
- prop->nonCSSHint = nonCSSHint;
-
+
propList->append(prop);
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "added property: " << getPropertyName(propId).string()
@@ -132,9 +131,8 @@ void CSSSelector::print(void)
unsigned int CSSSelector::specificity()
{
- if ( nonCSSHint )
- return 0;
-
+ // FIXME: Pseudo-elements and pseudo-classes do not have the same specificity. This function
+ // isn't quite correct.
int s = ((localNamePart(tag) == anyLocalName) ? 0 : 1);
switch(match)
{
@@ -167,6 +165,7 @@ void CSSSelector::extractPseudoType() co
static AtomicString active("active");
static AtomicString after("after");
+ static AtomicString anyLink("-khtml-any-link");
static AtomicString before("before");
static AtomicString empty("empty");
static AtomicString firstChild("first-child");
@@ -189,6 +188,8 @@ void CSSSelector::extractPseudoType() co
_pseudoType = PseudoActive;
else if (value == after)
_pseudoType = PseudoAfter;
+ else if (value == anyLink)
+ _pseudoType = PseudoAnyLink;
else if (value == before)
_pseudoType = PseudoBefore;
else if (value == empty)
@@ -234,7 +235,6 @@ bool CSSSelector::operator == ( const CS
while ( sel1 && sel2 ) {
if ( sel1->tag != sel2->tag || sel1->attr != sel2->attr ||
sel1->relation != sel2->relation || sel1->match != sel2->match ||
- sel1->nonCSSHint != sel2->nonCSSHint ||
sel1->value != sel2->value ||
sel1->pseudoType() != sel2->pseudoType())
return false;
Index: khtml/css/css_base.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_base.h,v
retrieving revision 1.4
diff -u -p -r1.4 khtml/css/css_base.h
--- khtml/css/css_base.h 2004/01/27 19:08:33 1.4
+++ khtml/css/css_base.h 2004/02/05 01:40:11
@@ -73,16 +73,22 @@ namespace DOM {
{
public:
CSSSelector()
- : tagHistory(0), simpleSelector(0), attr(0), tag(anyQName),
- relation( Descendant ), match( None ), nonCSSHint( false ),
+ : tagHistory(0), simpleSelector(0), nextSelector(0), attr(0), tag(anyQName),
+ relation( Descendant ), match( None ),
pseudoId( 0 ), _pseudoType(PseudoNotParsed)
{}
~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
*/
@@ -136,6 +142,7 @@ namespace DOM {
PseudoFirstLetter,
PseudoLink,
PseudoVisited,
+ PseudoAnyLink,
PseudoHover,
PseudoFocus,
PseudoActive,
@@ -156,14 +163,14 @@ namespace DOM {
}
mutable DOM::AtomicString value;
- CSSSelector *tagHistory;
+ CSSSelector* tagHistory;
CSSSelector* simpleSelector; // Used for :not.
+ CSSSelector* nextSelector; // used for ,-chained selectors
Q_UINT32 attr;
Q_UINT32 tag;
Relation relation : 2;
Match match : 4;
- bool nonCSSHint : 1;
unsigned int pseudoId : 3;
mutable PseudoType _pseudoType : 5;
@@ -175,9 +182,9 @@ namespace DOM {
class StyleBaseImpl : public khtml::TreeShared<StyleBaseImpl>
{
public:
- StyleBaseImpl() { m_parent = 0; hasInlinedDecl = false; strictParsing = true; multiLength = false; }
+ StyleBaseImpl() { m_parent = 0; strictParsing = true; multiLength = false; }
StyleBaseImpl(StyleBaseImpl *p) {
- m_parent = p; hasInlinedDecl = false;
+ m_parent = p;
strictParsing = (m_parent ? m_parent->useStrictParsing() : true);
multiLength = false;
}
@@ -209,7 +216,7 @@ namespace DOM {
void setParent(StyleBaseImpl *parent) { m_parent = parent; }
static void setParsedValue(int propId, const CSSValueImpl *parsedValue,
- bool important, bool nonCSSHint, QPtrList<CSSProperty> *propList);
+ bool important, QPtrList<CSSProperty> *propList);
virtual bool parseString(const DOMString &/*cssString*/, bool = false) { return false; }
@@ -221,7 +228,6 @@ namespace DOM {
StyleSheetImpl* stylesheet();
protected:
- bool hasInlinedDecl : 1;
bool strictParsing : 1;
bool multiLength : 1;
};
Index: khtml/css/css_ruleimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_ruleimpl.cpp,v
retrieving revision 1.13
diff -u -p -r1.13 khtml/css/css_ruleimpl.cpp
--- khtml/css/css_ruleimpl.cpp 2003/08/29 22:04:02 1.13
+++ khtml/css/css_ruleimpl.cpp 2004/02/05 01:40:11
@@ -320,12 +320,9 @@ CSSStyleRuleImpl::~CSSStyleRuleImpl()
DOM::DOMString CSSStyleRuleImpl::selectorText() const
{
- if ( m_selector && m_selector->first() ) {
- // ### m_selector will be a single selector hopefully. so ->first() will disappear
- CSSSelector* cs = m_selector->first();
- //cs->print(); // debug
- return cs->selectorText();
- }
+ // FIXME: Handle all the selectors in the chain for comma-separated selectors.
+ if (m_selector)
+ return m_selector->selectorText();
return DOMString();
}
@@ -349,15 +346,6 @@ void CSSStyleRuleImpl::setDeclaration( C
}
}
-void CSSStyleRuleImpl::setNonCSSHints()
-{
- CSSSelector *s = m_selector->first();
- while ( s ) {
- s->nonCSSHint = true;
- s = m_selector->next();
- }
-}
-
void CSSRuleListImpl::deleteRule ( unsigned long index )
{
CSSRuleImpl *rule = m_lstCSSRules.take( index );
@@ -384,4 +372,3 @@ unsigned long CSSRuleListImpl::insertRul
// ### Should throw INDEX_SIZE_ERR exception instead! (TODO)
return 0;
}
-
Index: khtml/css/css_ruleimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_ruleimpl.h,v
retrieving revision 1.9
diff -u -p -r1.9 khtml/css/css_ruleimpl.h
--- khtml/css/css_ruleimpl.h 2003/08/29 22:04:02 1.9
+++ khtml/css/css_ruleimpl.h 2004/02/05 01:40:11
@@ -30,6 +30,7 @@
#include "css/css_base.h"
#include "misc/loader_client.h"
#include "misc/shared.h"
+#include "css_valueimpl.h"
namespace khtml {
class CachedCSSStyleSheet;
@@ -191,6 +192,7 @@ protected:
CSSStyleDeclarationImpl *m_style;
};
+class CSSImportantRuleImpl;
class CSSStyleRuleImpl : public CSSRuleImpl
{
@@ -208,19 +210,16 @@ public:
virtual bool parseString( const DOMString &string, bool = false );
- void setSelector( QPtrList<CSSSelector> *selector) { m_selector = selector; }
+ void setSelector(CSSSelector* selector) { m_selector = selector; }
void setDeclaration( CSSStyleDeclarationImpl *style);
- QPtrList<CSSSelector> *selector() { return m_selector; }
+ CSSSelector* selector() { return m_selector; }
CSSStyleDeclarationImpl *declaration() { return m_style; }
-
- void setNonCSSHints();
-
+
protected:
CSSStyleDeclarationImpl *m_style;
- QPtrList<CSSSelector> *m_selector;
+ CSSSelector* m_selector;
};
-
class CSSUnknownRuleImpl : public CSSRuleImpl
{
Index: khtml/css/css_stylesheetimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_stylesheetimpl.cpp,v
retrieving revision 1.8
diff -u -p -r1.8 khtml/css/css_stylesheetimpl.cpp
--- khtml/css/css_stylesheetimpl.cpp 2004/01/26 22:33:18 1.8
+++ khtml/css/css_stylesheetimpl.cpp 2004/02/05 01:40:11
@@ -276,17 +276,6 @@ void CSSStyleSheetImpl::checkLoaded()
if(m_parentNode) m_parentNode->sheetLoaded();
}
-void CSSStyleSheetImpl::setNonCSSHints()
-{
- StyleBaseImpl *rule = m_lstChildren->first();
- while(rule) {
- if(rule->isStyleRule()) {
- static_cast<CSSStyleRuleImpl *>(rule)->setNonCSSHints();
- }
- rule = m_lstChildren->next();
- }
-}
-
khtml::DocLoader *CSSStyleSheetImpl::docLoader()
{
if ( !m_doc ) // doc is 0 for the user- and default-sheet!
Index: khtml/css/css_stylesheetimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_stylesheetimpl.h,v
retrieving revision 1.7
diff -u -p -r1.7 khtml/css/css_stylesheetimpl.h
--- khtml/css/css_stylesheetimpl.h 2004/01/26 22:33:18 1.7
+++ khtml/css/css_stylesheetimpl.h 2004/02/05 01:40:11
@@ -106,7 +106,6 @@ public:
virtual bool parseString( const DOMString &string, bool strict = true );
bool isLoading();
- void setNonCSSHints();
virtual void checkLoaded();
khtml::DocLoader *docLoader();
Index: khtml/css/css_valueimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_valueimpl.cpp,v
retrieving revision 1.31
diff -u -p -r1.31 khtml/css/css_valueimpl.cpp
--- khtml/css/css_valueimpl.cpp 2004/01/30 07:44:44 1.31
+++ khtml/css/css_valueimpl.cpp 2004/02/05 01:40:11
@@ -227,12 +227,12 @@ DOMString CSSStyleDeclarationImpl::getSh
QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
CSSProperty *current;
for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt )
- if (current->m_id == propertyID && !current->nonCSSHint)
+ if (current->m_id == propertyID)
return current->value();
return 0;
}
-DOMString CSSStyleDeclarationImpl::removeProperty( int propertyID, bool NonCSSHint )
+DOMString CSSStyleDeclarationImpl::removeProperty(int propertyID, bool notifyChanged)
{
if(!m_lstValues) return DOMString();
DOMString value;
@@ -240,10 +240,11 @@ DOMString CSSStyleDeclarationImpl::remov
QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
CSSProperty *current;
for ( lstValuesIt.toLast(); (current = lstValuesIt.current()); --lstValuesIt )
- if (current->m_id == propertyID && NonCSSHint == current->nonCSSHint) {
+ if (current->m_id == propertyID) {
value = current->value()->cssText();
m_lstValues->removeRef(current);
- setChanged();
+ if (notifyChanged)
+ setChanged();
break;
}
@@ -278,56 +279,57 @@ bool CSSStyleDeclarationImpl::getPropert
return false;
}
-bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool nonCSSHint)
+bool CSSStyleDeclarationImpl::setProperty(int id, const DOMString &value, bool important, bool notifyChanged)
{
if(!m_lstValues) {
m_lstValues = new QPtrList<CSSProperty>;
m_lstValues->setAutoDelete(true);
}
- removeProperty(id, nonCSSHint );
+ removeProperty(id);
CSSParser parser( strictParsing );
- bool success = parser.parseValue( this, id, value, important, nonCSSHint );
+ bool success = parser.parseValue(this, id, value, important);
if(!success)
kdDebug( 6080 ) << "CSSStyleDeclarationImpl::setProperty invalid property: [" << getPropertyName(id).string()
<< "] value: [" << value.string() << "]"<< endl;
- else
+ else if (notifyChanged)
setChanged();
return success;
}
-void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool nonCSSHint)
+void CSSStyleDeclarationImpl::setProperty(int id, int value, bool important, bool notifyChanged)
{
if(!m_lstValues) {
m_lstValues = new QPtrList<CSSProperty>;
m_lstValues->setAutoDelete(true);
}
- removeProperty(id, nonCSSHint );
+ removeProperty(id);
CSSValueImpl * cssValue = new CSSPrimitiveValueImpl(value);
- setParsedValue(id, cssValue, important, nonCSSHint, m_lstValues);
- setChanged();
+ setParsedValue(id, cssValue, important, m_lstValues);
+ if (notifyChanged)
+ setChanged();
}
-void CSSStyleDeclarationImpl::setStringProperty(int propertyId, const DOMString &value, CSSPrimitiveValue::UnitTypes type, bool important, bool nonCSSHint)
+void CSSStyleDeclarationImpl::setStringProperty(int propertyId, const DOMString &value, CSSPrimitiveValue::UnitTypes type, bool important)
{
if (!m_lstValues) {
m_lstValues = new QPtrList<CSSProperty>;
m_lstValues->setAutoDelete(true);
}
- removeProperty(propertyId, nonCSSHint);
- setParsedValue(propertyId, new CSSPrimitiveValueImpl(value, type), important, nonCSSHint, m_lstValues);
+ removeProperty(propertyId);
+ setParsedValue(propertyId, new CSSPrimitiveValueImpl(value, type), important, m_lstValues);
setChanged();
}
-void CSSStyleDeclarationImpl::setImageProperty(int propertyId, const DOMString &URL, bool important, bool nonCSSHint)
+void CSSStyleDeclarationImpl::setImageProperty(int propertyId, const DOMString &URL, bool important)
{
if (!m_lstValues) {
m_lstValues = new QPtrList<CSSProperty>;
m_lstValues->setAutoDelete(true);
}
- removeProperty(propertyId, nonCSSHint);
- setParsedValue(propertyId, new CSSImageValueImpl(URL, this), important, nonCSSHint, m_lstValues);
+ removeProperty(propertyId);
+ setParsedValue(propertyId, new CSSImageValueImpl(URL, this), important, m_lstValues);
setChanged();
}
@@ -338,17 +340,17 @@ void CSSStyleDeclarationImpl::setPropert
m_lstValues->setAutoDelete( true );
}
- CSSParser parser( strictParsing );
- parser.parseDeclaration( this, propertyString, false );
+ CSSParser parser(strictParsing);
+ parser.parseDeclaration(this, propertyString);
setChanged();
}
-void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint, bool _multiLength )
+void CSSStyleDeclarationImpl::setLengthProperty(int id, const DOM::DOMString &value, bool important, bool _multiLength )
{
bool parseMode = strictParsing;
strictParsing = false;
multiLength = _multiLength;
- setProperty( id, value, important, nonCSSHint);
+ setProperty( id, value, important);
strictParsing = parseMode;
multiLength = false;
}
@@ -378,40 +380,24 @@ DOM::DOMString CSSStyleDeclarationImpl::
if ( m_lstValues) {
QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
CSSProperty *current;
- for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) {
- if (!current->nonCSSHint) {
- result += current->cssText();
- }
- }
+ for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt )
+ result += current->cssText();
}
return result;
}
-void CSSStyleDeclarationImpl::setCssText(DOM::DOMString text)
+void CSSStyleDeclarationImpl::setCssText(const DOM::DOMString& text)
{
- if (m_lstValues) {
- QPtrList<CSSProperty> nonCSSHints;
-
- {
- // make sure to destruct iterator before reassigning list contents
- QPtrListIterator<CSSProperty> lstValuesIt(*m_lstValues);
- CSSProperty *current;
- for ( lstValuesIt.toFirst(); (current = lstValuesIt.current()); ++lstValuesIt ) {
- if (current->nonCSSHint) {
- nonCSSHints.append(new CSSProperty(*current));
- }
- }
- }
-
- *m_lstValues = nonCSSHints;
- } else {
+ if (m_lstValues)
+ m_lstValues->clear();
+ else {
m_lstValues = new QPtrList<CSSProperty>;
- m_lstValues->setAutoDelete( true );
+ m_lstValues->setAutoDelete(true);
}
- CSSParser parser( strictParsing );
- parser.parseDeclaration( this, text, false );
+ CSSParser parser(strictParsing);
+ parser.parseDeclaration(this, text);
setChanged();
}
Index: khtml/css/css_valueimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/css_valueimpl.h,v
retrieving revision 1.22
diff -u -p -r1.22 khtml/css/css_valueimpl.h
--- khtml/css/css_valueimpl.h 2004/01/27 01:29:19 1.22
+++ khtml/css/css_valueimpl.h 2004/02/05 01:40:11
@@ -56,21 +56,21 @@ public:
unsigned long length() const;
CSSRuleImpl *parentRule() const;
- DOM::DOMString removeProperty( int propertyID, bool NonCSSHints = false );
- bool setProperty ( int propertyId, const DOM::DOMString &value, bool important = false, bool nonCSSHint = false);
- void setProperty ( int propertyId, int value, bool important = false, bool nonCSSHint = false);
+ DOM::DOMString removeProperty(int propertyID, bool notifyChanged = true);
+ bool setProperty(int propertyId, const DOM::DOMString &value, bool important = false, bool notifyChanged = true);
+ void setProperty(int propertyId, int value, bool important = false, bool notifyChanged = true);
// this treats integers as pixels!
// needed for conversion of html attributes
- void setLengthProperty(int id, const DOM::DOMString &value, bool important, bool nonCSSHint = true, bool multiLength = false);
- void setStringProperty(int propertyId, const DOM::DOMString &value, DOM::CSSPrimitiveValue::UnitTypes, bool important = false, bool nonCSSHint = false); // parsed string value
- void setImageProperty(int propertyId, const DOM::DOMString &URL, bool important = false, bool nonCSSHint = false);
+ void setLengthProperty(int id, const DOM::DOMString &value, bool important,bool multiLength = false);
+ void setStringProperty(int propertyId, const DOM::DOMString &value, DOM::CSSPrimitiveValue::UnitTypes, bool important = false); // parsed string value
+ void setImageProperty(int propertyId, const DOM::DOMString &URL, bool important = false);
// add a whole, unparsed property
void setProperty ( const DOMString &propertyString);
DOM::DOMString item ( unsigned long index );
virtual DOM::DOMString cssText() const;
- void setCssText(DOM::DOMString str);
+ void setCssText(const DOM::DOMString& str);
virtual bool isStyleDeclaration() { return true; }
@@ -82,6 +82,7 @@ public:
QPtrList<CSSProperty> *values() { return m_lstValues; }
void setNode(NodeImpl *_node) { m_node = _node; }
+ NodeImpl* node() { return m_node; }
void setChanged();
@@ -360,14 +361,12 @@ public:
{
m_id = -1;
m_bImportant = false;
- nonCSSHint = false;
- m_value = 0;
+ m_value = 0;
}
CSSProperty(const CSSProperty& o)
{
m_id = o.m_id;
m_bImportant = o.m_bImportant;
- nonCSSHint = o.nonCSSHint;
m_value = o.m_value;
if (m_value) m_value->ref();
}
@@ -383,14 +382,16 @@ public:
}
}
+ int id() const { return m_id; }
+ bool isImportant() const { return m_bImportant; }
+
CSSValueImpl *value() { return m_value; }
-
+
DOM::DOMString cssText() const;
// make sure the following fits in 4 bytes.
- int m_id : 29;
+ int m_id : 30;
bool m_bImportant : 1;
- bool nonCSSHint : 1;
protected:
CSSValueImpl *m_value;
};
Index: khtml/css/cssparser.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/cssparser.cpp,v
retrieving revision 1.61
diff -u -p -r1.61 khtml/css/cssparser.cpp
--- khtml/css/cssparser.cpp 2004/01/30 07:44:44 1.61
+++ khtml/css/cssparser.cpp 2004/02/05 01:40:11
@@ -99,7 +99,6 @@ CSSParser::CSSParser( bool strictParsing
rule = 0;
id = 0;
important = false;
- nonCSSHint = false;
inParseShortHand = false;
defaultNamespace = anyNamespace;
@@ -131,7 +130,7 @@ CSSParser::~CSSParser()
void ParseString::lower()
{
for (int i = 0; i < length; i++)
- string[i] = QChar(string[i]).lower();
+ string[i] = QChar(string[i]).lower().unicode();
}
void CSSParser::parseSheet( CSSStyleSheetImpl *sheet, const DOMString &string )
@@ -197,11 +196,11 @@ CSSRuleImpl *CSSParser::parseRule( DOM::
}
bool CSSParser::parseValue( DOM::CSSStyleDeclarationImpl *declaration, int _id, const DOM::DOMString &string,
- bool _important, bool _nonCSSHint )
+ bool _important)
{
#ifdef CSS_DEBUG
kdDebug( 6080 ) << "CSSParser::parseValue: id=" << _id << " important=" << _important
- << " nonCSSHint=" << _nonCSSHint << " value='" << string.string() << "'" << endl;
+ << " value='" << string.string() << "'" << endl;
#endif
styleElement = declaration->stylesheet();
@@ -224,8 +223,7 @@ bool CSSParser::parseValue( DOM::CSSStyl
id = _id;
important = _important;
- nonCSSHint = _nonCSSHint;
-
+
CSSParser *old = currentParser;
currentParser = this;
cssyyparse( this );
@@ -238,7 +236,7 @@ bool CSSParser::parseValue( DOM::CSSStyl
if ( numParsedProperties ) {
ok = true;
for ( int i = 0; i < numParsedProperties; i++ ) {
- declaration->removeProperty(parsedProperties[i]->m_id, nonCSSHint);
+ declaration->removeProperty(parsedProperties[i]->m_id);
declaration->values()->append( parsedProperties[i] );
}
numParsedProperties = 0;
@@ -247,12 +245,10 @@ bool CSSParser::parseValue( DOM::CSSStyl
return ok;
}
-bool CSSParser::parseDeclaration( DOM::CSSStyleDeclarationImpl *declaration, const DOM::DOMString &string,
- bool _nonCSSHint )
+bool CSSParser::parseDeclaration( DOM::CSSStyleDeclarationImpl *declaration, const DOM::DOMString &string )
{
#ifdef CSS_DEBUG
- kdDebug( 6080 ) << "CSSParser::parseDeclaration: nonCSSHint=" << nonCSSHint
- << " value='" << string.string() << "'" << endl;
+ kdDebug( 6080 ) << "CSSParser::parseDeclaration:value='" << string.string() << "'" << endl;
#endif
styleElement = declaration->stylesheet();
@@ -273,8 +269,6 @@ bool CSSParser::parseDeclaration( DOM::C
yytext = yy_c_buf_p = data;
yy_hold_char = *yy_c_buf_p;
- nonCSSHint = _nonCSSHint;
-
CSSParser *old = currentParser;
currentParser = this;
cssyyparse( this );
@@ -287,7 +281,7 @@ bool CSSParser::parseDeclaration( DOM::C
if ( numParsedProperties ) {
ok = true;
for ( int i = 0; i < numParsedProperties; i++ ) {
- declaration->removeProperty(parsedProperties[i]->m_id, false);
+ declaration->removeProperty(parsedProperties[i]->m_id);
declaration->values()->append( parsedProperties[i] );
}
numParsedProperties = 0;
@@ -302,7 +296,6 @@ void CSSParser::addProperty( int propId,
prop->m_id = propId;
prop->setValue( value );
prop->m_bImportant = important;
- prop->nonCSSHint = nonCSSHint;
if ( numParsedProperties >= maxParsedProperties ) {
maxParsedProperties += 32;
@@ -706,7 +699,7 @@ bool CSSParser::parseValue( int propId,
case CSS_PROP_BACKGROUND_POSITION_X:
case CSS_PROP_BACKGROUND_POSITION_Y:
- valid_primitive = validUnit( value, FPercent|FLength, strict&(!nonCSSHint) );
+ valid_primitive = validUnit( value, FPercent|FLength, strict );
break;
case CSS_PROP_BORDER_SPACING: {
@@ -728,7 +721,7 @@ bool CSSParser::parseValue( int propId,
}
case CSS_PROP__KHTML_BORDER_HORIZONTAL_SPACING:
case CSS_PROP__KHTML_BORDER_VERTICAL_SPACING:
- valid_primitive = validUnit(value, FLength|FNonNeg, strict&(!nonCSSHint));
+ valid_primitive = validUnit(value, FLength|FNonNeg, strict);
break;
case CSS_PROP_SCROLLBAR_FACE_COLOR: // IE5.5
case CSS_PROP_SCROLLBAR_SHADOW_COLOR: // IE5.5
@@ -758,7 +751,7 @@ bool CSSParser::parseValue( int propId,
valid_primitive = true; // Always allow this, even when strict parsing is on,
// since we use this in our UA sheets.
else if ( id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT || id == CSS_VAL_MENU ||
- (id >= CSS_VAL_GREY && id < CSS_VAL__KHTML_TEXT && (nonCSSHint|!strict)) ) {
+ (id >= CSS_VAL_GREY && id < CSS_VAL__KHTML_TEXT && !strict) ) {
valid_primitive = true;
} else {
parsedValue = parseColor();
@@ -811,7 +804,7 @@ bool CSSParser::parseValue( int propId,
if (id == CSS_VAL_THIN || id == CSS_VAL_MEDIUM || id == CSS_VAL_THICK)
valid_primitive = true;
else
- valid_primitive = ( validUnit( value, FLength, strict&(!nonCSSHint) ) );
+ valid_primitive = ( validUnit( value, FLength, strict ) );
break;
case CSS_PROP_LETTER_SPACING: // normal | <length> | inherit
@@ -819,7 +812,7 @@ bool CSSParser::parseValue( int propId,
if ( id == CSS_VAL_NORMAL )
valid_primitive = true;
else
- valid_primitive = validUnit( value, FLength, strict&(!nonCSSHint) );
+ valid_primitive = validUnit( value, FLength, strict );
break;
case CSS_PROP_TEXT_INDENT: // <length> | <percentage> | inherit
@@ -827,7 +820,7 @@ bool CSSParser::parseValue( int propId,
case CSS_PROP_PADDING_RIGHT: // Which is defined as
case CSS_PROP_PADDING_BOTTOM: // <length> | <percentage>
case CSS_PROP_PADDING_LEFT: ////
- valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) );
+ valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict ) );
break;
case CSS_PROP_MAX_HEIGHT: // <length> | <percentage> | none | inherit
@@ -839,7 +832,7 @@ bool CSSParser::parseValue( int propId,
/* nobreak */
case CSS_PROP_MIN_HEIGHT: // <length> | <percentage> | inherit
case CSS_PROP_MIN_WIDTH: // <length> | <percentage> | inherit
- valid_primitive = ( !id && validUnit( value, FLength|FPercent|FNonNeg, strict&(!nonCSSHint) ) );
+ valid_primitive = ( !id && validUnit( value, FLength|FPercent|FNonNeg, strict ) );
break;
case CSS_PROP_FONT_SIZE:
@@ -847,7 +840,7 @@ bool CSSParser::parseValue( int propId,
if (id >= CSS_VAL_XX_SMALL && id <= CSS_VAL_LARGER)
valid_primitive = true;
else
- valid_primitive = ( validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) );
+ valid_primitive = ( validUnit( value, FLength|FPercent, strict ) );
break;
case CSS_PROP_FONT_STYLE: // normal | italic | oblique | inherit
@@ -867,7 +860,7 @@ bool CSSParser::parseValue( int propId,
if ( id >= CSS_VAL_BASELINE && id <= CSS_VAL__KHTML_BASELINE_MIDDLE )
valid_primitive = true;
else
- valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) );
+ valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict ) );
break;
case CSS_PROP_HEIGHT: // <length> | <percentage> | auto | inherit
@@ -876,7 +869,7 @@ bool CSSParser::parseValue( int propId,
valid_primitive = true;
else
// ### handle multilength case where we allow relative units
- valid_primitive = ( !id && validUnit( value, FLength|FPercent|FNonNeg, strict&(!nonCSSHint) ) );
+ valid_primitive = ( !id && validUnit( value, FLength|FPercent|FNonNeg, strict ) );
break;
case CSS_PROP_BOTTOM: // <length> | <percentage> | auto | inherit
@@ -890,7 +883,7 @@ bool CSSParser::parseValue( int propId,
if ( id == CSS_VAL_AUTO )
valid_primitive = true;
else
- valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict&(!nonCSSHint) ) );
+ valid_primitive = ( !id && validUnit( value, FLength|FPercent, strict ) );
break;
case CSS_PROP_Z_INDEX: // auto | <integer> | inherit
@@ -910,7 +903,7 @@ bool CSSParser::parseValue( int propId,
if ( id == CSS_VAL_NORMAL )
valid_primitive = true;
else
- valid_primitive = ( !id && validUnit( value, FNumber|FLength|FPercent, strict&(!nonCSSHint) ) );
+ valid_primitive = ( !id && validUnit( value, FNumber|FLength|FPercent, strict ) );
break;
#if 0
// removed from CSS 2.1
@@ -1021,7 +1014,7 @@ bool CSSParser::parseValue( int propId,
#endif
break;
case CSS_PROP_OUTLINE_OFFSET:
- valid_primitive = validUnit(value, FLength, strict&(!nonCSSHint));
+ valid_primitive = validUnit(value, FLength, strict);
break;
case CSS_PROP_TEXT_SHADOW: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
if (id == CSS_VAL_NONE)
@@ -1078,7 +1071,7 @@ bool CSSParser::parseValue( int propId,
if (id == CSS_VAL_SMALL || id == CSS_VAL_LARGE || id == CSS_VAL_MEDIUM)
valid_primitive = true;
else
- valid_primitive = validUnit(value, FLength|FPercent, strict&(!nonCSSHint));
+ valid_primitive = validUnit(value, FLength|FPercent, strict);
break;
case CSS_PROP__KHTML_MARQUEE_STYLE:
if (id == CSS_VAL_NONE || id == CSS_VAL_SLIDE || id == CSS_VAL_SCROLL || id == CSS_VAL_ALTERNATE ||
@@ -1089,13 +1082,13 @@ bool CSSParser::parseValue( int propId,
if (id == CSS_VAL_INFINITE)
valid_primitive = true;
else
- valid_primitive = validUnit(value, FInteger|FNonNeg, strict&(!nonCSSHint));
+ valid_primitive = validUnit(value, FInteger|FNonNeg, strict);
break;
case CSS_PROP__KHTML_MARQUEE_SPEED:
if (id == CSS_VAL_NORMAL || id == CSS_VAL_SLOW || id == CSS_VAL_FAST)
valid_primitive = true;
else
- valid_primitive = validUnit(value, FTime|FInteger|FNonNeg, strict&(!nonCSSHint));
+ valid_primitive = validUnit(value, FTime|FInteger|FNonNeg, strict);
break;
case CSS_PROP__KHTML_USER_MODIFY: // read-only | read-write
if (id == CSS_VAL_READ_ONLY || id == CSS_VAL_READ_WRITE)
@@ -1888,7 +1881,7 @@ bool CSSParser::parseShadow( int propId,
// The only other type of value that's ok is a color value.
CSSPrimitiveValueImpl* parsedColor = 0;
bool isColor = (val->id >= CSS_VAL_AQUA && val->id <= CSS_VAL_WINDOWTEXT || val->id == CSS_VAL_MENU ||
- (val->id >= CSS_VAL_GREY && val->id <= CSS_VAL__KHTML_TEXT && (nonCSSHint|!strict)));
+ (val->id >= CSS_VAL_GREY && val->id <= CSS_VAL__KHTML_TEXT && !strict));
if (isColor) {
if (!context.allowColor)
return context.failed();
Index: khtml/css/cssparser.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/cssparser.h,v
retrieving revision 1.21
diff -u -p -r1.21 khtml/css/cssparser.h
--- khtml/css/cssparser.h 2004/01/30 07:44:44 1.21
+++ khtml/css/cssparser.h 2004/02/05 01:40:11
@@ -108,9 +108,8 @@ namespace DOM {
void parseSheet( DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string );
DOM::CSSRuleImpl *parseRule( DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string );
bool parseValue( DOM::CSSStyleDeclarationImpl *decls, int id, const DOM::DOMString &string,
- bool _important, bool _nonCSSHint );
- bool parseDeclaration( DOM::CSSStyleDeclarationImpl *decls, const DOM::DOMString &string,
- bool _nonCSSHint );
+ bool _important );
+ bool parseDeclaration( DOM::CSSStyleDeclarationImpl *decls, const DOM::DOMString &string );
static CSSParser *current() { return currentParser; }
@@ -139,7 +138,6 @@ namespace DOM {
public:
bool strict;
bool important;
- bool nonCSSHint;
int id;
DOM::StyleListImpl *styleElement;
DOM::CSSRuleImpl *rule;
Index: khtml/css/cssstyleselector.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/cssstyleselector.cpp,v
retrieving revision 1.124
diff -u -p -r1.124 khtml/css/cssstyleselector.cpp
--- khtml/css/cssstyleselector.cpp 2004/01/30 07:44:44 1.124
+++ khtml/css/cssstyleselector.cpp 2004/02/05 01:40:11
@@ -107,16 +107,16 @@ if (id == propID) \
namespace khtml {
-CSSStyleSelectorList *CSSStyleSelector::defaultStyle = 0;
-CSSStyleSelectorList *CSSStyleSelector::defaultQuirksStyle = 0;
-CSSStyleSelectorList *CSSStyleSelector::defaultPrintStyle = 0;
+CSSRuleSet *CSSStyleSelector::defaultStyle = 0;
+CSSRuleSet *CSSStyleSelector::defaultQuirksStyle = 0;
+CSSRuleSet *CSSStyleSelector::defaultPrintStyle = 0;
CSSStyleSheetImpl *CSSStyleSelector::defaultSheet = 0;
RenderStyle* CSSStyleSelector::styleNotYetAvailable = 0;
CSSStyleSheetImpl *CSSStyleSelector::quirksSheet = 0;
static CSSStyleSelector::Encodedurl *encodedurl = 0;
-enum PseudoState { PseudoUnknown, PseudoNone, PseudoLink, PseudoVisited};
+enum PseudoState { PseudoUnknown, PseudoNone, PseudoAnyLink, PseudoLink, PseudoVisited};
static PseudoState pseudoState;
@@ -131,34 +131,27 @@ CSSStyleSelector::CSSStyleSelector( Docu
if(!defaultStyle) loadDefaultStyle(settings);
m_medium = view ? view->mediaType() : QString("all");
- selectors = 0;
- selectorCache = 0;
- properties = 0;
- userStyle = 0;
- userSheet = 0;
+ m_userStyle = 0;
+ m_userSheet = 0;
paintDeviceMetrics = doc->paintDeviceMetrics();
+ // FIXME: This sucks! The user sheet is reparsed every time!
if ( !userStyleSheet.isEmpty() ) {
- userSheet = new DOM::CSSStyleSheetImpl(doc);
- userSheet->parseString( DOMString( userStyleSheet ) );
+ m_userSheet = new DOM::CSSStyleSheetImpl(doc);
+ m_userSheet->parseString( DOMString( userStyleSheet ) );
- userStyle = new CSSStyleSelectorList();
- userStyle->append( userSheet, m_medium );
+ m_userStyle = new CSSRuleSet();
+ m_userStyle->addRulesFromSheet( m_userSheet, m_medium );
}
// add stylesheets from document
- authorStyle = new CSSStyleSelectorList();
+ m_authorStyle = new CSSRuleSet();
+ QPtrListIterator<StyleSheetImpl> it(styleSheets->styleSheets);
+ for (; it.current(); ++it)
+ if (it.current()->isCSSStyleSheet())
+ m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheetImpl*>(it.current()), m_medium);
- QPtrListIterator<StyleSheetImpl> it( styleSheets->styleSheets );
- for ( ; it.current(); ++it ) {
- if ( it.current()->isCSSStyleSheet() ) {
- authorStyle->append( static_cast<CSSStyleSheetImpl*>( it.current() ), m_medium );
- }
- }
-
- buildLists();
-
//kdDebug( 6080 ) << "number of style sheets in document " << authorStyleSheets.count() << endl;
//kdDebug( 6080 ) << "CSSStyleSelector: author style has " << authorStyle->count() << " elements"<< endl;
@@ -187,8 +180,8 @@ CSSStyleSelector::CSSStyleSelector( CSSS
KHTMLView *view = sheet->doc()->view();
m_medium = view ? view->mediaType() : QString("all");
- authorStyle = new CSSStyleSelectorList();
- authorStyle->append( sheet, m_medium );
+ m_authorStyle = new CSSRuleSet();
+ m_authorStyle->addRulesFromSheet( sheet, m_medium );
}
void CSSStyleSelector::init()
@@ -196,29 +189,16 @@ void CSSStyleSelector::init()
element = 0;
settings = 0;
paintDeviceMetrics = 0;
- propsToApply = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
- pseudoProps = (CSSOrderedProperty **)malloc(128*sizeof(CSSOrderedProperty *));
- propsToApplySize = 128;
- pseudoPropsSize = 128;
+ m_matchedRuleCount = m_matchedDeclCount = m_tmpRuleCount = 0;
}
CSSStyleSelector::~CSSStyleSelector()
{
- clearLists();
- delete authorStyle;
- delete userStyle;
- delete userSheet;
- free(propsToApply);
- free(pseudoProps);
+ delete m_authorStyle;
+ delete m_userStyle;
+ delete m_userSheet;
}
-void CSSStyleSelector::addSheet( CSSStyleSheetImpl *sheet )
-{
- KHTMLView *view = sheet->doc()->view();
- m_medium = view ? view->mediaType() : QString("all");
- authorStyle->append( sheet, m_medium );
-}
-
void CSSStyleSelector::loadDefaultStyle(const KHTMLSettings *s)
{
if(defaultStyle) return;
@@ -242,11 +222,11 @@ void CSSStyleSelector::loadDefaultStyle(
defaultSheet->parseString( str );
// Collect only strict-mode rules.
- defaultStyle = new CSSStyleSelectorList();
- defaultStyle->append( defaultSheet, "screen" );
-
- defaultPrintStyle = new CSSStyleSelectorList();
- defaultPrintStyle->append( defaultSheet, "print" );
+ defaultStyle = new CSSRuleSet();
+ defaultStyle->addRulesFromSheet( defaultSheet, "screen" );
+
+ defaultPrintStyle = new CSSRuleSet();
+ defaultPrintStyle->addRulesFromSheet( defaultSheet, "print" );
}
{
QFile f(locate( "data", "khtml/css/quirks.css" ) );
@@ -265,8 +245,8 @@ void CSSStyleSelector::loadDefaultStyle(
quirksSheet->parseString( str );
// Collect only quirks-mode rules.
- defaultQuirksStyle = new CSSStyleSelectorList();
- defaultQuirksStyle->append( quirksSheet, "screen" );
+ defaultQuirksStyle = new CSSRuleSet();
+ defaultQuirksStyle->addRulesFromSheet( quirksSheet, "screen" );
}
//kdDebug() << "CSSStyleSelector: default style has " << defaultStyle->count() << " elements"<< endl;
@@ -286,32 +266,165 @@ void CSSStyleSelector::clear()
styleNotYetAvailable = 0;
}
-static inline void bubbleSort( CSSOrderedProperty **b, CSSOrderedProperty **e )
+void CSSStyleSelector::addMatchedRule(CSSRuleData* rule)
{
- while( b < e ) {
- bool swapped = FALSE;
- CSSOrderedProperty **y = e+1;
- CSSOrderedProperty **x = e;
- CSSOrderedProperty **swappedPos = 0;
- do {
- if ( !((**(--x)) < (**(--y))) ) {
- swapped = TRUE;
- swappedPos = x;
- CSSOrderedProperty *tmp = *y;
- *y = *x;
- *x = tmp;
- }
- } while( x != b );
- if ( !swapped ) break;
- b = swappedPos + 1;
+ if (m_matchedRules.size() <= m_matchedRuleCount)
+ m_matchedRules.resize(2*m_matchedRules.size()+1);
+ m_matchedRules[m_matchedRuleCount++] = rule;
+}
+
+void CSSStyleSelector::addMatchedDeclaration(CSSStyleDeclarationImpl* decl)
+{
+ if (m_matchedDecls.size() <= m_matchedDeclCount)
+ m_matchedDecls.resize(2*m_matchedDecls.size()+1);
+ m_matchedDecls[m_matchedDeclCount++] = decl;
+}
+
+void CSSStyleSelector::matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex)
+{
+ m_matchedRuleCount = 0;
+ firstRuleIndex = lastRuleIndex = -1;
+ if (!rules || !element) return;
+
+ // We need to collect the rules for id, class, tag, and everything else into a buffer and
+ // then sort the buffer.
+ if (element->hasID())
+ matchRulesForList(rules->getIDRules(element->getIDAttribute().implementation()),
+ firstRuleIndex, lastRuleIndex);
+ if (element->hasClass()) {
+ for (const AtomicStringList* singleClass = element->getClassList();
+ singleClass; singleClass = singleClass->next())
+ matchRulesForList(rules->getClassRules(singleClass->string().implementation()),
+ firstRuleIndex, lastRuleIndex);
}
+ matchRulesForList(rules->getTagRules((void*)(int)localNamePart(element->id())),
+ firstRuleIndex, lastRuleIndex);
+ matchRulesForList(rules->getUniversalRules(), firstRuleIndex, lastRuleIndex);
+
+ // If we didn't match any rules, we're done.
+ if (m_matchedRuleCount == 0) return;
+
+ // Sort the set of matched rules.
+ sortMatchedRules(0, m_matchedRuleCount);
+
+ // Now transfer the set of matched rules over to our list of decls.
+ for (unsigned i = 0; i < m_matchedRuleCount; i++)
+ addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
}
+void CSSStyleSelector::matchRulesForList(CSSRuleDataList* rules,
+ int& firstRuleIndex, int& lastRuleIndex)
+{
+ if (!rules) return;
+ for (CSSRuleData* d = rules->first(); d; d = d->next()) {
+ CSSStyleRuleImpl* rule = d->rule();
+ Q_UINT16 cssTagId = localNamePart(element->id());
+ Q_UINT16 tag = localNamePart(d->selector()->tag);
+ if ((cssTagId == tag || tag == anyLocalName) && checkSelector(d->selector(), element)) {
+ // If the rule has no properties to apply, then ignore it.
+ CSSStyleDeclarationImpl* decl = rule->declaration();
+ if (!decl) continue;
+
+ // If we're matching normal rules, set a pseudo bit if
+ // we really just matched a pseudo-element.
+ if (dynamicPseudo != RenderStyle::NOPSEUDO && pseudoStyle == RenderStyle::NOPSEUDO)
+ style->setHasPseudoStyle(dynamicPseudo);
+ else {
+ // Update our first/last rule indices in the matched rules array.
+ lastRuleIndex = m_matchedDeclCount + m_matchedRuleCount;
+ if (firstRuleIndex == -1) firstRuleIndex = m_matchedDeclCount + m_matchedRuleCount;
+
+ // Add this rule to our list of matched rules.
+ addMatchedRule(d);
+ }
+ }
+ }
+}
+
+bool operator >(CSSRuleData& r1, CSSRuleData& r2)
+{
+ int spec1 = r1.selector()->specificity();
+ int spec2 = r2.selector()->specificity();
+ return (spec1 == spec2) ? r1.position() > r2.position() : spec1 > spec2;
+}
+bool operator <=(CSSRuleData& r1, CSSRuleData& r2)
+{
+ return !(r1 > r2);
+}
+
+void CSSStyleSelector::sortMatchedRules(uint start, uint end)
+{
+ if (start >= end || (end-start == 1))
+ return; // Sanity check.
+
+ if (end - start <= 6) {
+ // Apply a bubble sort for smaller lists.
+ for (uint i = end-1; i > start; i--) {
+ bool sorted = true;
+ for (uint j = start; j < i; j++) {
+ CSSRuleData* elt = m_matchedRules[j];
+ CSSRuleData* elt2 = m_matchedRules[j+1];
+ if (*elt > *elt2) {
+ sorted = false;
+ m_matchedRules[j] = elt2;
+ m_matchedRules[j+1] = elt;
+ }
+ }
+ if (sorted)
+ return;
+ }
+ }
+ else {
+ // Peform a merge sort for larger lists.
+ uint mid = (start+end)/2;
+ sortMatchedRules(start, mid);
+ sortMatchedRules(mid, end);
+
+ CSSRuleData* elt = m_matchedRules[mid-1];
+ CSSRuleData* elt2 = m_matchedRules[mid];
+
+ // Handle the fast common case (of equal specificity). The list may already
+ // be completely sorted.
+ if (*elt <= *elt2)
+ return;
+
+ // We have to merge sort. Ensure our merge buffer is big enough to hold
+ // all the items.
+ m_tmpRules.resize(end - start);
+ uint i1 = start;
+ uint i2 = mid;
+
+ elt = m_matchedRules[i1];
+ elt2 = m_matchedRules[i2];
+
+ while (i1 < mid || i2 < end) {
+ if (i1 < mid && (i2 == end || *elt <= *elt2)) {
+ m_tmpRules[m_tmpRuleCount++] = elt;
+ i1++;
+ if (i1 < mid)
+ elt = m_matchedRules[i1];
+ }
+ else {
+ m_tmpRules[m_tmpRuleCount++] = elt2;
+ i2++;
+ if (i2 < end)
+ elt2 = m_matchedRules[i2];
+ }
+ }
+
+ for (uint i = start; i < end; i++)
+ m_matchedRules[i] = m_tmpRules[i-start];
+
+ m_tmpRuleCount = 0;
+ }
+}
+
void CSSStyleSelector::initForStyleResolve(ElementImpl* e, RenderStyle* defaultParent)
{
// set some variables we will need
::encodedurl = &encodedurl;
pseudoState = PseudoUnknown;
+ pseudoStyle = RenderStyle::NOPSEUDO;
element = e;
parentNode = e->parentNode();
@@ -326,6 +439,12 @@ void CSSStyleSelector::initForStyleResol
paintDeviceMetrics = element->getDocument()->paintDeviceMetrics();
style = 0;
+
+ m_matchedRuleCount = 0;
+ m_matchedDeclCount = 0;
+ m_tmpRuleCount = 0;
+
+ fontDirty = false;
}
RenderStyle* CSSStyleSelector::styleForElement(ElementImpl* e, RenderStyle* defaultParent)
@@ -347,86 +466,88 @@ RenderStyle* CSSStyleSelector::styleForE
else
parentStyle = style;
- unsigned int numPropsToApply = 0;
-
- // try to sort out most style rules as early as possible.
- Q_UINT16 cssTagId = localNamePart(e->id());
- int smatch = 0;
- int schecked = 0;
-
- for ( unsigned int i = 0; i < selectors_size; i++ ) {
- Q_UINT16 tag = localNamePart(selectors[i]->tag);
- if ( cssTagId == tag || tag == anyLocalName ) {
- ++schecked;
-
- checkSelector( i, e );
-
- if ( selectorCache[i].state == Applies ) {
- ++smatch;
-
- //qDebug("adding property" );
- for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
- for ( unsigned int j = 0; j < (unsigned int )selectorCache[i].props[p+1]; ++j ) {
- if (numPropsToApply >= propsToApplySize ) {
- propsToApplySize *= 2;
- propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
- }
- propsToApply[numPropsToApply++] = properties[selectorCache[i].props[p]+j];
- }
- }
- else if (selectorCache[i].state == AppliesPseudo)
- style->setHasPseudoStyle((RenderStyle::PseudoId)selectors[i]->pseudoId);
- }
- else
- selectorCache[i].state = Invalid;
-
+ // 1. First we match rules from the user agent sheet.
+ int firstUARule = -1, lastUARule = -1;
+ matchRules(defaultStyle, firstUARule, lastUARule);
+
+ // 2. In quirks mode, we match rules from the quirks user agent sheet.
+ if (!strictParsing)
+ matchRules(defaultQuirksStyle, firstUARule, lastUARule);
+
+ // 3. If our medium is print, then we match rules from the print sheet.
+ if (m_medium == "print")
+ matchRules(defaultPrintStyle, firstUARule, lastUARule);
+
+ // 4. Now we check user sheet rules.
+ int firstUserRule = -1, lastUserRule = -1;
+ matchRules(m_userStyle, firstUserRule, lastUserRule);
+
+ // 5. Now check author rules, beginning first with presentational attributes
+ // mapped from HTML.
+ int firstAuthorRule = -1, lastAuthorRule = -1;
+ CSSStyleDeclarationImpl* attributeDecl = e->attributeStyleDecl();
+ if (attributeDecl) {
+ firstAuthorRule = lastAuthorRule = m_matchedDeclCount;
+ addMatchedDeclaration(attributeDecl);
+ }
+
+ // Table cells share an additional mapped rule.
+ attributeDecl = e->additionalAttributeStyleDecl();
+ if (attributeDecl) {
+ if (firstAuthorRule == -1) firstAuthorRule = m_matchedDeclCount;
+ lastAuthorRule = m_matchedDeclCount;
+ addMatchedDeclaration(attributeDecl);
+ }
+
+ // 6. Check the rules in author sheets next.
+ matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
+
+ // 7. Now check our inline style attribute.
+ CSSStyleDeclarationImpl* inlineDecl = e->inlineStyleDecl();
+ if (inlineDecl) {
+ if (firstAuthorRule == -1) firstAuthorRule = m_matchedDeclCount;
+ lastAuthorRule = m_matchedDeclCount;
+ addMatchedDeclaration(inlineDecl);
+ }
+
+ // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
+ // high-priority properties first, i.e., those properties that other properties depend on.
+ // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
+ // and (4) normal important.
+ applyDeclarations(true, false, 0, m_matchedDeclCount-1);
+ applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(true, true, firstUserRule, lastUserRule);
+ applyDeclarations(true, true, firstUARule, lastUARule);
+
+ // If our font got dirtied, go ahead and update it now.
+ if (fontDirty) {
+ checkForGenericFamilyChange(style, parentStyle);
+ style->htmlFont().update(paintDeviceMetrics);
+ fontDirty = false;
}
-
- //qDebug( "styleForElement( %s )", e->tagName().string().latin1() );
- //qDebug( "%d selectors, %d checked, %d match, %d properties ( of %d )",
- //selectors_size, schecked, smatch, propsToApply->count(), properties_size );
-
- // inline style declarations, after all others. non css hints
- // count as author rules, and come before all other style sheets, see hack in append()
- numPropsToApply = addInlineDeclarations( e, e->m_styleDecls, numPropsToApply );
-
- bubbleSort( propsToApply, propsToApply+numPropsToApply-1 );
- //qDebug("applying properties, count=%d", propsToApply->count() );
-
- // we can't apply style rules without a view() and a part. This
- // tends to happen on delayed destruction of widget Renderobjects
- if ( part ) {
+ // Now do the normal priority properties.
+ applyDeclarations(false, false, 0, m_matchedDeclCount-1);
+ applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(false, true, firstUserRule, lastUserRule);
+ applyDeclarations(false, true, firstUARule, lastUARule);
+
+ // If our font got dirtied by one of the non-essential font props,
+ // go ahead and update it a second time.
+ if (fontDirty) {
+ checkForGenericFamilyChange(style, parentStyle);
+ style->htmlFont().update(paintDeviceMetrics);
fontDirty = false;
-
- if (numPropsToApply ) {
- CSSStyleSelector::style = style;
- for (unsigned int i = 0; i < numPropsToApply; ++i) {
- if ( fontDirty && propsToApply[i]->priority >= (1 << 30) ) {
- // we are past the font properties, time to update to the
- // correct font
- checkForGenericFamilyChange(style, parentStyle);
- CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
- fontDirty = false;
- }
- DOM::CSSProperty *prop = propsToApply[i]->prop;
- applyRule( prop->m_id, prop->value() );
- }
- if ( fontDirty ) {
- checkForGenericFamilyChange(style, parentStyle);
- CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
- }
- }
-
- // Clean up our style object's display and text decorations (among other fixups).
- adjustRenderStyle(style, e);
}
+
+ // Clean up our style object's display and text decorations (among other fixups).
+ adjustRenderStyle(style, e);
// Now return the style.
return style;
}
-RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudoStyle,
+RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudo,
ElementImpl* e, RenderStyle* parentStyle)
{
if (!e)
@@ -442,37 +563,18 @@ RenderStyle* CSSStyleSelector::pseudoSty
}
initForStyleResolve(e, parentStyle);
+ pseudoStyle = pseudo;
- unsigned int numPseudoProps = 0;
+ // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
+ // those rules.
- // try to sort out most style rules as early as possible.
- Q_UINT16 cssTagId = localNamePart(e->id());
- int schecked = 0;
-
- for ( unsigned int i = 0; i < selectors_size; i++ ) {
- Q_UINT16 tag = localNamePart(selectors[i]->tag);
- if ( cssTagId == tag || tag == anyLocalName ) {
- ++schecked;
-
- checkSelector( i, e, pseudoStyle );
-
- if ( selectorCache[i].state == AppliesPseudo ) {
- for ( unsigned int p = 0; p < selectorCache[i].props_size; p += 2 )
- for ( unsigned int j = 0; j < (unsigned int) selectorCache[i].props[p+1]; ++j ) {
- if (numPseudoProps >= pseudoPropsSize ) {
- pseudoPropsSize *= 2;
- pseudoProps = (CSSOrderedProperty **)realloc( pseudoProps, pseudoPropsSize*sizeof( CSSOrderedProperty * ) );
- }
- pseudoProps[numPseudoProps++] = properties[selectorCache[i].props[p]+j];
- properties[selectorCache[i].props[p]+j]->pseudoId = (RenderStyle::PseudoId) selectors[i]->pseudoId;
- }
- }
- }
- else
- selectorCache[i].state = Invalid;
- }
+ // Check UA, user and author rules.
+ int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
+ matchRules(defaultStyle, firstUARule, lastUARule);
+ matchRules(m_userStyle, firstUserRule, lastUserRule);
+ matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
- if (numPseudoProps == 0)
+ if (m_matchedDeclCount == 0)
return 0;
style = new RenderStyle();
@@ -481,38 +583,37 @@ RenderStyle* CSSStyleSelector::pseudoSty
else
parentStyle = style;
style->noninherited_flags._styleType = pseudoStyle;
-
- bubbleSort( pseudoProps, pseudoProps+numPseudoProps-1 );
-
- // we can't apply style rules without a view() and a part. This
- // tends to happen on delayed destruction of widget Renderobjects
- if ( part ) {
+
+ // High-priority properties.
+ applyDeclarations(true, false, 0, m_matchedDeclCount-1);
+ applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(true, true, firstUserRule, lastUserRule);
+ applyDeclarations(true, true, firstUARule, lastUARule);
+
+ // If our font got dirtied, go ahead and update it now.
+ if (fontDirty) {
+ checkForGenericFamilyChange(style, parentStyle);
+ style->htmlFont().update(paintDeviceMetrics);
fontDirty = false;
- if ( numPseudoProps ) {
- fontDirty = false;
- //qDebug("%d applying %d pseudo props", e->cssTagId(), pseudoProps->count() );
- for (unsigned int i = 0; i < numPseudoProps; ++i) {
- if ( fontDirty && pseudoProps[i]->priority >= (1 << 30) ) {
- // we are past the font properties, time to update to the
- // correct font
- style->htmlFont().update( paintDeviceMetrics );
- fontDirty = false;
- }
-
- DOM::CSSProperty *prop = pseudoProps[i]->prop;
- applyRule( prop->m_id, prop->value() );
- }
-
- if ( fontDirty ) {
- checkForGenericFamilyChange(style, parentStyle);
- style->htmlFont().update( paintDeviceMetrics );
- }
- }
}
- // Do the post-resolve fixups on the style.
+ // Now do the normal priority properties.
+ applyDeclarations(false, false, 0, m_matchedDeclCount-1);
+ applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations(false, true, firstUserRule, lastUserRule);
+ applyDeclarations(false, true, firstUARule, lastUARule);
+
+ // If our font got dirtied by one of the non-essential font props,
+ // go ahead and update it a second time.
+ if (fontDirty) {
+ checkForGenericFamilyChange(style, parentStyle);
+ style->htmlFont().update(paintDeviceMetrics);
+ fontDirty = false;
+ }
+
+ // Clean up our style object's display and text decorations (among other fixups).
adjustRenderStyle(style, 0);
-
+
// Now return the style.
return style;
}
@@ -593,77 +694,6 @@ void CSSStyleSelector::adjustRenderStyle
style->addToTextDecorationsInEffect(style->textDecoration());
}
-unsigned int CSSStyleSelector::addInlineDeclarations(DOM::ElementImpl* e,
- DOM::CSSStyleDeclarationImpl *decl,
- unsigned int numProps)
-{
- CSSStyleDeclarationImpl* addDecls = 0;
- if (e->id() == ID_TD || e->id() == ID_TH) // For now only TableCellElement implements the
- addDecls = e->getAdditionalStyleDecls(); // virtual function for shared cell rules.
-
- if (!decl && !addDecls)
- return numProps;
-
- QPtrList<CSSProperty>* values = decl ? decl->values() : 0;
- QPtrList<CSSProperty>* addValues = addDecls ? addDecls->values() : 0;
- if (!values && !addValues)
- return numProps;
-
- int firstLen = values ? values->count() : 0;
- int secondLen = addValues ? addValues->count() : 0;
- int totalLen = firstLen + secondLen;
-
- if (inlineProps.size() < (uint)totalLen)
- inlineProps.resize(totalLen + 1);
-
- if (numProps + totalLen >= propsToApplySize ) {
- propsToApplySize += propsToApplySize;
- propsToApply = (CSSOrderedProperty **)realloc( propsToApply, propsToApplySize*sizeof( CSSOrderedProperty * ) );
- }
-
- CSSOrderedProperty *array = (CSSOrderedProperty *)inlineProps.data();
- for(int i = 0; i < totalLen; i++)
- {
- if (i == firstLen)
- values = addValues;
-
- CSSProperty *prop = values->at(i >= firstLen ? i - firstLen : i);
- Source source = Inline;
-
- if( prop->m_bImportant ) source = InlineImportant;
- if( prop->nonCSSHint ) source = NonCSSHint;
-
- bool first;
- // give special priority to font-xxx, color properties
- switch(prop->m_id)
- {
- case CSS_PROP_FONT_STYLE:
- case CSS_PROP_FONT_SIZE:
- case CSS_PROP_FONT_WEIGHT:
- case CSS_PROP_FONT_FAMILY:
- case CSS_PROP_FONT:
- case CSS_PROP_COLOR:
- case CSS_PROP_BACKGROUND_IMAGE:
- case CSS_PROP_DISPLAY:
- // these have to be applied first, because other properties use the computed
- // values of these porperties.
- first = true;
- break;
- default:
- first = false;
- break;
- }
-
- array->prop = prop;
- array->pseudoId = RenderStyle::NOPSEUDO;
- array->selector = 0;
- array->position = i;
- array->priority = (!first << 30) | (source << 24);
- propsToApply[numProps++] = array++;
- }
- return numProps;
-}
-
static bool subject;
// modified version of the one in kurl.cpp
@@ -704,17 +734,24 @@ static void cleanpath(QString &path)
//kdDebug() << "checkPseudoState " << path << endl;
}
-static void checkPseudoState( DOM::ElementImpl *e )
+static void checkPseudoState( DOM::ElementImpl *e, bool checkVisited = true )
{
if (!e->hasAnchor()) {
pseudoState = PseudoNone;
return;
}
+
const AtomicString& attr = e->getAttribute(ATTR_HREF);
- if( attr.isNull() ) {
+ if (attr.isNull()) {
pseudoState = PseudoNone;
return;
}
+
+ if (!checkVisited) {
+ pseudoState = PseudoAnyLink;
+ return;
+ }
+
QConstString cu(attr.unicode(), attr.length());
QString u = cu.string();
if ( !u.contains("://") ) {
@@ -730,15 +767,12 @@ static void checkPseudoState( DOM::Eleme
pseudoState = KHTMLFactory::vLinks()->contains( u ) ? PseudoVisited : PseudoLink;
}
-void CSSStyleSelector::checkSelector(int selIndex, DOM::ElementImpl *e, RenderStyle::PseudoId pseudo)
+bool CSSStyleSelector::checkSelector(CSSSelector* sel, ElementImpl *e)
{
dynamicPseudo = RenderStyle::NOPSEUDO;
NodeImpl *n = e;
- selectorCache[ selIndex ].state = Invalid;
- CSSSelector *sel = selectors[ selIndex ];
-
// we have the subject part of the selector
subject = true;
@@ -751,33 +785,34 @@ void CSSStyleSelector::checkSelector(int
sel->pseudoType() == CSSSelector::PseudoActive)));
bool affectedByHover = style ? style->affectedByHoverRules() : false;
bool affectedByActive = style ? style->affectedByActiveRules() : false;
- bool havePseudo = pseudo != RenderStyle::NOPSEUDO;
+ bool havePseudo = pseudoStyle != RenderStyle::NOPSEUDO;
// first selector has to match
- if(!checkOneSelector(sel, e)) return;
+ if (!checkOneSelector(sel, e)) return false;
// check the subselectors
CSSSelector::Relation relation = sel->relation;
while((sel = sel->tagHistory))
{
- if (!n->isElementNode()) return;
+ if (!n->isElementNode()) return false;
if (relation != CSSSelector::SubSelector) {
subject = false;
- if (havePseudo && dynamicPseudo != pseudo)
- return;
+ if (havePseudo && dynamicPseudo != pseudoStyle)
+ return false;
}
switch(relation)
{
case CSSSelector::Descendant:
{
+ // FIXME: This match needs to know how to backtrack and be non-deterministic.
bool found = false;
while(!found)
{
n = n->parentNode();
- if(!n || !n->isElementNode()) return;
+ if(!n || !n->isElementNode()) return false;
ElementImpl *elem = static_cast<ElementImpl *>(n);
- if(checkOneSelector(sel, elem)) found = true;
+ if (checkOneSelector(sel, elem)) found = true;
}
break;
}
@@ -786,9 +821,9 @@ void CSSStyleSelector::checkSelector(int
n = n->parentNode();
if (!strictParsing)
while (n && n->implicitNode()) n = n->parentNode();
- if(!n || !n->isElementNode()) return;
+ if(!n || !n->isElementNode()) return false;
ElementImpl *elem = static_cast<ElementImpl *>(n);
- if(!checkOneSelector(sel, elem)) return;
+ if (!checkOneSelector(sel, elem)) return false;
break;
}
case CSSSelector::Sibling:
@@ -796,9 +831,9 @@ void CSSStyleSelector::checkSelector(int
n = n->previousSibling();
while( n && !n->isElementNode() )
n = n->previousSibling();
- if( !n ) return;
+ if( !n ) return false;
ElementImpl *elem = static_cast<ElementImpl *>(n);
- if(!checkOneSelector(sel, elem)) return;
+ if (!checkOneSelector(sel, elem)) return false;
break;
}
case CSSSelector::SubSelector:
@@ -811,10 +846,9 @@ void CSSStyleSelector::checkSelector(int
//kdDebug() << "CSSOrderedRule::checkSelector" << endl;
ElementImpl *elem = static_cast<ElementImpl *>(n);
// a selector is invalid if something follows :first-xxx
- if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
- return;
- }
- if(!checkOneSelector(sel, elem)) return;
+ if (dynamicPseudo != RenderStyle::NOPSEUDO)
+ return false;
+ if (!checkOneSelector(sel, elem)) return false;
//kdDebug() << "CSSOrderedRule::checkSelector: passed" << endl;
break;
}
@@ -822,31 +856,24 @@ void CSSStyleSelector::checkSelector(int
relation = sel->relation;
}
- if (subject && havePseudo && dynamicPseudo != pseudo)
- return;
+ if (subject && havePseudo && dynamicPseudo != pseudoStyle)
+ return false;
// disallow *:hover, *:active, and *:hover:active except for links
if (onlyHoverActive && subject) {
if (pseudoState == PseudoUnknown)
- checkPseudoState( e );
+ checkPseudoState(e);
if (pseudoState == PseudoNone) {
if (!affectedByHover && style->affectedByHoverRules())
style->setAffectedByHoverRules(false);
if (!affectedByActive && style->affectedByActiveRules())
style->setAffectedByActiveRules(false);
- return;
+ return false;
}
}
- if ( dynamicPseudo != RenderStyle::NOPSEUDO ) {
- selectorCache[selIndex].state = AppliesPseudo;
- selectors[ selIndex ]->pseudoId = dynamicPseudo;
- } else
- selectorCache[ selIndex ].state = Applies;
- //qDebug( "selector %d applies", selIndex );
- //selectors[ selIndex ]->print();
- return;
+ return true;
}
bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e)
@@ -870,14 +897,16 @@ bool CSSStyleSelector::checkOneSelector(
}
if (sel->attr) {
- if (sel->match == CSSSelector::Class)
- return e->hasClass() && e->matchesCSSClass(sel->value, strictParsing);
- else if (sel->match == CSSSelector::Id) {
- if (!e->hasID()) return false;
- const AtomicString& value = e->getAttribute(sel->attr);
- return !((strictParsing && sel->value != value) ||
- (!strictParsing && !equalsIgnoreCase(sel->value, value)));
+ if (sel->match == CSSSelector::Class) {
+ if (!e->hasClass())
+ return false;
+ for (const AtomicStringList* c = e->getClassList(); c; c = c->next())
+ if (c->string() == sel->value)
+ return true;
+ return false;
}
+ else if (sel->match == CSSSelector::Id)
+ return e->hasID() && e->getIDAttribute() == sel->value;
const AtomicString& value = e->getAttribute(sel->attr);
if (value.isNull()) return false; // attribute is not set
@@ -1036,14 +1065,20 @@ bool CSSStyleSelector::checkOneSelector(
if (e == e->getDocument()->getCSSTarget())
return true;
break;
+ case CSSSelector::PseudoAnyLink:
+ if (pseudoState == PseudoUnknown)
+ checkPseudoState(e, false);
+ if (pseudoState == PseudoAnyLink || pseudoState == PseudoLink || pseudoState == PseudoVisited)
+ return true;
+ break;
case CSSSelector::PseudoLink:
- if ( pseudoState == PseudoUnknown )
+ if ( pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink )
checkPseudoState( e );
if ( pseudoState == PseudoLink )
return true;
break;
case CSSSelector::PseudoVisited:
- if ( pseudoState == PseudoUnknown )
+ if ( pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink )
checkPseudoState( e );
if ( pseudoState == PseudoVisited )
return true;
@@ -1121,205 +1156,101 @@ bool CSSStyleSelector::checkOneSelector(
return true;
}
-void CSSStyleSelector::clearLists()
+// -----------------------------------------------------------------
+
+CSSRuleSet::CSSRuleSet()
{
- if ( selectors ) delete [] selectors;
- if ( selectorCache ) {
- for ( unsigned int i = 0; i < selectors_size; i++ )
- if ( selectorCache[i].props )
- delete [] selectorCache[i].props;
-
- delete [] selectorCache;
- }
- if ( properties ) {
- CSSOrderedProperty **prop = properties;
- while ( *prop ) {
- delete (*prop);
- prop++;
- }
- delete [] properties;
+ m_idRules.setAutoDelete(true);
+ m_classRules.setAutoDelete(true);
+ m_tagRules.setAutoDelete(true);
+ m_universalRules = 0;
+ m_ruleCount = 0;
+}
+
+void CSSRuleSet::addToRuleSet(void* hash, QPtrDict<CSSRuleDataList>& dict,
+ CSSStyleRuleImpl* rule, CSSSelector* sel)
+{
+ if (!hash) return;
+ CSSRuleDataList* rules = dict.find(hash);
+ if (!rules) {
+ rules = new CSSRuleDataList(m_ruleCount++, rule, sel);
+ dict.insert(hash, rules);
}
- selectors = 0;
- properties = 0;
- selectorCache = 0;
+ else
+ rules->append(m_ruleCount++, rule, sel);
}
-
-void CSSStyleSelector::buildLists()
+void CSSRuleSet::addRule(CSSStyleRuleImpl* rule, CSSSelector* sel)
{
- clearLists();
- // collect all selectors and Properties in lists. Then transer them to the array for faster lookup.
-
- QPtrList<CSSSelector> selectorList;
- CSSOrderedPropertyList propertyList;
-
- if(m_medium == "print" && defaultPrintStyle)
- defaultPrintStyle->collect( &selectorList, &propertyList, Default,
- Default );
- else if(defaultStyle) defaultStyle->collect( &selectorList, &propertyList,
- Default, Default );
-
- if (!strictParsing && defaultQuirksStyle)
- defaultQuirksStyle->collect( &selectorList, &propertyList, Default, Default );
-
- if(userStyle) userStyle->collect(&selectorList, &propertyList, User, UserImportant );
- if(authorStyle) authorStyle->collect(&selectorList, &propertyList, Author, AuthorImportant );
-
- selectors_size = selectorList.count();
- selectors = new CSSSelector *[selectors_size];
- CSSSelector *s = selectorList.first();
- CSSSelector **sel = selectors;
- while ( s ) {
- *sel = s;
- s = selectorList.next();
- ++sel;
- }
-
- selectorCache = new SelectorCache[selectors_size];
- for ( unsigned int i = 0; i < selectors_size; i++ ) {
- selectorCache[i].state = Unknown;
- selectorCache[i].props_size = 0;
- selectorCache[i].props = 0;
+ if (sel->match == CSSSelector::Id) {
+ addToRuleSet(sel->value.implementation(), m_idRules, rule, sel);
+ return;
}
-
- // presort properties. Should make the sort() calls in styleForElement faster.
- propertyList.sort();
- properties_size = propertyList.count() + 1;
- properties = new CSSOrderedProperty *[ properties_size ];
- CSSOrderedProperty *p = propertyList.first();
- CSSOrderedProperty **prop = properties;
- while ( p ) {
- *prop = p;
- p = propertyList.next();
- ++prop;
+ if (sel->match == CSSSelector::Class) {
+ addToRuleSet(sel->value.implementation(), m_classRules, rule, sel);
+ return;
}
- *prop = 0;
-
- unsigned int* offsets = new unsigned int[selectors_size];
- if(properties[0])
- offsets[properties[0]->selector] = 0;
- for(unsigned int p = 1; p < properties_size; ++p) {
-
- if(!properties[p] || (properties[p]->selector != properties[p - 1]->selector)) {
- unsigned int sel = properties[p - 1]->selector;
- int* newprops = new int[selectorCache[sel].props_size+2];
- for ( unsigned int i=0; i < selectorCache[sel].props_size; i++ )
- newprops[i] = selectorCache[sel].props[i];
-
- newprops[selectorCache[sel].props_size] = offsets[sel];
- newprops[selectorCache[sel].props_size+1] = p - offsets[sel];
- delete [] selectorCache[sel].props;
- selectorCache[sel].props = newprops;
- selectorCache[sel].props_size += 2;
-
- if(properties[p]) {
- sel = properties[p]->selector;
- offsets[sel] = p;
- }
- }
+
+ Q_UINT16 localName = localNamePart(sel->tag);
+ if (localName != anyLocalName) {
+ addToRuleSet((void*)(int)localName, m_tagRules, rule, sel);
+ return;
}
- delete [] offsets;
-}
-
-
-// ----------------------------------------------------------------------
-
-
-CSSOrderedRule::CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index)
-{
- rule = r;
- if(rule) r->ref();
- index = _index;
- selector = s;
-}
-
-CSSOrderedRule::~CSSOrderedRule()
-{
- if(rule) rule->deref();
-}
-
-// -----------------------------------------------------------------
-
-CSSStyleSelectorList::CSSStyleSelectorList()
- : QPtrList<CSSOrderedRule>()
-{
- setAutoDelete(true);
-}
-CSSStyleSelectorList::~CSSStyleSelectorList()
-{
+
+ // Just put it in the universal rule set.
+ if (!m_universalRules)
+ m_universalRules = new CSSRuleDataList(m_ruleCount++, rule, sel);
+ else
+ m_universalRules->append(m_ruleCount++, rule, sel);
}
-void CSSStyleSelectorList::append( CSSStyleSheetImpl *sheet,
- const DOMString &medium )
+void CSSRuleSet::addRulesFromSheet(CSSStyleSheetImpl *sheet, const DOMString &medium)
{
- if(!sheet || !sheet->isCSSStyleSheet()) return;
+ if (!sheet || !sheet->isCSSStyleSheet()) return;
- // No media implies "all", but if a medialist exists it must
+ // No media implies "all", but if a media list exists it must
// contain our current medium
- if( sheet->media() && !sheet->media()->contains( medium ) )
- return; // style sheet not applicable for this medium
+ if (sheet->media() && !sheet->media()->contains(medium))
+ return; // the style sheet doesn't apply
int len = sheet->length();
- for(int i = 0; i< len; i++)
- {
+ for (int i = 0; i < len; i++) {
StyleBaseImpl *item = sheet->item(i);
- if(item->isStyleRule())
- {
- CSSStyleRuleImpl *r = static_cast<CSSStyleRuleImpl *>(item);
- QPtrList<CSSSelector> *s = r->selector();
- for(int j = 0; j < (int)s->count(); j++)
- {
- CSSOrderedRule *rule = new CSSOrderedRule(r, s->at(j), count());
- QPtrList<CSSOrderedRule>::append(rule);
- //kdDebug( 6080 ) << "appending StyleRule!" << endl;
- }
+ if (item->isStyleRule()) {
+ CSSStyleRuleImpl* rule = static_cast<CSSStyleRuleImpl*>(item);
+ for (CSSSelector* s = rule->selector(); s; s = s->next())
+ addRule(rule, s);
}
- else if(item->isImportRule())
- {
+ else if(item->isImportRule()) {
CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item);
//kdDebug( 6080 ) << "@import: Media: "
// << import->media()->mediaText().string() << endl;
- if( !import->media() || import->media()->contains( medium ) )
- {
- CSSStyleSheetImpl *importedSheet = import->styleSheet();
- append( importedSheet, medium );
- }
+ if (!import->media() || import->media()->contains(medium))
+ addRulesFromSheet(import->styleSheet(), medium);
}
- else if( item->isMediaRule() )
- {
- CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl *>( item );
+ else if(item->isMediaRule()) {
+ CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl*>(item);
CSSRuleListImpl *rules = r->cssRules();
//DOMString mediaText = media->mediaText();
//kdDebug( 6080 ) << "@media: Media: "
// << r->media()->mediaText().string() << endl;
- if( ( !r->media() || r->media()->contains( medium ) ) && rules)
- {
- // Traverse child elements of the @import rule. Since
- // many elements are not allowed as child we do not use
- // a recursive call to append() here
- for( unsigned j = 0; j < rules->length(); j++ )
- {
+ if ((!r->media() || r->media()->contains(medium)) && rules) {
+ // Traverse child elements of the @media rule.
+ for (unsigned j = 0; j < rules->length(); j++) {
//kdDebug( 6080 ) << "*** Rule #" << j << endl;
- CSSRuleImpl *childItem = rules->item( j );
- if( childItem->isStyleRule() )
- {
+ CSSRuleImpl *childItem = rules->item(j);
+ if (childItem->isStyleRule()) {
// It is a StyleRule, so append it to our list
- CSSStyleRuleImpl *styleRule =
- static_cast<CSSStyleRuleImpl *>( childItem );
-
- QPtrList<CSSSelector> *s = styleRule->selector();
- for( int j = 0; j < ( int ) s->count(); j++ )
- {
- CSSOrderedRule *orderedRule = new CSSOrderedRule(
- styleRule, s->at( j ), count() );
- QPtrList<CSSOrderedRule>::append( orderedRule );
- }
+ CSSStyleRuleImpl* rule = static_cast<CSSStyleRuleImpl*>(childItem);
+ for (CSSSelector* s = rule->selector(); s; s = s->next())
+ addRule(rule, s);
+
}
else
{
@@ -1338,79 +1269,6 @@ void CSSStyleSelectorList::append( CSSSt
}
}
-
-void CSSStyleSelectorList::collect( QPtrList<CSSSelector> *selectorList, CSSOrderedPropertyList *propList,
- Source regular, Source important )
-{
- CSSOrderedRule *r = first();
- while( r ) {
- CSSSelector *sel = selectorList->first();
- int selectorNum = 0;
- while( sel ) {
- if ( *sel == *(r->selector) )
- break;
- sel = selectorList->next();
- selectorNum++;
- }
- if ( !sel )
- selectorList->append( r->selector );
-// else
-// qDebug("merged one selector");
- propList->append(r->rule->declaration(), selectorNum, r->selector->specificity(), regular, important );
- r = next();
- }
-}
-
-// -------------------------------------------------------------------------
-
-int CSSOrderedPropertyList::compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2)
-{
- int diff = static_cast<CSSOrderedProperty *>(i1)->priority
- - static_cast<CSSOrderedProperty *>(i2)->priority;
- return diff ? diff : static_cast<CSSOrderedProperty *>(i1)->position
- - static_cast<CSSOrderedProperty *>(i2)->position;
-}
-
-void CSSOrderedPropertyList::append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity,
- Source regular, Source important )
-{
- QPtrList<CSSProperty> *values = decl->values();
- if(!values) return;
- int len = values->count();
- for(int i = 0; i < len; i++)
- {
- CSSProperty *prop = values->at(i);
- Source source = regular;
-
- if( prop->m_bImportant ) source = important;
- if( prop->nonCSSHint ) source = NonCSSHint;
-
- bool first = false;
- // give special priority to font-xxx, color properties
- switch(prop->m_id)
- {
- case CSS_PROP_FONT_STYLE:
- case CSS_PROP_FONT_SIZE:
- case CSS_PROP_FONT_WEIGHT:
- case CSS_PROP_FONT_FAMILY:
- case CSS_PROP_FONT:
- case CSS_PROP_COLOR:
- case CSS_PROP_BACKGROUND_IMAGE:
- case CSS_PROP_DISPLAY:
- // these have to be applied first, because other properties use the computed
- // values of these porperties.
- first = true;
- break;
- default:
- break;
- }
-
- QPtrList<CSSOrderedProperty>::append(new CSSOrderedProperty(prop, selector,
- first, source, specificity,
- count() ));
- }
-}
-
// -------------------------------------------------------------------------------------
// this is mostly boring stuff on how to apply a certain rule to the renderstyle...
@@ -1583,8 +1441,48 @@ static QColor colorForCSSValue( int css_
return c;
};
+void CSSStyleSelector::applyDeclarations(bool applyFirst, bool isImportant,
+ int startIndex, int endIndex)
+{
+ if (startIndex == -1) return;
+ for (int i = startIndex; i <= endIndex; i++) {
+ CSSStyleDeclarationImpl* decl = m_matchedDecls[i];
+ QPtrList<CSSProperty>* props = decl->values();
+ if (props) {
+ QPtrListIterator<CSSProperty> propertyIt(*props);
+ CSSProperty* current;
+ for (propertyIt.toFirst(); (current = propertyIt.current()); ++propertyIt) {
+ // give special priority to font-xxx, color properties
+ if (isImportant == current->isImportant()) {
+ bool first;
+ switch(current->id())
+ {
+ case CSS_PROP_FONT_STYLE:
+ case CSS_PROP_FONT_SIZE:
+ case CSS_PROP_FONT_WEIGHT:
+ case CSS_PROP_FONT_FAMILY:
+ case CSS_PROP_FONT:
+ case CSS_PROP_COLOR:
+ case CSS_PROP_BACKGROUND_IMAGE:
+ case CSS_PROP_DISPLAY:
+ // these have to be applied first, because other properties use the computed
+ // values of these porperties.
+ first = true;
+ break;
+ default:
+ first = false;
+ break;
+ }
+
+ if (first == applyFirst)
+ applyProperty(current->id(), current->value());
+ }
+ }
+ }
+ }
+}
-void CSSStyleSelector::applyRule( int id, DOM::CSSValueImpl *value )
+void CSSStyleSelector::applyProperty( int id, DOM::CSSValueImpl *value )
{
//kdDebug( 6080 ) << "applying property " << prop->m_id << endl;
@@ -2214,20 +2112,11 @@ void CSSStyleSelector::applyRule( int id
col = RenderStyle::initialColor();
}
else {
- if(!primitiveValue )
+ if(!primitiveValue)
return;
- int ident = primitiveValue->getIdent();
- if ( ident ) {
- if ( ident == CSS_VAL__KHTML_TEXT )
- col = element->getDocument()->textColor();
- else
- col = colorForCSSValue( ident );
- } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR )
- col.setRgb(primitiveValue->getRGBColorValue());
- else {
- return;
- }
+ col = getColorFromPrimitiveValue(primitiveValue);
}
+
//kdDebug( 6080 ) << "applying color " << col.isValid() << endl;
switch(id)
{
@@ -3139,10 +3028,10 @@ void CSSStyleSelector::applyRule( int id
if ( !font->style || !font->variant || !font->weight ||
!font->size || !font->lineHeight || !font->family )
return;
- applyRule( CSS_PROP_FONT_STYLE, font->style );
- applyRule( CSS_PROP_FONT_VARIANT, font->variant );
- applyRule( CSS_PROP_FONT_WEIGHT, font->weight );
- applyRule( CSS_PROP_FONT_SIZE, font->size );
+ applyProperty( CSS_PROP_FONT_STYLE, font->style );
+ applyProperty( CSS_PROP_FONT_VARIANT, font->variant );
+ applyProperty( CSS_PROP_FONT_WEIGHT, font->weight );
+ applyProperty( CSS_PROP_FONT_SIZE, font->size );
// Line-height can depend on font().pixelSize(), so we have to update the font
// before we evaluate line-height, e.g., font: 1em/1em. FIXME: Still not
@@ -3150,8 +3039,8 @@ void CSSStyleSelector::applyRule( int id
if (fontDirty)
CSSStyleSelector::style->htmlFont().update( paintDeviceMetrics );
- applyRule( CSS_PROP_LINE_HEIGHT, font->lineHeight );
- applyRule( CSS_PROP_FONT_FAMILY, font->family );
+ applyProperty( CSS_PROP_LINE_HEIGHT, font->lineHeight );
+ applyProperty( CSS_PROP_FONT_FAMILY, font->family );
}
return;
@@ -3624,6 +3513,33 @@ float CSSStyleSelector::smallerFontSize(
// FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale down to
// the next size level.
return size/1.2;
+}
+
+QColor CSSStyleSelector::getColorFromPrimitiveValue(CSSPrimitiveValueImpl* primitiveValue)
+{
+ QColor col;
+ int ident = primitiveValue->getIdent();
+ if (ident) {
+ if (ident == CSS_VAL__KHTML_TEXT)
+ col = element->getDocument()->textColor();
+ else if (ident == CSS_VAL__KHTML_LINK) {
+ QColor linkColor = element->getDocument()->linkColor();
+ QColor visitedColor = element->getDocument()->visitedLinkColor();
+ if (linkColor == visitedColor)
+ col = linkColor;
+ else {
+ if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
+ checkPseudoState(element);
+ col = (pseudoState == PseudoLink) ? linkColor : visitedColor;
+ }
+ }
+ else if (ident == CSS_VAL__KHTML_ACTIVELINK)
+ col = element->getDocument()->activeLinkColor();
+ else
+ col = colorForCSSValue( ident );
+ } else if ( primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR )
+ col.setRgb(primitiveValue->getRGBColorValue());
+ return col;
}
} // namespace khtml
Index: khtml/css/cssstyleselector.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/cssstyleselector.h,v
retrieving revision 1.20
diff -u -p -r1.20 khtml/css/cssstyleselector.h
--- khtml/css/cssstyleselector.h 2003/11/17 20:38:09 1.20
+++ khtml/css/cssstyleselector.h 2004/02/05 01:40:11
@@ -23,10 +23,12 @@
#ifndef _CSS_cssstyleselector_h_
#define _CSS_cssstyleselector_h_
-#include <qptrlist.h>
+#include <qptrvector.h>
+#include <qptrdict.h>
#include "rendering/render_style.h"
#include "dom/dom_string.h"
+#include "css/css_ruleimpl.h"
class KHTMLSettings;
class KHTMLView;
@@ -38,10 +40,8 @@ namespace DOM {
class NodeImpl;
class ElementImpl;
class StyleSheetImpl;
- class CSSStyleRuleImpl;
class CSSStyleSheetImpl;
class CSSSelector;
- class CSSStyleDeclarationImpl;
class CSSProperty;
class StyleSheetListImpl;
class CSSValueImpl;
@@ -49,28 +49,11 @@ namespace DOM {
namespace khtml
{
- class CSSStyleSelectorList;
- class CSSOrderedRule;
- class CSSOrderedProperty;
- class CSSOrderedPropertyList;
+ class CSSRuleData;
+ class CSSRuleDataList;
+ class CSSRuleSet;
class RenderStyle;
- /*
- * to remember the source where a rule came from. Differntiates between
- * important and not important rules. This is ordered in the order they have to be applied
- * to the RenderStyle.
- */
- enum Source {
- Default = 0,
- NonCSSHint = 1,
- User = 2,
- Author = 3,
- Inline = 4,
- AuthorImportant = 5,
- InlineImportant = 6,
- UserImportant =7
- };
-
/**
* this class selects a RenderStyle for a given Element based on the
* collection of styleshets it contains. This is just a vrtual base class
@@ -107,21 +90,16 @@ namespace khtml
* creates a new StyleSelector for a Document.
* goes through all StyleSheets defined in the document and
* creates a list of rules it needs to apply to objects
- *
- * Also takes into account special cases for HTML documents,
- * including the defaultStyle (which is html only)
*/
- CSSStyleSelector( DOM::DocumentImpl* doc, QString userStyleSheet, DOM::StyleSheetListImpl *styleSheets, const KURL &url,
- bool _strictParsing );
+ CSSStyleSelector(DOM::DocumentImpl* doc, QString userStyleSheet,
+ DOM::StyleSheetListImpl *styleSheets, const KURL &url,
+ bool _strictParsing);
/**
* same as above but for a single stylesheet.
*/
- CSSStyleSelector( DOM::CSSStyleSheetImpl *sheet );
-
+ CSSStyleSelector(DOM::CSSStyleSheetImpl *sheet);
~CSSStyleSelector();
- void addSheet( DOM::CSSStyleSheetImpl *sheet );
-
static void loadDefaultStyle(const KHTMLSettings *s = 0);
static void clear();
@@ -151,12 +129,14 @@ namespace khtml
void setFontSize(FontDef& fontDef, float size);
float getComputedSizeFromSpecifiedSize(bool isAbsoluteSize, float specifiedSize);
+ QColor getColorFromPrimitiveValue(DOM::CSSPrimitiveValueImpl* primitiveValue);
+
protected:
- /* checks if the complete selector (which can be build up from a few CSSSelector's
- with given relationships matches the given Element */
- void checkSelector(int selector, DOM::ElementImpl *e,
- RenderStyle::PseudoId pseudo = RenderStyle::NOPSEUDO);
+ /* checks if a compound selector (which can consist of multiple simple selectors)
+ matches the given Element */
+ bool checkSelector(DOM::CSSSelector* selector, DOM::ElementImpl *e);
+
/* checks if the selector matches the given Element */
bool checkOneSelector(DOM::CSSSelector *selector, DOM::ElementImpl *e);
@@ -164,23 +144,24 @@ namespace khtml
current generic font family has changed. -dwh */
void checkForGenericFamilyChange(RenderStyle* aStyle, RenderStyle* aParentStyle);
- /* builds up the selectors and properties lists from the CSSStyleSelectorList's */
- void buildLists();
- void clearLists();
-
- unsigned int addInlineDeclarations(DOM::ElementImpl* e, DOM::CSSStyleDeclarationImpl *decl,
- unsigned int numProps);
-
void adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e);
+ void matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex);
+ void matchRulesForList(CSSRuleDataList* rules,
+ int& firstRuleIndex, int& lastRuleIndex);
+ void sortMatchedRules(uint firstRuleIndex, uint lastRuleIndex);
+ void addMatchedRule(CSSRuleData* rule);
+ void addMatchedDeclaration(DOM::CSSStyleDeclarationImpl* decl);
+ void applyDeclarations(bool firstPass, bool important, int startIndex, int endIndex);
+
static DOM::CSSStyleSheetImpl *defaultSheet;
static DOM::CSSStyleSheetImpl *quirksSheet;
- static CSSStyleSelectorList *defaultStyle;
- static CSSStyleSelectorList *defaultQuirksStyle;
- static CSSStyleSelectorList *defaultPrintStyle;
- CSSStyleSelectorList *authorStyle;
- CSSStyleSelectorList *userStyle;
- DOM::CSSStyleSheetImpl *userSheet;
+ static CSSRuleSet* defaultStyle;
+ static CSSRuleSet* defaultQuirksStyle;
+ static CSSRuleSet* defaultPrintStyle;
+ CSSRuleSet* m_authorStyle;
+ CSSRuleSet* m_userStyle;
+ DOM::CSSStyleSheetImpl* m_userSheet;
public:
static RenderStyle* styleNotYetAvailable;
@@ -188,52 +169,30 @@ public:
private:
void init();
- public: // we need to make the enum public for SelectorCache
- enum SelectorState {
- Unknown = 0,
- Applies,
- AppliesPseudo,
- Invalid
- };
-
- enum SelectorMedia {
- MediaAural = 1,
- MediaBraille,
- MediaEmboss,
- MediaHandheld,
- MediaPrint,
- MediaProjection,
- MediaScreen,
- MediaTTY,
- MediaTV
- };
protected:
-
- struct SelectorCache {
- SelectorState state;
- unsigned int props_size;
- int *props;
- };
-
- unsigned int selectors_size;
- DOM::CSSSelector **selectors;
- SelectorCache *selectorCache;
- unsigned int properties_size;
- CSSOrderedProperty **properties;
- QMemArray<CSSOrderedProperty> inlineProps;
+ // We collect the set of decls that match in |m_matchedDecls|. We then walk the
+ // set of matched decls four times, once for those properties that others depend on (like font-size),
+ // and then a second time for all the remaining properties. We then do the same two passes
+ // for any !important rules.
+ QMemArray<DOM::CSSStyleDeclarationImpl*> m_matchedDecls;
+ unsigned m_matchedDeclCount;
+
+ // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
+ // merge sorting.
+ QMemArray<CSSRuleData*> m_matchedRules;
+ unsigned m_matchedRuleCount;
+ QMemArray<CSSRuleData*> m_tmpRules;
+ unsigned m_tmpRuleCount;
+
QString m_medium;
- CSSOrderedProperty **propsToApply;
- CSSOrderedProperty **pseudoProps;
- unsigned int propsToApplySize;
- unsigned int pseudoPropsSize;
-
RenderStyle::PseudoId dynamicPseudo;
RenderStyle *style;
RenderStyle *parentStyle;
DOM::ElementImpl *element;
DOM::NodeImpl *parentNode;
+ RenderStyle::PseudoId pseudoStyle;
KHTMLView *view;
KHTMLPart *part;
const KHTMLSettings *settings;
@@ -241,79 +200,69 @@ public:
bool fontDirty;
bool isXMLDoc;
- void applyRule(int id, DOM::CSSValueImpl *value);
+ void applyProperty(int id, DOM::CSSValueImpl *value);
};
- /*
- * List of properties that get applied to the Element. We need to collect them first
- * and then apply them one by one, because we have to change the apply order.
- * Some properties depend on other one already being applied (for example all properties spezifying
- * some length need to have already the correct font size. Same applies to color
- *
- * While sorting them, we have to take care not to mix up the original order.
- */
- class CSSOrderedProperty
- {
+ class CSSRuleData {
public:
- CSSOrderedProperty(DOM::CSSProperty *_prop, uint _selector,
- bool first, Source source, unsigned int specificity,
- unsigned int _position )
- : prop ( _prop ), pseudoId( RenderStyle::NOPSEUDO ), selector( _selector ),
- position( _position )
- {
- priority = (!first << 30) | (source << 24) | specificity;
- }
-
- bool operator < ( const CSSOrderedProperty &other ) const {
- if (priority < other.priority) return true;
- if (priority > other.priority) return false;
- if (position < other.position) return true;
- return false;
- }
-
- DOM::CSSProperty *prop;
- RenderStyle::PseudoId pseudoId;
- unsigned int selector;
- unsigned int position;
+ CSSRuleData(uint pos, DOM::CSSStyleRuleImpl* r, DOM::CSSSelector* sel, CSSRuleData* prev = 0)
+ :m_position(pos), m_rule(r), m_selector(sel), m_next(0) { if (prev) prev->m_next = this; }
+ ~CSSRuleData() { delete m_next; }
- Q_UINT32 priority;
+ uint position() { return m_position; }
+ DOM::CSSStyleRuleImpl* rule() { return m_rule; }
+ DOM::CSSSelector* selector() { return m_selector; }
+ CSSRuleData* next() { return m_next; }
+
+ private:
+ uint m_position;
+ DOM::CSSStyleRuleImpl* m_rule;
+ DOM::CSSSelector* m_selector;
+ CSSRuleData* m_next;
};
- /*
- * This is the list we will collect all properties we need to apply in.
- * It will get sorted once before applying.
- */
- class CSSOrderedPropertyList : public QPtrList<CSSOrderedProperty>
- {
+ class CSSRuleDataList {
public:
- virtual int compareItems(QPtrCollection::Item i1, QPtrCollection::Item i2);
- void append(DOM::CSSStyleDeclarationImpl *decl, uint selector, uint specificity,
- Source regular, Source important );
- };
+ CSSRuleDataList(uint pos, DOM::CSSStyleRuleImpl* rule, DOM::CSSSelector* sel)
+ { m_first = m_last = new CSSRuleData(pos, rule, sel); }
+ ~CSSRuleDataList() { delete m_first; }
- class CSSOrderedRule
+ CSSRuleData* first() { return m_first; }
+ CSSRuleData* last() { return m_last; }
+
+ void append(uint pos, DOM::CSSStyleRuleImpl* rule, DOM::CSSSelector* sel) {
+ m_last = new CSSRuleData(pos, rule, sel, m_last);
+ }
+
+ private:
+ CSSRuleData* m_first;
+ CSSRuleData* m_last;
+ };
+
+ class CSSRuleSet
{
public:
- CSSOrderedRule(DOM::CSSStyleRuleImpl *r, DOM::CSSSelector *s, int _index);
- ~CSSOrderedRule();
+ CSSRuleSet();
+ ~CSSRuleSet() { delete m_universalRules; }
- DOM::CSSSelector *selector;
- DOM::CSSStyleRuleImpl *rule;
- int index;
- };
+ void addRulesFromSheet(DOM::CSSStyleSheetImpl* sheet, const DOM::DOMString &medium = "screen");
- class CSSStyleSelectorList : public QPtrList<CSSOrderedRule>
- {
- public:
- CSSStyleSelectorList();
- virtual ~CSSStyleSelectorList();
+ void addRule(DOM::CSSStyleRuleImpl* rule, DOM::CSSSelector* sel);
+ void addToRuleSet(void* hash, QPtrDict<CSSRuleDataList>& dict,
+ DOM::CSSStyleRuleImpl* rule, DOM::CSSSelector* sel);
- void append( DOM::CSSStyleSheetImpl *sheet,
- const DOM::DOMString &medium = "screen" );
+ CSSRuleDataList* getIDRules(void* hash) { return m_idRules.find(hash); }
+ CSSRuleDataList* getClassRules(void* hash) { return m_classRules.find(hash); }
+ CSSRuleDataList* getTagRules(void* hash) { return m_tagRules.find(hash); }
+ CSSRuleDataList* getUniversalRules() { return m_universalRules; }
- void collect( QPtrList<DOM::CSSSelector> *selectorList, CSSOrderedPropertyList *propList,
- Source regular, Source important );
+ public:
+ QPtrDict<CSSRuleDataList> m_idRules;
+ QPtrDict<CSSRuleDataList> m_classRules;
+ QPtrDict<CSSRuleDataList> m_tagRules;
+ CSSRuleDataList* m_universalRules;
+
+ uint m_ruleCount;
};
-
};
#endif
Index: khtml/css/cssvalues.in
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/cssvalues.in,v
retrieving revision 1.19
diff -u -p -r1.19 khtml/css/cssvalues.in
--- khtml/css/cssvalues.in 2004/01/23 18:55:45 1.19
+++ khtml/css/cssvalues.in 2004/02/05 01:40:11
@@ -120,6 +120,8 @@ teal
white
yellow
transparent
+-khtml-link
+-khtml-activelink
activeborder
activecaption
appworkspace
Index: khtml/css/html4.css
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/html4.css,v
retrieving revision 1.61
diff -u -p -r1.61 khtml/css/html4.css
--- khtml/css/html4.css 2004/01/27 06:27:36 1.61
+++ khtml/css/html4.css 2004/02/05 01:40:11
@@ -419,29 +419,15 @@ SUP {
font-size: smaller;
}
-/* ### not supported at the moment
-ABBR, ACRONYM {
- font-variant: small-caps;
- letter-spacing: 0.1em
-}
-*/
abbr,
acronym {
font-style: italic;
}
-*|:focus { outline: auto 3px #1f5ccf }
-a:link { color: #0000EE; text-decoration: underline; }
-a:link:active { color: red }
-a:visited { color: #551A8B; text-decoration: underline; }
-a:visited:active { color: red }
-
-/* ### :before is now supported, but we haven't tried reinstating this
- ### rule that was comment out long ago.
- BR:before { content: "\n" }
-*/
+:focus { outline: auto 3px #1f5ccf }
+a:-khtml-any-link { color: -khtml-link; text-decoration: underline; }
+a:-khtml-any-link:active { color: -khtml-activelink; }
-
/* Bidirectionality settings (do not change) */
BDO[DIR="ltr"] {
@@ -497,19 +483,3 @@ wbr {
}
/* noscript is handled internally, as it depends on the html settings */
-
-/* media rules are commented out for the moment. We'll have to add
- * them later. Lars, 23.12.99
- */
-
-/*
- @media print {
- @page { margin: 10% }
- H1, H2, H3,
- H4, H5, H6 { page-break-after: avoid; page-break-inside: avoid }
- BLOCKQUOTE,
- PRE { page-break-inside: avoid }
- UL, OL, DL { page-break-before: avoid }
- }
-
-*/
Index: khtml/css/parser.y
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/css/parser.y,v
retrieving revision 1.25
diff -u -p -r1.25 khtml/css/parser.y
--- khtml/css/parser.y 2004/01/27 19:08:34 1.25
+++ khtml/css/parser.y 2004/02/05 01:40:12
@@ -86,7 +86,6 @@ static inline int getValueID(const char
%union {
CSSRuleImpl *rule;
CSSSelector *selector;
- QPtrList<CSSSelector> *selectorList;
bool ok;
MediaListImpl *mediaList;
CSSMediaRuleImpl *mediaRule;
@@ -208,7 +207,7 @@ static int cssyylex( YYSTYPE *yylval ) {
%type <selector> specifier_list
%type <selector> simple_selector
%type <selector> selector
-%type <selectorList> selector_list
+%type <selector> selector_list
%type <selector> class
%type <selector> attrib
%type <selector> pseudo
@@ -493,11 +492,11 @@ ruleset:
#endif
CSSParser *p = static_cast<CSSParser *>(parser);
if ( $1 && $4 && p->numParsedProperties ) {
- CSSStyleRuleImpl *rule = new CSSStyleRuleImpl( p->styleElement );
- CSSStyleDeclarationImpl *decl = p->createStyleDeclaration( rule );
- rule->setSelector( $1 );
- rule->setDeclaration(decl);
- $$ = rule;
+ CSSStyleRuleImpl *rule = new CSSStyleRuleImpl( p->styleElement );
+ CSSStyleDeclarationImpl *decl = p->createStyleDeclaration( rule );
+ rule->setSelector( $1 );
+ rule->setDeclaration(decl);
+ $$ = rule;
} else {
$$ = 0;
delete $1;
@@ -509,13 +508,11 @@ ruleset:
selector_list:
selector {
if ( $1 ) {
- $$ = new QPtrList<CSSSelector>;
- $$->setAutoDelete( true );
+ $$ = $1;
#ifdef CSS_DEBUG
kdDebug( 6080 ) << " got simple selector:" << endl;
$1->print();
#endif
- $$->append( $1 );
} else {
$$ = 0;
}
@@ -646,7 +643,6 @@ element_name:
specifier_list:
specifier {
$$ = $1;
- $$->nonCSSHint = static_cast<CSSParser *>(parser)->nonCSSHint;
}
| specifier_list specifier {
$$ = $1;
@@ -669,6 +665,9 @@ specifier:
$$ = new CSSSelector();
$$->match = CSSSelector::Id;
$$->attr = ATTR_ID;
+ CSSParser *p = static_cast<CSSParser *>(parser);
+ if (!p->strict)
+ $1.lower();
$$->value = atomicString($1);
}
| class
@@ -678,9 +677,12 @@ specifier:
class:
'.' IDENT {
- $$ = new CSSSelector();
+ $$ = new CSSSelector();
$$->match = CSSSelector::Class;
$$->attr = ATTR_CLASS;
+ CSSParser *p = static_cast<CSSParser *>(parser);
+ if (!p->strict)
+ $2.lower();
$$->value = atomicString($2);
}
;
Index: khtml/dom/dom_element.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/dom_element.cpp,v
retrieving revision 1.7
diff -u -p -r1.7 khtml/dom/dom_element.cpp
--- khtml/dom/dom_element.cpp 2004/01/30 07:44:44 1.7
+++ khtml/dom/dom_element.cpp 2004/02/05 01:40:12
@@ -293,7 +293,7 @@ bool Element::isHTMLElement() const
CSSStyleDeclaration Element::style()
{
- if (impl) return ((ElementImpl *)impl)->styleRules();
+ if (impl) return ((ElementImpl *)impl)->getInlineStyleDecl();
return 0;
}
Index: khtml/html/html_baseimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_baseimpl.cpp,v
retrieving revision 1.50
diff -u -p -r1.50 khtml/html/html_baseimpl.cpp
--- khtml/html/html_baseimpl.cpp 2004/01/30 07:44:44 1.50
+++ khtml/html/html_baseimpl.cpp 2004/02/05 01:40:12
@@ -50,14 +50,14 @@ using namespace khtml;
HTMLBodyElementImpl::HTMLBodyElementImpl(DocumentPtr *doc)
: HTMLElementImpl(doc),
- m_bgSet( false ), m_fgSet( false )
+ m_bgSet( false ), m_fgSet( false ), m_linkDecl(0)
{
- m_styleSheet = 0;
}
HTMLBodyElementImpl::~HTMLBodyElementImpl()
{
- if(m_styleSheet) m_styleSheet->deref();
+ if (m_linkDecl)
+ m_linkDecl->deref();
}
NodeImpl::Id HTMLBodyElementImpl::id() const
@@ -65,6 +65,16 @@ NodeImpl::Id HTMLBodyElementImpl::id() c
return ID_BODY;
}
+void HTMLBodyElementImpl::createLinkDecl()
+{
+ m_linkDecl = new CSSStyleDeclarationImpl(0);
+ m_linkDecl->ref();
+ m_linkDecl->setParent(getDocument()->elementSheet());
+ m_linkDecl->parent()->ref();
+ m_linkDecl->setNode(this);
+ m_linkDecl->setStrictParsing(!getDocument()->inCompatMode());
+}
+
void HTMLBodyElementImpl::parseAttribute(AttributeImpl *attr)
{
switch(attr->id())
@@ -111,22 +121,32 @@ void HTMLBodyElementImpl::parseAttribute
case ATTR_ALINK:
case ATTR_LINK:
{
- if(!m_styleSheet) {
- m_styleSheet = new CSSStyleSheetImpl(this,DOMString(),true);
- m_styleSheet->ref();
+ if (attr->isNull()) {
+ if (attr->id() == ATTR_LINK)
+ getDocument()->resetLinkColor();
+ else if (attr->id() == ATTR_VLINK)
+ getDocument()->resetVisitedLinkColor();
+ else
+ getDocument()->resetActiveLinkColor();
+ }
+ else {
+ if (!m_linkDecl)
+ createLinkDecl();
+ m_linkDecl->setProperty(CSS_PROP_COLOR, attr->value(), false, false);
+ CSSValueImpl* val = m_linkDecl->getPropertyCSSValue(CSS_PROP_COLOR);
+ if (val && val->isPrimitiveValue()) {
+ QColor col = getDocument()->styleSelector()->getColorFromPrimitiveValue(static_cast<CSSPrimitiveValueImpl*>(val));
+ if (attr->id() == ATTR_LINK)
+ getDocument()->setLinkColor(col);
+ else if (attr->id() == ATTR_VLINK)
+ getDocument()->setVisitedLinkColor(col);
+ else
+ getDocument()->setActiveLinkColor(col);
+ }
}
- QString aStr;
- if ( attr->id() == ATTR_LINK )
- aStr = "a:link";
- else if ( attr->id() == ATTR_VLINK )
- aStr = "a:visited";
- else if ( attr->id() == ATTR_ALINK )
- aStr = "a:link:active, a:visited:active";
- aStr += " { color: " + attr->value().string() + "; }";
- m_styleSheet->parseString(aStr, !getDocument()->inCompatMode());
- m_styleSheet->setNonCSSHints();
+
if (attached())
- getDocument()->updateStyleSelector();
+ getDocument()->recalcStyle(Force);
break;
}
case ATTR_ONLOAD:
Index: khtml/html/html_baseimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_baseimpl.h,v
retrieving revision 1.18
diff -u -p -r1.18 khtml/html/html_baseimpl.h
--- khtml/html/html_baseimpl.h 2004/01/30 07:44:44 1.18
+++ khtml/html/html_baseimpl.h 2004/02/05 01:40:12
@@ -58,13 +58,13 @@ public:
virtual void parseAttribute(AttributeImpl *);
virtual void insertedIntoDocument();
-
- CSSStyleSheetImpl *sheet() const { return m_styleSheet; }
+ void createLinkDecl();
+
protected:
- CSSStyleSheetImpl *m_styleSheet;
bool m_bgSet;
bool m_fgSet;
+ CSSStyleDeclarationImpl* m_linkDecl;
};
// -------------------------------------------------------------------------
Index: khtml/html/html_elementimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_elementimpl.cpp,v
retrieving revision 1.29
diff -u -p -r1.29 khtml/html/html_elementimpl.cpp
--- khtml/html/html_elementimpl.cpp 2004/01/30 21:00:38 1.29
+++ khtml/html/html_elementimpl.cpp 2004/02/05 01:40:12
@@ -45,6 +45,7 @@
#include "css/css_stylesheetimpl.h"
#include "css/cssproperties.h"
#include "css/cssvalues.h"
+#include "css/css_ruleimpl.h"
#include "xml/dom_textimpl.h"
#include "xml/dom2_eventsimpl.h"
@@ -67,12 +68,16 @@ bool HTMLNamedAttrMapImpl::isHTMLAttribu
return true;
}
-void HTMLNamedAttrMapImpl::parseClassAttribute(const DOMString& classAttr)
+void HTMLNamedAttrMapImpl::parseClassAttribute(const DOMString& classStr)
{
m_classList.clear();
if (!element->hasClass())
return;
+ DOMString classAttr = element->getDocument()->inCompatMode() ?
+ (classStr.implementation()->isLower() ? classStr : DOMString(classStr.implementation()->lower())) :
+ classStr;
+
if (classAttr.find(' ') == -1)
m_classList.setString(AtomicString(classAttr));
else {
@@ -97,30 +102,21 @@ void HTMLNamedAttrMapImpl::parseClassAtt
}
}
-bool HTMLNamedAttrMapImpl::matchesCSSClass(const AtomicString& c, bool caseSensitive) const
-{
- for (const AtomicStringList* curr = &m_classList; curr; curr = curr->next()) {
- if (caseSensitive) {
- if (c == curr->string())
- return true;
- }
- else {
- if (equalsIgnoreCase(c, curr->string()))
- return true;
- }
- }
- return false;
-}
-
// ------------------------------------------------------------------
HTMLElementImpl::HTMLElementImpl(DocumentPtr *doc)
: ElementImpl(doc)
{
+ m_inlineStyleDecl = 0;
+ m_attributeStyleDecl = 0;
}
HTMLElementImpl::~HTMLElementImpl()
{
+ if (m_inlineStyleDecl)
+ m_inlineStyleDecl->deref();
+ if (m_attributeStyleDecl)
+ m_attributeStyleDecl->deref();
}
bool HTMLElementImpl::isInline() const
@@ -165,6 +161,26 @@ bool HTMLElementImpl::isInline() const
}
}
+void HTMLElementImpl::createInlineStyleDecl()
+{
+ m_inlineStyleDecl = new CSSStyleDeclarationImpl(0);
+ m_inlineStyleDecl->ref();
+ m_inlineStyleDecl->setParent(getDocument()->elementSheet());
+ m_inlineStyleDecl->parent()->ref();
+ m_inlineStyleDecl->setNode(this);
+ m_inlineStyleDecl->setStrictParsing(!getDocument()->inCompatMode());
+}
+
+void HTMLElementImpl::createMappedAttributeDecl()
+{
+ m_attributeStyleDecl = new CSSStyleDeclarationImpl(0);
+ m_attributeStyleDecl->ref();
+ m_attributeStyleDecl->setParent(getDocument()->elementSheet());
+ m_attributeStyleDecl->parent()->ref();
+ m_attributeStyleDecl->setNode(this);
+ m_attributeStyleDecl->setStrictParsing(!getDocument()->inCompatMode());
+}
+
void HTMLElementImpl::parseAttribute(AttributeImpl *attr)
{
DOMString indexstring;
@@ -184,6 +200,14 @@ void HTMLElementImpl::parseAttribute(Att
case ATTR_ID:
// unique id
setHasID(!attr->isNull());
+ if (namedAttrMap) {
+ if (attr->isNull())
+ namedAttrMap->setID(nullAtom);
+ else if (getDocument()->inCompatMode() && !attr->value().implementation()->isLower())
+ namedAttrMap->setID(AtomicString(attr->value().implementation()->lower()));
+ else
+ namedAttrMap->setID(attr->value());
+ }
setChanged();
break;
case ATTR_CLASS:
@@ -203,8 +227,8 @@ void HTMLElementImpl::parseAttribute(Att
// ### the inline sheet ay contain more than 1 property!
// stylesheet info
setHasStyle();
- if(!m_styleDecls) createDecl();
- m_styleDecls->setProperty(attr->value());
+ if (!m_inlineStyleDecl) createInlineStyleDecl();
+ m_inlineStyleDecl->setProperty(attr->value());
setChanged();
break;
case ATTR_TABINDEX:
@@ -283,37 +307,54 @@ void HTMLElementImpl::createAttributeMap
namedAttrMap = new HTMLNamedAttrMapImpl(const_cast<HTMLElementImpl*>(this));
namedAttrMap->ref();
}
+
+CSSStyleDeclarationImpl* HTMLElementImpl::inlineStyleDecl() const
+{
+ return m_inlineStyleDecl;
+}
+
+CSSStyleDeclarationImpl* HTMLElementImpl::attributeStyleDecl() const
+{
+ return m_attributeStyleDecl;
+}
+
+CSSStyleDeclarationImpl* HTMLElementImpl::getInlineStyleDecl()
+{
+ if (!m_inlineStyleDecl)
+ createInlineStyleDecl();
+ return m_inlineStyleDecl;
+}
-bool HTMLElementImpl::matchesCSSClass(const AtomicString& c, bool cs) const
+const AtomicStringList* HTMLElementImpl::getClassList() const
{
- return namedAttrMap ? static_cast<HTMLNamedAttrMapImpl*>(namedAttrMap)->matchesCSSClass(c, cs) : false;
+ return namedAttrMap ? static_cast<HTMLNamedAttrMapImpl*>(namedAttrMap)->getClassList() : 0;
}
void HTMLElementImpl::addCSSProperty(int id, const DOMString &value)
{
- if(!m_styleDecls) createDecl();
- m_styleDecls->setProperty(id, value, false, true);
+ if (!m_attributeStyleDecl) createMappedAttributeDecl();
+ m_attributeStyleDecl->setProperty(id, value, false);
setChanged();
}
void HTMLElementImpl::addCSSProperty(int id, int value)
{
- if(!m_styleDecls) createDecl();
- m_styleDecls->setProperty(id, value, false, true);
+ if (!m_attributeStyleDecl) createMappedAttributeDecl();
+ m_attributeStyleDecl->setProperty(id, value, false);
setChanged();
}
void HTMLElementImpl::addCSSStringProperty(int id, const DOMString &value, CSSPrimitiveValue::UnitTypes type)
{
- if(!m_styleDecls) createDecl();
- m_styleDecls->setStringProperty(id, value, type, false, true);
+ if (!m_attributeStyleDecl) createMappedAttributeDecl();
+ m_attributeStyleDecl->setStringProperty(id, value, type, false);
setChanged();
}
void HTMLElementImpl::addCSSImageProperty(int id, const DOMString &URL)
{
- if(!m_styleDecls) createDecl();
- m_styleDecls->setImageProperty(id, URL, false, true);
+ if (!m_attributeStyleDecl) createMappedAttributeDecl();
+ m_attributeStyleDecl->setImageProperty(id, URL, false);
setChanged();
}
@@ -321,7 +362,7 @@ void HTMLElementImpl::addCSSLength(int i
{
// FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct
// length unit and make the appropriate parsed value.
- if(!m_styleDecls) createDecl();
+ if (!m_attributeStyleDecl) createMappedAttributeDecl();
// strip attribute garbage..
DOMStringImpl* v = value.implementation();
@@ -336,13 +377,13 @@ void HTMLElementImpl::addCSSLength(int i
break;
}
if ( l != v->l ) {
- m_styleDecls->setLengthProperty( id, DOMString( v->s, l ), false, true );
+ m_attributeStyleDecl->setLengthProperty(id, DOMString( v->s, l ), false);
setChanged();
return;
}
}
- m_styleDecls->setLengthProperty(id, value, false, true);
+ m_attributeStyleDecl->setLengthProperty(id, value, false);
setChanged();
}
@@ -365,13 +406,13 @@ static inline int toHex( const QChar &c
/* color parsing that tries to match as close as possible IE 6. */
void HTMLElementImpl::addHTMLColor( int id, const DOMString &c )
{
- if(!m_styleDecls) createDecl();
+ if (!m_attributeStyleDecl) createMappedAttributeDecl();
// this is the only case no color gets applied in IE.
if ( !c.length() )
return;
- if ( m_styleDecls->setProperty(id, c, false, true) )
+ if ( m_attributeStyleDecl->setProperty(id, c, false) )
return;
QString color = c.string();
@@ -434,21 +475,21 @@ void HTMLElementImpl::addHTMLColor( int
color.sprintf("#%02x%02x%02x", colors[0], colors[1], colors[2] );
// qDebug( "trying to add fixed color string '%s'", color.latin1() );
- if ( m_styleDecls->setProperty(id, DOMString(color), false, true) )
+ if ( m_attributeStyleDecl->setProperty(id, DOMString(color), false) )
return;
}
}
- m_styleDecls->setProperty(id, CSS_VAL_BLACK, false, true);
+ m_attributeStyleDecl->setProperty(id, CSS_VAL_BLACK, false);
}
void HTMLElementImpl::removeCSSProperty(int id)
{
- if(!m_styleDecls)
+ if(!m_attributeStyleDecl)
return;
- m_styleDecls->parent()->deref();
- m_styleDecls->setParent(getDocument()->elementSheet());
- m_styleDecls->parent()->ref();
- m_styleDecls->removeProperty(id);
+ m_attributeStyleDecl->parent()->deref();
+ m_attributeStyleDecl->setParent(getDocument()->elementSheet());
+ m_attributeStyleDecl->parent()->ref();
+ m_attributeStyleDecl->removeProperty(id);
setChanged();
}
Index: khtml/html/html_elementimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_elementimpl.h,v
retrieving revision 1.16
diff -u -p -r1.16 khtml/html/html_elementimpl.h
--- khtml/html/html_elementimpl.h 2004/01/30 07:44:44 1.16
+++ khtml/html/html_elementimpl.h 2004/02/05 01:40:12
@@ -43,7 +43,7 @@ public:
virtual bool isHTMLAttributeMap() const;
virtual void parseClassAttribute(const DOMString& classAttr);
- bool matchesCSSClass(const AtomicString& c, bool caseSensitive) const;
+ const AtomicStringList* getClassList() const { return &m_classList; }
private:
AtomicStringList m_classList;
@@ -65,7 +65,7 @@ public:
virtual void parseAttribute(AttributeImpl *token);
virtual void createAttributeMap() const;
- virtual bool matchesCSSClass(const AtomicString& c, bool caseSensitive) const;
+ virtual const AtomicStringList* getClassList() const;
void addCSSLength(int id, const DOMString &value); // FIXME: value will be parsed by the CSS parser
void addCSSProperty(int id, const DOMString &value); // value will be parsed by the CSS parser
@@ -90,6 +90,12 @@ public:
virtual void click();
+ virtual CSSStyleDeclarationImpl* inlineStyleDecl() const;
+ virtual CSSStyleDeclarationImpl* attributeStyleDecl() const;
+ virtual CSSStyleDeclarationImpl* getInlineStyleDecl();
+ void createInlineStyleDecl();
+ void createMappedAttributeDecl();
+
#if APPLE_CHANGES
virtual bool isGenericFormElement() const { return false; }
#endif
@@ -99,6 +105,9 @@ public:
protected:
// for IMG, OBJECT and APPLET
void addHTMLAlignment( const DOMString& alignment );
+
+ CSSStyleDeclarationImpl* m_inlineStyleDecl;
+ CSSStyleDeclarationImpl* m_attributeStyleDecl;
};
class HTMLGenericElementImpl : public HTMLElementImpl
Index: khtml/html/html_tableimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_tableimpl.cpp,v
retrieving revision 1.36
diff -u -p -r1.36 khtml/html/html_tableimpl.cpp
--- khtml/html/html_tableimpl.cpp 2004/01/30 07:44:44 1.36
+++ khtml/html/html_tableimpl.cpp 2004/02/05 01:40:12
@@ -94,15 +94,15 @@ DOM::CSSStyleDeclarationImpl* HTMLTableE
m_sharedCellDecls->setStrictParsing( !getDocument()->inCompatMode() );
if (m_noBorder)
- m_sharedCellDecls->setProperty(CSS_PROP_BORDER_WIDTH, "0", false, true);
+ m_sharedCellDecls->setProperty(CSS_PROP_BORDER_WIDTH, "0", false);
else {
- m_sharedCellDecls->setProperty(CSS_PROP_BORDER_WIDTH, "1px", false, true);
+ m_sharedCellDecls->setProperty(CSS_PROP_BORDER_WIDTH, "1px", false);
int v = m_solid ? CSS_VAL_SOLID : CSS_VAL_INSET;
- m_sharedCellDecls->setProperty(CSS_PROP_BORDER_TOP_STYLE, v, false, true);
- m_sharedCellDecls->setProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v, false, true);
- m_sharedCellDecls->setProperty(CSS_PROP_BORDER_LEFT_STYLE, v, false, true);
- m_sharedCellDecls->setProperty(CSS_PROP_BORDER_RIGHT_STYLE, v, false, true);
- m_sharedCellDecls->setProperty(CSS_PROP_BORDER_COLOR, "inherit", false, true);
+ m_sharedCellDecls->setProperty(CSS_PROP_BORDER_TOP_STYLE, v, false);
+ m_sharedCellDecls->setProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v, false);
+ m_sharedCellDecls->setProperty(CSS_PROP_BORDER_LEFT_STYLE, v, false);
+ m_sharedCellDecls->setProperty(CSS_PROP_BORDER_RIGHT_STYLE, v, false);
+ m_sharedCellDecls->setProperty(CSS_PROP_BORDER_COLOR, "inherit", false);
}
}
@@ -890,7 +890,7 @@ void HTMLTableCellElementImpl::parseAttr
}
// used by table cells to share style decls created by the enclosing table.
-DOM::CSSStyleDeclarationImpl* HTMLTableCellElementImpl::getAdditionalStyleDecls()
+CSSStyleDeclarationImpl* HTMLTableCellElementImpl::additionalAttributeStyleDecl()
{
HTMLElementImpl* p = static_cast<HTMLElementImpl*>(parentNode());
while(p && p->id() != ID_TABLE)
Index: khtml/html/html_tableimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_tableimpl.h,v
retrieving revision 1.12
diff -u -p -r1.12 khtml/html/html_tableimpl.h
--- khtml/html/html_tableimpl.h 2003/02/17 20:25:57 1.12
+++ khtml/html/html_tableimpl.h 2004/02/05 01:40:12
@@ -203,7 +203,7 @@ public:
virtual void attach();
// used by table cells to share style decls created by the enclosing table.
- virtual DOM::CSSStyleDeclarationImpl* getAdditionalStyleDecls();
+ virtual CSSStyleDeclarationImpl* additionalAttributeStyleDecl();
protected:
int _row;
Index: khtml/xml/dom_atomicstring.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_atomicstring.cpp,v
retrieving revision 1.2
diff -u -p -r1.2 khtml/xml/dom_atomicstring.cpp
--- khtml/xml/dom_atomicstring.cpp 2004/02/02 18:42:37 1.2
+++ khtml/xml/dom_atomicstring.cpp 2004/02/05 01:40:12
@@ -134,6 +134,7 @@ DOMStringImpl *AtomicString::add(const c
DOMStringImpl *r = new DOMStringImpl(c, length);
r->_hash = hash;
+ r->_inTable = true;
_table[i] = r;
++_keyCount;
@@ -170,6 +171,7 @@ DOMStringImpl *AtomicString::add(const Q
DOMStringImpl *r = new DOMStringImpl(s, length);
r->_hash = hash;
+ r->_inTable = true;
_table[i] = r;
++_keyCount;
@@ -182,8 +184,8 @@ DOMStringImpl *AtomicString::add(const Q
DOMStringImpl *AtomicString::add(DOMStringImpl *r)
{
- if (!r)
- return 0;
+ if (!r || r->_inTable)
+ return r;
if (r->l == 0)
return DOMStringImpl::empty();
@@ -199,11 +201,13 @@ DOMStringImpl *AtomicString::add(DOMStri
numCollisions += _table[i] && !equal(_table[i], r);
#endif
while (DOMStringImpl *key = _table[i]) {
- if (equal(key, r))
+ if (equal(key, r)) {
return key;
+ }
i = (i + 1) & _tableSizeMask;
}
+ r->_inTable = true;
_table[i] = r;
++_keyCount;
@@ -230,7 +234,7 @@ inline void AtomicString::insert(DOMStri
void AtomicString::remove(DOMStringImpl *r)
{
- unsigned hash = r->hash();
+ unsigned hash = r->_hash;
DOMStringImpl *key;
@@ -240,7 +244,7 @@ void AtomicString::remove(DOMStringImpl
numCollisions += _table[i] && equal(_table[i], r);
#endif
while ((key = _table[i])) {
- if (equal(key, r))
+ if (key == r)
break;
i = (i + 1) & _tableSizeMask;
}
Index: khtml/xml/dom_docimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_docimpl.cpp,v
retrieving revision 1.109
diff -u -p -r1.109 khtml/xml/dom_docimpl.cpp
--- khtml/xml/dom_docimpl.cpp 2004/02/02 17:47:30 1.109
+++ khtml/xml/dom_docimpl.cpp 2004/02/05 01:40:12
@@ -315,6 +315,10 @@ DocumentImpl::DocumentImpl(DOMImplementa
m_cssTarget = 0;
m_accessKeyDictValid = false;
+ resetLinkColor();
+ resetVisitedLinkColor();
+ resetActiveLinkColor();
+
m_processingLoadEvent = false;
m_startTime.restart();
}
@@ -383,7 +387,21 @@ DocumentImpl::~DocumentImpl()
}
}
+void DocumentImpl::resetLinkColor()
+{
+ m_linkColor = QColor(0, 0, 238);
+}
+
+void DocumentImpl::resetVisitedLinkColor()
+{
+ m_visitedLinkColor = QColor(85, 26, 139);
+}
+void DocumentImpl::resetActiveLinkColor()
+{
+ m_activeLinkColor.setNamedColor(QString("red"));
+}
+
DocumentTypeImpl *DocumentImpl::doctype() const
{
return m_doctype;
@@ -2201,12 +2219,7 @@ void DocumentImpl::recalcStyleSelector()
sheet = 0;
}
}
- else if (n->isHTMLElement() && n->id() == ID_BODY) {
- // <BODY> element (doesn't contain styles as such but vlink="..." and friends
- // are treated as style declarations)
- sheet = static_cast<HTMLBodyElementImpl*>(n)->sheet();
- }
-
+
if (sheet) {
sheet->ref();
m_styleSheets->styleSheets.append(sheet);
Index: khtml/xml/dom_docimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_docimpl.h,v
retrieving revision 1.53
diff -u -p -r1.53 khtml/xml/dom_docimpl.h
--- khtml/xml/dom_docimpl.h 2004/01/30 07:44:44 1.53
+++ khtml/xml/dom_docimpl.h 2004/02/05 01:40:12
@@ -61,7 +61,6 @@ class KWQAccObjectCache;
namespace khtml {
class CSSStyleSelector;
class DocLoader;
- class CSSStyleSelectorList;
class RenderImage;
class EditCommand;
}
@@ -340,6 +339,16 @@ public:
void setTextColor( QColor color ) { m_textColor = color; }
QColor textColor() const { return m_textColor; }
+ const QColor& linkColor() const { return m_linkColor; }
+ const QColor& visitedLinkColor() const { return m_visitedLinkColor; }
+ const QColor& activeLinkColor() const { return m_activeLinkColor; }
+ void setLinkColor(const QColor& c) { m_linkColor = c; }
+ void setVisitedLinkColor(const QColor& c) { m_visitedLinkColor = c; }
+ void setActiveLinkColor(const QColor& c) { m_activeLinkColor = c; }
+ void resetLinkColor();
+ void resetVisitedLinkColor();
+ void resetActiveLinkColor();
+
// internal
NodeImpl *findElement( Id id );
@@ -558,6 +567,10 @@ protected:
LocalStyleRefs m_localStyleRefs; // references to inlined style elements
QPtrList<RegisteredEventListener> m_windowEventListeners;
QPtrList<NodeImpl> m_maintainsState;
+
+ QColor m_linkColor;
+ QColor m_visitedLinkColor;
+ QColor m_activeLinkColor;
DOMString m_preferredStylesheetSet;
Index: khtml/xml/dom_elementimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_elementimpl.cpp,v
retrieving revision 1.34
diff -u -p -r1.34 khtml/xml/dom_elementimpl.cpp
--- khtml/xml/dom_elementimpl.cpp 2004/01/30 07:44:44 1.34
+++ khtml/xml/dom_elementimpl.cpp 2004/02/05 01:40:12
@@ -186,24 +186,16 @@ ElementImpl::ElementImpl(DocumentPtr *do
: NodeBaseImpl(doc)
{
namedAttrMap = 0;
- m_styleDecls = 0;
m_prefix = 0;
}
ElementImpl::~ElementImpl()
{
- if(namedAttrMap) {
+ if (namedAttrMap) {
namedAttrMap->detachFromElement();
namedAttrMap->deref();
}
- if (m_styleDecls) {
- m_styleDecls->setNode(0);
- m_styleDecls->parent()->deref();
- m_styleDecls->setParent(0);
- m_styleDecls->deref();
- }
-
if (m_prefix)
m_prefix->deref();
}
@@ -228,14 +220,37 @@ unsigned short ElementImpl::nodeType() c
{
return Node::ELEMENT_NODE;
}
+
+CSSStyleDeclarationImpl* ElementImpl::inlineStyleDecl() const
+{
+ return 0;
+}
+
+CSSStyleDeclarationImpl* ElementImpl::attributeStyleDecl() const
+{
+ return 0;
+}
+
+CSSStyleDeclarationImpl* ElementImpl::getInlineStyleDecl()
+{
+ return 0;
+}
-bool ElementImpl::matchesCSSClass(const AtomicString& c, bool caseSensitive) const
+CSSStyleDeclarationImpl* ElementImpl::additionalAttributeStyleDecl()
{
- // Class is not supported on random XML elements. A language (e.g., HTML, SVG) should indicate
- // support using a subclass override.
- return false;
+ return 0;
}
+const AtomicStringList* ElementImpl::getClassList() const
+{
+ return 0;
+}
+
+const AtomicString& ElementImpl::getIDAttribute() const
+{
+ return namedAttrMap ? namedAttrMap->id() : nullAtom;
+}
+
const AtomicString& ElementImpl::getAttribute(NodeImpl::Id id) const
{
if (namedAttrMap) {
@@ -313,13 +328,9 @@ NodeImpl *ElementImpl::cloneNode(bool de
if (!clone) return 0;
// clone attributes
- if(namedAttrMap)
+ if (namedAttrMap)
*(static_cast<NamedAttrMapImpl*>(clone->attributes())) = *namedAttrMap;
- // clone individual style rules
- if (m_styleDecls)
- *(clone->styleRules()) = *m_styleDecls;
-
if (deep)
cloneChildNodes(clone);
return clone;
@@ -542,16 +553,6 @@ bool ElementImpl::childTypeAllowed( unsi
}
}
-void ElementImpl::createDecl( )
-{
- m_styleDecls = new CSSStyleDeclarationImpl(0);
- m_styleDecls->ref();
- m_styleDecls->setParent(getDocument()->elementSheet());
- m_styleDecls->parent()->ref();
- m_styleDecls->setNode(this);
- m_styleDecls->setStrictParsing( !getDocument()->inCompatMode() );
-}
-
void ElementImpl::dispatchAttrRemovalEvent(AttributeImpl *attr)
{
if (!getDocument()->hasListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER))
@@ -708,10 +709,6 @@ NodeImpl *XMLElementImpl::cloneNode ( bo
// clone attributes
if(namedAttrMap)
*(static_cast<NamedAttrMapImpl*>(clone->attributes())) = *namedAttrMap;
-
- // clone individual style rules
- if (m_styleDecls)
- *(clone->styleRules()) = *m_styleDecls;
if (deep)
cloneChildNodes(clone);
Index: khtml/xml/dom_elementimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_elementimpl.h,v
retrieving revision 1.21
diff -u -p -r1.21 khtml/xml/dom_elementimpl.h
--- khtml/xml/dom_elementimpl.h 2004/01/30 07:44:44 1.21
+++ khtml/xml/dom_elementimpl.h 2004/02/05 01:40:12
@@ -46,6 +46,7 @@ namespace DOM {
class ElementImpl;
class DocumentImpl;
class NamedAttrMapImpl;
+class AtomicStringList;
// this has no counterpart in DOM, purely internal
// representation of the nodevalue of an Attr.
@@ -154,8 +155,8 @@ public:
~ElementImpl();
// Used to quickly determine whether or not an element has a given CSS class.
- virtual bool matchesCSSClass(const AtomicString& c, bool caseSensitive) const;
-
+ virtual const AtomicStringList* getClassList() const;
+ const AtomicString& getIDAttribute() const;
const AtomicString& getAttribute( NodeImpl::Id id ) const;
const AtomicString& getAttribute(const DOMString& localName) const { return getAttributeNS(QString::null, localName); }
const AtomicString& getAttributeNS(const DOMString &namespaceURI,
@@ -201,12 +202,12 @@ public:
virtual bool childAllowed( NodeImpl *newChild );
virtual bool childTypeAllowed( unsigned short type );
- DOM::CSSStyleDeclarationImpl *styleRules() {
- if (!m_styleDecls) createDecl();
- return m_styleDecls;
- }
+ virtual CSSStyleDeclarationImpl* inlineStyleDecl() const;
+ virtual CSSStyleDeclarationImpl* attributeStyleDecl() const;
+ virtual CSSStyleDeclarationImpl* getInlineStyleDecl();
+
// used by table cells to share style decls created by the enclosing table.
- virtual DOM::CSSStyleDeclarationImpl* getAdditionalStyleDecls() { return 0; }
+ virtual CSSStyleDeclarationImpl* additionalAttributeStyleDecl();
void dispatchAttrRemovalEvent(AttributeImpl *attr);
void dispatchAttrAdditionEvent(AttributeImpl *attr);
@@ -226,7 +227,6 @@ public:
#endif
protected:
virtual void createAttributeMap() const;
- void createDecl();
DOMString openTagStartToString() const;
private:
@@ -234,8 +234,6 @@ private:
protected: // member variables
mutable NamedAttrMapImpl *namedAttrMap;
-
- DOM::CSSStyleDeclarationImpl *m_styleDecls;
DOMStringImpl *m_prefix;
};
@@ -296,6 +294,9 @@ public:
virtual bool isHTMLAttributeMap() const;
+ const AtomicString& id() const { return m_id; }
+ void setID(const AtomicString& _id) { m_id = _id; }
+
private:
// this method is internal, does no error checking at all
void addAttribute(AttributeImpl* newAttribute);
@@ -308,6 +309,7 @@ protected:
ElementImpl *element;
AttributeImpl **attrs;
uint len;
+ AtomicString m_id;
};
}; //namespace
Index: khtml/xml/dom_stringimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_stringimpl.cpp,v
retrieving revision 1.20
diff -u -p -r1.20 khtml/xml/dom_stringimpl.cpp
--- khtml/xml/dom_stringimpl.cpp 2004/01/30 07:44:44 1.20
+++ khtml/xml/dom_stringimpl.cpp 2004/02/05 01:40:12
@@ -44,6 +44,7 @@ DOMStringImpl* DOMStringImpl::empty()
DOMStringImpl::DOMStringImpl(const QChar *str, unsigned int len) {
_hash = 0;
+ _inTable = false;
bool havestr = str && len;
s = QT_ALLOC_QCHAR_VEC( havestr ? len : 1 );
if(str && len) {
@@ -59,6 +60,7 @@ DOMStringImpl::DOMStringImpl(const QChar
DOMStringImpl::DOMStringImpl(const char *str)
{
_hash = 0;
+ _inTable = false;
if(str && *str)
{
l = strlen(str);
@@ -79,6 +81,7 @@ DOMStringImpl::DOMStringImpl(const char
DOMStringImpl::DOMStringImpl(const char *str, unsigned int len)
{
_hash = 0;
+ _inTable = false;
l = len;
if (!l || !str)
return;
@@ -92,6 +95,7 @@ DOMStringImpl::DOMStringImpl(const char
DOMStringImpl::DOMStringImpl(const QChar &ch) {
_hash = 0;
+ _inTable = false;
s = QT_ALLOC_QCHAR_VEC( 1 );
s[0] = ch;
l = 1;
@@ -99,13 +103,15 @@ DOMStringImpl::DOMStringImpl(const QChar
DOMStringImpl::~DOMStringImpl()
{
- if (_hash) AtomicString::remove(this);
- if(s) QT_DELETE_QCHAR_VEC(s);
+ if (_inTable)
+ AtomicString::remove(this);
+ if (s)
+ QT_DELETE_QCHAR_VEC(s);
}
void DOMStringImpl::append(DOMStringImpl *str)
{
- assert(_hash == 0);
+ assert(!_inTable);
if(str && str->l != 0)
{
int newlen = l+str->l;
@@ -120,7 +126,7 @@ void DOMStringImpl::append(DOMStringImpl
void DOMStringImpl::insert(DOMStringImpl *str, uint pos)
{
- assert(_hash == 0);
+ assert(!_inTable);
if(pos > l)
{
append(str);
@@ -141,7 +147,7 @@ void DOMStringImpl::insert(DOMStringImpl
void DOMStringImpl::truncate(int len)
{
- assert(_hash == 0);
+ assert(!_inTable);
if(len > (int)l) return;
int nl = len < 1 ? 1 : len;
@@ -154,7 +160,7 @@ void DOMStringImpl::truncate(int len)
void DOMStringImpl::remove(uint pos, int len)
{
- assert(_hash == 0);
+ assert(!_inTable);
if(len <= 0) return;
if(pos >= l ) return;
if((unsigned)len > l - pos)
@@ -171,7 +177,7 @@ void DOMStringImpl::remove(uint pos, int
DOMStringImpl *DOMStringImpl::split(uint pos)
{
- assert(_hash == 0);
+ assert(!_inTable);
if( pos >=l ) return new DOMStringImpl();
uint newLen = l-pos;
Index: khtml/xml/dom_stringimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_stringimpl.h,v
retrieving revision 1.8
diff -u -p -r1.8 khtml/xml/dom_stringimpl.h
--- khtml/xml/dom_stringimpl.h 2004/01/28 21:19:39 1.8
+++ khtml/xml/dom_stringimpl.h 2004/02/05 01:40:12
@@ -37,10 +37,10 @@ class DOMStringImpl : public khtml::Shar
{
private:
struct WithOneRef { };
- DOMStringImpl(WithOneRef) { s = 0; l = 0; _hash = 0; ref(); }
+ DOMStringImpl(WithOneRef) { s = 0; l = 0; _hash = 0; _inTable = false; ref(); }
protected:
- DOMStringImpl() { s = 0, l = 0; _hash = 0; }
+ DOMStringImpl() { s = 0, l = 0; _hash = 0; _inTable = false; }
public:
DOMStringImpl(const QChar *str, unsigned int len);
DOMStringImpl(const char *str);
@@ -87,6 +87,7 @@ public:
unsigned int l;
QChar *s;
mutable unsigned _hash;
+ bool _inTable;
};
};
-------------- next part --------------
More information about the Khtml-devel
mailing list