[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 07:56:40 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 29ff69e75388b38357ee72f296dbac7af3cd631e
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Sep 19 22:54:38 2003 +0000

    	Fix for 3401409, fix negative z-index.  This code actually substantially
    	reworks layers to be more efficient in both painting and event handling.
    	It also fixes bugs with clipping as well as with negative z-indices.
    
            Reviewed by kocienda
    
            * khtml/css/cssstyleselector.cpp:
            * khtml/rendering/render_block.cpp:
            * khtml/rendering/render_block.h:
            * khtml/rendering/render_box.cpp:
            (RenderBox::setStyle):
            (RenderBox::repaintRectangle):
            * khtml/rendering/render_box.h:
            * khtml/rendering/render_frames.cpp:
            (RenderFrameSet::nodeAtPoint):
            * khtml/rendering/render_frames.h:
            * khtml/rendering/render_image.cpp:
            (RenderImage::nodeAtPoint):
            * khtml/rendering/render_image.h:
            * khtml/rendering/render_inline.cpp:
            (RenderInline::nodeAtPoint):
            * khtml/rendering/render_inline.h:
            * khtml/rendering/render_layer.cpp:
            (RenderLayer::RenderLayer):
            (RenderLayer::~RenderLayer):
            (RenderLayer::updateLayerPosition):
            (RenderLayer::stackingContext):
            (RenderLayer::enclosingPositionedAncestor):
            (RenderLayer::transparentAncestor):
            (RenderLayer::addChild):
            (RenderLayer::removeChild):
            (RenderLayer::convertToLayerCoords):
            (RenderLayer::checkScrollbarsAfterLayout):
            (RenderLayer::paintScrollbars):
            (RenderLayer::paint):
            (setClip):
            (restoreClip):
            (RenderLayer::paintLayer):
            (RenderLayer::nodeAtPoint):
            (RenderLayer::nodeAtPointForLayer):
            (RenderLayer::calculateClipRects):
            (RenderLayer::calculateRects):
            (RenderLayer::intersectsDamageRect):
            (RenderLayer::containsPoint):
            (hoverAncestor):
            (commonAncestor):
            (RenderLayer::updateHoverActiveState):
            (sortByZOrder):
            (RenderLayer::dirtyZOrderLists):
            (RenderLayer::updateZOrderLists):
            (RenderLayer::collectLayers):
            * khtml/rendering/render_layer.h:
            * khtml/rendering/render_object.cpp:
            (RenderObject::setStyle):
            (RenderObject::document):
            (RenderObject::renderArena):
            (RenderObject::nodeAtPoint):
            * khtml/rendering/render_object.h:
            * khtml/rendering/render_text.cpp:
            (RenderText::nodeAtPoint):
            * khtml/rendering/render_text.h:
            * khtml/xml/dom_docimpl.cpp:
            (DocumentImpl::DocumentImpl):
            (DocumentImpl::~DocumentImpl):
            (DocumentImpl::recalcStyleSelector):
            (DocumentImpl::setHoverNode):
            * khtml/xml/dom_docimpl.h:
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::paint):
            (KWQKHTMLPart::paintSelectionOnly):
            (KWQKHTMLPart::adjustPageHeight):
            * kwq/KWQRect.h:
            * kwq/KWQRenderTreeDebug.cpp:
            (write):
            (writeLayers):
            (externalRepresentation):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5009 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index c1728ce..bd4a785 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,82 @@
+2003-09-19  David Hyatt  <hyatt at apple.com>
+
+	Fix for 3401409, fix negative z-index.  This code actually substantially
+	reworks layers to be more efficient in both painting and event handling.
+	It also fixes bugs with clipping as well as with negative z-indices.
+	
+        Reviewed by kocienda
+
+        * khtml/css/cssstyleselector.cpp:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::setStyle):
+        (RenderBox::repaintRectangle):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_frames.cpp:
+        (RenderFrameSet::nodeAtPoint):
+        * khtml/rendering/render_frames.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::nodeAtPoint):
+        * khtml/rendering/render_image.h:
+        * khtml/rendering/render_inline.cpp:
+        (RenderInline::nodeAtPoint):
+        * khtml/rendering/render_inline.h:
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::RenderLayer):
+        (RenderLayer::~RenderLayer):
+        (RenderLayer::updateLayerPosition):
+        (RenderLayer::stackingContext):
+        (RenderLayer::enclosingPositionedAncestor):
+        (RenderLayer::transparentAncestor):
+        (RenderLayer::addChild):
+        (RenderLayer::removeChild):
+        (RenderLayer::convertToLayerCoords):
+        (RenderLayer::checkScrollbarsAfterLayout):
+        (RenderLayer::paintScrollbars):
+        (RenderLayer::paint):
+        (setClip):
+        (restoreClip):
+        (RenderLayer::paintLayer):
+        (RenderLayer::nodeAtPoint):
+        (RenderLayer::nodeAtPointForLayer):
+        (RenderLayer::calculateClipRects):
+        (RenderLayer::calculateRects):
+        (RenderLayer::intersectsDamageRect):
+        (RenderLayer::containsPoint):
+        (hoverAncestor):
+        (commonAncestor):
+        (RenderLayer::updateHoverActiveState):
+        (sortByZOrder):
+        (RenderLayer::dirtyZOrderLists):
+        (RenderLayer::updateZOrderLists):
+        (RenderLayer::collectLayers):
+        * khtml/rendering/render_layer.h:
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::setStyle):
+        (RenderObject::document):
+        (RenderObject::renderArena):
+        (RenderObject::nodeAtPoint):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_text.cpp:
+        (RenderText::nodeAtPoint):
+        * khtml/rendering/render_text.h:
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::DocumentImpl):
+        (DocumentImpl::~DocumentImpl):
+        (DocumentImpl::recalcStyleSelector):
+        (DocumentImpl::setHoverNode):
+        * khtml/xml/dom_docimpl.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::paint):
+        (KWQKHTMLPart::paintSelectionOnly):
+        (KWQKHTMLPart::adjustPageHeight):
+        * kwq/KWQRect.h:
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write):
+        (writeLayers):
+        (externalRepresentation):
+
 2003-09-19  Darin Adler  <darin at apple.com>
 
         Reviewed by Dave.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index c1728ce..bd4a785 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,82 @@
+2003-09-19  David Hyatt  <hyatt at apple.com>
+
+	Fix for 3401409, fix negative z-index.  This code actually substantially
+	reworks layers to be more efficient in both painting and event handling.
+	It also fixes bugs with clipping as well as with negative z-indices.
+	
+        Reviewed by kocienda
+
+        * khtml/css/cssstyleselector.cpp:
+        * khtml/rendering/render_block.cpp:
+        * khtml/rendering/render_block.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::setStyle):
+        (RenderBox::repaintRectangle):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_frames.cpp:
+        (RenderFrameSet::nodeAtPoint):
+        * khtml/rendering/render_frames.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::nodeAtPoint):
+        * khtml/rendering/render_image.h:
+        * khtml/rendering/render_inline.cpp:
+        (RenderInline::nodeAtPoint):
+        * khtml/rendering/render_inline.h:
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::RenderLayer):
+        (RenderLayer::~RenderLayer):
+        (RenderLayer::updateLayerPosition):
+        (RenderLayer::stackingContext):
+        (RenderLayer::enclosingPositionedAncestor):
+        (RenderLayer::transparentAncestor):
+        (RenderLayer::addChild):
+        (RenderLayer::removeChild):
+        (RenderLayer::convertToLayerCoords):
+        (RenderLayer::checkScrollbarsAfterLayout):
+        (RenderLayer::paintScrollbars):
+        (RenderLayer::paint):
+        (setClip):
+        (restoreClip):
+        (RenderLayer::paintLayer):
+        (RenderLayer::nodeAtPoint):
+        (RenderLayer::nodeAtPointForLayer):
+        (RenderLayer::calculateClipRects):
+        (RenderLayer::calculateRects):
+        (RenderLayer::intersectsDamageRect):
+        (RenderLayer::containsPoint):
+        (hoverAncestor):
+        (commonAncestor):
+        (RenderLayer::updateHoverActiveState):
+        (sortByZOrder):
+        (RenderLayer::dirtyZOrderLists):
+        (RenderLayer::updateZOrderLists):
+        (RenderLayer::collectLayers):
+        * khtml/rendering/render_layer.h:
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::setStyle):
+        (RenderObject::document):
+        (RenderObject::renderArena):
+        (RenderObject::nodeAtPoint):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_text.cpp:
+        (RenderText::nodeAtPoint):
+        * khtml/rendering/render_text.h:
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::DocumentImpl):
+        (DocumentImpl::~DocumentImpl):
+        (DocumentImpl::recalcStyleSelector):
+        (DocumentImpl::setHoverNode):
+        * khtml/xml/dom_docimpl.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::paint):
+        (KWQKHTMLPart::paintSelectionOnly):
+        (KWQKHTMLPart::adjustPageHeight):
+        * kwq/KWQRect.h:
+        * kwq/KWQRenderTreeDebug.cpp:
+        (write):
+        (writeLayers):
+        (externalRepresentation):
+
 2003-09-19  Darin Adler  <darin at apple.com>
 
         Reviewed by Dave.
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index 291c39a..8e3359c 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -527,6 +527,21 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e
         }
     }
 
+    // Make sure our z-index value is only applied if the object is positioned,
+    // relatively positioned, or transparent.
+    if (style->position() == STATIC && style->opacity() == 1.0f) {
+        if (e && e->getDocument()->documentElement() == e)
+            style->setZIndex(0); // The root has a z-index of 0 if not positioned or transparent.
+        else
+            style->setHasAutoZIndex(); // Everyone else gets an auto z-index.
+    }
+
+    // Auto z-index becomes 0 for transparent objects.  This prevents cases where
+    // objects that should be blended as a single unit end up with a non-transparent object
+    // wedged in between them.
+    if (style->opacity() < 1.0f && style->hasAutoZIndex())
+        style->setZIndex(0);
+    
     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
     // tables, inline blocks, inline tables, or run-ins.
     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 3c5c328..bb97360 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -1853,13 +1853,14 @@ bool RenderBlock::isPointInScrollbar(int _x, int _y, int _tx, int _ty)
     return false;    
 }
 
-bool RenderBlock::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inBox)
+bool RenderBlock::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                              HitTestAction hitTestAction, bool inBox)
 {
     bool inScrollbar = isPointInScrollbar(_x, _y, _tx+xPos(), _ty+yPos());
-    if (inScrollbar)
+    if (inScrollbar && hitTestAction != HitTestChildrenOnly)
         inBox = true;
     
-    if (m_floatingObjects && !inScrollbar) {
+    if (hitTestAction != HitTestSelfOnly && m_floatingObjects && !inScrollbar) {
         int stx = _tx + xPos();
         int sty = _ty + yPos();
         if (style()->hidesOverflow() && m_layer)
@@ -1877,7 +1878,7 @@ bool RenderBlock::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
                                               sty+o->startY + o->node->marginTop() - o->node->yPos());
     }
 
-    inBox |= RenderFlow::nodeAtPoint(info, _x, _y, _tx, _ty, inBox);
+    inBox |= RenderFlow::nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inBox);
     return inBox;
 }
 
diff --git a/WebCore/khtml/rendering/render_block.h b/WebCore/khtml/rendering/render_block.h
index e4733d1..6675b74 100644
--- a/WebCore/khtml/rendering/render_block.h
+++ b/WebCore/khtml/rendering/render_block.h
@@ -158,7 +158,8 @@ public:
                       int *heightRemaining = 0) const;
     int leftOffset(int y) const { return leftRelOffset(y, leftOffset(), true); }
 
-    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
+    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
+                             HitTestAction hitTestAction = HitTestAll, bool inside=false);
 
     bool isPointInScrollbar(int x, int y, int tx, int ty);
     
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index ab6ccc3..4ad3b97 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -108,34 +108,11 @@ void RenderBox::setStyle(RenderStyle *_style)
         m_layer = 0;
     }
 
-    adjustZIndex();
-
     // Set the text color if we're the body.
     if (isBody())
         element()->getDocument()->setTextColor(_style->color());
 }
 
-void RenderBox::adjustZIndex()
-{
-    if (m_layer) {
-        // Make sure our z-index values are only applied if we're positioned or
-        // relpositioned or transparent.
-        if (!isPositioned() && !isRelPositioned() && style()->opacity() == 1.0f) {
-            // Set the auto z-index flag.
-            if (isRoot())
-                style()->setZIndex(0);
-            else
-                style()->setHasAutoZIndex();
-        }
-        
-        // Auto z-index becomes 0 for transparent objects.  This prevents cases where
-        // objects that should be blended as a single unit end up with a non-transparent object
-        // wedged in between them.
-        if (style()->opacity() < 1.0f && style()->hasAutoZIndex())
-            style()->setZIndex(0);
-    }
-}
-
 RenderBox::~RenderBox()
 {
     //kdDebug( 6040 ) << "Element destructor: this=" << nodeName().string() << endl;
@@ -612,8 +589,9 @@ void RenderBox::repaintRectangle(int x, int y, int w, int h, bool immediate, boo
     
     // Apply the relative position offset when invalidating a rectangle.  The layer
     // is translated, but the render box isn't, so we need to do this to get the
-    // right dirty rect.
-    if (isRelPositioned())
+    // right dirty rect.  Since this is called from RenderObject::setStyle, the relative position
+    // flag on the RenderObject has been cleared, so use the one on the style().
+    if (style()->position() == RELATIVE)
         relativePositionOffset(x,y);
     
     if (style()->position()==FIXED) f=true;
diff --git a/WebCore/khtml/rendering/render_box.h b/WebCore/khtml/rendering/render_box.h
index a18711f..1023b82 100644
--- a/WebCore/khtml/rendering/render_box.h
+++ b/WebCore/khtml/rendering/render_box.h
@@ -137,9 +137,6 @@ protected:
     virtual QRect getOverflowClipRect(int tx, int ty);
     virtual QRect getClipRect(int tx, int ty);
 
-    // Called to correct the z-index after the style has been changed.
-    void adjustZIndex();
-    
     // the actual height of the contents + borders + padding
     int m_height;
 
diff --git a/WebCore/khtml/rendering/render_frames.cpp b/WebCore/khtml/rendering/render_frames.cpp
index eda1e13..611d7a6 100644
--- a/WebCore/khtml/rendering/render_frames.cpp
+++ b/WebCore/khtml/rendering/render_frames.cpp
@@ -84,9 +84,10 @@ RenderFrameSet::~RenderFrameSet()
       delete [] m_vSplitVar;
 }
 
-bool RenderFrameSet::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inside)
+bool RenderFrameSet::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                                 HitTestAction hitTestAction, bool inside)
 {
-    RenderBox::nodeAtPoint(info, _x, _y, _tx, _ty, inside);
+    RenderBox::nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inside);
 
     inside = m_resizing || canResize(_x, _y);
 
diff --git a/WebCore/khtml/rendering/render_frames.h b/WebCore/khtml/rendering/render_frames.h
index c71fa5b..4e0067b 100644
--- a/WebCore/khtml/rendering/render_frames.h
+++ b/WebCore/khtml/rendering/render_frames.h
@@ -60,7 +60,8 @@ public:
   bool canResize( int _x, int _y);
   void setResizing(bool e);
 
-  bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
+  bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
+                   HitTestAction hitTestAction = HitTestAll, bool inside=false);
 
     DOM::HTMLFrameSetElementImpl *element() const
     { return static_cast<DOM::HTMLFrameSetElementImpl*>(RenderObject::element()); }
diff --git a/WebCore/khtml/rendering/render_image.cpp b/WebCore/khtml/rendering/render_image.cpp
index 4122a1e..4ed65bc 100644
--- a/WebCore/khtml/rendering/render_image.cpp
+++ b/WebCore/khtml/rendering/render_image.cpp
@@ -439,9 +439,10 @@ void RenderImage::detach(RenderArena *arena)
     RenderReplaced::detach(arena);
 }
 
-bool RenderImage::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inside)
+bool RenderImage::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                              HitTestAction hitTestAction, bool inside)
 {
-    inside |= RenderReplaced::nodeAtPoint(info, _x, _y, _tx, _ty, inside);
+    inside |= RenderReplaced::nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inside);
 
     if (inside && element()) {
         int tx = _tx + m_x;
diff --git a/WebCore/khtml/rendering/render_image.h b/WebCore/khtml/rendering/render_image.h
index 55558d4..c8083c2 100644
--- a/WebCore/khtml/rendering/render_image.h
+++ b/WebCore/khtml/rendering/render_image.h
@@ -64,7 +64,8 @@ public:
     virtual void notifyFinished(CachedObject *finishedObj);
     void dispatchLoadEvent();
 
-    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
+    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
+                             HitTestAction hitTestAction = HitTestAll, bool inside=false);
     
     virtual short calcReplacedWidth() const;
     virtual int calcReplacedHeight() const;
diff --git a/WebCore/khtml/rendering/render_inline.cpp b/WebCore/khtml/rendering/render_inline.cpp
index c43d1dd..69fa098 100644
--- a/WebCore/khtml/rendering/render_inline.cpp
+++ b/WebCore/khtml/rendering/render_inline.cpp
@@ -366,15 +366,18 @@ const char *RenderInline::renderName() const
     return "RenderInline";
 }
 
-bool RenderInline::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inside)
+bool RenderInline::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                               HitTestAction hitTestAction, bool inside)
 {
-    // Always check our kids.
-    for (RenderObject* child = lastChild(); child; child = child->previousSibling())
-        if (!child->layer() && !child->isFloating() && child->nodeAtPoint(info, _x, _y, _tx, _ty))
-            inside = true;
-
+    // Check our kids if our HitTestAction says to.
+    if (hitTestAction != HitTestSelfOnly) {
+        for (RenderObject* child = lastChild(); child; child = child->previousSibling())
+            if (!child->layer() && !child->isFloating() && child->nodeAtPoint(info, _x, _y, _tx, _ty))
+                inside = true;
+    }
+    
     // Check our line boxes if we're still not inside.
-    if (!inside && style()->visibility() != HIDDEN) {
+    if (hitTestAction != HitTestChildrenOnly && !inside && style()->visibility() != HIDDEN) {
         // See if we're inside one of our line boxes.
         for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
             if((_y >=_ty + curr->m_y) && (_y < _ty + curr->m_y + curr->m_height) &&
@@ -401,31 +404,8 @@ bool RenderInline::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
 
         if(!info.innerNonSharedNode())
             info.setInnerNonSharedNode(element());
-
-        if (!info.URLElement()) {
-            RenderObject* p = this;
-            while (p) {
-                if (p->element() && p->element()->hasAnchor()) {
-                    info.setURLElement(p->element());
-                    break;
-                }
-                if (!isFloatingOrPositioned()) break;
-                p = p->parent();
-            }
-        }
-        
     }
 
-    if (!info.readonly()) {
-        // lets see if we need a new style
-        bool oldinside = mouseInside();
-        setMouseInside(inside);
-
-        setHoverAndActive(info, oldinside, inside);
-        if (!isInline() && continuation())
-            continuation()->setHoverAndActive(info, oldinside, inside);
-    }
-    
     return inside;
 }
 
diff --git a/WebCore/khtml/rendering/render_inline.h b/WebCore/khtml/rendering/render_inline.h
index 364e5b7..3e17624 100644
--- a/WebCore/khtml/rendering/render_inline.h
+++ b/WebCore/khtml/rendering/render_inline.h
@@ -58,7 +58,8 @@ public:
     virtual void paintObject(QPainter *, int x, int y, int w, int h,
                              int tx, int ty, PaintAction paintAction);
 
-    virtual bool nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inside);
+    virtual bool nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                             HitTestAction hitTestAction = HitTestAll, bool inside=false);
     
     virtual void calcMinMaxWidth();
 
diff --git a/WebCore/khtml/rendering/render_layer.cpp b/WebCore/khtml/rendering/render_layer.cpp
index b3864cc..05b35c7 100644
--- a/WebCore/khtml/rendering/render_layer.cpp
+++ b/WebCore/khtml/rendering/render_layer.cpp
@@ -49,15 +49,18 @@
 #include "render_arena.h"
 #include "xml/dom_docimpl.h"
 
+#include <qscrollbar.h>
+#include <qptrvector.h>
+
 using namespace DOM;
 using namespace khtml;
 
-QWidget* RenderLayer::gScrollBar = 0;
+#ifdef APPLE_CHANGES
+QScrollBar* RenderLayer::gScrollBar = 0;
+#endif
 
 #ifndef NDEBUG
 static bool inRenderLayerDetach;
-static bool inRenderLayerElementDetach;
-static bool inRenderZTreeNodeDetach;
 #endif
 
 void
@@ -73,17 +76,20 @@ m_previous( 0 ),
 m_next( 0 ),
 m_first( 0 ),
 m_last( 0 ),
-m_height( 0 ),
-m_y( 0 ),
 m_x( 0 ),
+m_y( 0 ),
 m_width( 0 ),
+m_height( 0 ),
 m_scrollX( 0 ),
 m_scrollY( 0 ),
 m_scrollWidth( 0 ),
 m_scrollHeight( 0 ),
 m_hBar( 0 ),
 m_vBar( 0 ),
-m_scrollMediator( 0 )
+m_scrollMediator( 0 ),
+m_posZOrderList( 0 ),
+m_negZOrderList( 0 ),
+m_zOrderListsDirty( true )
 {
 }
 
@@ -95,6 +101,8 @@ RenderLayer::~RenderLayer()
     delete m_hBar;
     delete m_vBar;
     delete m_scrollMediator;
+    delete m_posZOrderList;
+    delete m_negZOrderList;
 }
 
 void RenderLayer::updateLayerPosition()
@@ -135,94 +143,44 @@ void RenderLayer::updateLayerPosition()
             setWidth(m_object->overflowWidth());
         if (m_object->overflowHeight() > m_object->height())
             setHeight(m_object->overflowHeight());
-    }
+    }    
 }
 
-RenderLayer*
-RenderLayer::enclosingPositionedAncestor()
+RenderLayer *RenderLayer::stackingContext() const
 {
     RenderLayer* curr = parent();
     for ( ; curr && !curr->m_object->isCanvas() && !curr->m_object->isRoot() &&
-         !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned();
-         curr = curr->parent());
-         
+          curr->m_object->style()->hasAutoZIndex();
+          curr = curr->parent());
     return curr;
 }
 
 RenderLayer*
-RenderLayer::transparentAncestor()
+RenderLayer::enclosingPositionedAncestor() const
 {
     RenderLayer* curr = parent();
-    for ( ; curr && curr->m_object->style()->opacity() == 1.0f; curr = curr->parent());
+    for ( ; curr && !curr->m_object->isCanvas() && !curr->m_object->isRoot() &&
+         !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned();
+         curr = curr->parent());
+         
     return curr;
 }
 
+#if APPLE_CHANGES
 bool
 RenderLayer::isTransparent()
 {
     return m_object->style()->opacity() < 1.0f;
 }
 
-static RenderLayer* commonTransparentAncestor(RenderLayer* layer1, RenderLayer* layer2)
-{
-    if (!layer1 || !layer2)
-        return 0;
-    
-    for (RenderLayer* currLayer1 = layer1; currLayer1; currLayer1 = currLayer1->transparentAncestor())
-        for (RenderLayer* currLayer2 = layer2; currLayer2; currLayer2 = currLayer2->transparentAncestor())
-            if (currLayer1 == currLayer2)
-                return currLayer1;
-    
-    return 0;
-}
-
-void RenderLayer::updateTransparentState(QPainter* painter, RenderLayer* newLayer, RenderLayer*& currLayer)
-{
-    RenderLayer* transparentLayer = (!newLayer || newLayer->isTransparent()) ? newLayer :
-                                    newLayer->transparentAncestor();
-    if (transparentLayer == currLayer)
-        return;
-    
-    RenderLayer* commonAncestor = commonTransparentAncestor(currLayer, transparentLayer);
-    endTransparencyLayers(painter, currLayer, commonAncestor);
-    beginTransparencyLayers(painter, transparentLayer, commonAncestor);
-    
-    // Update our current layer.
-    currLayer = transparentLayer;
-}
-
-void RenderLayer::beginTransparencyLayers(QPainter* painter, RenderLayer* newLayer, RenderLayer* ancestorLayer)
+RenderLayer*
+RenderLayer::transparentAncestor()
 {
-    if (!newLayer || newLayer == ancestorLayer)
-        return;
-    
-    // We need to open from the outside in, so begin ancestor layers first.
-    beginTransparencyLayers(painter, newLayer->transparentAncestor(), ancestorLayer);
-    
-    // Konqueror should add its own code for setting up the opacity layer here.
-    // Safari uses a custom extension to QPainter to communicate with CoreGraphics.
-#ifdef APPLE_CHANGES
-    // Begin the layer
-    painter->beginTransparencyLayer(newLayer->renderer()->style()->opacity());
-#endif
+    RenderLayer* curr = parent();
+    for ( ; curr && curr->m_object->style()->opacity() == 1.0f; curr = curr->parent());
+    return curr;
 }
