Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / tests / WebViewTest.cpp
index af2752f..817e82b 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
+#include "core/editing/FrameSelection.h"
+#include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLTextAreaElement.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/page/Chrome.h"
+#include "core/page/Page.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderView.h"
 #include "platform/KeyboardCodes.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/graphics/Color.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebClipboard.h"
 #include "public/platform/WebDragData.h"
 #include "public/platform/WebSize.h"
 #include "public/platform/WebThread.h"
@@ -62,6 +66,7 @@
 #include "public/web/WebFrameClient.h"
 #include "public/web/WebHitTestResult.h"
 #include "public/web/WebInputEvent.h"
+#include "public/web/WebScriptSource.h"
 #include "public/web/WebSettings.h"
 #include "public/web/WebViewClient.h"
 #include "public/web/WebWidget.h"
@@ -213,6 +218,21 @@ protected:
     FrameTestHelpers::WebViewHelper m_webViewHelper;
 };
 
+TEST_F(WebViewTest, CopyImageAt)
+{
+    std::string url = m_baseURL + "canvas-copy-image.html";
+    URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");
+    WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0);
+    webView->resize(WebSize(400, 400));
+    webView->copyImageAt(WebPoint(50, 50));
+
+    blink::WebData data = blink::Platform::current()->clipboard()->readImage(blink::WebClipboard::Buffer());
+    blink::WebImage image = blink::WebImage::fromData(data, WebSize());
+
+    SkAutoLockPixels autoLock(image.getSkBitmap());
+    EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
+};
+
 TEST_F(WebViewTest, SetBaseBackgroundColor)
 {
     const WebColor kWhite    = 0xFFFFFFFF;
@@ -244,21 +264,22 @@ TEST_F(WebViewTest, SetBaseBackgroundColor)
     // Expected: transparent on top of kTransparent will still be transparent.
     EXPECT_EQ(kTransparent, webView->backgroundColor());
 
-    WebCore::LocalFrame* frame = webView->mainFrameImpl()->frame();
+    blink::LocalFrame* frame = webView->mainFrameImpl()->frame();
 
     // Creating a new frame view with the background color having 0 alpha.
-    frame->createView(WebCore::IntSize(1024, 768), WebCore::Color::transparent, true);
+    frame->createView(blink::IntSize(1024, 768), blink::Color::transparent, true);
     EXPECT_EQ(kTransparent, frame->view()->baseBackgroundColor());
 
-    WebCore::Color kTransparentRed(100, 0, 0, 0);
-    frame->createView(WebCore::IntSize(1024, 768), kTransparentRed, true);
+    blink::Color kTransparentRed(100, 0, 0, 0);
+    frame->createView(blink::IntSize(1024, 768), kTransparentRed, true);
     EXPECT_EQ(kTransparentRed, frame->view()->baseBackgroundColor());
 }
 
 TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame)
 {
     const WebColor kBlue = 0xFF0000FF;
-    WebView* webView = WebViewImpl::create(0);
+    FrameTestHelpers::TestWebViewClient webViewClient;
+    WebView* webView = WebViewImpl::create(&webViewClient);
     EXPECT_NE(kBlue, webView->backgroundColor());
     // webView does not have a frame yet, but we should still be able to set the background color.
     webView->setBaseBackgroundColor(kBlue);
@@ -288,19 +309,19 @@ TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
     SkCanvas canvas(bitmap);
     canvas.clear(kAlphaRed);
 
-    WebCore::GraphicsContext context(&canvas);
+    blink::GraphicsContext context(&canvas);
 
     // Paint the root of the main frame in the way that CompositedLayerMapping would.
-    WebCore::FrameView* view = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
-    WebCore::RenderLayer* rootLayer = view->renderView()->layer();
-    WebCore::IntRect paintRect(0, 0, kWidth, kHeight);
-    WebCore::LayerPaintingInfo paintingInfo(rootLayer, paintRect, WebCore::PaintBehaviorNormal, WebCore::LayoutSize());
-    rootLayer->paintLayerContents(&context, paintingInfo, WebCore::PaintLayerPaintingCompositingAllPhases);
+    blink::FrameView* view = m_webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
+    blink::RenderLayer* rootLayer = view->renderView()->layer();
+    blink::IntRect paintRect(0, 0, kWidth, kHeight);
+    blink::LayerPaintingInfo paintingInfo(rootLayer, paintRect, blink::PaintBehaviorNormal, blink::LayoutSize());
+    rootLayer->paintLayerContents(&context, paintingInfo, blink::PaintLayerPaintingCompositingAllPhases);
 
     // The result should be a blend of red and green.
     SkColor color = bitmap.getColor(kWidth / 2, kHeight / 2);
-    EXPECT_TRUE(WebCore::redChannel(color));
-    EXPECT_TRUE(WebCore::greenChannel(color));
+    EXPECT_TRUE(blink::redChannel(color));
+    EXPECT_TRUE(blink::greenChannel(color));
 }
 
 TEST_F(WebViewTest, FocusIsInactive)
@@ -313,7 +334,7 @@ TEST_F(WebViewTest, FocusIsInactive)
     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
 
-    WebCore::HTMLDocument* document = WebCore::toHTMLDocument(frame->frame()->document());
+    blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
     EXPECT_TRUE(document->hasFocus());
     webView->setFocus(false);
     webView->setIsActive(false);
@@ -357,14 +378,14 @@ TEST_F(WebViewTest, HitTestResultAtWithPageScale)
     // Image is at top left quandrant, so should not hit it.
     WebHitTestResult negativeResult = webView->hitTestResultAt(hitPoint);
     ASSERT_EQ(WebNode::ElementNode, negativeResult.node().nodeType());
-    EXPECT_FALSE(negativeResult.node().to<WebElement>().hasTagName("img"));
+    EXPECT_FALSE(negativeResult.node().to<WebElement>().hasHTMLTagName("img"));
     negativeResult.reset();
 
     // Scale page up 2x so image should occupy the whole viewport.
     webView->setPageScaleFactor(2.0f);
     WebHitTestResult positiveResult = webView->hitTestResultAt(hitPoint);
     ASSERT_EQ(WebNode::ElementNode, positiveResult.node().nodeType());
-    EXPECT_TRUE(positiveResult.node().to<WebElement>().hasTagName("img"));
+    EXPECT_TRUE(positiveResult.node().to<WebElement>().hasHTMLTagName("img"));
     positiveResult.reset();
 }
 
@@ -380,7 +401,7 @@ void WebViewTest::testAutoResize(const WebSize& minAutoResize, const WebSize& ma
     client.testData().setWebView(webView);
 
     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
-    WebCore::FrameView* frameView = frame->frame()->view();
+    blink::FrameView* frameView = frame->frame()->view();
     frameView->layout();
     EXPECT_FALSE(frameView->layoutPending());
     EXPECT_FALSE(frameView->needsLayout());
@@ -804,7 +825,7 @@ TEST_F(WebViewTest, HistoryResetScrollAndScaleState)
     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
-    WebCore::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
+    blink::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
     mainFrameLocal->loader().saveScrollState();
     EXPECT_EQ(2.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
     EXPECT_EQ(116, mainFrameLocal->loader().currentItem()->scrollPoint().x());
@@ -831,25 +852,25 @@ TEST_F(WebViewTest, BackForwardRestoreScroll)
 
     // Emulate a user scroll
     webViewImpl->setMainFrameScrollOffset(WebPoint(0, 900));
-    WebCore::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
-    RefPtr<WebCore::HistoryItem> item1 = mainFrameLocal->loader().currentItem();
+    blink::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
+    RefPtr<blink::HistoryItem> item1 = mainFrameLocal->loader().currentItem();
 
     // Click an anchor
-    mainFrameLocal->loader().load(WebCore::FrameLoadRequest(mainFrameLocal->document(), WebCore::ResourceRequest(mainFrameLocal->document()->completeURL("#a"))));
-    RefPtr<WebCore::HistoryItem> item2 = mainFrameLocal->loader().currentItem();
+    mainFrameLocal->loader().load(blink::FrameLoadRequest(mainFrameLocal->document(), blink::ResourceRequest(mainFrameLocal->document()->completeURL("#a"))));
+    RefPtr<blink::HistoryItem> item2 = mainFrameLocal->loader().currentItem();
 
     // Go back, then forward, then back again.
-    mainFrameLocal->loader().loadHistoryItem(item1.get(), WebCore::HistorySameDocumentLoad);
-    mainFrameLocal->loader().loadHistoryItem(item2.get(), WebCore::HistorySameDocumentLoad);
-    mainFrameLocal->loader().loadHistoryItem(item1.get(), WebCore::HistorySameDocumentLoad);
+    mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
+    mainFrameLocal->loader().loadHistoryItem(item2.get(), blink::HistorySameDocumentLoad);
+    mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
 
     // Click a different anchor
-    mainFrameLocal->loader().load(WebCore::FrameLoadRequest(mainFrameLocal->document(), WebCore::ResourceRequest(mainFrameLocal->document()->completeURL("#b"))));
-    RefPtr<WebCore::HistoryItem> item3 = mainFrameLocal->loader().currentItem();
+    mainFrameLocal->loader().load(blink::FrameLoadRequest(mainFrameLocal->document(), blink::ResourceRequest(mainFrameLocal->document()->completeURL("#b"))));
+    RefPtr<blink::HistoryItem> item3 = mainFrameLocal->loader().currentItem();
 
     // Go back, then forward. The scroll position should be properly set on the forward navigation.
-    mainFrameLocal->loader().loadHistoryItem(item1.get(), WebCore::HistorySameDocumentLoad);
-    mainFrameLocal->loader().loadHistoryItem(item3.get(), WebCore::HistorySameDocumentLoad);
+    mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
+    mainFrameLocal->loader().loadHistoryItem(item3.get(), blink::HistorySameDocumentLoad);
     EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
     EXPECT_GT(webViewImpl->mainFrame()->scrollOffset().height, 2000);
 }
@@ -879,7 +900,7 @@ TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
     EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
     EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
 
-    RefPtrWillBeRawPtr<WebCore::Element> element = static_cast<PassRefPtrWillBeRawPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().body());
+    RefPtrWillBeRawPtr<blink::Element> element = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webViewImpl->mainFrame()->document().body());
     webViewImpl->enterFullScreenForElement(element.get());
     webViewImpl->willEnterFullScreen();
     webViewImpl->didEnterFullScreen();
@@ -889,7 +910,7 @@ TEST_F(WebViewTest, EnterFullscreenResetScrollAndScaleState)
     EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
 
     // Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
-    RefPtrWillBeRawPtr<WebCore::Element> otherElement = static_cast<PassRefPtrWillBeRawPtr<WebCore::Element> >(webViewImpl->mainFrame()->document().head());
+    RefPtrWillBeRawPtr<blink::Element> otherElement = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webViewImpl->mainFrame()->document().head());
     webViewImpl->enterFullScreenForElement(otherElement.get());
 
     // Confirm that exiting fullscreen restores the parameters.
@@ -928,7 +949,7 @@ TEST_F(WebViewTest, PrintWithXHRInFlight)
     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("print_with_xhr_inflight.html"));
     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "print_with_xhr_inflight.html", true, 0, &client);
 
-    ASSERT_EQ(WebCore::FrameStateComplete, toLocalFrame(webViewImpl->page()->mainFrame())->loader().state());
+    ASSERT_EQ(blink::FrameStateComplete, toLocalFrame(webViewImpl->page()->mainFrame())->loader().state());
     EXPECT_TRUE(client.printCalled());
     m_webViewHelper.reset();
 }
