Commit 1aee657f authored by luoe's avatar luoe Committed by Commit bot

DevTools: fix ViewportControl's text selection logic

ViewportControl's _selectedText currently does this:
1 - get a selection+range with native window/shadowRoot.getSelection()
2 - calculate first and last viewport items that are part of the selection
3 - get the deepTextContent() of all those items
4 - trim out text based on the offsets provided by the selection

Step 4 is done by _textOffsetInNode(), which takes an itemElement, container,
and offset. Beforethis CL, it would start at the item and traverse all text
nodes until it stops at the container (node !== container). In this logic, it
assumes that the container is a text node itself so that (node !== container)
will be false and we will stop before counting the container's text length. In
reality, a user can drag to create a selection where the
range.start/endContainer can be an element that is not a text node (e.g. <span>
containing a text node). Then, _textOffsetInNode() would continue to traverse
and node.traverseNextTextNode() will never return a node that is === container.
This results in extra text length being counted which breaks the offset logic.

This CL makes sure that in those cases where the range.start/endContainer is not
a text node, such as a <span> containing the boundary text, we will stop
traversing when we hit a text node that is the end or is a descendant.

BUG=647287

Review-Url: https://codereview.chromium.org/2340223002
Cr-Commit-Position: refs/heads/master@{#419227}
parent 22c22eb7
...@@ -224,3 +224,11 @@ Selected text: world ...@@ -224,3 +224,11 @@ Selected text: world
Running: testSelectAll Running: testSelectAll
Selected all 150 messages. Selected all 150 messages.
Running: testSelectWithNonTextNodeContainer
Selected text: console-viewport-selection.html:5 Message #1
Selected text: console-viewport-selection.html:5 Message #1
Selected text: console-viewport-selection.html:5 Message #1
...@@ -181,6 +181,27 @@ function test() ...@@ -181,6 +181,27 @@ function test()
var text = viewport._selectedText(); var text = viewport._selectedText();
var count = text ? text.split("\n").length : 0; var count = text ? text.split("\n").length : 0;
InspectorTest.addResult(count === messagesCount ? "Selected all " + count + " messages." : "Selected " + count + " messages instead of " + messagesCount); InspectorTest.addResult(count === messagesCount ? "Selected all " + count + " messages." : "Selected " + count + " messages instead of " + messagesCount);
next();
},
function testSelectWithNonTextNodeContainer(next)
{
viewport.forceScrollItemToBeFirst(0);
var nonTextNodeBase = consoleView.itemElement(1).element();
var nonTextNodeExtent = consoleView.itemElement(2).element();
var textNodeBase = consoleView.itemElement(1).element().traverseNextTextNode();
var textNodeExtent = consoleView.itemElement(2).element().traverseNextTextNode();
window.getSelection().setBaseAndExtent(nonTextNodeBase, 0, nonTextNodeExtent, 0);
InspectorTest.addResult("Selected text: " + viewport._selectedText());
window.getSelection().setBaseAndExtent(textNodeBase, 0, nonTextNodeExtent, 0);
InspectorTest.addResult("Selected text: " + viewport._selectedText());
window.getSelection().setBaseAndExtent(nonTextNodeBase, 0, textNodeExtent, 0);
InspectorTest.addResult("Selected text: " + viewport._selectedText());
next(); next();
} }
]; ];
......
...@@ -567,7 +567,7 @@ WebInspector.ViewportControl.prototype = { ...@@ -567,7 +567,7 @@ WebInspector.ViewportControl.prototype = {
{ {
var chars = 0; var chars = 0;
var node = itemElement; var node = itemElement;
while ((node = node.traverseNextTextNode()) && node !== container) while ((node = node.traverseNextTextNode()) && !node.isSelfOrDescendant(container))
chars += node.textContent.length; chars += node.textContent.length;
return chars + offset; return chars + offset;
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment