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

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, 2 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
« no previous file with comments | « Source/web/WebDocument.cpp ('k') | public/web/WebDocument.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "RuntimeEnabledFeatures.h" 38 #include "RuntimeEnabledFeatures.h"
38 #include "SkBitmap.h" 39 #include "SkBitmap.h"
39 #include "SkCanvas.h" 40 #include "SkCanvas.h"
40 #include "URLTestHelpers.h" 41 #include "URLTestHelpers.h"
41 #include "WebDataSource.h" 42 #include "WebDataSource.h"
42 #include "WebDocument.h" 43 #include "WebDocument.h"
43 #include "WebFindOptions.h" 44 #include "WebFindOptions.h"
44 #include "WebFormElement.h" 45 #include "WebFormElement.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 #include "core/rendering/RenderView.h" 79 #include "core/rendering/RenderView.h"
79 #include "core/rendering/TextAutosizer.h" 80 #include "core/rendering/TextAutosizer.h"
80 #include "v8.h" 81 #include "v8.h"
81 #include "public/platform/Platform.h" 82 #include "public/platform/Platform.h"
82 #include "public/platform/WebFloatRect.h" 83 #include "public/platform/WebFloatRect.h"
83 #include "public/platform/WebThread.h" 84 #include "public/platform/WebThread.h"
84 #include "public/platform/WebUnitTestSupport.h" 85 #include "public/platform/WebUnitTestSupport.h"
85 #include "public/platform/WebURLResponse.h" 86 #include "public/platform/WebURLResponse.h"
86 #include "wtf/dtoa/utils.h" 87 #include "wtf/dtoa/utils.h"
87 #include "wtf/Forward.h" 88 #include "wtf/Forward.h"
89 #include <map>
88 90
89 using namespace WebKit; 91 using namespace WebKit;
90 using WebCore::Document; 92 using WebCore::Document;
91 using WebCore::DocumentMarker; 93 using WebCore::DocumentMarker;
92 using WebCore::Element; 94 using WebCore::Element;
93 using WebCore::FloatRect; 95 using WebCore::FloatRect;
94 using WebCore::HitTestRequest; 96 using WebCore::HitTestRequest;
95 using WebCore::Range; 97 using WebCore::Range;
96 using WebKit::URLTestHelpers::toKURL; 98 using WebKit::URLTestHelpers::toKURL;
97 using WebKit::FrameTestHelpers::runPendingTasks; 99 using WebKit::FrameTestHelpers::runPendingTasks;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascrip t:document.body.appendChild(document.createTextNode('Clobbered'))"); 280 FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascrip t:document.body.appendChild(document.createTextNode('Clobbered'))");
279 281
280 // Required to see any updates in contentAsText. 282 // Required to see any updates in contentAsText.
281 webViewHelper.webView()->layout(); 283 webViewHelper.webView()->layout();
282 284
283 // Now retrieve the frame's text and ensure it wasn't modified by running ja vascript. 285 // Now retrieve the frame's text and ensure it wasn't modified by running ja vascript.
284 std::string content = std::string(webViewHelper.webView()->mainFrame()->cont entAsText(1024).utf8().data()); 286 std::string content = std::string(webViewHelper.webView()->mainFrame()->cont entAsText(1024).utf8().data());
285 EXPECT_EQ(std::string::npos, content.find("Clobbered")); 287 EXPECT_EQ(std::string::npos, content.find("Clobbered"));
286 } 288 }
287 289
290 class CSSCallbackWebFrameClient : public WebFrameClient {
291 public:
292 CSSCallbackWebFrameClient() : m_updateCount(0) { }
293 virtual void didMatchCSS(WebFrame*, const WebVector<WebString>& newlyMatchin gSelectors, const WebVector<WebString>& stoppedMatchingSelectors) OVERRIDE;
294
295 std::map<WebFrame*, std::set<std::string> > m_matchedSelectors;
296 int m_updateCount;
297 };
298
299 void CSSCallbackWebFrameClient::didMatchCSS(WebFrame* frame, const WebVector<Web String>& newlyMatchingSelectors, const WebVector<WebString>& stoppedMatchingSele ctors)
300 {
301 ++m_updateCount;
302 std::set<std::string>& frameSelectors = m_matchedSelectors[frame];
303 for (size_t i = 0; i < newlyMatchingSelectors.size(); ++i) {
304 std::string selector = newlyMatchingSelectors[i].utf8();
305 EXPECT_EQ(0U, frameSelectors.count(selector)) << selector;
306 frameSelectors.insert(selector);
307 }
308 for (size_t i = 0; i < stoppedMatchingSelectors.size(); ++i) {
309 std::string selector = stoppedMatchingSelectors[i].utf8();
310 EXPECT_EQ(1U, frameSelectors.count(selector)) << selector;
311 frameSelectors.erase(selector);
312 }
313 }
314
315 class WebFrameCSSCallbackTest : public testing::Test {
316 protected:
317 WebFrameCSSCallbackTest()
318 {
319
320 m_frame = m_helper.initializeAndLoad("about:blank", true, &m_client)->ma inFrame();
321 }
322
323 ~WebFrameCSSCallbackTest()
324 {
325 EXPECT_EQ(1U, m_client.m_matchedSelectors.size());
326 }
327
328 WebDocument doc() const
329 {
330 return m_frame->document();
331 }
332
333 int updateCount() const
334 {
335 return m_client.m_updateCount;
336 }
337
338 const std::set<std::string>& matchedSelectors()
339 {
340 return m_client.m_matchedSelectors[m_frame];
341 }
342
343 void loadHTML(const WebData& html)
344 {
345 m_frame->loadHTMLString(html, toKURL("about:blank"));
346 runPendingTasks();
347 }
348
349 void executeScript(const WebString& code)
350 {
351 m_frame->executeScript(WebScriptSource(code));
352 runPendingTasks();
353 }
354
355 CSSCallbackWebFrameClient m_client;
356 FrameTestHelpers::WebViewHelper m_helper;
357 WebFrame* m_frame;
358 };
359
360 TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet)
361 {
362 loadHTML(
363 "<style>"
364 // This stylesheet checks that the internal property and value can't be
365 // set by a stylesheet, only WebDocument::watchCSSSelectors().
366 "div.initial_on { -internal-callback: none; }"
367 "div.initial_off { -internal-callback: -internal-presence; }"
368 "</style>"
369 "<div class=\"initial_on\"></div>"
370 "<div class=\"initial_off\"></div>");
371
372 std::vector<WebString> selectors;
373 selectors.push_back(WebString::fromUTF8("div.initial_on"));
374 m_frame->document().watchCSSSelectors(WebVector<WebString>(selectors));
375 runPendingTasks();
376 EXPECT_EQ(1, updateCount());
377 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_on"));
378
379 // Check that adding a watched selector calls back for already-present nodes .
380 selectors.push_back(WebString::fromUTF8("div.initial_off"));
381 doc().watchCSSSelectors(WebVector<WebString>(selectors));
382 runPendingTasks();
383 EXPECT_EQ(2, updateCount());
384 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_off", "div .initial_on"));
385
386 // Check that we can turn off callbacks for certain selectors.
387 doc().watchCSSSelectors(WebVector<WebString>());
388 runPendingTasks();
389 EXPECT_EQ(3, updateCount());
390 EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
391 }
392
393 TEST_F(WebFrameCSSCallbackTest, SharedRenderStyle)
394 {
395 // Check that adding an element calls back when it matches an existing rule.
396 std::vector<WebString> selectors;
397 selectors.push_back(WebString::fromUTF8("span"));
398 doc().watchCSSSelectors(WebVector<WebString>(selectors));
399
400 executeScript(
401 "i1 = document.createElement('span');"
402 "i1.id = 'first_span';"
403 "document.body.appendChild(i1)");
404 EXPECT_EQ(1, updateCount());
405 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
406
407 // Adding a second element that shares a RenderStyle shouldn't call back.
408 // We use <span>s to avoid default style rules that can set
409 // RenderStyle::unique().
410 executeScript(
411 "i2 = document.createElement('span');"
412 "i2.id = 'second_span';"
413 "i1 = document.getElementById('first_span');"
414 "i1.parentNode.insertBefore(i2, i1.nextSibling);");
415 EXPECT_EQ(1, updateCount());
416 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
417
418 // Removing the first element shouldn't call back.
419 executeScript(
420 "i1 = document.getElementById('first_span');"
421 "i1.parentNode.removeChild(i1);");
422 EXPECT_EQ(1, updateCount());
423 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
424
425 // But removing the second element *should* call back.
426 executeScript(
427 "i2 = document.getElementById('second_span');"
428 "i2.parentNode.removeChild(i2);");
429 EXPECT_EQ(2, updateCount());
430 EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
431 }
432
433 TEST_F(WebFrameCSSCallbackTest, CatchesAttributeChange)
434 {
435 loadHTML("<span></span>");
436
437 std::vector<WebString> selectors;
438 selectors.push_back(WebString::fromUTF8("span[attr=\"value\"]"));
439 doc().watchCSSSelectors(WebVector<WebString>(selectors));
440 runPendingTasks();
441
442 EXPECT_EQ(0, updateCount());
443 EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
444
445 executeScript(
446 "document.querySelector('span').setAttribute('attr', 'value');");
447 EXPECT_EQ(1, updateCount());
448 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span[attr=\"value\"]") );
449 }
450
451 TEST_F(WebFrameCSSCallbackTest, DisplayNone)
452 {
453 loadHTML("<div style='display:none'><span></span></div>");
454
455 std::vector<WebString> selectors;
456 selectors.push_back(WebString::fromUTF8("span"));
457 doc().watchCSSSelectors(WebVector<WebString>(selectors));
458 runPendingTasks();
459
460 EXPECT_EQ(0, updateCount()) << "Don't match elements in display:none trees." ;
461
462 executeScript(
463 "d = document.querySelector('div');"
464 "d.style.display = 'block';");
465 EXPECT_EQ(1, updateCount()) << "Match elements when they become displayed.";
466 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
467
468 executeScript(
469 "d = document.querySelector('div');"
470 "d.style.display = 'none';");
471 EXPECT_EQ(2, updateCount()) << "Unmatch elements when they become undisplaye d.";
472 EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
473
474 executeScript(
475 "s = document.querySelector('span');"
476 "s.style.display = 'none';");
477 EXPECT_EQ(2, updateCount()) << "No effect from no-display'ing a span that's already undisplayed.";
478
479 executeScript(
480 "d = document.querySelector('div');"
481 "d.style.display = 'block';");
482 EXPECT_EQ(2, updateCount()) << "No effect from displaying a div whose span i s display:none.";
483
484 executeScript(
485 "s = document.querySelector('span');"
486 "s.style.display = 'inline';");
487 EXPECT_EQ(3, updateCount()) << "Now the span is visible and produces a callb ack.";
488 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
489
490 executeScript(
491 "s = document.querySelector('span');"
492 "s.style.display = 'none';");
493 EXPECT_EQ(4, updateCount()) << "Undisplaying the span directly should produc e another callback.";
494 EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
495 }
496
497 TEST_F(WebFrameCSSCallbackTest, Reparenting)
498 {
499 loadHTML(
500 "<div id='d1'><span></span></div>"
501 "<div id='d2'></div>");
502
503 std::vector<WebString> selectors;
504 selectors.push_back(WebString::fromUTF8("span"));
505 doc().watchCSSSelectors(WebVector<WebString>(selectors));
506 runPendingTasks();
507
508 EXPECT_EQ(1, updateCount());
509 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
510
511 executeScript(
512 "s = document.querySelector('span');"
513 "d2 = document.getElementById('d2');"
514 "d2.appendChild(s);");
515 EXPECT_EQ(1, updateCount()) << "Just moving an element that continues to mat ch shouldn't send a spurious callback.";
516 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
517 }
518
519 TEST_F(WebFrameCSSCallbackTest, MultiSelector)
520 {
521 loadHTML("<span></span>");
522
523 // Check that selector lists match as the whole list, not as each element
524 // independently.
525 std::vector<WebString> selectors;
526 selectors.push_back(WebString::fromUTF8("span"));
527 selectors.push_back(WebString::fromUTF8("span,p"));
528 doc().watchCSSSelectors(WebVector<WebString>(selectors));
529
530 runPendingTasks();
531 EXPECT_EQ(1, updateCount());
532 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span", "span, p"));
533 }
534
535 TEST_F(WebFrameCSSCallbackTest, InvalidSelector)
536 {
537 loadHTML("<p><span></span></p>");
538
539 // Build a list with one valid selector and one invalid.
540 std::vector<WebString> selectors;
541 selectors.push_back(WebString::fromUTF8("span"));
542 selectors.push_back(WebString::fromUTF8("[")); // Invalid.
543 selectors.push_back(WebString::fromUTF8("p span")); // Not compound.
544 doc().watchCSSSelectors(WebVector<WebString>(selectors));
545
546 runPendingTasks();
547 EXPECT_EQ(1, updateCount());
548 EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"))
549 << "An invalid selector shouldn't prevent other selectors from matching. ";
550 }
551
288 TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck) 552 TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck)
289 { 553 {
290 registerMockedHttpURLLoad("postmessage_test.html"); 554 registerMockedHttpURLLoad("postmessage_test.html");
291 555
292 // Pass true to enable JavaScript. 556 // Pass true to enable JavaScript.
293 FrameTestHelpers::WebViewHelper webViewHelper; 557 FrameTestHelpers::WebViewHelper webViewHelper;
294 webViewHelper.initializeAndLoad(m_baseURL + "postmessage_test.html", true); 558 webViewHelper.initializeAndLoad(m_baseURL + "postmessage_test.html", true);
295 559
296 // Send a message with the correct origin. 560 // Send a message with the correct origin.
297 WebSecurityOrigin correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL)) ); 561 WebSecurityOrigin correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL)) );
(...skipping 3761 matching lines...) Expand 10 before | Expand all | Expand 10 after
4059 TestStartStopCallbackWebViewClient client; 4323 TestStartStopCallbackWebViewClient client;
4060 FrameTestHelpers::WebViewHelper webViewHelper; 4324 FrameTestHelpers::WebViewHelper webViewHelper;
4061 webViewHelper.initializeAndLoad(m_baseURL + "push_state.html", true, 0, &cli ent); 4325 webViewHelper.initializeAndLoad(m_baseURL + "push_state.html", true, 0, &cli ent);
4062 runPendingTasks(); 4326 runPendingTasks();
4063 4327
4064 EXPECT_EQ(client.startLoadingCount(), 2); 4328 EXPECT_EQ(client.startLoadingCount(), 2);
4065 EXPECT_EQ(client.stopLoadingCount(), 2); 4329 EXPECT_EQ(client.stopLoadingCount(), 2);
4066 } 4330 }
4067 4331
4068 } // namespace 4332 } // namespace
OLDNEW
« no previous file with comments | « Source/web/WebDocument.cpp ('k') | public/web/WebDocument.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698