Index: Source/WebKit/chromium/tests/WebFrameTest.cpp |
diff --git a/Source/WebKit/chromium/tests/WebFrameTest.cpp b/Source/WebKit/chromium/tests/WebFrameTest.cpp |
index ac3158719c1ed8d1d615e058ac22feeb6a5ca04e..4e158224d0b0d17401677af2779a5d181448a012 100644 |
--- a/Source/WebKit/chromium/tests/WebFrameTest.cpp |
+++ b/Source/WebKit/chromium/tests/WebFrameTest.cpp |
@@ -32,6 +32,7 @@ |
#include "WebFrame.h" |
+#include <gmock/gmock.h> |
abarth-chromium
2013/07/12 23:44:11
I remember someone was telling us to avoid gmock..
Jeffrey Yasskin
2013/07/16 00:38:51
Actual mocks are often a mistake. Here I'm just us
|
#include <gtest/gtest.h> |
#include "FrameTestHelpers.h" |
#include "SkBitmap.h" |
@@ -75,12 +76,14 @@ |
#include "core/rendering/TextAutosizer.h" |
#include "v8.h" |
#include "public/platform/Platform.h" |
+#include "public/platform/WebCString.h" |
#include "public/platform/WebFloatRect.h" |
#include "public/platform/WebThread.h" |
#include "public/platform/WebUnitTestSupport.h" |
#include "public/platform/WebURLResponse.h" |
#include "wtf/dtoa/utils.h" |
#include "wtf/Forward.h" |
+#include <map> |
using namespace WebKit; |
using WebCore::Document; |
@@ -270,6 +273,157 @@ TEST_F(WebFrameTest, ChromePageNoJavascript) |
EXPECT_EQ(std::string::npos, content.find("Clobbered")); |
} |
+#if ENABLE(CSS_CALLBACKS) |
+struct CssCallbackWebFrameClient : public WebFrameClient { |
abarth-chromium
2013/07/12 23:44:11
CssCallbackWebFrameClient -> CSSCallbackWebFrameCl
Jeffrey Yasskin
2013/07/16 00:38:51
Done.
|
+ CssCallbackWebFrameClient() : m_updateCount(0) { } |
+ virtual void didMatchCss(WebFrame* frame, const WebVector<WebString>& newlyMatchingSelectors, const WebVector<WebString>& stoppedMatchingSelectors) OVERRIDE |
abarth-chromium
2013/07/12 23:44:11
didMatchCss -> didMatchCSS
Basically, we use CSS
Jeffrey Yasskin
2013/07/16 00:38:51
Done everywhere.
|
+ { |
+ ++m_updateCount; |
+ std::set<std::string>& frameSelectors = m_matchedSelectors[frame]; |
+ for (size_t i = 0; i < newlyMatchingSelectors.size(); ++i) { |
+ std::string selector = newlyMatchingSelectors[i].utf8(); |
+ EXPECT_EQ(0U, frameSelectors.count(selector)) << selector; |
+ frameSelectors.insert(selector); |
+ } |
+ for (size_t i = 0; i < stoppedMatchingSelectors.size(); ++i) { |
+ std::string selector = stoppedMatchingSelectors[i].utf8(); |
+ EXPECT_EQ(1U, frameSelectors.count(selector)) << selector; |
+ frameSelectors.erase(selector); |
+ } |
+ } |
+ |
+ std::map<WebFrame*, std::set<std::string> > m_matchedSelectors; |
+ int m_updateCount; |
+}; |
+ |
+TEST_F(WebFrameTest, CssCallbackAuthorStyleSheet) |
+{ |
+ CssCallbackWebFrameClient client; |
+ WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, &client); |
+ WebFrame* frame = webView->mainFrame(); |
+ |
+ frame->loadHTMLString( |
+ "<style>" |
+ // This stylesheet checks that the internal property and value can't be |
+ // set by a stylesheet, only WebDocument::watchCssSelectors(). |
+ "div.initial_on { -internal-callback: none; }" |
+ "div.initial_off { -internal-callback: -internal-presence; }" |
+ "</style>" |
+ "<div class=\"initial_on\"></div>" |
+ "<div class=\"initial_off\"></div>", |
+ toKURL("about:blank")); |
+ runPendingTasks(); |
+ |
+ std::vector<WebString> selectors; |
+ selectors.push_back(WebString::fromUTF8("div.initial_on")); |
+ frame->document().watchCssSelectors(WebVector<WebString>(selectors)); |
+ runPendingTasks(); |
+ EXPECT_EQ(1, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre("div.initial_on")); |
+ |
+ WebDocument doc = frame->document(); |
+ // Check that adding a watched selector calls back for already-present nodes. |
+ selectors.push_back(WebString::fromUTF8("div.initial_off")); |
+ frame->document().watchCssSelectors(WebVector<WebString>(selectors)); |
+ runPendingTasks(); |
+ EXPECT_EQ(2, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre("div.initial_off", "div.initial_on")); |
+ |
+ // Check that we can turn off callbacks for certain selectors. |
+ frame->document().watchCssSelectors(WebVector<WebString>()); |
+ runPendingTasks(); |
+ EXPECT_EQ(3, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre()); |
+ |
+ EXPECT_EQ(1U, client.m_matchedSelectors.size()); |
+ webView->close(); |
+} |
+ |
+TEST_F(WebFrameTest, CssCallbackSharedRenderStyle) |
+{ |
+ CssCallbackWebFrameClient client; |
+ WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, &client); |
+ WebFrame* frame = webView->mainFrame(); |
+ WebDocument doc = frame->document(); |
+ |
+ // Check that adding an element calls back when it matches an existing rule. |
+ std::vector<WebString> selectors; |
+ selectors.push_back(WebString::fromUTF8("span")); |
+ doc.watchCssSelectors(WebVector<WebString>(selectors)); |
+ |
+ frame->executeScript(WebScriptSource( |
+ "i1 = document.createElement('span');" |
+ "i1.id = 'first_span';" |
+ "document.body.appendChild(i1)")); |
+ runPendingTasks(); |
+ EXPECT_EQ(1, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre("span")); |
+ |
+ // Adding a second element that shares a RenderStyle shouldn't call back. |
+ // We use <span>s to avoid default style rules that can set |
+ // RenderStyle::unique(). |
+ frame->executeScript(WebScriptSource( |
+ "i2 = document.createElement('span');" |
+ "i2.id = 'second_span';" |
+ "i1 = document.getElementById('first_span');" |
+ "i1.parentNode.insertBefore(i2, i1.nextSibling);")); |
+ runPendingTasks(); |
+ EXPECT_EQ(1, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre("span")); |
+ |
+ // Removing the first element shouldn't call back. |
+ frame->executeScript(WebScriptSource( |
+ "i1 = document.getElementById('first_span');" |
+ "i1.parentNode.removeChild(i1);")); |
+ runPendingTasks(); |
+ EXPECT_EQ(1, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre("span")); |
+ |
+ // But removing the second element *should* call back. |
+ frame->executeScript(WebScriptSource( |
+ "i2 = document.getElementById('second_span');" |
+ "i2.parentNode.removeChild(i2);")); |
+ runPendingTasks(); |
+ EXPECT_EQ(2, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre()); |
+ |
+ EXPECT_EQ(1U, client.m_matchedSelectors.size()); |
+ webView->close(); |
+} |
+ |
+TEST_F(WebFrameTest, CssCallbackMultiSelector) |
+{ |
+ CssCallbackWebFrameClient client; |
+ WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, &client); |
+ WebFrame* frame = webView->mainFrame(); |
+ frame->loadHTMLString("<span></span>", toKURL("about:blank")); |
+ runPendingTasks(); |
+ WebDocument doc = frame->document(); |
+ |
+ // Check that selector lists match as the whole list, not as each element |
+ // independently. |
+ std::vector<WebString> selectors; |
+ selectors.push_back(WebString::fromUTF8("span")); |
+ selectors.push_back(WebString::fromUTF8("span,p")); |
+ frame->document().watchCssSelectors(WebVector<WebString>(selectors)); |
+ |
+ runPendingTasks(); |
+ EXPECT_EQ(1, client.m_updateCount); |
+ EXPECT_THAT(client.m_matchedSelectors[frame], |
+ testing::ElementsAre("span", "span, p")); |
+ |
+ EXPECT_EQ(1U, client.m_matchedSelectors.size()); |
+ webView->close(); |
+} |
+#endif |
+ |
TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck) |
{ |
registerMockedHttpURLLoad("postmessage_test.html"); |