-
-void RenderLayer::endTransparencyLayers(QPainter* painter, RenderLayer* newLayer, RenderLayer* ancestorLayer)
-{
-    if (!newLayer || newLayer == ancestorLayer)
-        return;
-    
-    // We need to close from the inside out.
-    
-    // Konqueror should add its own code for popping opacity layers here.
-    // Safari uses a custom extension to QPainter to communicate with CoreGraphics.
-#ifdef APPLE_CHANGES
-    // End the layer
-    painter->endTransparencyLayer();
 #endif
-    
-    endTransparencyLayers(painter, newLayer->transparentAncestor(), ancestorLayer);
-}
 
 void* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw()
 {
@@ -269,6 +227,9 @@ void RenderLayer::addChild(RenderLayer *child, RenderLayer* beforeChild)
         setLastChild(child);
    
     child->setParent(this);
+
+    // Dirty the z-order list in which we are contained.
+    child->stackingContext()->dirtyZOrderLists();
 }
 
 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
@@ -284,6 +245,13 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
     if (m_last == oldChild)
         m_last = oldChild->previousSibling();
 
+    // Dirty the z-order list in which we are contained.  When called via the
+    // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
+    // from the main layer tree, so we need to null-check the |stackingContext| value.
+    RenderLayer* stackingContext = oldChild->stackingContext();
+    if (stackingContext)
+        oldChild->stackingContext()->dirtyZOrderLists();
+    
     oldChild->setPreviousSibling(0);
     oldChild->setNextSibling(0);
     oldChild->setParent(0);
@@ -330,7 +298,7 @@ void RenderLayer::insertOnlyThisLayer()
 }
 
 void 
-RenderLayer::convertToLayerCoords(RenderLayer* ancestorLayer, int& x, int& y)
+RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const
 {
     if (ancestorLayer == this)
         return;
@@ -533,8 +501,8 @@ RenderLayer::checkScrollbarsAfterLayout()
     if (bottomPos - m_object->borderTop() > m_scrollHeight)
         m_scrollHeight = bottomPos - m_object->borderTop();
     
-    bool needHorizontalBar = rightPos > m_width;
-    bool needVerticalBar = bottomPos > m_height;
+    bool needHorizontalBar = rightPos > width();
+    bool needVerticalBar = bottomPos > height();
 
     bool haveHorizontalBar = m_hBar;
     bool haveVerticalBar = m_vBar;
@@ -583,425 +551,405 @@ RenderLayer::checkScrollbarsAfterLayout()
     }
 }
 
+#if APPLE_CHANGES
 void
-RenderLayer::paintScrollbars(QPainter* p, int x, int y, int w, int h)
+RenderLayer::paintScrollbars(QPainter* p, const QRect& damageRect)
 {
-#if APPLE_CHANGES
     if (m_hBar)
-        m_hBar->paint(p, QRect(x, y, w, h));
+        m_hBar->paint(p, damageRect);
     if (m_vBar)
-        m_vBar->paint(p, QRect(x, y, w, h));
-#endif
+        m_vBar->paint(p, damageRect);
 }
+#endif
 
 void
-RenderLayer::paint(QPainter *p, int x, int y, int w, int h, bool selectionOnly)
+RenderLayer::paint(QPainter *p, const QRect& damageRect, bool selectionOnly)
 {
-    // Create the z-tree of layers that should be displayed.
-    QRect damageRect(x,y,w,h);
-    RenderZTreeNode* node = constructZTree(damageRect, damageRect, this);
-    if (!node)
-        return;
+    paintLayer(this, p, damageRect, selectionOnly);
+}
 
