[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

hyatt hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:37:43 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 026e5b0f0cad1f22635c3d1bc197fed9465dbf11
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Apr 29 01:19:04 2004 +0000

    	Implement sharing of similar style objects. Cuts the # of style objects allocated on the PLT by more
    	than half.
    
            Reviewed by kocienda
    
            * khtml/css/cssstyleselector.cpp:
            (khtml::CSSStyleSelector::initElementAndPseudoState):
            (khtml::CSSStyleSelector::initForStyleResolve):
            (khtml::cleanpath):
            (khtml::checkPseudoState):
            (khtml::CSSStyleSelector::locateSiblingList):
            (khtml::CSSStyleSelector::canShareStyleWithElement):
            (khtml::CSSStyleSelector::locateSharedStyle):
            (khtml::CSSStyleSelector::styleForElement):
            (khtml::CSSStyleSelector::pseudoStyleForElement):
            (khtml::CSSStyleSelector::checkOneSelector):
            * khtml/css/cssstyleselector.h:
            * khtml/css/html4.css:
            * khtml/css/parser.cpp:
            * khtml/css/parser.y:
            * khtml/html/html_baseimpl.cpp:
            (HTMLBodyElementImpl::mapToEntry):
            (HTMLIFrameElementImpl::mapToEntry):
            * khtml/html/html_baseimpl.h:
            * khtml/html/html_blockimpl.cpp:
            (HTMLDivElementImpl::mapToEntry):
            (HTMLHRElementImpl::mapToEntry):
            (HTMLParagraphElementImpl::mapToEntry):
            (HTMLMarqueeElementImpl::mapToEntry):
            * khtml/html/html_blockimpl.h:
            * khtml/html/html_elementimpl.cpp:
            (HTMLNamedAttrMapImpl::declCount):
            (HTMLNamedAttrMapImpl::mapsEquivalent):
            (HTMLElementImpl::attributeChanged):
            (HTMLElementImpl::mapToEntry):
            * khtml/html/html_elementimpl.h:
            (DOM::HTMLElementImpl::isMappedAttribute):
            * khtml/html/html_formimpl.cpp:
            (HTMLInputElementImpl::mapToEntry):
            * khtml/html/html_formimpl.h:
            * khtml/html/html_imageimpl.cpp:
            (HTMLImageElementImpl::mapToEntry):
            * khtml/html/html_imageimpl.h:
            * khtml/html/html_inlineimpl.cpp:
            (HTMLBRElementImpl::mapToEntry):
            (HTMLFontElementImpl::mapToEntry):
            * khtml/html/html_inlineimpl.h:
            * khtml/html/html_listimpl.cpp:
            (HTMLUListElementImpl::mapToEntry):
            (HTMLOListElementImpl::mapToEntry):
            (HTMLLIElementImpl::mapToEntry):
            * khtml/html/html_listimpl.h:
            * khtml/html/html_objectimpl.cpp:
            (HTMLAppletElementImpl::mapToEntry):
            (HTMLEmbedElementImpl::mapToEntry):
            (HTMLObjectElementImpl::mapToEntry):
            * khtml/html/html_objectimpl.h:
            * khtml/html/html_tableimpl.cpp:
            (HTMLTableElementImpl::mapToEntry):
            (HTMLTablePartElementImpl::mapToEntry):
            (HTMLTableCellElementImpl::mapToEntry):
            (HTMLTableColElementImpl::mapToEntry):
            (HTMLTableCaptionElementImpl::mapToEntry):
            * khtml/html/html_tableimpl.h:
            * khtml/rendering/render_object.cpp:
            (RenderObject::setStyle):
            * khtml/rendering/render_style.cpp:
            (m_affectedByAttributeSelectors):
            (RenderStyle::RenderStyle):
            * khtml/rendering/render_style.h:
            (khtml::):
            (khtml::RenderStyle::pseudoState):
            (khtml::RenderStyle::setPseudoState):
            (khtml::RenderStyle::affectedByAttributeSelectors):
            (khtml::RenderStyle::setAffectedByAttributeSelectors):
            * khtml/xml/dom_docimpl.cpp:
            (DocumentImpl::DocumentImpl):
            * khtml/xml/dom_docimpl.h:
            (DOM::DocumentImpl::usesSiblingRules):
            (DOM::DocumentImpl::setUsesSiblingRules):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6514 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index f01dbfe..1b4c058 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,86 @@
+2004-04-27  David Hyatt  <hyatt at apple.com>
+
+	Implement sharing of similar style objects. Cuts the # of style objects allocated on the PLT by more
+	than half.
+	
+        Reviewed by kocienda
+
+        * khtml/css/cssstyleselector.cpp:
+        (khtml::CSSStyleSelector::initElementAndPseudoState):
+        (khtml::CSSStyleSelector::initForStyleResolve):
+        (khtml::cleanpath):
+        (khtml::checkPseudoState):
+        (khtml::CSSStyleSelector::locateSiblingList):
+        (khtml::CSSStyleSelector::canShareStyleWithElement):
+        (khtml::CSSStyleSelector::locateSharedStyle):
+        (khtml::CSSStyleSelector::styleForElement):
+        (khtml::CSSStyleSelector::pseudoStyleForElement):
+        (khtml::CSSStyleSelector::checkOneSelector):
+        * khtml/css/cssstyleselector.h:
+        * khtml/css/html4.css:
+        * khtml/css/parser.cpp:
+        * khtml/css/parser.y:
+        * khtml/html/html_baseimpl.cpp:
+        (HTMLBodyElementImpl::mapToEntry):
+        (HTMLIFrameElementImpl::mapToEntry):
+        * khtml/html/html_baseimpl.h:
+        * khtml/html/html_blockimpl.cpp:
+        (HTMLDivElementImpl::mapToEntry):
+        (HTMLHRElementImpl::mapToEntry):
+        (HTMLParagraphElementImpl::mapToEntry):
+        (HTMLMarqueeElementImpl::mapToEntry):
+        * khtml/html/html_blockimpl.h:
+        * khtml/html/html_elementimpl.cpp:
+        (HTMLNamedAttrMapImpl::declCount):
+        (HTMLNamedAttrMapImpl::mapsEquivalent):
+        (HTMLElementImpl::attributeChanged):
+        (HTMLElementImpl::mapToEntry):
+        * khtml/html/html_elementimpl.h:
+        (DOM::HTMLElementImpl::isMappedAttribute):
+        * khtml/html/html_formimpl.cpp:
+        (HTMLInputElementImpl::mapToEntry):
+        * khtml/html/html_formimpl.h:
+        * khtml/html/html_imageimpl.cpp:
+        (HTMLImageElementImpl::mapToEntry):
+        * khtml/html/html_imageimpl.h:
+        * khtml/html/html_inlineimpl.cpp:
+        (HTMLBRElementImpl::mapToEntry):
+        (HTMLFontElementImpl::mapToEntry):
+        * khtml/html/html_inlineimpl.h:
+        * khtml/html/html_listimpl.cpp:
+        (HTMLUListElementImpl::mapToEntry):
+        (HTMLOListElementImpl::mapToEntry):
+        (HTMLLIElementImpl::mapToEntry):
+        * khtml/html/html_listimpl.h:
+        * khtml/html/html_objectimpl.cpp:
+        (HTMLAppletElementImpl::mapToEntry):
+        (HTMLEmbedElementImpl::mapToEntry):
+        (HTMLObjectElementImpl::mapToEntry):
+        * khtml/html/html_objectimpl.h:
+        * khtml/html/html_tableimpl.cpp:
+        (HTMLTableElementImpl::mapToEntry):
+        (HTMLTablePartElementImpl::mapToEntry):
+        (HTMLTableCellElementImpl::mapToEntry):
+        (HTMLTableColElementImpl::mapToEntry):
+        (HTMLTableCaptionElementImpl::mapToEntry):
+        * khtml/html/html_tableimpl.h:
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::setStyle):
+        * khtml/rendering/render_style.cpp:
+        (m_affectedByAttributeSelectors):
+        (RenderStyle::RenderStyle):
+        * khtml/rendering/render_style.h:
+        (khtml::):
+        (khtml::RenderStyle::pseudoState):
+        (khtml::RenderStyle::setPseudoState):
+        (khtml::RenderStyle::affectedByAttributeSelectors):
+        (khtml::RenderStyle::setAffectedByAttributeSelectors):
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::DocumentImpl):
+        * khtml/xml/dom_docimpl.h:
+        (DOM::DocumentImpl::usesSiblingRules):
+        (DOM::DocumentImpl::setUsesSiblingRules):
+
 2004-04-28  Darin Adler  <darin at apple.com>
 
         Reviewed by Chris.
@@ -140,7 +223,6 @@
 
 	<rdar://problem/3564519>: API: please add a way to set the media type for a WebView
 
-
         Reviewed by Chris.
 
         * khtml/khtmlview.cpp:
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index d974928..8786556 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -115,11 +115,8 @@ RenderStyle* CSSStyleSelector::styleNotYetAvailable = 0;
 CSSStyleSheetImpl *CSSStyleSelector::quirksSheet = 0;
 
 static CSSStyleSelector::Encodedurl *encodedurl = 0;
-
-enum PseudoState { PseudoUnknown, PseudoNone, PseudoAnyLink, PseudoLink, PseudoVisited};
 static PseudoState pseudoState;
 
-
 CSSStyleSelector::CSSStyleSelector( DocumentImpl* doc, QString userStyleSheet, StyleSheetListImpl *styleSheets,
                                     const KURL &url, bool _strictParsing )
 {
@@ -405,18 +402,21 @@ void CSSStyleSelector::sortMatchedRules(uint start, uint end)
     }    
 }
 
-void CSSStyleSelector::initForStyleResolve(ElementImpl* e, RenderStyle* defaultParent)
+void CSSStyleSelector::initElementAndPseudoState(ElementImpl* e)
 {
-    // set some variables we will need
-    ::encodedurl = &encodedurl;
-    pseudoState = PseudoUnknown;
-    pseudoStyle = RenderStyle::NOPSEUDO;
-    
     element = e;
     if (element && element->isHTMLElement())
         htmlElement = static_cast<HTMLElementImpl*>(element);
     else
         htmlElement = 0;
+    ::encodedurl = &encodedurl;
+    pseudoState = PseudoUnknown;
+}
+
+void CSSStyleSelector::initForStyleResolve(ElementImpl* e, RenderStyle* defaultParent)
+{
+    // set some variables we will need
+    pseudoStyle = RenderStyle::NOPSEUDO;
 
     parentNode = e->parentNode();
     if (defaultParent)
@@ -438,6 +438,195 @@ void CSSStyleSelector::initForStyleResolve(ElementImpl* e, RenderStyle* defaultP
     fontDirty = false;
 }
 
+// modified version of the one in kurl.cpp
+static void cleanpath(QString &path)
+{
+    int pos;
+    while ( (pos = path.find( "/../" )) != -1 ) {
+        int prev = 0;
+        if ( pos > 0 )
+            prev = path.findRev( "/", pos -1 );
+        // don't remove the host, i.e. http://foo.org/../foo.html
+        if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
+            path.remove( pos, 3);
+        else
+            // matching directory found ?
+            path.remove( prev, pos- prev + 3 );
+    }
+    pos = 0;
+    
+    // Don't remove "//" from an anchor identifier. -rjw
+    // Set refPos to -2 to mean "I haven't looked for the anchor yet".
+    // We don't want to waste a function call on the search for the the anchor
+    // in the vast majority of cases where there is no "//" in the path.
+    int refPos = -2;
+    while ( (pos = path.find( "//", pos )) != -1) {
+        if (refPos == -2)
+            refPos = path.find("#", 0);
+        if (refPos > 0 && pos >= refPos)
+            break;
+        
+        if ( pos == 0 || path[pos-1] != ':' )
+            path.remove( pos, 1 );
+        else
+            pos += 2;
+    }
+    while ( (pos = path.find( "/./" )) != -1)
+        path.remove( pos, 2 );
+    //kdDebug() << "checkPseudoState " << path << endl;
+}
+
+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()) {
+        pseudoState = PseudoNone;
+        return;
+    }
+    
+    if (!checkVisited) {
+        pseudoState = PseudoAnyLink;
+        return;
+    }
+    
+    QConstString cu(attr.unicode(), attr.length());
+    QString u = cu.string();
+    if ( !u.contains("://") ) {
+        if ( u[0] == '/' )
+            u.prepend(encodedurl->host);
+        else if ( u[0] == '#' )
+            u.prepend(encodedurl->file);
+        else
+            u.prepend(encodedurl->path);
+        cleanpath( u );
+    }
+    //completeURL( attr.string() );
+    pseudoState = KHTMLFactory::vLinks()->contains( u ) ? PseudoVisited : PseudoLink;
+}
+
+#ifdef STYLE_SHARING_STATS
+static int fraction = 0;
+static int total = 0;
+#endif
+
+const int siblingThreshold = 10;
+
+NodeImpl* CSSStyleSelector::locateCousinList(ElementImpl* parent)
+{
+    if (parent && parent->isHTMLElement()) {
+        HTMLElementImpl* p = static_cast<HTMLElementImpl*>(parent);
+        if (p->renderer() && !p->inlineStyleDecl() && !p->hasID()) {
+            DOM::NodeImpl* r = p->previousSibling();
+            int subcount = 0;
+            RenderStyle* st = p->renderer()->style();
+            while (r) {
+                if (r->renderer() && r->renderer()->style() == st)
+                    return r->lastChild();
+                if (subcount++ == siblingThreshold)
+                    return 0;
+                r = r->previousSibling();
+            }
+            if (!r)
+                r = locateCousinList(static_cast<ElementImpl*>(parent->parentNode()));
+            while (r) {
+                if (r->renderer() && r->renderer()->style() == st)
+                    return r->lastChild();
+                if (subcount++ == siblingThreshold)
+                    return 0;
+                r = r->previousSibling();
+            }
+        }
+    }
+    return 0;
+}
+
+bool CSSStyleSelector::canShareStyleWithElement(NodeImpl* n)
+{
+    if (n->isHTMLElement()) {
+        bool mouseInside = element->renderer() ? element->renderer()->mouseInside() : false;
+        HTMLElementImpl* s = static_cast<HTMLElementImpl*>(n);
+        if (s->renderer() && (s->id() == element->id()) && !s->hasID() &&
+            (s->hasClass() == element->hasClass()) && !s->inlineStyleDecl() &&
+            (s->hasMappedAttributes() == htmlElement->hasMappedAttributes()) &&
+            (s->hasAnchor() == element->hasAnchor()) && 
+            !s->renderer()->style()->affectedByAttributeSelectors() &&
+            (s->renderer()->mouseInside() == mouseInside) &&
+            (s->active() == element->active()) &&
+            (s->focused() == element->focused())) {
+            bool classesMatch = true;
+            if (s->hasClass()) {
+                const AtomicString& class1 = element->getAttribute(ATTR_CLASS);
+                const AtomicString& class2 = s->getAttribute(ATTR_CLASS);
+                classesMatch = (class1 == class2);
+            }
+            
+            if (classesMatch) {
+                bool mappedAttrsMatch = true;
+                if (s->hasMappedAttributes())
+                    mappedAttrsMatch = s->htmlAttributes()->mapsEquivalent(htmlElement->htmlAttributes());
+                if (mappedAttrsMatch) {
+                    bool anchorsMatch = true;
+                    if (s->hasAnchor()) {
+                        // We need to check to see if the visited state matches.
+                        QColor linkColor = element->getDocument()->linkColor();
+                        QColor visitedColor = element->getDocument()->visitedLinkColor();
+                        if (pseudoState == PseudoUnknown)
+                            checkPseudoState(s, s->renderer()->style()->pseudoState() != PseudoAnyLink ||
+                                             linkColor != visitedColor);
+                        anchorsMatch = (pseudoState == s->renderer()->style()->pseudoState());
+                    }
+                    
+                    if (anchorsMatch) {
+#ifdef STYLE_SHARING_STATS
+                        fraction++;
+                        printf("Sharing %d out of %d\n", fraction, total);
+#endif
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
+RenderStyle* CSSStyleSelector::locateSharedStyle()
+{
+    //total++;
+    if (htmlElement && !htmlElement->inlineStyleDecl() && !htmlElement->hasID() &&
+        !htmlElement->getDocument()->usesSiblingRules()) {
+        // Check previous siblings.
+        int count = 0;
+        DOM::NodeImpl* n;
+        for (n = element->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());
+        while (n) {
+            if (canShareStyleWithElement(n))
+                return n->renderer()->style();
+            if (count++ == siblingThreshold)
+                return 0;
+            for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());
+        }
+        if (!n) 
+            n = locateCousinList(static_cast<ElementImpl*>(element->parentNode()));
+        while (n) {
+            if (canShareStyleWithElement(n))
+                return n->renderer()->style();
+            if (count++ == siblingThreshold)
+                return 0;
+            for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());
+        }        
+    }
+#ifdef STYLE_SHARING_STATS
+    printf("Sharing %d out of %d\n", fraction, total);
+#endif
+    return 0;
+}
+
 RenderStyle* CSSStyleSelector::styleForElement(ElementImpl* e, RenderStyle* defaultParent)
 {
     if (!e->getDocument()->haveStylesheetsLoaded()) {
@@ -449,6 +638,10 @@ RenderStyle* CSSStyleSelector::styleForElement(ElementImpl* e, RenderStyle* defa
         return styleNotYetAvailable;
     }
     
+    initElementAndPseudoState(e);
+    style = locateSharedStyle();
+    if (style)
+        return style;
     initForStyleResolve(e, defaultParent);
 
     style = new (e->getDocument()->renderArena()) RenderStyle();
@@ -548,6 +741,10 @@ RenderStyle* CSSStyleSelector::styleForElement(ElementImpl* e, RenderStyle* defa
     // Clean up our style object's display and text decorations (among other fixups).
     adjustRenderStyle(style, e);
 
+    // If we are a link, cache the determined pseudo-state.
+    if (e->hasAnchor())
+        style->setPseudoState(pseudoState);
+
     // Now return the style.
     return style;
 }
@@ -567,6 +764,7 @@ RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseud
         return styleNotYetAvailable;
     }
     
+    initElementAndPseudoState(e);
     initForStyleResolve(e, parentStyle);
     pseudoStyle = pseudo;
     
@@ -701,77 +899,6 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e
 
 static bool subject;
 
-// modified version of the one in kurl.cpp
-static void cleanpath(QString &path)
-{
-    int pos;
-    while ( (pos = path.find( "/../" )) != -1 ) {
-        int prev = 0;
-        if ( pos > 0 )
-            prev = path.findRev( "/", pos -1 );
-        // don't remove the host, i.e. http://foo.org/../foo.html
-        if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
-            path.remove( pos, 3);
-        else
-            // matching directory found ?
-            path.remove( prev, pos- prev + 3 );
-    }
-    pos = 0;
-
-    // Don't remove "//" from an anchor identifier. -rjw
-    // Set refPos to -2 to mean "I haven't looked for the anchor yet".
-    // We don't want to waste a function call on the search for the the anchor
-    // in the vast majority of cases where there is no "//" in the path.
-    int refPos = -2;
-    while ( (pos = path.find( "//", pos )) != -1) {
-        if (refPos == -2)
-            refPos = path.find("#", 0);
-        if (refPos > 0 && pos >= refPos)
-            break;
-
-        if ( pos == 0 || path[pos-1] != ':' )
-            path.remove( pos, 1 );
-        else
-            pos += 2;
-    }
-    while ( (pos = path.find( "/./" )) != -1)
-        path.remove( pos, 2 );
-    //kdDebug() << "checkPseudoState " << path << endl;
-}
-
-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()) {
-        pseudoState = PseudoNone;
-        return;
-    }
-    
-    if (!checkVisited) {
-        pseudoState = PseudoAnyLink;
-        return;
-    }
-
-    QConstString cu(attr.unicode(), attr.length());
-    QString u = cu.string();
-    if ( !u.contains("://") ) {
-        if ( u[0] == '/' )
-            u.prepend(encodedurl->host);
-        else if ( u[0] == '#' )
-            u.prepend(encodedurl->file);
-        else
-            u.prepend(encodedurl->path);
-        cleanpath( u );
-    }
-    //completeURL( attr.string() );
-    pseudoState = KHTMLFactory::vLinks()->contains( u ) ? PseudoVisited : PseudoLink;
-}
-
 bool CSSStyleSelector::checkSelector(CSSSelector* sel, ElementImpl *e)
 {
     dynamicPseudo = RenderStyle::NOPSEUDO;
@@ -912,6 +1039,8 @@ bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl
         }
         else if (sel->match == CSSSelector::Id)
             return e->hasID() && e->getIDAttribute() == sel->value;
+        else if (e != element || !htmlElement || !htmlElement->isMappedAttribute(sel->attr))
+            style->setAffectedByAttributeSelectors();
 
         const AtomicString& value = e->getAttribute(sel->attr);
         if (value.isNull()) return false; // attribute is not set
diff --git a/WebCore/khtml/css/cssstyleselector.h b/WebCore/khtml/css/cssstyleselector.h
index 64f8b7f..6cd62eb 100644
--- a/WebCore/khtml/css/cssstyleselector.h
+++ b/WebCore/khtml/css/cssstyleselector.h
@@ -103,11 +103,16 @@ namespace khtml
 
 	static void loadDefaultStyle(const KHTMLSettings *s = 0);
 
+        void initElementAndPseudoState(DOM::ElementImpl* e);
         void initForStyleResolve(DOM::ElementImpl* e, RenderStyle* parentStyle);
 	RenderStyle *styleForElement(DOM::ElementImpl* e, RenderStyle* parentStyle=0);
         RenderStyle* pseudoStyleForElement(RenderStyle::PseudoId pseudoStyle, 
                                            DOM::ElementImpl* e, RenderStyle* parentStyle=0);
 
+        RenderStyle* locateSharedStyle();
+        DOM::NodeImpl* locateCousinList(DOM::ElementImpl* parent);
+        bool canShareStyleWithElement(DOM::NodeImpl* e);
+        
 	bool strictParsing;
 	struct Encodedurl {
 	    QString host; //also contains protocol
diff --git a/WebCore/khtml/css/html4.css b/WebCore/khtml/css/html4.css
index f1d9b3e..a7d8aa8 100644
--- a/WebCore/khtml/css/html4.css
+++ b/WebCore/khtml/css/html4.css
@@ -170,9 +170,9 @@ TABLE {
 	border-color: gray;
 }
 
-TABLE[align="center"] { 
-    margin-left: auto; 
-    margin-right: auto;
+TABLE[align="center"] {
+        margin-left: auto;
+        margin-right: auto;
 }
 
 THEAD { 
@@ -231,14 +231,14 @@ UL, MENU, DIR {
         display: block;
         list-style-type: disc;
         margin: 1__qem 0 1em 0;
-        padding-left: 40px;
+        padding-left: 40px; /* For RTL, we need to implement padding-start */
 }
 
 OL {
         display: block;
         list-style-type: decimal;
         margin: 1__qem 0 1em 0;
-        padding-left: 40px;
+        padding-left: 40px; /* For RTL, we need to implement padding-start */
 }
 
 LI {
@@ -246,22 +246,18 @@ LI {
 }
 
 
-UL UL { 
+UL UL, OL UL { 
 	list-style-type: circle;
 }
 
-OL UL { 
-	list-style-type: circle;
-}
-
-UL UL UL { 
+OL OL UL, OL UL UL, UL OL UL, UL UL UL { 
 	list-style-type: square;
 }
       
 
 DD {
 	display: block;
-	margin-left: 40px;
+	margin-left: 40px; /* For RTL, we need to implement margin-start */
 }
 
 DL {
@@ -272,24 +268,13 @@ DL {
 DT {
 	display: block;
 }
- 
-/* for right to left */
-      
-*[dir="rtl"] UL, 
-*[dir="rtl"] OL,  
-*[dir="rtl"] DIR, 
-*[dir="rtl"] MENU, 
-*[dir="rtl"] DD { 
-	margin-right:40px; 
-	margin-left: auto;
-}
-      
+
 OL UL, 
 UL OL,
 UL UL, 
 OL OL { 
-	margin-top: auto; 
-	margin-bottom: auto; 
+	margin-top: 0; 
+	margin-bottom: 0; 
 }
 
 /*
@@ -437,12 +422,7 @@ BDO[DIR="rtl"]  {
 	direction: rtl; 
 	unicode-bidi: bidi-override;
 }
-
-/* ### this selector seems to be still broken ...
-      *[DIR="ltr"]    { direction: ltr; unicode-bidi: embed }
-      *[DIR="rtl"]    { direction: rtl; unicode-bidi: embed }
-*/
-      
+   
 /* Elements that are block-level in HTML4 */
 /* ### don't support unicode-bidi at the moment
       ADDRESS, BLOCKQUOTE, BODY, DD, DIV, DL, DT, FIELDSET,
diff --git a/WebCore/khtml/css/parser.cpp b/WebCore/khtml/css/parser.cpp
index 28ce175..e90a51c 100644
--- a/WebCore/khtml/css/parser.cpp
+++ b/WebCore/khtml/css/parser.cpp
@@ -311,17 +311,17 @@ static const short yyrline[] = { 0,
    357,   362,   371,   372,   375,   377,   380,   382,   385,   389,
    393,   397,   401,   406,   412,   426,   428,   437,   459,   463,
    468,   472,   477,   479,   480,   483,   485,   488,   508,   520,
-   534,   540,   544,   567,   573,   575,   576,   579,   584,   589,
-   594,   601,   610,   621,   638,   643,   647,   657,   663,   673,
-   674,   675,   678,   690,   710,   716,   722,   730,   741,   745,
-   748,   751,   754,   757,   762,   764,   767,   774,   781,   790,
-   794,   799,   802,   808,   816,   820,   823,   829,   835,   840,
-   846,   854,   877,   881,   889,   894,   901,   908,   910,   913,
-   918,   931,   937,   941,   944,   949,   951,   952,   953,   960,
-   961,   962,   963,   964,   965,   967,   972,   974,   975,   976,
-   977,   978,   979,   980,   981,   982,   983,   984,   985,   986,
-   987,   988,   989,   990,   994,  1002,  1017,  1024,  1031,  1039,
-  1065,  1067,  1070,  1072
+   534,   540,   544,   573,   579,   581,   582,   585,   590,   595,
+   600,   607,   616,   627,   644,   649,   653,   663,   669,   679,
+   680,   681,   684,   696,   716,   722,   728,   736,   747,   751,
+   754,   757,   760,   763,   768,   770,   773,   787,   794,   803,
+   807,   812,   815,   821,   829,   833,   836,   842,   848,   853,
+   859,   867,   890,   894,   902,   907,   914,   921,   923,   926,
+   931,   944,   950,   954,   957,   962,   964,   965,   966,   973,
+   974,   975,   976,   977,   978,   980,   985,   987,   988,   989,
+   990,   991,   992,   993,   994,   995,   996,   997,   998,   999,
+  1000,  1001,  1002,  1003,  1007,  1015,  1030,  1037,  1044,  1052,
+  1078,  1080,  1083,  1085
 };
 #endif
 
@@ -1468,39 +1468,45 @@ case 63:
                 if ( doc )
                     doc->setUsesDescendantRules(true);
             }
+            else if (yyvsp[-1].relation == CSSSelector::Sibling) {
+                CSSParser *p = static_cast<CSSParser *>(parser);
+                DOM::DocumentImpl *doc = p->document();
+                if (doc)
+                    doc->setUsesSiblingRules(true);
+            }
         } else {
             delete yyvsp[-2].selector;
         }
     ;
     break;}
 case 64:
-#line 567 "parser.y"
+#line 573 "parser.y"
 {
         delete yyvsp[-1].selector;
         yyval.selector = 0;
     ;
     break;}
 case 65:
-#line 574 "parser.y"
+#line 580 "parser.y"
 { yyval.string.string = 0; yyval.string.length = 0; ;
     break;}
 case 66:
-#line 575 "parser.y"
+#line 581 "parser.y"
 { static unsigned short star = '*'; yyval.string.string = &star; yyval.string.length = 1; ;
     break;}
 case 67:
-#line 576 "parser.y"
+#line 582 "parser.y"
 { yyval.string = yyvsp[0].string; ;
     break;}
 case 68:
-#line 580 "parser.y"
+#line 586 "parser.y"
 {
 	yyval.selector = new CSSSelector();
 	yyval.selector->tag = yyvsp[-1].element;
     ;
     break;}
 case 69:
-#line 584 "parser.y"
+#line 590 "parser.y"
 {
 	yyval.selector = yyvsp[-1].selector;
 	if ( yyval.selector )
@@ -1508,7 +1514,7 @@ case 69:
     ;
     break;}
 case 70:
-#line 589 "parser.y"
+#line 595 "parser.y"
 {
 	yyval.selector = yyvsp[-1].selector;
         if (yyval.selector)
@@ -1516,7 +1522,7 @@ case 70:
     ;
     break;}
 case 71:
-#line 594 "parser.y"
+#line 600 "parser.y"
 {
         yyval.selector = new CSSSelector();
         yyval.selector->tag = yyvsp[-1].element;
@@ -1526,7 +1532,7 @@ case 71:
     ;
     break;}
 case 72:
-#line 601 "parser.y"
+#line 607 "parser.y"
 {
         yyval.selector = yyvsp[-1].selector;
         if (yyval.selector) {
@@ -1538,7 +1544,7 @@ case 72:
     ;
     break;}
 case 73:
-#line 610 "parser.y"
+#line 616 "parser.y"
 {
         yyval.selector = yyvsp[-1].selector;
         if (yyval.selector) {
@@ -1550,7 +1556,7 @@ case 73:
     ;
     break;}
 case 74:
-#line 622 "parser.y"
+#line 628 "parser.y"
 {
 	CSSParser *p = static_cast<CSSParser *>(parser);
 	DOM::DocumentImpl *doc = p->document();
@@ -1569,19 +1575,19 @@ case 74:
     ;
     break;}
 case 75:
-#line 638 "parser.y"
+#line 644 "parser.y"
 {
 	yyval.element = makeId(static_cast<CSSParser*>(parser)->defaultNamespace, anyLocalName);
     ;
     break;}
 case 76:
-#line 644 "parser.y"
+#line 650 "parser.y"
 {
 	yyval.selector = yyvsp[0].selector;
     ;
     break;}
 case 77:
-#line 647 "parser.y"
+#line 653 "parser.y"
 {
 	yyval.selector = yyvsp[-1].selector;
         if (yyval.selector) {
@@ -1594,14 +1600,14 @@ case 77:
     ;
     break;}
 case 78:
-#line 657 "parser.y"
+#line 663 "parser.y"
 {
         delete yyvsp[-1].selector;
         yyval.selector = 0;
     ;
     break;}
 case 79:
-#line 664 "parser.y"
+#line 670 "parser.y"
 {
 	yyval.selector = new CSSSelector();
 	yyval.selector->match = CSSSelector::Id;
@@ -1613,7 +1619,7 @@ case 79:
     ;
     break;}
 case 83:
-#line 679 "parser.y"
+#line 685 "parser.y"
 {
         yyval.selector = new CSSSelector();
 	yyval.selector->match = CSSSelector::Class;
@@ -1625,7 +1631,7 @@ case 83:
     ;
     break;}
 case 84:
-#line 691 "parser.y"
+#line 697 "parser.y"
 {
 	CSSParser *p = static_cast<CSSParser *>(parser);
 	DOM::DocumentImpl *doc = p->document();
@@ -1645,7 +1651,7 @@ case 84:
     ;
     break;}
 case 85:
-#line 711 "parser.y"
+#line 717 "parser.y"
 {
 	yyval.selector = new CSSSelector();
 	yyval.selector->attr = yyvsp[-1].attribute;
@@ -1653,7 +1659,7 @@ case 85:
     ;
     break;}
 case 86:
-#line 716 "parser.y"
+#line 722 "parser.y"
 {
 	yyval.selector = new CSSSelector();
 	yyval.selector->attr = yyvsp[-5].attribute;
@@ -1662,7 +1668,7 @@ case 86:
     ;
     break;}
 case 87:
-#line 722 "parser.y"
+#line 728 "parser.y"
 {
         yyval.selector = new CSSSelector();
         yyval.selector->attr = yyvsp[-1].attribute;
@@ -1673,7 +1679,7 @@ case 87:
     ;
     break;}
 case 88:
-#line 730 "parser.y"
+#line 736 "parser.y"
 {
         yyval.selector = new CSSSelector();
         yyval.selector->attr = yyvsp[-5].attribute;
@@ -1685,52 +1691,59 @@ case 88:
     ;
     break;}
 case 89:
-#line 742 "parser.y"
+#line 748 "parser.y"
 {
 	yyval.val = CSSSelector::Exact;
     ;
     break;}
 case 90:
-#line 745 "parser.y"
+#line 751 "parser.y"
 {
 	yyval.val = CSSSelector::List;
     ;
     break;}
 case 91:
-#line 748 "parser.y"
+#line 754 "parser.y"
 {
 	yyval.val = CSSSelector::Hyphen;
     ;
     break;}
 case 92:
-#line 751 "parser.y"
+#line 757 "parser.y"
 {
 	yyval.val = CSSSelector::Begin;
     ;
     break;}
 case 93:
-#line 754 "parser.y"
+#line 760 "parser.y"
 {
 	yyval.val = CSSSelector::End;
     ;
     break;}
 case 94:
-#line 757 "parser.y"
+#line 763 "parser.y"
 {
 	yyval.val = CSSSelector::Contain;
     ;
     break;}
 case 97:
-#line 768 "parser.y"
+#line 774 "parser.y"
 {
         yyval.selector = new CSSSelector();
         yyval.selector->match = CSSSelector::Pseudo;
         yyvsp[0].string.lower();
         yyval.selector->value = atomicString(yyvsp[0].string);
+        if (yyval.selector->value == "empty" || yyval.selector->value == "only-child" ||
+            yyval.selector->value == "first-child" || yyval.selector->value == "last-child") {
+            CSSParser *p = static_cast<CSSParser *>(parser);
+            DOM::DocumentImpl *doc = p->document();
+            if (doc)
+                doc->setUsesSiblingRules(true);
+        }
     ;
     break;}
 case 98:
-#line 775 "parser.y"
+#line 788 "parser.y"
 {
         yyval.selector = new CSSSelector();
         yyval.selector->match = CSSSelector::Pseudo;
@@ -1739,7 +1752,7 @@ case 98:
     ;
     break;}
 case 99:
-#line 781 "parser.y"
+#line 794 "parser.y"
 {
         yyval.selector = new CSSSelector();
         yyval.selector->match = CSSSelector::Pseudo;
@@ -1749,13 +1762,13 @@ case 99:
     ;
     break;}
 case 100:
-#line 791 "parser.y"
+#line 804 "parser.y"
 {
 	yyval.ok = yyvsp[0].ok;
     ;
     break;}
 case 101:
-#line 794 "parser.y"
+#line 807 "parser.y"
 {
 	yyval.ok = yyvsp[-1].ok;
 	if ( yyvsp[0].ok )
@@ -1763,13 +1776,13 @@ case 101:
     ;
     break;}
 case 102:
-#line 799 "parser.y"
+#line 812 "parser.y"
 {
 	yyval.ok = yyvsp[0].ok;
     ;
     break;}
 case 103:
-#line 802 "parser.y"
+#line 815 "parser.y"
 {
 	yyval.ok = false;
 #ifdef CSS_DEBUG
@@ -1778,7 +1791,7 @@ case 103:
     ;
     break;}
 case 104:
-#line 808 "parser.y"
+#line 821 "parser.y"
 {
 	yyval.ok = false;
 #ifdef CSS_DEBUG
@@ -1787,19 +1800,19 @@ case 104:
     ;
     break;}
 case 105:
-#line 817 "parser.y"
+#line 830 "parser.y"
 {
 	yyval.ok = yyvsp[-2].ok;
     ;
     break;}
 case 106:
-#line 820 "parser.y"
+#line 833 "parser.y"
 {
         yyval.ok = false;
     ;
     break;}
 case 107:
-#line 823 "parser.y"
+#line 836 "parser.y"
 {
 	yyval.ok = false;
 #ifdef CSS_DEBUG
@@ -1808,7 +1821,7 @@ case 107:
     ;
     break;}
 case 108:
-#line 829 "parser.y"
+#line 842 "parser.y"
 {
 	yyval.ok = false;
 #ifdef CSS_DEBUG
@@ -1817,7 +1830,7 @@ case 108:
     ;
     break;}
 case 109:
-#line 835 "parser.y"
+#line 848 "parser.y"
 {
 	yyval.ok = yyvsp[-3].ok;
 	if ( yyvsp[-2].ok )
@@ -1825,7 +1838,7 @@ case 109:
     ;
     break;}
 case 110:
-#line 840 "parser.y"
+#line 853 "parser.y"
 {
 	yyval.ok = yyvsp[-3].ok;
 #ifdef CSS_DEBUG
@@ -1834,7 +1847,7 @@ case 110:
     ;
     break;}
 case 111:
-#line 846 "parser.y"
+#line 859 "parser.y"
 {
 	yyval.ok = yyvsp[-5].ok;
 #ifdef CSS_DEBUG
@@ -1843,7 +1856,7 @@ case 111:
     ;
     break;}
 case 112:
-#line 855 "parser.y"
+#line 868 "parser.y"
 {
 	yyval.ok = false;
 	CSSParser *p = static_cast<CSSParser *>(parser);
@@ -1868,13 +1881,13 @@ case 112:
     ;
     break;}
 case 113:
-#line 878 "parser.y"
+#line 891 "parser.y"
 {
         yyval.ok = false;
     ;
     break;}
 case 114:
-#line 882 "parser.y"
+#line 895 "parser.y"
 {
         /* The default movable type template has letter-spacing: .none;  Handle this by looking for
         error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
@@ -1884,43 +1897,43 @@ case 114:
     ;
     break;}
 case 115:
-#line 890 "parser.y"
+#line 903 "parser.y"
 {
         /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
         yyval.ok = false;
     ;
     break;}
 case 116:
-#line 895 "parser.y"
+#line 908 "parser.y"
 {
         /* div { font-family: } Just reduce away this property with no value. */
         yyval.ok = false;
     ;
     break;}
 case 117:
-#line 902 "parser.y"
+#line 915 "parser.y"
 {
 	QString str = qString(yyvsp[-1].string);
 	yyval.prop_id = getPropertyID( str.lower().latin1(), str.length() );
     ;
     break;}
 case 118:
-#line 909 "parser.y"
+#line 922 "parser.y"
 { yyval.b = true; ;
     break;}
 case 119:
-#line 910 "parser.y"
+#line 923 "parser.y"
 { yyval.b = false; ;
     break;}
 case 120:
-#line 914 "parser.y"
+#line 927 "parser.y"
 {
 	yyval.valueList = new ValueList;
 	yyval.valueList->addValue( yyvsp[0].value );
     ;
     break;}
 case 121:
-#line 918 "parser.y"
+#line 931 "parser.y"
 {
         yyval.valueList = yyvsp[-2].valueList;
 	if ( yyval.valueList ) {
@@ -1936,44 +1949,44 @@ case 121:
     ;
     break;}
 case 122:
-#line 931 "parser.y"
+#line 944 "parser.y"
 {
         delete yyvsp[-1].valueList;
         yyval.valueList = 0;
     ;
     break;}
 case 123:
-#line 938 "parser.y"
+#line 951 "parser.y"
 {
 	yyval.tok = '/';
     ;
     break;}
 case 124:
-#line 941 "parser.y"
+#line 954 "parser.y"
 {
 	yyval.tok = ',';
     ;
     break;}
 case 125:
-#line 944 "parser.y"
+#line 957 "parser.y"
 {
         yyval.tok = 0;
   ;
     break;}
 case 126:
-#line 950 "parser.y"
+#line 963 "parser.y"
 { yyval.value = yyvsp[0].value; ;
     break;}
 case 127:
-#line 951 "parser.y"
+#line 964 "parser.y"
 { yyval.value = yyvsp[0].value; yyval.value.fValue *= yyvsp[-1].val; ;
     break;}
 case 128:
-#line 952 "parser.y"
+#line 965 "parser.y"
 { yyval.value.id = 0; yyval.value.string = yyvsp[-1].string; yyval.value.unit = CSSPrimitiveValue::CSS_STRING; ;
     break;}
 case 129:
-#line 953 "parser.y"
+#line 966 "parser.y"
 {
       QString str = qString( yyvsp[-1].string );
       yyval.value.id = getValueID( str.lower().latin1(), str.length() );
@@ -1982,109 +1995,109 @@ case 129:
   ;
     break;}
 case 130:
-#line 960 "parser.y"
+#line 973 "parser.y"
 { yyval.value.id = 0; yyval.value.string = yyvsp[-1].string; yyval.value.unit = CSSPrimitiveValue::CSS_DIMENSION ;
     break;}
 case 131:
-#line 961 "parser.y"
+#line 974 "parser.y"
 { yyval.value.id = 0; yyval.value.string = yyvsp[-1].string; yyval.value.unit = CSSPrimitiveValue::CSS_DIMENSION ;
     break;}
 case 132:
-#line 962 "parser.y"
+#line 975 "parser.y"
 { yyval.value.id = 0; yyval.value.string = yyvsp[-1].string; yyval.value.unit = CSSPrimitiveValue::CSS_URI; ;
     break;}
 case 133:
-#line 963 "parser.y"
+#line 976 "parser.y"
 { yyval.value.id = 0; yyval.value.iValue = 0; yyval.value.unit = CSSPrimitiveValue::CSS_UNKNOWN;/* ### */ ;
     break;}
 case 134:
-#line 964 "parser.y"
+#line 977 "parser.y"
 { yyval.value.id = 0; yyval.value.string = yyvsp[0].string; yyval.value.unit = CSSPrimitiveValue::CSS_RGBCOLOR; ;
     break;}
 case 135:
-#line 965 "parser.y"
+#line 978 "parser.y"
 { yyval.value.id = 0; yyval.value.string = ParseString(); yyval.value.unit = CSSPrimitiveValue::CSS_RGBCOLOR; ;
     break;}
 case 136:
-#line 967 "parser.y"
+#line 980 "parser.y"
 {
       yyval.value = yyvsp[0].value;
   ;
     break;}
 case 137:
-#line 973 "parser.y"
+#line 986 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_NUMBER; ;
     break;}
 case 138:
-#line 974 "parser.y"
+#line 987 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PERCENTAGE; ;
     break;}
 case 139:
-#line 975 "parser.y"
+#line 988 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PX; ;
     break;}
 case 140:
-#line 976 "parser.y"
+#line 989 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_CM; ;
     break;}
 case 141:
-#line 977 "parser.y"
+#line 990 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_MM; ;
     break;}
 case 142:
-#line 978 "parser.y"
+#line 991 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_IN; ;
     break;}
 case 143:
-#line 979 "parser.y"
+#line 992 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PT; ;
     break;}
 case 144:
-#line 980 "parser.y"
+#line 993 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_PC; ;
     break;}
 case 145:
-#line 981 "parser.y"
+#line 994 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_DEG; ;
     break;}
 case 146:
-#line 982 "parser.y"
+#line 995 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_RAD; ;
     break;}
 case 147:
-#line 983 "parser.y"
+#line 996 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_GRAD; ;
     break;}
 case 148:
-#line 984 "parser.y"
+#line 997 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_MS; ;
     break;}
 case 149:
-#line 985 "parser.y"
+#line 998 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_S; ;
     break;}
 case 150:
-#line 986 "parser.y"
+#line 999 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_HZ; ;
     break;}
 case 151:
-#line 987 "parser.y"
+#line 1000 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_KHZ; ;
     break;}
 case 152:
-#line 988 "parser.y"
+#line 1001 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_EMS; ;
     break;}
 case 153:
-#line 989 "parser.y"
+#line 1002 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = Value::Q_EMS; ;
     break;}
 case 154:
-#line 990 "parser.y"
+#line 1003 "parser.y"
 { yyval.value.id = 0; yyval.value.fValue = yyvsp[-1].val; yyval.value.unit = CSSPrimitiveValue::CSS_EXS; ;
     break;}
 case 155:
-#line 995 "parser.y"
+#line 1008 "parser.y"
 {
       Function *f = new Function;
       f->name = yyvsp[-4].string;
@@ -2095,7 +2108,7 @@ case 155:
   ;
     break;}
 case 156:
-#line 1003 "parser.y"
+#line 1016 "parser.y"
 {
       Function *f = new Function;
       f->name = yyvsp[-2].string;
@@ -2106,11 +2119,11 @@ case 156:
   ;
     break;}
 case 157:
-#line 1018 "parser.y"
+#line 1031 "parser.y"
 { yyval.string = yyvsp[-1].string; ;
     break;}
 case 158:
-#line 1025 "parser.y"
+#line 1038 "parser.y"
 {
 	yyval.rule = 0;
 #ifdef CSS_DEBUG
@@ -2119,7 +2132,7 @@ case 158:
     ;
     break;}
 case 159:
-#line 1031 "parser.y"
+#line 1044 "parser.y"
 {
 	yyval.rule = 0;
 #ifdef CSS_DEBUG
@@ -2128,7 +2141,7 @@ case 159:
     ;
     break;}
 case 160:
-#line 1040 "parser.y"
+#line 1053 "parser.y"
 {
 	yyval.rule = 0;
 #ifdef CSS_DEBUG
@@ -2358,6 +2371,6 @@ yyerrhandle:
     }
   return 1;
 }
-#line 1075 "parser.y"
+#line 1088 "parser.y"
 
 
diff --git a/WebCore/khtml/css/parser.y b/WebCore/khtml/css/parser.y
index 542a56e..af88ef5 100644
--- a/WebCore/khtml/css/parser.y
+++ b/WebCore/khtml/css/parser.y
@@ -560,6 +560,12 @@ selector:
                 if ( doc )
                     doc->setUsesDescendantRules(true);
             }