@@ -1038,12 +1059,12 @@ private:
 static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
 {
     ASSERT(webView);
-    RefPtrWillBeRawPtr<WebCore::Element> element = static_cast<PassRefPtrWillBeRawPtr<WebCore::Element> >(webView->mainFrame()->document().getElementById(id));
+    RefPtrWillBeRawPtr<blink::Element> element = static_cast<PassRefPtrWillBeRawPtr<blink::Element> >(webView->mainFrame()->document().getElementById(id));
     if (!element)
         return false;
 
     element->scrollIntoViewIfNeeded();
-    WebCore::IntPoint center = element->screenRect().center();
+    blink::IntPoint center = element->screenRect().center();
 
     WebGestureEvent event;
     event.type = type;
@@ -1150,6 +1171,29 @@ TEST_F(WebViewTest, LongPressSelection)
     EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
     EXPECT_EQ("testword", std::string(frame->selectionAsText().utf8().data()));
 }
+
+TEST_F(WebViewTest, BlinkCaretOnTypingAfterLongPress)
+{
+    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("blink_caret_on_typing_after_long_press.html"));
+
+    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "blink_caret_on_typing_after_long_press.html", true);
+    webView->resize(WebSize(640, 480));
+    webView->layout();
+    runPendingTasks();
+
+    WebString target = WebString::fromUTF8("target");
+    WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webView->mainFrame());
+
+    EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, target));
+    EXPECT_TRUE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
+
+    WebKeyboardEvent keyEvent;
+    keyEvent.type = WebInputEvent::RawKeyDown;
+    webView->handleInputEvent(keyEvent);
+    keyEvent.type = WebInputEvent::KeyUp;
+    webView->handleInputEvent(keyEvent);
+    EXPECT_FALSE(mainFrame->frame()->selection().isCaretBlinkingSuspended());
+}
 #endif
 
 TEST_F(WebViewTest, SelectionOnDisabledInput)
@@ -1404,7 +1448,7 @@ TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
     // Make a request that will open a new window
     WebURLRequest webURLRequest;
     webURLRequest.initialize();
-    WebCore::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
+    blink::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
     toLocalFrame(webViewImpl->page()->mainFrame())->loader().load(request);
     ASSERT_TRUE(client.createdWebView());
     EXPECT_FALSE(client.didFocusCalled());
@@ -1412,7 +1456,7 @@ TEST_F(WebViewTest, FocusExistingFrameOnNavigate)
     // Make a request from the new window that will navigate the original window. The original window should be focused.
     WebURLRequest webURLRequestWithTargetStart;
     webURLRequestWithTargetStart.initialize();
-    WebCore::FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
+    blink::FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
     toLocalFrame(toWebViewImpl(client.createdWebView())->page()->mainFrame())->loader().load(requestWithTargetStart);
     EXPECT_TRUE(client.didFocusCalled());
 
@@ -1446,12 +1490,12 @@ TEST_F(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus)
 }
 
 #if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
-static void openDateTimeChooser(WebView* webView, WebCore::HTMLInputElement* inputElement)
+static void openDateTimeChooser(WebView* webView, blink::HTMLInputElement* inputElement)
 {
     inputElement->focus();
 
     WebKeyboardEvent keyEvent;
-    keyEvent.windowsKeyCode = WebCore::VKEY_SPACE;
+    keyEvent.windowsKeyCode = blink::VKEY_SPACE;
     keyEvent.type = WebInputEvent::RawKeyDown;
     keyEvent.setKeyIdentifierFromWindowsKeyCode();
     webView->handleInputEvent(keyEvent);
@@ -1467,9 +1511,9 @@ TEST_F(WebViewTest, ChooseValueFromDateTimeChooser)
     URLTestHelpers::registerMockedURLLoad(toKURL(url), "date_time_chooser.html");
     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
 
-    WebCore::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
+    blink::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
 
-    WebCore::HTMLInputElement* inputElement;
+    blink::HTMLInputElement* inputElement;
 
     inputElement = toHTMLInputElement(document->getElementById("date"));
     openDateTimeChooser(webViewImpl, inputElement);
@@ -1580,6 +1624,23 @@ TEST_F(WebViewTest, SmartClipData)
     EXPECT_STREQ(kExpectedClipHtml, clipHtml.utf8().c_str());
 }
 