-    // Flatten the tree into a back-to-front list for painting.
-    QPtrVector<RenderLayerElement> layerList;
-    constructLayerList(node, &layerList);
+static void setClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
+{
+    if (paintDirtyRect == clipRect)
+        return;
 
-    // Walk the list and paint each layer, adding in the appropriate offset.
-    QRect paintRect(x, y, w, h);
-    QRect currRect(paintRect);
-    RenderLayer* currentTransparentLayer = 0;
+    p->save();
     
-    uint count = layerList.count();
-    for (uint i = 0; i < count; i++) {
-        RenderLayerElement* elt = layerList.at(i);
-
-        // Elements add in their own positions as a translation factor.  This forces
-        // us to subtract that out, so that when it's added back in, we get the right
-        // bounds.  This is really disgusting (that paint only sets up the right paint
-        // position after you call into it). -dwh
-        //printf("Painting layer at %d %d\n", elt->absBounds.x(), elt->absBounds.y());
-
-        bool updatedTransparentState = false;
-        if (elt->clipOriginator) {
-            // We originated a clip (we're either positioned or an element with
-            // overflow: hidden).  We need to paint our background and border, subject
-            // to clip regions established by our parent layers.
-            if (elt->backgroundClipRect != currRect) {
-                if (currRect != paintRect)
-                    p->restore(); // Pop the clip.
-
-                // This is called to update our transparency state.
-                updateTransparentState(p, elt->layer, currentTransparentLayer);
-                updatedTransparentState = true;
-                
-                currRect = elt->backgroundClipRect;
-                
-                // Now apply the clip rect.
-                QRect clippedRect = p->xForm(currRect);
 #if APPLE_CHANGES
-                p->save();
-                p->addClip(clippedRect);
+    p->addClip(clipRect);
 #else
-                QRegion creg(cr);
-                QRegion old = p->clipRegion();
-                if (!old.isNull())
-                    creg = old.intersect(creg);
-            
-                p->save();
-                p->setClipRegion(creg);
+    QRect clippedRect = p->xForm(clipRect);
+    QRegion creg(clippedRect);
+    QRegion old = p->clipRegion();
+    if (!old.isNull())
+        creg = old.intersect(creg);
+    p->setClipRegion(creg);
 #endif
-            }
-            
-            // A clip is in effect.  The clip is never allowed to clip our render object's
-            // background, borders or scrollbars.  Go ahead and draw those now without our clip (that will
-            // be used for our children) in effect.
-            elt->layer->renderer()->paintBoxDecorations(p, x, y, w, h,
-                                elt->absBounds.x(),
-                                elt->absBounds.y());
+    
+}
 
-            // Position our scrollbars prior to painting.
-            elt->layer->positionScrollbars(elt->absBounds);
+static void restoreClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
+{
+    if (paintDirtyRect == clipRect)
+        return;
+    p->restore();
+}
+
+void
+RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
+                        const QRect& paintDirtyRect, bool selectionOnly)
+{
+    // Calculate the clip rects we should use.
+    QRect layerBounds, damageRect, clipRectToApply;
+    calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply);
+    int x = layerBounds.x();
+    int y = layerBounds.y();
+                             
+    // Ensure our z-order lists are up-to-date.
+    updateZOrderLists();
 
 #if APPLE_CHANGES
-            // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
-            // z-index.
-            elt->layer->paintScrollbars(p, x, y, w, h);
+    // Set our transparency if we need to.
+    if (isTransparent())
+        p->beginTransparencyLayer(renderer()->style()->opacity());
 #endif
-        }
-        
-        if (elt->clipRect != currRect) {
-            if (currRect != paintRect)
-                p->restore(); // Pop the clip.
-
-            if (!updatedTransparentState) {
-                // This is called to update our transparency state.
-                updateTransparentState(p, elt->layer, currentTransparentLayer);
-                updatedTransparentState = true;
-            }
-            
-            currRect = elt->clipRect;
-            if (currRect != paintRect) {
-                                
-                // Now apply the clip rect.
-                QRect clippedRect = p->xForm(currRect);
+    
+    // We want to paint our layer, but only if we intersect the damage rect.
+    bool shouldPaint = intersectsDamageRect(layerBounds, damageRect);
+    if (shouldPaint && !selectionOnly) {
+        // Paint our background first, before painting any child layers.
+        if (!damageRect.isEmpty()) {
+            // Establish the clip used to paint our background.
+            setClip(p, paintDirtyRect, damageRect);
+
+            // Paint the background.
+            renderer()->paint(p, damageRect.x(), damageRect.y(),
+                              damageRect.width(), damageRect.height(),
+                              x - renderer()->xPos(), y - renderer()->yPos(),
+                              PaintActionElementBackground);
+
+            // Position our scrollbars.
+            positionScrollbars(layerBounds);
+
 #if APPLE_CHANGES
-                p->save();
-                p->addClip(clippedRect);
-#else
-                QRegion creg(cr);
-                QRegion old = p->clipRegion();
-                if (!old.isNull())
-                    creg = old.intersect(creg);
-            
-                p->save();
-                p->setClipRegion(creg);
+            // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
+            // z-index.  We paint after we painted the background/border, so that the scrollbars will
+            // sit above the background/border.
+            paintScrollbars(p, damageRect);
 #endif
-            }
+            // Restore the clip.
+            restoreClip(p, paintDirtyRect, damageRect);
         }
+    }
 
-        if (!updatedTransparentState) {
-            // This is called to update our transparency state.
-            updateTransparentState(p, elt->layer, currentTransparentLayer);
-            updatedTransparentState = true;
-        }
-        
-        if (currRect.isEmpty())
-            continue;
-        
-        if (selectionOnly) {
-            if (elt->layerElementType == RenderLayerElement::Normal ||
-                elt->layerElementType == RenderLayerElement::Foreground)
-                elt->layer->renderer()->paint(p, x, y, w, h,
-                                            elt->absBounds.x() - elt->layer->renderer()->xPos(),
-                                            elt->absBounds.y() - elt->layer->renderer()->yPos(),
-                                            PaintActionSelection);
-        } else {
-            if (elt->layerElementType == RenderLayerElement::Normal ||
-                elt->layerElementType == RenderLayerElement::Background)
-                elt->layer->renderer()->paint(p, x, y, w, h,
-                                            elt->absBounds.x() - elt->layer->renderer()->xPos(),
-                                            elt->absBounds.y() - elt->layer->renderer()->yPos(),
-                                            PaintActionElementBackground);
-
-            if (elt->layerElementType == RenderLayerElement::Normal ||
-                elt->layerElementType == RenderLayerElement::Foreground) {
-                elt->layer->renderer()->paint(p, x, y, w, h,
-                                              elt->absBounds.x() - elt->layer->renderer()->xPos(),
-                                              elt->absBounds.y() - elt->layer->renderer()->yPos(),
-                                              PaintActionChildBackgrounds);
-                elt->layer->renderer()->paint(p, x, y, w, h,
-                                            elt->absBounds.x() - elt->layer->renderer()->xPos(),
-                                            elt->absBounds.y() - elt->layer->renderer()->yPos(),
-                                            PaintActionFloat);
-                elt->layer->renderer()->paint(p, x, y, w, h,
-                                            elt->absBounds.x() - elt->layer->renderer()->xPos(),
-                                            elt->absBounds.y() - elt->layer->renderer()->yPos(),
-                                            PaintActionForeground);
-            }
+    // Now walk the sorted list of children with negative z-indices.
+    if (m_negZOrderList) {
+        uint count = m_negZOrderList->count();
+        for (uint i = 0; i < count; i++) {
+            RenderLayer* child = m_negZOrderList->at(i);
+            child->paintLayer(rootLayer, p, paintDirtyRect, selectionOnly);
         }
     }
     
-    if (currRect != paintRect)
-        p->restore(); // Pop the clip.
-        
-    updateTransparentState(p, 0, currentTransparentLayer); // End any open transparency layers.
-    
-    node->detach(renderer()->renderArena());
-}
+    // Now establish the appropriate clip and paint our child RenderObjects.
+    if (shouldPaint && !clipRectToApply.isEmpty()) {
+        // Set up the clip used when painting our children.
+        setClip(p, paintDirtyRect, clipRectToApply);
+
+        if (selectionOnly)
+            renderer()->paint(p, clipRectToApply.x(), clipRectToApply.y(),
+                              clipRectToApply.width(), clipRectToApply.height(),
+                              x - renderer()->xPos(), y - renderer()->yPos(), PaintActionSelection);
+        else {
+            renderer()->paint(p, clipRectToApply.x(), clipRectToApply.y(),
+                              clipRectToApply.width(), clipRectToApply.height(),
+                              x - renderer()->xPos(), y - renderer()->yPos(), PaintActionChildBackgrounds);
+            renderer()->paint(p, clipRectToApply.x(), clipRectToApply.y(),
+                              clipRectToApply.width(), clipRectToApply.height(),
+                              x - renderer()->xPos(), y - renderer()->yPos(), PaintActionFloat);
+            renderer()->paint(p, clipRectToApply.x(), clipRectToApply.y(),
+                              clipRectToApply.width(), clipRectToApply.height(),
+                              x - renderer()->xPos(), y - renderer()->yPos(), PaintActionForeground);
+        }
 
-void
-RenderLayer::clearOtherLayersHoverActiveState()
-{
-    if (!m_parent)
-        return;
-        
-    for (RenderLayer* curr = m_parent->firstChild(); curr; curr = curr->nextSibling()) {
-        if (curr == this)
-            continue;
-        curr->clearHoverAndActiveState(curr->renderer());
+        // Now restore our clip.
+        restoreClip(p, paintDirtyRect, clipRectToApply);
+    }
+    
+    // Now walk the sorted list of children with positive z-indices.
+    if (m_posZOrderList) {
+        uint count = m_posZOrderList->count();
+        for (uint i = 0; i < count; i++) {
+            RenderLayer* child = m_posZOrderList->at(i);
+            child->paintLayer(rootLayer, p, paintDirtyRect, selectionOnly);
+        }
     }
     
-    m_parent->clearOtherLayersHoverActiveState();
+#if APPLE_CHANGES
+    // End our transparency layer
+    if (isTransparent())
+        p->endTransparencyLayer();
+#endif
 }
 
-void
-RenderLayer::clearHoverAndActiveState(RenderObject* obj)
+bool
+RenderLayer::nodeAtPoint(RenderObject::NodeInfo& info, int x, int y)
 {
-    if (!obj->mouseInside())
-        return;
+#if APPLE_CHANGES
+    // Clear our our scrollbar variable
+    RenderLayer::gScrollBar = 0;
+#endif
     
-    obj->setMouseInside(false);
-    if (obj->element()) {
-        obj->element()->setActive(false);
-        if (obj->style()->affectedByHoverRules() || obj->style()->affectedByActiveRules())
-            obj->element()->setChanged(true);
+    QRect damageRect(m_x, m_y, width(), height());
+    RenderLayer* insideLayer = nodeAtPointForLayer(this, info, x, y, damageRect);
+
+    // Now determine if the result is inside an anchor.
+    DOM::NodeImpl* node = info.innerNode();
+    while (node) {
+        if (node->hasAnchor())
+            info.setURLElement(node);
+        node = node->parentNode();
     }
-    
-    for (RenderObject* child = obj->firstChild(); child; child = child->nextSibling())
-        if (child->mouseInside())
-            clearHoverAndActiveState(child);
+
+    // Next set up the correct :hover/:active state along the new chain.
+    updateHoverActiveState(info);
+
+    // Now return whether we were inside this layer (this will always be true for the root
+    // layer).
+    return insideLayer;
 }
 
-bool
-RenderLayer::nodeAtPoint(RenderObject::NodeInfo& info, int x, int y)
+RenderLayer*
+RenderLayer::nodeAtPointForLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
+                                 int xMousePos, int yMousePos, const QRect& hitTestRect)
 {
-    // Clear out our global scrollbar tracking variable.
-    gScrollBar = 0;
+    // Calculate the clip rects we should use.
+    QRect layerBounds, bgRect, fgRect;
+    calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect);
     
-    bool inside = false;
+    // Ensure our z-order lists are up-to-date.
+    updateZOrderLists();
+
+    // This variable tracks which layer the mouse ends up being inside.  The minute we find an insideLayer,
+    // we are done and can return it.
     RenderLayer* insideLayer = 0;
-    QRect damageRect(m_x, m_y, m_width, m_height);
-    RenderZTreeNode* node = constructZTree(damageRect, damageRect, this, true, x, y);
-    if (!node)
-        return false;
-
-    // Flatten the tree into a back-to-front list for painting.
-    QPtrVector<RenderLayerElement> layerList;
-    constructLayerList(node, &layerList);
-
-    // Walk the list and test each layer, adding in the appropriate offset.
-    uint count = layerList.count();
-    for (int i = count-1; i >= 0; i--) {
-        RenderLayerElement* elt = layerList.at(i);
-        
-        // Elements add in their own positions as a translation factor.  This forces
-        // us to subtract that out, so that when it's added back in, we get the right
-        // bounds.  This is really disgusting (that paint only sets up the right paint
-        // position after you call into it). -dwh
-        //printf("Painting layer at %d %d\n", elt->absBounds.x(), elt->absBounds.y());
-
-        inside = elt->layer->renderer()->nodeAtPoint(info, x, y,
-                                      elt->absBounds.x() - elt->layer->renderer()->xPos(),
-                                      elt->absBounds.y() - elt->layer->renderer()->yPos());
-        if (inside) {
-            // For foreground layer elements where the layer has been split into two, we
-            // are only considered to be inside the foreground layer if we hit content other
-            // than ourselves.
-            if (elt->layerElementType == RenderLayerElement::Foreground &&
-                info.innerNode() == elt->layer->renderer()->element()) {
-                inside = false;
-                info.setInnerNode(0);
-                info.setInnerNonSharedNode(0);
-                info.setURLElement(0);
-                continue;
-            }
-            // Otherwise the mouse is inside this layer, and we can stop looking.
-            insideLayer = elt->layer;
-            break;
+    
+    // Begin by walking our list of positive layers from highest z-index down to the lowest
+    // z-index.
+    if (m_posZOrderList) {
+        uint count = m_posZOrderList->count();
+        for (int i = count-1; i >= 0; i--) {
+            RenderLayer* child = m_posZOrderList->at(i);
+            insideLayer = child->nodeAtPointForLayer(rootLayer, info, xMousePos, yMousePos, hitTestRect);
+            if (insideLayer)
+                return insideLayer;
         }
     }
-    node->detach(renderer()->renderArena());
 
-    if (insideLayer) {
-        // Clear out the other layers' hover/active state
-        insideLayer->clearOtherLayersHoverActiveState();
-    
-        // Now clear out our descendant layers
-        for (RenderLayer* child = insideLayer->firstChild();
-             child; child = child->nextSibling())
-            child->clearHoverAndActiveState(child->renderer());
+    // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
+    if (containsPoint(xMousePos, yMousePos, fgRect) &&
+        renderer()->nodeAtPoint(info, xMousePos, yMousePos,
+                                layerBounds.x() - renderer()->xPos(),
+                                layerBounds.y() - renderer()->yPos(),
+                                HitTestChildrenOnly))
+        return this;
+        
+    // Now check our negative z-index children.
+    if (m_negZOrderList) {
+        uint count = m_negZOrderList->count();
+        for (int i = count-1; i >= 0; i--) {
+            RenderLayer* child = m_negZOrderList->at(i);
+            insideLayer = child->nodeAtPointForLayer(rootLayer, info, xMousePos, yMousePos, hitTestRect);
+            if (insideLayer)
+                return insideLayer;
+        }
     }
-    
-    return inside;
+
+    // Next we want to see if the mouse pos is inside this layer but not any of its children.
+    if (containsPoint(xMousePos, yMousePos, bgRect) &&
+        renderer()->nodeAtPoint(info, xMousePos, yMousePos,
+                                layerBounds.x() - renderer()->xPos(),
+                                layerBounds.y() - renderer()->yPos(),
+                                HitTestSelfOnly))
+        return this;
+
+    // No luck.
+    return 0;
 }
 
-RenderLayer::RenderZTreeNode*
-RenderLayer::constructZTree(QRect overflowClipRect, QRect posClipRect,
-                            RenderLayer* rootLayer,
-                            bool eventProcessing, int xMousePos, int yMousePos)
+void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, QRect& overflowClipRect,
+                                     QRect& posClipRect, QRect& fixedClipRect)
 {
-    // The arena we use for allocating our temporary ztree elements.
-    RenderArena* renderArena = renderer()->renderArena();
-    
-    // This variable stores the result we will hand back.
-    RenderZTreeNode* returnNode = 0;
-
-    // FIXME: A child render object or layer could override visibility.  Don't remove this
-    // optimization though until nodeAtPoint is patched as well.
-    //
-    // If a layer isn't visible, then none of its child layers are visible either.
-    // Don't build this branch of the z-tree, since these layers should not be painted.
-    if (renderer()->style()->visibility() != VISIBLE)
-        return 0;
-    
-    // Compute this layer's absolute position, so that we can compare it with our
-    // damage rect and avoid repainting the layer if it falls outside that rect.
-    // An exception to this rule is the root layer, which always paints (hence the
-    // m_parent null check below).
-    updateLayerPosition(); // For relpositioned layers or non-positioned layers,
-                            // we need to keep in sync, since we may have shifted relative
-                            // to our parent layer.
-                               
-    int x = 0;
-    int y = 0;
-    convertToLayerCoords(rootLayer, x, y);
-    QRect layerBounds(x, y, width(), height());
-     
-    returnNode = new (renderArena) RenderZTreeNode(this);
-
-    // Positioned elements are clipped according to the posClipRect.  All other
-    // layers are clipped according to the overflowClipRect.
-    QRect clipRectToApply = m_object->isPositioned() ? posClipRect : overflowClipRect;
-    QRect damageRect = clipRectToApply.intersect(layerBounds);
-    
-    // Clip applies to *us* as well, so go ahead and update the damageRect.
-    if (m_object->hasClip())
-        damageRect = damageRect.intersect(m_object->getClipRect(x,y));
+    if (parent())
+        parent()->calculateClipRects(rootLayer, overflowClipRect, posClipRect, fixedClipRect);
         
-    // If we establish a clip rect, then we want to intersect that rect
-    // with the damage rect to form a new damage rect.
-    bool clipOriginator = false;
+    updateLayerPosition(); // For relpositioned layers or non-positioned layers,
+                           // we need to keep in sync, since we may have shifted relative
+                           // to our parent layer.
+
+    // A fixed object is essentially the root of its containing block hierarchy, so when
+    // we encounter such an object, we reset our clip rects to the fixedClipRect.
+    if (m_object->style()->position() == FIXED) {
+        posClipRect = fixedClipRect;
+        overflowClipRect = fixedClipRect;
+    }
+    else if (m_object->style()->position() == RELATIVE)
+        posClipRect = overflowClipRect;
     
-    // Update the clip rects that will be passed to children layers.
+    // Update the clip rects that will be passed to child layers.
     if (m_object->hasOverflowClip() || m_object->hasClip()) {
         // This layer establishes a clip of some kind.
-        clipOriginator = true;
+        int x = 0;
+        int y = 0;
+        convertToLayerCoords(rootLayer, x, y);
+        
         if (m_object->hasOverflowClip()) {
             QRect newOverflowClip = m_object->getOverflowClipRect(x,y);
             overflowClipRect  = newOverflowClip.intersect(overflowClipRect);
-            clipRectToApply = clipRectToApply.intersect(newOverflowClip);
             if (m_object->isPositioned() || m_object->isRelPositioned())
                 posClipRect = newOverflowClip.intersect(posClipRect);
         }
         if (m_object->hasClip()) {
             QRect newPosClip = m_object->getClipRect(x,y);
-            posClipRect = newPosClip.intersect(posClipRect);
-            overflowClipRect = overflowClipRect.intersect(posClipRect);
-            clipRectToApply = clipRectToApply.intersect(newPosClip);
+            posClipRect = posClipRect.intersect(newPosClip);
+            overflowClipRect = overflowClipRect.intersect(newPosClip);
+            fixedClipRect = fixedClipRect.intersect(newPosClip);
         }
     }
+}
+
+void RenderLayer::calculateRects(const RenderLayer* rootLayer, const QRect& paintDirtyRect, QRect& layerBounds,
+                                 QRect& backgroundRect, QRect& foregroundRect)
+{
+    QRect overflowClipRect = paintDirtyRect;
+    QRect posClipRect = paintDirtyRect;
+    QRect fixedClipRect = paintDirtyRect;
+    if (parent())
+        parent()->calculateClipRects(rootLayer, overflowClipRect, posClipRect, fixedClipRect);
+
+    updateLayerPosition();
     
-    // Walk our list of child layers looking only for those layers that have a 
-    // non-negative z-index (a z-index >= 0).
-    RenderZTreeNode* lastChildNode = 0;
-    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->zIndex() < 0)
-            continue; // Ignore negative z-indices in this first pass.
-
-        RenderZTreeNode* childNode = child->constructZTree(overflowClipRect, posClipRect, 
-                                                           rootLayer, eventProcessing, 
-                                                           xMousePos, yMousePos);
-        if (childNode) {
-            // Put the new node into the tree at the front of the parent's list.
-            if (lastChildNode)
-                lastChildNode->next = childNode;
-            else
-                returnNode->child = childNode;
-            lastChildNode = childNode;
-        }
-    }
+    int x = 0;
+    int y = 0;
+    convertToLayerCoords(rootLayer, x, y);
+    layerBounds = QRect(x,y,width(),height());
 
-    // Now add a leaf node for ourselves, but only if we intersect the damage
-    // rect.  This intersection test is valid only for replaced elements or
-    // block elements, since inline non-replaced elements have a width of 0 (and
-    // thus the layer does too).  We also exclude the root from this test, since
-    // the HTML can be much taller than the root (because of scrolling).
-    if (renderer()->isCanvas() || renderer()->isRoot() || renderer()->isBody() ||
-        renderer()->hasOverhangingFloats() || 
-        (renderer()->isInline() && !renderer()->isReplaced()) ||
-        (eventProcessing && damageRect.contains(xMousePos,yMousePos)) ||
-        (!eventProcessing && layerBounds.intersects(damageRect))) {
-        RenderLayerElement* layerElt = new (renderArena) RenderLayerElement(this, layerBounds, 
-                                                              damageRect, clipRectToApply,
-                                                              clipOriginator, x, y);
-        if (returnNode->child) {
-            RenderZTreeNode* leaf = new (renderArena) RenderZTreeNode(layerElt);
-            leaf->next = returnNode->child;
-            returnNode->child = leaf;
-            
-            // We are an interior node and have other child layers.  Our layer
-            // will need to be sorted with the other layers as though it has
-            // a z-index of 0.
-            if (!layerElt->zauto)
-                layerElt->zindex = 0;
-        }
-        else
-            returnNode->layerElement = layerElt;
-    } 
+    backgroundRect = m_object->style()->position() == FIXED ? fixedClipRect :
+        (m_object->isPositioned() ? posClipRect : overflowClipRect);
+    foregroundRect = backgroundRect;
     
-    // Now look for children that have a negative z-index.
-    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->zIndex() >= 0)
-            continue; // Ignore non-negative z-indices in this second pass.
-
-        RenderZTreeNode* childNode = child->constructZTree(overflowClipRect, posClipRect,
-                                                           rootLayer, eventProcessing,
-                                                           xMousePos, yMousePos);
-        if (childNode) {
-            // Deal with the case where all our children views had negative z-indices.
-            // Demote our leaf node and make a new interior node that can hold these
-            // children.
-            if (returnNode->layerElement) {
-                RenderZTreeNode* leaf = returnNode;
-                returnNode = new (renderArena) RenderZTreeNode(this);
-                returnNode->child = leaf;
-            }
-            
-            // Put the new node into the tree at the front of the parent's list.
-            childNode->next = returnNode->child;
-            returnNode->child = childNode;
+    // Update the clip rects that will be passed to child layers.
+    if (m_object->hasOverflowClip() || m_object->hasClip()) {
+        // This layer establishes a clip of some kind.
+        if (m_object->hasOverflowClip())
+            foregroundRect = foregroundRect.intersect(m_object->getOverflowClipRect(x,y));
+        if (m_object->hasClip()) {
+            // Clip applies to *us* as well, so go ahead and update the damageRect.
+            QRect newPosClip = m_object->getClipRect(x,y);
+            backgroundRect = backgroundRect.intersect(newPosClip);
+            foregroundRect = foregroundRect.intersect(newPosClip);
         }
+
+        // If we establish a clip at all, then go ahead and make sure our background
+        // rect is intersected with our layer's bounds.
+        backgroundRect = backgroundRect.intersect(layerBounds);
     }
-    
-    return returnNode;
 }
 
-void
-RenderLayer::constructLayerList(RenderZTreeNode* ztree, QPtrVector<RenderLayerElement>* result)
+bool RenderLayer::intersectsDamageRect(const QRect& layerBounds, const QRect& damageRect) const
+{
+    return (renderer()->isCanvas() || renderer()->isRoot() || renderer()->isBody() ||
+            renderer()->hasOverhangingFloats() ||
+            (renderer()->isInline() && !renderer()->isReplaced()) ||
+            layerBounds.intersects(damageRect));
+}
+
+bool RenderLayer::containsPoint(int x, int y, const QRect& damageRect) const
+{
+    return (renderer()->isCanvas() || renderer()->isRoot() || renderer()->isBody() ||
+            renderer()->hasOverhangingFloats() ||
+            (renderer()->isInline() && !renderer()->isReplaced()) ||
+            damageRect.contains(x, y));
+}
+
+// This code has been written to anticipate the addition of CSS3-::outside and ::inside generated
+// content (and perhaps XBL).  That's why it uses the render tree and not the DOM tree.
+static RenderObject* hoverAncestor(RenderObject* obj)
+{
+    return (!obj->isInline() && obj->continuation()) ? obj->continuation() : obj->parent();
+}
+
+static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2)
 {
-    // This merge buffer is just a temporary used during computation as we do merge sorting.
-    QPtrVector<RenderLayerElement> mergeBuffer;
-    ztree->constructLayerList(&mergeBuffer, result);
+    if (!obj1 || !obj2)
+        return 0;
+
+    for (RenderObject* currObj1 = obj1; currObj1; currObj1 = hoverAncestor(currObj1))
+        for (RenderObject* currObj2 = obj2; currObj2; currObj2 = hoverAncestor(currObj2))
+            if (currObj1 == currObj2)
+                return currObj1;
+
+    return 0;
+}
+
+void RenderLayer::updateHoverActiveState(RenderObject::NodeInfo& info)
+{
+    // We don't update :hover/:active state when the info is marked as readonly.
+    if (info.readonly())
+        return;
+    
+    // Check to see if the hovered node has changed.  If not, then we don't need to
+    // do anything.  An exception is if we just went from :hover into :hover:active,
+    // in which case we need to update to get the new :active state.
+    DOM::DocumentImpl* doc = renderer()->document();
+    DOM::NodeImpl* oldHoverNode = doc ? doc->hoverNode() : 0;
+    DOM::NodeImpl* newHoverNode = info.innerNode();
+        
+    if (oldHoverNode == newHoverNode && (!oldHoverNode || oldHoverNode->active() == info.active()))
+        return;
+
+    // Update our current hover node.
+    info.innerNode()->getDocument()->setHoverNode(newHoverNode);
+    
+    // We have two different objects.  Fetch their renderers.
+    RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;
+    RenderObject* newHoverObj = info.innerNode() ? info.innerNode()->renderer() : 0;
+    
+    // Locate the common ancestor render object for the two renderers.
+    RenderObject* ancestor = commonAncestor(oldHoverObj, newHoverObj);
+    
+    // The old hover path only needs to be cleared up to (and not including) the common ancestor;
+    for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = hoverAncestor(curr)) {
+        curr->setMouseInside(false);
+        if (curr->element() && !curr->isText()) {
+            bool oldActive = curr->element()->active();
+            curr->element()->setActive(false);
+            if (curr->style()->affectedByHoverRules() ||
+                (curr->style()->affectedByActiveRules() && oldActive))
+                curr->element()->setChanged();
+        }
+    }
+
+    // Now set the hover state for our new object up to the root.
+    for (RenderObject* curr = newHoverObj; curr; curr = hoverAncestor(curr)) {
+        bool oldInside = curr->mouseInside();
+        curr->setMouseInside(true);
+        if (curr->element() && !curr->isText()) {
+            bool oldActive = curr->element()->active();
+            curr->element()->setActive(info.active());
+            if ((curr->style()->affectedByHoverRules() && !oldInside) ||
+                (curr->style()->affectedByActiveRules() && oldActive != info.active()))
+                curr->element()->setChanged();
+        }
+    }
 }
 
 // Sort the buffer from lowest z-index to highest.  The common scenario will have
 // most z-indices equal, so we optimize for that case (i.e., the list will be mostly
 // sorted already).
