<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[245912] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/245912">245912</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2019-05-30 17:02:59 -0700 (Thu, 30 May 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Inserting a newline in contenteditable causes two characters to be added instead of one
https://bugs.webkit.org/show_bug.cgi?id=197894
<rdar://problem/49700998>

Patch by Andres Gonzalez <andresg_22@apple.com> on 2019-05-30
Reviewed by Wenson Hsieh and Chris Fleizach.

Source/WebCore:

There were two issues with inserting a newline character at the end of
a line that caused problems for accessibility:
- the first '\n' inserted after text would result in two line breaks
inserted instead of one. createFragmentFromText in markup.cpp was
splitting the string "\n" into two empty strings and creating a <div>
and a <br> respectively. Then the emission code would emit a '\n' for
the empty div and another for the <br>.
- the second problem is a consequence of <rdar://problem/5192593> and
the workaround is the change in editing.cpp in the function
visiblePositionForIndexUsingCharacterIterator, similar to what is done
in VisibleUnits.cpp for nextBoundary.
The rest of the changes in this patch are accessibility changes to
execute the layout tests.

Tests: accessibility/ios-simulator/set-selected-text-range-after-newline.html
       accessibility/set-selected-text-range-after-newline.html

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::setSelectedTextRange):
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper stringForRange:]):
(-[WebAccessibilityObjectWrapper _accessibilitySelectedTextRange]):
(-[WebAccessibilityObjectWrapper accessibilityReplaceRange:withText:]):
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
* editing/Editing.cpp:
(WebCore::visiblePositionForIndexUsingCharacterIterator):
* editing/markup.cpp:
(WebCore::createFragmentFromText):

Tools:

iOS implementation of several AccessibilityUIElement methods to execute
LayoutTests.

* WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm:
(WTR::AccessibilityUIElement::selectedTextRange):
(WTR::AccessibilityUIElement::setSelectedTextRange):
(WTR::AccessibilityUIElement::replaceTextInRange):

LayoutTests:

* accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt: Added.
* accessibility/ios-simulator/set-selected-text-range-after-newline.html: Added.
* accessibility/ios-simulator/text-marker-list-item-expected.txt:
* accessibility/set-selected-text-range-after-newline-expected.txt: Added.
* accessibility/set-selected-text-range-after-newline.html: Added.
* platform/win/TestExpectations:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsaccessibilityiossimulatortextmarkerlistitemexpectedtxt">trunk/LayoutTests/accessibility/ios-simulator/text-marker-list-item-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformwinTestExpectations">trunk/LayoutTests/platform/win/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityRenderObjectcpp">trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityiosWebAccessibilityObjectWrapperIOSmm">trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreaccessibilitymacWebAccessibilityObjectWrapperMacmm">trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm</a></li>
<li><a href="#trunkSourceWebCoreeditingEditingcpp">trunk/Source/WebCore/editing/Editing.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditingmarkupcpp">trunk/Source/WebCore/editing/markup.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleiosAccessibilityUIElementIOSmm">trunk/Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsaccessibilityiossimulatorsetselectedtextrangeafternewlineexpectedtxt">trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt</a></li>
<li><a href="#trunkLayoutTestsaccessibilityiossimulatorsetselectedtextrangeafternewlinehtml">trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline.html</a></li>
<li><a href="#trunkLayoutTestsaccessibilitysetselectedtextrangeafternewlineexpectedtxt">trunk/LayoutTests/accessibility/set-selected-text-range-after-newline-expected.txt</a></li>
<li><a href="#trunkLayoutTestsaccessibilitysetselectedtextrangeafternewlinehtml">trunk/LayoutTests/accessibility/set-selected-text-range-after-newline.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/LayoutTests/ChangeLog 2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2019-05-30  Andres Gonzalez  <andresg_22@apple.com>
+
+        Inserting a newline in contenteditable causes two characters to be added instead of one
+        https://bugs.webkit.org/show_bug.cgi?id=197894
+        <rdar://problem/49700998>
+
+        Reviewed by Wenson Hsieh and Chris Fleizach.
+
+        * accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt: Added.
+        * accessibility/ios-simulator/set-selected-text-range-after-newline.html: Added.
+        * accessibility/ios-simulator/text-marker-list-item-expected.txt:
+        * accessibility/set-selected-text-range-after-newline-expected.txt: Added.
+        * accessibility/set-selected-text-range-after-newline.html: Added.
+        * platform/win/TestExpectations:
+
</ins><span class="cx"> 2019-05-30  Devin Rousso  <drousso@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Audit: tests are unable to get the current Audit version
</span></span></pre></div>
<a id="trunkLayoutTestsaccessibilityiossimulatorsetselectedtextrangeafternewlineexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt (0 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt                         (rev 0)
+++ trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt    2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+hello
+world
+PASS text.selectedTextRange became '{5, 0}'
+There must be only one [newline] between hello and world: hello[newline]world
+PASS text.selectedTextRange became '{6, 0}'
+The text after the newline should be world: world
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsaccessibilityiossimulatorsetselectedtextrangeafternewlinehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline.html (0 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline.html                         (rev 0)
+++ trunk/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline.html    2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+
+<div id="content" contenteditable tabindex="0">helloworld</div>
+
+<div id="console"></div>
+
+<script>
+    if (window.accessibilityController) {
+        window.jsTestIsAsync = true;
+
+        var content = document.getElementById("content");
+        content.focus();
+
+        var text = accessibilityController.focusedElement;
+        text.setSelectedTextRange(5, 0);
+        shouldBecomeEqual("text.selectedTextRange", "'{5, 0}'", function() {
+            text.replaceTextInRange("\n", 5, 0);
+
+            var t = text.stringForRange(0, 11);
+            t = t.replace(/(?:\r\n|\r|\n)/g, '[newline]');
+            debug("There must be only one [newline] between hello and world: " + t);
+
+            text.setSelectedTextRange(6, 0);
+            shouldBecomeEqual("text.selectedTextRange", "'{6, 0}'", function() {
+                var t = text.stringForRange(6, 5);
+                t = t.replace(/(?:\r\n|\r|\n)/g, '[newline]');
+                debug("The text after the newline should be world: " + t);
+
+                finishJSTest();
+            });
+        });
+    }
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsaccessibilityiossimulatortextmarkerlistitemexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/accessibility/ios-simulator/text-marker-list-item-expected.txt (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/ios-simulator/text-marker-list-item-expected.txt 2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/LayoutTests/accessibility/ios-simulator/text-marker-list-item-expected.txt    2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -4,7 +4,7 @@
</span><span class="cx"> On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-FAIL text should be 1. item 1. Was 1. .
</del><ins>+PASS text is '1. item 1'
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsaccessibilitysetselectedtextrangeafternewlineexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/accessibility/set-selected-text-range-after-newline-expected.txt (0 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/set-selected-text-range-after-newline-expected.txt                               (rev 0)
+++ trunk/LayoutTests/accessibility/set-selected-text-range-after-newline-expected.txt  2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+hello
+world
+PASS text.selectedTextRange became '{5, 0}'
+There must be only one [newline] between hello and world: hello[newline]world
+PASS text.selectedTextRange became '{6, 0}'
+The text after the newline should be world: world
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsaccessibilitysetselectedtextrangeafternewlinehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/accessibility/set-selected-text-range-after-newline.html (0 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/set-selected-text-range-after-newline.html                               (rev 0)
+++ trunk/LayoutTests/accessibility/set-selected-text-range-after-newline.html  2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+
+<div id="content" contenteditable tabindex="0">helloworld</div>
+
+<div id="console"></div>
+
+<script>
+    if (window.accessibilityController) {
+        window.jsTestIsAsync = true;
+
+        var content = document.getElementById("content");
+        content.focus();
+
+        var text = accessibilityController.focusedElement;
+        text.setSelectedTextRange(5, 0);
+        shouldBecomeEqual("text.selectedTextRange", "'{5, 0}'", function() {
+            text.replaceTextInRange("\n", 5, 0);
+
+            var t = text.stringForRange(0, 11);
+            t = t.replace(/(?:\r\n|\r|\n)/g, '[newline]');
+            debug("There must be only one [newline] between hello and world: " + t);
+
+            text.setSelectedTextRange(6, 0);
+            shouldBecomeEqual("text.selectedTextRange", "'{6, 0}'", function() {
+                var t = text.stringForRange(6, 5);
+                t = t.replace(/(?:\r\n|\r|\n)/g, '[newline]');
+                debug("The text after the newline should be world: " + t);
+
+                finishJSTest();
+            });
+        });
+    }
+</script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformwinTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/win/TestExpectations (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/win/TestExpectations  2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/LayoutTests/platform/win/TestExpectations     2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -3394,6 +3394,7 @@
</span><span class="cx"> js/dom/create-lots-of-workers.html [ Crash ]
</span><span class="cx"> # Timeouts tracked in webkit.org/b/160447.
</span><span class="cx"> accessibility/set-selected-text-range-contenteditable.html [ Skip ]
</span><ins>+accessibility/set-selected-text-range-after-newline.html [ Skip ]
</ins><span class="cx"> crypto/crypto-key-algorithm-gc.html [ Skip ]
</span><span class="cx"> crypto/crypto-key-usages-gc.html [ Skip ]
</span><span class="cx"> editing/deleting/delete-emoji.html [ Skip ]
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Source/WebCore/ChangeLog      2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -1,3 +1,41 @@
</span><ins>+2019-05-30  Andres Gonzalez  <andresg_22@apple.com>
+
+        Inserting a newline in contenteditable causes two characters to be added instead of one
+        https://bugs.webkit.org/show_bug.cgi?id=197894
+        <rdar://problem/49700998>
+
+        Reviewed by Wenson Hsieh and Chris Fleizach.
+
+        There were two issues with inserting a newline character at the end of 
+        a line that caused problems for accessibility:
+        - the first '\n' inserted after text would result in two line breaks 
+        inserted instead of one. createFragmentFromText in markup.cpp was 
+        splitting the string "\n" into two empty strings and creating a <div> 
+        and a <br> respectively. Then the emission code would emit a '\n' for 
+        the empty div and another for the <br>.
+        - the second problem is a consequence of <rdar://problem/5192593> and 
+        the workaround is the change in editing.cpp in the function
+        visiblePositionForIndexUsingCharacterIterator, similar to what is done
+        in VisibleUnits.cpp for nextBoundary.
+        The rest of the changes in this patch are accessibility changes to 
+        execute the layout tests.
+
+        Tests: accessibility/ios-simulator/set-selected-text-range-after-newline.html
+               accessibility/set-selected-text-range-after-newline.html
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::setSelectedTextRange):
+        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+        (-[WebAccessibilityObjectWrapper stringForRange:]):
+        (-[WebAccessibilityObjectWrapper _accessibilitySelectedTextRange]):
+        (-[WebAccessibilityObjectWrapper accessibilityReplaceRange:withText:]):
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+        * editing/Editing.cpp:
+        (WebCore::visiblePositionForIndexUsingCharacterIterator):
+        * editing/markup.cpp:
+        (WebCore::createFragmentFromText):
+
</ins><span class="cx"> 2019-05-30  Justin Fan  <justin_fan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Web GPU] Vertex Buffers/Input State API updates
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAccessibilityRenderObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp    2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -1621,9 +1621,10 @@
</span><span class="cx">         HTMLTextFormControlElement& textControl = downcast<RenderTextControl>(*m_renderer).textFormControlElement();
</span><span class="cx">         textControl.setSelectionRange(range.start, range.start + range.length);
</span><span class="cx">     } else {
</span><del>-        ASSERT(node());
-        VisiblePosition start = visiblePositionForIndexUsingCharacterIterator(*node(), range.start);
-        VisiblePosition end = visiblePositionForIndexUsingCharacterIterator(*node(), range.start + range.length);
</del><ins>+        auto node = this->node();
+        ASSERT(node);
+        VisiblePosition start = visiblePositionForIndexUsingCharacterIterator(*node, range.start);
+        VisiblePosition end = visiblePositionForIndexUsingCharacterIterator(*node, range.start + range.length);
</ins><span class="cx">         m_renderer->frame().selection().setSelection(VisibleSelection(start, end), FrameSelection::defaultSetSelectionOptions(UserTriggered));
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityiosWebAccessibilityObjectWrapperIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm       2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm  2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -2497,11 +2497,13 @@
</span><span class="cx">     return [self _stringFromStartMarker:startMarker toEndMarker:endMarker attributed:attributed];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-
-// A convenience method for getting the text of a NSRange. Currently used only by DRT.
</del><ins>+// A convenience method for getting the text of a NSRange.
</ins><span class="cx"> - (NSString *)stringForRange:(NSRange)range
</span><span class="cx"> {
</span><del>-    return [self _stringForRange:range attributed:NO];
</del><ins>+    if (![self _prepareAccessibilityCall])
+        return nil;
+
+    return m_object->stringForRange([self _convertToDOMRange:range]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (NSAttributedString *)attributedStringForRange:(NSRange)range
</span><span class="lines">@@ -2525,11 +2527,11 @@
</span><span class="cx"> {
</span><span class="cx">     if (![self _prepareAccessibilityCall] || !m_object->isTextControl())
</span><span class="cx">         return NSMakeRange(NSNotFound, 0);
</span><del>-    
</del><ins>+
</ins><span class="cx">     PlainTextRange textRange = m_object->selectedTextRange();
</span><span class="cx">     if (textRange.isNull())
</span><span class="cx">         return NSMakeRange(NSNotFound, 0);
</span><del>-    return NSMakeRange(textRange.start, textRange.length);    
</del><ins>+    return NSMakeRange(textRange.start, textRange.length);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_accessibilitySetSelectedTextRange:(NSRange)range
</span><span class="lines">@@ -2540,6 +2542,14 @@
</span><span class="cx">     m_object->setSelectedTextRange(PlainTextRange(range.location, range.length));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (BOOL)accessibilityReplaceRange:(NSRange)range withText:(NSString *)string
+{
+    if (![self _prepareAccessibilityCall])
+        return NO;
+
+    return m_object->replaceTextInRange(string, PlainTextRange(range));
+}
+
</ins><span class="cx"> // A convenience method for getting the accessibility objects of a NSRange. Currently used only by DRT.
</span><span class="cx"> - (NSArray *)elementsForRange:(NSRange)range
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilitymacWebAccessibilityObjectWrapperMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm       2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm  2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -2742,8 +2742,6 @@
</span><span class="cx">         }
</span><span class="cx">         if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
</span><span class="cx">             PlainTextRange textRange = m_object->selectedTextRange();
</span><del>-            if (textRange.isNull())
-                return [NSValue valueWithRange:NSMakeRange(0, 0)];
</del><span class="cx">             return [NSValue valueWithRange:NSMakeRange(textRange.start, textRange.length)];
</span><span class="cx">         }
</span><span class="cx">         // TODO: Get actual visible range. <rdar://problem/4712101>
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editing.cpp (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editing.cpp 2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Source/WebCore/editing/Editing.cpp    2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -1121,6 +1121,16 @@
</span><span class="cx">     range->selectNodeContents(node);
</span><span class="cx">     CharacterIterator it(range.get());
</span><span class="cx">     it.advance(index - 1);
</span><ins>+
+    if (!it.atEnd() && it.text()[0] == '\n') {
+        // FIXME: workaround for collapsed range (where only start position is correct) emitted for some emitted newlines (see rdar://5192593)
+        auto range = it.range();
+        if (range->startPosition() == range->endPosition()) {
+            it.advance(1);
+            return VisiblePosition(it.range()->startPosition());
+        }
+    }
+
</ins><span class="cx">     return { it.atEnd() ? range->endPosition() : it.range()->endPosition(), UPSTREAM };
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingmarkupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/markup.cpp (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/markup.cpp  2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Source/WebCore/editing/markup.cpp     2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -1115,12 +1115,16 @@
</span><span class="cx">     string.replace("\r\n", "\n");
</span><span class="cx">     string.replace('\r', '\n');
</span><span class="cx"> 
</span><ins>+    auto createHTMLBRElement = [&document]() {
+        auto element = HTMLBRElement::create(document);
+        element->setAttributeWithoutSynchronization(classAttr, AppleInterchangeNewline);
+        return element;
+    };
+
</ins><span class="cx">     if (contextPreservesNewline(context)) {
</span><span class="cx">         fragment->appendChild(document.createTextNode(string));
</span><span class="cx">         if (string.endsWith('\n')) {
</span><del>-            auto element = HTMLBRElement::create(document);
-            element->setAttributeWithoutSynchronization(classAttr, AppleInterchangeNewline);
-            fragment->appendChild(element);
</del><ins>+            fragment->appendChild(createHTMLBRElement());
</ins><span class="cx">         }
</span><span class="cx">         return fragment;
</span><span class="cx">     }
</span><span class="lines">@@ -1131,6 +1135,12 @@
</span><span class="cx">         return fragment;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (string.length() == 1 && string[0] == '\n') {
+        // This is a single newline char, thus just create one HTMLBRElement.
+        fragment->appendChild(createHTMLBRElement());
+        return fragment;
+    }
+
</ins><span class="cx">     // Break string into paragraphs. Extra line breaks turn into empty paragraphs.
</span><span class="cx">     Node* blockNode = enclosingBlock(context.firstNode());
</span><span class="cx">     Element* block = downcast<Element>(blockNode);
</span><span class="lines">@@ -1149,8 +1159,7 @@
</span><span class="cx">         RefPtr<Element> element;
</span><span class="cx">         if (s.isEmpty() && i + 1 == numLines) {
</span><span class="cx">             // For last line, use the "magic BR" rather than a P.
</span><del>-            element = HTMLBRElement::create(document);
-            element->setAttributeWithoutSynchronization(classAttr, AppleInterchangeNewline);
</del><ins>+            element = createHTMLBRElement();
</ins><span class="cx">         } else if (useLineBreak) {
</span><span class="cx">             element = HTMLBRElement::create(document);
</span><span class="cx">             fillContainerFromString(fragment, s);
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Tools/ChangeLog       2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2019-05-30  Andres Gonzalez  <andresg_22@apple.com>
+
+        Inserting a newline in contenteditable causes two characters to be added instead of one
+        https://bugs.webkit.org/show_bug.cgi?id=197894
+        <rdar://problem/49700998>
+
+        Reviewed by Wenson Hsieh and Chris Fleizach.
+
+        iOS implementation of several AccessibilityUIElement methods to execute
+        LayoutTests.

+        * WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm:
+        (WTR::AccessibilityUIElement::selectedTextRange):
+        (WTR::AccessibilityUIElement::setSelectedTextRange):
+        (WTR::AccessibilityUIElement::replaceTextInRange):
+
</ins><span class="cx"> 2019-05-30  Keith Miller  <keith_miller@apple.com>
</span><span class="cx"> 
</span><span class="cx">         IsoHeaps don't notice uncommitted VA becoming the first eligible.
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleiosAccessibilityUIElementIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm (245911 => 245912)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm     2019-05-31 00:00:09 UTC (rev 245911)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm        2019-05-31 00:02:59 UTC (rev 245912)
</span><span class="lines">@@ -55,6 +55,9 @@
</span><span class="cx"> - (NSString *)selectionRangeString;
</span><span class="cx"> - (CGPoint)accessibilityClickPoint;
</span><span class="cx"> - (void)accessibilityModifySelection:(WebCore::TextGranularity)granularity increase:(BOOL)increase;
</span><ins>+- (NSRange)_accessibilitySelectedTextRange;
+- (void)_accessibilitySetSelectedTextRange:(NSRange)range;
+- (BOOL)accessibilityReplaceRange:(NSRange)range withText:(NSString *)string;
</ins><span class="cx"> - (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function withContext:(void*)context;
</span><span class="cx"> - (CGFloat)_accessibilityMinValue;
</span><span class="cx"> - (CGFloat)_accessibilityMaxValue;
</span><span class="lines">@@ -836,7 +839,9 @@
</span><span class="cx"> 
</span><span class="cx"> JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
</span><span class="cx"> {
</span><del>-    return createEmptyJSString();
</del><ins>+    NSRange range = [m_element _accessibilitySelectedTextRange];
+    NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", static_cast<unsigned long>(range.location), static_cast<unsigned long>(range.length)];
+    return [rangeDescription createJSStringRef];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool AccessibilityUIElement::setSelectedVisibleTextRange(AccessibilityTextMarkerRange*)
</span><span class="lines">@@ -846,7 +851,8 @@
</span><span class="cx"> 
</span><span class="cx"> bool AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
</span><span class="cx"> {
</span><del>-    return false;
</del><ins>+    [m_element _accessibilitySetSelectedTextRange:NSMakeRange(location, length)];
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AccessibilityUIElement::increment()
</span><span class="lines">@@ -1145,9 +1151,9 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-bool AccessibilityUIElement::replaceTextInRange(JSStringRef, int, int)
</del><ins>+bool AccessibilityUIElement::replaceTextInRange(JSStringRef string, int location, int length)
</ins><span class="cx"> {
</span><del>-    return false;
</del><ins>+    return [m_element accessibilityReplaceRange:NSMakeRange(location, length) withText:[NSString stringWithJSStringRef:string]];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
</span></span></pre>
</div>
</div>

</body>
</html>