зеркало из https://github.com/mozilla/pjs.git
Bug 240933 - Part 3: Correct the caret movement throughout textareas (and pre elements with caret browsing turned on as well); r=roc a=dbaron
--HG-- extra : rebase_source : 198f679bb5cea82b710c921576fa44c59f77aa23
This commit is contained in:
Родитель
5c72c73a4a
Коммит
e40ce9864e
|
@ -5219,6 +5219,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
|
|||
{
|
||||
PRBool eatingNonRenderableWS = PR_FALSE;
|
||||
PRBool done = PR_FALSE;
|
||||
PRBool jumpedLine = PR_FALSE;
|
||||
|
||||
while (!done) {
|
||||
PRBool movingInFrameDirection =
|
||||
|
@ -5230,7 +5231,6 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
|
|||
done = current->PeekOffsetCharacter(movingInFrameDirection, &offset);
|
||||
|
||||
if (!done) {
|
||||
PRBool jumpedLine;
|
||||
result =
|
||||
current->GetFrameFromDirection(aPos->mDirection, aPos->mVisual,
|
||||
aPos->mJumpLines, aPos->mScrollViewStop,
|
||||
|
@ -5251,6 +5251,15 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
|
|||
aPos->mResultContent = range.content;
|
||||
// Output offset is relative to content, not frame
|
||||
aPos->mContentOffset = offset < 0 ? range.end : range.start + offset;
|
||||
// If we're dealing with a text frame and moving backward positions us at
|
||||
// the end of that line, decrease the offset by one to make sure that
|
||||
// we're placed before the linefeed character on the previous line.
|
||||
if (offset < 0 && jumpedLine &&
|
||||
aPos->mDirection == eDirPrevious &&
|
||||
current->GetStyleText()->NewlineIsSignificant() &&
|
||||
current->HasTerminalNewline()) {
|
||||
--aPos->mContentOffset;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5425,8 +5425,7 @@ IsAcceptableCaretPosition(const gfxSkipCharsIterator& aIter, gfxTextRun* aTextRu
|
|||
PRUint32 index = aIter.GetSkippedOffset();
|
||||
if (!aTextRun->IsClusterStart(index))
|
||||
return PR_FALSE;
|
||||
return !(aFrame->GetStyleText()->NewlineIsSignificant() &&
|
||||
aTextRun->GetChar(index) == '\n');
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -5451,8 +5450,8 @@ nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
|
|||
PRInt32 startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset);
|
||||
|
||||
if (!aForward) {
|
||||
PRInt32 i;
|
||||
for (i = NS_MIN(trimmed.GetEnd(), startOffset) - 1;
|
||||
// If at the beginning of the line, look at the previous continuation
|
||||
for (PRInt32 i = NS_MIN(trimmed.GetEnd(), startOffset) - 1;
|
||||
i >= trimmed.mStart; --i) {
|
||||
iter.SetOriginalOffset(i);
|
||||
if (IsAcceptableCaretPosition(iter, mTextRun, this)) {
|
||||
|
@ -5462,16 +5461,19 @@ nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
|
|||
}
|
||||
*aOffset = 0;
|
||||
} else {
|
||||
PRInt32 i;
|
||||
for (i = startOffset + 1; i <= trimmed.GetEnd(); ++i) {
|
||||
iter.SetOriginalOffset(i);
|
||||
// XXX we can't necessarily stop at the end of this frame,
|
||||
// but we really have no choice right now. We need to do a deeper
|
||||
// fix/restructuring of PeekOffsetCharacter
|
||||
if (i == trimmed.GetEnd() ||
|
||||
IsAcceptableCaretPosition(iter, mTextRun, this)) {
|
||||
*aOffset = i - mContentOffset;
|
||||
return PR_TRUE;
|
||||
// If we're at the end of a line, look at the next continuation
|
||||
iter.SetOriginalOffset(startOffset);
|
||||
if (iter.GetSkippedOffset() <= PRUint32(trimmed.GetEnd()) &&
|
||||
!(iter.GetSkippedOffset() < PRUint32(trimmed.GetEnd()) &&
|
||||
GetStyleText()->NewlineIsSignificant() &&
|
||||
mTextRun->GetChar(iter.GetSkippedOffset()) == '\n')) {
|
||||
for (PRInt32 i = startOffset + 1; i <= trimmed.GetEnd(); ++i) {
|
||||
iter.SetOriginalOffset(i);
|
||||
if (i == trimmed.GetEnd() ||
|
||||
IsAcceptableCaretPosition(iter, mTextRun, this)) {
|
||||
*aOffset = i - mContentOffset;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
*aOffset = contentLength;
|
||||
|
|
|
@ -18,6 +18,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=288789
|
|||
|
||||
אaב
|
||||
|
||||
</textarea>
|
||||
<textarea id="tb">
|
||||
|
||||
abc
|
||||
|
||||
</textarea>
|
||||
</div>
|
||||
<pre id="test">
|
||||
|
@ -50,9 +55,59 @@ function test() {
|
|||
|
||||
textarea.focus();
|
||||
collapse(0);
|
||||
testLeft(1);
|
||||
collapse(5);
|
||||
testRight(4);
|
||||
ok(true, "Testing forward movement in RTL mode");
|
||||
for (var i = 0; i < textarea.textContent.length; ++i) {
|
||||
if (i == 0) {
|
||||
testRight(i);
|
||||
}
|
||||
if (textarea.textContent[i] == 'a') {
|
||||
testLeft(i);
|
||||
} else {
|
||||
testLeft(i + 1);
|
||||
}
|
||||
if (i == textarea.textContent.length - 1) {
|
||||
testLeft(i + 1);
|
||||
}
|
||||
}
|
||||
ok(true, "Testing backward movement in RTL mode");
|
||||
for (var i = textarea.textContent.length; i > 0; --i) {
|
||||
if (i == textarea.textContent.length) {
|
||||
testLeft(i);
|
||||
}
|
||||
if (i > 0 && textarea.textContent[i - 1] == 'a') {
|
||||
testRight(i);
|
||||
} else {
|
||||
testRight(i - 1);
|
||||
}
|
||||
if (i == 1) {
|
||||
testRight(i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
textarea = $("tb");
|
||||
textarea.focus();
|
||||
collapse(0);
|
||||
ok(true, "Testing forward movement in LTR mode");
|
||||
for (var i = 0; i < textarea.textContent.length; ++i) {
|
||||
if (i == 0) {
|
||||
testLeft(i);
|
||||
}
|
||||
testRight(i + 1);
|
||||
if (i == textarea.textContent.length - 1) {
|
||||
testRight(i + 1);
|
||||
}
|
||||
}
|
||||
ok(true, "Testing backward movement in LTR mode");
|
||||
for (var i = textarea.textContent.length; i > 0; --i) {
|
||||
if (i == textarea.textContent.length) {
|
||||
testRight(i);
|
||||
}
|
||||
testLeft(i - 1);
|
||||
if (i == 1) {
|
||||
testLeft(i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -68,13 +68,13 @@ function test() {
|
|||
editor.innerHTML = "<pre>aa\nbb</pre>";
|
||||
sel.collapse(editor.firstChild.firstChild, 0);
|
||||
testRight(editor.firstChild.firstChild, 1);
|
||||
// at the 'bb' but HINTLEFT so appears at the end of the first line
|
||||
testRight(editor.firstChild.firstChild, 3);
|
||||
// at the end of the first line, before the \n
|
||||
testRight(editor.firstChild.firstChild, 2);
|
||||
testRight(editor.firstChild.firstChild, 3);
|
||||
testRight(editor.firstChild.firstChild, 4);
|
||||
testLeft(editor.firstChild.firstChild, 3);
|
||||
// at the 'bb' but HINTLEFT so appears at the end of the first line
|
||||
testLeft(editor.firstChild.firstChild, 3);
|
||||
// at the end of the first line, before the \n
|
||||
testLeft(editor.firstChild.firstChild, 2);
|
||||
testLeft(editor.firstChild.firstChild, 1);
|
||||
testLeft(editor.firstChild.firstChild, 0);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче