Bug 1015550 - Line boundary is incorrect for multi-char bullet. r=surkov

This commit is contained in:
Xidorn Quan 2014-05-27 18:07:00 +02:00
parent 40c1076f3d
commit bba20bcad0
2 changed files with 66 additions and 17 deletions

View File

@ -429,6 +429,9 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
nsSelectionAmount aAmount,
EWordMovementType aWordMovementType)
{
NS_ASSERTION(aDirection == eDirPrevious || aAmount != eSelectBeginLine,
"eSelectBeginLine should only be used with eDirPrevious");
// Find a leaf accessible frame to start with. PeekOffset wants this.
HyperTextAccessible* text = this;
Accessible* child = nullptr;
@ -447,22 +450,32 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
if (text->IsHTMLListItem()) {
HTMLLIAccessible* li = text->AsHTMLListItem();
if (child == li->Bullet()) {
// It works only when the bullet is one single char.
if (aDirection == eDirPrevious)
return text != this ? TransformOffset(text, 0, false) : 0;
if (aAmount == eSelectEndLine || aAmount == eSelectLine) {
if (text != this)
return TransformOffset(text, 1, true);
// Ask a text leaf next (if not empty) to the bullet for an offset
// since list item may be multiline.
return aOffset + 1 < CharacterCount() ?
FindOffset(aOffset + 1, aDirection, aAmount, aWordMovementType) : 1;
// XXX: the logic is broken for multichar bullets in moving by
// char/cluster/word cases.
if (text != this) {
return aDirection == eDirPrevious ?
TransformOffset(text, 0, false) :
TransformOffset(text, 1, true);
}
if (aDirection == eDirPrevious)
return 0;
// Case of word and char boundaries.
return text != this ? TransformOffset(text, 1, true) : 1;
uint32_t nextOffset = GetChildOffset(1);
if (nextOffset == 0)
return 0;
switch (aAmount) {
case eSelectLine:
case eSelectEndLine:
// Ask a text leaf next (if not empty) to the bullet for an offset
// since list item may be multiline.
return nextOffset < CharacterCount() ?
FindOffset(nextOffset, aDirection, aAmount, aWordMovementType) :
nextOffset;
default:
return nextOffset;
}
}
}
@ -521,8 +534,12 @@ HyperTextAccessible::FindOffset(uint32_t aOffset, nsDirection aDirection,
return 0;
// PeekOffset stops right before bullet so return 0 to workaround it.
if (IsHTMLListItem() && aAmount == eSelectBeginLine && hyperTextOffset == 1)
return 0;
if (IsHTMLListItem() && aAmount == eSelectBeginLine &&
hyperTextOffset > 0) {
Accessible* prevOffsetChild = GetChildAtOffset(hyperTextOffset - 1);
if (prevOffsetChild == AsHTMLListItem()->Bullet())
return 0;
}
}
return hyperTextOffset;

View File

@ -126,11 +126,34 @@
[ 8, 11, "and ", 8, 12 ] ]);
testTextAtOffset([ "li4" ], BOUNDARY_LINE_START,
[ [ 0, 6, kDiscBulletChar + "a " + kEmbedChar + " c", 0, 6 ] ]);
testTextAtOffset([ "li5" ], BOUNDARY_LINE_START,
[ [ 0, 1, kDiscBulletChar + "\n", 0, 2 ],
[ 2, 6, "hello", 2, 7 ] ]);
testTextAtOffset([ "ul1" ], BOUNDARY_LINE_START,
[ [ 0, 0, kEmbedChar, 0, 1 ],
[ 1, 1, kEmbedChar, 1, 2 ],
[ 2, 2, kEmbedChar, 2, 3 ],
[ 3, 4, kEmbedChar, 3, 4 ] ]);
[ 3, 3, kEmbedChar, 3, 4 ],
[ 4, 5, kEmbedChar, 4, 5 ] ]);
testTextAtOffset([ "li6" ], BOUNDARY_LINE_START,
[ [ 0, 6, "1.Item", 0, 6 ] ]);
testTextAtOffset([ "li7" ], BOUNDARY_LINE_START,
[ [ 0, 2, "2.", 0, 2 ] ]);
testTextAtOffset([ "li8" ], BOUNDARY_LINE_START,
[ [ 0, 8, "3.a long ", 0, 9 ],
[ 9, 12, "and ", 9, 13 ] ]);
testTextAtOffset([ "li9" ], BOUNDARY_LINE_START,
[ [ 0, 7, "4.a " + kEmbedChar + " c", 0, 7 ] ]);
testTextAtOffset([ "li10" ], BOUNDARY_LINE_START,
[ [ 0, 2, "5.\n", 0, 3 ],
[ 3, 7, "hello", 3, 8 ] ]);
testTextAtOffset([ "ol1" ], BOUNDARY_LINE_START,
[ [ 0, 0, kEmbedChar, 0, 1 ],
[ 1, 1, kEmbedChar, 1, 2 ],
[ 2, 2, kEmbedChar, 2, 3 ],
[ 3, 3, kEmbedChar, 3, 4 ],
[ 4, 5, kEmbedChar, 4, 5 ] ]);
//////////////////////////////////////////////////////////////////////////
// Nested hypertexts
@ -210,8 +233,17 @@ two words
<li id="li2"></li>
<li id="li3" style="width:10ex; font-family:monospace; font-size:10pt;">a long and winding road that lead me to your door</li>
<li id="li4">a <a href=''>b</a> c</li>
<li id="li5"><br>hello</li>
</ul>
<ol id="ol1">
<li id="li6">Item</li>
<li id="li7"></li>
<li id="li8" style="width:10ex; font-family:monospace; font-size:10pt;">a long and winding road that lead me to your door</li>
<li id="li9">a <a href=''>b</a> c</li>
<li id="li10"><br>hello</li>
</ol>
<div id="ht_5">
<div>
<p>sectiounus</p>