Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: Source/web/tests/WebFrameTest.cpp

Issue 18371008: Add a WebDocument::watchCssSelectors(selectors) (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@pinned
Patch Set: Sync Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698