2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "web/LinkHighlightImpl.h"
28 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
29 #include "core/dom/Node.h"
30 #include "core/frame/FrameView.h"
31 #include "core/input/EventHandler.h"
32 #include "core/page/Page.h"
33 #include "core/page/TouchDisambiguation.h"
34 #include "platform/geometry/IntRect.h"
35 #include "platform/testing/URLTestHelpers.h"
36 #include "public/platform/Platform.h"
37 #include "public/platform/WebContentLayer.h"
38 #include "public/platform/WebFloatPoint.h"
39 #include "public/platform/WebSize.h"
40 #include "public/platform/WebUnitTestSupport.h"
41 #include "public/web/WebFrame.h"
42 #include "public/web/WebFrameClient.h"
43 #include "public/web/WebInputEvent.h"
44 #include "public/web/WebViewClient.h"
45 #include "web/WebInputEventConversion.h"
46 #include "web/WebLocalFrameImpl.h"
47 #include "web/WebViewImpl.h"
48 #include "web/tests/FrameTestHelpers.h"
49 #include "wtf/PassOwnPtr.h"
50 #include <gtest/gtest.h>
54 GestureEventWithHitTestResults
getTargetedEvent(WebViewImpl
* webViewImpl
, WebGestureEvent
& touchEvent
)
56 PlatformGestureEventBuilder
platformEvent(webViewImpl
->mainFrameImpl()->frameView(), touchEvent
);
57 return webViewImpl
->page()->deprecatedLocalMainFrame()->eventHandler().targetGestureEvent(platformEvent
, true);
60 TEST(LinkHighlightImplTest
, verifyWebViewImplIntegration
)
62 const std::string
baseURL("http://www.test.com/");
63 const std::string
fileName("test_touch_link_highlight.html");
65 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL
.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
66 FrameTestHelpers::WebViewHelper webViewHelper
;
67 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(baseURL
+ fileName
, true);
70 webViewImpl
->resize(WebSize(pageWidth
, pageHeight
));
71 webViewImpl
->layout();
73 WebGestureEvent touchEvent
;
74 touchEvent
.type
= WebInputEvent::GestureShowPress
;
76 // The coordinates below are linked to absolute positions in the referenced .html file.
80 ASSERT_TRUE(webViewImpl
->bestTapNode(getTargetedEvent(webViewImpl
, touchEvent
)));
83 EXPECT_FALSE(webViewImpl
->bestTapNode(getTargetedEvent(webViewImpl
, touchEvent
)));
87 webViewImpl
->enableTapHighlightAtPoint(getTargetedEvent(webViewImpl
, touchEvent
));
89 EXPECT_TRUE(webViewImpl
->linkHighlight(0));
90 EXPECT_TRUE(webViewImpl
->linkHighlight(0)->contentLayer());
91 EXPECT_TRUE(webViewImpl
->linkHighlight(0)->clipLayer());
93 // Find a target inside a scrollable div
95 webViewImpl
->enableTapHighlightAtPoint(getTargetedEvent(webViewImpl
, touchEvent
));
96 ASSERT_TRUE(webViewImpl
->linkHighlight(0));
98 // Don't highlight if no "hand cursor"
99 touchEvent
.y
= 220; // An A-link with cross-hair cursor.
100 webViewImpl
->enableTapHighlightAtPoint(getTargetedEvent(webViewImpl
, touchEvent
));
101 ASSERT_EQ(0U, webViewImpl
->numLinkHighlights());
103 touchEvent
.y
= 260; // A text input box.
104 webViewImpl
->enableTapHighlightAtPoint(getTargetedEvent(webViewImpl
, touchEvent
));
105 ASSERT_EQ(0U, webViewImpl
->numLinkHighlights());
107 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
112 class FakeWebFrameClient
: public WebFrameClient
{
113 // To make the destructor public.
116 class FakeCompositingWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
118 FakeWebFrameClient m_fakeWebFrameClient
;
121 WebViewClient
* compositingWebViewClient()
123 DEFINE_STATIC_LOCAL(FakeCompositingWebViewClient
, client
, ());
127 } // anonymous namespace
129 TEST(LinkHighlightImplTest
, resetDuringNodeRemoval
)
131 const std::string
baseURL("http://www.test.com/");
132 const std::string
fileName("test_touch_link_highlight.html");
134 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL
.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
135 FrameTestHelpers::WebViewHelper webViewHelper
;
136 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(baseURL
+ fileName
, true, 0, compositingWebViewClient());
139 int pageHeight
= 480;
140 webViewImpl
->resize(WebSize(pageWidth
, pageHeight
));
141 webViewImpl
->layout();
143 WebGestureEvent touchEvent
;
144 touchEvent
.type
= WebInputEvent::GestureShowPress
;
148 GestureEventWithHitTestResults targetedEvent
= getTargetedEvent(webViewImpl
, touchEvent
);
149 Node
* touchNode
= webViewImpl
->bestTapNode(targetedEvent
);
150 ASSERT_TRUE(touchNode
);
152 webViewImpl
->enableTapHighlightAtPoint(targetedEvent
);
153 ASSERT_TRUE(webViewImpl
->linkHighlight(0));
155 GraphicsLayer
* highlightLayer
= webViewImpl
->linkHighlight(0)->currentGraphicsLayerForTesting();
156 ASSERT_TRUE(highlightLayer
);
157 EXPECT_TRUE(highlightLayer
->linkHighlight(0));
159 touchNode
->remove(IGNORE_EXCEPTION
);
160 webViewImpl
->layout();
161 ASSERT_EQ(0U, highlightLayer
->numLinkHighlights());
163 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
166 TEST(LinkHighlightImplTest
, multipleHighlights
)
168 const std::string
baseURL("http://www.test.com/");
169 const std::string
fileName("test_touch_link_highlight.html");
171 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL
.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
172 FrameTestHelpers::WebViewHelper webViewHelper
;
173 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(baseURL
+ fileName
, true, 0, compositingWebViewClient());
176 int pageHeight
= 480;
177 webViewImpl
->resize(WebSize(pageWidth
, pageHeight
));
178 webViewImpl
->layout();
180 WebGestureEvent touchEvent
;
183 touchEvent
.data
.tap
.width
= 30;
184 touchEvent
.data
.tap
.height
= 30;
186 Vector
<IntRect
> goodTargets
;
187 WillBeHeapVector
<RawPtrWillBeMember
<Node
>> highlightNodes
;
188 IntRect
boundingBox(touchEvent
.x
- touchEvent
.data
.tap
.width
/ 2, touchEvent
.y
- touchEvent
.data
.tap
.height
/ 2, touchEvent
.data
.tap
.width
, touchEvent
.data
.tap
.height
);
189 findGoodTouchTargets(boundingBox
, webViewImpl
->mainFrameImpl()->frame(), goodTargets
, highlightNodes
);
191 webViewImpl
->enableTapHighlights(highlightNodes
);
192 EXPECT_EQ(2U, webViewImpl
->numLinkHighlights());
194 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();