+            else if ($2 == CSSSelector::Sibling) {
+                CSSParser *p = static_cast<CSSParser *>(parser);
+                DOM::DocumentImpl *doc = p->document();
+                if (doc)
+                    doc->setUsesSiblingRules(true);
+            }
         } else {
             delete $1;
         }
@@ -770,6 +776,13 @@ pseudo:
         $$->match = CSSSelector::Pseudo;
         $2.lower();
         $$->value = atomicString($2);
+        if ($$->value == "empty" || $$->value == "only-child" ||
+            $$->value == "first-child" || $$->value == "last-child") {
+            CSSParser *p = static_cast<CSSParser *>(parser);
+            DOM::DocumentImpl *doc = p->document();
+            if (doc)
+                doc->setUsesSiblingRules(true);
+        }
     }
     |
     ':' ':' IDENT {
diff --git a/WebCore/khtml/html/html_baseimpl.cpp b/WebCore/khtml/html/html_baseimpl.cpp
index 8431083..58999e2 100644
--- a/WebCore/khtml/html/html_baseimpl.cpp
+++ b/WebCore/khtml/html/html_baseimpl.cpp
@@ -75,9 +75,9 @@ void HTMLBodyElementImpl::createLinkDecl()
     m_linkDecl->setStrictParsing(!getDocument()->inCompatMode());
 }
 
-bool HTMLBodyElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLBodyElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch(attr->id())
+    switch(attr)
     {
         case ATTR_BACKGROUND:
         case ATTR_BGCOLOR:
@@ -690,9 +690,9 @@ NodeImpl::Id HTMLIFrameElementImpl::id() const
     return ID_IFRAME;
 }
 
-bool HTMLIFrameElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLIFrameElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
             result = eUniversal;
diff --git a/WebCore/khtml/html/html_baseimpl.h b/WebCore/khtml/html/html_baseimpl.h
index 2cc5d37..9103d3b 100644
--- a/WebCore/khtml/html/html_baseimpl.h
+++ b/WebCore/khtml/html/html_baseimpl.h
@@ -56,7 +56,7 @@ public:
 
     virtual Id id() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *);
 
     virtual void insertedIntoDocument();
@@ -202,7 +202,7 @@ public:
 
     virtual Id id() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 
     virtual void attach();
diff --git a/WebCore/khtml/html/html_blockimpl.cpp b/WebCore/khtml/html/html_blockimpl.cpp
index 835c462..8e58e95 100644
--- a/WebCore/khtml/html/html_blockimpl.cpp
+++ b/WebCore/khtml/html/html_blockimpl.cpp
@@ -66,9 +66,9 @@ NodeImpl::Id HTMLDivElementImpl::id() const
     return ID_DIV;
 }
 
-bool HTMLDivElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLDivElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    if (attr->id() == ATTR_ALIGN) {
+    if (attr == ATTR_ALIGN) {
         result = eBlock;
         return false;
     }
@@ -113,9 +113,9 @@ NodeImpl::Id HTMLHRElementImpl::id() const
     return ID_HR;
 }
 
-bool HTMLHRElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLHRElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_ALIGN:
         case ATTR_WIDTH:
         case ATTR_COLOR:
@@ -209,9 +209,9 @@ NodeImpl::Id HTMLParagraphElementImpl::id() const
     return ID_P;
 }
 
-bool HTMLParagraphElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLParagraphElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    if (attr->id() == ATTR_ALIGN) {
+    if (attr == ATTR_ALIGN) {
         result = eBlock; // We can share with DIV here.
         return false;
     }
@@ -274,9 +274,9 @@ NodeImpl::Id HTMLMarqueeElementImpl::id() const
     return ID_MARQUEE;
 }
 
-bool HTMLMarqueeElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLMarqueeElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
         case ATTR_BGCOLOR:
diff --git a/WebCore/khtml/html/html_blockimpl.h b/WebCore/khtml/html/html_blockimpl.h
index 47a9cf4..ffed488 100644
--- a/WebCore/khtml/html/html_blockimpl.h
+++ b/WebCore/khtml/html/html_blockimpl.h
@@ -55,7 +55,7 @@ public:
 
     virtual NodeImpl::Id id() const;
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *token);
 };
 
@@ -69,7 +69,7 @@ public:
 
     virtual NodeImpl::Id id() const;
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *);
 };
 
@@ -94,7 +94,7 @@ class HTMLParagraphElementImpl : public HTMLElementImpl
 public:
     HTMLParagraphElementImpl(DocumentPtr *doc);
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
     
     virtual NodeImpl::Id id() const;
@@ -120,7 +120,7 @@ public:
 
     virtual NodeImpl::Id id() const;
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *token);
 
     int minimumDelay() const { return m_minimumDelay; }
diff --git a/WebCore/khtml/html/html_elementimpl.cpp b/WebCore/khtml/html/html_elementimpl.cpp
index 687aa0e..abbb750 100644
--- a/WebCore/khtml/html/html_elementimpl.cpp
+++ b/WebCore/khtml/html/html_elementimpl.cpp
@@ -139,6 +139,35 @@ bool HTMLNamedAttrMapImpl::isHTMLAttributeMap() const
     return true;
 }
 
+int HTMLNamedAttrMapImpl::declCount() const
+{
+    int result = 0;
+    for (uint i = 0; i < length(); i++) {
+        HTMLAttributeImpl* attr = attributeItem(i);
+        if (attr->decl())
+            result++;
+    }
+    return result;
+}
+
+bool HTMLNamedAttrMapImpl::mapsEquivalent(const HTMLNamedAttrMapImpl* otherMap) const
+{
+    // The # of decls must match.
+    if (declCount() != otherMap->declCount())
+        return false;
+    
+    // The values for each decl must match.
+    for (uint i = 0; i < length(); i++) {
+        HTMLAttributeImpl* attr = attributeItem(i);
+        if (attr->decl()) {
+            AttributeImpl* otherAttr = otherMap->getAttributeItem(attr->id());
+            if (!otherAttr || (attr->value() != otherAttr->value()))
+                return false;
+        }
+    }
+    return true;
+}
+
 void HTMLNamedAttrMapImpl::parseClassAttribute(const DOMString& classStr)
 {
     m_classList.clear();
@@ -257,7 +286,7 @@ void HTMLElementImpl::attributeChanged(AttributeImpl* attr, bool preserveDecls)
 
     bool checkDecl = true;
     MappedAttributeEntry entry;
-    bool needToParse = mapToEntry(attr, entry);
+    bool needToParse = mapToEntry(attr->id(), entry);
     if (preserveDecls) {
         if (htmlAttr->decl()) {
             setChanged();
@@ -292,9 +321,9 @@ void HTMLElementImpl::attributeChanged(AttributeImpl* attr, bool preserveDecls)
     }
 }
 
-bool HTMLElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id())
+    switch (attr)
     {
         case ATTR_ALIGN:
         case ATTR_CONTENTEDITABLE:
diff --git a/WebCore/khtml/html/html_elementimpl.h b/WebCore/khtml/html/html_elementimpl.h
index 44caa9a..4b559d8 100644
--- a/WebCore/khtml/html/html_elementimpl.h
+++ b/WebCore/khtml/html/html_elementimpl.h
@@ -102,6 +102,9 @@ public:
     void declRemoved() { m_mappedAttributeCount--; }
     void declAdded() { m_mappedAttributeCount++; }
     
+    bool mapsEquivalent(const HTMLNamedAttrMapImpl* otherMap) const;
+    int declCount() const;
+
     HTMLAttributeImpl* attributeItem(unsigned long index) const
     { return attrs ? static_cast<HTMLAttributeImpl*>(attrs[index]) : 0; }
     
@@ -131,8 +134,9 @@ public:
 
     bool hasMappedAttributes() const { return namedAttrMap ? static_cast<HTMLNamedAttrMapImpl*>(namedAttrMap)->hasMappedAttributes() : false; }
     const HTMLNamedAttrMapImpl* htmlAttributes() const { return static_cast<HTMLNamedAttrMapImpl*>(namedAttrMap); }
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
-        
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
+    bool isMappedAttribute(NodeImpl::Id attr) const { MappedAttributeEntry res = eNone; mapToEntry(attr, res); return res != eNone; }
+
     void addCSSLength(HTMLAttributeImpl* attr, int id, const DOMString &value);
     void addCSSProperty(HTMLAttributeImpl* attr, int id, const DOMString &value);
     void addCSSProperty(HTMLAttributeImpl* attr, int id, int value);
diff --git a/WebCore/khtml/html/html_formimpl.cpp b/WebCore/khtml/html/html_formimpl.cpp
index 992be1c..5cc2f2a 100644
--- a/WebCore/khtml/html/html_formimpl.cpp
+++ b/WebCore/khtml/html/html_formimpl.cpp
@@ -1382,9 +1382,9 @@ void HTMLInputElementImpl::accessKeyAction()
     }
 }
 
