| Index: Source/core/rendering/RenderView.cpp
|
| diff --git a/Source/core/rendering/RenderView.cpp b/Source/core/rendering/RenderView.cpp
|
| index c676442fe0d1c1450ab2685bfecceb689cb7c011..3ab28457101659ef8a8db559562aa3e14a57a0dc 100644
|
| --- a/Source/core/rendering/RenderView.cpp
|
| +++ b/Source/core/rendering/RenderView.cpp
|
| @@ -705,6 +705,27 @@ void RenderView::setMaximalOutlineSize(int o)
|
| }
|
| }
|
|
|
| +// When exploring the RenderTree looking for the nodes involved in the Selection, sometimes it's
|
| +// required to change the traversing direction because the "start" position is below the "end" one.
|
| +static inline RenderObject* getNextOrPrevRenderObjectBasedOnDirection(const RenderObject* o, const RenderObject* stop, bool& continueExploring, bool& exploringBackwards)
|
| +{
|
| + RenderObject* next;
|
| + if (exploringBackwards) {
|
| + next = o->previousInPreOrder();
|
| + continueExploring = next && !(next)->isRenderView();
|
| + } else {
|
| + next = o->nextInPreOrder();
|
| + continueExploring = next && next != stop;
|
| + exploringBackwards = !next && (next != stop);
|
| + if (exploringBackwards) {
|
| + next = stop->previousInPreOrder();
|
| + continueExploring = next && !next->isRenderView();
|
| + }
|
| + }
|
| +
|
| + return next;
|
| +}
|
| +
|
| void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
|
| {
|
| // Make sure both our start and end objects are defined.
|
| @@ -717,9 +738,6 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
|
| m_selectionEnd == end && m_selectionEndPos == endPos)
|
| return;
|
|
|
| - if ((start && end) && (start->flowThreadContainingBlock() != end->flowThreadContainingBlock()))
|
| - return;
|
| -
|
| // Record the old selected objects. These will be used later
|
| // when we compare against the new selected objects.
|
| int oldStartPos = m_selectionStartPos;
|
| @@ -739,7 +757,9 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
|
|
|
| RenderObject* os = m_selectionStart;
|
| RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
|
| - while (os && os != stop) {
|
| + bool exploringBackwards = false;
|
| + bool continueExploring = os && (os != stop);
|
| + while (continueExploring) {
|
| if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
|
| // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
|
| oldSelectedObjects.set(os, adoptPtr(new RenderSelectionInfo(os, true)));
|
| @@ -755,7 +775,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
|
| }
|
| }
|
|
|
| - os = os->nextInPreOrder();
|
| + os = getNextOrPrevRenderObjectBasedOnDirection(os, stop, continueExploring, exploringBackwards);
|
| }
|
|
|
| // Now clear the selection.
|
| @@ -794,7 +814,9 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
|
| // Now that the selection state has been updated for the new objects, walk them again and
|
| // put them in the new objects list.
|
| o = start;
|
| - while (o && o != stop) {
|
| + exploringBackwards = false;
|
| + continueExploring = o && (o != stop);
|
| + while (continueExploring) {
|
| if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
|
| newSelectedObjects.set(o, adoptPtr(new RenderSelectionInfo(o, true)));
|
| RenderBlock* cb = o->containingBlock();
|
| @@ -807,7 +829,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
|
| }
|
| }
|
|
|
| - o = o->nextInPreOrder();
|
| + o = getNextOrPrevRenderObjectBasedOnDirection(o, stop, continueExploring, exploringBackwards);
|
| }
|
|
|
| if (!m_frameView || blockRepaintMode == RepaintNothing)
|
|
|