+TEST_F(WebViewTest, SmartClipReturnsEmptyStringsWhenUserSelectIsNone)
+{
+    WebString clipText;
+    WebString clipHtml;
+    WebRect clipRect;
+    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("Ahem.ttf"));
+    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("smartclip_user_select_none.html"));
+    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip_user_select_none.html");
+    webView->setPageScaleFactorLimits(1, 1);
+    webView->resize(WebSize(500, 500));
+    webView->layout();
+    WebRect cropRect(0, 0, 100, 100);
+    webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
+    EXPECT_STREQ("", clipText.utf8().c_str());
+    EXPECT_STREQ("", clipHtml.utf8().c_str());
+}
+
 class CreateChildCounterFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
     CreateChildCounterFrameClient() : m_count(0) { }
@@ -1661,15 +1722,17 @@ private:
     int m_hasTouchEventHandlerCount[2];
 };
 
-// This test verifies that WebWidgetClient::hasTouchEventHandlers is called accordingly for various
-// calls to Document::did{Add|Remove|Clear}TouchEventHandler. Verifying that those calls are made
-// correctly is the job of LayoutTests/fast/events/touch/touch-handler-count.html.
+// This test verifies that WebWidgetClient::hasTouchEventHandlers is called
+// accordingly for various calls to EventHandlerRegistry::did{Add|Remove|
+// RemoveAll}EventHandler(..., TouchEvent). Verifying that those calls are made
+// correctly is the job of LayoutTests/fast/events/event-handler-count.html.
 TEST_F(WebViewTest, HasTouchEventHandlers)
 {
     TouchEventHandlerWebViewClient client;
     std::string url = m_baseURL + "has_touch_event_handlers.html";
     URLTestHelpers::registerMockedURLLoad(toKURL(url), "has_touch_event_handlers.html");
     WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
+    const blink::EventHandlerRegistry::EventHandlerClass touchEvent = blink::EventHandlerRegistry::TouchEvent;
 
     // The page is initialized with at least one no-handlers call.
     // In practice we get two such calls because WebViewHelper::initializeAndLoad first
@@ -1679,101 +1742,102 @@ TEST_F(WebViewTest, HasTouchEventHandlers)
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding the first document handler results in a has-handlers call.
-    WebCore::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
-    document->didAddTouchEventHandler(document);
+    blink::Document* document = webViewImpl->mainFrameImpl()->frame()->document();
+    blink::EventHandlerRegistry* registry = &document->frameHost()->eventHandlerRegistry();
+    registry->didAddEventHandler(*document, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding another handler has no effect.
-    document->didAddTouchEventHandler(document);
+    registry->didAddEventHandler(*document, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Removing the duplicate handler has no effect.
-    document->didRemoveTouchEventHandler(document);
+    registry->didRemoveEventHandler(*document, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Removing the final handler results in a no-handlers call.
-    document->didRemoveTouchEventHandler(document);
+    registry->didRemoveEventHandler(*document, touchEvent);
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding a handler on a div results in a has-handlers call.
-    WebCore::Element* parentDiv = document->getElementById("parentdiv");
+    blink::Element* parentDiv = document->getElementById("parentdiv");
     ASSERT(parentDiv);
-    document->didAddTouchEventHandler(parentDiv);
+    registry->didAddEventHandler(*parentDiv, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding a duplicate handler on the div, clearing all document handlers
     // (of which there are none) and removing the extra handler on the div
     // all have no effect.
-    document->didAddTouchEventHandler(parentDiv);
-    document->didClearTouchEventHandlers(document);
-    document->didRemoveTouchEventHandler(parentDiv);
+    registry->didAddEventHandler(*parentDiv, touchEvent);
+    registry->didRemoveAllEventHandlers(*document);
+    registry->didRemoveEventHandler(*parentDiv, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Removing the final handler on the div results in a no-handlers call.
-    document->didRemoveTouchEventHandler(parentDiv);
+    registry->didRemoveEventHandler(*parentDiv, touchEvent);
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding two handlers then clearing them in a single call results in a
     // has-handlers then no-handlers call.
-    document->didAddTouchEventHandler(parentDiv);
+    registry->didAddEventHandler(*parentDiv, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
-    document->didAddTouchEventHandler(parentDiv);
+    registry->didAddEventHandler(*parentDiv, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
-    document->didClearTouchEventHandlers(parentDiv);
+    registry->didRemoveAllEventHandlers(*parentDiv);
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding a handler inside of a child iframe results in a has-handlers call.
-    WebCore::Element* childFrame = document->getElementById("childframe");
+    blink::Element* childFrame = document->getElementById("childframe");
     ASSERT(childFrame);
-    WebCore::Document* childDocument = toHTMLIFrameElement(childFrame)->contentDocument();
-    WebCore::Element* childDiv = childDocument->getElementById("childdiv");
+    blink::Document* childDocument = toHTMLIFrameElement(childFrame)->contentDocument();
+    blink::Element* childDiv = childDocument->getElementById("childdiv");
     ASSERT(childDiv);
-    childDocument->didAddTouchEventHandler(childDiv);
+    registry->didAddEventHandler(*childDiv, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding and clearing handlers in the parent doc or elsewhere in the child doc
     // has no impact.
-    document->didAddTouchEventHandler(document);
-    document->didAddTouchEventHandler(childFrame);
-    childDocument->didAddTouchEventHandler(childDocument);
-    document->didClearTouchEventHandlers(document);
-    document->didClearTouchEventHandlers(childFrame);
-    childDocument->didClearTouchEventHandlers(childDocument);
+    registry->didAddEventHandler(*document, touchEvent);
+    registry->didAddEventHandler(*childFrame, touchEvent);
+    registry->didAddEventHandler(*childDocument, touchEvent);
+    registry->didRemoveAllEventHandlers(*document);
+    registry->didRemoveAllEventHandlers(*childFrame);
+    registry->didRemoveAllEventHandlers(*childDocument);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Removing the final handler inside the child frame results in a no-handlers call.
-    childDocument->didRemoveTouchEventHandler(childDiv);
+    registry->didRemoveAllEventHandlers(*childDiv);
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding a handler inside the child frame results in a has-handlers call.
-    childDocument->didAddTouchEventHandler(childDocument);
+    registry->didAddEventHandler(*childDocument, touchEvent);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Adding a handler in the parent document and removing the one in the frame
     // has no effect.
-    document->didAddTouchEventHandler(childFrame);
-    childDocument->didRemoveTouchEventHandler(childDocument);
-    childDocument->didClearTouchEventHandlers(childDocument);
-    document->didClearTouchEventHandlers(document);
+    registry->didAddEventHandler(*childFrame, touchEvent);
+    registry->didRemoveEventHandler(*childDocument, touchEvent);
+    registry->didRemoveAllEventHandlers(*childDocument);
+    registry->didRemoveAllEventHandlers(*document);
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
     // Now removing the handler in the parent document results in a no-handlers call.
-    document->didRemoveTouchEventHandler(childFrame);
+    registry->didRemoveEventHandler(*childFrame, touchEvent);
     EXPECT_EQ(1, client.getAndResetHasTouchEventHandlerCallCount(false));
     EXPECT_EQ(0, client.getAndResetHasTouchEventHandlerCallCount(true));
 
@@ -1781,17 +1845,46 @@ TEST_F(WebViewTest, HasTouchEventHandlers)
     m_webViewHelper.reset();
 }
 
-static WebRect ExpectedRootBounds(WebCore::Document* document, float scaleFactor)
+// This test checks that deleting nodes which have only non-JS-registered touch
+// handlers also removes them from the event handler registry. Note that this
+// is different from detaching and re-attaching the same node, which is covered
+// by layout tests under fast/events/.
+TEST_F(WebViewTest, DeleteElementWithRegisteredHandler)
+{
+    std::string url = m_baseURL + "simple_div.html";
+    URLTestHelpers::registerMockedURLLoad(toKURL(url), "simple_div.html");
+    WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true);
+
+    RefPtrWillBePersistent<blink::Document> document = webViewImpl->mainFrameImpl()->frame()->document();
+    blink::Element* div = document->getElementById("div");
+    blink::EventHandlerRegistry& registry = document->frameHost()->eventHandlerRegistry();
+
+    registry.didAddEventHandler(*div, blink::EventHandlerRegistry::ScrollEvent);
+    EXPECT_TRUE(registry.hasEventHandlers(blink::EventHandlerRegistry::ScrollEvent));
+
+    blink::TrackExceptionState exceptionState;
+    div->remove(exceptionState);
+#if ENABLE(OILPAN)
+    // For oilpan we have to force a GC to ensure the event handlers have been removed when
+    // checking below. We do a precise GC (collectAllGarbage does not scan the stack)
+    // to ensure the div element dies. This is also why the Document is in a Persistent
+    // since we want that to stay around.
+    Heap::collectAllGarbage();
+#endif
+    EXPECT_FALSE(registry.hasEventHandlers(blink::EventHandlerRegistry::ScrollEvent));
+}
+
+static WebRect ExpectedRootBounds(blink::Document* document, float scaleFactor)
 {
-    WebCore::Element* element = document->getElementById("root");
+    blink::Element* element = document->getElementById("root");
     if (!element)
         element = document->getElementById("target");
-    if (element->hasTagName(WebCore::HTMLNames::iframeTag))
+    if (element->hasTagName(blink::HTMLNames::iframeTag))
         return ExpectedRootBounds(toHTMLIFrameElement(element)->contentDocument(), scaleFactor);
 
-    WebCore::IntRect boundingBox;
-    if (element->hasTagName(WebCore::HTMLNames::htmlTag))
-        boundingBox = WebCore::IntRect(WebCore::IntPoint(0, 0), document->frame()->view()->contentsSize());
+    blink::IntRect boundingBox;
+    if (element->hasTagName(blink::HTMLNames::htmlTag))
+        boundingBox = blink::IntRect(blink::IntPoint(0, 0), document->frame()->view()->contentsSize());
     else
         boundingBox = element->pixelSnappedBoundingBox();
     boundingBox = document->frame()->view()->contentsToWindow(boundingBox);
@@ -1811,7 +1904,7 @@ void WebViewTest::testSelectionRootBounds(const char* htmlFile, float pageScaleF
 
     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
     EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
-    WebCore::HTMLDocument* document = WebCore::toHTMLDocument(frame->frame()->document());
+    blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
 
     WebRect expectedRootBounds = ExpectedRootBounds(document, webView->pageScaleFactor());
     WebRect actualRootBounds;
@@ -1820,7 +1913,7 @@ void WebViewTest::testSelectionRootBounds(const char* htmlFile, float pageScaleF
 
     WebRect anchor, focus;
     webView->selectionBounds(anchor, focus);
-    WebCore::IntRect expectedIntRect = expectedRootBounds;
+    blink::IntRect expectedIntRect = expectedRootBounds;
     ASSERT_TRUE(expectedIntRect.contains(anchor));
     // The "overflow" tests have the focus boundary outside of the element box.
     ASSERT_EQ(url.find("overflow") == std::string::npos, expectedIntRect.contains(focus));
@@ -1929,17 +2022,17 @@ TEST_F(WebViewTest, NonUserInputTextUpdate)
     webViewImpl->setInitialFocus(false);
 
     WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
-    WebCore::HTMLDocument* document = WebCore::toHTMLDocument(frame->frame()->document());
+    blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
 
     // (A) <input>
     // (A.1) Focused and value is changed by script.
     client.reset();
     EXPECT_FALSE(client.textIsUpdated());
 
-    WebCore::HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
+    blink::HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
     document->setFocusedElement(inputElement);
     webViewImpl->setFocus(true);
-    EXPECT_EQ(document->focusedElement(), static_cast<WebCore::Element*>(inputElement));
+    EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(inputElement));
 
     // Emulate value change from script.
     inputElement->setValue("testA");
@@ -1963,7 +2056,7 @@ TEST_F(WebViewTest, NonUserInputTextUpdate)
     EXPECT_FALSE(client.textIsUpdated());
     document->setFocusedElement(nullptr);
     webViewImpl->setFocus(false);
-    EXPECT_NE(document->focusedElement(), static_cast<WebCore::Element*>(inputElement));
+    EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(inputElement));
     inputElement->setValue("testA3");
     EXPECT_FALSE(client.textIsUpdated());
 
@@ -1971,10 +2064,10 @@ TEST_F(WebViewTest, NonUserInputTextUpdate)
     // (B.1) Focused and value is changed by script.
     client.reset();
     EXPECT_FALSE(client.textIsUpdated());
-    WebCore::HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
+    blink::HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
     document->setFocusedElement(textAreaElement);
     webViewImpl->setFocus(true);
-    EXPECT_EQ(document->focusedElement(), static_cast<WebCore::Element*>(textAreaElement));
+    EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
     textAreaElement->setValue("testB");
     EXPECT_TRUE(client.textIsUpdated());
     info = webViewImpl->textInputInfo();
@@ -1993,7 +2086,7 @@ TEST_F(WebViewTest, NonUserInputTextUpdate)
     EXPECT_FALSE(client.textIsUpdated());
     document->setFocusedElement(nullptr);
     webViewImpl->setFocus(false);
-    EXPECT_NE(document->focusedElement(), static_cast<WebCore::Element*>(textAreaElement));
+    EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
     inputElement->setValue("testB3");
     EXPECT_FALSE(client.textIsUpdated());
 
@@ -2014,7 +2107,7 @@ TEST_F(WebViewTest, FirstUserGestureObservedKeyEvent)
     EXPECT_EQ(0, client.getUserGestureNotificationsCount());
 
     WebKeyboardEvent keyEvent;
-    keyEvent.windowsKeyCode = WebCore::VKEY_SPACE;
+    keyEvent.windowsKeyCode = blink::VKEY_SPACE;
     keyEvent.type = WebInputEvent::RawKeyDown;
     keyEvent.setKeyIdentifierFromWindowsKeyCode();
     webView->handleInputEvent(keyEvent);
@@ -2065,4 +2158,18 @@ TEST_F(WebViewTest, FirstUserGestureObservedGestureTap)
     webView->setAutofillClient(0);
 }
 
+TEST_F(WebViewTest, CompareSelectAllToContentAsText)
+{
+    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
+    WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
+
+    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+    frame->executeScript(WebScriptSource(WebString::fromUTF8("document.execCommand('SelectAll', false, null)")));
+    std::string actual = frame->selectionAsText().utf8();
+
+    const int kMaxOutputCharacters = 1024;
+    std::string expected = frame->contentAsText(kMaxOutputCharacters).utf8();
+    EXPECT_EQ(expected, actual);
+}
+
 } // namespace