-static void sortByZOrder(QPtrVector<RenderLayer::RenderLayerElement>* buffer,
-                         QPtrVector<RenderLayer::RenderLayerElement>* mergeBuffer,
-                         uint start,
-                         uint end)
+static void sortByZOrder(QPtrVector<RenderLayer::RenderLayer>* buffer,
+                         QPtrVector<RenderLayer::RenderLayer>* mergeBuffer,
+                         uint start, uint end)
 {
     if (start >= end)
         return; // Sanity check.
@@ -1011,9 +959,9 @@ static void sortByZOrder(QPtrVector<RenderLayer::RenderLayerElement>* buffer,
         for (uint i = end-1; i > start; i--) {
             bool sorted = true;
             for (uint j = start; j < i; j++) {
-                RenderLayer::RenderLayerElement* elt = buffer->at(j);
-                RenderLayer::RenderLayerElement* elt2 = buffer->at(j+1);
-                if (elt->zindex > elt2->zindex) {
+                RenderLayer* elt = buffer->at(j);
+                RenderLayer* elt2 = buffer->at(j+1);
+                if (elt->zIndex() > elt2->zIndex()) {
                     sorted = false;
                     buffer->insert(j, elt2);
                     buffer->insert(j+1, elt);
@@ -1029,12 +977,12 @@ static void sortByZOrder(QPtrVector<RenderLayer::RenderLayerElement>* buffer,
         sortByZOrder(buffer, mergeBuffer, start, mid);
         sortByZOrder(buffer, mergeBuffer, mid, end);
 
-        RenderLayer::RenderLayerElement* elt = buffer->at(mid-1);
-        RenderLayer::RenderLayerElement* elt2 = buffer->at(mid);
+        RenderLayer* elt = buffer->at(mid-1);
+        RenderLayer* elt2 = buffer->at(mid);
 
         // Handle the fast common case (of equal z-indices).  The list may already
         // be completely sorted.
-        if (elt->zindex <= elt2->zindex)
+        if (elt->zIndex() <= elt2->zIndex())
             return;
 
         // We have to merge sort.  Ensure our merge buffer is big enough to hold
@@ -1047,7 +995,7 @@ static void sortByZOrder(QPtrVector<RenderLayer::RenderLayerElement>* buffer,
         elt2 = buffer->at(i2);
 
         while (i1 < mid || i2 < end) {
-            if (i1 < mid && (i2 == end || elt->zindex <= elt2->zindex)) {
+            if (i1 < mid && (i2 == end || elt->zIndex() <= elt2->zIndex())) {
                 mergeBuffer->insert(mergeBuffer->count(), elt);
                 i1++;
                 if (i1 < mid)
@@ -1068,160 +1016,62 @@ static void sortByZOrder(QPtrVector<RenderLayer::RenderLayerElement>* buffer,
     }
 }
 
-void RenderLayer::RenderZTreeNode::constructLayerList(QPtrVector<RenderLayerElement>* mergeTmpBuffer,
-                                                      QPtrVector<RenderLayerElement>* buffer)
-{
-    // The root always establishes a stacking context.  We could add a rule for this
-    // to the UA sheet, but this code guarantees that nobody can do anything wacky
-    // in CSS to prevent the root from establishing a stacking context.
-    bool autoZIndex = layer->parent() ? layer->hasAutoZIndex() : false;
-    int explicitZIndex = layer->zIndex();
-
-    if (layerElement) {
-        // We are a leaf node of the ztree, and so we just place our layer element into
-        // the buffer.
-        if (buffer->count() == buffer->size())
-            // Resize by a power of 2.
-            buffer->resize(2*(buffer->size()+1));
-        
-        buffer->insert(buffer->count(), layerElement);
-        return;
-    }
-
-    uint startIndex = buffer->count();
-    for (RenderZTreeNode* current = child; current; current = current->next)
-        current->constructLayerList(mergeTmpBuffer, buffer);
-    uint endIndex = buffer->count();
-
-    if (autoZIndex || !(endIndex-startIndex))
-        return; // We just had to collect the kids.  We don't apply a sort to them, since
-                // they will actually be layered in some ancestor layer's stacking context.
-    
-    sortByZOrder(buffer, mergeTmpBuffer, startIndex, endIndex);
-
-    // Find out if we have any elements with negative z-indices in this stacking context.
-    // If so, then we need to split our layer in two (a background layer and a foreground
-    // layer).  We then put the background layer before the negative z-index objects, and
-    // leave the foreground layer in the position previously occupied by the unsplit original.
-    RenderLayerElement* elt = buffer->at(startIndex);
-    if (elt->zindex < 0) {
-        // Locate our layer in the layer list.
-        for (uint i = startIndex; i < endIndex; i++) {
-            elt = buffer->at(i);
-            if (elt->layer == layer) {
-                // Clone the layer element.
-                RenderLayerElement* bgLayer =
-                  new (layer->renderer()->renderArena()) RenderLayerElement(*elt);
-
-                // Set the layer types (foreground and background) on the two layer elements.
-                elt->layerElementType = RenderLayerElement::Foreground;
-                bgLayer->layerElementType = RenderLayerElement::Background;
-
-                // Ensure our buffer is big enough to hold a new layer element.
-                if (buffer->count() == buffer->size())
-                    // Resize by a power of 2.
-                    buffer->resize(2*(buffer->size()+1));
-
-                // Insert the background layer element at the front of our sorted list.
-                for (uint j = buffer->count(); j > startIndex; j--)
-                    buffer->insert(j, buffer->at(j-1));
-                buffer->insert(startIndex, bgLayer);
-
-                // Augment endIndex since we added a layer element.
-                endIndex++;
-                break;
-            }
-        }
-    }
-    
-    // Now set all of the elements' z-indices to match the parent's explicit z-index, so that
-    // they will be layered properly in the ancestor layer's stacking context.
-    for (uint i = startIndex; i < endIndex; i++) {
-        elt = buffer->at(i);
-        elt->zindex = explicitZIndex;
-    }
-}
-
-void* RenderLayer::RenderLayerElement::operator new(size_t sz, RenderArena* renderArena) throw()
+void RenderLayer::dirtyZOrderLists()
 {
-    void* result = renderArena->allocate(sz);
-    if (result)
-        memset(result, 0, sz);
-    return result;
+    if (m_posZOrderList)
+        m_posZOrderList->clear();
+    if (m_negZOrderList)
+        m_negZOrderList->clear();
+    m_zOrderListsDirty = true;
 }
-
-void RenderLayer::RenderLayerElement::operator delete(void* ptr, size_t sz)
-{
-    assert(inRenderLayerElementDetach);
     
-    // Stash size where detach can find it.
-    *(size_t *)ptr = sz;
-}
-
-void RenderLayer::RenderLayerElement::detach(RenderArena* renderArena)
+void RenderLayer::updateZOrderLists()
 {
-#ifndef NDEBUG
-    inRenderLayerElementDetach = true;
-#endif
-    delete this;
-#ifndef NDEBUG
-    inRenderLayerElementDetach = false;
-#endif
+    if (!isStackingContext() || !m_zOrderListsDirty)
+        return;
     
-    // Recover the size left there for us by operator delete and free the memory.
-    renderArena->free(*(size_t *)this, this);
-}
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+        child->collectLayers(m_posZOrderList, m_negZOrderList);
 
-void* RenderLayer::RenderZTreeNode::operator new(size_t sz, RenderArena* renderArena) throw()
-{
-    void* result = renderArena->allocate(sz);
-    if (result)
-        memset(result, 0, sz);
-    return result;
-}
+    // Sort the two lists.
+    if (m_posZOrderList) {
+        QPtrVector<RenderLayer> mergeBuffer;
+        sortByZOrder(m_posZOrderList, &mergeBuffer, 0, m_posZOrderList->count());
+    }
+    if (m_negZOrderList) {
+        QPtrVector<RenderLayer> mergeBuffer;
+        sortByZOrder(m_negZOrderList, &mergeBuffer, 0, m_negZOrderList->count());
+    }
 
-void RenderLayer::RenderZTreeNode::operator delete(void* ptr, size_t sz)
-{
-    assert(inRenderZTreeNodeDetach);
-    
-    // Stash size where detach can find it.
-    *(size_t *)ptr = sz;
+    m_zOrderListsDirty = false;
 }
 
-void RenderLayer::RenderZTreeNode::detach(RenderArena* renderArena)
+void RenderLayer::collectLayers(QPtrVector<RenderLayer>*& posBuffer, QPtrVector<RenderLayer>*& negBuffer)
 {
-    assert(!next);
-    
-    RenderZTreeNode *n;
-    for (RenderZTreeNode *c = child; c; c = n) {
-        n = c->next;
-        c->next = 0;
-        c->detach(renderArena);
-    }
-    if (layerElement)
-        layerElement->detach(renderArena);
-
-#ifndef NDEBUG
-    inRenderZTreeNodeDetach = true;
-#endif
-    delete this;
-#ifndef NDEBUG
-    inRenderZTreeNodeDetach = false;
-#endif
+    // FIXME: A child render object or layer could override visibility.  Don't remove this
+    // optimization though until RenderObject's nodeAtPoint is patched to understand what to do
+    // when visibility is overridden by a child.
+    if (renderer()->style()->visibility() != VISIBLE)
+        return;
     
-    // Recover the size left there for us by operator delete and free the memory.
-    renderArena->free(*(size_t *)this, this);
-}
+    // Determine which buffer the child should be in.
+    QPtrVector<RenderLayer>*& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
 
-QPtrVector<RenderLayer::RenderLayerElement> RenderLayer::elementList(RenderZTreeNode *&node)
-{
-    QPtrVector<RenderLayerElement> list;
+    // Create the buffer if it doesn't exist yet.
+    if (!buffer)
+        buffer = new QPtrVector<RenderLayer>();
     
-    QRect damageRect(m_x, m_y, m_width, m_height);
-    node = constructZTree(damageRect, damageRect, this);
-    if (node) {
-        constructLayerList(node, &list);
+    // Resize by a power of 2 when our buffer fills up.
+    if (buffer->count() == buffer->size())
+        buffer->resize(2*(buffer->size()+1));
+
+    // Append ourselves at the end of the appropriate buffer.
+    buffer->insert(buffer->count(), this);
+
+    // Recur into our children to collect more layers, but only if we don't establish
+    // a stacking context.
+    if (!isStackingContext()) {
+        for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+            child->collectLayers(posBuffer, negBuffer);
     }
-    
-    return list;
 }
diff --git a/WebCore/khtml/rendering/render_layer.h b/WebCore/khtml/rendering/render_layer.h
index 35b14a4..6408fd2 100644
--- a/WebCore/khtml/rendering/render_layer.h
+++ b/WebCore/khtml/rendering/render_layer.h
@@ -49,8 +49,9 @@
 #include <assert.h>
 
 #include "render_object.h"
-#include <qvector.h>
-#include <qscrollbar.h>
+
+class QScrollBar;
+template <class T> class QPtrVector;
 
 namespace khtml {
     class RenderStyle;
@@ -60,7 +61,8 @@ namespace khtml {
     class RenderText;
     class RenderFrameSet;
     class RenderObject;
-
+    class RenderScrollMediator;
+    
 class RenderScrollMediator: public QObject
 {
 public:
@@ -76,6 +78,10 @@ private:
 class RenderLayer
 {
 public:
+#ifdef APPLE_CHANGES
+    static QScrollBar* gScrollBar;
+#endif
+    
     RenderLayer(RenderObject* object);
     ~RenderLayer();
     
@@ -90,14 +96,13 @@ public:
     void addChild(RenderLayer *newChild, RenderLayer* beforeChild = 0);
     RenderLayer* removeChild(RenderLayer *oldChild);
 
-    RenderLayer* transparentAncestor();
-    bool isTransparent();
-    void updateTransparentState(QPainter* painter, RenderLayer* newLayer, RenderLayer*& currLayer);
-    void beginTransparencyLayers(QPainter* painter, RenderLayer* newLayer, RenderLayer* ancestorLayer);
-    void endTransparencyLayers(QPainter* painter, RenderLayer* newLayer, RenderLayer* ancestorLayer);
-    
     void removeOnlyThisLayer();
     void insertOnlyThisLayer();
+
+#if APPLE_CHANGES
+    bool isTransparent();
+    RenderLayer* transparentAncestor();
+#endif
     
     RenderLayer* root() {
         RenderLayer* curr = this;
@@ -109,15 +114,13 @@ public:
     int yPos() const { return m_y; }
     short width() const { return m_width; }
     int height() const { return m_height; }
+
+    void setWidth(short w) { m_width = w; }
+    void setHeight(int h) { m_height = h; }
+    
     short scrollWidth() const { return m_scrollWidth; }
     int scrollHeight() const { return m_scrollHeight; }
     
-    void setWidth( int width ) {
-        m_width = width;
-    }
-    void setHeight( int height ) {
-        m_height = height;
-    }
     void setPos( int xPos, int yPos ) {
         m_x = xPos;
         m_y = yPos;
@@ -133,40 +136,62 @@ public:
     void scrollToYOffset(int y) { scrollToOffset(m_scrollX, y); }
     void setHasHorizontalScrollbar(bool hasScrollbar);
     void setHasVerticalScrollbar(bool hasScrollbar);
-    QWidget* horizontalScrollbar() { return m_hBar; }
-    QWidget* verticalScrollbar() { return m_vBar; }
+    QScrollBar* horizontalScrollbar() { return m_hBar; }
+    QScrollBar* verticalScrollbar() { return m_vBar; }
     int verticalScrollbarWidth();
     int horizontalScrollbarHeight();
     void moveScrollbarsAside();
     void positionScrollbars(const QRect& absBounds);
-    void paintScrollbars(QPainter* p, int x, int y, int w, int h);
+#ifdef APPLE_CHANGES
+    void paintScrollbars(QPainter* p, const QRect& damageRect);
+#endif
     void checkScrollbarsAfterLayout();
     void slotValueChanged(int);
     void updateScrollPositionFromScrollbars();
-    
+
     void updateLayerPosition();
+
+    // Get the enclosing stacking context for this layer.  A stacking context is a layer
+    // that has a non-auto z-index.
+    RenderLayer* stackingContext() const;
+    bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isCanvas(); }
+
+    void dirtyZOrderLists();
+    void updateZOrderLists();
+    QPtrVector<RenderLayer>* posZOrderList() const { return m_posZOrderList; }
+    QPtrVector<RenderLayer>* negZOrderList() const { return m_negZOrderList; }
     
     // Gets the nearest enclosing positioned ancestor layer (also includes
     // the <html> layer and the root layer).
-    RenderLayer* enclosingPositionedAncestor();
+    RenderLayer* enclosingPositionedAncestor() const;
     
-    void convertToLayerCoords(RenderLayer* ancestorLayer, int& x, int& y);
+    void convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const;
     
-    bool hasAutoZIndex() { return renderer()->style()->hasAutoZIndex(); }
-    int zIndex() { return renderer()->style()->zIndex(); }
+    bool hasAutoZIndex() const { return renderer()->style()->hasAutoZIndex(); }
+    int zIndex() const { return renderer()->style()->zIndex(); }
 
     // The two main functions that use the layer system.  The paint method
     // paints the layers that intersect the damage rect from back to
     // front.  The nodeAtPoint method looks for mouse events by walking
     // layers that intersect the point from front to back.
-    void paint(QPainter *p, int x, int y, int w, int h, bool selectionOnly=false);
+    void paint(QPainter *p, const QRect& damageRect, bool selectionOnly=false);
     bool nodeAtPoint(RenderObject::NodeInfo& info, int x, int y);
+
+    // This method figures out our layerBounds in coordinates relative to
+    // |rootLayer}.  It also computes our background and foreground clip rects
+    // for painting/event handling.
+    void calculateRects(const RenderLayer* rootLayer, const QRect& paintDirtyRect, QRect& layerBounds,
+                        QRect& backgroundRect, QRect& foregroundRect);
+    void calculateClipRects(const RenderLayer* rootLayer, QRect& overflowClipRect,
+                            QRect& posClipRect, QRect& fixedClipRect);
+
+    bool intersectsDamageRect(const QRect& layerBounds, const QRect& damageRect) const;
+    bool containsPoint(int x, int y, const QRect& damageRect) const;
     
-    void clearOtherLayersHoverActiveState();
-    void clearHoverAndActiveState(RenderObject* obj);
+    void updateHoverActiveState(RenderObject::NodeInfo& info);
     
     void detach(RenderArena* renderArena);
-    
+
      // Overloaded new operator.  Derived classes must override operator new
     // in order to allocate out of the RenderArena.
     void* operator new(size_t sz, RenderArena* renderArena) throw();    
@@ -178,179 +203,6 @@ private:
     // The normal operator new is disallowed on all render objects.
     void* operator new(size_t sz) throw();
 
-public:
-    // Z-Index Implementation Notes
-    //
-    // In order to properly handle mouse events as well as painting,
-    // we must compute a correct list of layers that should be painted
-    // from back to front (and for mouse events walked from front to
-    // back).
-    //
-    // Positioned elements in the render tree (e.g., relative positioned
-    // divs and absolute positioned divs) have a corresponding layer
-    // that holds them and all children that reside in the same layer.
-    //
-    // When painting is performed on a layer, all render objects in that
-    // layer are painted.  If the render object has descendants in another
-    // layer, those will be dealt with separately.
-    //
-    // A RenderLayerElement represents a single entry in our list of
-    // layers that should be painted.  We perform computations as we
-    // build up this list so that we have the correct translation factor
-    // for painting.  We also use a temporary z-index variable for storage
-    // (more on this below).
-    // 
-    struct RenderLayerElement {
-      enum LayerElementType { Normal, Background, Foreground };
-        
-      RenderLayer* layer;
-      QRect absBounds; // Our bounds in absolute coordinates relative to the root.
-      QRect backgroundClipRect; // Clip rect used for our background/borders. 
-      QRect clipRect; // Clip rect used for our children.
-      int zindex; // Temporary z-index used for processing and sorting.
-      bool zauto : 1; // Whether or not we are using auto z-indexing.
-      bool clipOriginator : 1; // Whether or not we established a clip.
-      int x; // The coords relative to the layer that will be using this list
-             // to paint.
-      int y;
-      LayerElementType layerElementType; // For negative z-indices, we have to split a single layer into two
-                           // RenderLayerElements, one that sits beneath the negative content, and
-                           // another that sits above (denoted with values of Background and Foreground,
-                           // respectively).  A normal layer that fully paints is denoted with the value Normal.
-      
-      RenderLayerElement(RenderLayer* l, const QRect& rect, const QRect& bgclip, 
-                         const QRect& clip, bool clipOrig, int xpos, int ypos,
-                         LayerElementType lType = Normal)
-          :layer(l), absBounds(rect), backgroundClipRect(bgclip), clipRect(clip), 
-           zindex(l->zIndex()), zauto(l->hasAutoZIndex()), clipOriginator(clipOrig),
-           x(xpos), y(ypos), layerElementType(lType) {}
-          
-      void detach(RenderArena* renderArena);
-    
-      // Overloaded new operator.  Derived classes must override operator new
-      // in order to allocate out of the RenderArena.
-      void* operator new(size_t sz, RenderArena* renderArena) throw();    
-
-      // Overridden to prevent the normal delete from being called.
-      void operator delete(void* ptr, size_t sz);
-        
-      // The normal operator new is disallowed.
-      void* operator new(size_t sz) throw();
-    };
-
-    // The list of layer elements is built through a recursive examination
-    // of a tree of z nodes. This tree structure mimics the layer 
-    // hierarchy itself, but only leaf nodes represent items that will
-    // end up in the layer list for painting.
-    //
-    // Every leaf layer in the layer hierarchy will have a corresponding
-    // leaf node in the z-tree.  Layers with children have an
-    // interior z-tree node that contains the tree nodes for the child
-    // layers as well as a leaf node that represents the containing layer.
-    //
-    // Sibling z-tree nodes match the same order as the layers in the
-    // layer hierarchy, which will have been arranged in document order
-    // when the render tree was constructed (since the render tree
-    // constructed the layers).  An exception is if a negative z-index
-    // is specified on a child (see below).
-    
-    struct RenderZTreeNode {
-      RenderLayer* layer;
-      RenderZTreeNode* next;
-
-      // Only one of these will ever be defined.
-      RenderZTreeNode* child; // Defined for interior nodes.
-      RenderLayerElement* layerElement; // Defined for leaf nodes.
-
-      RenderZTreeNode(RenderLayer* l)
-          :layer(l), next(0), child(0), layerElement(0) {}
-
-      RenderZTreeNode(RenderLayerElement* layerElt)
-          :layer(layerElt->layer), next(0), child(0), layerElement(layerElt) {}
-      
-      ~RenderZTreeNode() {}
-
-      void constructLayerList(QPtrVector<RenderLayerElement>* mergeTmpBuffer,
-                              QPtrVector<RenderLayerElement>* finalBuffer);
-      
-      void detach(RenderArena* renderArena);
-          
-      // Overloaded new operator.  Derived classes must override operator new
-      // in order to allocate out of the RenderArena.
-      void* operator new(size_t sz, RenderArena* renderArena) throw();    
-
-      // Overridden to prevent the normal delete from being called.
-      void operator delete(void* ptr, size_t sz);
-        
-      // The normal operator new is disallowed.
-      void* operator new(size_t sz) throw();
-    };
-
-    static QWidget* gScrollBar;
-
-    // For debugging.
-    QPtrVector<RenderLayerElement> elementList(RenderZTreeNode *&node);
-      
-private:
-    // The constructZTree function creates a z-tree for a given layer hierarchy
-    // rooted on this layer.  It will ensure that immediate child
-    // elements of a given z-tree node are at least initially sorted
-    // into <negative z-index children>, <this layer>, <non-negative z-index
-    // children>.
-    //
-    // Here is a concrete example (lifted from Gecko's view system,
-    // which is analogous to our layer system and works the same way):
-    // z-index values as specified by CSS are shown in parentheses.
-    //
-    // L0(auto) --> L1(0) --> L2(auto) --> L3(0)
-    // |        |    +------> L4(2)
-    // |        +-----------> L5(1)
-    // +--------------------> L6(1)
-    //
-    // The corresponding z-tree for this layer hierarchy will be
-    // the following, where |I| represents an interior node, and |L|
-    // represents a leaf RenderLayerElement.
-    //
-    // I(L0) --> L(L0)
-    // +-------> I(L1) --------> L(L1)
-    // |           |   +-------> I(L2) ------> L(L2)
-    // |           |               +---------> L(L3)
-    // |           +-----------> L(L4)
-    // +-------> L(L5)
-    // +-------> L(L6)
-    //
-    RenderZTreeNode* constructZTree(QRect overflowClipRect,
-                                    QRect clipRect,
-                                    RenderLayer* rootLayer,
-                                    bool eventProcessing = false, int x=0, int y=0);
-
-    // Once the z-tree has been constructed, we call constructLayerList
-    // to produce a flattened layer list for rendering/event handling.
-    // This function recursively computes a layer list for each z-tree
-    // node by computing lists for each child node.  It then concatenates
-    // them and sorts them by z-index.
-    //
-    // Z-indices are updated during this computation.  After a list is
-    // computed for one z-tree node, the elements of the layer list are
-    // all changed so that their z-indices match the specified z-index
-    // of the tree node's layer (unless that layer doesn't establish
-    // a z-index, e.g., it just has z-index: auto).
-    //
-    // Continuing the above example, the computation of the list for
-    // L0 would be as follows:
-    //
-    // I(L2) has a list [ L(L2)(0), L(L3)(0), L(L4)(2) ]
-    // I(L2) is auto so the z-indices of the child layer elements remain
-    // unaltered.
-    // I(L1) has a list [ L(L1)(0), L(L2)(0), L(L3)(0), L(L4)(2), L(L5)(1) ]
-    // The nodes are sorted and then reassigned a z-index of 0, so this
-    // list becomes:
-    // [ L(L1)(0), L(L2)(0), L(L3)(0), L(L5)(0), L(L4)(0) ]
-    // Finally we end up with the list for L0, which sorted becomes:
-    // [ L(L0)(0), L(L1)(0), L(L2)(0), L(L3)(0), L(L5)(0), L(L4)(0), L(L6)(1) ]
-    void constructLayerList(RenderZTreeNode* ztree,
-                            QPtrVector<RenderLayerElement>* result);
-
 private:
     void setNextSibling(RenderLayer* next) { m_next = next; }
     void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
@@ -358,34 +210,50 @@ private:
     void setFirstChild(RenderLayer* first) { m_first = first; }
     void setLastChild(RenderLayer* last) { m_last = last; }
 
+    void collectLayers(QPtrVector<RenderLayer>*&, QPtrVector<RenderLayer>*&);
+
+    void paintLayer(RenderLayer* rootLayer, QPainter *p, const QRect& paintDirtyRect, bool selectionOnly=false);
+    RenderLayer* nodeAtPointForLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
+                                     int x, int y, const QRect& hitTestRect);
+
 protected:   
     RenderObject* m_object;
     
-    RenderLayer *m_parent;
-    RenderLayer *m_previous;
-    RenderLayer *m_next;
+    RenderLayer* m_parent;
+    RenderLayer* m_previous;
+    RenderLayer* m_next;
 
-    RenderLayer *m_first;
-    RenderLayer *m_last;
+    RenderLayer* m_first;
+    RenderLayer* m_last;
     
     // Our (x,y) coordinates are in our parent layer's coordinate space.
-    int m_height;
-    int m_y;
     short m_x;
-    short m_width;
+    int m_y;
 
+    // The layer's width/height
+    short m_width;
+    int m_height;
+    
     // Our scroll offsets if the view is scrolled.
     short m_scrollX;
     int m_scrollY;
-
+    
     // The width/height of our scrolled area.
     short m_scrollWidth;
-    short m_scrollHeight;
+    int m_scrollHeight;
     
     // For layers with overflow, we have a pair of scrollbars.
     QScrollBar* m_hBar;
     QScrollBar* m_vBar;
     RenderScrollMediator* m_scrollMediator;
+
+    // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
+    // descendant layers within the stacking context that have z-indices of 0 or greater
+    // (auto will count as 0).  m_negZOrderList holds descendants within our stacking context with negative
+    // z-indices.
+    QPtrVector<RenderLayer>* m_posZOrderList;
+    QPtrVector<RenderLayer>* m_negZOrderList;
+    bool m_zOrderListsDirty;
 };
 
 }; // namespace
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 73d7801..5a8679e 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -983,6 +983,19 @@ 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();
+        }
+    }
+
     RenderStyle::Diff d = m_style ? m_style->diff( style ) : RenderStyle::Layout;
 
     if (m_style && m_parent && d == RenderStyle::Visible && !isText())
@@ -1220,7 +1233,7 @@ void RenderObject::removeFromObjectLists()
     }
 }
 
-RenderArena* RenderObject::renderArena() const
+DOM::DocumentImpl* RenderObject::document() const
 {
     DOM::NodeImpl* elt = element();
     RenderObject* current = parent();
@@ -1228,9 +1241,13 @@ RenderArena* RenderObject::renderArena() const
         elt = current->element();
         current = current->parent();
     }
-    if (!elt)
-        return 0;
-    return elt->getDocument()->renderArena();
+    return elt ? elt->getDocument() : 0;
+}
+
+RenderArena* RenderObject::renderArena() const
+{
+    DOM::DocumentImpl* doc = document();
+    return doc ? doc->renderArena() : 0;
 }
 
 
@@ -1336,20 +1353,8 @@ bool RenderObject::mouseInside() const
     return m_mouseInside; 
 }
 
-void RenderObject::setHoverAndActive(NodeInfo& info, bool oldinside, bool inside)
-{
-    DOM::NodeImpl* elt = element();
-    if (elt) {
-        bool oldactive = elt->active();
-        if (oldactive != (inside && info.active()))
-            elt->setActive(inside && info.active());
-        if ((oldinside != mouseInside() && style()->affectedByHoverRules()) ||
-            (oldactive != elt->active() && style()->affectedByActiveRules()))
-            elt->setChanged();
-    }
-}
-
-bool RenderObject::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inside)
+bool RenderObject::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                               HitTestAction hitTestAction, bool inside)
 {
     int tx = _tx + xPos();
     int ty = _ty + yPos();
@@ -1363,11 +1368,14 @@ bool RenderObject::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
     }
     
     // ### table should have its own, more performant method
-    if ((!isRenderBlock() ||
+    if (hitTestAction != HitTestSelfOnly &&
+        ((!isRenderBlock() ||
          !static_cast<RenderBlock*>(this)->isPointInScrollbar(_x, _y, _tx, _ty)) &&
         (overhangingContents() || inOverflowRect || isInline() || isCanvas() ||
          isTableRow() || isTableSection() || inside || mouseInside() ||
-         (childrenInline() && firstChild() && firstChild()->isCompact()))) {
+         (childrenInline() && firstChild() && firstChild()->isCompact())))) {
+        if (hitTestAction == HitTestChildrenOnly)
+            inside = false;
         int stx = _tx + xPos();
         int sty = _ty + yPos();
         if (style()->hidesOverflow() && layer())
@@ -1379,6 +1387,15 @@ bool RenderObject::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
     }
 
     if (inside) {
+        if (!info.innerNode() && !isInline() && continuation()) {
+            // We are in the margins of block elements that are part of a continuation.  In
+            // this case we're actually still inside the enclosing inline element that was
+            // split.  Go ahead and set our inner node accordingly.
+            info.setInnerNode(continuation()->element());
+            if (!info.innerNonSharedNode())
+                info.setInnerNonSharedNode(continuation()->element());
+        }
+            
         if (info.innerNode() && info.innerNode()->renderer() && 
             !info.innerNode()->renderer()->isInline() && element() && isInline()) {
             // Within the same layer, inlines are ALWAYS fully above blocks.  Change inner node.
@@ -1394,28 +1411,6 @@ bool RenderObject::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
 
         if(!info.innerNonSharedNode() && element())
             info.setInnerNonSharedNode(element());
-        
-        if (!info.URLElement()) {
-            RenderObject* p = (!isInline() && continuation()) ? continuation() : this;
-            while (p) {
-                if (p->element() && p->element()->hasAnchor()) {
-                    info.setURLElement(p->element());
-                    break;
-                }
-                if (!isFloatingOrPositioned()) break;
-                p = p->parent();
-            }
-        }
-    }
-
-    if (!info.readonly()) {
-        // lets see if we need a new style
-        bool oldinside = mouseInside();
-        setMouseInside(inside);
-        
-        setHoverAndActive(info, oldinside, inside);
-        if (!isInline() && continuation())
-            continuation()->setHoverAndActive(info, oldinside, inside);
     }
 
     return inside;
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index 8d6dcab..cab0c0f 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -70,10 +70,17 @@ typedef enum {
     PaintActionSelection
 } PaintAction;
 
+typedef enum {
+    HitTestAll = 0,
+    HitTestSelfOnly = 1,
+    HitTestChildrenOnly = 2
+} HitTestAction;
+
 namespace DOM {
     class HTMLAreaElementImpl;
     class DOMString;
     class NodeImpl;
+    class DocumentImpl;
     class ElementImpl;
     class EventImpl;
 };
@@ -241,7 +248,8 @@ public:
 
     // don't even think about making this method virtual!
     DOM::NodeImpl* element() const { return m_node; }
-
+    DOM::DocumentImpl* document() const;
+    
    /**
      * returns the object containing this one. can be different from parent for
      * positioned elements
@@ -405,8 +413,8 @@ public:
 
     FindSelectionResult checkSelectionPoint(int x, int y, int tx, int ty, DOM::NodeImpl*&, int& offset);
     virtual FindSelectionResult checkSelectionPointIgnoringContinuations(int x, int y, int tx, int ty, DOM::NodeImpl*&, int& offset);
-    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside=false);
-    void setHoverAndActive(NodeInfo& info, bool oldinside, bool inside);
+    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
+                             HitTestAction hitTestAction = HitTestAll, bool inside=false);
     
     // set the style of the object.
     virtual void setStyle(RenderStyle *style);
diff --git a/WebCore/khtml/rendering/render_text.cpp b/WebCore/khtml/rendering/render_text.cpp
index 5928633..32faef7 100644
--- a/WebCore/khtml/rendering/render_text.cpp
+++ b/WebCore/khtml/rendering/render_text.cpp
@@ -379,7 +379,8 @@ TextRun * RenderText::findTextRun( int offset, int &pos )
     return s;
 }
 
-bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, bool inside)
+bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,
+                             HitTestAction hitTestAction, bool inside)
 {
     assert(parent());
 
@@ -395,8 +396,6 @@ bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, b
         s = si < (int) m_lines.count()-1 ? m_lines[++si] : 0;
     }
 
-    setMouseInside(inside);
-
     if (inside && element()) {
         if (info.innerNode() && info.innerNode()->renderer() && 
             !info.innerNode()->renderer()->isInline()) {
@@ -411,7 +410,7 @@ bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, b
         if (!info.innerNode())
             info.setInnerNode(element());
 
-        if(!info.innerNonSharedNode())
+        if (!info.innerNonSharedNode())
             info.setInnerNonSharedNode(element());
     }
 
diff --git a/WebCore/khtml/rendering/render_text.h b/WebCore/khtml/rendering/render_text.h
index 032d6a1..c3ae5ac 100644
--- a/WebCore/khtml/rendering/render_text.h
+++ b/WebCore/khtml/rendering/render_text.h
@@ -141,7 +141,8 @@ public:
     
     virtual void layout() {assert(false);}
 
-    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, bool inside = false);
+    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
+                             HitTestAction hitTestAction = HitTestAll, bool inside=false);
 
     // Return before, after (offset set to max), or inside the text, at @p offset
     virtual FindSelectionResult checkSelectionPointIgnoringContinuations
diff --git a/WebCore/khtml/xml/dom_docimpl.cpp b/WebCore/khtml/xml/dom_docimpl.cpp
index 876302f..66c373c 100644
--- a/WebCore/khtml/xml/dom_docimpl.cpp
+++ b/WebCore/khtml/xml/dom_docimpl.cpp
@@ -284,6 +284,7 @@ DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
     m_namespaceURIs[0] = new DOMStringImpl(xhtml.unicode(), xhtml.length());
     m_namespaceURIs[0]->ref();
     m_focusNode = 0;
+    m_hoverNode = 0;
     m_defaultView = new AbstractViewImpl(this);
     m_defaultView->ref();
     m_listenerTypes = 0;
@@ -336,9 +337,12 @@ DocumentImpl::~DocumentImpl()
     delete [] m_namespaceURIs;
     m_defaultView->deref();
     m_styleSheets->deref();
+
     if (m_focusNode)
         m_focusNode->deref();
-        
+    if (m_hoverNode)
+        m_hoverNode->deref();
+    
     if (m_renderArena){
         delete m_renderArena;
         m_renderArena = 0;
@@ -2022,6 +2026,17 @@ void DocumentImpl::recalcStyleSelector()
     m_styleSelectorDirty = false;
 }
 
+void DocumentImpl::setHoverNode(NodeImpl* newHoverNode)
+{
+    if (m_hoverNode != newHoverNode) {
+        if (m_hoverNode)
+            m_hoverNode->deref();
+        m_hoverNode = newHoverNode;
+        if (m_hoverNode)
+            m_hoverNode->ref();
+    }    
+}
+
 void DocumentImpl::setFocusNode(NodeImpl *newFocusNode)
 {    
     // Make sure newFocusNode is actually in this document
diff --git a/WebCore/khtml/xml/dom_docimpl.h b/WebCore/khtml/xml/dom_docimpl.h
index 6c88c75..e3bc40f 100644
--- a/WebCore/khtml/xml/dom_docimpl.h
+++ b/WebCore/khtml/xml/dom_docimpl.h
@@ -344,9 +344,13 @@ public:
     void setSelectedStylesheetSet(const DOMString& aString);
 
     QStringList availableStyleSheets() const;
+
     NodeImpl *focusNode() const { return m_focusNode; }
     void setFocusNode(NodeImpl *newFocusNode);
 
+    NodeImpl *hoverNode() const { return m_hoverNode; }
+    void setHoverNode(NodeImpl *newHoverNode);
+    
     // Updates for :target (CSS3 selector).
     void setCSSTarget(NodeImpl* n);
     NodeImpl* getCSSTarget();
@@ -478,8 +482,10 @@ protected:
     HTMLMode hMode;
 
     QColor m_textColor;
-    NodeImpl *m_focusNode;
 
+    NodeImpl *m_focusNode;
+    NodeImpl *m_hoverNode;
+    
     // ### replace me with something more efficient
     // in lookup and insertion.
     DOMStringImpl **m_elementNames;
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index 3286f71..0c9a886 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -56,6 +56,8 @@
 
 #import <JavaScriptCore/property_map.h>
 
+#import <qscrollbar.h>
+
 #undef _KWQ_TIMING
 
 using DOM::DocumentImpl;
@@ -787,7 +789,7 @@ void KWQKHTMLPart::paint(QPainter *p, const QRect &rect)
 #endif
 
     if (renderer()) {
-        renderer()->layer()->paint(p, rect.x(), rect.y(), rect.width(), rect.height(), false);
+        renderer()->layer()->paint(p, rect);
     } else {
         ERROR("called KWQKHTMLPart::paint with nil renderer");
     }
@@ -796,7 +798,7 @@ void KWQKHTMLPart::paint(QPainter *p, const QRect &rect)
 void KWQKHTMLPart::paintSelectionOnly(QPainter *p, const QRect &rect)
 {
     if (renderer()) {
-        renderer()->layer()->paint(p, rect.x(), rect.y(), rect.width(), rect.height(), true);
+        renderer()->layer()->paint(p, rect, true);
     } else {
         ERROR("called KWQKHTMLPart::paintSelectionOnly with nil renderer");
     }
@@ -811,8 +813,9 @@ void KWQKHTMLPart::adjustPageHeight(float *newBottom, float oldTop, float oldBot
         painter.setPaintingDisabled(true);
 
         root->setTruncatedAt((int)floor(oldBottom));
-        root->layer()->paint(&painter, 0, (int)floor(oldTop),
-                             root->docWidth(), (int)ceil(oldBottom-oldTop), false);
+        QRect dirtyRect(0, (int)floor(oldTop),
+                        root->docWidth(), (int)ceil(oldBottom-oldTop));
+        root->layer()->paint(&painter, dirtyRect);
         *newBottom = root->bestTruncatedAt();
         if (*newBottom == 0) {
             *newBottom = oldBottom;
diff --git a/WebCore/kwq/KWQRect.h b/WebCore/kwq/KWQRect.h
index e36359a..9591a9a 100644
--- a/WebCore/kwq/KWQRect.h
+++ b/WebCore/kwq/KWQRect.h
@@ -61,7 +61,7 @@ public:
     bool intersects(const QRect &) const;
     QRect unite(const QRect &) const;
 
-    bool contains(int x, int y, bool proper = false) {
+    bool contains(int x, int y, bool proper = false) const {
         if (proper)
             return x > xp && (x < (xp + w - 1)) && y > yp && y < (yp + h - 1);
         return x >= xp && x < (xp + w) && y >= yp && y < (yp + h);
diff --git a/WebCore/kwq/KWQRenderTreeDebug.cpp b/WebCore/kwq/KWQRenderTreeDebug.cpp
index 3df48ef..06d6edc 100644
--- a/WebCore/kwq/KWQRenderTreeDebug.cpp
+++ b/WebCore/kwq/KWQRenderTreeDebug.cpp
@@ -42,10 +42,8 @@ using khtml::RenderText;
 using khtml::TextRun;
 using khtml::TextRunArray;
 
-typedef khtml::RenderLayer::RenderLayerElement RenderLayerElement;
-typedef khtml::RenderLayer::RenderZTreeNode RenderZTreeNode;
-
-static void writeLayers(QTextStream &ts, const RenderObject &o, int indent = 0);
+static void writeLayers(QTextStream &ts, const RenderLayer* rootLayer, RenderLayer* l,
+                        const QRect& paintDirtyRect, int indent=0);
 
 static QTextStream &operator<<(QTextStream &ts, const QRect &r)
 {
@@ -149,16 +147,18 @@ static void write(QTextStream &ts, const RenderObject &o, int indent = 0)
         if (view) {
             RenderObject *root = KWQ(view->part())->renderer();
             if (root) {
-                writeLayers(ts, *root, indent + 1);
+                RenderLayer* l = root->layer();
+                if (l)
+                    writeLayers(ts, l, l, QRect(l->xPos(), l->yPos(), l->width(), l->height()), indent+1);
             }
         }
     }
 }
 
-static void write(QTextStream &ts, const RenderLayerElement &e, int indent = 0)
+static void write(QTextStream &ts, const RenderLayer &l,
+                  const QRect& layerBounds, const QRect& backgroundClipRect, const QRect& clipRect,
+                  int layerType = 0, int indent = 0)
 {
-    RenderLayer &l = *e.layer;
-    
     writeIndent(ts, indent);
     
     ts << "layer";
@@ -166,34 +166,52 @@ static void write(QTextStream &ts, const RenderLayerElement &e, int indent = 0)
     QRect r(e.absBounds);
     
     ts << " " << r;
-    
-    if (r != r.intersect(e.backgroundClipRect)) {
-        ts << " backgroundClip " << e.backgroundClipRect;
+
+    if (layerBounds != layerBounds.intersect(backgroundClipRect)) {
+        ts << " backgroundClip " << backgroundClipRect;
     }
-    if (r != r.intersect(e.clipRect)) {
-        ts << " clip " << e.clipRect;
+    if (layerBounds != layerBounds.intersect(clipRect)) {
+        ts << " clip " << clipRect;
     }
 
-    if (e.layerElementType == RenderLayerElement::Background)
+    if (layerType == -1)
         ts << " layerType: background only";
-    else if (e.layerElementType == RenderLayerElement::Foreground)
+    else if (layerType == 1)
         ts << " layerType: foreground only";
     
     ts << "\n";
 
-    if (e.layerElementType != RenderLayerElement::Background)
+    if (layerType != -1)
         write(ts, *l.renderer(), indent + 1);
 }
-
-static void writeLayers(QTextStream &ts, const RenderObject &o, int indent)
+    
+static void writeLayers(QTextStream &ts, const RenderLayer* rootLayer, RenderLayer* l,
+                        const QRect& paintDirtyRect, int indent)
 {
-    RenderZTreeNode *node;
-    QPtrVector<RenderLayerElement> list = o.layer()->elementList(node);
-    for (unsigned i = 0; i != list.count(); ++i) {
-        write(ts, *list[i], indent);
+    // Calculate the clip rects we should use.
+    QRect layerBounds, damageRect, clipRectToApply;
+    l->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply);
+    
+    // Ensure our z-order lists are up-to-date.
+    l->updateZOrderLists();
+
+    bool shouldPaint = l->intersectsDamageRect(layerBounds, damageRect);
+    QPtrVector<RenderLayer>* negList = l->negZOrderList();
+    if (shouldPaint && negList && negList->count() > 0)
+        write(ts, *l, layerBounds, damageRect, clipRectToApply, -1, indent);
+
+    if (negList) {
+        for (unsigned i = 0; i != negList->count(); ++i)
+            writeLayers(ts, rootLayer, negList->at(i), paintDirtyRect, indent);
     }
-    if (node) {
-        node->detach(o.renderArena());
+
+    if (shouldPaint)
+        write(ts, *l, layerBounds, damageRect, clipRectToApply, negList && negList->count() > 0, indent);
+
+    QPtrVector<RenderLayer>* posList = l->posZOrderList();
+    if (posList) {
+        for (unsigned i = 0; i != posList->count(); ++i)
+            writeLayers(ts, rootLayer, posList->at(i), paintDirtyRect, indent);
     }
 }
 
@@ -203,7 +221,9 @@ QString externalRepresentation(const RenderObject *o)
     {
         QTextStream ts(&s);
         if (o) {
-            writeLayers(ts, *o);
+            RenderLayer* l = o->layer();
+            if (l)
+                writeLayers(ts, l, l, QRect(l->xPos(), l->yPos(), l->width(), l->height()));
         }
     }
     return s;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list