*/
#include "config.h"
-#include "WebView.h"
+#include "public/web/WebView.h"
-#include <gtest/gtest.h>
-#include "FrameTestHelpers.h"
-#include "URLTestHelpers.h"
-#include "WebAutofillClient.h"
-#include "WebContentDetectionResult.h"
-#include "WebDateTimeChooserCompletion.h"
-#include "WebDocument.h"
-#include "WebElement.h"
-#include "WebFrame.h"
-#include "WebFrameClient.h"
-#include "WebFrameImpl.h"
-#include "WebHelperPlugin.h"
-#include "WebHitTestResult.h"
-#include "WebInputEvent.h"
-#include "WebSettings.h"
-#include "WebViewClient.h"
-#include "WebViewImpl.h"
-#include "WebWidget.h"
#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/HTMLDocument.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLTextAreaElement.h"
#include "core/loader/FrameLoadRequest.h"
-#include "core/frame/FrameView.h"
#include "core/page/Chrome.h"
-#include "core/frame/Settings.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderView.h"
#include "platform/KeyboardCodes.h"
-#include "platform/Timer.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"
#include "public/platform/WebUnitTestSupport.h"
+#include "public/web/WebAutofillClient.h"
+#include "public/web/WebContentDetectionResult.h"
+#include "public/web/WebDateTimeChooserCompletion.h"
+#include "public/web/WebDocument.h"
+#include "public/web/WebDragOperation.h"
+#include "public/web/WebElement.h"
+#include "public/web/WebFrame.h"
+#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"
#include "public/web/WebWidgetClient.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkBitmapDevice.h"
#include "third_party/skia/include/core/SkCanvas.h"
+#include "web/WebLocalFrameImpl.h"
+#include "web/WebSettingsImpl.h"
+#include "web/WebViewImpl.h"
+#include "web/tests/FrameTestHelpers.h"
+#include "web/tests/URLTestHelpers.h"
+#include <gtest/gtest.h>
using namespace blink;
using blink::FrameTestHelpers::runPendingTasks;
WebViewImpl* m_webView;
};
-class AutoResizeWebViewClient : public WebViewClient {
+class AutoResizeWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
// WebViewClient methods
virtual void didAutoResize(const WebSize& newSize) { m_testData.setSize(newSize); }
TestData m_testData;
};
-class TapHandlingWebViewClient : public WebViewClient {
+class TapHandlingWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
// WebViewClient methods
virtual void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled)
int m_longpressY;
};
-class HelperPluginCreatingWebViewClient : public WebViewClient {
-public:
- // WebViewClient methods
- virtual blink::WebWidget* createPopupMenu(blink::WebPopupType popupType) OVERRIDE
- {
- EXPECT_EQ(WebPopupTypeHelperPlugin, popupType);
- // The caller owns the object, but we retain a pointer for use in closeWidgetNow().
- m_helperPluginWebWidget = blink::WebHelperPlugin::create(this);
- return m_helperPluginWebWidget;
- }
-
- virtual void initializeHelperPluginWebFrame(blink::WebHelperPlugin* plugin) OVERRIDE
- {
- ASSERT_TRUE(m_webFrameClient);
- plugin->initializeFrame(m_webFrameClient);
- }
-
- // WebWidgetClient methods
- virtual void closeWidgetSoon() OVERRIDE
- {
- ASSERT_TRUE(m_helperPluginWebWidget);
- // m_helperPluginWebWidget->close() must be called asynchronously.
- if (!m_closeTimer.isActive())
- m_closeTimer.startOneShot(0);
- }
-
- void closeWidgetNow(WebCore::Timer<HelperPluginCreatingWebViewClient>* timer)
- {
- m_helperPluginWebWidget->close();
- m_helperPluginWebWidget = 0;
- }
-
- // Local methods
- HelperPluginCreatingWebViewClient()
- : m_helperPluginWebWidget(0)
- , m_webFrameClient(0)
- , m_closeTimer(this, &HelperPluginCreatingWebViewClient::closeWidgetNow)
- {
- }
-
- void setWebFrameClient(WebFrameClient* client) { m_webFrameClient = client; }
-
-private:
- WebWidget* m_helperPluginWebWidget;
- WebFrameClient* m_webFrameClient;
- WebCore::Timer<HelperPluginCreatingWebViewClient> m_closeTimer;
-};
-
-class DateTimeChooserWebViewClient : public WebViewClient {
+class DateTimeChooserWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
WebDateTimeChooserCompletion* chooserCompletion()
{
}
protected:
+ void registerMockedHttpURLLoad(const std::string& fileName)
+ {
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
+ }
+
void testAutoResize(const WebSize& minAutoResize, const WebSize& maxAutoResize,
const std::string& pageWidth, const std::string& pageHeight,
int expectedWidth, int expectedHeight,
void testTextInputType(WebTextInputType expectedType, const std::string& htmlFile);
void testInputMode(const WebString& expectedInputMode, const std::string& htmlFile);
+ void testSelectionRootBounds(const char* htmlFile, float pageScaleFactor);
std::string m_baseURL;
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;
const WebColor kBlue = 0xFF0000FF;
const WebColor kDarkCyan = 0xFF227788;
const WebColor kTranslucentPutty = 0x80BFB196;
+ const WebColor kTransparent = 0x00000000;
- WebView* webView = m_webViewHelper.initialize();
+ WebViewImpl* webView = m_webViewHelper.initialize();
EXPECT_EQ(kWhite, webView->backgroundColor());
webView->setBaseBackgroundColor(kBlue);
EXPECT_EQ(kBlue, webView->backgroundColor());
WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
- webView->mainFrame()->loadHTMLString(
- "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
- Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+ FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:#227788}</style></head></html>", baseURL);
EXPECT_EQ(kDarkCyan, webView->backgroundColor());
- webView->mainFrame()->loadHTMLString(
- "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
- Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+ FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:rgba(255,0,0,0.5)}</style></head></html>", baseURL);
// Expected: red (50% alpha) blended atop base of kBlue.
EXPECT_EQ(0xFF7F0080, webView->backgroundColor());
webView->setBaseBackgroundColor(kTranslucentPutty);
// Expected: red (50% alpha) blended atop kTranslucentPutty. Note the alpha.
EXPECT_EQ(0xBFE93B32, webView->backgroundColor());
+
+ webView->setBaseBackgroundColor(kTransparent);
+ FrameTestHelpers::loadHTMLString(webView->mainFrame(), "<html><head><style>body {background-color:transparent}</style></head></html>", baseURL);
+ // Expected: transparent on top of kTransparent will still be transparent.
+ EXPECT_EQ(kTransparent, webView->backgroundColor());
+
+ blink::LocalFrame* frame = webView->mainFrameImpl()->frame();
+
+ // Creating a new frame view with the background color having 0 alpha.
+ frame->createView(blink::IntSize(1024, 768), blink::Color::transparent, true);
+ EXPECT_EQ(kTransparent, frame->view()->baseBackgroundColor());
+
+ 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);
EXPECT_EQ(kBlue, webView->backgroundColor());
+ webView->setMainFrame(WebLocalFrameImpl::create(0));
+ webView->close();
}
TEST_F(WebViewTest, SetBaseBackgroundColorAndBlendWithExistingContent)
const int kWidth = 100;
const int kHeight = 100;
- // Set WebView background to green with alpha.
WebView* webView = m_webViewHelper.initialize();
+
+ // Set WebView background to green with alpha.
webView->setBaseBackgroundColor(kAlphaGreen);
webView->settings()->setShouldClearDocumentBackground(false);
webView->resize(WebSize(kWidth, kHeight));
// Set canvas background to red with alpha.
SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, kWidth, kHeight);
- bitmap.allocPixels();
- SkBitmapDevice device(bitmap);
- SkCanvas canvas(&device);
+ ASSERT_TRUE(bitmap.allocN32Pixels(kWidth, kHeight));
+ SkCanvas canvas(bitmap);
canvas.clear(kAlphaRed);
- webView->paint(&canvas, WebRect(0, 0, kWidth, kHeight));
+
+ blink::GraphicsContext context(&canvas);
+
+ // Paint the root of the main frame in the way that CompositedLayerMapping would.
+ 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)
webView->setFocus(true);
webView->setIsActive(true);
- WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
+ 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);
// 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, WebPoint(0, 0));
+ 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();
}
WebView* webView = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
client.testData().setWebView(webView);
- WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
- WebCore::FrameView* frameView = frame->frame()->view();
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ blink::FrameView* frameView = frame->frame()->view();
frameView->layout();
EXPECT_FALSE(frameView->layoutPending());
EXPECT_FALSE(frameView->needsLayout());
testInputMode(WebString("verbatim"), "input_mode_textarea_verbatim.html");
}
+TEST_F(WebViewTest, TextInputInfoWithReplacedElements)
+{
+ std::string url = m_baseURL + "div_with_image.html";
+ URLTestHelpers::registerMockedURLLoad(toKURL(url), "div_with_image.html");
+ WebView* webView = m_webViewHelper.initializeAndLoad(url);
+ webView->setInitialFocus(false);
+ WebTextInputInfo info = webView->textInputInfo();
+
+ EXPECT_EQ("foo\xef\xbf\xbc", info.value.utf8());
+}
+
TEST_F(WebViewTest, SetEditableSelectionOffsetsAndTextInputInfo)
{
URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
webView->setInitialFocus(false);
- webView->setEditableSelectionOffsets(5, 13);
- WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setEditableSelectionOffsets(5, 13);
EXPECT_EQ("56789abc", frame->selectionAsText());
WebTextInputInfo info = webView->textInputInfo();
EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("content_editable_populated.html"));
webView = m_webViewHelper.initializeAndLoad(m_baseURL + "content_editable_populated.html");
webView->setInitialFocus(false);
- webView->setEditableSelectionOffsets(8, 19);
- frame = toWebFrameImpl(webView->mainFrame());
+ frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setEditableSelectionOffsets(8, 19);
EXPECT_EQ("89abcdefghi", frame->selectionAsText());
info = webView->textInputInfo();
EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", info.value);
WebVector<WebCompositionUnderline> emptyUnderlines;
- webView->setEditableSelectionOffsets(4, 4);
- webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setEditableSelectionOffsets(4, 4);
+ frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
WebTextInputInfo info = webView->textInputInfo();
EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
{
URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("input_field_populated.html"));
WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
webView->setInitialFocus(false);
- webView->setEditableSelectionOffsets(10, 10);
- webView->extendSelectionAndDelete(5, 8);
+ frame->setEditableSelectionOffsets(10, 10);
+ frame->extendSelectionAndDelete(5, 8);
WebTextInputInfo info = webView->textInputInfo();
EXPECT_EQ("01234ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
EXPECT_EQ(5, info.selectionStart);
EXPECT_EQ(5, info.selectionEnd);
- webView->extendSelectionAndDelete(10, 0);
+ frame->extendSelectionAndDelete(10, 0);
info = webView->textInputInfo();
EXPECT_EQ("ijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
}
WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
webView->setInitialFocus(false);
WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
- underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false);
- webView->setEditableSelectionOffsets(4, 10);
- webView->setCompositionFromExistingText(8, 12, underlines);
+ underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false, 0);
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setEditableSelectionOffsets(4, 10);
+ frame->setCompositionFromExistingText(8, 12, underlines);
WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
EXPECT_EQ(8u, underlineResults[0].startOffset);
EXPECT_EQ(12u, underlineResults[0].endOffset);
EXPECT_EQ(8, info.compositionStart);
EXPECT_EQ(12, info.compositionEnd);
WebVector<WebCompositionUnderline> emptyUnderlines;
- webView->setCompositionFromExistingText(0, 0, emptyUnderlines);
+ frame->setCompositionFromExistingText(0, 0, emptyUnderlines);
info = webView->textInputInfo();
EXPECT_EQ(4, info.selectionStart);
EXPECT_EQ(10, info.selectionEnd);
WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "text_area_populated.html");
webView->setInitialFocus(false);
WebVector<WebCompositionUnderline> underlines(static_cast<size_t>(1));
- underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false);
- webView->setEditableSelectionOffsets(27, 27);
+ underlines[0] = blink::WebCompositionUnderline(0, 4, 0, false, 0);
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setEditableSelectionOffsets(27, 27);
std::string newLineText("\n");
webView->confirmComposition(WebString::fromUTF8(newLineText.c_str()));
WebTextInputInfo info = webView->textInputInfo();
EXPECT_EQ("0123456789abcdefghijklmnopq\nrstuvwxyz", std::string(info.value.utf8().data()));
- webView->setEditableSelectionOffsets(31, 31);
- webView->setCompositionFromExistingText(30, 34, underlines);
+ frame->setEditableSelectionOffsets(31, 31);
+ frame->setCompositionFromExistingText(30, 34, underlines);
WebVector<WebCompositionUnderline> underlineResults = toWebViewImpl(webView)->compositionUnderlines();
EXPECT_EQ(2u, underlineResults[0].startOffset);
EXPECT_EQ(6u, underlineResults[0].endOffset);
EXPECT_EQ(6, info.compositionStart);
EXPECT_EQ(11, info.compositionEnd);
- webView->setEditableSelectionOffsets(6, 6);
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setEditableSelectionOffsets(6, 6);
info = webView->textInputInfo();
EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
EXPECT_EQ(6, info.selectionStart);
EXPECT_EQ(6, info.compositionStart);
EXPECT_EQ(11, info.compositionEnd);
- webView->setEditableSelectionOffsets(8, 8);
+ frame->setEditableSelectionOffsets(8, 8);
info = webView->textInputInfo();
EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
EXPECT_EQ(8, info.selectionStart);
EXPECT_EQ(6, info.compositionStart);
EXPECT_EQ(11, info.compositionEnd);
- webView->setEditableSelectionOffsets(11, 11);
+ frame->setEditableSelectionOffsets(11, 11);
info = webView->textInputInfo();
EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
EXPECT_EQ(11, info.selectionStart);
EXPECT_EQ(6, info.compositionStart);
EXPECT_EQ(11, info.compositionEnd);
- webView->setEditableSelectionOffsets(6, 11);
+ frame->setEditableSelectionOffsets(6, 11);
info = webView->textInputInfo();
EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
EXPECT_EQ(6, info.selectionStart);
EXPECT_EQ(6, info.compositionStart);
EXPECT_EQ(11, info.compositionEnd);
- webView->setEditableSelectionOffsets(2, 2);
+ frame->setEditableSelectionOffsets(2, 2);
info = webView->textInputInfo();
EXPECT_EQ("hello world", std::string(info.value.utf8().data()));
EXPECT_EQ(2, info.selectionStart);
WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "input_field_populated.html");
WebFrame* frame = webView->mainFrame();
+ webView->setPageScaleFactorLimits(1, 1);
webView->setInitialFocus(false);
- webView->setEditableSelectionOffsets(4, 10);
+ frame->setEditableSelectionOffsets(4, 10);
EXPECT_TRUE(webView->isSelectionAnchorFirst());
WebRect anchor;
WebRect focus;
EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
// Make the page scale and scroll with the given paremeters.
- webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84));
- EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
- EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
- EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
- webViewImpl->page()->mainFrame()->loader().saveDocumentAndScrollState();
-
- // Confirm that restoring the page state restores the parameters.
- webViewImpl->setPageScaleFactor(1.5f, WebPoint(16, 24));
- EXPECT_EQ(1.5f, webViewImpl->pageScaleFactor());
- EXPECT_EQ(16, webViewImpl->mainFrame()->scrollOffset().width);
- EXPECT_EQ(24, webViewImpl->mainFrame()->scrollOffset().height);
- // WebViewImpl::setPageScaleFactor is performing user scrolls, which will set the
- // wasScrolledByUser flag on the main frame, and prevent restoreScrollPositionAndViewState
- // from restoring the scrolling position.
- webViewImpl->page()->mainFrame()->view()->setWasScrolledByUser(false);
- webViewImpl->page()->mainFrame()->loader().setLoadType(WebCore::FrameLoadTypeBackForward);
- webViewImpl->page()->mainFrame()->loader().restoreScrollPositionAndViewState();
+ webViewImpl->setPageScaleFactor(2.0f);
+ webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
- webViewImpl->page()->mainFrame()->loader().saveDocumentAndScrollState();
+ 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());
+ EXPECT_EQ(84, mainFrameLocal->loader().currentItem()->scrollPoint().y());
// Confirm that resetting the page state resets the saved scroll position.
// The HistoryController treats a page scale factor of 0.0f as special and avoids
EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
- webViewImpl->page()->mainFrame()->loader().restoreScrollPositionAndViewState();
- EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
+ EXPECT_EQ(0.0f, mainFrameLocal->loader().currentItem()->pageScaleFactor());
+ EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().x());
+ EXPECT_EQ(0, mainFrameLocal->loader().currentItem()->scrollPoint().y());
+}
+
+TEST_F(WebViewTest, BackForwardRestoreScroll)
+{
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("back_forward_restore_scroll.html"));
+ WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "back_forward_restore_scroll.html");
+ webViewImpl->resize(WebSize(640, 480));
+ webViewImpl->layout();
+
+ // Emulate a user scroll
+ webViewImpl->setMainFrameScrollOffset(WebPoint(0, 900));
+ blink::LocalFrame* mainFrameLocal = toLocalFrame(webViewImpl->page()->mainFrame());
+ RefPtr<blink::HistoryItem> item1 = mainFrameLocal->loader().currentItem();
+
+ // Click an anchor
+ 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(), blink::HistorySameDocumentLoad);
+ mainFrameLocal->loader().loadHistoryItem(item2.get(), blink::HistorySameDocumentLoad);
+ mainFrameLocal->loader().loadHistoryItem(item1.get(), blink::HistorySameDocumentLoad);
+
+ // Click a different anchor
+ 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(), blink::HistorySameDocumentLoad);
+ mainFrameLocal->loader().loadHistoryItem(item3.get(), blink::HistorySameDocumentLoad);
EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
- EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
+ EXPECT_GT(webViewImpl->mainFrame()->scrollOffset().height, 2000);
}
-class EnterFullscreenWebViewClient : public WebViewClient {
+class EnterFullscreenWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
// WebViewClient methods
virtual bool enterFullScreen() { return true; }
EnterFullscreenWebViewClient client;
URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("hello_world.html"));
WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true, 0, &client);
- webViewImpl->settings()->setFullScreenEnabled(true);
webViewImpl->resize(WebSize(640, 480));
webViewImpl->layout();
EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().width);
EXPECT_EQ(0, webViewImpl->mainFrame()->scrollOffset().height);
// Make the page scale and scroll with the given paremeters.
- webViewImpl->setPageScaleFactor(2.0f, WebPoint(116, 84));
+ webViewImpl->setPageScaleFactor(2.0f);
+ webViewImpl->setMainFrameScrollOffset(WebPoint(116, 84));
EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
EXPECT_EQ(116, webViewImpl->mainFrame()->scrollOffset().width);
EXPECT_EQ(84, webViewImpl->mainFrame()->scrollOffset().height);
- RefPtr<WebCore::Element> element = static_cast<PassRefPtr<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();
EXPECT_EQ(1.0f, webViewImpl->pageScaleFactor());
// Make sure fullscreen nesting doesn't disrupt scroll/scale saving.
- RefPtr<WebCore::Element> otherElement = static_cast<PassRefPtr<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.
m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
}
-class ContentDetectorClient : public WebViewClient {
+class PrintWebViewClient : public FrameTestHelpers::TestWebViewClient {
+public:
+ PrintWebViewClient()
+ : m_printCalled(false)
+ {
+ }
+
+ // WebViewClient methods
+ virtual void printPage(WebLocalFrame*) OVERRIDE
+ {
+ m_printCalled = true;
+ }
+
+ bool printCalled() const { return m_printCalled; }
+
+private:
+ bool m_printCalled;
+};
+
+
+TEST_F(WebViewTest, PrintWithXHRInFlight)
+{
+ PrintWebViewClient client;
+ 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(blink::FrameStateComplete, toLocalFrame(webViewImpl->page()->mainFrame())->loader().state());
+ EXPECT_TRUE(client.printCalled());
+ m_webViewHelper.reset();
+}
+
+class DropTask : public WebThread::Task {
+public:
+ explicit DropTask(WebView* webView) : m_webView(webView)
+ {
+ }
+
+ virtual void run() OVERRIDE
+ {
+ const WebPoint clientPoint(0, 0);
+ const WebPoint screenPoint(0, 0);
+ m_webView->dragTargetDrop(clientPoint, screenPoint, 0);
+ }
+
+private:
+ WebView* const m_webView;
+};
+static void DragAndDropURL(WebViewImpl* webView, const std::string& url)
+{
+ blink::WebDragData dragData;
+ dragData.initialize();
+
+ WebDragData::Item item;
+ item.storageType = WebDragData::Item::StorageTypeString;
+ item.stringType = "text/uri-list";
+ item.stringData = WebString::fromUTF8(url);
+ dragData.addItem(item);
+
+ const WebPoint clientPoint(0, 0);
+ const WebPoint screenPoint(0, 0);
+ webView->dragTargetDragEnter(dragData, clientPoint, screenPoint, blink::WebDragOperationCopy, 0);
+ Platform::current()->currentThread()->postTask(new DropTask(webView));
+ FrameTestHelpers::pumpPendingRequestsDoNotUse(webView->mainFrame());
+}
+
+TEST_F(WebViewTest, DragDropURL)
+{
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "foo.html");
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), "bar.html");
+
+ const std::string fooUrl = m_baseURL + "foo.html";
+ const std::string barUrl = m_baseURL + "bar.html";
+
+ WebViewImpl* webView = m_webViewHelper.initializeAndLoad(fooUrl);
+
+ ASSERT_TRUE(webView);
+
+ // Drag and drop barUrl and verify that we've navigated to it.
+ DragAndDropURL(webView, barUrl);
+ EXPECT_EQ(barUrl, webView->mainFrame()->document().url().string().utf8());
+
+ // Drag and drop fooUrl and verify that we've navigated back to it.
+ DragAndDropURL(webView, fooUrl);
+ EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
+
+ // Disable navigation on drag-and-drop.
+ webView->settingsImpl()->setNavigateOnDragDrop(false);
+
+ // Attempt to drag and drop to barUrl and verify that no navigation has occurred.
+ DragAndDropURL(webView, barUrl);
+ EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8());
+}
+
+class ContentDetectorClient : public FrameTestHelpers::TestWebViewClient {
public:
ContentDetectorClient() { reset(); }
static bool tapElementById(WebView* webView, WebInputEvent::Type type, const WebString& id)
{
ASSERT(webView);
- RefPtr<WebCore::Element> element = static_cast<PassRefPtr<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;
WebString target = WebString::fromUTF8("target");
WebString onselectstartfalse = WebString::fromUTF8("onselectstartfalse");
- WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureLongPress, onselectstartfalse));
EXPECT_EQ("", std::string(frame->selectionAsText().utf8().data()));
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)
std::string testWord = "This text should be selected.";
- WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
size_t location;
std::string testWord = "This text should be selected.";
- WebFrameImpl* frame = toWebFrameImpl(webView->mainFrame());
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
EXPECT_EQ(testWord, std::string(frame->selectionAsText().utf8().data()));
size_t location;
EXPECT_EQ(length, testWord.length());
}
+static void configueCompositingWebView(WebSettings* settings)
+{
+ settings->setAcceleratedCompositingEnabled(true);
+ settings->setAcceleratedCompositingForFixedPositionEnabled(true);
+ settings->setAcceleratedCompositingForOverflowScrollEnabled(true);
+ settings->setCompositedScrollingForFramesEnabled(true);
+}
+
+TEST_F(WebViewTest, ShowPressOnTransformedLink)
+{
+ OwnPtr<FrameTestHelpers::TestWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FrameTestHelpers::TestWebViewClient());
+ FrameTestHelpers::WebViewHelper webViewHelper;
+ WebViewImpl* webViewImpl = webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
+
+ int pageWidth = 640;
+ int pageHeight = 480;
+ webViewImpl->resize(WebSize(pageWidth, pageHeight));
+
+ WebURL baseURL = URLTestHelpers::toKURL("http://example.com/");
+ FrameTestHelpers::loadHTMLString(webViewImpl->mainFrame(), "<a href='http://www.test.com' style='position: absolute; left: 20px; top: 20px; width: 200px; -webkit-transform:translateZ(0);'>A link to highlight</a>", baseURL);
+
+ WebGestureEvent event;
+ event.type = WebInputEvent::GestureShowPress;
+ event.x = 20;
+ event.y = 20;
+
+ // Just make sure we don't hit any asserts.
+ webViewImpl->handleInputEvent(event);
+}
+
class MockAutofillClient : public WebAutofillClient {
public:
MockAutofillClient()
: m_ignoreTextChanges(false)
, m_textChangesWhileIgnored(0)
- , m_textChangesWhileNotIgnored(0) { }
+ , m_textChangesWhileNotIgnored(0)
+ , m_userGestureNotificationsCount(0) { }
virtual ~MockAutofillClient() { }
virtual void setIgnoreTextChanges(bool ignore) OVERRIDE { m_ignoreTextChanges = ignore; }
- virtual void textFieldDidChange(const WebInputElement&) OVERRIDE
+ virtual void textFieldDidChange(const WebFormControlElement&) OVERRIDE
{
if (m_ignoreTextChanges)
++m_textChangesWhileIgnored;
else
++m_textChangesWhileNotIgnored;
}
+ virtual void firstUserGestureObserved() OVERRIDE { ++m_userGestureNotificationsCount; }
void clearChangeCounts()
{
int textChangesWhileIgnored() { return m_textChangesWhileIgnored; }
int textChangesWhileNotIgnored() { return m_textChangesWhileNotIgnored; }
+ int getUserGestureNotificationsCount() { return m_userGestureNotificationsCount; }
private:
bool m_ignoreTextChanges;
int m_textChangesWhileIgnored;
int m_textChangesWhileNotIgnored;
+ int m_userGestureNotificationsCount;
};
// Set up a composition that needs to be committed.
WebVector<WebCompositionUnderline> emptyUnderlines;
- webView->setEditableSelectionOffsets(4, 10);
- webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setEditableSelectionOffsets(4, 10);
+ frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
WebTextInputInfo info = webView->textInputInfo();
EXPECT_EQ(4, info.selectionStart);
EXPECT_EQ(10, info.selectionEnd);
WebVector<WebCompositionUnderline> emptyUnderlines;
client.clearChangeCounts();
- webView->setCompositionFromExistingText(8, 12, emptyUnderlines);
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ frame->setCompositionFromExistingText(8, 12, emptyUnderlines);
WebTextInputInfo info = webView->textInputInfo();
EXPECT_EQ("0123456789abcdefghijklmnopqrstuvwxyz", std::string(info.value.utf8().data()));
}
}
-TEST_F(WebViewTest, HelperPlugin)
-{
- HelperPluginCreatingWebViewClient client;
- WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
-
- WebFrameImpl* frame = toWebFrameImpl(webViewImpl->mainFrame());
- client.setWebFrameClient(frame->client());
-
- OwnPtr<WebHelperPlugin> helperPlugin = adoptPtr(webViewImpl->createHelperPlugin("dummy-plugin-type", frame->document()));
- EXPECT_TRUE(helperPlugin);
- EXPECT_EQ(0, helperPlugin->getPlugin()); // Invalid plugin type means no plugin.
-
- helperPlugin.clear();
- runPendingTasks();
-
- m_webViewHelper.reset(); // Explicitly reset to break dependency on locally scoped client.
-}
-
-
-class ViewCreatingWebViewClient : public WebViewClient {
+class ViewCreatingWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
ViewCreatingWebViewClient()
: m_didFocusCalled(false)
}
// WebViewClient methods
- virtual WebView* createView(WebFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) OVERRIDE
+ virtual WebView* createView(WebLocalFrame*, const WebURLRequest&, const WebWindowFeatures&, const WebString& name, WebNavigationPolicy, bool) OVERRIDE
{
return m_webViewHelper.initialize(true, 0, 0);
}
FrameTestHelpers::WebViewHelper m_webViewHelper;
WebViewImpl* webViewImpl = m_webViewHelper.initialize(true, 0, &client);
webViewImpl->page()->settings().setJavaScriptCanOpenWindowsAutomatically(true);
- WebFrameImpl* frame = toWebFrameImpl(webViewImpl->mainFrame());
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
frame->setName("_start");
// Make a request that will open a new window
WebURLRequest webURLRequest;
webURLRequest.initialize();
- WebCore::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
- webViewImpl->page()->mainFrame()->loader().load(request);
+ blink::FrameLoadRequest request(0, webURLRequest.toResourceRequest(), "_blank");
+ toLocalFrame(webViewImpl->page()->mainFrame())->loader().load(request);
ASSERT_TRUE(client.createdWebView());
EXPECT_FALSE(client.didFocusCalled());
// 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");
- toWebViewImpl(client.createdWebView())->page()->mainFrame()->loader().load(requestWithTargetStart);
+ blink::FrameLoadRequest requestWithTargetStart(0, webURLRequestWithTargetStart.toResourceRequest(), "_start");
+ toLocalFrame(toWebViewImpl(client.createdWebView())->page()->mainFrame())->loader().load(requestWithTargetStart);
EXPECT_TRUE(client.didFocusCalled());
m_webViewHelper.reset(); // Remove dependency on locally scoped client.
}
#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);
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);
client.chooserCompletion()->didChooseValue(std::numeric_limits<double>::quiet_NaN());
client.clearChooserCompletion();
EXPECT_STREQ("", inputElement->value().utf8().data());
+
+ // Clear the WebViewClient from the webViewHelper to avoid use-after-free in the
+ // WebViewHelper destructor.
+ m_webViewHelper.reset();
}
#endif
TEST_F(WebViewTest, SmartClipData)
{
+ static const char* kExpectedClipText = "\nPrice 10,000,000won";
+ static const char* kExpectedClipHtml =
+ "<div id=\"div4\" style=\"padding: 10px; margin: 10px; border: 2px "
+ "solid rgb(135, 206, 235); float: left; width: 190px; height: 30px; "
+ "color: rgb(0, 0, 0); font-family: myahem; font-size: 8px; font-style: "
+ "normal; font-variant: normal; font-weight: normal; letter-spacing: "
+ "normal; line-height: normal; orphans: auto; text-align: start; "
+ "text-indent: 0px; text-transform: none; white-space: normal; widows: "
+ "auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;\">Air "
+ "conditioner</div><div id=\"div5\" style=\"padding: 10px; margin: "
+ "10px; border: 2px solid rgb(135, 206, 235); float: left; width: "
+ "190px; height: 30px; color: rgb(0, 0, 0); font-family: myahem; "
+ "font-size: 8px; font-style: normal; font-variant: normal; "
+ "font-weight: normal; letter-spacing: normal; line-height: normal; "
+ "orphans: auto; text-align: start; text-indent: 0px; text-transform: "
+ "none; white-space: normal; widows: auto; word-spacing: 0px; "
+ "-webkit-text-stroke-width: 0px;\">Price 10,000,000won</div>";
+ 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.html"));
WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "smartclip.html");
+ webView->setPageScaleFactorLimits(1, 1);
webView->resize(WebSize(500, 500));
webView->layout();
WebRect cropRect(300, 125, 100, 50);
+ webView->extractSmartClipData(cropRect, clipText, clipHtml, clipRect);
+ EXPECT_STREQ(kExpectedClipText, clipText.utf8().c_str());
+ EXPECT_STREQ(kExpectedClipHtml, clipHtml.utf8().c_str());
+}
- // FIXME: We should test the structure of the data we get back.
- EXPECT_FALSE(webView->getSmartClipData(cropRect).isEmpty());
+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) { }
- virtual WebFrame* createChildFrame(WebFrame* parent, const WebString& frameName) OVERRIDE;
+ virtual WebFrame* createChildFrame(WebLocalFrame* parent, const WebString& frameName) OVERRIDE;
int count() const { return m_count; }
int m_count;
};
-WebFrame* CreateChildCounterFrameClient::createChildFrame(WebFrame* parent, const WebString& frameName)
+WebFrame* CreateChildCounterFrameClient::createChildFrame(WebLocalFrame* parent, const WebString& frameName)
{
++m_count;
return TestWebFrameClient::createChildFrame(parent, frameName);
CreateChildCounterFrameClient frameClient;
URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("add_frame_in_unload.html"));
m_webViewHelper.initializeAndLoad(m_baseURL + "add_frame_in_unload.html", true, &frameClient);
- m_webViewHelper.webViewImpl()->dispatchUnloadEvent();
+ m_webViewHelper.webViewImpl()->mainFrame()->dispatchUnloadEvent();
EXPECT_EQ(0, frameClient.count());
m_webViewHelper.reset();
}
m_webViewHelper.reset();
}
-class TouchEventHandlerWebViewClient : public WebViewClient {
+class TouchEventHandlerWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
// WebWidgetClient methods
virtual void hasTouchEventHandlers(bool state) OVERRIDE
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
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));
+
+ // Free the webView before the TouchEventHandlerWebViewClient gets freed.
+ m_webViewHelper.reset();
+}
+
+// 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)
+{
+ blink::Element* element = document->getElementById("root");
+ if (!element)
+ element = document->getElementById("target");
+ if (element->hasTagName(blink::HTMLNames::iframeTag))
+ return ExpectedRootBounds(toHTMLIFrameElement(element)->contentDocument(), scaleFactor);
+
+ 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);
+ boundingBox.scale(scaleFactor);
+ return boundingBox;
+}
+
+void WebViewTest::testSelectionRootBounds(const char* htmlFile, float pageScaleFactor)
+{
+ std::string url = m_baseURL + htmlFile;
+
+ WebView* webView = m_webViewHelper.initializeAndLoad(url, true);
+ webView->resize(WebSize(640, 480));
+ webView->setPageScaleFactor(pageScaleFactor);
+ webView->layout();
+ runPendingTasks();
+
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
+ blink::HTMLDocument* document = blink::toHTMLDocument(frame->frame()->document());
+
+ WebRect expectedRootBounds = ExpectedRootBounds(document, webView->pageScaleFactor());
+ WebRect actualRootBounds;
+ webView->getSelectionRootBounds(actualRootBounds);
+ ASSERT_EQ(expectedRootBounds, actualRootBounds);
+
+ WebRect anchor, focus;
+ webView->selectionBounds(anchor, focus);
+ 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));
+}
+
+TEST_F(WebViewTest, GetSelectionRootBounds)
+{
+ // Register all the pages we will be using.
+ registerMockedHttpURLLoad("select_range_basic.html");
+ registerMockedHttpURLLoad("select_range_div_editable.html");
+ registerMockedHttpURLLoad("select_range_scroll.html");
+ registerMockedHttpURLLoad("select_range_span_editable.html");
+ registerMockedHttpURLLoad("select_range_input.html");
+ registerMockedHttpURLLoad("select_range_input_overflow.html");
+ registerMockedHttpURLLoad("select_range_textarea.html");
+ registerMockedHttpURLLoad("select_range_textarea_overflow.html");
+ registerMockedHttpURLLoad("select_range_iframe.html");
+ registerMockedHttpURLLoad("select_range_iframe_div_editable.html");
+ registerMockedHttpURLLoad("select_range_iframe_scroll.html");
+ registerMockedHttpURLLoad("select_range_iframe_span_editable.html");
+ registerMockedHttpURLLoad("select_range_iframe_input.html");
+ registerMockedHttpURLLoad("select_range_iframe_input_overflow.html");
+ registerMockedHttpURLLoad("select_range_iframe_textarea.html");
+ registerMockedHttpURLLoad("select_range_iframe_textarea_overflow.html");
+
+ // Test with simple pages.
+ testSelectionRootBounds("select_range_basic.html", 1.0f);
+ testSelectionRootBounds("select_range_div_editable.html", 1.0f);
+ testSelectionRootBounds("select_range_scroll.html", 1.0f);
+ testSelectionRootBounds("select_range_span_editable.html", 1.0f);
+ testSelectionRootBounds("select_range_input.html", 1.0f);
+ testSelectionRootBounds("select_range_input_overflow.html", 1.0f);
+ testSelectionRootBounds("select_range_textarea.html", 1.0f);
+ testSelectionRootBounds("select_range_textarea_overflow.html", 1.0f);
+
+ // Test with the same pages as above in iframes.
+ testSelectionRootBounds("select_range_iframe.html", 1.0f);
+ testSelectionRootBounds("select_range_iframe_div_editable.html", 1.0f);
+ testSelectionRootBounds("select_range_iframe_scroll.html", 1.0f);
+ testSelectionRootBounds("select_range_iframe_span_editable.html", 1.0f);
+ testSelectionRootBounds("select_range_iframe_input.html", 1.0f);
+ testSelectionRootBounds("select_range_iframe_input_overflow.html", 1.0f);
+ testSelectionRootBounds("select_range_iframe_textarea.html", 1.0f);
+ testSelectionRootBounds("select_range_iframe_textarea_overflow.html", 1.0f);
+
+ // Basic page with scale factor.
+ testSelectionRootBounds("select_range_basic.html", 0.0f);
+ testSelectionRootBounds("select_range_basic.html", 0.1f);
+ testSelectionRootBounds("select_range_basic.html", 1.5f);
+ testSelectionRootBounds("select_range_basic.html", 2.0f);
+}
+
+TEST_F(WebViewTest, GetSelectionRootBoundsBrokenHeight)
+{
+ WebSize contentSize = WebSize(640, 480);
+
+ registerMockedHttpURLLoad("select_range_basic_broken_height.html");
+
+ WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "select_range_basic_broken_height.html", true);
+ webView->resize(contentSize);
+ webView->setPageScaleFactor(1.0f, WebPoint(0, 0));
+ webView->layout();
+ runPendingTasks();
+
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webView->mainFrame());
+ EXPECT_TRUE(frame->frame()->document()->isHTMLDocument());
+
+ WebRect expectedRootBounds = WebRect(0, 0, contentSize.width, contentSize.height);
+ WebRect actualRootBounds;
+ webView->getSelectionRootBounds(actualRootBounds);
+ ASSERT_EQ(expectedRootBounds, actualRootBounds);
+}
+
+class NonUserInputTextUpdateWebViewClient : public FrameTestHelpers::TestWebViewClient {
+public:
+ NonUserInputTextUpdateWebViewClient() : m_textIsUpdated(false) { }
+
+ // WebWidgetClient methods
+ virtual void didUpdateTextOfFocusedElementByNonUserInput() OVERRIDE
+ {
+ m_textIsUpdated = true;
+ }
+
+ void reset()
+ {
+ m_textIsUpdated = false;
+ }
+
+ bool textIsUpdated() const
+ {
+ return m_textIsUpdated;
+ }
+
+private:
+ int m_textIsUpdated;
+};
+
+// This test verifies that WebWidgetClient::didUpdateTextOfFocusedElementByNonUserInput is
+// called iff value of a focused element is modified via script.
+TEST_F(WebViewTest, NonUserInputTextUpdate)
+{
+ NonUserInputTextUpdateWebViewClient client;
+ std::string url = m_baseURL + "non_user_input_text_update.html";
+ URLTestHelpers::registerMockedURLLoad(toKURL(url), "non_user_input_text_update.html");
+ WebViewImpl* webViewImpl = m_webViewHelper.initializeAndLoad(url, true, 0, &client);
+ webViewImpl->setInitialFocus(false);
+
+ WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame());
+ 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());
+
+ blink::HTMLInputElement* inputElement = toHTMLInputElement(document->getElementById("input"));
+ document->setFocusedElement(inputElement);
+ webViewImpl->setFocus(true);
+ EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(inputElement));
+
+ // Emulate value change from script.
+ inputElement->setValue("testA");
+ EXPECT_TRUE(client.textIsUpdated());
+ WebTextInputInfo info = webViewImpl->textInputInfo();
+ EXPECT_EQ("testA", std::string(info.value.utf8().data()));
+
+ // (A.2) Focused and user input modifies value.
+ client.reset();
+ EXPECT_FALSE(client.textIsUpdated());
+
+ WebVector<WebCompositionUnderline> emptyUnderlines;
+ webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
+ webViewImpl->confirmComposition(WebWidget::KeepSelection);
+ EXPECT_FALSE(client.textIsUpdated());
+ info = webViewImpl->textInputInfo();
+ EXPECT_EQ("testA2", std::string(info.value.utf8().data()));
+
+ // (A.3) Unfocused and value is changed by script.
+ client.reset();
+ EXPECT_FALSE(client.textIsUpdated());
+ document->setFocusedElement(nullptr);
+ webViewImpl->setFocus(false);
+ EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(inputElement));
+ inputElement->setValue("testA3");
+ EXPECT_FALSE(client.textIsUpdated());
+
+ // (B) <textarea>
+ // (B.1) Focused and value is changed by script.
+ client.reset();
+ EXPECT_FALSE(client.textIsUpdated());
+ blink::HTMLTextAreaElement* textAreaElement = toHTMLTextAreaElement(document->getElementById("textarea"));
+ document->setFocusedElement(textAreaElement);
+ webViewImpl->setFocus(true);
+ EXPECT_EQ(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
+ textAreaElement->setValue("testB");
+ EXPECT_TRUE(client.textIsUpdated());
+ info = webViewImpl->textInputInfo();
+ EXPECT_EQ("testB", std::string(info.value.utf8().data()));
+
+ // (B.2) Focused and user input modifies value.
+ client.reset();
+ EXPECT_FALSE(client.textIsUpdated());
+ webViewImpl->setComposition(WebString::fromUTF8("2"), emptyUnderlines, 1, 1);
+ webViewImpl->confirmComposition(WebWidget::KeepSelection);
+ info = webViewImpl->textInputInfo();
+ EXPECT_EQ("testB2", std::string(info.value.utf8().data()));
+
+ // (B.3) Unfocused and value is changed by script.
+ client.reset();
+ EXPECT_FALSE(client.textIsUpdated());
+ document->setFocusedElement(nullptr);
+ webViewImpl->setFocus(false);
+ EXPECT_NE(document->focusedElement(), static_cast<blink::Element*>(textAreaElement));
+ inputElement->setValue("testB3");
+ EXPECT_FALSE(client.textIsUpdated());
+
+ // Free the webView before freeing the NonUserInputTextUpdateWebViewClient.
+ m_webViewHelper.reset();
+}
+
+// Check that the WebAutofillClient is correctly notified about first user
+// gestures after load, following various input events.
+TEST_F(WebViewTest, FirstUserGestureObservedKeyEvent)
+{
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
+ MockAutofillClient client;
+ WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
+ webView->setAutofillClient(&client);
+ webView->setInitialFocus(false);
+
+ EXPECT_EQ(0, client.getUserGestureNotificationsCount());
+
+ WebKeyboardEvent keyEvent;
+ keyEvent.windowsKeyCode = blink::VKEY_SPACE;
+ keyEvent.type = WebInputEvent::RawKeyDown;
+ keyEvent.setKeyIdentifierFromWindowsKeyCode();
+ webView->handleInputEvent(keyEvent);
+ keyEvent.type = WebInputEvent::KeyUp;
+ webView->handleInputEvent(keyEvent);
+
+ EXPECT_EQ(1, client.getUserGestureNotificationsCount());
+ webView->setAutofillClient(0);
+}
+
+TEST_F(WebViewTest, FirstUserGestureObservedMouseEvent)
+{
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("form.html"));
+ MockAutofillClient client;
+ WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "form.html", true);
+ webView->setAutofillClient(&client);
+ webView->setInitialFocus(false);
+
+ EXPECT_EQ(0, client.getUserGestureNotificationsCount());
+
+ WebMouseEvent mouseEvent;
+ mouseEvent.button = WebMouseEvent::ButtonLeft;
+ mouseEvent.x = 1;
+ mouseEvent.y = 1;
+ mouseEvent.clickCount = 1;
+ mouseEvent.type = WebInputEvent::MouseDown;
+ webView->handleInputEvent(mouseEvent);
+ mouseEvent.type = WebInputEvent::MouseUp;
+ webView->handleInputEvent(mouseEvent);
+
+ EXPECT_EQ(1, client.getUserGestureNotificationsCount());
+ webView->setAutofillClient(0);
+}
+
+TEST_F(WebViewTest, FirstUserGestureObservedGestureTap)
+{
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("longpress_selection.html"));
+ MockAutofillClient client;
+ WebView* webView = m_webViewHelper.initializeAndLoad(m_baseURL + "longpress_selection.html", true);
+ webView->setAutofillClient(&client);
+ webView->setInitialFocus(false);
+
+ EXPECT_EQ(0, client.getUserGestureNotificationsCount());
+
+ EXPECT_TRUE(tapElementById(webView, WebInputEvent::GestureTap, WebString::fromUTF8("target")));
+
+ EXPECT_EQ(1, client.getUserGestureNotificationsCount());
+ 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