LayoutTests/ChangeLog

 12011-04-11 Alice Boxhall <aboxhall@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Text selection changes unexpectedly when dragging out of the <input>
 6 https://bugs.webkit.org/show_bug.cgi?id=55552
 7
 8 Tests that dragging outside of a contenteditable, input or textarea selects to the end of the
 9 element, rather than jumping back to the beginning.
 10
 11 * editing/selection/resources/select-out-of-floated-editable.js: Added.
 12 (log):
 13 (else.window.onmouseup):
 14 (getSelectionStart):
 15 (getSelectionEnd):
 16 (checkSelection):
 17 * editing/selection/select-out-of-editable-expected.txt: Added.
 18 * editing/selection/select-out-of-editable.html: Added.
 19 * editing/selection/select-out-of-floated-contenteditable-expected.txt: Added.
 20 * editing/selection/select-out-of-floated-contenteditable.html: Added.
 21 * editing/selection/select-out-of-floated-input-expected.txt: Added.
 22 * editing/selection/select-out-of-floated-input.html: Added.
 23 * editing/selection/select-out-of-floated-textarea-expected.txt: Added.
 24 * editing/selection/select-out-of-floated-textarea.html: Added.
 25
1262011-04-12 Csaba Osztrogonác <ossy@webkit.org>
227
328 [Qt] http/tests/misc/favicon-loads-with-icon-loading-override.html fails

LayoutTests/editing/selection/resources/select-out-of-floated-editable.js

 1function log(msg) {
 2 document.getElementById('console').appendChild(document.createTextNode(msg + '\n'));
 3}
 4
 5if (window.layoutTestController && window.eventSender) {
 6 layoutTestController.dumpAsText();
 7
 8 var x = floatedEditable.offsetLeft + (floatedEditable.offsetWidth / 2);
 9 var y = floatedEditable.offsetTop + (floatedEditable.offsetHeight / 2);
 10 eventSender.mouseMoveTo(x, y);
 11 eventSender.mouseDown();
 12 x = floatedEditable.offsetLeft + floatedEditable.offsetWidth + 5;
 13 eventSender.mouseMoveTo(x, y);
 14 eventSender.leapForward(100);
 15 eventSender.mouseUp();
 16
 17 checkSelection();
 18} else {
 19 window.onmouseup = function() {
 20 window.setTimeout(function() {
 21 log('Input selection start: ' + getSelectionStart(floatedEditable) + ', end: ' +
 22 getSelectionEnd(floatedEditable));
 23 checkSelection();
 24 }, 0); // Without a timeout the selection is inaccurately printed
 25 }
 26}
 27
 28function getSelectionStart(element) {
 29 return element.isContentEditable ? window.getSelection().baseOffset : element.selectionStart;
 30}
 31
 32function getSelectionEnd(element) {
 33 return element.isContentEditable ? window.getSelection().extentOffset : element.selectionEnd;
 34}
 35
 36function checkSelection() {
 37 var inputText = floatedEditable.isContentEditable ? floatedEditable.textContent : floatedEditable.value;
 38 var inputTextLength = inputText.length;
 39 var selectionStart = getSelectionStart(floatedEditable);
 40 var selectionEnd = getSelectionEnd(floatedEditable);
 41
 42 var selectionStartsFromMiddle = selectionStart > 0 && selectionStart < inputTextLength;
 43 var selectionGoesToEnd = selectionEnd == inputTextLength;
 44 if (selectionStartsFromMiddle && selectionGoesToEnd)
 45 result.innerHTML = '<span style="padding: 5px; background-color: green">SUCCESS</span>';
 46 else
 47 result.innerHTML = '<span style="padding: 5px; background-color: red">FAIL</span>';
 48}

LayoutTests/editing/selection/select-out-of-editable-expected.txt

 1hello world
 2Dragging to the left: PASS
 3Dragging to the left: PASS
 4This test requires eventSender since the bug does not reproduce reliably when tested manually.

LayoutTests/editing/selection/select-out-of-editable.html

 1<!DOCTYPE html>
 2<html>
 3<body>
 4<p id="description">This test ensures that when editable text is selected by a drag that ends outside of the editable region, selection is extended to the either end of the text. See the <a href="https://bugs.webkit.org/show_bug.cgi?id=52986">bug 52986</a> for more details.</p>
 5<div id="test" contenteditable style="width: 200px; margin: 20px; border: solid 1px; font-size: x-large;">hello world</div>
 6<script>
 7
 8function selectTextByDrag(div, endX, endY) {
 9 window.getSelection().removeAllRanges();
 10
 11 eventSender.mouseMoveTo(div.offsetLeft + (div.offsetWidth / 2) , div.offsetTop + (div.offsetHeight / 2));
 12 eventSender.mouseDown();
 13
 14 eventSender.leapForward(200);
 15
 16 // Without this, drag doesn't start selection.
 17 eventSender.mouseMoveTo(div.offsetLeft + (div.offsetWidth / 3) , div.offsetTop + (div.offsetHeight / 3));
 18 eventSender.mouseDown();
 19
 20 eventSender.leapForward(200);
 21
 22 eventSender.mouseMoveTo(endX, endY);
 23 eventSender.mouseUp();
 24}
 25
 26var log = '';
 27
 28function assertEqual(actual, expected) {
 29 if (actual == expected)
 30 log += 'PASS';
 31 else
 32 log += 'FAIL - expected ' + expected + ' but got ' + actual;
 33 log += '\n';
 34}
 35
 36if (!window.layoutTestController || !window.eventSender)
 37 document.writeln("This test requires eventSender since the bug does not reproduce reliably when tested manually.");
 38else {
 39 layoutTestController.dumpAsText();
 40 var description = document.getElementById('description');
 41 description.style.display = 'none';
 42
 43 var div = document.getElementById('test');
 44
 45 log += 'Dragging to the left: ';
 46 selectTextByDrag(div, div.offsetLeft - 10, div.offsetTop - 10);
 47 assertEqual(window.getSelection().getRangeAt(0).startOffset, 0);
 48
 49 log += 'Dragging to the left: ';
 50 selectTextByDrag(div, div.offsetLeft + 300, div.offsetTop + 100);
 51 assertEqual(window.getSelection().getRangeAt(0).endOffset, div.innerText.length);
 52
 53 // Having the log in DOM will interfere with the test so append it at last.
 54 var console = document.createElement('pre');
 55 document.body.appendChild(console);
 56 console.innerHTML = log;
 57}
 58
 59</script>
 60</body>
 61</html>

LayoutTests/editing/selection/select-out-of-floated-contenteditable-expected.txt

 1Some text before the floats. Drag from the middle. Some floated text in a div. Some text after the floats.
 2To test manually, drag from the middle of the editable div to the right, into the non-floated text. The selection should go to the end of the input element and not jump to the beginning.
 3
 4SUCCESS
 5
 6

LayoutTests/editing/selection/select-out-of-floated-contenteditable.html

 1<!DOCTYPE html>
 2Some text before the floats.
 3<div contenteditable=true id="floatedEditable" style="float: left;">
 4 Drag from the middle.
 5</div>
 6<div style="width: 100%; float: left;">
 7 Some floated text in a div.
 8</div>
 9Some text after the floats.
 10<p style="padding-top: 1em;">
 11To test manually, drag from the middle of the editable div to the
 12right, into the non-floated text. The selection should go to the end
 13of the input element and not jump to the beginning.
 14</p>
 15<p id="result"></p>
 16<pre id="console"></pre>
 17<script src="resources/select-out-of-floated-editable.js"></script>
 18

LayoutTests/editing/selection/select-out-of-floated-input-expected.txt

 1Some text before the floats. Some floated text in a div. Some text after the floats.
 2To test manually, drag from the middle of the input element to the right, into the non-floated text. The selection should go to the end of the input element and not jump to the beginning.
 3
 4SUCCESS
 5
 6

LayoutTests/editing/selection/select-out-of-floated-input.html

 1<!DOCTYPE html>
 2Some text before the floats.
 3<div style="float: left;">
 4 <input type="text" id="floatedEditable" value="Drag from the middle.">
 5</div>
 6<div style="width: 100%; float: left;">
 7 Some floated text in a div.
 8</div>
 9Some text after the floats.
 10<p style="padding-top: 1em;">
 11To test manually, drag from the middle of the input element to the
 12right, into the non-floated text. The selection should go to the end
 13of the input element and not jump to the beginning.
 14</p>
 15<p id="result"></p>
 16<pre id="console"></pre>
 17<script src="resources/select-out-of-floated-editable.js"></script>
 18

LayoutTests/editing/selection/select-out-of-floated-textarea-expected.txt

 1Some text before the floats. Some floated text in a div. Some text after the floats.
 2To test manually, drag from the middle of the textarea to the right, into the non-floated text. The selection should go to the end of the input element and not jump to the beginning.
 3
 4SUCCESS
 5
 6

LayoutTests/editing/selection/select-out-of-floated-textarea.html

 1<!DOCTYPE html>
 2Some text before the floats.
 3<div style="float: left;">
 4 <textarea rows="1" id="floatedEditable">Drag from the middle.</textarea>
 5</div>
 6<div style="width: 100%; float: left;">
 7 Some floated text in a div.
 8</div>
 9Some text after the floats.
 10<p style="padding-top: 1em;">
 11To test manually, drag from the middle of the textarea to the
 12right, into the non-floated text. The selection should go to the end
 13of the input element and not jump to the beginning.
 14</p>
 15<p id="result"></p>
 16<pre id="console"></pre>
 17<script src="resources/select-out-of-floated-editable.js"></script>
 18

Source/WebCore/ChangeLog

 12011-04-11 Alice Boxhall <aboxhall@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Text selection changes unexpectedly when dragging out of the <input>
 6 https://bugs.webkit.org/show_bug.cgi?id=55552
 7
 8 Tests: editing/selection/select-out-of-editable.html
 9 editing/selection/select-out-of-floated-contenteditable.html
 10 editing/selection/select-out-of-floated-input.html
 11 editing/selection/select-out-of-floated-textarea.html
 12
 13 * page/EventHandler.cpp:
 14 (WebCore::targetPositionForSelectionEndpoint): When dragging from an editable element, check that
 15 the endpoint is not outside the element. If it is, translate the point into a local point within
 16 the editable element.
 17 (WebCore::EventHandler::updateSelectionForMouseDrag): Call targetPositionForSelectionEndpoint() to
 18 calculate the selection endpoint.
 19
1202011-04-12 Adrienne Walker <enne@google.com>
221
322 Reviewed by James Robinson.

Source/WebCore/page/EventHandler.cpp

@@void EventHandler::updateSelectionForMouseDrag()
622622 updateSelectionForMouseDrag(result);
623623}
624624
 625static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection& selection, const IntPoint& localPoint, Node* targetNode)
 626{
 627 Element* editableElement = selection.rootEditableElement();
 628 IntPoint selectionEndPoint = localPoint;
 629 Node* selectionEndNode = targetNode;
 630
 631 if (editableElement && !editableElement->contains(targetNode)) {
 632 selectionEndNode = editableElement;
 633 FloatPoint absolutePoint = targetNode->renderer()->localToAbsolute(FloatPoint(selectionEndPoint));
 634
 635 selectionEndPoint = roundedIntPoint(selectionEndNode->renderer()->absoluteToLocal(absolutePoint));
 636 }
 637
 638 return selectionEndNode->renderer()->positionForPoint(selectionEndPoint);
 639}
 640
625641void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult)
626642{
627643 if (!m_mouseDownMayStartSelect)

@@void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResul
638654 if (!targetRenderer)
639655 return;
640656
641  VisiblePosition targetPosition = targetRenderer->positionForPoint(hitTestResult.localPoint());
 657 VisibleSelection newSelection = m_frame->selection()->selection();
 658 VisiblePosition targetPosition = selectionExtentRespectingEditingBoundary(newSelection, hitTestResult.localPoint(), target);
642659
643660 // Don't modify the selection if we're not on a node.
644661 if (targetPosition.isNull())
645662 return;
646663
647  // Restart the selection if this is the first mouse move. This work is usually
648  // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
649  VisibleSelection newSelection = m_frame->selection()->selection();
650 
651664#if ENABLE(SVG)
652665 // Special case to limit selection to the containing block for SVG text.
653666 // FIXME: Isn't there a better non-SVG-specific way to do this?