[Webkit-unassigned] [Bug 24168] RTL: Home/End key does not behave correctly in mixed bidi text in RTL document
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Thu Apr 23 16:10:16 PDT 2009
https://bugs.webkit.org/show_bug.cgi?id=24168
------- Comment #12 from xji at chromium.org 2009-04-23 16:10 PDT -------
(In reply to comment #11)
> (In reply to comment #10)
>
> > > + if (!startRenderer) {
> > > + startNode = NULL;
> > > + return;
> > > + }
> > >
> > > Can this ever happen? I know that there is other old code checking for this,
> > > but I don't think this case can happen. Maybe the code should assert that it
> > > doesn't happen. Again, if you leave this code in, please use 0 instead of NULL.
> >
> > I will run layout test against it to check whether it happens.
> > But I see checking whether renderer exists in many places of the code. I am
> > thinking probably to leave it there.
> > Or renderer of leave box is different, and should *never* be NULL?
>
> A Node's renderer() can be null, but, as far as I can tell, an InlineBox's
> renderer() can never be null. Most places in WebCore that access an InlineBox's
> render() don't null check.
Running all the layout test of webkit, and InlineBox's renderer is never NULL.
So, I am removing the null check.
>
> > I have to admit that I copied most of the logic from startOfLine/endOfLine by
> > understanding the main part of them, but not every path.
> > I did not quite understand the former logic, and I forgot whether it is ever
> > been hit by the test. As to the latter logic, I think it is hit by the code,
> > and that is why I changed isSameLine() to isSameLogicLine().
> > I will run test again to find out more.
>
> I think some of that logic my actually apply to home/end but *not* to the
> actual current behavior of startOfLine() and endOfLine(), and it was just
> written assuming that the logical and visual orders are the same. You may be
> able to find cases where startOfLine() and endOfLine() fail with RTL or
> bidirectional text because of the wrong assumptions.
>
First, following is the case where inSameLine() and isLogicalSameLine() return
different result:
For the test case:
<div dir=rtl contenteditable class="test">abc אבג xyz
דהו def</div>
If you place caret at visually right most point (right of 'c'), which is
position 1 in the line, the logicEndOfLine is position 20 in the line. These 2
positions are inSameLogicalLine(), but not inSame(Visual)Line().
The (visual)startOfLine() of position 20 is position 17, but the
(visual)startOfLine() of position 1 falls into the following if block:
if (visPos.isNotNull()) {
// Make sure ....
Position p = visPos.deepEquivalent();
if (p.m_offset > c.deepEquivalent().m_offset &&
p.node()->isSameNode(c.deepEquivalent().node())) {
visPos = c.previous();
if (visPos.isNull())
return VisiblePosition();
visPos = startPositionForLine(visPos);
}
}
And returned "VisiblePosition()".
That is might be a bug in startOfLine() as you mentioned. And that is why I
changed it to isLogicalSameLine().
==========================
Second, as to the 2 'if' block in logicalStartOfLine() and logicalEndOfLine().
I did not find test cases that hit the following 'if' block in
logicalStartOfLine():
// Make sure the start of line is not greater than the given input
position. Else use the previous position to
// obtain start of line. This condition happens when the input position is
before the space character at the end
// of a soft-wrapped non-editable line. In this scenario,
logicalStartPositionForLine would incorrectly hand back a position
// greater than the input position. This fix is to account for the
discrepancy between lines with webkit-line-break:after-white-space
// style versus lines without that style, which would break before a space
by default.
Position p = visPos.deepEquivalent();
if (p.m_offset > c.deepEquivalent().m_offset &&
p.node()->isSameNode(c.deepEquivalent().node())) {
visPos = c.previous();
if (visPos.isNull())
return VisiblePosition();
visPos = logicalStartPositionForLine(visPos);
}
But I did not find test cases that hit the following 'if' block in
logicalEndOfLine().
if (!inSameLogicalLine(c, visPos))
For a long line which needs wrapping, the logical end position for the lines
which is not the last 2 lines might incorrectly hand back the logical beginning
of the next line. So the input position and logical end position are not in the
same logical line.
For example, <div contenteditable dir="rtl"
style="line-break:before-white-space">abcdefg abcdefg abcdefg a abcdefg abcdefg
abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg </div>
For such case, the following statement inside the 'if' does not solve the
problem because every previous point (except the right-most one) would still
return the same logical end position for the line, while the right-most point's
previous point will be null, and a VisiblePosition() will be returned which
makes the END key does not have any effect if the caret is at the right-most of
the line (right of any characters in the line).
if (!inSameLogicLine(c, visPos)) {
visPos = c.previous();
if (visPos.isNull())
return VisiblePosition();
visPos = logicEndPositionForLine(visPos);
}
For such case, I think the above should be changed to:
// In this case, use the previous position of the computed logical end
position.
if (!inSameLogicalLine(c, visPos))
visPos = visPos.previous();
--
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
More information about the webkit-unassigned
mailing list