Diff
Modified: releases/WebKitGTK/webkit-1.8/LayoutTests/ChangeLog (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/LayoutTests/ChangeLog 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/LayoutTests/ChangeLog 2012-03-24 00:58:40 UTC (rev 111951)
@@ -1,3 +1,15 @@
+2012-03-23 Ryosuke Niwa <[email protected]>
+
+ REGRESSION(r74971): Can't select a line of RTL text on Facebook
+ https://bugs.webkit.org/show_bug.cgi?id=59435
+
+ Reviewed by Eric Seidel.
+
+ Add a regression test for selecting multiline bidirectional text.
+
+ * editing/selection/select-line-break-with-opposite-directionality-expected.txt: Added.
+ * editing/selection/select-line-break-with-opposite-directionality.html: Added.
+
2012-03-23 Antti Koivisto <[email protected]>
REGRESSION (r104060): Page contents not painted if inserting a new stylesheet and temporary body node
Added: releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality-expected.txt (0 => 111951)
--- releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality-expected.txt (rev 0)
+++ releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality-expected.txt 2012-03-24 00:58:40 UTC (rev 111951)
@@ -0,0 +1,30 @@
+This tests selecting LTR/RTL text that spans multiple lines in RTL/LTR block (opposite directionality). To manually test, select text in each of editable regions below by dragging mouse from one edge to another. The entire line should be selected.
+
+TEST 1 line 1:PASS
+TEST 1 line 2:PASS
+TEST 2 line 1:PASS
+TEST 3 line 1:PASS
+TEST 4 line 1:PASS
+TEST 4 line 2:PASS
+TEST 4 line 3:PASS
+TEST 5 line 1:PASS
+TEST 5 line 2:PASS
+TEST 5 line 3:PASS
+TEST 6 line 1:PASS
+TEST 6 line 2:PASS
+TEST 6 line 3:PASS
+TEST 7 line 1:PASS
+TEST 7 line 2:PASS
+TEST 7 line 3:PASS
+TEST 8 line 1:PASS
+TEST 8 line 2:PASS
+TEST 8 line 3:PASS
+TEST 9 line 1:PASS
+TEST 9 line 2:PASS
+TEST 9 line 3:PASS
+TEST 10 line 1:PASS
+TEST 10 line 2:PASS
+TEST 10 line 3:PASS
+
+
+
Property changes on: releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality-expected.txt
___________________________________________________________________
Added: svn:eol-style
Added: releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality.html (0 => 111951)
--- releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality.html (rev 0)
+++ releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality.html 2012-03-24 00:58:40 UTC (rev 111951)
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<style type="text/css">
+
+.tests {
+ width: 250px;
+ float: left;
+ list-style: none;
+}
+
+.tests div, .tests pre {
+ border: solid 1px black;
+ width: 200px;
+ font-size: 13px;
+ line-height: 13px;
+ padding: 13px;
+}
+
+.hideTestsInDRT .tests {
+ display: none;
+}
+
+</style>
+</head>
+<body>
+<p>This tests selecting LTR/RTL text that spans multiple lines in RTL/LTR block (opposite directionality).
+To manually test, select text in each of editable regions below by dragging mouse from one edge to another.
+The entire line should be selected.</p>
+<body>
+<ol class="tests">
+<li><div contenteditable title="0 3, 4 6">abc<br>def</div></li>
+<li><div contenteditable title="0 3">ابص</div></li>
+<li><div contenteditable dir="rtl" title="0 3">abc</div></li>
+<li><div contenteditable title="0 3, 4, 5 6">ابص<span dir="ltr"><br><br>a</span></div></li>
+<li><div contenteditable dir="rtl" title="0 3, 4, 5 6">abc<span dir="rtl"><br><br>ا</span></div></li>
+<li><div contenteditable title="0 3, 4, 5 6">ابص<br><br>a</div></li>
+<li><div contenteditable dir="rtl" title="0 3, 4, 5 6">ابص<br><br>a</div></li>
+</ol>
+<ol class="tests">
+<li><pre contenteditable title="0 3, 4, 5 6"><span dir="rtl">ابص
+
+a</span></pre></li>
+<li><pre contenteditable dir="rtl" title="0 3, 4, 5 6"><span dir="ltr">abc
+
+a</span></pre></li>
+<li><pre contenteditable dir="rtl" title="0 3, 4, 5 6">abc<span dir="rtl">
+
+a</span></pre></li>
+</ol>
+<pre id="log"><script>
+
+function selectLineSafely(test, lineTop) {
+ var y = test.offsetTop + lineTop + 5;
+ eventSender.mouseMoveTo(test.offsetLeft + 5, y);
+ eventSender.mouseDown();
+
+ eventSender.leapForward(200);
+
+ eventSender.mouseMoveTo(test.offsetLeft + test.offsetWidth - 5, y);
+ eventSender.mouseUp();
+}
+
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+
+ if (!window.eventSender)
+ document.writeln('This test requires eventSender');
+ else {
+ var tests = document.getElementsByTagName('li');
+ var testNumber = 0;
+
+ for (var i = 0; i < tests.length; i++) {
+ var test = tests[i].firstChild;
+ offsets = test.title.split(', ');
+
+ for (var j = 0; j < offsets.length; j++) {
+ function log(msg) {
+ return document.write('TEST ' + (i + 1) + ' line ' + (j + 1) + ':' + msg + '\n');
+ }
+
+ var start = parseInt(offsets[j].split(' ')[0]);
+ var afterEnd = parseInt(offsets[j].split(' ')[1]); // Might be NaN
+ var selection = window.getSelection();
+
+ selectLineSafely(test, 13 * (j + 1));
+
+ var actual = selection.toString();
+ var expected = test.innerText.substr(start, afterEnd);
+ if (actual == expected)
+ log('PASS');
+ else
+ log('FAIL - expected "' + expected + '" but got "' + actual + '"');
+ }
+ }
+ }
+
+ document.body.className = 'hideTestsInDRT';
+}
+
+document.addEventListener('selectionchange', function () {
+ var selection = window.getSelection();
+ if (selection.isCollapsed)
+ document.getElementById('log').innerHTML += selection.baseOffset + '\n';
+ else
+ document.getElementById('log').innerHTML += selection.baseOffset + ':' + selection.extentOffset + '\n';
+})
+
+</script
+></body>
+</html>
Property changes on: releases/WebKitGTK/webkit-1.8/LayoutTests/editing/selection/select-line-break-with-opposite-directionality.html
___________________________________________________________________
Added: svn:eol-style
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/ChangeLog (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/ChangeLog 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/ChangeLog 2012-03-24 00:58:40 UTC (rev 111951)
@@ -1,3 +1,49 @@
+2012-03-23 Ryosuke Niwa <[email protected]>
+
+ REGRESSION(r74971): Can't select a line of RTL text on Facebook
+ https://bugs.webkit.org/show_bug.cgi?id=59435
+
+ Reviewed by Eric Seidel.
+
+ The bug was caused by inline text boxes created by BRs being placed at the end of the line
+ according to the block's direction regardless of its unicode bidi-level. e.g. if we have
+ <div dir="rtl"><span dir="ltr">hello<br>world</span></div>
+ the inline box generated by the br has the bidi-level of 2 like the rest of text in the span.
+ This inline text box gives an illusion of having text on the left of "hello" to hit testing
+ and editing code and causes all sorts of problems.
+
+ Fixed the bug by replacing calls to nextLeafChild and prevLeafChild by newly introduced
+ nextLeafChildIgnoringLineBreak and prevLeafChildIgnoringLineBreak. These two functions will
+ return 0 when they hit the end of a line or inline text box that's a line break. In effect,
+ hit testing and editing code can ignore inline boxes generated by br's.
+
+ In the long term, we should move these two functions into RenderedPosition along with the rest
+ of code that converts a Position and an inline box, offset pair.
+
+ Test: editing/selection/select-line-break-with-opposite-directionality.html
+
+ * dom/Position.cpp:
+ (WebCore::Position::getInlineBoxAndOffset):
+ * editing/RenderedPosition.cpp:
+ (WebCore::RenderedPosition::prevLeafChild):
+ (WebCore::RenderedPosition::nextLeafChild):
+ * rendering/InlineBox.cpp:
+ (WebCore::InlineBox::nextLeafChildIgnoringLineBreak):
+ (WebCore::InlineBox::prevLeafChildIgnoringLineBreak):
+ * rendering/InlineBox.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::positionForPointWithInlineChildren):
+ * rendering/RenderText.cpp:
+ (WebCore::lineDirectionPointFitsInBox): If we're on the left of a RTL line, we should stay at
+ upstream position since we're at the end of a line.
+ (WebCore::createVisiblePositionAfterAdjustingOffsetForBiDi): Merge the two special cases into
+ the general loop as the comment suggests. Skip an inline text box for a line break at the left
+ edge when there are more line boxes on the line.
+ (WebCore::RenderText::positionForPoint):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::closestLeafChildForLogicalLeftPosition): Ignore line boxes created for
+ line boxes when there are other boxes on the line.
+
2012-03-23 Antti Koivisto <[email protected]>
REGRESSION (r104060): Page contents not painted if inserting a new stylesheet and temporary body node
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/dom/Position.cpp (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/dom/Position.cpp 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/dom/Position.cpp 2012-03-24 00:58:40 UTC (rev 111951)
@@ -1152,7 +1152,8 @@
}
if (((caretOffset == caretMaxOffset) ^ (affinity == DOWNSTREAM))
- || ((caretOffset == caretMinOffset) ^ (affinity == UPSTREAM)))
+ || ((caretOffset == caretMinOffset) ^ (affinity == UPSTREAM))
+ || (caretOffset == caretMaxOffset && box->nextLeafChild() && box->nextLeafChild()->isLineBreak()))
break;
candidate = box;
@@ -1217,10 +1218,10 @@
}
if (caretOffset == inlineBox->caretLeftmostOffset()) {
- InlineBox* prevBox = inlineBox->prevLeafChild();
+ InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak();
if (!prevBox || prevBox->bidiLevel() < level) {
// Left edge of a secondary run. Set to the right edge of the entire run.
- while (InlineBox* nextBox = inlineBox->nextLeafChild()) {
+ while (InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
if (nextBox->bidiLevel() < level)
break;
inlineBox = nextBox;
@@ -1228,7 +1229,7 @@
caretOffset = inlineBox->caretRightmostOffset();
} else if (prevBox->bidiLevel() > level) {
// Right edge of a "tertiary" run. Set to the left edge of that run.
- while (InlineBox* tertiaryBox = inlineBox->prevLeafChild()) {
+ while (InlineBox* tertiaryBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
if (tertiaryBox->bidiLevel() <= level)
break;
inlineBox = tertiaryBox;
@@ -1236,10 +1237,10 @@
caretOffset = inlineBox->caretLeftmostOffset();
}
} else {
- InlineBox* nextBox = inlineBox->nextLeafChild();
+ InlineBox* nextBox = inlineBox->nextLeafChildIgnoringLineBreak();
if (!nextBox || nextBox->bidiLevel() < level) {
// Right edge of a secondary run. Set to the left edge of the entire run.
- while (InlineBox* prevBox = inlineBox->prevLeafChild()) {
+ while (InlineBox* prevBox = inlineBox->prevLeafChildIgnoringLineBreak()) {
if (prevBox->bidiLevel() < level)
break;
inlineBox = prevBox;
@@ -1247,7 +1248,7 @@
caretOffset = inlineBox->caretLeftmostOffset();
} else if (nextBox->bidiLevel() > level) {
// Left edge of a "tertiary" run. Set to the right edge of that run.
- while (InlineBox* tertiaryBox = inlineBox->nextLeafChild()) {
+ while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
if (tertiaryBox->bidiLevel() <= level)
break;
inlineBox = tertiaryBox;
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/editing/RenderedPosition.cpp (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/editing/RenderedPosition.cpp 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/editing/RenderedPosition.cpp 2012-03-24 00:58:40 UTC (rev 111951)
@@ -100,14 +100,14 @@
InlineBox* RenderedPosition::prevLeafChild() const
{
if (m_prevLeafChild == uncachedInlineBox())
- m_prevLeafChild = m_inlineBox->prevLeafChild();
+ m_prevLeafChild = m_inlineBox->prevLeafChildIgnoringLineBreak();
return m_prevLeafChild;
}
InlineBox* RenderedPosition::nextLeafChild() const
{
if (m_nextLeafChild == uncachedInlineBox())
- m_nextLeafChild = m_inlineBox->nextLeafChild();
+ m_nextLeafChild = m_inlineBox->nextLeafChildIgnoringLineBreak();
return m_nextLeafChild;
}
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/InlineBox.cpp (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/InlineBox.cpp 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/InlineBox.cpp 2012-03-24 00:58:40 UTC (rev 111951)
@@ -299,7 +299,23 @@
leaf = parent()->prevLeafChild();
return leaf;
}
-
+
+InlineBox* InlineBox::nextLeafChildIgnoringLineBreak() const
+{
+ InlineBox* leaf = nextLeafChild();
+ if (leaf && leaf->isLineBreak())
+ return 0;
+ return leaf;
+}
+
+InlineBox* InlineBox::prevLeafChildIgnoringLineBreak() const
+{
+ InlineBox* leaf = prevLeafChild();
+ if (leaf && leaf->isLineBreak())
+ return 0;
+ return leaf;
+}
+
RenderObject::SelectionState InlineBox::selectionState()
{
return renderer()->selectionState();
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/InlineBox.h (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/InlineBox.h 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/InlineBox.h 2012-03-24 00:58:40 UTC (rev 111951)
@@ -200,7 +200,13 @@
InlineBox* nextLeafChild() const;
InlineBox* prevLeafChild() const;
-
+
+ // Helper functions for editing and hit-testing code.
+ // FIXME: These two functions should be moved to RenderedPosition once the code to convert between
+ // Position and inline box, offset pair is moved to RenderedPosition.
+ InlineBox* nextLeafChildIgnoringLineBreak() const;
+ InlineBox* prevLeafChildIgnoringLineBreak() const;
+
RenderObject* renderer() const { return m_renderer; }
InlineFlowBox* parent() const
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RenderBlock.cpp (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RenderBlock.cpp 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RenderBlock.cpp 2012-03-24 00:58:40 UTC (rev 111951)
@@ -4606,12 +4606,17 @@
if (closestBox) {
if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()
&& pointInLogicalContents.y() < firstRootBoxWithChildren->logicalTop()) {
+ InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
+ if (box->isLineBreak()) {
+ if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
+ box = newBox;
+ }
// y coordinate is above first root line box, so return the start of the first
- return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
+ return VisiblePosition(positionForBox(box, true), DOWNSTREAM);
}
// pass the box a top position that is inside it
- LayoutPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
+ LayoutPoint point(pointInLogicalContents.x(), max(closestBox->root()->lineTop(), closestBox->root()->selectionTop()));
if (!isHorizontalWritingMode())
point = point.transposedPoint();
if (closestBox->renderer()->isReplaced())
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RenderText.cpp (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RenderText.cpp 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RenderText.cpp 2012-03-24 00:58:40 UTC (rev 111951)
@@ -479,8 +479,11 @@
// the x coordinate is equal to the left edge of this box
// the affinity must be downstream so the position doesn't jump back to the previous line
- if (pointLineDirection == box->logicalLeft())
+ // except when box is the first box in the line
+ if (pointLineDirection <= box->logicalLeft()) {
+ shouldAffinityBeDownstream = !box->prevLeafChild() ? UpstreamIfPositionIsNotAtStart : AlwaysDownstream;
return true;
+ }
// and the x coordinate is to the left of the right edge of this box
// check to see if position goes in this box
@@ -491,10 +494,10 @@
// box is first on line
// and the x coordinate is to the left of the first text box left edge
- if (!box->prevOnLine() && pointLineDirection < box->logicalLeft())
+ if (!box->prevLeafChildIgnoringLineBreak() && pointLineDirection < box->logicalLeft())
return true;
- if (!box->nextOnLine()) {
+ if (!box->nextLeafChildIgnoringLineBreak()) {
// box is last on line
// and the x coordinate is to the right of the last text box right edge
// generate VisiblePosition, use UPSTREAM affinity if possible
@@ -535,7 +538,7 @@
if (positionIsAtStartOfBox == box->isLeftToRightDirection()) {
// offset is on the left edge
- const InlineBox* prevBox = box->prevLeafChild();
+ const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak();
if ((prevBox && prevBox->bidiLevel() == box->bidiLevel())
|| box->renderer()->containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA
return createVisiblePositionForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
@@ -545,7 +548,7 @@
const InlineBox* leftmostBox;
do {
leftmostBox = prevBox;
- prevBox = leftmostBox->prevLeafChild();
+ prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
} while (prevBox && prevBox->bidiLevel() > box->bidiLevel());
return createVisiblePositionForBox(leftmostBox, leftmostBox->caretRightmostOffset(), shouldAffinityBeDownstream);
}
@@ -556,7 +559,7 @@
const InlineBox* nextBox = box;
do {
rightmostBox = nextBox;
- nextBox = rightmostBox->nextLeafChild();
+ nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
} while (nextBox && nextBox->bidiLevel() >= box->bidiLevel());
return createVisiblePositionForBox(rightmostBox,
box->isLeftToRightDirection() ? rightmostBox->caretMaxOffset() : rightmostBox->caretMinOffset(), shouldAffinityBeDownstream);
@@ -565,7 +568,7 @@
return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
}
- const InlineBox* nextBox = box->nextLeafChild();
+ const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak();
if ((nextBox && nextBox->bidiLevel() == box->bidiLevel())
|| box->renderer()->containingBlock()->style()->direction() == box->direction())
return createVisiblePositionForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
@@ -576,7 +579,7 @@
const InlineBox* rightmostBox;
do {
rightmostBox = nextBox;
- nextBox = rightmostBox->nextLeafChild();
+ nextBox = rightmostBox->nextLeafChildIgnoringLineBreak();
} while (nextBox && nextBox->bidiLevel() > box->bidiLevel());
return createVisiblePositionForBox(rightmostBox, rightmostBox->caretLeftmostOffset(), shouldAffinityBeDownstream);
}
@@ -587,7 +590,7 @@
const InlineBox* prevBox = box;
do {
leftmostBox = prevBox;
- prevBox = leftmostBox->prevLeafChild();
+ prevBox = leftmostBox->prevLeafChildIgnoringLineBreak();
} while (prevBox && prevBox->bidiLevel() >= box->bidiLevel());
return createVisiblePositionForBox(leftmostBox,
box->isLeftToRightDirection() ? leftmostBox->caretMinOffset() : leftmostBox->caretMaxOffset(), shouldAffinityBeDownstream);
@@ -601,28 +604,14 @@
if (!firstTextBox() || textLength() == 0)
return createVisiblePosition(0, DOWNSTREAM);
- // Get the offset for the position, since this will take rtl text into account.
- int offset;
-
LayoutUnit pointLineDirection = firstTextBox()->isHorizontal() ? point.x() : point.y();
LayoutUnit pointBlockDirection = firstTextBox()->isHorizontal() ? point.y() : point.x();
-
- // FIXME: We should be able to roll these special cases into the general cases in the loop below.
- if (firstTextBox() && pointBlockDirection < firstTextBox()->root()->selectionBottom() && pointLineDirection < firstTextBox()->logicalLeft()) {
- // at the y coordinate of the first line or above
- // and the x coordinate is to the left of the first text box left edge
- offset = firstTextBox()->offsetForPosition(pointLineDirection);
- return createVisiblePositionAfterAdjustingOffsetForBiDi(firstTextBox(), offset, UpstreamIfPositionIsNotAtStart);
- }
- if (lastTextBox() && pointBlockDirection >= lastTextBox()->root()->selectionTop() && pointLineDirection >= lastTextBox()->logicalRight()) {
- // at the y coordinate of the last line or below
- // and the x coordinate is to the right of the last text box right edge
- offset = lastTextBox()->offsetForPosition(pointLineDirection);
- return createVisiblePositionAfterAdjustingOffsetForBiDi(lastTextBox(), offset, AlwaysUpstream);
- }
- InlineTextBox* lastBoxAbove = 0;
+ InlineTextBox* lastBox = 0;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
+ if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak())
+ box = box->nextTextBox();
+
RootInlineBox* rootBox = box->root();
if (pointBlockDirection >= rootBox->selectionTop() || pointBlockDirection >= rootBox->lineTop()) {
LayoutUnit bottom = rootBox->selectionBottom();
@@ -631,15 +620,19 @@
if (pointBlockDirection < bottom) {
ShouldAffinityBeDownstream shouldAffinityBeDownstream;
- offset = box->offsetForPosition(pointLineDirection);
if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream))
- return createVisiblePositionAfterAdjustingOffsetForBiDi(box, offset, shouldAffinityBeDownstream);
+ return createVisiblePositionAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
}
- lastBoxAbove = box;
}
+ lastBox = box;
}
- return createVisiblePosition(lastBoxAbove ? lastBoxAbove->start() + lastBoxAbove->len() : 0, DOWNSTREAM);
+ if (lastBox) {
+ ShouldAffinityBeDownstream shouldAffinityBeDownstream;
+ lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream);
+ return createVisiblePositionAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
+ }
+ return createVisiblePosition(0, DOWNSTREAM);
}
LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
Modified: releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RootInlineBox.cpp (111950 => 111951)
--- releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RootInlineBox.cpp 2012-03-24 00:58:06 UTC (rev 111950)
+++ releases/WebKitGTK/webkit-1.8/Source/WebCore/rendering/RootInlineBox.cpp 2012-03-24 00:58:40 UTC (rev 111951)
@@ -580,6 +580,14 @@
{
InlineBox* firstLeaf = firstLeafChild();
InlineBox* lastLeaf = lastLeafChild();
+
+ if (firstLeaf != lastLeaf) {
+ if (firstLeaf->isLineBreak())
+ firstLeaf = firstLeaf->nextLeafChildIgnoringLineBreak();
+ else if (lastLeaf->isLineBreak())
+ lastLeaf = lastLeaf->prevLeafChildIgnoringLineBreak();
+ }
+
if (firstLeaf == lastLeaf && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
return firstLeaf;
@@ -595,7 +603,7 @@
return lastLeaf;
InlineBox* closestLeaf = 0;
- for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChild()) {
+ for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChildIgnoringLineBreak()) {
if (!leaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
closestLeaf = leaf;
if (leftPosition < leaf->logicalRight())