OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 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 14 matching lines...) Expand all Loading... | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 | 32 |
33 #include "WebFrame.h" | 33 #include "WebFrame.h" |
34 | 34 |
35 #include <gmock/gmock.h> | |
35 #include <gtest/gtest.h> | 36 #include <gtest/gtest.h> |
36 #include "FrameTestHelpers.h" | 37 #include "FrameTestHelpers.h" |
37 #include "SkBitmap.h" | 38 #include "SkBitmap.h" |
38 #include "SkCanvas.h" | 39 #include "SkCanvas.h" |
39 #include "URLTestHelpers.h" | 40 #include "URLTestHelpers.h" |
40 #include "WebDataSource.h" | 41 #include "WebDataSource.h" |
41 #include "WebDocument.h" | 42 #include "WebDocument.h" |
42 #include "WebFindOptions.h" | 43 #include "WebFindOptions.h" |
43 #include "WebFormElement.h" | 44 #include "WebFormElement.h" |
44 #include "WebFrameClient.h" | 45 #include "WebFrameClient.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
77 #include "core/rendering/RenderView.h" | 78 #include "core/rendering/RenderView.h" |
78 #include "core/rendering/TextAutosizer.h" | 79 #include "core/rendering/TextAutosizer.h" |
79 #include "v8.h" | 80 #include "v8.h" |
80 #include "public/platform/Platform.h" | 81 #include "public/platform/Platform.h" |
81 #include "public/platform/WebFloatRect.h" | 82 #include "public/platform/WebFloatRect.h" |
82 #include "public/platform/WebThread.h" | 83 #include "public/platform/WebThread.h" |
83 #include "public/platform/WebUnitTestSupport.h" | 84 #include "public/platform/WebUnitTestSupport.h" |
84 #include "public/platform/WebURLResponse.h" | 85 #include "public/platform/WebURLResponse.h" |
85 #include "wtf/dtoa/utils.h" | 86 #include "wtf/dtoa/utils.h" |
86 #include "wtf/Forward.h" | 87 #include "wtf/Forward.h" |
88 #include <map> | |
87 | 89 |
88 using namespace WebKit; | 90 using namespace WebKit; |
89 using WebCore::Document; | 91 using WebCore::Document; |
90 using WebCore::DocumentMarker; | 92 using WebCore::DocumentMarker; |
91 using WebCore::Element; | 93 using WebCore::Element; |
92 using WebCore::FloatRect; | 94 using WebCore::FloatRect; |
93 using WebCore::HitTestRequest; | 95 using WebCore::HitTestRequest; |
94 using WebCore::Range; | 96 using WebCore::Range; |
95 using WebKit::URLTestHelpers::toKURL; | 97 using WebKit::URLTestHelpers::toKURL; |
96 using WebKit::FrameTestHelpers::runPendingTasks; | 98 using WebKit::FrameTestHelpers::runPendingTasks; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 FrameTestHelpers::loadFrame(m_webView->mainFrame(), "javascript:document.bod y.appendChild(document.createTextNode('Clobbered'))"); | 272 FrameTestHelpers::loadFrame(m_webView->mainFrame(), "javascript:document.bod y.appendChild(document.createTextNode('Clobbered'))"); |
271 | 273 |
272 // Required to see any updates in contentAsText. | 274 // Required to see any updates in contentAsText. |
273 m_webView->layout(); | 275 m_webView->layout(); |
274 | 276 |
275 // Now retrieve the frame's text and ensure it wasn't modified by running ja vascript. | 277 // Now retrieve the frame's text and ensure it wasn't modified by running ja vascript. |
276 std::string content = std::string(m_webView->mainFrame()->contentAsText(1024 ).utf8().data()); | 278 std::string content = std::string(m_webView->mainFrame()->contentAsText(1024 ).utf8().data()); |
277 EXPECT_EQ(std::string::npos, content.find("Clobbered")); | 279 EXPECT_EQ(std::string::npos, content.find("Clobbered")); |
278 } | 280 } |
279 | 281 |
282 struct CSSCallbackWebFrameClient : public WebFrameClient { | |
esprehn
2013/09/04 06:08:28
class
Jeffrey Yasskin
2013/09/12 22:09:59
Done.
| |
283 CSSCallbackWebFrameClient() : m_updateCount(0) { } | |
284 virtual void didMatchCSS(WebFrame* frame, const WebVector<WebString>& newlyM atchingSelectors, const WebVector<WebString>& stoppedMatchingSelectors) OVERRIDE | |
esprehn
2013/09/04 06:08:28
I think we usually put long methods not in the cla
Jeffrey Yasskin
2013/09/12 22:09:59
Even in .cpp files? Ok.
| |
285 { | |
286 ++m_updateCount; | |
287 std::set<std::string>& frameSelectors = m_matchedSelectors[frame]; | |
288 for (size_t i = 0; i < newlyMatchingSelectors.size(); ++i) { | |
289 std::string selector = newlyMatchingSelectors[i].utf8(); | |
290 EXPECT_EQ(0U, frameSelectors.count(selector)) << selector; | |
291 frameSelectors.insert(selector); | |
292 } | |
293 for (size_t i = 0; i < stoppedMatchingSelectors.size(); ++i) { | |
294 std::string selector = stoppedMatchingSelectors[i].utf8(); | |
295 EXPECT_EQ(1U, frameSelectors.count(selector)) << selector; | |
296 frameSelectors.erase(selector); | |
297 } | |
298 } | |
299 | |
300 std::map<WebFrame*, std::set<std::string> > m_matchedSelectors; | |
301 int m_updateCount; | |
302 }; | |
303 | |
304 class WebFrameCSSCallbackTest : public testing::Test { | |
305 protected: | |
306 WebFrameCSSCallbackTest() | |
307 { | |
308 m_webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, &m_client); | |
309 m_frame = m_webView->mainFrame(); | |
310 } | |
311 | |
312 ~WebFrameCSSCallbackTest() | |
313 { | |
314 EXPECT_EQ(1U, m_client.m_matchedSelectors.size()); | |
315 m_webView->close(); | |
316 } | |
317 | |
318 WebDocument doc() const | |
319 { | |
320 return m_frame->document(); | |
321 } | |
322 | |
323 int updateCount() const | |
324 { | |
325 return m_client.m_updateCount; | |
326 } | |
327 | |
328 const std::set<std::string>& matchedSelectors() | |
329 { | |
330 return m_client.m_matchedSelectors[m_frame]; | |
331 } | |
332 | |
333 void loadHTML(const WebData& html) | |
334 { | |
335 m_frame->loadHTMLString(html, toKURL("about:blank")); | |
336 runPendingTasks(); | |
337 } | |
338 | |
339 void executeScript(const WebString& code) | |
340 { | |
341 m_frame->executeScript(WebScriptSource(code)); | |
342 runPendingTasks(); | |
343 } | |
344 | |
345 CSSCallbackWebFrameClient m_client; | |
346 WebView* m_webView; | |
347 WebFrame* m_frame; | |
348 }; | |
349 | |
350 TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet) | |
351 { | |
352 loadHTML( | |
353 "<style>" | |
354 // This stylesheet checks that the internal property and value can't be | |
355 // set by a stylesheet, only WebDocument::watchCSSSelectors(). | |
356 "div.initial_on { -internal-callback: none; }" | |
357 "div.initial_off { -internal-callback: -internal-presence; }" | |
358 "</style>" | |
359 "<div class=\"initial_on\"></div>" | |
360 "<div class=\"initial_off\"></div>"); | |
361 | |
362 std::vector<WebString> selectors; | |
363 selectors.push_back(WebString::fromUTF8("div.initial_on")); | |
364 m_frame->document().watchCSSSelectors(WebVector<WebString>(selectors)); | |
365 runPendingTasks(); | |
366 EXPECT_EQ(1, updateCount()); | |
367 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_on")); | |
368 | |
369 // Check that adding a watched selector calls back for already-present nodes . | |
370 selectors.push_back(WebString::fromUTF8("div.initial_off")); | |
371 doc().watchCSSSelectors(WebVector<WebString>(selectors)); | |
372 runPendingTasks(); | |
373 EXPECT_EQ(2, updateCount()); | |
374 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_off", "div .initial_on")); | |
375 | |
376 // Check that we can turn off callbacks for certain selectors. | |
377 doc().watchCSSSelectors(WebVector<WebString>()); | |
378 runPendingTasks(); | |
379 EXPECT_EQ(3, updateCount()); | |
380 EXPECT_THAT(matchedSelectors(), testing::ElementsAre()); | |
381 } | |
382 | |
383 TEST_F(WebFrameCSSCallbackTest, SharedRenderStyle) | |
384 { | |
385 // Check that adding an element calls back when it matches an existing rule. | |
386 std::vector<WebString> selectors; | |
387 selectors.push_back(WebString::fromUTF8("span")); | |
388 doc().watchCSSSelectors(WebVector<WebString>(selectors)); | |
389 | |
390 executeScript( | |
391 "i1 = document.createElement('span');" | |
392 "i1.id = 'first_span';" | |
393 "document.body.appendChild(i1)"); | |
394 EXPECT_EQ(1, updateCount()); | |
395 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")); | |
396 | |
397 // Adding a second element that shares a RenderStyle shouldn't call back. | |
398 // We use <span>s to avoid default style rules that can set | |
399 // RenderStyle::unique(). | |
400 executeScript( | |
401 "i2 = document.createElement('span');" | |
402 "i2.id = 'second_span';" | |
403 "i1 = document.getElementById('first_span');" | |
404 "i1.parentNode.insertBefore(i2, i1.nextSibling);"); | |
405 EXPECT_EQ(1, updateCount()); | |
406 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")); | |
407 | |
408 // Removing the first element shouldn't call back. | |
409 executeScript( | |
410 "i1 = document.getElementById('first_span');" | |
411 "i1.parentNode.removeChild(i1);"); | |
412 EXPECT_EQ(1, updateCount()); | |
413 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")); | |
414 | |
415 // But removing the second element *should* call back. | |
416 executeScript( | |
417 "i2 = document.getElementById('second_span');" | |
418 "i2.parentNode.removeChild(i2);"); | |
419 EXPECT_EQ(2, updateCount()); | |
420 EXPECT_THAT(matchedSelectors(), testing::ElementsAre()); | |
421 } | |
422 | |
423 TEST_F(WebFrameCSSCallbackTest, CatchesAttributeChange) | |
424 { | |
425 loadHTML("<span></span>"); | |
426 | |
427 std::vector<WebString> selectors; | |
428 selectors.push_back(WebString::fromUTF8("span[attr=\"value\"]")); | |
429 doc().watchCSSSelectors(WebVector<WebString>(selectors)); | |
430 runPendingTasks(); | |
431 | |
432 EXPECT_EQ(0, updateCount()); | |
433 EXPECT_THAT(matchedSelectors(), testing::ElementsAre()); | |
434 | |
435 executeScript( | |
436 "document.querySelector('span').setAttribute('attr', 'value');"); | |
437 EXPECT_EQ(1, updateCount()); | |
438 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span[attr=\"value\"]") ); | |
439 } | |
440 | |
441 TEST_F(WebFrameCSSCallbackTest, DisplayNone) | |
442 { | |
443 loadHTML("<div style='display:none'><span></span></div>"); | |
444 | |
445 std::vector<WebString> selectors; | |
446 selectors.push_back(WebString::fromUTF8("span")); | |
447 doc().watchCSSSelectors(WebVector<WebString>(selectors)); | |
448 runPendingTasks(); | |
449 | |
450 EXPECT_EQ(0, updateCount()) << "Don't match elements in display:none trees." ; | |
451 | |
452 executeScript( | |
453 "d = document.querySelector('div');" | |
454 "d.style.display = 'block';"); | |
455 EXPECT_EQ(1, updateCount()) << "Match elements when they become displayed."; | |
456 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")); | |
457 | |
458 executeScript( | |
459 "d = document.querySelector('div');" | |
460 "d.style.display = 'none';"); | |
461 EXPECT_EQ(2, updateCount()) << "Unmatch elements when they become undisplaye d."; | |
462 EXPECT_THAT(matchedSelectors(), testing::ElementsAre()); | |
463 | |
464 executeScript( | |
465 "s = document.querySelector('span');" | |
466 "s.style.display = 'none';"); | |
467 EXPECT_EQ(2, updateCount()) << "No effect from no-display'ing a span that's already undisplayed."; | |
468 | |
469 executeScript( | |
470 "d = document.querySelector('div');" | |
471 "d.style.display = 'block';"); | |
472 EXPECT_EQ(2, updateCount()) << "No effect from displaying a div whose span i s display:none."; | |
473 | |
474 executeScript( | |
475 "s = document.querySelector('span');" | |
476 "s.style.display = 'inline';"); | |
477 EXPECT_EQ(3, updateCount()) << "Now the span is visible and produces a callb ack."; | |
478 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")); | |
479 | |
480 executeScript( | |
481 "s = document.querySelector('span');" | |
482 "s.style.display = 'none';"); | |
483 EXPECT_EQ(4, updateCount()) << "Undisplaying the span directly should produc e another callback."; | |
484 EXPECT_THAT(matchedSelectors(), testing::ElementsAre()); | |
485 } | |
486 | |
487 TEST_F(WebFrameCSSCallbackTest, Reparenting) | |
488 { | |
489 loadHTML( | |
490 "<div id='d1'><span></span></div>" | |
491 "<div id='d2'></div>"); | |
492 | |
493 std::vector<WebString> selectors; | |
494 selectors.push_back(WebString::fromUTF8("span")); | |
495 doc().watchCSSSelectors(WebVector<WebString>(selectors)); | |
496 runPendingTasks(); | |
497 | |
498 EXPECT_EQ(1, updateCount()); | |
499 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")); | |
500 | |
501 executeScript( | |
502 "s = document.querySelector('span');" | |
503 "d2 = document.getElementById('d2');" | |
504 "d2.appendChild(s);"); | |
505 EXPECT_EQ(1, updateCount()) << "Just moving an element that continues to mat ch shouldn't send a spurious callback."; | |
506 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")); | |
507 } | |
508 | |
509 TEST_F(WebFrameCSSCallbackTest, MultiSelector) | |
510 { | |
511 loadHTML("<span></span>"); | |
512 | |
513 // Check that selector lists match as the whole list, not as each element | |
514 // independently. | |
515 std::vector<WebString> selectors; | |
516 selectors.push_back(WebString::fromUTF8("span")); | |
517 selectors.push_back(WebString::fromUTF8("span,p")); | |
518 doc().watchCSSSelectors(WebVector<WebString>(selectors)); | |
519 | |
520 runPendingTasks(); | |
521 EXPECT_EQ(1, updateCount()); | |
522 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span", "span, p")); | |
523 } | |
524 | |
525 TEST_F(WebFrameCSSCallbackTest, InvalidSelector) | |
526 { | |
527 loadHTML("<p><span></span></p>"); | |
528 | |
529 // Build a list with one valid selector and one invalid. | |
530 std::vector<WebString> selectors; | |
531 selectors.push_back(WebString::fromUTF8("span")); | |
532 selectors.push_back(WebString::fromUTF8("[")); // Invalid. | |
533 selectors.push_back(WebString::fromUTF8("p span")); // Not compound. | |
534 doc().watchCSSSelectors(WebVector<WebString>(selectors)); | |
535 | |
536 runPendingTasks(); | |
537 EXPECT_EQ(1, updateCount()); | |
538 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span")) | |
539 << "An invalid selector shouldn't prevent other selectors from matching. "; | |
540 } | |
541 | |
280 TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck) | 542 TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck) |
281 { | 543 { |
282 registerMockedHttpURLLoad("postmessage_test.html"); | 544 registerMockedHttpURLLoad("postmessage_test.html"); |
283 | 545 |
284 // Pass true to enable JavaScript. | 546 // Pass true to enable JavaScript. |
285 m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "postmessage_ test.html", true); | 547 m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "postmessage_ test.html", true); |
286 | 548 |
287 // Send a message with the correct origin. | 549 // Send a message with the correct origin. |
288 WebSecurityOrigin correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL)) ); | 550 WebSecurityOrigin correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL)) ); |
289 WebDOMEvent event = m_webView->mainFrame()->document().createEvent("MessageE vent"); | 551 WebDOMEvent event = m_webView->mainFrame()->document().createEvent("MessageE vent"); |
(...skipping 3303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3593 m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "push_state.h tml", true, 0, &client); | 3855 m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "push_state.h tml", true, 0, &client); |
3594 runPendingTasks(); | 3856 runPendingTasks(); |
3595 | 3857 |
3596 EXPECT_EQ(client.startLoadingCount(), 2); | 3858 EXPECT_EQ(client.startLoadingCount(), 2); |
3597 EXPECT_EQ(client.stopLoadingCount(), 2); | 3859 EXPECT_EQ(client.stopLoadingCount(), 2); |
3598 m_webView->close(); | 3860 m_webView->close(); |
3599 m_webView = 0; | 3861 m_webView = 0; |
3600 } | 3862 } |
3601 | 3863 |
3602 } // namespace | 3864 } // namespace |
OLD | NEW |