Commit 81434a02 authored by Damián Nohales's avatar Damián Nohales Committed by Debarshi Ray

Port to WebKit 2

Bump minimum WebKitGTK+ version to 2.7.2 because we need to create our
own WebKitWebContext and handle user script messages.

https://bugzilla.gnome.org/show_bug.cgi?id=742680
parent 03ff2281
......@@ -90,7 +90,7 @@ PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 3.11.1])
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
PKG_CHECK_MODULES(WEBKIT_GTK, [webkitgtk-3.0 >= 2.1.90])
PKG_CHECK_MODULES(WEBKIT_GTK, [webkit2gtk-4.0 >= 2.7.2])
AC_SUBST(WEBKIT_GTK_CFLAGS)
AC_SUBST(WEBKIT_GTK_LIBS)
......
......@@ -3,9 +3,6 @@ NULL =
SUBDIRS = icons
cssdir = $(pkgdatadir)
css_DATA = goawebview.css
gsettings_in_files = org.gnome.online-accounts.gschema.xml.in
gsettings_SCHEMAS = $(gsettings_in_files:.xml.in=.xml)
......@@ -20,7 +17,6 @@ $(service_DATA): $(service_in_files) Makefile
@sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
EXTRA_DIST = \
$(css_DATA) \
$(gsettings_in_files) \
$(service_in_files) \
dbus-interfaces.xml \
......
::-webkit-scrollbar {
display: none !important;
}
......@@ -19,6 +19,7 @@ AM_CPPFLAGS = \
-DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-DPACKAGE_WEB_EXTENSIONS_DIR=\""$(libdir)/goa-1.0/web-extensions"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
$(WARN_CFLAGS) \
$(NULL)
......@@ -139,6 +140,34 @@ libgoa_backend_1_0_la_LDFLAGS = \
# ----------------------------------------------------------------------------------------------------
webextension_LTLIBRARIES = libgoawebextension.la
webextensiondir = $(libdir)/goa-1.0/web-extensions
libgoawebextension_la_SOURCES = \
goawebextension.h goawebextension.c \
goawebextensionmain.c \
$(NULL)
libgoawebextension_la_CFLAGS = \
$(REST_CFLAGS) \
$(WEBKIT_GTK_CFLAGS) \
$(NULL)
libgoawebextension_la_LIBADD = \
libgoa-backend-1.0.la \
$(REST_LIBS) \
$(WEBKIT_GTK_LIBS) \
$(NULL)
libgoawebextension_la_LDFLAGS = \
-avoid-version \
-module \
-no-undefined \
$(NULL)
# ----------------------------------------------------------------------------------------------------
BUILT_SOURCES = \
$(libgoa_backend_1_0_la_built_sources) \
$(NULL)
......
......@@ -23,7 +23,7 @@
#include <rest/oauth2-proxy.h>
#include <libsoup/soup.h>
#include <json-glib/json-glib.h>
#include <webkit/webkit.h>
#include <webkit2/webkit2.h>
#include "goaprovider.h"
#include "goautils.h"
......@@ -66,7 +66,6 @@ struct _GoaOAuth2ProviderPrivate
GError *error;
GMainLoop *loop;
WebKitDOMHTMLInputElement *password_node;
const gchar *existing_identity;
gchar *account_object_path;
......@@ -774,7 +773,7 @@ get_tokens_sync (GoaOAuth2Provider *provider,
/* ---------------------------------------------------------------------------------------------------- */
static void
on_dom_node_click (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data)
on_web_view_deny_click (GoaWebView *web_view, gpointer user_data)
{
GoaOAuth2Provider *provider = GOA_OAUTH2_PROVIDER (user_data);
GoaOAuth2ProviderPrivate *priv = provider->priv;
......@@ -782,84 +781,26 @@ on_dom_node_click (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_
}
static void
on_form_submit (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data)
on_web_view_password_submit (GoaWebView *web_view, const gchar *password, gpointer user_data)
{
GoaOAuth2Provider *provider = GOA_OAUTH2_PROVIDER (user_data);
GoaOAuth2ProviderPrivate *priv = provider->priv;
if (priv->password_node == NULL)
return;
priv->password = webkit_dom_html_input_element_get_value (priv->password_node);
priv->password_node = NULL;
}
static void
on_web_view_document_load_finished (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data)
{
GoaOAuth2Provider *provider = GOA_OAUTH2_PROVIDER (user_data);
GoaOAuth2ProviderPrivate *priv = provider->priv;
WebKitDOMDocument *document;
WebKitDOMNodeList *elements;
gulong element_count;
gulong i;
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view));
elements = webkit_dom_document_get_elements_by_tag_name (document, "*");
element_count = webkit_dom_node_list_get_length (elements);
for (i = 0; i < element_count; i++)
{
WebKitDOMNode *element = webkit_dom_node_list_item (elements, i);
if (goa_oauth2_provider_is_deny_node (provider, element))
{
webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (element),
"click",
G_CALLBACK (on_dom_node_click),
FALSE,
provider);
}
else if (priv->existing_identity != NULL
&& WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element)
&& goa_oauth2_provider_is_identity_node (provider, WEBKIT_DOM_HTML_INPUT_ELEMENT (element)))
{
webkit_dom_html_input_element_set_value (WEBKIT_DOM_HTML_INPUT_ELEMENT (element),
priv->existing_identity);
webkit_dom_html_input_element_set_read_only (WEBKIT_DOM_HTML_INPUT_ELEMENT (element), TRUE);
}
else if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element)
&& goa_oauth2_provider_is_password_node (provider, WEBKIT_DOM_HTML_INPUT_ELEMENT (element)))
{
WebKitDOMHTMLFormElement *form;
form = webkit_dom_html_input_element_get_form (WEBKIT_DOM_HTML_INPUT_ELEMENT (element));
if (form != NULL)
{
priv->password_node = WEBKIT_DOM_HTML_INPUT_ELEMENT (element);
g_clear_pointer (&priv->password, g_free);
webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (form),
"submit",
G_CALLBACK (on_form_submit),
FALSE,
provider);
}
}
}
g_free (priv->password);
priv->password = g_strdup (password);
}
static gboolean
on_web_view_navigation_policy_decision_requested (WebKitWebView *webView,
WebKitWebFrame *frame,
WebKitNetworkRequest *request,
WebKitWebNavigationAction *navigation_action,
WebKitWebPolicyDecision *policy_decision,
gpointer user_data)
on_web_view_decide_policy (WebKitWebView *web_view,
WebKitPolicyDecision *decision,
WebKitPolicyDecisionType decision_type,
gpointer user_data)
{
GoaOAuth2Provider *provider = GOA_OAUTH2_PROVIDER (user_data);
GoaOAuth2ProviderPrivate *priv = provider->priv;
GHashTable *key_value_pairs;
SoupMessage *message;
WebKitNavigationAction *action;
WebKitURIRequest *request;
SoupURI *uri;
const gchar *fragment;
const gchar *oauth2_error;
......@@ -868,15 +809,19 @@ on_web_view_navigation_policy_decision_requested (WebKitWebView *web
const gchar *requested_uri;
gint response_id = GTK_RESPONSE_NONE;
if (decision_type != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
goto default_behaviour;
/* TODO: use oauth2_proxy_extract_access_token() */
requested_uri = webkit_network_request_get_uri (request);
action = webkit_navigation_policy_decision_get_navigation_action (WEBKIT_NAVIGATION_POLICY_DECISION (decision));
request = webkit_navigation_action_get_request (action);
requested_uri = webkit_uri_request_get_uri (request);
redirect_uri = goa_oauth2_provider_get_redirect_uri (provider);
if (!g_str_has_prefix (requested_uri, redirect_uri))
goto default_behaviour;
message = webkit_network_request_get_message (request);
uri = soup_message_get_uri (message);
uri = soup_uri_new (requested_uri);
fragment = soup_uri_get_fragment (uri);
query = soup_uri_get_query (uri);
......@@ -974,7 +919,7 @@ on_web_view_navigation_policy_decision_requested (WebKitWebView *web
ignore_request:
g_assert (response_id != GTK_RESPONSE_NONE);
gtk_dialog_response (priv->dialog, response_id);
webkit_web_policy_decision_ignore (policy_decision);
webkit_policy_decision_ignore (decision);
return TRUE;
default_behaviour:
......@@ -1048,7 +993,7 @@ get_tokens_and_identity (GoaOAuth2Provider *provider,
gtk_grid_set_row_spacing (GTK_GRID (grid), 12);
gtk_container_add (GTK_CONTAINER (vbox), grid);
web_view = goa_web_view_new ();
web_view = goa_web_view_new (GOA_PROVIDER (provider), existing_identity);
gtk_widget_set_hexpand (web_view, TRUE);
gtk_widget_set_vexpand (web_view, TRUE);
embed = goa_web_view_get_view (GOA_WEB_VIEW (web_view));
......@@ -1062,11 +1007,12 @@ get_tokens_and_identity (GoaOAuth2Provider *provider,
goa_web_view_fake_mobile (GOA_WEB_VIEW (web_view));
webkit_web_view_load_uri (WEBKIT_WEB_VIEW (embed), url);
g_signal_connect (embed, "document-load-finished", G_CALLBACK (on_web_view_document_load_finished), provider);
g_signal_connect (embed,
"navigation-policy-decision-requested",
G_CALLBACK (on_web_view_navigation_policy_decision_requested),
"decide-policy",
G_CALLBACK (on_web_view_decide_policy),
provider);
g_signal_connect (web_view, "deny-click", G_CALLBACK (on_web_view_deny_click), provider);
g_signal_connect (web_view, "password-submit", G_CALLBACK (on_web_view_password_submit), provider);
gtk_container_add (GTK_CONTAINER (grid), web_view);
......
......@@ -23,7 +23,7 @@
#include <rest/oauth-proxy.h>
#include <libsoup/soup.h>
#include <json-glib/json-glib.h>
#include <webkit/webkit.h>
#include <webkit2/webkit2.h>
#include "goaprovider.h"
#include "goautils.h"
......@@ -619,7 +619,6 @@ typedef struct
GError *error;
GMainLoop *loop;
WebKitDOMHTMLInputElement *password_node;
gchar *password;
gchar *oauth_verifier;
......@@ -639,102 +638,48 @@ typedef struct
} IdentifyData;
static void
on_dom_node_click (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data)
on_web_view_deny_click (GoaWebView *web_view, gpointer user_data)
{
IdentifyData *data = user_data;
gtk_dialog_response (data->dialog, GTK_RESPONSE_CANCEL);
}
static void
on_form_submit (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data)
on_web_view_password_submit (GoaWebView *web_view, const gchar *password, gpointer user_data)
{
IdentifyData *data = user_data;
if (data->password_node == NULL)
return;
data->password = webkit_dom_html_input_element_get_value (data->password_node);
data->password_node = NULL;
}
static void
on_web_view_document_load_finished (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data)
{
IdentifyData *data = user_data;
GoaOAuthProvider *provider = data->provider;
WebKitDOMDocument *document;
WebKitDOMNodeList *elements;
gulong element_count;
gulong i;
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view));
elements = webkit_dom_document_get_elements_by_tag_name (document, "*");
element_count = webkit_dom_node_list_get_length (elements);
for (i = 0; i < element_count; i++)
{
WebKitDOMNode *element = webkit_dom_node_list_item (elements, i);
if (goa_oauth_provider_is_deny_node (provider, element))
{
webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (element),
"click",
G_CALLBACK (on_dom_node_click),
FALSE,
data);
}
else if (data->existing_identity != NULL
&& WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element)
&& goa_oauth_provider_is_identity_node (provider, WEBKIT_DOM_HTML_INPUT_ELEMENT (element)))
{
webkit_dom_html_input_element_set_value (WEBKIT_DOM_HTML_INPUT_ELEMENT (element),
data->existing_identity);
webkit_dom_html_input_element_set_read_only (WEBKIT_DOM_HTML_INPUT_ELEMENT (element), TRUE);
}
else if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element)
&& goa_oauth_provider_is_password_node (provider, WEBKIT_DOM_HTML_INPUT_ELEMENT (element)))
{
WebKitDOMHTMLFormElement *form;
form = webkit_dom_html_input_element_get_form (WEBKIT_DOM_HTML_INPUT_ELEMENT (element));
if (form != NULL)
{
data->password_node = WEBKIT_DOM_HTML_INPUT_ELEMENT (element);
g_clear_pointer (&data->password, g_free);
webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (form),
"submit",
G_CALLBACK (on_form_submit),
FALSE,
data);
}
}
}
g_free (data->password);
data->password = g_strdup (password);
}
static gboolean
on_web_view_navigation_policy_decision_requested (WebKitWebView *webView,
WebKitWebFrame *frame,
WebKitNetworkRequest *request,
WebKitWebNavigationAction *navigation_action,
WebKitWebPolicyDecision *policy_decision,
gpointer user_data)
on_web_view_decide_policy (WebKitWebView *web_view,
WebKitPolicyDecision *decision,
WebKitPolicyDecisionType decision_type,
gpointer user_data)
{
IdentifyData *data = user_data;
WebKitNavigationAction *action;
WebKitURIRequest *request;
const gchar *redirect_uri;
const gchar *requested_uri;
if (decision_type != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
return FALSE;
/* TODO: use oauth_proxy_extract_access_token() */
requested_uri = webkit_network_request_get_uri (request);
action = webkit_navigation_policy_decision_get_navigation_action (WEBKIT_NAVIGATION_POLICY_DECISION (decision));
request = webkit_navigation_action_get_request (action);
requested_uri = webkit_uri_request_get_uri (request);
redirect_uri = goa_oauth_provider_get_callback_uri (data->provider);
if (g_str_has_prefix (requested_uri, redirect_uri))
{
SoupMessage *message;
SoupURI *uri;
GHashTable *key_value_pairs;
message = webkit_network_request_get_message (request);
uri = soup_message_get_uri (message);
uri = soup_uri_new (requested_uri);
key_value_pairs = soup_form_decode (uri->query);
/* TODO: error handling? */
......@@ -744,7 +689,7 @@ on_web_view_navigation_policy_decision_requested (WebKitWebView *web
gtk_dialog_response (data->dialog, GTK_RESPONSE_OK);
}
g_hash_table_unref (key_value_pairs);
webkit_web_policy_decision_ignore (policy_decision);
webkit_policy_decision_ignore (decision);
return TRUE; /* ignore the request */
}
else
......@@ -887,7 +832,7 @@ get_tokens_and_identity (GoaOAuthProvider *provider,
goa_oauth_provider_get_authorization_uri (provider),
escaped_request_token);
web_view = goa_web_view_new ();
web_view = goa_web_view_new (GOA_PROVIDER (provider), existing_identity);
gtk_widget_set_hexpand (web_view, TRUE);
gtk_widget_set_vexpand (web_view, TRUE);
embed = goa_web_view_get_view (GOA_WEB_VIEW (web_view));
......@@ -896,11 +841,12 @@ get_tokens_and_identity (GoaOAuthProvider *provider,
goa_web_view_fake_mobile (GOA_WEB_VIEW (web_view));
webkit_web_view_load_uri (WEBKIT_WEB_VIEW (embed), url);
g_signal_connect (embed, "document-load-finished", G_CALLBACK (on_web_view_document_load_finished), &data);
g_signal_connect (embed,
"navigation-policy-decision-requested",
G_CALLBACK (on_web_view_navigation_policy_decision_requested),
"decide-policy",
G_CALLBACK (on_web_view_decide_policy),
&data);
g_signal_connect (web_view, "deny-click", G_CALLBACK (on_web_view_deny_click), &data);
g_signal_connect (web_view, "password-submit", G_CALLBACK (on_web_view_password_submit), &data);
gtk_container_add (GTK_CONTAINER (grid), web_view);
......
......@@ -120,8 +120,10 @@ struct _GoaOAuthProviderClass
WebKitDOMHTMLInputElement *element);
/*< private >*/
GoaOAuthProviderPrivate *priv;
/* Padding for future expansion */
gpointer goa_reserved[29];
gpointer goa_reserved[28];
};
GType goa_oauth_provider_get_type (void) G_GNUC_CONST;
......
This diff is collapsed.
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2015 Damián Nohales
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GOA_WEB_EXTENSION_H__
#define __GOA_WEB_EXTENSION_H__
#include <glib-object.h>
#include <webkit2/webkit-web-extension.h>
G_BEGIN_DECLS
#define GOA_TYPE_WEB_EXTENSION (goa_web_extension_get_type())
#define GOA_WEB_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOA_TYPE_WEB_EXTENSION, GoaWebExtension))
#define GOA_WEB_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOA_TYPE_WEB_EXTENSION, GoaWebExtensionClass))
#define GOA_IS_WEB_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOA_TYPE_WEB_EXTENSION))
#define GOA_IS_WEB_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOA_TYPE_WEB_EXTENSION))
#define GOA_WEB_EXTENSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOA_TYPE_WEB_EXTENSION, GoaWebExtensionClass))
typedef struct _GoaWebExtension GoaWebExtension;
typedef struct _GoaWebExtensionClass GoaWebExtensionClass;
GType goa_web_extension_get_type (void);
GoaWebExtension *goa_web_extension_new (WebKitWebExtension *wk_extension,
const gchar *provider_type,
const gchar *existing_identity);
G_END_DECLS
#endif /* __GOA_WEB_EXTENSION_H__ */
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2015 Damián Nohales
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gmodule.h>
#include <webkit2/webkit-web-extension.h>
#include "goawebextension.h"
static GoaWebExtension *the_extension;
/* Silence -Wmissing-prototypes */
void webkit_web_extension_initialize (WebKitWebExtension *wk_extension);
void webkit_web_extension_initialize_with_user_data (WebKitWebExtension *wk_extension, GVariant *user_data);
G_MODULE_EXPORT void
webkit_web_extension_initialize (WebKitWebExtension *wk_extension)
{
g_warning ("Error initializing web extension: user data not set");
}
G_MODULE_EXPORT void
webkit_web_extension_initialize_with_user_data (WebKitWebExtension *wk_extension, GVariant *user_data)
{
const gchar *existing_identity;
const gchar *provider_type;
g_variant_get (user_data, "(&s&s)", &provider_type, &existing_identity);
the_extension = goa_web_extension_new (wk_extension, provider_type, existing_identity);
}
static void __attribute__((destructor))
goa_web_extension_shutdown (void)
{
g_clear_object (&the_extension);
}
This diff is collapsed.
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2012 Red Hat, Inc.
* Copyright (C) 2012, 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -21,6 +21,8 @@
#include <gtk/gtk.h>
#include "goaprovider.h"
G_BEGIN_DECLS
#define GOA_TYPE_WEB_VIEW (goa_web_view_get_type ())
......@@ -46,7 +48,8 @@ struct _GoaWebViewClass
};
GType goa_web_view_get_type (void) G_GNUC_CONST;
GtkWidget *goa_web_view_new (void);
GtkWidget *goa_web_view_new (GoaProvider *provider,
const gchar *existing_identity);
GtkWidget *goa_web_view_get_view (GoaWebView *self);
void goa_web_view_fake_mobile (GoaWebView *self);
void goa_web_view_add_cookies (GoaWebView *self,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment