aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2012-05-30 01:11:56 +0800
committerCarlos Garcia Campos <carlosgc@gnome.org>2012-06-25 18:00:31 +0800
commit6f24b1f37b9f53907a848b4531ac90a7b830a206 (patch)
treee1ccc05e43645acd9fe6c94275c0321f0a87797f
parentd5a3f08cb80d85dd9924d7d3a2cb828ad481c2e2 (diff)
downloadgsoc2013-epiphany-6f24b1f37b9f53907a848b4531ac90a7b830a206.tar
gsoc2013-epiphany-6f24b1f37b9f53907a848b4531ac90a7b830a206.tar.gz
gsoc2013-epiphany-6f24b1f37b9f53907a848b4531ac90a7b830a206.tar.bz2
gsoc2013-epiphany-6f24b1f37b9f53907a848b4531ac90a7b830a206.tar.lz
gsoc2013-epiphany-6f24b1f37b9f53907a848b4531ac90a7b830a206.tar.xz
gsoc2013-epiphany-6f24b1f37b9f53907a848b4531ac90a7b830a206.tar.zst
gsoc2013-epiphany-6f24b1f37b9f53907a848b4531ac90a7b830a206.zip
Port policy client to WebKit2
https://bugzilla.gnome.org/show_bug.cgi?id=678591
-rw-r--r--embed/ephy-web-view.c62
-rw-r--r--src/ephy-window.c152
2 files changed, 209 insertions, 5 deletions
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index ff3788cb7..93f79aa90 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -1690,7 +1690,63 @@ ge_popup_blocked_cb (EphyWebView *view,
}
#ifdef HAVE_WEBKIT2
-/* TODO: Policy Client */
+static gboolean
+decide_policy_cb (WebKitWebView *web_view,
+ WebKitPolicyDecision *decision,
+ WebKitPolicyDecisionType decision_type,
+ gpointer user_data)
+{
+ WebKitResponsePolicyDecision *response_decision;
+ WebKitURIResponse *response;
+ EphyWebViewDocumentType type;
+ const gchar *mime_type;
+
+ if (decision_type != WEBKIT_POLICY_DECISION_TYPE_RESPONSE)
+ return FALSE;
+
+ response_decision = WEBKIT_RESPONSE_POLICY_DECISION (decision);
+ response = webkit_response_policy_decision_get_response (response_decision);
+ mime_type = webkit_uri_response_get_mime_type (response);
+
+ type = EPHY_WEB_VIEW_DOCUMENT_OTHER;
+ if (!strcmp (mime_type, "text/html") || !strcmp (mime_type, "text/plain"))
+ type = EPHY_WEB_VIEW_DOCUMENT_HTML;
+ else if (!strcmp (mime_type, "application/xhtml+xml"))
+ type = EPHY_WEB_VIEW_DOCUMENT_XML;
+ else if (!strncmp (mime_type, "image/", 6))
+ type = EPHY_WEB_VIEW_DOCUMENT_IMAGE;
+
+ /* FIXME: maybe it makes more sense to have an API to query the mime
+ * type when the load of a page starts than doing this here.
+ */
+ if (EPHY_WEB_VIEW (web_view)->priv->document_type != type) {
+ EPHY_WEB_VIEW (web_view)->priv->document_type = type;
+
+ g_object_notify (G_OBJECT (web_view), "document-type");
+ }
+
+ /* TODO: Check also Content-Disposition header before emitting
+ * handle-content signal. We need API for that in WebKit2.
+ */
+ if (!webkit_web_view_can_show_mime_type (web_view, mime_type)) {
+ GObject *single;
+ WebKitURIRequest *request;
+ const char *uri;
+ gboolean handled = FALSE;
+
+ single = ephy_embed_shell_get_embed_single (embed_shell);
+ request = webkit_response_policy_decision_get_request (response_decision);
+ g_signal_emit_by_name (single, "handle-content", mime_type, uri, &handled);
+
+ if (handled) {
+ webkit_policy_decision_ignore (decision);
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
#else
static gboolean
mime_type_policy_decision_requested_cb (WebKitWebView *web_view,
@@ -2578,7 +2634,9 @@ ephy_web_view_init (EphyWebView *web_view)
web_view);
#ifdef HAVE_WEBKIT2
- /* TODO: Policy Client */
+ g_signal_connect (web_view, "decide-policy",
+ G_CALLBACK (decide_policy_cb),
+ NULL);
#else
g_signal_connect (web_view, "mime-type-policy-decision-requested",
G_CALLBACK (mime_type_policy_decision_requested_cb),
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 5050452ac..e57860748 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -2123,7 +2123,149 @@ create_web_view_cb (WebKitWebView *web_view,
#endif
#ifdef HAVE_WEBKIT2
-/* TODO: Policy client */
+static gboolean
+decide_policy_cb (WebKitWebView *web_view,
+ WebKitPolicyDecision *decision,
+ WebKitPolicyDecisionType decision_type,
+ EphyWindow *window)
+{
+ WebKitNavigationPolicyDecision *navigation_decision;
+ WebKitNavigationType navigation_type;
+ WebKitURIRequest *request;
+ gint button;
+ gint state;
+ const char *uri;
+ EphyEmbed *embed;
+ EphyNewTabFlags flags;
+
+ if (decision_type == WEBKIT_POLICY_DECISION_TYPE_RESPONSE)
+ return FALSE;
+
+ navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
+ request = webkit_navigation_policy_decision_get_request (navigation_decision);
+ uri = webkit_uri_request_get_uri (request);
+
+ if (!ephy_embed_utils_address_has_web_scheme (uri))
+ {
+ GError *error = NULL;
+ GdkScreen *screen;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (web_view));
+ gtk_show_uri (screen, uri, GDK_CURRENT_TIME, &error);
+
+ if (error)
+ {
+ LOG ("failed to handle non web scheme: %s", error->message);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ webkit_policy_decision_ignore (decision);
+
+ return TRUE;
+ }
+
+ navigation_type = webkit_navigation_policy_decision_get_navigation_type (navigation_decision);
+
+ if (navigation_type == WEBKIT_NAVIGATION_TYPE_LINK_CLICKED &&
+ ephy_embed_shell_get_mode (embed_shell) == EPHY_EMBED_SHELL_MODE_APPLICATION)
+ {
+ /* The only thing we allow here is to either navigate
+ * in the same window and tab to the current domain,
+ * or launch a new (non app mode) epiphany instance
+ * for all the other cases. */
+ gboolean return_value;
+ SoupURI *soup_uri = soup_uri_new (uri);
+ SoupURI *current_soup_uri = soup_uri_new (webkit_web_view_get_uri (web_view));
+
+ if (g_str_equal (soup_uri->host, current_soup_uri->host))
+ {
+ return_value = FALSE;
+ }
+ else
+ {
+ char *command_line;
+ GError *error = NULL;
+
+ return_value = TRUE;
+ /* A gross hack to be able to launch epiphany from within
+ * Epiphany. Might be a good idea to figure out a better
+ * solution... */
+ g_unsetenv (EPHY_UUID_ENVVAR);
+ command_line = g_strdup_printf ("gvfs-open %s", uri);
+ g_spawn_command_line_async (command_line, &error);
+
+ if (error)
+ {
+ g_debug ("Error opening %s: %s", uri, error->message);
+ g_error_free (error);
+ }
+
+ g_free (command_line);
+
+ webkit_policy_decision_ignore (decision);
+ }
+
+ soup_uri_free (soup_uri);
+ soup_uri_free (current_soup_uri);
+
+ return return_value;
+ }
+
+ if (navigation_type != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED)
+ return FALSE;
+
+
+ button = webkit_navigation_policy_decision_get_mouse_button (navigation_decision);
+ state = webkit_navigation_policy_decision_get_modifiers (navigation_decision);
+ flags = EPHY_NEW_TAB_OPEN_PAGE;
+
+ ephy_web_view_set_visit_type (EPHY_WEB_VIEW (web_view),
+ EPHY_PAGE_VISIT_LINK);
+
+ /* New tab in new window for control+shift+click */
+ if (button == 1 && state == (GDK_SHIFT_MASK | GDK_CONTROL_MASK))
+ {
+ flags |= EPHY_NEW_TAB_IN_NEW_WINDOW;
+ }
+ /* New tab in existing window for middle click and
+ * control+click */
+ else if (button == 2 || (button == 1 && state == GDK_CONTROL_MASK))
+ {
+ flags |= EPHY_NEW_TAB_IN_EXISTING_WINDOW | EPHY_NEW_TAB_APPEND_AFTER;
+ }
+ /* Because we connect to button-press-event *after*
+ * (G_CONNECT_AFTER) we need to prevent WebKit from browsing to
+ * a link when you shift+click it. Otherwise when you
+ * shift+click a link to download it you would also be taken to
+ * the link destination. */
+ else if (button == 1 && state == GDK_SHIFT_MASK)
+ {
+ webkit_policy_decision_ignore (decision);
+
+ return TRUE;
+ }
+ /* Those were our special cases, we won't handle this */
+ else
+ {
+ return FALSE;
+ }
+
+ embed = ephy_embed_container_get_active_child
+ (EPHY_EMBED_CONTAINER (window));
+
+ ephy_shell_new_tab_full (ephy_shell_get_default (),
+ window,
+ embed,
+ request,
+ flags,
+ EPHY_WEB_VIEW_CHROME_ALL, FALSE, 0);
+
+ webkit_policy_decision_ignore (decision);
+
+ return TRUE;
+}
#else
static gboolean
policy_decision_required_cb (WebKitWebView *web_view,
@@ -2307,7 +2449,9 @@ ephy_window_connect_active_embed (EphyWindow *window)
window, 0);
#endif
#ifdef HAVE_WEBKIT2
- /* TODO: Policy Client */
+ g_signal_connect_object (web_view, "decide-policy",
+ G_CALLBACK (decide_policy_cb),
+ window, 0);
#else
g_signal_connect_object (web_view, "navigation-policy-decision-requested",
G_CALLBACK (policy_decision_required_cb),
@@ -2390,7 +2534,9 @@ ephy_window_disconnect_active_embed (EphyWindow *window)
window);
#endif
#ifdef HAVE_WEBKIT2
- /* TODO: Policy client */
+ g_signal_handlers_disconnect_by_func (view,
+ G_CALLBACK (decide_policy_cb),
+ window);
#else
sid = g_signal_lookup ("navigation-policy-decision-requested",
WEBKIT_TYPE_WEB_VIEW);