REGRESSION(r180726): Removing an empty line at the end of textarea clears the entire...
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Mar 2015 00:57:10 +0000 (00:57 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Mar 2015 00:57:10 +0000 (00:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142646

Reviewed by Darin Adler.

Source/WebCore:

The bug was caused by TypingCommand::deleteKeyPressed erroneously determining the editable root to be empty because
Position::atStartOfTree returns true when it's anchored at a BR that is immediately below the root editable element.

Fixed the bug by replacing the use of the deprecated atFirstEditingPositionForNode by a code that understands modern
position types such as PositionIsBeforeAnchor in atStartOfTree and atEndOfTree. These two functions will no longer
return true when anchored before or after BR after this patch.

Test: editing/deleting/delete-empty-line-breaks-at-end-of-textarea.html

* dom/Position.cpp:
(WebCore::Position::atStartOfTree):
(WebCore::Position::atEndOfTree):

LayoutTests:

Added a regression test for deleting empty lines at the end of a textarea element.

* editing/deleting/delete-empty-line-breaks-at-end-of-textarea-expected.txt: Added.
* editing/deleting/delete-empty-line-breaks-at-end-of-textarea.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@181465 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/editing/deleting/delete-empty-line-breaks-at-end-of-textarea-expected.txt [new file with mode: 0644]
LayoutTests/editing/deleting/delete-empty-line-breaks-at-end-of-textarea.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Position.cpp

index ce23cf2a542a0b596d427dd24fcd4f94b361ead5..790110bd94e412e30aa2e745d0ea8c8dc86b6fd9 100644 (file)
@@ -1,3 +1,15 @@
+2015-03-12  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r180726): Removing an empty line at the end of textarea clears the entire texture
+        https://bugs.webkit.org/show_bug.cgi?id=142646
+
+        Reviewed by Darin Adler.
+
+        Added a regression test for deleting empty lines at the end of a textarea element.
+
+        * editing/deleting/delete-empty-line-breaks-at-end-of-textarea-expected.txt: Added.
+        * editing/deleting/delete-empty-line-breaks-at-end-of-textarea.html: Added.
+
 2015-03-12  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Integrate MapData into JSMap and JSSet
diff --git a/LayoutTests/editing/deleting/delete-empty-line-breaks-at-end-of-textarea-expected.txt b/LayoutTests/editing/deleting/delete-empty-line-breaks-at-end-of-textarea-expected.txt
new file mode 100644 (file)
index 0000000..2389652
--- /dev/null
@@ -0,0 +1,20 @@
+This tests removing empty lines at the end of an textarea.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+textarea.focus();
+textarea.selectionStart = textarea.selectionEnd = textarea.value.length
+PASS textarea.value is "hello\n\n"
+PASS textarea.selectionStart is 7
+PASS textarea.selectionEnd is 7
+PASS document.execCommand("delete", false, null); textarea.value is "hello\n"
+PASS textarea.selectionStart is 6
+PASS textarea.selectionEnd is 6
+PASS document.execCommand("delete", false, null); textarea.value is "hello"
+PASS textarea.selectionStart is 5
+PASS textarea.selectionEnd is 5
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/deleting/delete-empty-line-breaks-at-end-of-textarea.html b/LayoutTests/editing/deleting/delete-empty-line-breaks-at-end-of-textarea.html
new file mode 100644 (file)
index 0000000..7b1b18d
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<body>
+<textarea cols=5 rows=5>
+hello
+
+</textarea>
+<script src="../../resources/js-test-pre.js"></script>
+<script>
+
+description('This tests removing empty lines at the end of an textarea.');
+
+var textarea = document.querySelector('textarea');
+evalAndLog('textarea.focus();');
+evalAndLog('textarea.selectionStart = textarea.selectionEnd = textarea.value.length');
+shouldBe('textarea.value' ,'"hello\\n\\n"');
+shouldBe('textarea.selectionStart' ,'7');
+shouldBe('textarea.selectionEnd' ,'7');
+
+shouldBe('document.execCommand("delete", false, null); textarea.value', '"hello\\n"');
+shouldBe('textarea.selectionStart', '6');
+shouldBe('textarea.selectionEnd', '6');
+
+shouldBe('document.execCommand("delete", false, null); textarea.value', '"hello"');
+shouldBe('textarea.selectionStart', '5');
+shouldBe('textarea.selectionEnd', '5');
+
+textarea.style.display = 'none';
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index ab229c9e91c1c084475455fbd8abac3c3d96ad7e..fd1f99e905a182aea98abcb5364b7f360eb69fb1 100644 (file)
@@ -1,3 +1,23 @@
+2015-03-12  Ryosuke Niwa  <rniwa@webkit.org>
+
+        REGRESSION(r180726): Removing an empty line at the end of textarea clears the entire texture
+        https://bugs.webkit.org/show_bug.cgi?id=142646
+
+        Reviewed by Darin Adler.
+
+        The bug was caused by TypingCommand::deleteKeyPressed erroneously determining the editable root to be empty because
+        Position::atStartOfTree returns true when it's anchored at a BR that is immediately below the root editable element.
+
+        Fixed the bug by replacing the use of the deprecated atFirstEditingPositionForNode by a code that understands modern
+        position types such as PositionIsBeforeAnchor in atStartOfTree and atEndOfTree. These two functions will no longer
+        return true when anchored before or after BR after this patch.
+
+        Test: editing/deleting/delete-empty-line-breaks-at-end-of-textarea.html
+
+        * dom/Position.cpp:
+        (WebCore::Position::atStartOfTree):
+        (WebCore::Position::atEndOfTree):
+
 2015-03-12  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Integrate MapData into JSMap and JSSet
index e044043337c4f60abc3402210acc64d194abc505..ab596badf1a383e8cf71a5fbf327e9914381093e 100644 (file)
@@ -476,14 +476,46 @@ bool Position::atStartOfTree() const
 {
     if (isNull())
         return true;
-    return !findParent(containerNode()) && atFirstEditingPositionForNode();
+    if (findParent(containerNode()))
+        return false;
+
+    switch (m_anchorType) {
+    case PositionIsOffsetInAnchor:
+        return m_offset <= 0;
+    case PositionIsBeforeAnchor:
+        return !m_anchorNode->previousSibling();
+    case PositionIsAfterAnchor:
+        return false;
+    case PositionIsBeforeChildren:
+        return true;
+    case PositionIsAfterChildren:
+        return !lastOffsetForEditing(m_anchorNode.get());
+    }
+    ASSERT_NOT_REACHED();
+    return false;
 }
 
 bool Position::atEndOfTree() const
 {
     if (isNull())
         return true;
-    return !findParent(containerNode()) && atLastEditingPositionForNode();
+    if (findParent(containerNode()))
+        return false;
+
+    switch (m_anchorType) {
+    case PositionIsOffsetInAnchor:
+        return m_offset >= lastOffsetForEditing(m_anchorNode.get());
+    case PositionIsBeforeAnchor:
+        return false;
+    case PositionIsAfterAnchor:
+        return !m_anchorNode->nextSibling();
+    case PositionIsBeforeChildren:
+        return !lastOffsetForEditing(m_anchorNode.get());
+    case PositionIsAfterChildren:
+        return true;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
 }
 
 // return first preceding DOM position rendered at a different location, or "this"