-bool HTMLInputElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLInputElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
         case ATTR_VSPACE:
diff --git a/WebCore/khtml/html/html_formimpl.h b/WebCore/khtml/html/html_formimpl.h
index 87f2d17..bf21352 100644
--- a/WebCore/khtml/html/html_formimpl.h
+++ b/WebCore/khtml/html/html_formimpl.h
@@ -318,7 +318,7 @@ public:
     virtual void click();
     virtual void accessKeyAction();
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 
     virtual void attach();
diff --git a/WebCore/khtml/html/html_imageimpl.cpp b/WebCore/khtml/html/html_imageimpl.cpp
index 0ed24c9..1a4863f 100644
--- a/WebCore/khtml/html/html_imageimpl.cpp
+++ b/WebCore/khtml/html/html_imageimpl.cpp
@@ -70,9 +70,9 @@ NodeImpl::Id HTMLImageElementImpl::id() const
     return ID_IMG;
 }
 
-bool HTMLImageElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLImageElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch(attr->id())
+    switch(attr)
     {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
diff --git a/WebCore/khtml/html/html_imageimpl.h b/WebCore/khtml/html/html_imageimpl.h
index dd297a5..7bf961b 100644
--- a/WebCore/khtml/html/html_imageimpl.h
+++ b/WebCore/khtml/html/html_imageimpl.h
@@ -43,7 +43,7 @@ public:
 
     virtual Id id() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *);
 
     virtual void attach();
diff --git a/WebCore/khtml/html/html_inlineimpl.cpp b/WebCore/khtml/html/html_inlineimpl.cpp
index 5360953..43af4d3 100644
--- a/WebCore/khtml/html/html_inlineimpl.cpp
+++ b/WebCore/khtml/html/html_inlineimpl.cpp
@@ -254,9 +254,9 @@ NodeImpl::Id HTMLBRElementImpl::id() const
     return ID_BR;
 }
 
-bool HTMLBRElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLBRElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    if (attr->id() == ATTR_CLEAR) {
+    if (attr == ATTR_CLEAR) {
         result = eUniversal;
         return false;
     }
@@ -353,9 +353,9 @@ static bool parseFontSizeNumber(const DOMString &s, int &size)
     return true;
 }
 
-bool HTMLFontElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLFontElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch(attr->id())
+    switch(attr)
     {
         case ATTR_SIZE:
         case ATTR_COLOR:
diff --git a/WebCore/khtml/html/html_inlineimpl.h b/WebCore/khtml/html/html_inlineimpl.h
index 3f2546f..dc39549 100644
--- a/WebCore/khtml/html/html_inlineimpl.h
+++ b/WebCore/khtml/html/html_inlineimpl.h
@@ -62,7 +62,7 @@ public:
 
     virtual Id id() const;
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
     
     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
@@ -78,7 +78,7 @@ public:
 
     virtual Id id() const;
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 };
 
diff --git a/WebCore/khtml/html/html_listimpl.cpp b/WebCore/khtml/html/html_listimpl.cpp
index 47f7674..0b92863 100644
--- a/WebCore/khtml/html/html_listimpl.cpp
+++ b/WebCore/khtml/html/html_listimpl.cpp
@@ -37,9 +37,9 @@ NodeImpl::Id HTMLUListElementImpl::id() const
     return ID_UL;
 }
 
-bool HTMLUListElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLUListElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_TYPE:
             result = eUnorderedList;
             return false;
@@ -83,9 +83,9 @@ NodeImpl::Id HTMLOListElementImpl::id() const
     return ID_OL;
 }
 
-bool HTMLOListElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLOListElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_TYPE:
             result = eListItem; // Share with <li>
             return false;
@@ -126,9 +126,9 @@ NodeImpl::Id HTMLLIElementImpl::id() const
     return ID_LI;
 }
 
-bool HTMLLIElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLLIElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_TYPE:
             result = eListItem; // Share with <ol> since all the values are the same
             return false;
diff --git a/WebCore/khtml/html/html_listimpl.h b/WebCore/khtml/html/html_listimpl.h
index cb6a989..54e1f49 100644
--- a/WebCore/khtml/html/html_listimpl.h
+++ b/WebCore/khtml/html/html_listimpl.h
@@ -42,7 +42,7 @@ public:
 
     virtual Id id() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *);
 
     virtual int start() const { return 1; }
@@ -81,7 +81,7 @@ public:
 
     virtual Id id() const;
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *);
 
     int start() const { return _start; }
@@ -100,7 +100,7 @@ public:
 
     virtual Id id() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 
     virtual void attach();
diff --git a/WebCore/khtml/html/html_objectimpl.cpp b/WebCore/khtml/html/html_objectimpl.cpp
index 5734de6..a9f8dc7 100644
--- a/WebCore/khtml/html/html_objectimpl.cpp
+++ b/WebCore/khtml/html/html_objectimpl.cpp
@@ -71,9 +71,9 @@ NodeImpl::Id HTMLAppletElementImpl::id() const
     return ID_APPLET;
 }
 
-bool HTMLAppletElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLAppletElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
             result = eUniversal;
@@ -228,9 +228,9 @@ NodeImpl::Id HTMLEmbedElementImpl::id() const
     return ID_EMBED;
 }
 
-bool HTMLEmbedElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLEmbedElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
         case ATTR_BORDER:
@@ -358,9 +358,9 @@ HTMLFormElementImpl *HTMLObjectElementImpl::form() const
   return 0;
 }
 
-bool HTMLObjectElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLObjectElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch (attr->id()) {
+    switch (attr) {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
             result = eUniversal;
diff --git a/WebCore/khtml/html/html_objectimpl.h b/WebCore/khtml/html/html_objectimpl.h
index 6463e93..f30e0f7 100644
--- a/WebCore/khtml/html/html_objectimpl.h
+++ b/WebCore/khtml/html/html_objectimpl.h
@@ -51,7 +51,7 @@ public:
 
     virtual Id id() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *token);
     
     virtual bool rendererIsNeeded(khtml::RenderStyle *);
@@ -83,7 +83,7 @@ public:
 
     virtual Id id() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 
     virtual void attach();
@@ -110,7 +110,7 @@ public:
 
     HTMLFormElementImpl *form() const;
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *token);
 
     virtual void attach();
diff --git a/WebCore/khtml/html/html_tableimpl.cpp b/WebCore/khtml/html/html_tableimpl.cpp
index 971381b..bac182c 100644
--- a/WebCore/khtml/html/html_tableimpl.cpp
+++ b/WebCore/khtml/html/html_tableimpl.cpp
@@ -344,9 +344,9 @@ NodeImpl *HTMLTableElementImpl::addChild(NodeImpl *child)
     return retval;
 }
 
-bool HTMLTableElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLTableElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch(attr->id()) {
+    switch(attr) {
         case ATTR_WIDTH:
         case ATTR_HEIGHT:
         case ATTR_BGCOLOR:
@@ -597,9 +597,9 @@ bool HTMLTableElementImpl::isURLAttribute(AttributeImpl *attr) const
 
 // --------------------------------------------------------------------------
 
-bool HTMLTablePartElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLTablePartElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch(attr->id()) {
+    switch(attr) {
         case ATTR_BGCOLOR:
         case ATTR_BACKGROUND:
         case ATTR_BORDERCOLOR:
@@ -892,9 +892,9 @@ HTMLTableCellElementImpl::~HTMLTableCellElementImpl()
 }
 
 
-bool HTMLTableCellElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLTableCellElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch(attr->id()) {
+    switch(attr) {
         case ATTR_NOWRAP:
             result = eUniversal;
             return false;
@@ -992,9 +992,9 @@ NodeImpl::Id HTMLTableColElementImpl::id() const
     return _id;
 }
 
-bool HTMLTableColElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLTableColElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    switch(attr->id()) {
+    switch(attr) {
         case ATTR_WIDTH:
             result = eUniversal;
             return false;
@@ -1028,9 +1028,9 @@ NodeImpl::Id HTMLTableCaptionElementImpl::id() const
     return ID_CAPTION;
 }
 
-bool HTMLTableCaptionElementImpl::mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const
+bool HTMLTableCaptionElementImpl::mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const
 {
-    if (attr->id() == ATTR_ALIGN) {
+    if (attr == ATTR_ALIGN) {
         result = eCaption;
         return false;
     }
diff --git a/WebCore/khtml/html/html_tableimpl.h b/WebCore/khtml/html/html_tableimpl.h
index 7533b4a..19e1551 100644
--- a/WebCore/khtml/html/html_tableimpl.h
+++ b/WebCore/khtml/html/html_tableimpl.h
@@ -98,7 +98,7 @@ public:
     // overrides
     virtual NodeImpl *addChild(NodeImpl *child);
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 
     // Used to obtain either a solid or outset border decl.
@@ -137,7 +137,7 @@ public:
         : HTMLElementImpl(doc)
         { }
 
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 };
 
@@ -206,7 +206,7 @@ public:
     
     virtual Id id() const { return _id; }
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 
     virtual void attach();
@@ -238,7 +238,7 @@ public:
     void setTable(HTMLTableElementImpl *t) { table = t; }
 
     // overrides
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 
     int span() const { return _span; }
@@ -262,7 +262,7 @@ public:
 
     virtual Id id() const;
     
-    virtual bool mapToEntry(AttributeImpl* attr, MappedAttributeEntry& result) const;
+    virtual bool mapToEntry(NodeImpl::Id attr, MappedAttributeEntry& result) const;
     virtual void parseHTMLAttribute(HTMLAttributeImpl *attr);
 };
 
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 01b5028..c440613 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -1253,6 +1253,8 @@ void RenderBlock::paintObject(PaintInfo& i, int _tx, int _ty)
     int scrolledY = _ty;
     if (hasOverflowClip())
         m_layer->subtractScrollOffset(scrolledX, scrolledY);
+    
+    paintLineBoxDecorations(paintInfo, scrolledX, scrolledY); // Underline/overline
     for (RenderObject *child = firstChild(); child; child = child->nextSibling()) {        
         // Check for page-break-before: always, and if it's set, break and bail.
         if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS &&
@@ -1273,7 +1275,7 @@ void RenderBlock::paintObject(PaintInfo& i, int _tx, int _ty)
             return;
         }
     }
-    paintLineBoxDecorations(paintInfo, scrolledX, scrolledY);
+    paintLineBoxDecorations(paintInfo, scrolledX, scrolledY, true); // Strike-through
     
     // 3. paint floats.
     if (!inlineFlow && (paintAction == PaintActionFloat || paintAction == PaintActionSelection))
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index 653ae22..317466e 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -334,17 +334,14 @@ void RenderFlow::paintLineBoxBackgroundBorder(PaintInfo& i, int _tx, int _ty)
     }
 }
 
-void RenderFlow::paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty)
+void RenderFlow::paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty, bool paintedChildren)
 {
-    if (!firstLineBox())
+    // We only paint line box decorations in strict or almost strict mode.
+    // Otherwise we let the InlineTextBoxes paint their own decorations.
+    if (style()->htmlHacks() || !firstLineBox())
         return;
 
     if (style()->visibility() == VISIBLE && i.phase == PaintActionForeground) {
-        // We only paint line box decorations in strict or almost strict mode.
-        // Otherwise we let the InlineTextBoxes paint their own decorations.
-        if (style()->htmlHacks())
-            return;
-        
         // We can check the first box and last box and avoid painting if we don't
         // intersect.
         int yPos = _ty + firstLineBox()->yPos();;
@@ -359,7 +356,7 @@ void RenderFlow::paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty)
             yPos = _ty + curr->yPos();
             h = curr->height();
             if ((yPos < i.r.y() + i.r.height()) && (yPos + h > i.r.y()))
-                curr->paintDecorations(i, _tx, _ty);
+                curr->paintDecorations(i, _tx, _ty, paintedChildren);
         }
     }
 }
diff --git a/WebCore/khtml/rendering/render_flow.h b/WebCore/khtml/rendering/render_flow.h
index 3076f7f..9bb6b26 100644
--- a/WebCore/khtml/rendering/render_flow.h
+++ b/WebCore/khtml/rendering/render_flow.h
@@ -73,7 +73,7 @@ public:
     virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false);
     
     void paintLineBoxBackgroundBorder(PaintInfo& i, int _tx, int _ty);
-    void paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty);
+    void paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty, bool paintedChildren = false);
 
     virtual QRect getAbsoluteRepaintRect();
     
diff --git a/WebCore/khtml/rendering/render_inline.cpp b/WebCore/khtml/rendering/render_inline.cpp
index e59d93a..1e3a1a0 100644
--- a/WebCore/khtml/rendering/render_inline.cpp
+++ b/WebCore/khtml/rendering/render_inline.cpp
@@ -273,11 +273,14 @@ void RenderInline::paint(PaintInfo& i, int _tx, int _ty)
 
     paintLineBoxBackgroundBorder(paintInfo, _tx, _ty);
     
+    paintLineBoxDecorations(paintInfo, _tx, _ty); // Underline/overline
+    
     for (RenderObject *child = firstChild(); child; child = child->nextSibling())
         if(!child->layer() && !child->isFloating())
             child->paint(paintInfo, _tx, _ty);
 
-    paintLineBoxDecorations(paintInfo, _tx, _ty);
+    paintLineBoxDecorations(paintInfo, _tx, _ty, true); // Strike-through
+    
     if (style()->visibility() == VISIBLE && paintInfo.phase == PaintActionOutline) {
 #if APPLE_CHANGES
         if (style()->outlineStyleIsAuto())
diff --git a/WebCore/khtml/rendering/render_line.cpp b/WebCore/khtml/rendering/render_line.cpp
index a5f52aa..4f92cc5 100644
--- a/WebCore/khtml/rendering/render_line.cpp
+++ b/WebCore/khtml/rendering/render_line.cpp
@@ -681,7 +681,7 @@ static bool shouldDrawDecoration(RenderObject* obj)
     return shouldDraw;
 }
 
-void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty)
+void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren)
 {
     // Now paint our text decorations. We only do this if we aren't in quirks mode (i.e., in
     // almost-strict mode or strict mode).
@@ -690,7 +690,9 @@ void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& i, int _tx, int _t
     _ty += m_y;
     RenderStyle* styleToUse = object()->style(m_firstLine);
     int deco = parent() ? styleToUse->textDecoration() : styleToUse->textDecorationsInEffect();
-    if (deco != TDNONE && shouldDrawDecoration(object())) {
+    if (deco != TDNONE && 
+        ((!paintedChildren && ((deco & UNDERLINE) || (deco & OVERLINE))) || (paintedChildren && (deco & LINE_THROUGH))) &&
+        shouldDrawDecoration(object())) {
 #if APPLE_CHANGES
         // Set up the appropriate text-shadow effect for the decoration.
         // FIXME: Support multiple shadow effects.  Need more from the CG API before we can do this.
@@ -709,15 +711,19 @@ void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& i, int _tx, int _t
         underline = overline = linethrough = styleToUse->color();
         if (!parent())
             object()->getTextDecorationColors(deco, underline, overline, linethrough);
-        if (deco & UNDERLINE) {
+
+        if (styleToUse->font() != p->font())
+            p->setFont(styleToUse->font());
+
+        if (deco & UNDERLINE && !paintedChildren) {
             p->setPen(underline);
             p->drawLineForText(_tx, _ty, m_baseline, w);
         }
-        if (deco & OVERLINE) {
+        if (deco & OVERLINE && !paintedChildren) {
             p->setPen(overline);
             p->drawLineForText(_tx, _ty, 0, w);
         }
-        if (deco & LINE_THROUGH) {
+        if (deco & LINE_THROUGH && paintedChildren) {
             p->setPen(linethrough);
             p->drawLineForText(_tx, _ty, 2*m_baseline/3, w);
         }
diff --git a/WebCore/khtml/rendering/render_line.h b/WebCore/khtml/rendering/render_line.h
index 970393b..900196a 100644
--- a/WebCore/khtml/rendering/render_line.h
+++ b/WebCore/khtml/rendering/render_line.h
@@ -167,7 +167,7 @@ public:
     void setPreviousLineBox(InlineRunBox* p) { m_prevLine = p; }
 
     virtual void paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty, int xOffsetOnLine) {};
-    virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty) {};
+    virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren = false) {};
     
 protected:
     InlineRunBox* m_prevLine;  // The previous box that also uses our RenderObject
@@ -223,7 +223,7 @@ public:
     virtual void adjustVerticalPosition(int delta);
 
     virtual void paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty, int xOffsetOnLine);
-    virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty);
+    virtual void paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren = false);
     
     int marginBorderPaddingLeft();
     int marginBorderPaddingRight();
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 349daa6..56fa118 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -1379,57 +1379,57 @@ void RenderObject::setStyle(RenderStyle *style)
     if (m_style == style)
         return;
 
-    // If our z-index changes value or our visibility changes,
-    // we need to dirty our stacking context's z-order list.
-    if (m_style && style) {
-        if ((m_style->hasAutoZIndex() != style->hasAutoZIndex() ||
-             m_style->zIndex() != style->zIndex() ||
-             m_style->visibility() != style->visibility()) && layer()) {
-            layer()->stackingContext()->dirtyZOrderLists();
-            if (m_style->hasAutoZIndex() != style->hasAutoZIndex() ||
-                m_style->visibility() != style->visibility())
-                layer()->dirtyZOrderLists();
+    bool affectsParentBlock = false;
+    RenderStyle::Diff d = RenderStyle::Equal;
+    if (m_style) {
+        // If our z-index changes value or our visibility changes,
+        // we need to dirty our stacking context's z-order list.
+        if (style) {
+            if ((m_style->hasAutoZIndex() != style->hasAutoZIndex() ||
+                 m_style->zIndex() != style->zIndex() ||
+                 m_style->visibility() != style->visibility()) && layer()) {
+                layer()->stackingContext()->dirtyZOrderLists();
+                if (m_style->hasAutoZIndex() != style->hasAutoZIndex() ||
+                    m_style->visibility() != style->visibility())
+                    layer()->dirtyZOrderLists();
+            }
         }
-    }
-
-    RenderStyle::Diff d = m_style ? m_style->diff( style ) : RenderStyle::Layout;
 
-    // The background of the root element or the body element could propagate up to
-    // the canvas.  Just dirty the entire canvas when our style changes substantially.
-    if (m_style && d >= RenderStyle::Visible && element() &&
-        (element()->id() == ID_HTML || element()->id() == ID_BODY))
-        canvas()->repaint();
-    else if (m_style && m_parent && d == RenderStyle::Visible && !isText())
-        // Do a repaint with the old style first, e.g., for example if we go from
-        // having an outline to not having an outline.
-        repaint();
-
-    if (m_style && m_style->position() != style->position() && layer())
-        layer()->repaintIncludingDescendants();
-
-    if (m_style && isFloating() && (m_style->floating() != style->floating()))
-        // For changes in float styles, we need to conceivably remove ourselves
-        // from the floating objects list.
-        removeFromObjectLists();
-    else if (isPositioned() && (style->position() != ABSOLUTE && style->position() != FIXED))
-        // For changes in positioning styles, we need to conceivably remove ourselves
-        // from the positioned objects list.
-        removeFromObjectLists();
-
-    bool affectsParentBlock = m_style && isFloatingOrPositioned() &&
-        (!style->isFloating() && style->position() != ABSOLUTE && style->position() != FIXED)
-        && parent() && (parent()->isBlockFlow() || parent()->isInlineFlow());
-    
-    //qDebug("new style, diff=%d", d);
-    // reset style flags
-    m_floating = false;
-    m_positioned = false;
-    m_relPositioned = false;
-    m_paintBackground = false;
-    m_hasOverflowClip = false;
-    // no support for changing the display type dynamically... object must be
-    // detached and re-attached as a different type
-    //m_inline = true;
+        d = m_style->diff(style);
+
+        // The background of the root element or the body element could propagate up to
+        // the canvas.  Just dirty the entire canvas when our style changes substantially.
+        if (d >= RenderStyle::Visible && element() &&
+            (element()->id() == ID_HTML || element()->id() == ID_BODY))
+            canvas()->repaint();
+        else if (m_parent && d == RenderStyle::Visible && !isText())
+            // Do a repaint with the old style first, e.g., for example if we go from
+            // having an outline to not having an outline.
+            repaint();
+
+        if (m_style->position() != style->position() && layer())
+            layer()->repaintIncludingDescendants();
+
+        if (isFloating() && (m_style->floating() != style->floating()))
+            // For changes in float styles, we need to conceivably remove ourselves
+            // from the floating objects list.
+            removeFromObjectLists();
+        else if (isPositioned() && (style->position() != ABSOLUTE && style->position() != FIXED))
+            // For changes in positioning styles, we need to conceivably remove ourselves
+            // from the positioned objects list.
+            removeFromObjectLists();
+        
+        // reset style flags
+        m_floating = false;
+        m_positioned = false;
+        m_relPositioned = false;
+        m_paintBackground = false;
+        m_hasOverflowClip = false;
+        
+        affectsParentBlock = m_style && isFloatingOrPositioned() &&
+            (!style->isFloating() && style->position() != ABSOLUTE && style->position() != FIXED)
+            && parent() && (parent()->isBlockFlow() || parent()->isInlineFlow());
+    }
 
     RenderStyle *oldStyle = m_style;
     m_style = style;
@@ -1437,20 +1437,18 @@ void RenderObject::setStyle(RenderStyle *style)
     CachedImage* ob = 0;
     CachedImage* nb = 0;
 
-    if (m_style)
-    {
+    if (m_style) {
         m_style->ref();
         nb = m_style->backgroundImage();
     }
-    if (oldStyle)
-    {
+    if (oldStyle) {
         ob = oldStyle->backgroundImage();
         oldStyle->deref(renderArena());
     }
 
-    if( ob != nb ) {
-        if(ob) ob->deref(this);
-        if(nb) nb->ref(this);
+    if (ob != nb) {
+        if (ob) ob->deref(this);
+        if (nb) nb->ref(this);
     }
 
     setShouldPaintBackgroundOrBorder((m_style->backgroundColor().isValid() &&
@@ -1464,7 +1462,7 @@ void RenderObject::setStyle(RenderStyle *style)
     // we already did this for the parent of the text run.
     if (d >= RenderStyle::Position && m_parent)
         setNeedsLayoutAndMinMaxRecalc();
-    else if (!isText() && m_parent && d == RenderStyle::Visible)
+    else if (d == RenderStyle::Visible && !isText() && m_parent)
         repaint();
 }
 
diff --git a/WebCore/khtml/rendering/render_style.cpp b/WebCore/khtml/rendering/render_style.cpp
index db1e575..934affa 100644
--- a/WebCore/khtml/rendering/render_style.cpp
+++ b/WebCore/khtml/rendering/render_style.cpp
@@ -347,6 +347,7 @@ void RenderStyle::arenaDelete(RenderArena *arena)
 }
 
 RenderStyle::RenderStyle()
+:m_pseudoState(PseudoUnknown), m_affectedByAttributeSelectors(false)
 {
     m_ref = 0;
     
@@ -369,6 +370,7 @@ RenderStyle::RenderStyle()
 }
 
 RenderStyle::RenderStyle(bool)
+:m_pseudoState(PseudoUnknown), m_affectedByAttributeSelectors(false)
 {
     setBitDefaults();
 
@@ -391,7 +393,8 @@ RenderStyle::RenderStyle(const RenderStyle& o)
     : inherited_flags( o.inherited_flags ), noninherited_flags( o.noninherited_flags ),
       box( o.box ), visual( o.visual ), background( o.background ), surround( o.surround ),
       css3NonInheritedData( o.css3NonInheritedData ), css3InheritedData( o.css3InheritedData ),
-      inherited( o.inherited ), pseudoStyle( 0 ), content( o.content )
+      inherited( o.inherited ), pseudoStyle( 0 ), content( o.content ), m_pseudoState(o.m_pseudoState),
+      m_affectedByAttributeSelectors(false)
 {
     m_ref = 0;
 }
diff --git a/WebCore/khtml/rendering/render_style.h b/WebCore/khtml/rendering/render_style.h
index 3dc077c..86cff44 100644
--- a/WebCore/khtml/rendering/render_style.h
+++ b/WebCore/khtml/rendering/render_style.h
@@ -136,6 +136,7 @@ private:
     DATA* data;
 };
 
+enum PseudoState { PseudoUnknown, PseudoNone, PseudoAnyLink, PseudoLink, PseudoVisited};
 
 //------------------------------------------------
 
@@ -843,6 +844,9 @@ protected:
     // added this here, so we can get rid of the vptr in this class.
     // makes up for the same size.
     ContentData *content;
+
+    PseudoState m_pseudoState : 3;
+    bool m_affectedByAttributeSelectors : 1;
     
     int m_ref;
     
@@ -1292,6 +1296,14 @@ public:
                originalDisplay() == INLINE_BOX || originalDisplay() == INLINE_TABLE;
     }
     
+    // To obtain at any time the pseudo state for a given link.
+    PseudoState pseudoState() const { return m_pseudoState; }
+    void setPseudoState(PseudoState s) { m_pseudoState = s; }
+    
+    // To tell if this style matched attribute selectors. This makes it impossible to share.
+    bool affectedByAttributeSelectors() const { return m_affectedByAttributeSelectors; }
+    void setAffectedByAttributeSelectors() { m_affectedByAttributeSelectors = true; }
+
     // Initial values for all the properties
     static bool initialBackgroundAttachment() { return true; }
     static EBackgroundRepeat initialBackgroundRepeat() { return REPEAT; }
diff --git a/WebCore/khtml/xml/dom_docimpl.cpp b/WebCore/khtml/xml/dom_docimpl.cpp
index 8cd8319..42a29af 100644
--- a/WebCore/khtml/xml/dom_docimpl.cpp
+++ b/WebCore/khtml/xml/dom_docimpl.cpp
@@ -306,7 +306,8 @@ DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
     m_styleSelectorDirty = false;
     m_inStyleRecalc = false;
     m_usesDescendantRules = false;
-    
+    m_usesSiblingRules = false;
+
     m_styleSelector = new CSSStyleSelector( this, m_usersheet, m_styleSheets, m_url,
                                             !inCompatMode() );
     m_windowEventListeners.setAutoDelete(true);
diff --git a/WebCore/khtml/xml/dom_docimpl.h b/WebCore/khtml/xml/dom_docimpl.h
index c02774a..26f4266 100644
--- a/WebCore/khtml/xml/dom_docimpl.h
+++ b/WebCore/khtml/xml/dom_docimpl.h
@@ -223,7 +223,9 @@ public:
 
     bool usesDescendantRules() { return m_usesDescendantRules; }
     void setUsesDescendantRules(bool b) { m_usesDescendantRules = b; }
-    
+    bool usesSiblingRules() { return m_usesSiblingRules; }
+    void setUsesSiblingRules(bool b) { m_usesSiblingRules = b; }\
+
     QString nextState();
 
     // Query all registered elements for their state
@@ -589,7 +591,8 @@ protected:
     bool m_styleSelectorDirty;
     bool m_inStyleRecalc;
     bool m_usesDescendantRules;
-    
+    bool m_usesSiblingRules;
+
     DOMString m_title;
     
     RenderArena* m_renderArena;
diff --git a/WebCore/kwq/KWQPainter.h b/WebCore/kwq/KWQPainter.h
index c99ff81..d51b4b2 100644
--- a/WebCore/kwq/KWQPainter.h
+++ b/WebCore/kwq/KWQPainter.h
@@ -136,7 +136,7 @@ private:
     
     void _drawPoints(const QPointArray &_points, bool winding, int index, int _npoints, bool fill);
 
-    void _updateRenderer(NSString **families);
+    void _updateRenderer();
 
     QPainterPrivate *data;
     bool _isForPrinting;
diff --git a/WebCore/kwq/KWQPainter.mm b/WebCore/kwq/KWQPainter.mm
index 50d0ffe..a94a520 100644
--- a/WebCore/kwq/KWQPainter.mm
+++ b/WebCore/kwq/KWQPainter.mm
@@ -512,7 +512,7 @@ void QPainter::drawTiledPixmap( int x, int y, int w, int h,
     KWQ_UNBLOCK_EXCEPTIONS;
 }
 
-void QPainter::_updateRenderer(NSString **families)
+void QPainter::_updateRenderer()
 {
     if (data->textRenderer == 0 || data->state.font != data->textRendererFont) {
         data->textRendererFont = data->state.font;
@@ -530,12 +530,12 @@ void QPainter::drawText(int x, int y, int, int, int alignmentFlags, const QStrin
 {
     if (data->state.paintingDisabled)
         return;
-        
+
     // Avoid allocations, use stack array to pass font families.  Normally these
     // css fallback lists are small <= 3.
-    CREATE_FAMILY_ARRAY(data->state.font, families);
+    CREATE_FAMILY_ARRAY(data->state.font, families);    
 
-    _updateRenderer(families);
+    _updateRenderer();
 
     const UniChar* str = (const UniChar*)qstring.unicode();
 
@@ -565,8 +565,8 @@ void QPainter::drawText(int x, int y, const QChar *str, int len, int from, int t
     // Avoid allocations, use stack array to pass font families.  Normally these
     // css fallback lists are small <= 3.
     CREATE_FAMILY_ARRAY(data->state.font, families);
-    
-    _updateRenderer(families);
+
+    _updateRenderer();
 
     if (from < 0)
         from = 0;
@@ -603,8 +603,8 @@ void QPainter::drawHighlightForText(int x, int minX, int maxX, int y, int h,
     // Avoid allocations, use stack array to pass font families.  Normally these
     // css fallback lists are small <= 3.
     CREATE_FAMILY_ARRAY(data->state.font, families);
-    
-    _updateRenderer(families);
+
+    _updateRenderer();
 
     if (from < 0)
         from = 0;
@@ -622,7 +622,7 @@ void QPainter::drawHighlightForText(int x, int minX, int maxX, int y, int h,
     style.letterSpacing = letterSpacing;
     style.wordSpacing = wordSpacing;
     style.smallCaps = smallCaps;
-    style.families = families;
+    style.families = families;    
     style.padding = toAdd;
     WebCoreTextGeometry geometry;
     WebCoreInitializeEmptyTextGeometry(&geometry);
@@ -639,7 +639,7 @@ void QPainter::drawLineForText(int x, int y, int yOffset, int width)
 {
     if (data->state.paintingDisabled)
         return;
-
+    _updateRenderer();
     [data->textRenderer
         drawLineForCharacters: NSMakePoint(x, y)
                yOffset:(float)yOffset

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list