Title: [246972] releases/WebKitGTK/webkit-2.24
Revision
246972
Author
carlo...@webkit.org
Date
2019-07-01 01:53:22 -0700 (Mon, 01 Jul 2019)

Log Message

Merge r245912 - 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...@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:

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog	2019-07-01 08:53:22 UTC (rev 246972)
@@ -1,3 +1,18 @@
+2019-05-30  Andres Gonzalez  <andresg...@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:
+
 2019-05-28  Yacine Bandou  <yacine.ban...@softathome.com>
 
         [MSE][GStreamer] update the readyState correctly in MediaPlayerPrivateGStreamerMSE

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt (0 => 246972)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline-expected.txt	2019-07-01 08:53:22 UTC (rev 246972)
@@ -0,0 +1,10 @@
+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
+

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline.html (0 => 246972)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/set-selected-text-range-after-newline.html	2019-07-01 08:53:22 UTC (rev 246972)
@@ -0,0 +1,40 @@
+<html>
+<head>
+<script src=""
+</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=""
+</body>
+</html>

Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/text-marker-list-item-expected.txt (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/text-marker-list-item-expected.txt	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/ios-simulator/text-marker-list-item-expected.txt	2019-07-01 08:53:22 UTC (rev 246972)
@@ -4,7 +4,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-FAIL text should be 1. item 1. Was 1. .
+PASS text is '1. item 1'
 PASS successfullyParsed is true
 
 TEST COMPLETE

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/set-selected-text-range-after-newline-expected.txt (0 => 246972)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/set-selected-text-range-after-newline-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/set-selected-text-range-after-newline-expected.txt	2019-07-01 08:53:22 UTC (rev 246972)
@@ -0,0 +1,10 @@
+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
+

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/set-selected-text-range-after-newline.html (0 => 246972)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/set-selected-text-range-after-newline.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/accessibility/set-selected-text-range-after-newline.html	2019-07-01 08:53:22 UTC (rev 246972)
@@ -0,0 +1,40 @@
+<html>
+<head>
+<script src=""
+</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=""
+</body>
+</html>

Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/platform/win/TestExpectations (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/platform/win/TestExpectations	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/platform/win/TestExpectations	2019-07-01 08:53:22 UTC (rev 246972)
@@ -3387,6 +3387,7 @@
 js/dom/create-lots-of-workers.html [ Crash ]
 # Timeouts tracked in webkit.org/b/160447.
 accessibility/set-selected-text-range-contenteditable.html [ Skip ]
+accessibility/set-selected-text-range-after-newline.html [ Skip ]
 crypto/crypto-key-algorithm-gc.html [ Skip ]
 crypto/crypto-key-usages-gc.html [ Skip ]
 editing/deleting/delete-emoji.html [ Skip ]

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog	2019-07-01 08:53:22 UTC (rev 246972)
@@ -1,3 +1,41 @@
+2019-05-30  Andres Gonzalez  <andresg...@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):
+
 2019-06-24  Charlie Turner  <ctur...@igalia.com>
 
         [GStreamer][MSE] Pausing video sometimes causes skip to finish

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2019-07-01 08:53:22 UTC (rev 246972)
@@ -1558,9 +1558,10 @@
         HTMLTextFormControlElement& textControl = downcast<RenderTextControl>(*m_renderer).textFormControlElement();
         textControl.setSelectionRange(range.start, range.start + range.length);
     } else {
-        ASSERT(node());
-        VisiblePosition start = visiblePositionForIndexUsingCharacterIterator(*node(), range.start);
-        VisiblePosition end = visiblePositionForIndexUsingCharacterIterator(*node(), range.start + range.length);
+        auto node = this->node();
+        ASSERT(node);
+        VisiblePosition start = visiblePositionForIndexUsingCharacterIterator(*node, range.start);
+        VisiblePosition end = visiblePositionForIndexUsingCharacterIterator(*node, range.start + range.length);
         m_renderer->frame().selection().setSelection(VisibleSelection(start, end), FrameSelection::defaultSetSelectionOptions(UserTriggered));
     }
     

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm	2019-07-01 08:53:22 UTC (rev 246972)
@@ -2517,11 +2517,13 @@
     return [self _stringFromStartMarker:startMarker toEndMarker:endMarker attributed:attributed];
 }
 
-
-// A convenience method for getting the text of a NSRange. Currently used only by DRT.
+// A convenience method for getting the text of a NSRange.
 - (NSString *)stringForRange:(NSRange)range
 {
-    return [self _stringForRange:range attributed:NO];
+    if (![self _prepareAccessibilityCall])
+        return nil;
+
+    return m_object->stringForRange([self _convertToDOMRange:range]);
 }
 
 - (NSAttributedString *)attributedStringForRange:(NSRange)range
@@ -2545,11 +2547,11 @@
 {
     if (![self _prepareAccessibilityCall] || !m_object->isTextControl())
         return NSMakeRange(NSNotFound, 0);
-    
+
     PlainTextRange textRange = m_object->selectedTextRange();
     if (textRange.isNull())
         return NSMakeRange(NSNotFound, 0);
-    return NSMakeRange(textRange.start, textRange.length);    
+    return NSMakeRange(textRange.start, textRange.length);
 }
 
 - (void)_accessibilitySetSelectedTextRange:(NSRange)range
@@ -2560,6 +2562,14 @@
     m_object->setSelectedTextRange(PlainTextRange(range.location, range.length));
 }
 
+- (BOOL)accessibilityReplaceRange:(NSRange)range withText:(NSString *)string
+{
+    if (![self _prepareAccessibilityCall])
+        return NO;
+
+    return m_object->replaceTextInRange(string, PlainTextRange(range));
+}
+
 // A convenience method for getting the accessibility objects of a NSRange. Currently used only by DRT.
 - (NSArray *)elementsForRange:(NSRange)range
 {

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2019-07-01 08:53:22 UTC (rev 246972)
@@ -2531,8 +2531,6 @@
         }
         if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
             PlainTextRange textRange = m_object->selectedTextRange();
-            if (textRange.isNull())
-                return [NSValue valueWithRange:NSMakeRange(0, 0)];
             return [NSValue valueWithRange:NSMakeRange(textRange.start, textRange.length)];
         }
         // TODO: Get actual visible range. <rdar://problem/4712101>

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/editing/Editing.cpp (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/editing/Editing.cpp	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/editing/Editing.cpp	2019-07-01 08:53:22 UTC (rev 246972)
@@ -1121,6 +1121,16 @@
     range->selectNodeContents(node);
     CharacterIterator it(range.get());
     it.advance(index - 1);
+
+    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());
+        }
+    }
+
     return { it.atEnd() ? range->endPosition() : it.range()->endPosition(), UPSTREAM };
 }
 

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/editing/markup.cpp (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/editing/markup.cpp	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/editing/markup.cpp	2019-07-01 08:53:22 UTC (rev 246972)
@@ -1114,12 +1114,16 @@
     string.replace("\r\n", "\n");
     string.replace('\r', '\n');
 
+    auto createHTMLBRElement = [&document]() {
+        auto element = HTMLBRElement::create(document);
+        element->setAttributeWithoutSynchronization(classAttr, AppleInterchangeNewline);
+        return element;
+    };
+
     if (contextPreservesNewline(context)) {
         fragment->appendChild(document.createTextNode(string));
         if (string.endsWith('\n')) {
-            auto element = HTMLBRElement::create(document);
-            element->setAttributeWithoutSynchronization(classAttr, AppleInterchangeNewline);
-            fragment->appendChild(element);
+            fragment->appendChild(createHTMLBRElement());
         }
         return fragment;
     }
@@ -1130,6 +1134,12 @@
         return fragment;
     }
 
+    if (string.length() == 1 && string[0] == '\n') {
+        // This is a single newline char, thus just create one HTMLBRElement.
+        fragment->appendChild(createHTMLBRElement());
+        return fragment;
+    }
+
     // Break string into paragraphs. Extra line breaks turn into empty paragraphs.
     Node* blockNode = enclosingBlock(context.firstNode());
     Element* block = downcast<Element>(blockNode);
@@ -1148,8 +1158,7 @@
         RefPtr<Element> element;
         if (s.isEmpty() && i + 1 == numLines) {
             // For last line, use the "magic BR" rather than a P.
-            element = HTMLBRElement::create(document);
-            element->setAttributeWithoutSynchronization(classAttr, AppleInterchangeNewline);
+            element = createHTMLBRElement();
         } else if (useLineBreak) {
             element = HTMLBRElement::create(document);
             fillContainerFromString(fragment, s);

Modified: releases/WebKitGTK/webkit-2.24/Tools/ChangeLog (246971 => 246972)


--- releases/WebKitGTK/webkit-2.24/Tools/ChangeLog	2019-07-01 08:53:14 UTC (rev 246971)
+++ releases/WebKitGTK/webkit-2.24/Tools/ChangeLog	2019-07-01 08:53:22 UTC (rev 246972)
@@ -1,3 +1,19 @@
+2019-05-30  Andres Gonzalez  <andresg...@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):
+
 2019-06-12  Michael Catanzaro  <mcatanz...@igalia.com>
 
         [WPE][GTK] Deprecate WebSQL APIs
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to