Title: [200787] trunk
Revision
200787
Author
[email protected]
Date
2016-05-12 12:51:14 -0700 (Thu, 12 May 2016)

Log Message

indexForVisiblePosition should use the root editable element as the scope
https://bugs.webkit.org/show_bug.cgi?id=157611

Reviewed by Darin Adler.

Source/WebCore:

Use the highest editing host instead of the document node as the scope in indexForVisiblePosition
when it's called inside an editable region. This refactoring is necessary to unblock the work to support
undo/redo in VoiceOver after r199030.

We have to workaround a bug in indexForVisiblePosition that it could return a slightly higher index than
the expected value because TextIterator emits an extra new line after a block element with a large margin
at the bottom. Unfortunately, fixing this requires a lot of code changes since the rest of the editing
code assumes this behavior and/or happens to cancel it out with some other quirks.

* editing/ApplyBlockElementCommand.cpp:
(WebCore::ApplyBlockElementCommand::doApply):
* editing/htmlediting.cpp:
(WebCore::indexForVisiblePosition):

LayoutTests:

Rebaselined tests with progressions.

* editing/execCommand/crash-indenting-list-item-expected.txt: Now preseves the selection at the beginning of
the editable region instead of moving it to the end.
* editing/execCommand/format-block-multiple-paragraphs-in-pre-expected.txt: Now preserves selection in more test
cases. This test is the one that required the workaround in ApplyBlockElementCommand::doApply. One of the test
cases would regress and clear the selection without it.
* editing/execCommand/indent-pre-list-expected.txt: Now preserves the selection instead of clearing it.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (200786 => 200787)


--- trunk/LayoutTests/ChangeLog	2016-05-12 19:29:48 UTC (rev 200786)
+++ trunk/LayoutTests/ChangeLog	2016-05-12 19:51:14 UTC (rev 200787)
@@ -1,3 +1,19 @@
+2016-05-12  Ryosuke Niwa  <[email protected]>
+
+        indexForVisiblePosition should use the root editable element as the scope
+        https://bugs.webkit.org/show_bug.cgi?id=157611
+
+        Reviewed by Darin Adler.
+
+        Rebaselined tests with progressions.
+
+        * editing/execCommand/crash-indenting-list-item-expected.txt: Now preseves the selection at the beginning of
+        the editable region instead of moving it to the end.
+        * editing/execCommand/format-block-multiple-paragraphs-in-pre-expected.txt: Now preserves selection in more test
+        cases. This test is the one that required the workaround in ApplyBlockElementCommand::doApply. One of the test
+        cases would regress and clear the selection without it.
+        * editing/execCommand/indent-pre-list-expected.txt: Now preserves the selection instead of clearing it.
+
 2016-05-12  Eric Carlson  <[email protected]>
 
         Adjust "main content" video heuristic

Modified: trunk/LayoutTests/editing/execCommand/crash-indenting-list-item-expected.txt (200786 => 200787)


--- trunk/LayoutTests/editing/execCommand/crash-indenting-list-item-expected.txt	2016-05-12 19:29:48 UTC (rev 200786)
+++ trunk/LayoutTests/editing/execCommand/crash-indenting-list-item-expected.txt	2016-05-12 19:51:14 UTC (rev 200787)
@@ -7,8 +7,8 @@
 |         <ul>
 |           <li>
 |             id="foo"
+|             <#selection-caret>
 |             "PASSED"
-|         <#selection-caret>
 |     "
 "
 |     <script>

Modified: trunk/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-in-pre-expected.txt (200786 => 200787)


--- trunk/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-in-pre-expected.txt	2016-05-12 19:29:48 UTC (rev 200786)
+++ trunk/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-in-pre-expected.txt	2016-05-12 19:51:14 UTC (rev 200787)
@@ -4,7 +4,7 @@
 | "
 "
 | <h3>
-|   "hello"
+|   "<#selection-anchor>hello"
 |   <br>
 |   "
 "
@@ -12,7 +12,7 @@
 |   <br>
 |   "
 "
-|   "webkit"
+|   "webkit<#selection-focus>"
 | "
 "
 
@@ -65,12 +65,11 @@
 |   "hello
 "
 |   <h3>
-|     "
+|     "<#selection-anchor>
 "
 |     "world"
 |     "
 "
-|     "webkit"
-|   <#selection-caret>
+|     "webkit<#selection-focus>"
 | "
 "

Modified: trunk/LayoutTests/editing/execCommand/indent-pre-list-expected.txt (200786 => 200787)


--- trunk/LayoutTests/editing/execCommand/indent-pre-list-expected.txt	2016-05-12 19:29:48 UTC (rev 200786)
+++ trunk/LayoutTests/editing/execCommand/indent-pre-list-expected.txt	2016-05-12 19:51:14 UTC (rev 200787)
@@ -69,11 +69,11 @@
 |     <pre>
 |       <blockquote>
 |         style="margin: 0 0 0 40px; border: none; padding: 0px;"
-|         "hello"
+|         "<#selection-anchor>hello"
 |         <br>
 |         "world"
 |         <br>
-|         "webkit"
+|         "webkit<#selection-focus>"
 | "
 "
 

Modified: trunk/Source/WebCore/ChangeLog (200786 => 200787)


--- trunk/Source/WebCore/ChangeLog	2016-05-12 19:29:48 UTC (rev 200786)
+++ trunk/Source/WebCore/ChangeLog	2016-05-12 19:51:14 UTC (rev 200787)
@@ -1,3 +1,24 @@
+2016-05-12  Ryosuke Niwa  <[email protected]>
+
+        indexForVisiblePosition should use the root editable element as the scope
+        https://bugs.webkit.org/show_bug.cgi?id=157611
+
+        Reviewed by Darin Adler.
+
+        Use the highest editing host instead of the document node as the scope in indexForVisiblePosition
+        when it's called inside an editable region. This refactoring is necessary to unblock the work to support
+        undo/redo in VoiceOver after r199030.
+
+        We have to workaround a bug in indexForVisiblePosition that it could return a slightly higher index than
+        the expected value because TextIterator emits an extra new line after a block element with a large margin
+        at the bottom. Unfortunately, fixing this requires a lot of code changes since the rest of the editing
+        code assumes this behavior and/or happens to cancel it out with some other quirks.
+
+        * editing/ApplyBlockElementCommand.cpp:
+        (WebCore::ApplyBlockElementCommand::doApply):
+        * editing/htmlediting.cpp:
+        (WebCore::indexForVisiblePosition):
+
 2016-05-12  Zalan Bujtas  <[email protected]>
 
         Cleanup RenderObject::containingBlock.

Modified: trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp (200786 => 200787)


--- trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp	2016-05-12 19:29:48 UTC (rev 200786)
+++ trunk/Source/WebCore/editing/ApplyBlockElementCommand.cpp	2016-05-12 19:51:14 UTC (rev 200787)
@@ -97,6 +97,11 @@
     if (startScope == endScope && startIndex >= 0 && startIndex <= endIndex) {
         VisiblePosition start(visiblePositionForIndex(startIndex, startScope.get()));
         VisiblePosition end(visiblePositionForIndex(endIndex, endScope.get()));
+        // Work around the fact indexForVisiblePosition can return a larger index due to TextIterator
+        // using an extra newline to represent a large margin.
+        // FIXME: Add a new TextIteratorBehavior to suppress it.
+        if (start.isNotNull() && end.isNull())
+            end = lastPositionInNode(endScope.get());
         if (start.isNotNull() && end.isNotNull())
             setEndingSelection(VisibleSelection(start, end, endingSelection().isDirectional()));
     }

Modified: trunk/Source/WebCore/editing/htmlediting.cpp (200786 => 200787)


--- trunk/Source/WebCore/editing/htmlediting.cpp	2016-05-12 19:29:48 UTC (rev 200786)
+++ trunk/Source/WebCore/editing/htmlediting.cpp	2016-05-12 19:51:14 UTC (rev 200787)
@@ -1133,17 +1133,21 @@
     if (visiblePosition.isNull())
         return 0;
 
-    Position p(visiblePosition.deepEquivalent());
-    Document& document = p.anchorNode()->document();
-    ShadowRoot* shadowRoot = p.anchorNode()->containingShadowRoot();
+    Position position = visiblePosition.deepEquivalent();
+    auto& document = *position.document();
 
-    if (shadowRoot)
-        scope = shadowRoot;
-    else
-        scope = document.documentElement();
+    Node* editableRoot = highestEditableRoot(position, AXObjectCache::accessibilityEnabled() ? HasEditableAXRole : ContentIsEditable);
+    if (editableRoot && !document.inDesignMode())
+        scope = downcast<ContainerNode>(editableRoot);
+    else {
+        if (position.containerNode()->isInShadowTree())
+            scope = position.containerNode()->containingShadowRoot();
+        else
+            scope = &document;
+    }
 
-    RefPtr<Range> range = Range::create(document, firstPositionInNode(scope.get()), p.parentAnchoredEquivalent());
-    return TextIterator::rangeLength(range.get(), true);
+    auto range = Range::create(document, firstPositionInNode(scope.get()), position.parentAnchoredEquivalent());
+    return TextIterator::rangeLength(range.ptr(), true);
 }
 
 // FIXME: Merge these two functions.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to