Title: [132488] trunk
Revision
132488
Author
[email protected]
Date
2012-10-25 08:40:49 -0700 (Thu, 25 Oct 2012)

Log Message

Can't easily position the cursor on an empty line in a textarea with touch if touch adjustment is enabled
https://bugs.webkit.org/show_bug.cgi?id=97576

Patch by Kevin Ellis <[email protected]> on 2012-10-25
Reviewed by Antonio Gomes.

Source/WebCore:

Consolidate touch adjustment candidates that are
editable.  Adjustment becomes coarse being based
on the bounds of the outermost editable element.
This fix allows tap positioning of the text caret
on a blank line immediately above or below another
element.

Test: touchadjustment/editable-content.html

* page/TouchAdjustment.cpp:
(WebCore::TouchAdjustment::compileSubtargetList):
(WebCore::TouchAdjustment::hybridDistanceFunction):

LayoutTests:

Add test to verify that touch adjustment is coarse for
editable content, being based on the bounds of the
editable content and not its children.

* touchadjustment/editable-content-expected.txt: Added.
* touchadjustment/editable-content.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (132487 => 132488)


--- trunk/LayoutTests/ChangeLog	2012-10-25 15:33:21 UTC (rev 132487)
+++ trunk/LayoutTests/ChangeLog	2012-10-25 15:40:49 UTC (rev 132488)
@@ -1,3 +1,17 @@
+2012-10-25  Kevin Ellis  <[email protected]>
+
+        Can't easily position the cursor on an empty line in a textarea with touch if touch adjustment is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=97576
+
+        Reviewed by Antonio Gomes.
+
+        Add test to verify that touch adjustment is coarse for
+        editable content, being based on the bounds of the
+        editable content and not its children.
+
+        * touchadjustment/editable-content-expected.txt: Added.
+        * touchadjustment/editable-content.html: Added.
+
 2012-10-25  Csaba Osztrogonác  <[email protected]>
 
         [Qt] Unreviewed gardening, skip tests because TestRunner::overridePreference()

Added: trunk/LayoutTests/touchadjustment/editable-content-expected.txt (0 => 132488)


--- trunk/LayoutTests/touchadjustment/editable-content-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/touchadjustment/editable-content-expected.txt	2012-10-25 15:40:49 UTC (rev 132488)
@@ -0,0 +1,45 @@
+
+Hello
+
+World
+Tests touch adjustment on a text-area.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+test textarea
+test direct touches
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 0
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 0
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 0
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 1
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 1
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 1
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 2
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 2
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 2
+test indirect touches
+PASS adjusted node was TEXTAREA#text-area.
+PASS adjusted node was TEXTAREA#text-area.
+PASS adjusted node was TEXTAREA#text-area.
+PASS adjusted node was TEXTAREA#text-area.
+test richly editable div
+test direct touches
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 0
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 0
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 0
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 1
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 1
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 1
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 2
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 2
+PASS Math.floor((adjustedPoint.y - origin) / rowHeight) is 2
+test indirect touches
+PASS adjusted node was DIV#rich-text.
+PASS adjusted node was DIV#rich-text.
+PASS adjusted node was DIV#rich-text.
+PASS adjusted node was DIV#rich-text.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/touchadjustment/editable-content.html (0 => 132488)


--- trunk/LayoutTests/touchadjustment/editable-content.html	                        (rev 0)
+++ trunk/LayoutTests/touchadjustment/editable-content.html	2012-10-25 15:40:49 UTC (rev 132488)
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Touch Adjustment : content editable div - bug 97576</title>
+    <script src=""
+    <script src=""
+    <style>
+        body {
+            font-size: 12px;
+            line-height: 14px;
+        }
+
+        #text-area,
+        #rich-text {
+            background: #eee;
+            border: none;
+            margin: 0 5px;
+            padding: 0;
+        }
+
+        #rich-text {
+            margin-top: 50px;
+            outline: none;
+            width: 300px;
+        }
+    </style>
+</head>
+
+<body>
+
+<div id=sandbox>
+    <textarea id="text-area" rows="5" cols="40">A lengthy line of text.
+
+Another line of text separated by a blank line.</textarea>
+
+    <div id="rich-text" contentEditable>
+        <b>Hello</b><br><br><i>World</i>
+    </div>
+</div>
+
+<p id='description'></p>
+<div id='console'></div>
+
+<script>
+    var element;
+    var rowHeight;
+    var touchOffset = 4;
+    var touchRadius = 20;
+    var origin;
+    var adjustedNode;
+    var adjustedPoint;
+
+    function testTouchOnRow(row, offset) {
+        var bounds = findAbsoluteBounds(element);
+        var midPoint = bounds.left + 0.5 * bounds.width;
+        var x = bounds.left + 2 * touchRadius;  
+        var y = bounds.top + (row + 0.5) * rowHeight + offset; // Vertically centered on row when offset is zero.
+        var point = touchPoint(x, y, touchRadius, touchRadius);
+        adjustedPoint = adjustTouchPoint(point);
+        origin = bounds.top;
+        shouldEvaluateTo('Math.floor((adjustedPoint.y - origin) / rowHeight)', row);
+    }
+
+    function testDirectTouches() {
+        debug('test direct touches');
+        // Touches centered on the blank line should not be adjusted a neighboring text line.
+        for (var row = 0; row < 3; row++) {
+            for (var offset = -touchOffset; offset <= touchOffset; offset += touchOffset) {
+                testTouchOnRow(row, offset);
+            }
+        }
+    }
+
+    function testTouchOnBoundary(position) {
+        var touchpoint = offsetTouchPoint(findAbsoluteBounds(element), position, touchOffset, touchRadius, touchRadius);
+        testTouchPoint(touchpoint, element);
+    }
+
+    function testIndirectTouches() {
+      debug('test indirect touches');
+      testTouchOnBoundary('bottom');
+      testTouchOnBoundary('left');
+      testTouchOnBoundary('right');
+      testTouchOnBoundary('top');
+    }
+
+    function runTests()
+    {
+        if (window.testRunner && window.internals && internals.touchNodeAdjustedToBestClickableNode) {
+            description('Tests touch adjustment on a text-area.');
+            debug('test textarea');
+            element = document.getElementById('text-area');
+            rowHeight = 15; // Height of each row is line-height + 1
+            testDirectTouches();
+            testIndirectTouches();
+            debug('test richly editable div');
+            element = document.getElementById('rich-text');
+            rowHeight = 14;
+            testDirectTouches();
+            testIndirectTouches();
+        }
+    }
+    runTests();
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (132487 => 132488)


--- trunk/Source/WebCore/ChangeLog	2012-10-25 15:33:21 UTC (rev 132487)
+++ trunk/Source/WebCore/ChangeLog	2012-10-25 15:40:49 UTC (rev 132488)
@@ -1,3 +1,23 @@
+2012-10-25  Kevin Ellis  <[email protected]>
+
+        Can't easily position the cursor on an empty line in a textarea with touch if touch adjustment is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=97576
+
+        Reviewed by Antonio Gomes.
+
+        Consolidate touch adjustment candidates that are
+        editable.  Adjustment becomes coarse being based
+        on the bounds of the outermost editable element.
+        This fix allows tap positioning of the text caret
+        on a blank line immediately above or below another
+        element.
+
+        Test: touchadjustment/editable-content.html
+
+        * page/TouchAdjustment.cpp:
+        (WebCore::TouchAdjustment::compileSubtargetList):
+        (WebCore::TouchAdjustment::hybridDistanceFunction):
+
 2012-10-25  Yury Semikhatsky  <[email protected]>
 
         Memory instrumentation: add reportMemoryUsage to ImageObserver interface

Modified: trunk/Source/WebCore/page/TouchAdjustment.cpp (132487 => 132488)


--- trunk/Source/WebCore/page/TouchAdjustment.cpp	2012-10-25 15:33:21 UTC (rev 132487)
+++ trunk/Source/WebCore/page/TouchAdjustment.cpp	2012-10-25 15:40:49 UTC (rev 132488)
@@ -223,6 +223,7 @@
     HashMap<Node*, Node*> responderMap;
     HashSet<Node*> ancestorsToRespondersSet;
     Vector<Node*> candidates;
+    HashSet<Node*> editableAncestors;
 
     // A node matching the NodeFilter is called a responder. Candidate nodes must either be a
     // responder or have an ancestor that is a responder.
@@ -270,7 +271,25 @@
         ASSERT(respondingNode);
         if (ancestorsToRespondersSet.contains(respondingNode))
             continue;
-        appendSubtargetsForNode(candidate, subtargets);
+        // Consolidate bounds for editable content.
+        if (editableAncestors.contains(candidate))
+            continue;
+        if (candidate->isContentEditable()) {
+            Node* replacement = candidate;
+            Node* parent = candidate->parentOrHostNode();
+            while (parent && parent->isContentEditable()) {
+                replacement = parent;
+                if (editableAncestors.contains(replacement)) {
+                    replacement = 0;
+                    break;
+                }
+                editableAncestors.add(replacement);
+                parent = parent->parentOrHostNode();
+            }
+            candidate = replacement;
+        }
+        if (candidate)
+            appendSubtargetsForNode(candidate, subtargets);
     }
 }
 
@@ -320,7 +339,7 @@
     float radiusSquared = 0.25f * (touchRect.size().diagonalLengthSquared());
     float distanceToAdjustScore = rect.distanceSquaredToPoint(touchHotspot) / radiusSquared;
 
-    float targetArea = rect.size().area();
+    float targetArea = max(rect.size().area(), 1);
     rect.intersect(touchRect);
     float intersectArea = rect.size().area();
     float intersectionScore = 1 - intersectArea / targetArea;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to