Bug 645914 - Do not eat the white-space when doing word selection if the eaten whitespace is a newline character and we have been instructed not to jump between lines; r=roc

This fixes a bug in selecting words at the end of lines in textarea's for Windows.
This commit is contained in:
Ehsan Akhgari 2011-03-30 11:56:48 -04:00
parent 6c4d70e8f0
commit 5199d98d91
3 changed files with 76 additions and 1 deletions

View File

@ -61,6 +61,7 @@ _TEST_FILES = \
test_bug629172.html \
test_bug638596.html \
test_bug641466.html \
test_bug645914.html \
$(NULL)
# disables the key handling test on gtk2 because gtk2 overrides some key events

View File

@ -0,0 +1,66 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=645914
-->
<head>
<title>Test for Bug 645914</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=645914">Mozilla Bug 645914</a>
<p id="display"></p>
<div id="content">
<textarea>foo
bar</textarea>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 645914 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
var textarea = document.querySelector("textarea");
SpecialPowers.setBoolPref("layout.word_select.eat_space_to_next_word", true);
SpecialPowers.setBoolPref("browser.triple_click_selects_paragraph", false);
textarea.selectionStart = textarea.selectionEnd = 0;
// Simulate a double click on foo
synthesizeMouse(textarea, 5, 5, {clickCount: 2});
ok(true, "Testing word selection");
is(textarea.selectionStart, 0, "The start of the selection should be at the beginning of the text");
is(textarea.selectionEnd, 3, "The end of the selection should not include a newline character");
textarea.selectionStart = textarea.selectionEnd = 0;
// Simulate a triple click on foo
synthesizeMouse(textarea, 5, 5, {clickCount: 3});
ok(true, "Testing line selection");
is(textarea.selectionStart, 0, "The start of the selection should be at the beginning of the text");
is(textarea.selectionEnd, 3, "The end of the selection should not include a newline character");
textarea.selectionStart = textarea.selectionEnd = 0;
textarea.value = "Very very long value which would eventually overflow the visible section of the textarea";
// Simulate a quadruple click on Very
synthesizeMouse(textarea, 5, 5, {clickCount: 4});
ok(true, "Testing paragraph selection");
is(textarea.selectionStart, 0, "The start of the selection should be at the beginning of the text");
is(textarea.selectionEnd, textarea.value.length, "The end of the selection should be the end of the paragraph");
SpecialPowers.clearUserPref("layout.word_select.eat_space_to_next_word");
SpecialPowers.clearUserPref("browser.triple_click_selects_paragraph");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -5543,6 +5543,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
// between non-whitespace and whitespace), then eatingWS==PR_TRUE means
// "we already saw some non-whitespace".
PeekWordState state;
PRInt32 offsetAdjustment = 0;
PRBool done = PR_FALSE;
while (!done) {
PRBool movingInFrameDirection =
@ -5564,6 +5565,13 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
if (NS_FAILED(result) ||
(jumpedLine && !wordSelectEatSpace && state.mSawBeforeType)) {
done = PR_TRUE;
// If we've crossed the line boundary, check to make sure that we
// have not consumed a trailing newline as whitesapce if it's significant.
if (jumpedLine && wordSelectEatSpace &&
current->HasTerminalNewline() &&
current->GetStyleText()->NewlineIsSignificant()) {
offsetAdjustment = -1;
}
} else {
if (jumpedLine) {
state.mContext.Truncate();
@ -5582,7 +5590,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
aPos->mResultFrame = current;
aPos->mResultContent = range.content;
// 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) + offsetAdjustment;
break;
}
case eSelectLine :