- 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.