зеркало из https://github.com/mozilla/gecko-dev.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 : 9f015607bc84a11137ab11ba47c14e98c20e3970
This commit is contained in:
Родитель
93e95a8bd1
Коммит
8de2c3cb19
|
@ -5348,6 +5348,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
|
||||||
{
|
{
|
||||||
PRBool eatingNonRenderableWS = PR_FALSE;
|
PRBool eatingNonRenderableWS = PR_FALSE;
|
||||||
PRBool done = PR_FALSE;
|
PRBool done = PR_FALSE;
|
||||||
|
PRBool jumpedLine = PR_FALSE;
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
PRBool movingInFrameDirection =
|
PRBool movingInFrameDirection =
|
||||||
|
@ -5359,7 +5360,6 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
|
||||||
done = current->PeekOffsetCharacter(movingInFrameDirection, &offset);
|
done = current->PeekOffsetCharacter(movingInFrameDirection, &offset);
|
||||||
|
|
||||||
if (!done) {
|
if (!done) {
|
||||||
PRBool jumpedLine;
|
|
||||||
result =
|
result =
|
||||||
current->GetFrameFromDirection(aPos->mDirection, aPos->mVisual,
|
current->GetFrameFromDirection(aPos->mDirection, aPos->mVisual,
|
||||||
aPos->mJumpLines, aPos->mScrollViewStop,
|
aPos->mJumpLines, aPos->mScrollViewStop,
|
||||||
|
@ -5380,6 +5380,15 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
|
||||||
aPos->mResultContent = range.content;
|
aPos->mResultContent = range.content;
|
||||||
// Output offset is relative to content, not frame
|
// Output offset is relative to content, not frame
|
||||||
aPos->mContentOffset = offset < 0 ? range.end : range.start + offset;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5425,8 +5425,7 @@ IsAcceptableCaretPosition(const gfxSkipCharsIterator& aIter, gfxTextRun* aTextRu
|
||||||
PRUint32 index = aIter.GetSkippedOffset();
|
PRUint32 index = aIter.GetSkippedOffset();
|
||||||
if (!aTextRun->IsClusterStart(index))
|
if (!aTextRun->IsClusterStart(index))
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
return !(aFrame->GetStyleText()->NewlineIsSignificant() &&
|
return PR_TRUE;
|
||||||
aTextRun->GetChar(index) == '\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -5451,8 +5450,8 @@ nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
|
||||||
PRInt32 startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset);
|
PRInt32 startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset);
|
||||||
|
|
||||||
if (!aForward) {
|
if (!aForward) {
|
||||||
PRInt32 i;
|
// If at the beginning of the line, look at the previous continuation
|
||||||
for (i = NS_MIN(trimmed.GetEnd(), startOffset) - 1;
|
for (PRInt32 i = NS_MIN(trimmed.GetEnd(), startOffset) - 1;
|
||||||
i >= trimmed.mStart; --i) {
|
i >= trimmed.mStart; --i) {
|
||||||
iter.SetOriginalOffset(i);
|
iter.SetOriginalOffset(i);
|
||||||
if (IsAcceptableCaretPosition(iter, mTextRun, this)) {
|
if (IsAcceptableCaretPosition(iter, mTextRun, this)) {
|
||||||
|
@ -5462,16 +5461,19 @@ nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
|
||||||
}
|
}
|
||||||
*aOffset = 0;
|
*aOffset = 0;
|
||||||
} else {
|
} else {
|
||||||
PRInt32 i;
|
// If we're at the end of a line, look at the next continuation
|
||||||
for (i = startOffset + 1; i <= trimmed.GetEnd(); ++i) {
|
iter.SetOriginalOffset(startOffset);
|
||||||
iter.SetOriginalOffset(i);
|
if (iter.GetSkippedOffset() <= PRUint32(trimmed.GetEnd()) &&
|
||||||
// XXX we can't necessarily stop at the end of this frame,
|
!(iter.GetSkippedOffset() < PRUint32(trimmed.GetEnd()) &&
|
||||||
// but we really have no choice right now. We need to do a deeper
|
GetStyleText()->NewlineIsSignificant() &&
|
||||||
// fix/restructuring of PeekOffsetCharacter
|
mTextRun->GetChar(iter.GetSkippedOffset()) == '\n')) {
|
||||||
if (i == trimmed.GetEnd() ||
|
for (PRInt32 i = startOffset + 1; i <= trimmed.GetEnd(); ++i) {
|
||||||
IsAcceptableCaretPosition(iter, mTextRun, this)) {
|
iter.SetOriginalOffset(i);
|
||||||
*aOffset = i - mContentOffset;
|
if (i == trimmed.GetEnd() ||
|
||||||
return PR_TRUE;
|
IsAcceptableCaretPosition(iter, mTextRun, this)) {
|
||||||
|
*aOffset = i - mContentOffset;
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*aOffset = contentLength;
|
*aOffset = contentLength;
|
||||||
|
|
|
@ -18,6 +18,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=288789
|
||||||
|
|
||||||
אaב
|
אaב
|
||||||
|
|
||||||
|
</textarea>
|
||||||
|
<textarea id="tb">
|
||||||
|
|
||||||
|
abc
|
||||||
|
|
||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
</div>
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
|
@ -50,9 +55,59 @@ function test() {
|
||||||
|
|
||||||
textarea.focus();
|
textarea.focus();
|
||||||
collapse(0);
|
collapse(0);
|
||||||
testLeft(1);
|
ok(true, "Testing forward movement in RTL mode");
|
||||||
collapse(5);
|
for (var i = 0; i < textarea.textContent.length; ++i) {
|
||||||
testRight(4);
|
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();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,13 +68,13 @@ function test() {
|
||||||
editor.innerHTML = "<pre>aa\nbb</pre>";
|
editor.innerHTML = "<pre>aa\nbb</pre>";
|
||||||
sel.collapse(editor.firstChild.firstChild, 0);
|
sel.collapse(editor.firstChild.firstChild, 0);
|
||||||
testRight(editor.firstChild.firstChild, 1);
|
testRight(editor.firstChild.firstChild, 1);
|
||||||
// at the 'bb' but HINTLEFT so appears at the end of the first line
|
// at the end of the first line, before the \n
|
||||||
testRight(editor.firstChild.firstChild, 3);
|
testRight(editor.firstChild.firstChild, 2);
|
||||||
testRight(editor.firstChild.firstChild, 3);
|
testRight(editor.firstChild.firstChild, 3);
|
||||||
testRight(editor.firstChild.firstChild, 4);
|
testRight(editor.firstChild.firstChild, 4);
|
||||||
testLeft(editor.firstChild.firstChild, 3);
|
testLeft(editor.firstChild.firstChild, 3);
|
||||||
// at the 'bb' but HINTLEFT so appears at the end of the first line
|
// at the end of the first line, before the \n
|
||||||
testLeft(editor.firstChild.firstChild, 3);
|
testLeft(editor.firstChild.firstChild, 2);
|
||||||
testLeft(editor.firstChild.firstChild, 1);
|
testLeft(editor.firstChild.firstChild, 1);
|
||||||
testLeft(editor.firstChild.firstChild, 0);
|
testLeft(editor.firstChild.firstChild, 0);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче