Title: [127776] trunk/Source/WebKit/chromium
Revision
127776
Author
[email protected]
Date
2012-09-06 12:52:07 -0700 (Thu, 06 Sep 2012)

Log Message

[chromium] Add WebFrame::moveSelectionStart, moveSelectionEnd, moveCaret
https://bugs.webkit.org/show_bug.cgi?id=93998

Patch by Iain Merrick <[email protected]> on 2012-09-06
Reviewed by Adam Barth.

These provide the same functionality selectRange(WebPoint, WebPoint),
with finer-grained control needed on the Android platform. By passing
allowCollapsedSelection=false, we can ensure the selection stays at
least one character wide.

I have reimplemented WebFrameImpl::selectRange(WebPoint, WebPoint) by
calling the new methods. The existing test passes, and I've added new
tests for the new methods.

* public/WebFrame.h:
(WebFrame):
* src/WebFrameImpl.cpp:
(WebKit::WebFrameImpl::selectRange):
(WebKit):
(WebKit::WebFrameImpl::moveSelectionStart):
(WebKit::WebFrameImpl::moveSelectionEnd):
(WebKit::WebFrameImpl::moveCaret):
* src/WebFrameImpl.h:
(WebFrameImpl):
* tests/WebFrameTest.cpp:
* tests/data/text_selection.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/chromium/ChangeLog (127775 => 127776)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-09-06 19:50:18 UTC (rev 127775)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-09-06 19:52:07 UTC (rev 127776)
@@ -1,3 +1,32 @@
+2012-09-06  Iain Merrick  <[email protected]>
+
+        [chromium] Add WebFrame::moveSelectionStart, moveSelectionEnd, moveCaret
+        https://bugs.webkit.org/show_bug.cgi?id=93998
+
+        Reviewed by Adam Barth.
+
+        These provide the same functionality selectRange(WebPoint, WebPoint),
+        with finer-grained control needed on the Android platform. By passing
+        allowCollapsedSelection=false, we can ensure the selection stays at
+        least one character wide.
+
+        I have reimplemented WebFrameImpl::selectRange(WebPoint, WebPoint) by
+        calling the new methods. The existing test passes, and I've added new
+        tests for the new methods.
+
+        * public/WebFrame.h:
+        (WebFrame):
+        * src/WebFrameImpl.cpp:
+        (WebKit::WebFrameImpl::selectRange):
+        (WebKit):
+        (WebKit::WebFrameImpl::moveSelectionStart):
+        (WebKit::WebFrameImpl::moveSelectionEnd):
+        (WebKit::WebFrameImpl::moveCaret):
+        * src/WebFrameImpl.h:
+        (WebFrameImpl):
+        * tests/WebFrameTest.cpp:
+        * tests/data/text_selection.html: Added.
+
 2012-09-06  Robert Kroeger  <[email protected]>
 
         [chromium] Enable different fling behaviour for touchscreen and touchpad

Modified: trunk/Source/WebKit/chromium/public/WebFrame.h (127775 => 127776)


--- trunk/Source/WebKit/chromium/public/WebFrame.h	2012-09-06 19:50:18 UTC (rev 127775)
+++ trunk/Source/WebKit/chromium/public/WebFrame.h	2012-09-06 19:52:07 UTC (rev 127776)
@@ -472,11 +472,30 @@
     // there is ranged selection.
     virtual bool selectWordAroundCaret() = 0;
 
+    // DEPRECATED: Use moveSelectionStart / moveSelectionEnd / moveCaret
+    // This method is intended for touch-based UIs, but it's missing some
+    // functionality needed on Android, like preventing collapsed selections.
     virtual void selectRange(const WebPoint& start, const WebPoint& end) = 0;
 
     virtual void selectRange(const WebRange&) = 0;
 
+    // The methods below are for adjusting the start and/or end of the current
+    // selection by direct manipulation on a touch-based UI. To enter selection
+    // mode in the first place, call selectRange() or send a fake mouse event.
 
+    // Moves the start of the current selection, keeping the end fixed.
+    // Returns true on success, false if there is no selection to modify.
+    virtual bool moveSelectionStart(const WebPoint&, bool allowCollapsedSelection) = 0;
+
+    // Moves the end of the current selection, keeping the start fixed.
+    // Returns true on success, false if there is no selection to modify.
+    virtual bool moveSelectionEnd(const WebPoint&, bool allowCollapsedSelection) = 0;
+
+    // Move both endpoints of the current selection to the given position.
+    // The caret will remain pinned inside the current editable region.
+    // Returns true on success, false if there is no selection or if we're not editing.
+    virtual bool moveCaret(const WebPoint&) = 0;
+
     // Printing ------------------------------------------------------------
 
     // Reformats the WebFrame for printing. WebPrintParams specifies the printable

Modified: trunk/Source/WebKit/chromium/src/WebFrameImpl.cpp (127775 => 127776)


--- trunk/Source/WebKit/chromium/src/WebFrameImpl.cpp	2012-09-06 19:50:18 UTC (rev 127775)
+++ trunk/Source/WebKit/chromium/src/WebFrameImpl.cpp	2012-09-06 19:52:07 UTC (rev 127776)
@@ -170,6 +170,7 @@
 #include "WebSecurityOrigin.h"
 #include "WebViewImpl.h"
 #include "XPathResult.h"
+#include "htmlediting.h"
 #include "markup.h"
 #include "painting/GraphicsContextBuilder.h"
 #include "platform/WebFloatPoint.h"
@@ -1465,24 +1466,69 @@
 
 void WebFrameImpl::selectRange(const WebPoint& start, const WebPoint& end)
 {
-    VisiblePosition startPosition = visiblePositionForWindowPoint(start);
-    VisiblePosition endPosition = visiblePositionForWindowPoint(end);
+    if (start == end && moveCaret(start))
+        return;
 
-    // To correctly handle editable boundaries, we adjust the selection by setting its extent
-    // while keeping its base fixed. For a touch-based UI, this means that moving the selection
-    // handles behaves like a drag-select with the mouse, which is what we want here. If both
-    // endpoints changed, we need to set the extent twice.
-    // FIXME: the WebFrame::SelectRange API should explicitly state which endpoint is moving.
-    VisibleSelection newSelection = frame()->selection()->selection();
-    if (startPosition != newSelection.visibleStart())
-        newSelection = VisibleSelection(newSelection.visibleEnd(), startPosition);
-    if (endPosition != newSelection.visibleEnd())
-        newSelection = VisibleSelection(newSelection.visibleStart(), endPosition);
+    if (moveSelectionStart(start, true) && moveSelectionEnd(end, true))
+        return;
 
+    // Failed to move endpoints, probably because there's no current selection.
+    // Just set the selection explicitly (but this won't handle editable boundaries correctly).
+    VisibleSelection newSelection(visiblePositionForWindowPoint(start), visiblePositionForWindowPoint(end));    
     if (frame()->selection()->shouldChangeSelection(newSelection))
         frame()->selection()->setSelection(newSelection, CharacterGranularity);
 }
 
+bool WebFrameImpl::moveSelectionStart(const WebPoint& point, bool allowCollapsedSelection)
+{
+    const VisibleSelection& selection = frame()->selection()->selection();
+    if (selection.isNone())
+        return false;
+
+    VisiblePosition start = visiblePositionForWindowPoint(point);
+    if (!allowCollapsedSelection) {
+        VisiblePosition maxStart = selection.visibleEnd().previous();
+        if (comparePositions(start, maxStart) > 0)
+            start = maxStart;
+    }
+
+    // start is moving, so base=end, extent=start
+    VisibleSelection newSelection = VisibleSelection(selection.visibleEnd(), start);
+    frame()->selection()->setNonDirectionalSelectionIfNeeded(newSelection, CharacterGranularity);
+    return true;
+}
+
+bool WebFrameImpl::moveSelectionEnd(const WebPoint& point, bool allowCollapsedSelection)
+{
+    const VisibleSelection& selection = frame()->selection()->selection();
+    if (selection.isNone())
+        return false;
+
+    VisiblePosition end = visiblePositionForWindowPoint(point);
+    if (!allowCollapsedSelection) {
+        VisiblePosition minEnd = selection.visibleStart().next();
+        if (comparePositions(end, minEnd) < 0)
+            end = minEnd;
+    }
+
+    // end is moving, so base=start, extent=end
+    VisibleSelection newSelection = VisibleSelection(selection.visibleStart(), end);
+    frame()->selection()->setNonDirectionalSelectionIfNeeded(newSelection, CharacterGranularity);
+    return true;
+}
+
+bool WebFrameImpl::moveCaret(const WebPoint& point)
+{
+    FrameSelection* frameSelection = frame()->selection();
+    if (frameSelection->isNone() || !frameSelection->isContentEditable())
+        return false;
+
+    VisiblePosition pos = visiblePositionForWindowPoint(point);
+    frameSelection->setExtent(pos, UserTriggered);
+    frameSelection->setBase(frameSelection->extent(), UserTriggered);
+    return true;
+}
+
 void WebFrameImpl::selectRange(const WebRange& webRange)
 {
     RefPtr<Range> range = static_cast<PassRefPtr<Range> >(webRange);

Modified: trunk/Source/WebKit/chromium/src/WebFrameImpl.h (127775 => 127776)


--- trunk/Source/WebKit/chromium/src/WebFrameImpl.h	2012-09-06 19:50:18 UTC (rev 127775)
+++ trunk/Source/WebKit/chromium/src/WebFrameImpl.h	2012-09-06 19:52:07 UTC (rev 127776)
@@ -186,6 +186,9 @@
     virtual bool selectWordAroundCaret();
     virtual void selectRange(const WebPoint& start, const WebPoint& end);
     virtual void selectRange(const WebRange&);
+    virtual bool moveSelectionStart(const WebPoint&, bool allowCollapsedSelection);
+    virtual bool moveSelectionEnd(const WebPoint&, bool allowCollapsedSelection);
+    virtual bool moveCaret(const WebPoint&);
     virtual int printBegin(const WebPrintParams&,
                            const WebNode& constrainToNode,
                            bool* useBrowserOverlays);

Modified: trunk/Source/WebKit/chromium/tests/WebFrameTest.cpp (127775 => 127776)


--- trunk/Source/WebKit/chromium/tests/WebFrameTest.cpp	2012-09-06 19:50:18 UTC (rev 127775)
+++ trunk/Source/WebKit/chromium/tests/WebFrameTest.cpp	2012-09-06 19:52:07 UTC (rev 127776)
@@ -990,10 +990,11 @@
     webView->close();
 }
 
-static WebView* selectRangeTestCreateWebView(const std::string& url)
+static WebView* createWebViewForTextSelection(const std::string& url)
 {
     WebView* webView = FrameTestHelpers::createWebViewAndLoad(url, true);
     webView->settings()->setDefaultFontSize(12);
+    webView->enableFixedLayoutMode(false);
     webView->resize(WebSize(640, 480));
     return webView;
 }
@@ -1012,6 +1013,11 @@
     return WebPoint(rect.x + rect.width - 1, rect.y + rect.height - 1);
 }
 
+static WebRect elementBounds(WebFrame* frame, const WebString& id)
+{
+    return frame->document().getElementById(id).boundsInViewportSpace();
+}
+
 static std::string selectionAsString(WebFrame* frame)
 {
     return std::string(frame->selectionAsText().utf8().data());
@@ -1029,7 +1035,7 @@
     registerMockedHttpURLLoad("select_range_iframe.html");
     registerMockedHttpURLLoad("select_range_editable.html");
 
-    webView = selectRangeTestCreateWebView(m_baseURL + "select_range_basic.html");
+    webView = createWebViewForTextSelection(m_baseURL + "select_range_basic.html");
     frame = webView->mainFrame();
     EXPECT_EQ("Some test text for testing.", selectionAsString(frame));
     webView->selectionBounds(startWebRect, endWebRect);
@@ -1039,7 +1045,7 @@
     EXPECT_EQ("Some test text for testing.", selectionAsString(frame));
     webView->close();
 
-    webView = selectRangeTestCreateWebView(m_baseURL + "select_range_scroll.html");
+    webView = createWebViewForTextSelection(m_baseURL + "select_range_scroll.html");
     frame = webView->mainFrame();
     EXPECT_EQ("Some offscreen test text for testing.", selectionAsString(frame));
     webView->selectionBounds(startWebRect, endWebRect);
@@ -1049,7 +1055,7 @@
     EXPECT_EQ("Some offscreen test text for testing.", selectionAsString(frame));
     webView->close();
 
-    webView = selectRangeTestCreateWebView(m_baseURL + "select_range_iframe.html");
+    webView = createWebViewForTextSelection(m_baseURL + "select_range_iframe.html");
     frame = webView->mainFrame();
     WebFrame* subframe = frame->findChildByExpression(WebString::fromUTF8("/html/body/iframe"));
     EXPECT_EQ("Some test text for testing.", selectionAsString(subframe));
@@ -1062,7 +1068,7 @@
 
     // Select the middle of an editable element, then try to extend the selection to the top of the document.
     // The selection range should be clipped to the bounds of the editable element.
-    webView = selectRangeTestCreateWebView(m_baseURL + "select_range_editable.html");
+    webView = createWebViewForTextSelection(m_baseURL + "select_range_editable.html");
     frame = webView->mainFrame();
     EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
     webView->selectionBounds(startWebRect, endWebRect);
@@ -1071,7 +1077,7 @@
     webView->close();
 
     // As above, but extending the selection to the bottom of the document.
-    webView = selectRangeTestCreateWebView(m_baseURL + "select_range_editable.html");
+    webView = createWebViewForTextSelection(m_baseURL + "select_range_editable.html");
     frame = webView->mainFrame();
     EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
     webView->selectionBounds(startWebRect, endWebRect);
@@ -1080,6 +1086,176 @@
     webView->close();
 }
 
+TEST_F(WebFrameTest, MoveSelectionStart)
+{
+    registerMockedHttpURLLoad("text_selection.html");
+    WebView* webView = createWebViewForTextSelection(m_baseURL + "text_selection.html");
+    WebFrame* frame = webView->mainFrame();
+
+    // moveSelectionStart() always returns false if there's no selection.
+    EXPECT_FALSE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), false));
+    EXPECT_FALSE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), true));
+
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "header_2")), false));
+    EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame));
+
+    // Select second span. We can move the start to include the first span.
+    frame->executeScript(WebScriptSource("selectElement('header_2');"));
+    EXPECT_EQ("Header 2.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), false));
+    EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame));
+
+    // If allowCollapsedSelection=false we can't move the selection start beyond the current end.
+    // We end up with a single character selected.
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionStart(bottomRightMinusOne(elementBounds(frame, "header_1")), false));
+    EXPECT_EQ(".", selectionAsString(frame));
+
+    // If allowCollapsedSelection=true we can move the start and end together.
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionStart(bottomRightMinusOne(elementBounds(frame, "header_1")), true));
+    EXPECT_EQ("", selectionAsString(frame));
+    // Selection is a caret, not empty.
+    EXPECT_FALSE(frame->selectionRange().isNull());
+    EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_1")), true));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+
+    // If allowCollapsedSelection=true we can move the start across the end.
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionStart(bottomRightMinusOne(elementBounds(frame, "header_2")), true));
+    EXPECT_EQ(" Header 2.", selectionAsString(frame));
+
+    // Can't extend the selection part-way into an editable element.
+    frame->executeScript(WebScriptSource("selectElement('footer_2');"));
+    EXPECT_EQ("Footer 2.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "editable_2")), true));
+    EXPECT_EQ(" [ Footer 1. Footer 2.", selectionAsString(frame));
+
+    // Can extend the selection completely across editable elements.
+    frame->executeScript(WebScriptSource("selectElement('footer_2');"));
+    EXPECT_EQ("Footer 2.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_2")), true));
+    EXPECT_EQ("Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1. Footer 2.", selectionAsString(frame));
+
+    // If the selection is editable text, we can't extend it into non-editable text.
+    frame->executeScript(WebScriptSource("selectElement('editable_2');"));
+    EXPECT_EQ("Editable 2.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "header_2")), true));
+    EXPECT_EQ("[ Editable 1. Editable 2.", selectionAsString(frame));
+
+    webView->close();
+}
+
+TEST_F(WebFrameTest, MoveSelectionEnd)
+{
+    registerMockedHttpURLLoad("text_selection.html");
+    WebView* webView = createWebViewForTextSelection(m_baseURL + "text_selection.html");
+    WebFrame* frame = webView->mainFrame();
+
+    // moveSelectionEnd() always returns false if there's no selection.
+    EXPECT_FALSE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_1")), false));
+    EXPECT_FALSE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_1")), true));
+
+    // Select first span. We can move the end to include the second span.
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "header_2")), false));
+    EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame));
+
+    // If allowCollapsedSelection=false we can't move the selection end beyond the current start.
+    // We end up with a single character selected.
+    frame->executeScript(WebScriptSource("selectElement('header_2');"));
+    EXPECT_EQ("Header 2.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_2")), false));
+    EXPECT_EQ("H", selectionAsString(frame));
+
+    // If allowCollapsedSelection=true we can move the start and end together.
+    frame->executeScript(WebScriptSource("selectElement('header_2');"));
+    EXPECT_EQ("Header 2.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_2")), true));
+    EXPECT_EQ("", selectionAsString(frame));
+    // Selection is a caret, not empty.
+    EXPECT_FALSE(frame->selectionRange().isNull());
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "header_2")), true));
+    EXPECT_EQ("Header 2.", selectionAsString(frame));
+
+    // If allowCollapsedSelection=true we can move the end across the start.
+    frame->executeScript(WebScriptSource("selectElement('header_2');"));
+    EXPECT_EQ("Header 2.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(topLeft(elementBounds(frame, "header_1")), true));
+    EXPECT_EQ("Header 1. ", selectionAsString(frame));
+
+    // Can't extend the selection part-way into an editable element.
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "editable_1")), true));
+    EXPECT_EQ("Header 1. Header 2. ] ", selectionAsString(frame));
+
+    // Can extend the selection completely across editable elements.
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "footer_1")), true));
+    EXPECT_EQ("Header 1. Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1.", selectionAsString(frame));
+
+    // If the selection is editable text, we can't extend it into non-editable text.
+    frame->executeScript(WebScriptSource("selectElement('editable_1');"));
+    EXPECT_EQ("Editable 1.", selectionAsString(frame));
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "footer_1")), true));
+    EXPECT_EQ("Editable 1. Editable 2. ]", selectionAsString(frame));
+
+    webView->close();
+}
+
+TEST_F(WebFrameTest, MoveCaret)
+{
+    registerMockedHttpURLLoad("text_selection.html");
+    WebView* webView = createWebViewForTextSelection(m_baseURL + "text_selection.html");
+    WebFrame* frame = webView->mainFrame();
+
+    // moveCaret() returns false if there's no selection, or if it isn't editable.
+    EXPECT_FALSE(frame->moveCaret(topLeft(elementBounds(frame, "editable"))));
+    frame->executeScript(WebScriptSource("selectElement('header_1');"));
+    EXPECT_EQ("Header 1.", selectionAsString(frame));
+    EXPECT_FALSE(frame->moveCaret(topLeft(elementBounds(frame, "editable"))));
+
+    // Select the editable text span. Now moveCaret() works.
+    frame->executeScript(WebScriptSource("selectElement('editable_1');"));
+    EXPECT_EQ("Editable 1.", selectionAsString(frame));
+
+    EXPECT_TRUE(frame->moveCaret(topLeft(elementBounds(frame, "editable_1"))));
+    EXPECT_EQ("", selectionAsString(frame));
+    EXPECT_FALSE(frame->selectionRange().isNull());
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "editable_1")), false));
+    EXPECT_EQ("Editable 1.", selectionAsString(frame));
+
+    EXPECT_TRUE(frame->moveCaret(bottomRightMinusOne(elementBounds(frame, "editable_2"))));
+    EXPECT_EQ("", selectionAsString(frame));
+    EXPECT_FALSE(frame->selectionRange().isNull());
+    EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "editable_2")), false));
+    EXPECT_EQ("Editable 2.", selectionAsString(frame));
+
+    // Caret is pinned at the start of the editable region.
+    EXPECT_TRUE(frame->moveCaret(topLeft(elementBounds(frame, "header_1"))));
+    EXPECT_EQ("", selectionAsString(frame));
+    EXPECT_FALSE(frame->selectionRange().isNull());
+    EXPECT_TRUE(frame->moveSelectionEnd(bottomRightMinusOne(elementBounds(frame, "editable_1")), false));
+    EXPECT_EQ("[ Editable 1.", selectionAsString(frame));
+
+    // Caret is pinned at the end of the editable region.
+    EXPECT_TRUE(frame->moveCaret(bottomRightMinusOne(elementBounds(frame, "footer_2"))));
+    EXPECT_EQ("", selectionAsString(frame));
+    EXPECT_FALSE(frame->selectionRange().isNull());
+    EXPECT_TRUE(frame->moveSelectionStart(topLeft(elementBounds(frame, "editable_2")), false));
+    EXPECT_EQ("Editable 2. ]", selectionAsString(frame));
+
+    webView->close();
+}
+
 class DisambiguationPopupTestWebViewClient : public WebViewClient {
 public:
     virtual bool didTapMultipleTargets(const WebGestureEvent&, const WebVector<WebRect>& targetRects) OVERRIDE

Added: trunk/Source/WebKit/chromium/tests/data/text_selection.html (0 => 127776)


--- trunk/Source/WebKit/chromium/tests/data/text_selection.html	                        (rev 0)
+++ trunk/Source/WebKit/chromium/tests/data/text_selection.html	2012-09-06 19:52:07 UTC (rev 127776)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<span id="header">[
+<span id="header_1">Header 1.</span>
+<span id="header_2">Header 2.</span>
+]</span>
+
+<span id="editable" contenteditable="true">[
+<span id="editable_1">Editable 1.</span>
+<span id="editable_2">Editable 2.</span>
+]</span>
+
+<span id="footer">[
+<span id="footer_1">Footer 1.</span>
+<span id="footer_2">Footer 2.</span>
+]</span>
+
+<script>
+function selectElement(id) {
+  var element = document.getElementById(id);
+  var range = document.createRange();
+  range.selectNode(document.getElementById(id));
+  window.getSelection().removeAllRanges();
+  window.getSelection().addRange(range);
+}
+</script>
+</body>
+</html>
+
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to