diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog index c0be9d5cb359b0136ad39e721b0ae90bdced5a97..46348d5bca1f512d7ca413ebc8ee03a4aa2cffd1 100644 --- a/WebCore/ChangeLog +++ b/WebCore/ChangeLog @@ -1,3 +1,32 @@ +2006-11-16 David Harrison + + Reviewed by Beth. + + REGRESSION (Tiger): Deleting top part of reply email leaves fails to clear text at end of message + + The problem was triggered by the fact that the parent div was changing both + in position and in height. The renderer normally bifurcates its logic for + x-position changes vs height changes. + + Call repaintDuringLayoutIfMoved() with old rect (incl. width and height) instead of just the old position. + + Test added: + * manual-tests/delete-into-nested-block.html + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::layoutBlockChildren): + (WebCore::RenderBlock::positionNewFloats): + * rendering/RenderBox.cpp: + (WebCore::RenderBox::repaintDuringLayoutIfMoved): + * rendering/RenderBox.h: + * rendering/RenderFlexibleBox.cpp: + (WebCore::RenderFlexibleBox::placeChild): + * rendering/RenderObject.cpp: + (WebCore::RenderObject::repaintDuringLayoutIfMoved): + * rendering/RenderObject.h: + * rendering/RenderTableSection.cpp: + (WebCore::RenderTableSection::layoutRows): + 2006-11-16 Adele Peterson Reviewed by Adam. diff --git a/WebCore/manual-tests/delete-into-nested-block.html b/WebCore/manual-tests/delete-into-nested-block.html new file mode 100644 index 0000000000000000000000000000000000000000..df904930404dcc790ebe8323b9611731bd04ed49 --- /dev/null +++ b/WebCore/manual-tests/delete-into-nested-block.html @@ -0,0 +1,18 @@ + +

Deleting into a nested block (was Radar 4056100)

+
    +
  1. open this file in Safari or Blot
  2. +
  3. select the first two lines "one" and "two"
  4. +
  5. press the delete key
  6. +
+ +
The bug's symptom was that the visual result were two instances of the word "three", because the original was not erased. Resize cleared it up.
+
+
+
one
+
+
two
+
three
+
+
+ \ No newline at end of file diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp index 3c7ff0970cc9b650265631816e543ec7c5c9bef1..77db9381b8477d00a7f5f0ddb120f3878f786f22 100644 --- a/WebCore/rendering/RenderBlock.cpp +++ b/WebCore/rendering/RenderBlock.cpp @@ -1092,13 +1092,12 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren) child->setChildNeedsLayout(true); } - // Cache our old position so that we can dirty the proper repaint rects if the child moves. - int oldChildX = child->xPos(); - int oldChildY = child->yPos(); - + // Cache our old rect so that we can dirty the proper repaint rects if the child moves. + IntRect oldRect(child->xPos(), child->yPos() , child->width(), child->height()); + // Go ahead and position the child as though it didn't collapse with the top. child->setPos(child->xPos(), yPosEstimate); - if (yPosEstimate != oldChildY && !child->avoidsFloats() && child->containsFloats()) + if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->containsFloats()) child->markAllDescendantsWithFloatsForLayout(); child->layoutIfNeeded(); @@ -1148,8 +1147,8 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren) if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) { int finalChildX = child->xPos(); int finalChildY = child->yPos(); - if (finalChildX != oldChildX || finalChildY != oldChildY) - child->repaintDuringLayoutIfMoved(oldChildX, oldChildY); + if (finalChildX != oldRect.x() || finalChildY != oldRect.y()) + child->repaintDuringLayoutIfMoved(oldRect); else if (finalChildY != yPosEstimate || finalChildY != postCollapseChildY) { // The child's repaints during layout were done before it reached its final position, // so they were wrong. @@ -1943,8 +1942,7 @@ void RenderBlock::positionNewFloats() if (ro - lo < fwidth) fwidth = ro - lo; // Never look for more than what will be available. - int oldChildX = o->xPos(); - int oldChildY = o->yPos(); + IntRect oldRect(o->xPos(), o->yPos() , o->width(), o->height()); if ( o->style()->clear() & CLEFT ) y = max( leftBottom(), y ); @@ -1984,7 +1982,7 @@ void RenderBlock::positionNewFloats() // If the child moved, we have to repaint it. if (o->checkForRepaintDuringLayout()) - o->repaintDuringLayoutIfMoved(oldChildX, oldChildY); + o->repaintDuringLayoutIfMoved(oldRect); f = m_floatingObjects->next(); } diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp index c9f5a0d6ef5ea2c4a4572769f8a1bbd6afa8c2f5..41f5bd03d24fe5458598390ef268b1571860a928 100644 --- a/WebCore/rendering/RenderBox.cpp +++ b/WebCore/rendering/RenderBox.cpp @@ -954,17 +954,19 @@ void RenderBox::computeAbsoluteRepaintRect(IntRect& r, bool f) } } -void RenderBox::repaintDuringLayoutIfMoved(int oldX, int oldY) +void RenderBox::repaintDuringLayoutIfMoved(const IntRect& rect) { int newX = m_x; int newY = m_y; - if (oldX != newX || oldY != newY) { + int newWidth = m_width; + int newHeight = m_height; + if (rect.x() != newX || rect.y() != newY) { // The child moved. Invalidate the object's old and new positions. We have to do this // since the object may not have gotten a layout. - m_x = oldX; m_y = oldY; + m_x = rect.x(); m_y = rect.y(); m_width = rect.width(); m_height = rect.height(); repaint(); repaintOverhangingFloats(true); - m_x = newX; m_y = newY; + m_x = newX; m_y = newY; m_width = newWidth; m_height = newHeight; repaint(); repaintOverhangingFloats(true); } diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h index 9b79229a5a411d5defad1bb405ceaa02f10c11c5..205fed9fe1467e6b5438154f419781b5bac8212e 100644 --- a/WebCore/rendering/RenderBox.h +++ b/WebCore/rendering/RenderBox.h @@ -105,7 +105,7 @@ public: virtual IntRect getAbsoluteRepaintRect(); virtual void computeAbsoluteRepaintRect(IntRect& r, bool f=false); - virtual void repaintDuringLayoutIfMoved(int oldX, int oldY); + virtual void repaintDuringLayoutIfMoved(const IntRect& rect); virtual int containingBlockWidth() const; diff --git a/WebCore/rendering/RenderFlexibleBox.cpp b/WebCore/rendering/RenderFlexibleBox.cpp index 5415e8ba933e1ee081180c198a75a7989a7f3fa3..00b60724dced1ed3b2f4dc6bd04b6e1a0ecd864b 100644 --- a/WebCore/rendering/RenderFlexibleBox.cpp +++ b/WebCore/rendering/RenderFlexibleBox.cpp @@ -1056,8 +1056,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) void RenderFlexibleBox::placeChild(RenderObject* child, int x, int y) { - int oldChildX = child->xPos(); - int oldChildY = child->yPos(); + IntRect oldRect(child->xPos(), child->yPos() , child->width(), child->height()); // Place the child. child->setPos(x, y); @@ -1066,7 +1065,7 @@ void RenderFlexibleBox::placeChild(RenderObject* child, int x, int y) // descendants. An exception is if we need a layout. In this case, we know we're going to // repaint ourselves (and the child) anyway. if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) - child->repaintDuringLayoutIfMoved(oldChildX, oldChildY); + child->repaintDuringLayoutIfMoved(oldRect); } int RenderFlexibleBox::allowedChildFlex(RenderObject* child, bool expanding, unsigned int group) diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp index db4307719f64123f1b9ff8cb6113479b8e0cf937..b8f6eb939587d97e578bc977448cd015262d3e5f 100644 --- a/WebCore/rendering/RenderObject.cpp +++ b/WebCore/rendering/RenderObject.cpp @@ -1775,7 +1775,7 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const In return false; } -void RenderObject::repaintDuringLayoutIfMoved(int x, int y) +void RenderObject::repaintDuringLayoutIfMoved(const IntRect& rect) { } diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h index 75fad797ccd8636a82ba24022a237cc0658ddf1b..29f7d9b0dd8764cf68c702898a76ecdf865ebac9 100644 --- a/WebCore/rendering/RenderObject.h +++ b/WebCore/rendering/RenderObject.h @@ -725,7 +725,7 @@ public: bool repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const IntRect& oldFullBounds); // Repaint only if the object moved. - virtual void repaintDuringLayoutIfMoved(int oldX, int oldY); + virtual void repaintDuringLayoutIfMoved(const IntRect& rect); // Called to repaint a block's floats. virtual void repaintOverhangingFloats(bool paintAllDescendants = false); diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp index 433a7b9ca5a502e123a851ea72aa7f2e6a1e5040..0037c778b69b05dca5cbb2cbe340ed4b5200377f 100644 --- a/WebCore/rendering/RenderTableSection.cpp +++ b/WebCore/rendering/RenderTableSection.cpp @@ -544,8 +544,7 @@ int RenderTableSection::layoutRows(int toAdd) cell->repaint(); } - int oldCellX = cell->xPos(); - int oldCellY = cell->yPos() - cell->borderTopExtra(); + IntRect oldCellRect(cell->xPos(), cell->yPos() - cell->borderTopExtra() , cell->width(), cell->height()); if (style()->direction() == RTL) { cell->setPos( @@ -560,7 +559,7 @@ int RenderTableSection::layoutRows(int toAdd) // descendants. An exception is if we need a layout. In this case, we know we're going to // repaint ourselves (and the cell) anyway. if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) - cell->repaintDuringLayoutIfMoved(oldCellX, oldCellY); + cell->repaintDuringLayoutIfMoved(oldCellRect); } }