TextIterator emits LF for a br element inside an empty input element
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Mar 2013 22:22:23 +0000 (22:22 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Mar 2013 22:22:23 +0000 (22:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=112275

Patch by Aurimas Liutikas <aurimas@chromium.org> on 2013-03-15
Reviewed by Ryosuke Niwa.

Source/WebCore:

Adding a check to avoid emiting LF for br elements inside a shadow tree
of an input element.

Test: editing/text-iterator/basic-iteration.html
      editing/text-iterator/basic-iteration-shadowdom.html

* editing/TextIterator.cpp:
(WebCore::shouldEmitNewlineForNode):
(WebCore::TextIterator::handleNonTextNode):
(WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator):
(WebCore::SimplifiedBackwardsTextIterator::handleNonTextNode):
(WebCore::SimplifiedBackwardsTextIterator::exitNode):
* editing/TextIterator.h:
(SimplifiedBackwardsTextIterator):

LayoutTests:

* editing/text-iterator/basic-iteration-expected.txt: Extended to add two more cases.
* editing/text-iterator/basic-iteration-shadowdom-expected.txt: Added.
* editing/text-iterator/basic-iteration-shadowdom.html: Added.
* editing/text-iterator/script-tests/basic-iteration.js: Extended to add two mroe cases.
* platform/mac/TestExpectations:

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

LayoutTests/ChangeLog
LayoutTests/editing/text-iterator/basic-iteration-expected.txt
LayoutTests/editing/text-iterator/basic-iteration-shadowdom-expected.txt [new file with mode: 0644]
LayoutTests/editing/text-iterator/basic-iteration-shadowdom.html [new file with mode: 0644]
LayoutTests/editing/text-iterator/script-tests/basic-iteration.js
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/editing/TextIterator.cpp
Source/WebCore/editing/TextIterator.h

index e575b94..0832ef7 100644 (file)
@@ -1,3 +1,16 @@
+2013-03-15  Aurimas Liutikas  <aurimas@chromium.org>
+
+        TextIterator emits LF for a br element inside an empty input element
+        https://bugs.webkit.org/show_bug.cgi?id=112275
+
+        Reviewed by Ryosuke Niwa.
+
+        * editing/text-iterator/basic-iteration-expected.txt: Extended to add two more cases.
+        * editing/text-iterator/basic-iteration-shadowdom-expected.txt: Added.
+        * editing/text-iterator/basic-iteration-shadowdom.html: Added.
+        * editing/text-iterator/script-tests/basic-iteration.js: Extended to add two mroe cases.
+        * platform/mac/TestExpectations:
+
 2013-03-15  Zan Dobersek  <zdobersek@igalia.com>
 
         Unreviewed GTK gardening.
index 69312d9..e2e40f3 100644 (file)
@@ -14,6 +14,8 @@ FAIL range.selectNodeContents(testDocument.body); internals.rangeAsText(range) s
 .
 PASS range.selectNodeContents(testDocument.body); internals.rangeAsText(range) is "hey"
 PASS range.setStartBefore(testDocument.body); range.setEndAfter(testDocument.body); internals.rangeAsText(range) is "hey"
+PASS range.selectNodeContents(internals.oldestShadowRoot(input)); internals.rangeAsText(range) is "b"
+PASS appendBrElement(internals.oldestShadowRoot(input).childNodes[0]); range.selectNodeContents(internals.oldestShadowRoot(input)); internals.rangeAsText(range) is "b"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/editing/text-iterator/basic-iteration-shadowdom-expected.txt b/LayoutTests/editing/text-iterator/basic-iteration-shadowdom-expected.txt
new file mode 100644 (file)
index 0000000..9364a53
--- /dev/null
@@ -0,0 +1,11 @@
+Unit tests for WebCore text iterator with shadow tree support enabled
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS addShadowTreeWithDivElement(div); range.selectNodeContents(internals.oldestShadowRoot(div)); internals.rangeAsText(range) is "b"
+PASS appendBrElement(internals.oldestShadowRoot(div).childNodes[0]); range.selectNodeContents(internals.oldestShadowRoot(div)); internals.rangeAsText(range) is "b\n"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/text-iterator/basic-iteration-shadowdom.html b/LayoutTests/editing/text-iterator/basic-iteration-shadowdom.html
new file mode 100644 (file)
index 0000000..a19be9d
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/js-test-selection-shared.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description('Unit tests for WebCore text iterator with shadow tree support enabled');
+
+var subframe = document.createElement('iframe');
+document.body.appendChild(subframe);
+
+function appendBrElement(node)
+{
+    node.appendChild(document.createElement('br'));
+}
+
+function addShadowTreeWithDivElement(node)
+{
+    node.webkitCreateShadowRoot();
+    internals.oldestShadowRoot(node).innerHTML = '<div>b</div>';
+}
+
+var testDocument = subframe.contentDocument;
+var range = testDocument.createRange();
+
+var head = testDocument.createElement("head");
+testDocument.documentElement.insertBefore(head, testDocument.documentElement.firstChild);
+
+testDocument.body.innerHTML = '<div>a</div>';
+var div = testDocument.body.childNodes[0];
+shouldBe('addShadowTreeWithDivElement(div); range.selectNodeContents(internals.oldestShadowRoot(div)); internals.rangeAsText(range)', '"b"');
+
+shouldBe('appendBrElement(internals.oldestShadowRoot(div).childNodes[0]); range.selectNodeContents(internals.oldestShadowRoot(div)); internals.rangeAsText(range)', '"b\\n"');
+
+document.body.removeChild(subframe);
+
+var successfullyParsed = true;
+</script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 4f5e5ff..dc9646b 100644 (file)
@@ -1,5 +1,16 @@
 description('Unit tests for WebCore text iterator');
 
+function appendBrElement(node)
+{
+    node.appendChild(document.createElement('br'));
+}
+
+function addShadowTreeWithDivElement(node)
+{
+    node.webkitCreateShadowRoot();
+    internals.oldestShadowRoot(node).innerHTML = '<div>b</div>';
+}
+
 var subframe = document.createElement('iframe');
 document.body.appendChild(subframe);
 
@@ -31,6 +42,12 @@ testDocument.body.innerHTML = '<div class="note-rule-vertical" style="left:22px"
 shouldBe('range.selectNodeContents(testDocument.body); internals.rangeAsText(range)', '"hey"');
 shouldBe('range.setStartBefore(testDocument.body); range.setEndAfter(testDocument.body); internals.rangeAsText(range)', '"hey"');
 
+testDocument.body.innerHTML = '<input id="a" value="b" />';
+var input = testDocument.querySelector('input');
+shouldBe('range.selectNodeContents(internals.oldestShadowRoot(input)); internals.rangeAsText(range)', '"b"');
+
+shouldBe('appendBrElement(internals.oldestShadowRoot(input).childNodes[0]); range.selectNodeContents(internals.oldestShadowRoot(input)); internals.rangeAsText(range)', '"b"');
+
 document.body.removeChild(subframe);
 
 var successfullyParsed = true;
index d01f00b..40a351b 100644 (file)
@@ -450,6 +450,7 @@ fast/dom/shadow
 editing/shadow
 inspector/elements/update-shadowdom.html
 accessibility/corresponding-control-deleted-crash.html
+editing/text-iterator/basic-iteration-shadowdom.html
 
 # ENABLE(TEMPLATE_ELEMENT) is disabled.
 fast/dom/HTMLTemplateElement
index 5ae1125..3dd46db 100644 (file)
@@ -1,3 +1,25 @@
+2013-03-15  Aurimas Liutikas  <aurimas@chromium.org>
+
+        TextIterator emits LF for a br element inside an empty input element
+        https://bugs.webkit.org/show_bug.cgi?id=112275
+
+        Reviewed by Ryosuke Niwa.
+
+        Adding a check to avoid emiting LF for br elements inside a shadow tree
+        of an input element.
+
+        Test: editing/text-iterator/basic-iteration.html
+              editing/text-iterator/basic-iteration-shadowdom.html
+
+        * editing/TextIterator.cpp:
+        (WebCore::shouldEmitNewlineForNode):
+        (WebCore::TextIterator::handleNonTextNode):
+        (WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator):
+        (WebCore::SimplifiedBackwardsTextIterator::handleNonTextNode):
+        (WebCore::SimplifiedBackwardsTextIterator::exitNode):
+        * editing/TextIterator.h:
+        (SimplifiedBackwardsTextIterator):
+
 2013-03-15  Arvid Nilsson  <anilsson@rim.com>
 
         [BlackBerry] Allow an embedder to position child windows using window coordinates
index 0094910..a8508c2 100644 (file)
@@ -747,14 +747,13 @@ static bool shouldEmitTabBeforeNode(Node* node)
     return t && (t->cellBefore(rc) || t->cellAbove(rc));
 }
 
-static bool shouldEmitNewlineForNode(Node* node)
+static bool shouldEmitNewlineForNode(Node* node, bool emitsOriginalText)
 {
-    // br elements are represented by a single newline.
-    RenderObject* r = node->renderer();
-    if (!r)
-        return node->hasTagName(brTag);
-        
-    return r->isBR();
+    RenderObject* renderer = node->renderer();
+
+    if (renderer ? !renderer->isBR() : !node->hasTagName(brTag))
+        return false;
+    return emitsOriginalText || !(node->isInShadowTree() && node->shadowHost()->toInputElement());
 }
 
 static bool shouldEmitNewlinesBeforeAndAfterNode(Node* node)
@@ -956,7 +955,7 @@ void TextIterator::representNodeOffsetZero()
 
 bool TextIterator::handleNonTextNode()
 {
-    if (shouldEmitNewlineForNode(m_node))
+    if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText))
         emitCharacter('\n', m_node->parentNode(), m_node, 0, 1);
     else if (m_emitsCharactersBetweenAllVisiblePositions && m_node->renderer() && m_node->renderer()->isHR())
         emitCharacter(' ', m_node->parentNode(), m_node, 0, 1);
@@ -1110,6 +1109,7 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator()
     , m_shouldHandleFirstLetter(false)
     , m_stopsOnFormControls(false)
     , m_shouldStop(false)
+    , m_emitsOriginalText(false)
 {
 }
 
@@ -1134,6 +1134,7 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
     , m_shouldHandleFirstLetter(false)
     , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls)
     , m_shouldStop(false)
+    , m_emitsOriginalText(false)
 {
     ASSERT(behavior == TextIteratorDefaultBehavior || behavior == TextIteratorStopsOnFormControls);
 
@@ -1342,7 +1343,7 @@ bool SimplifiedBackwardsTextIterator::handleNonTextNode()
 {    
     // We can use a linefeed in place of a tab because this simple iterator is only used to
     // find boundaries, not actual content.  A linefeed breaks words, sentences, and paragraphs.
-    if (shouldEmitNewlineForNode(m_node) || shouldEmitNewlineAfterNode(m_node) || shouldEmitTabBeforeNode(m_node)) {
+    if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewlineAfterNode(m_node) || shouldEmitTabBeforeNode(m_node)) {
         unsigned index = m_node->nodeIndex();
         // The start of this emitted range is wrong. Ensuring correctness would require
         // VisiblePositions and so would be slow. previousBoundary expects this.
@@ -1353,7 +1354,7 @@ bool SimplifiedBackwardsTextIterator::handleNonTextNode()
 
 void SimplifiedBackwardsTextIterator::exitNode()
 {
-    if (shouldEmitNewlineForNode(m_node) || shouldEmitNewlineBeforeNode(m_node) || shouldEmitTabBeforeNode(m_node)) {
+    if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewlineBeforeNode(m_node) || shouldEmitTabBeforeNode(m_node)) {
         // The start of this emitted range is wrong. Ensuring correctness would require
         // VisiblePositions and so would be slow. previousBoundary expects this.
         emitCharacter('\n', m_node, 0, 0);
index 48afc7b..68d8010 100644 (file)
@@ -260,6 +260,9 @@ private:
 
     // Used when m_stopsOnFormControls is set to determine if the iterator should keep advancing.
     bool m_shouldStop;
+
+    // Used in pasting inside password field.
+    bool m_emitsOriginalText;
 };
 
 // Builds on the text iterator, adding a character position so we can walk one