| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 // To ensure that the references on the stack are also traced, we | 134 // To ensure that the references on the stack are also traced, we |
| 135 // turn them into persistent, stack allocated references. This | 135 // turn them into persistent, stack allocated references. This |
| 136 // workaround is sufficient to handle this artificial test | 136 // workaround is sufficient to handle this artificial test |
| 137 // scenario. | 137 // scenario. |
| 138 WebView* webView = setupTest(file, client); | 138 WebView* webView = setupTest(file, client); |
| 139 | 139 |
| 140 Persistent<Document> document = | 140 Persistent<Document> document = |
| 141 static_cast<Document*>(webView->mainFrame()->document()); | 141 static_cast<Document*>(webView->mainFrame()->document()); |
| 142 runTestOnTree(document.get(), webView, client); | 142 runTestOnTree(document.get(), webView, client); |
| 143 | 143 |
| 144 m_webViewHelper | 144 // Explicitly reset to break dependency on locally scoped client. |
| 145 .reset(); // Explicitly reset to break dependency on locally scoped clien
t. | 145 m_webViewHelper.reset(); |
| 146 } | 146 } |
| 147 | 147 |
| 148 void TouchActionTest::runShadowDOMTest(std::string file) { | 148 void TouchActionTest::runShadowDOMTest(std::string file) { |
| 149 TouchActionTrackingWebViewClient client; | 149 TouchActionTrackingWebViewClient client; |
| 150 | 150 |
| 151 WebView* webView = setupTest(file, client); | 151 WebView* webView = setupTest(file, client); |
| 152 | 152 |
| 153 TrackExceptionState es; | 153 TrackExceptionState es; |
| 154 | 154 |
| 155 // Oilpan: see runTouchActionTest() comment why these are persistent reference
s. | 155 // Oilpan: see runTouchActionTest() comment why these are persistent |
| 156 // references. |
| 156 Persistent<Document> document = | 157 Persistent<Document> document = |
| 157 static_cast<Document*>(webView->mainFrame()->document()); | 158 static_cast<Document*>(webView->mainFrame()->document()); |
| 158 Persistent<StaticElementList> hostNodes = | 159 Persistent<StaticElementList> hostNodes = |
| 159 document->querySelectorAll("[shadow-host]", es); | 160 document->querySelectorAll("[shadow-host]", es); |
| 160 ASSERT_FALSE(es.hadException()); | 161 ASSERT_FALSE(es.hadException()); |
| 161 ASSERT_GE(hostNodes->length(), 1u); | 162 ASSERT_GE(hostNodes->length(), 1u); |
| 162 | 163 |
| 163 for (unsigned index = 0; index < hostNodes->length(); index++) { | 164 for (unsigned index = 0; index < hostNodes->length(); index++) { |
| 164 ShadowRoot* shadowRoot = hostNodes->item(index)->openShadowRoot(); | 165 ShadowRoot* shadowRoot = hostNodes->item(index)->openShadowRoot(); |
| 165 runTestOnTree(shadowRoot, webView, client); | 166 runTestOnTree(shadowRoot, webView, client); |
| 166 } | 167 } |
| 167 | 168 |
| 168 // Projections show up in the main document. | 169 // Projections show up in the main document. |
| 169 runTestOnTree(document.get(), webView, client); | 170 runTestOnTree(document.get(), webView, client); |
| 170 | 171 |
| 171 m_webViewHelper | 172 // Explicitly reset to break dependency on locally scoped client. |
| 172 .reset(); // Explicitly reset to break dependency on locally scoped clien
t. | 173 m_webViewHelper.reset(); |
| 173 } | 174 } |
| 174 | 175 |
| 175 void TouchActionTest::runIFrameTest(std::string file) { | 176 void TouchActionTest::runIFrameTest(std::string file) { |
| 176 TouchActionTrackingWebViewClient client; | 177 TouchActionTrackingWebViewClient client; |
| 177 | 178 |
| 178 WebView* webView = setupTest(file, client); | 179 WebView* webView = setupTest(file, client); |
| 179 WebFrame* curFrame = webView->mainFrame()->firstChild(); | 180 WebFrame* curFrame = webView->mainFrame()->firstChild(); |
| 180 ASSERT_TRUE(curFrame); | 181 ASSERT_TRUE(curFrame); |
| 181 | 182 |
| 182 for (; curFrame; curFrame = curFrame->nextSibling()) { | 183 for (; curFrame; curFrame = curFrame->nextSibling()) { |
| 183 // Oilpan: see runTouchActionTest() comment why these are persistent referen
ces. | 184 // Oilpan: see runTouchActionTest() comment why these are persistent |
| 185 // references. |
| 184 Persistent<Document> contentDoc = | 186 Persistent<Document> contentDoc = |
| 185 static_cast<Document*>(curFrame->document()); | 187 static_cast<Document*>(curFrame->document()); |
| 186 runTestOnTree(contentDoc.get(), webView, client); | 188 runTestOnTree(contentDoc.get(), webView, client); |
| 187 } | 189 } |
| 188 | 190 |
| 189 m_webViewHelper | 191 // Explicitly reset to break dependency on locally scoped client. |
| 190 .reset(); // Explicitly reset to break dependency on locally scoped clien
t. | 192 m_webViewHelper.reset(); |
| 191 } | 193 } |
| 192 | 194 |
| 193 WebView* TouchActionTest::setupTest(std::string file, | 195 WebView* TouchActionTest::setupTest(std::string file, |
| 194 TouchActionTrackingWebViewClient& client) { | 196 TouchActionTrackingWebViewClient& client) { |
| 195 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL), | 197 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL), |
| 196 WebString::fromUTF8(file)); | 198 WebString::fromUTF8(file)); |
| 197 // Note that JavaScript must be enabled for shadow DOM tests. | 199 // Note that JavaScript must be enabled for shadow DOM tests. |
| 198 WebView* webView = | 200 WebView* webView = |
| 199 m_webViewHelper.initializeAndLoad(m_baseURL + file, true, 0, &client); | 201 m_webViewHelper.initializeAndLoad(m_baseURL + file, true, 0, &client); |
| 200 | 202 |
| 201 // Set size to enable hit testing, and avoid line wrapping for consistency wit
h browser. | 203 // Set size to enable hit testing, and avoid line wrapping for consistency |
| 204 // with browser. |
| 202 webView->resize(WebSize(800, 1200)); | 205 webView->resize(WebSize(800, 1200)); |
| 203 | 206 |
| 204 // Scroll to verify the code properly transforms windows to client co-ords. | 207 // Scroll to verify the code properly transforms windows to client co-ords. |
| 205 const int kScrollOffset = 100; | 208 const int kScrollOffset = 100; |
| 206 Document* document = static_cast<Document*>(webView->mainFrame()->document()); | 209 Document* document = static_cast<Document*>(webView->mainFrame()->document()); |
| 207 document->frame()->view()->setScrollPosition(IntPoint(0, kScrollOffset), | 210 document->frame()->view()->setScrollPosition(IntPoint(0, kScrollOffset), |
| 208 ProgrammaticScroll); | 211 ProgrammaticScroll); |
| 209 | 212 |
| 210 return webView; | 213 return webView; |
| 211 } | 214 } |
| 212 | 215 |
| 213 IntRect windowClipRect(const FrameView& frameView) { | 216 IntRect windowClipRect(const FrameView& frameView) { |
| 214 LayoutRect clipRect( | 217 LayoutRect clipRect( |
| 215 LayoutPoint(), | 218 LayoutPoint(), |
| 216 LayoutSize(frameView.visibleContentSize(ExcludeScrollbars))); | 219 LayoutSize(frameView.visibleContentSize(ExcludeScrollbars))); |
| 217 frameView.layoutViewItem().mapToVisualRectInAncestorSpace( | 220 frameView.layoutViewItem().mapToVisualRectInAncestorSpace( |
| 218 &frameView.layoutView()->containerForPaintInvalidation(), clipRect); | 221 &frameView.layoutView()->containerForPaintInvalidation(), clipRect); |
| 219 return enclosingIntRect(clipRect); | 222 return enclosingIntRect(clipRect); |
| 220 } | 223 } |
| 221 | 224 |
| 222 void TouchActionTest::runTestOnTree(ContainerNode* root, | 225 void TouchActionTest::runTestOnTree(ContainerNode* root, |
| 223 WebView* webView, | 226 WebView* webView, |
| 224 TouchActionTrackingWebViewClient& client) { | 227 TouchActionTrackingWebViewClient& client) { |
| 225 // Find all elements to test the touch-action of in the document. | 228 // Find all elements to test the touch-action of in the document. |
| 226 TrackExceptionState es; | 229 TrackExceptionState es; |
| 227 | 230 |
| 228 // Oilpan: see runTouchActionTest() comment why these are persistent reference
s. | 231 // Oilpan: see runTouchActionTest() comment why these are persistent |
| 232 // references. |
| 229 Persistent<StaticElementList> elements = | 233 Persistent<StaticElementList> elements = |
| 230 root->querySelectorAll("[expected-action]", es); | 234 root->querySelectorAll("[expected-action]", es); |
| 231 ASSERT_FALSE(es.hadException()); | 235 ASSERT_FALSE(es.hadException()); |
| 232 | 236 |
| 233 for (unsigned index = 0; index < elements->length(); index++) { | 237 for (unsigned index = 0; index < elements->length(); index++) { |
| 234 Element* element = elements->item(index); | 238 Element* element = elements->item(index); |
| 235 element->scrollIntoViewIfNeeded(); | 239 element->scrollIntoViewIfNeeded(); |
| 236 | 240 |
| 237 std::string failureContext("Test case: "); | 241 std::string failureContext("Test case: "); |
| 238 if (element->hasID()) { | 242 if (element->hasID()) { |
| 239 failureContext.append(element->getIdAttribute().ascii().data()); | 243 failureContext.append(element->getIdAttribute().ascii().data()); |
| 240 } else if (element->firstChild()) { | 244 } else if (element->firstChild()) { |
| 241 failureContext.append("\""); | 245 failureContext.append("\""); |
| 242 failureContext.append(element->firstChild() | 246 failureContext.append(element->firstChild() |
| 243 ->textContent(false) | 247 ->textContent(false) |
| 244 .stripWhiteSpace() | 248 .stripWhiteSpace() |
| 245 .ascii() | 249 .ascii() |
| 246 .data()); | 250 .data()); |
| 247 failureContext.append("\""); | 251 failureContext.append("\""); |
| 248 } else { | 252 } else { |
| 249 failureContext += "<missing ID>"; | 253 failureContext += "<missing ID>"; |
| 250 } | 254 } |
| 251 | 255 |
| 252 // Run each test three times at different positions in the element. | 256 // Run each test three times at different positions in the element. |
| 253 // Note that we don't want the bounding box because our tests sometimes have
elements with | 257 // Note that we don't want the bounding box because our tests sometimes have |
| 254 // multiple border boxes with other elements in between. Use the first borde
r box (which | 258 // elements with multiple border boxes with other elements in between. Use |
| 255 // we can easily visualize in a browser for debugging). | 259 // the first border box (which we can easily visualize in a browser for |
| 260 // debugging). |
| 256 Persistent<ClientRectList> rects = element->getClientRects(); | 261 Persistent<ClientRectList> rects = element->getClientRects(); |
| 257 ASSERT_GE(rects->length(), 0u) << failureContext; | 262 ASSERT_GE(rects->length(), 0u) << failureContext; |
| 258 Persistent<ClientRect> r = rects->item(0); | 263 Persistent<ClientRect> r = rects->item(0); |
| 259 FloatRect clientFloatRect = | 264 FloatRect clientFloatRect = |
| 260 FloatRect(r->left(), r->top(), r->width(), r->height()); | 265 FloatRect(r->left(), r->top(), r->width(), r->height()); |
| 261 IntRect clientRect = enclosedIntRect(clientFloatRect); | 266 IntRect clientRect = enclosedIntRect(clientFloatRect); |
| 262 for (int locIdx = 0; locIdx < 3; locIdx++) { | 267 for (int locIdx = 0; locIdx < 3; locIdx++) { |
| 263 IntPoint framePoint; | 268 IntPoint framePoint; |
| 264 std::stringstream contextStream; | 269 std::stringstream contextStream; |
| 265 contextStream << failureContext << " ("; | 270 contextStream << failureContext << " ("; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 289 LocalFrame* mainFrame = | 294 LocalFrame* mainFrame = |
| 290 static_cast<LocalFrame*>(webView->mainFrame()->toImplBase()->frame()); | 295 static_cast<LocalFrame*>(webView->mainFrame()->toImplBase()->frame()); |
| 291 FrameView* mainFrameView = mainFrame->view(); | 296 FrameView* mainFrameView = mainFrame->view(); |
| 292 IntRect visibleRect = windowClipRect(*mainFrameView); | 297 IntRect visibleRect = windowClipRect(*mainFrameView); |
| 293 ASSERT_TRUE(visibleRect.contains(windowPoint)) | 298 ASSERT_TRUE(visibleRect.contains(windowPoint)) |
| 294 << failureContextPos | 299 << failureContextPos |
| 295 << " Test point not contained in visible area: " << visibleRect.x() | 300 << " Test point not contained in visible area: " << visibleRect.x() |
| 296 << "," << visibleRect.y() << "-" << visibleRect.maxX() << "," | 301 << "," << visibleRect.y() << "-" << visibleRect.maxX() << "," |
| 297 << visibleRect.maxY(); | 302 << visibleRect.maxY(); |
| 298 | 303 |
| 299 // First validate that a hit test at this point will really hit the elemen
t | 304 // First validate that a hit test at this point will really hit the |
| 300 // we intended. This is the easiest way for a test to be broken, but has n
othing really | 305 // element we intended. This is the easiest way for a test to be broken, |
| 301 // to do with touch action. | 306 // but has nothing really to do with touch action. Note that we can't use |
| 302 // Note that we can't use WebView's hit test API because it doesn't look i
nto shadow DOM. | 307 // WebView's hit test API because it doesn't look into shadow DOM. |
| 303 IntPoint docPoint(mainFrameView->frameToContents(windowPoint)); | 308 IntPoint docPoint(mainFrameView->frameToContents(windowPoint)); |
| 304 HitTestResult result = mainFrame->eventHandler().hitTestResultAtPoint( | 309 HitTestResult result = mainFrame->eventHandler().hitTestResultAtPoint( |
| 305 docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active); | 310 docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active); |
| 306 ASSERT_EQ(element, result.innerElement()) | 311 ASSERT_EQ(element, result.innerElement()) |
| 307 << "Unexpected hit test result " << failureContextPos | 312 << "Unexpected hit test result " << failureContextPos |
| 308 << " Got element: \"" | 313 << " Got element: \"" |
| 309 << result.innerElement() | 314 << result.innerElement() |
| 310 ->outerHTML() | 315 ->outerHTML() |
| 311 .stripWhiteSpace() | 316 .stripWhiteSpace() |
| 312 .left(80) | 317 .left(80) |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 | 406 |
| 402 TEST_F(TouchActionTest, ShadowDOM) { | 407 TEST_F(TouchActionTest, ShadowDOM) { |
| 403 runShadowDOMTest("touch-action-shadow-dom.html"); | 408 runShadowDOMTest("touch-action-shadow-dom.html"); |
| 404 } | 409 } |
| 405 | 410 |
| 406 TEST_F(TouchActionTest, Pan) { | 411 TEST_F(TouchActionTest, Pan) { |
| 407 runTouchActionTest("touch-action-pan.html"); | 412 runTouchActionTest("touch-action-pan.html"); |
| 408 } | 413 } |
| 409 | 414 |
| 410 } // namespace blink | 415 } // namespace blink |
| OLD | NEW |