1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 23 */ 24 25 #include "config.h" 26 27 #include "LinkHighlight.h" 28 29 #include <gtest/gtest.h> 30 #include "FrameTestHelpers.h" 31 #include "URLTestHelpers.h" 32 #include "WebFrame.h" 33 #include "WebFrameClient.h" 34 #include "WebFrameImpl.h" 35 #include "WebInputEvent.h" 36 #include "WebInputEventConversion.h" 37 #include "WebViewClient.h" 38 #include "WebViewImpl.h" 39 #include "bindings/v8/ExceptionStatePlaceholder.h" 40 #include "core/dom/Node.h" 41 #include "core/page/FrameView.h" 42 #include "core/platform/graphics/IntRect.h" 43 #include "public/platform/Platform.h" 44 #include "public/platform/WebContentLayer.h" 45 #include "public/platform/WebFloatPoint.h" 46 #include "public/platform/WebSize.h" 47 #include "public/platform/WebUnitTestSupport.h" 48 #include "wtf/PassOwnPtr.h" 49 50 51 using namespace WebKit; 52 using namespace WebCore; 53 54 namespace { 55 56 TEST(LinkHighlightTest, verifyWebViewImplIntegration) 57 { 58 const std::string baseURL("http://www.test.com/"); 59 const std::string fileName("test_touch_link_highlight.html"); 60 61 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("test_touch_link_highlight.html")); 62 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(baseURL + fileName, true)); 63 int pageWidth = 640; 64 int pageHeight = 480; 65 webViewImpl->resize(WebSize(pageWidth, pageHeight)); 66 webViewImpl->layout(); 67 68 WebGestureEvent touchEvent; 69 touchEvent.type = WebInputEvent::GestureTapDown; 70 71 // The coordinates below are linked to absolute positions in the referenced .html file. 72 touchEvent.x = 20; 73 touchEvent.y = 20; 74 75 { 76 PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent); 77 Node* touchNode = webViewImpl->bestTapNode(platformEvent); 78 ASSERT_TRUE(touchNode); 79 } 80 81 touchEvent.y = 40; 82 { 83 PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent); 84 EXPECT_FALSE(webViewImpl->bestTapNode(platformEvent)); 85 } 86 87 touchEvent.y = 20; 88 // Shouldn't crash. 89 90 { 91 PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent); 92 webViewImpl->enableTapHighlight(platformEvent); 93 } 94 95 EXPECT_TRUE(webViewImpl->linkHighlight()); 96 EXPECT_TRUE(webViewImpl->linkHighlight()->contentLayer()); 97 EXPECT_TRUE(webViewImpl->linkHighlight()->clipLayer()); 98 99 // Find a target inside a scrollable div 100 101 touchEvent.y = 100; 102 { 103 PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent); 104 webViewImpl->enableTapHighlight(platformEvent); 105 } 106 107 ASSERT_TRUE(webViewImpl->linkHighlight()); 108 109 // Don't highlight if no "hand cursor" 110 touchEvent.y = 220; // An A-link with cross-hair cursor. 111 { 112 PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent); 113 webViewImpl->enableTapHighlight(platformEvent); 114 } 115 ASSERT_FALSE(webViewImpl->linkHighlight()); 116 117 touchEvent.y = 260; // A text input box. 118 { 119 PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent); 120 webViewImpl->enableTapHighlight(platformEvent); 121 } 122 ASSERT_FALSE(webViewImpl->linkHighlight()); 123 124 webViewImpl->close(); 125 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); 126 } 127 128 class FakeWebFrameClient : public WebFrameClient { 129 // To make the destructor public. 130 }; 131 132 class FakeCompositingWebViewClient : public WebViewClient { 133 public: 134 virtual ~FakeCompositingWebViewClient() 135 { 136 } 137 138 virtual void initializeLayerTreeView() OVERRIDE 139 { 140 m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLayerTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest)); 141 ASSERT(m_layerTreeView); 142 } 143 144 virtual WebLayerTreeView* layerTreeView() OVERRIDE 145 { 146 return m_layerTreeView.get(); 147 } 148 149 FakeWebFrameClient m_fakeWebFrameClient; 150 151 private: 152 OwnPtr<WebLayerTreeView> m_layerTreeView; 153 }; 154 155 static WebViewClient* compositingWebViewClient() 156 { 157 DEFINE_STATIC_LOCAL(FakeCompositingWebViewClient, client, ()); 158 return &client; 159 } 160 161 TEST(LinkHighlightTest, resetDuringNodeRemoval) 162 { 163 const std::string baseURL("http://www.test.com/"); 164 const std::string fileName("test_touch_link_highlight.html"); 165 166 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("test_touch_link_highlight.html")); 167 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(baseURL + fileName, true, 0, compositingWebViewClient())); 168 169 int pageWidth = 640; 170 int pageHeight = 480; 171 webViewImpl->resize(WebSize(pageWidth, pageHeight)); 172 webViewImpl->layout(); 173 174 WebGestureEvent touchEvent; 175 touchEvent.type = WebInputEvent::GestureTapDown; 176 touchEvent.x = 20; 177 touchEvent.y = 20; 178 179 PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent); 180 Node* touchNode = webViewImpl->bestTapNode(platformEvent); 181 ASSERT_TRUE(touchNode); 182 183 webViewImpl->enableTapHighlight(platformEvent); 184 ASSERT_TRUE(webViewImpl->linkHighlight()); 185 186 GraphicsLayer* highlightLayer = webViewImpl->linkHighlight()->currentGraphicsLayerForTesting(); 187 ASSERT_TRUE(highlightLayer); 188 EXPECT_TRUE(highlightLayer->linkHighlight()); 189 190 touchNode->remove(IGNORE_EXCEPTION); 191 webViewImpl->layout(); 192 EXPECT_FALSE(highlightLayer->linkHighlight()); 193 194 webViewImpl->close(); 195 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); 196 } 197 198 } // namespace 199