Unable to move selection into editable roots with 0 height
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 3 Feb 2019 20:52:58 +0000 (20:52 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 3 Feb 2019 20:52:58 +0000 (20:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194143
<rdar://problem/47767284>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Currently, positions inside editable elements of height 0 are not considered to be candidates when
canonicalizing a position to its visible counterpart. This prevents us from moving the selection into these
editable roots at all. To fix this, we relax this constraint by allowing positions anchored by root editable
elements to be candidates.

Test: editing/selection/insert-text-in-empty-content-editable.html

* dom/Position.cpp:
(WebCore::Position::isCandidate const):

LayoutTests:

Add a new layout test that executes editing commands in a contenteditable element of height 0, and adjust an
existing layout test that copies and pastes an image element to wait until the image has loaded.

* editing/pasteboard/styled-element-markup.html:
* editing/selection/insert-text-in-empty-content-editable-expected.txt: Added.
* editing/selection/insert-text-in-empty-content-editable.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/styled-element-markup.html
LayoutTests/editing/selection/insert-text-in-empty-content-editable-expected.txt [new file with mode: 0644]
LayoutTests/editing/selection/insert-text-in-empty-content-editable.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Position.cpp

index ebc74c4..3c0ced3 100644 (file)
@@ -1,3 +1,18 @@
+2019-02-03  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Unable to move selection into editable roots with 0 height
+        https://bugs.webkit.org/show_bug.cgi?id=194143
+        <rdar://problem/47767284>
+
+        Reviewed by Ryosuke Niwa.
+
+        Add a new layout test that executes editing commands in a contenteditable element of height 0, and adjust an
+        existing layout test that copies and pastes an image element to wait until the image has loaded.
+
+        * editing/pasteboard/styled-element-markup.html:
+        * editing/selection/insert-text-in-empty-content-editable-expected.txt: Added.
+        * editing/selection/insert-text-in-empty-content-editable.html: Added.
+
 2019-02-03  Megan Gardner  <megan_gardner@apple.com>
 
         Turn on Smart Paste
index a831e28..0638247 100644 (file)
@@ -1,16 +1,16 @@
-<script>
-if (window.testRunner)
-     testRunner.dumpEditingCallbacks();
-</script>
 <p>This tests copy/paste of styled elements, like images.  The image in the region below should be centered after its copied and pasted.</p>
 <p><b>This demonstrates a bug: createMarkup puts the text-align property on the image, which doesn't center it, so its left aligned on paste.</b></p>
 <div contenteditable="true" id="copy"><center><img src="../resources/abe.png"></center></div>
 <div contenteditable="true" id="paste"></div>
+<script>
+if (window.testRunner)
+    testRunner.dumpEditingCallbacks();
 
-<script>;
-window.getSelection().setPosition(document.getElementById("copy"));
-document.execCommand("SelectAll");
-document.execCommand("Copy");
-window.getSelection().setPosition(document.getElementById("paste"));
-document.execCommand("Paste");
+addEventListener("load", () => {
+    getSelection().setPosition(document.getElementById("copy"));
+    document.execCommand("SelectAll");
+    document.execCommand("Copy");
+    getSelection().setPosition(document.getElementById("paste"));
+    document.execCommand("Paste");
+});
 </script>
diff --git a/LayoutTests/editing/selection/insert-text-in-empty-content-editable-expected.txt b/LayoutTests/editing/selection/insert-text-in-empty-content-editable-expected.txt
new file mode 100644 (file)
index 0000000..09d6c9c
--- /dev/null
@@ -0,0 +1,29 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 11 of #text > DIV > BODY > HTML > #document to 11 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+EDITING DELEGATE: shouldEndEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 11 of #text > DIV > BODY > HTML > #document to 11 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
+Verifies the ability to programmatically focus and insert text in an empty editable element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS editor1.textContent is "Hello world"
+PASS editor2.textContent is "Hello world!"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Hello world
+Hello world!
diff --git a/LayoutTests/editing/selection/insert-text-in-empty-content-editable.html b/LayoutTests/editing/selection/insert-text-in-empty-content-editable.html
new file mode 100644 (file)
index 0000000..f14ef07
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<head>
+<script src="../../resources/js-test.js"></script>
+<style>
+    #editor1, #editor2 {
+        width: 100%;
+        height: 0;
+    }
+</style>
+</head>
+<body>
+<div contenteditable="true" id="editor1"></div>
+<div contenteditable="true" id="editor2">!</div>
+<script>
+    if (window.testRunner)
+        testRunner.dumpEditingCallbacks();
+
+    description("Verifies the ability to programmatically focus and insert text in an empty editable element.");
+    editor1 = document.getElementById("editor1");
+    editor1.focus();
+    document.execCommand("InsertText", true, "Hello world");
+    shouldBeEqualToString("editor1.textContent", "Hello world");
+
+    editor2 = document.getElementById("editor2");
+    editor2.focus();
+    document.execCommand("InsertText", true, "Hello world");
+    shouldBeEqualToString("editor2.textContent", "Hello world!");
+</script>
+</body>
index 1ef03e8..2e903de 100644 (file)
@@ -1,3 +1,21 @@
+2019-02-03  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Unable to move selection into editable roots with 0 height
+        https://bugs.webkit.org/show_bug.cgi?id=194143
+        <rdar://problem/47767284>
+
+        Reviewed by Ryosuke Niwa.
+
+        Currently, positions inside editable elements of height 0 are not considered to be candidates when
+        canonicalizing a position to its visible counterpart. This prevents us from moving the selection into these
+        editable roots at all. To fix this, we relax this constraint by allowing positions anchored by root editable
+        elements to be candidates.
+
+        Test: editing/selection/insert-text-in-empty-content-editable.html
+
+        * dom/Position.cpp:
+        (WebCore::Position::isCandidate const):
+
 2019-02-03  Simon Fraser  <simon.fraser@apple.com>
 
         Tidyup of Pagination and FrameView m_mediaType initialization
index f23627f..5ef5b11 100644 (file)
@@ -1032,7 +1032,7 @@ bool Position::isCandidate() const
 
     if (is<RenderBlockFlow>(*renderer) || is<RenderGrid>(*renderer) || is<RenderFlexibleBox>(*renderer)) {
         RenderBlock& block = downcast<RenderBlock>(*renderer);
-        if (block.logicalHeight() || is<HTMLBodyElement>(*m_anchorNode)) {
+        if (block.logicalHeight() || is<HTMLBodyElement>(*m_anchorNode) || m_anchorNode->isRootEditableElement()) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(block))
                 return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
             return m_anchorNode->hasEditableStyle() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();