Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp (149218 => 149219)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp 2013-04-26 22:29:00 UTC (rev 149218)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp 2013-04-26 23:06:10 UTC (rev 149219)
@@ -20,6 +20,7 @@
#include "config.h"
#include "WebKitWebViewGroup.h"
+#include "ImmutableArray.h"
#include "WebKitPrivate.h"
#include "WebKitSettingsPrivate.h"
#include "WebKitWebViewGroupPrivate.h"
@@ -221,3 +222,66 @@
webkitWebViewGroupAttachSettingsToPageGroup(group);
g_object_notify(G_OBJECT(group), "settings");
}
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_INJECTED_CONTENT_FRAMES_ALL, WebCore::InjectInAllFrames);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY, WebCore::InjectInTopFrameOnly);
+
+static PassRefPtr<ImmutableArray> toImmutableArray(const char* const* list)
+{
+ if (!list)
+ return 0;
+
+ Vector<RefPtr<APIObject> > entries;
+ while (*list) {
+ entries.append(WebString::createFromUTF8String(*list));
+ list++;
+ }
+ return ImmutableArray::adopt(entries);
+}
+
+/**
+ * webkit_web_view_group_add_user_style_sheet:
+ * @group: a #WebKitWebViewGroup
+ * @source: the source of the style_sheet to inject
+ * @base_uri: (allow-none): the base URI to use when processing the style_sheet contents or %NULL for about:blank
+ * @whitelist: (array zero-terminated=1) (allow-none): a whitelist of URI patterns or %NULL
+ * @blacklist: (array zero-terminated=1) (allow-none): a blacklist of URI patterns or %NULL
+ * @injected_frames: a #WebKitInjectedContentFrames describing to which frames the style_sheet should apply
+ *
+ * Inject an external style sheet into pages. It is possible to only apply the style sheet
+ * to some URIs by passing non-null values for @whitelist or @blacklist. Passing a %NULL
+ * whitelist implies that all URIs are on the whitelist. The style sheet is applied if a URI matches
+ * the whitelist and not the blacklist. URI patterns must be of the form [protocol]://[host]/[path]
+ * where the host and path components can contain the wildcard character ('*') to represent zero
+ * or more other characters.
+ */
+void webkit_web_view_group_add_user_style_sheet(WebKitWebViewGroup* group, const char* source, const char* baseURI, const char* const* whitelist, const char* const* blacklist, WebKitInjectedContentFrames injectedFrames)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group));
+ g_return_if_fail(source);
+
+ RefPtr<ImmutableArray> webWhitelist = toImmutableArray(whitelist);
+ RefPtr<ImmutableArray> webBlacklist = toImmutableArray(blacklist);
+
+ // We always use UserStyleUserLevel to match the behavior of WKPageGroupAddUserStyleSheet.
+ group->priv->pageGroup->addUserStyleSheet(
+ String::fromUTF8(source),
+ String::fromUTF8(baseURI),
+ webWhitelist.get(),
+ webBlacklist.get(),
+ static_cast<WebCore::UserContentInjectedFrames>(injectedFrames),
+ WebCore::UserStyleUserLevel);
+}
+
+/**
+ * webkit_web_view_group_remove_all_user_style_sheets:
+ * @group: a #WebKitWebViewGroup
+ *
+ * Remove all style sheets previously injected into this #WebKitWebViewGroup
+ * via webkit_web_view_group_add_user_style_sheet().
+ */
+void webkit_web_view_group_remove_all_user_style_sheets(WebKitWebViewGroup* group)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group));
+ group->priv->pageGroup->removeAllUserStyleSheets();
+}
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h (149218 => 149219)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h 2013-04-26 22:29:00 UTC (rev 149218)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h 2013-04-26 23:06:10 UTC (rev 149219)
@@ -51,22 +51,45 @@
GObjectClass parent_class;
};
+/**
+ * WebKitInjectedContentFrames:
+ * @WEBKIT_INJECTED_CONTENT_FRAMES_ALL: Content will be injected into all frames.
+ * @WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY: Content will only be injected into the main frame.
+ *
+ * Enum values used for determining into which frames content is injected.
+ */
+typedef enum {
+ WEBKIT_INJECTED_CONTENT_FRAMES_ALL,
+ WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY,
+} WebKitInjectedContentFrames;
+
WEBKIT_API GType
-webkit_web_view_group_get_type (void);
+webkit_web_view_group_get_type (void);
WEBKIT_API WebKitWebViewGroup *
-webkit_web_view_group_new (const gchar *name);
+webkit_web_view_group_new (const gchar *name);
WEBKIT_API const gchar *
-webkit_web_view_group_get_name (WebKitWebViewGroup *group);
+webkit_web_view_group_get_name (WebKitWebViewGroup *group);
WEBKIT_API WebKitSettings *
-webkit_web_view_group_get_settings (WebKitWebViewGroup *group);
+webkit_web_view_group_get_settings (WebKitWebViewGroup *group);
WEBKIT_API void
-webkit_web_view_group_set_settings (WebKitWebViewGroup *group,
- WebKitSettings *settings);
+webkit_web_view_group_set_settings (WebKitWebViewGroup *group,
+ WebKitSettings *settings);
+WEBKIT_API void
+webkit_web_view_group_add_user_style_sheet (WebKitWebViewGroup *group,
+ const gchar *source,
+ const gchar *base_uri,
+ const gchar * const *whitelist,
+ const gchar * const *blacklist,
+ WebKitInjectedContentFrames injected_frames);
+
+WEBKIT_API void
+webkit_web_view_group_remove_all_user_style_sheets (WebKitWebViewGroup *group);
+
G_END_DECLS
#endif
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebViewGroup.cpp (149218 => 149219)
--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebViewGroup.cpp 2013-04-26 22:29:00 UTC (rev 149218)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebViewGroup.cpp 2013-04-26 23:06:10 UTC (rev 149219)
@@ -19,11 +19,21 @@
#include "config.h"
+#include "WebKitTestServer.h"
#include "WebViewTest.h"
+#include <cstdarg>
#include <gtk/gtk.h>
#include <webkit2/webkit2.h>
#include <wtf/gobject/GRefPtr.h>
+static WebKitTestServer* kServer;
+
+// These are all here so that they can be changed easily, if necessary.
+static const char* kStyleSheetHTML = "<html><div id=\"styledElement\">Sweet stylez!</div></html>";
+static const char* kInjectedStyleSheet = "#styledElement { font-weight: bold; }";
+static const char* kStyleSheetTestScript = "getComputedStyle(document.getElementById('styledElement'))['font-weight']";
+static const char* kStyleSheetTestScriptResult = "bold";
+
static void testWebViewGroupDefault(Test* test, gconstpointer)
{
// Default group is shared by all WebViews by default.
@@ -88,15 +98,109 @@
g_assert(webkit_web_view_group_get_settings(webkit_web_view_get_group(webView1.get())) == webView2Settings);
}
+static bool isStyleSheetInjectedForURLAtPath(WebViewTest* test, const char* path)
+{
+ test->loadURI(kServer->getURIForPath(path).data());
+ test->waitUntilLoadFinished();
+
+ GOwnPtr<GError> error;
+ WebKitJavascriptResult* _javascript_Result = test->runJavaScriptAndWaitUntilFinished(kStyleSheetTestScript, &error.outPtr());
+ g_assert(_javascript_Result);
+ g_assert(!error.get());
+
+ GOwnPtr<char> resultString(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+ return !g_strcmp0(resultString.get(), kStyleSheetTestScriptResult);
+}
+
+static void fillURLListFromPaths(char** list, const char* path, ...)
+{
+ va_list argumentList;
+ va_start(argumentList, path);
+
+ int i = 0;
+ while (path) {
+ // FIXME: We must use a wildcard for the host here until http://wkbug.com/112476 is fixed.
+ // Until that time patterns with port numbers in them will not properly match URLs with port numbers.
+ list[i++] = g_strdup_printf("http://*/%s*", path);
+ path = va_arg(argumentList, const char*);
+ }
+}
+
+static void removeOldInjectedStyleSheetsAndResetLists(WebKitWebViewGroup* group, char** whitelist, char** blacklist)
+{
+ webkit_web_view_group_remove_all_user_style_sheets(group);
+
+ while (*whitelist) {
+ g_free(*whitelist);
+ *whitelist = 0;
+ whitelist++;
+ }
+
+ while (*blacklist) {
+ g_free(*blacklist);
+ *blacklist = 0;
+ blacklist++;
+ }
+}
+
+static void testWebViewGroupInjectedStyleSheet(WebViewTest* test, gconstpointer)
+{
+ WebKitWebViewGroup* group = webkit_web_view_get_group(test->m_webView);
+ char* whitelist[3] = { 0, 0, 0 };
+ char* blacklist[3] = { 0, 0, 0 };
+
+ removeOldInjectedStyleSheetsAndResetLists(group, whitelist, blacklist);
+
+ // Without a whitelist or a blacklist all URLs should have the injected style sheet.
+ static const char* randomPath = "somerandompath";
+ g_assert(!isStyleSheetInjectedForURLAtPath(test, randomPath));
+ webkit_web_view_group_add_user_style_sheet(group, kInjectedStyleSheet, 0, 0, 0, WEBKIT_INJECTED_CONTENT_FRAMES_ALL);
+ g_assert(isStyleSheetInjectedForURLAtPath(test, randomPath));
+
+ removeOldInjectedStyleSheetsAndResetLists(group, whitelist, blacklist);
+
+ fillURLListFromPaths(blacklist, randomPath, 0);
+ webkit_web_view_group_add_user_style_sheet(group, kInjectedStyleSheet, 0, 0, blacklist, WEBKIT_INJECTED_CONTENT_FRAMES_ALL);
+ g_assert(!isStyleSheetInjectedForURLAtPath(test, randomPath));
+ g_assert(isStyleSheetInjectedForURLAtPath(test, "someotherrandompath"));
+
+ removeOldInjectedStyleSheetsAndResetLists(group, whitelist, blacklist);
+
+ static const char* inTheWhiteList = "inthewhitelist";
+ static const char* notInWhitelist = "notinthewhitelist";
+ static const char* inTheWhiteListAndBlackList = "inthewhitelistandblacklist";
+
+ fillURLListFromPaths(whitelist, inTheWhiteList, inTheWhiteListAndBlackList, 0);
+ fillURLListFromPaths(blacklist, inTheWhiteListAndBlackList, 0);
+ webkit_web_view_group_add_user_style_sheet(group, kInjectedStyleSheet, 0, whitelist, blacklist, WEBKIT_INJECTED_CONTENT_FRAMES_ALL);
+ g_assert(isStyleSheetInjectedForURLAtPath(test, inTheWhiteList));
+ g_assert(!isStyleSheetInjectedForURLAtPath(test, inTheWhiteListAndBlackList));
+ g_assert(!isStyleSheetInjectedForURLAtPath(test, notInWhitelist));
+
+ // It's important to clean up the environment before other tests.
+ removeOldInjectedStyleSheetsAndResetLists(group, whitelist, blacklist);
+}
+
+static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
+{
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kStyleSheetHTML, strlen(kStyleSheetHTML));
+ soup_message_body_complete(message->response_body);
+}
+
void beforeAll()
{
+ kServer = new WebKitTestServer();
+ kServer->run(serverCallback);
+
Test::add("WebKitWebViewGroup", "default-group", testWebViewGroupDefault);
Test::add("WebKitWebViewGroup", "new-group", testWebViewGroupNewGroup);
Test::add("WebKitWebView", "new-with-group", testWebViewNewWithGroup);
Test::add("WebKitWebViewGroup", "settings", testWebViewGroupSettings);
+ WebViewTest::add("WebKitWebViewGroup", "injected-style-sheet", testWebViewGroupInjectedStyleSheet);
}
void afterAll()
{
-
+ delete kServer;
}