Commit b100b8e7 authored by harrison's avatar harrison

Reviewed by Beth.

        <rdar://problem/4056100> 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):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@17824 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a3f13fdc
2006-11-16 David Harrison <harrison@apple.com>
Reviewed by Beth.
<rdar://problem/4056100> 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 <adele@apple.com>
Reviewed by Adam.
<html><body>
<h4>Deleting into a nested block (was Radar 4056100)</h4>
<ol>
<li>open this file in Safari or Blot</li>
<li>select the first two lines "one" and "two"</li>
<li>press the delete key</li>
</ol>
<div style="width:400px;">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. </div>
<hr>
<div contenteditable>
<div>one</div>
<div>
<div>two</div>
<div>three</div>
</div>
</div>
</body></html>
\ No newline at end of file
......@@ -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();
}
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -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)
......
......@@ -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)
{
}
......
......@@ -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);
......
......@@ -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);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment