diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2012-06-21 23:27:10 +0800 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@gnome.org> | 2012-06-24 19:34:43 +0800 |
commit | 6652006561a09e58a50b8f9003bc2c1baf7c8a4c (patch) | |
tree | 8676f577972dd20e9f230c0a74359f6bd81a1c42 | |
parent | ccc2a6f6a9cfea8a06dd7b8968c3ad59597950e9 (diff) | |
download | gsoc2013-epiphany-6652006561a09e58a50b8f9003bc2c1baf7c8a4c.tar.gz gsoc2013-epiphany-6652006561a09e58a50b8f9003bc2c1baf7c8a4c.tar.zst gsoc2013-epiphany-6652006561a09e58a50b8f9003bc2c1baf7c8a4c.zip |
Port web view loading progress and feedback to WebKit2
https://bugzilla.gnome.org/show_bug.cgi?id=678532
-rw-r--r-- | embed/ephy-embed.c | 25 | ||||
-rw-r--r-- | embed/ephy-web-view.c | 198 | ||||
-rw-r--r-- | src/ephy-notebook.c | 13 | ||||
-rw-r--r-- | src/ephy-session.c | 16 | ||||
-rw-r--r-- | tests/ephy-web-view-test.c | 24 |
5 files changed, 253 insertions, 23 deletions
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c index a458f17dd..fb27e4710 100644 --- a/embed/ephy-embed.c +++ b/embed/ephy-embed.c @@ -277,7 +277,14 @@ remove_from_destroy_list_cb (GtkWidget *widget, EphyEmbed *embed) } #ifdef HAVE_WEBKIT2 -/* TODO: Loader */ +static void +load_changed_cb (WebKitWebView *web_view, + WebKitLoadEvent load_event, + EphyEmbed *embed) +{ + if (load_event == WEBKIT_LOAD_COMMITTED) + ephy_embed_destroy_top_widgets (embed); +} #else static void load_status_changed_cb (WebKitWebView *web_view, @@ -682,9 +689,6 @@ clear_progress_cb (EphyEmbed *embed) return FALSE; } -#ifdef HAVE_WEBKIT2 -/* TODO: Load progress */ -#else static void progress_update (EphyWebView *view, GParamSpec *pspec, EphyEmbed *embed) { @@ -703,7 +707,11 @@ progress_update (EphyWebView *view, GParamSpec *pspec, EphyEmbed *embed) if (!uri || g_str_equal (uri, "about:blank")) return; +#ifdef HAVE_WEBKIT2 + progress = webkit_web_view_get_estimated_load_progress (priv->web_view); +#else progress = webkit_web_view_get_progress (priv->web_view); +#endif loading = ephy_web_view_is_loading (EPHY_WEB_VIEW (priv->web_view)); if (progress == 1.0 || !loading) @@ -716,7 +724,6 @@ progress_update (EphyWebView *view, GParamSpec *pspec, EphyEmbed *embed) gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress), (loading || progress == 1.0) ? progress : 0.0); } -#endif static void ephy_embed_constructed (GObject *object) @@ -778,7 +785,8 @@ ephy_embed_constructed (GObject *object) priv->web_view = web_view; #ifdef HAVE_WEBKIT2 - /* TODO: Load progress */ + priv->progress_update_handler_id = g_signal_connect (web_view, "notify::estimated-load-progress", + G_CALLBACK (progress_update), object); #else priv->progress_update_handler_id = g_signal_connect (web_view, "notify::progress", G_CALLBACK (progress_update), object); @@ -801,7 +809,10 @@ ephy_embed_constructed (GObject *object) gtk_widget_show_all (paned); #ifdef HAVE_WEBKIT2 - /* TODO: Loader, WebKitWebResource::send-request, Downloads */ + /* TODO: WebKitWebResource::send-request, Downloads */ + g_signal_connect (web_view, "load-changed", + G_CALLBACK (load_changed_cb), + embed); #else g_object_connect (web_view, "signal::notify::load-status", G_CALLBACK (load_status_changed_cb), embed, diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c index df290c82a..ff3788cb7 100644 --- a/embed/ephy-web-view.c +++ b/embed/ephy-web-view.c @@ -72,9 +72,7 @@ struct _EphyWebViewPrivate { EphyWebViewSecurityLevel security_level; EphyWebViewDocumentType document_type; EphyWebViewNavigationFlags nav_flags; -#ifdef HAVE_WEBKIT2 - /* TODO: Loader */ -#else +#ifndef HAVE_WEBKIT2 WebKitLoadStatus load_status; #endif @@ -83,6 +81,9 @@ struct _EphyWebViewPrivate { guint visibility : 1; guint loading_homepage : 1; guint is_setting_zoom : 1; +#ifdef HAVE_WEBKIT2 + guint is_loading : 1; +#endif guint load_failed : 1; char *address; @@ -1921,7 +1922,164 @@ restore_zoom_level (EphyWebView *view, } #ifdef HAVE_WEBKIT2 -/* TODO: Loader */ +static void +load_changed_cb (WebKitWebView *web_view, + WebKitLoadEvent load_event, + gpointer user_data) +{ + EphyWebView *view = EPHY_WEB_VIEW (web_view); + EphyWebViewPrivate *priv = view->priv; + GObject *object = G_OBJECT (web_view); + + g_object_freeze_notify (object); + + switch (load_event) { + case WEBKIT_LOAD_STARTED: { + const gchar *loading_uri = NULL; + + priv->is_loading = TRUE; + priv->load_failed = FALSE; + + loading_uri = webkit_web_view_get_uri (web_view); + g_signal_emit_by_name (view, "new-document-now", loading_uri); + + if ((priv->address == NULL || priv->address[0] == '\0') && + priv->expire_address_now == TRUE) { + ephy_web_view_set_address (view, loading_uri); + ephy_web_view_set_title (view, NULL); + } + + ephy_web_view_set_loading_title (view, loading_uri, TRUE); + + g_free (priv->status_message); + priv->status_message = g_strdup (priv->loading_title); + g_object_notify (object, "status-message"); + + priv->expire_address_now = TRUE; + break; + } + case WEBKIT_LOAD_REDIRECTED: + /* TODO: Update the loading uri */ + break; + case WEBKIT_LOAD_COMMITTED: { + const gchar* uri; + EphyWebViewSecurityLevel security_level = EPHY_WEB_VIEW_STATE_IS_UNKNOWN; + + /* Title and location. */ + uri = webkit_web_view_get_uri (web_view); + ephy_web_view_location_changed (view, uri); + + ephy_web_view_set_title (view, NULL); + + /* Security status. */ + if (uri && g_str_has_prefix (uri, "https")) { +#if 0 + /* TODO: security */ + WebKitWebFrame *frame; + WebKitWebDataSource *source; + WebKitNetworkRequest *request; + SoupMessage *message; + + frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW(view)); + source = webkit_web_frame_get_data_source (frame); + request = webkit_web_data_source_get_request (source); + message = webkit_network_request_get_message (request); + + if (message && + (soup_message_get_flags (message) & SOUP_MESSAGE_CERTIFICATE_TRUSTED)) + security_level = EPHY_WEB_VIEW_STATE_IS_SECURE_HIGH; + else + security_level = EPHY_WEB_VIEW_STATE_IS_BROKEN; +#endif + } + + ephy_web_view_set_security_level (EPHY_WEB_VIEW (web_view), security_level); + + /* Zoom level. */ + restore_zoom_level (view, uri); + + /* History. */ + if (!ephy_web_view_is_loading_homepage (view)) { + char *history_uri = NULL; + + /* TODO: move the normalization down to the history service? */ + if (g_str_has_prefix (uri, EPHY_ABOUT_SCHEME)) + history_uri = g_strdup_printf ("about:%s", uri + EPHY_ABOUT_SCHEME_LEN + 1); + else + history_uri = g_strdup (uri); + + ephy_history_service_visit_url (priv->history_service, + history_uri, + priv->visit_type); + + g_free (history_uri); + } + break; + } + case WEBKIT_LOAD_FINISHED: { + SoupURI *uri; + + priv->is_loading = FALSE; + priv->loading_homepage = FALSE; + + g_free (priv->status_message); + priv->status_message = NULL; + g_object_notify (object, "status-message"); + ephy_web_view_set_loading_title (view, NULL, FALSE); + + if (priv->is_blank) + g_object_notify (object, "embed-title"); + +#if 0 + /* TODO: DOM bindings */ + if (ephy_embed_shell_get_mode (embed_shell) != EPHY_EMBED_SHELL_MODE_PRIVATE && + g_settings_get_boolean (EPHY_SETTINGS_MAIN, + EPHY_PREFS_REMEMBER_PASSWORDS)) + _ephy_web_view_hook_into_forms (view); + + _ephy_web_view_hook_into_links (view); +#endif + + /* FIXME: It sucks to do this here, but it's not really possible + * to hook the DOM actions nicely in the about: generator. */ + uri = soup_uri_new (webkit_web_view_get_uri (web_view)); + if (uri && + !g_strcmp0 (uri->scheme, "ephy-about") && + !g_strcmp0 (uri->path, "applications")) { +#if 0 + /* TODO: DOM bindings */ + WebKitDOMDocument *document; + WebKitDOMNodeList *buttons; + gulong buttons_n; + int i; + + document = webkit_web_view_get_dom_document (web_view); + buttons = webkit_dom_document_get_elements_by_tag_name (document, "input"); + buttons_n = webkit_dom_node_list_get_length (buttons); + + for (i = 0; i < buttons_n; i++) { + WebKitDOMNode *button; + + button = webkit_dom_node_list_item (buttons, i); + webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (button), "click", + G_CALLBACK (delete_web_app_cb), false, + NULL); + } +#endif + } + + if (uri) + soup_uri_free (uri); + + /* Reset visit type. */ + priv->visit_type = EPHY_PAGE_VISIT_NONE; + + break; + } + } + + g_object_thaw_notify (object); +} #else static void load_status_cb (WebKitWebView *web_view, @@ -2217,7 +2375,7 @@ ephy_web_view_load_error_page (EphyWebView *view, g_free (image_data); #ifdef HAVE_WEBKIT2 - webkit_web_view_load_html (WEBKIT_WEB_VIEW (view), html->str, uri); + webkit_web_view_replace_content (WEBKIT_WEB_VIEW (view), html->str, uri, 0); #else webkit_web_view_load_string (WEBKIT_WEB_VIEW (view), html->str, "text/html", "utf8", uri); @@ -2226,7 +2384,12 @@ ephy_web_view_load_error_page (EphyWebView *view, } #ifdef HAVE_WEBKIT2 -/* TODO: Load error */ +static gboolean +load_failed_cb (WebKitWebView *web_view, + WebKitLoadEvent load_event, + const gchar *uri, + GError *error, + gpointer user_data) #else static gboolean load_error_cb (WebKitWebView *web_view, @@ -2234,11 +2397,18 @@ load_error_cb (WebKitWebView *web_view, char *uri, GError *error, gpointer user_data) +#endif { EphyWebView *view = EPHY_WEB_VIEW (web_view); +#ifdef HAVE_WEBKIT2 + view->priv->load_failed = TRUE; + ephy_web_view_set_link_message (view, NULL); + update_navigation_flags (view); +#else if (webkit_web_view_get_main_frame (web_view) != frame) return FALSE; +#endif if (error->domain == SOUP_HTTP_ERROR) { ephy_web_view_load_error_page (view, uri, EPHY_WEB_VIEW_ERROR_PAGE_NETWORK_ERROR, error); @@ -2256,7 +2426,11 @@ load_error_cb (WebKitWebView *web_view, case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST: case WEBKIT_POLICY_ERROR_FAILED: case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE: +#ifdef HAVE_WEBKIT2 + case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URI: +#else case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL: +#endif case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT: case WEBKIT_PLUGIN_ERROR_FAILED: case WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN: @@ -2289,7 +2463,6 @@ load_error_cb (WebKitWebView *web_view, return FALSE; } -#endif #ifdef HAVE_WEBKIT2 /* TODO: WebKitWebView::close */ @@ -2421,7 +2594,9 @@ ephy_web_view_init (EphyWebView *web_view) #endif #ifdef HAVE_WEBKIT2 - /* TODO: Loader */ + g_signal_connect (web_view, "load-changed", + G_CALLBACK (load_changed_cb), + NULL); #else g_signal_connect (web_view, "notify::load-status", G_CALLBACK (load_status_cb), @@ -2437,7 +2612,9 @@ ephy_web_view_init (EphyWebView *web_view) #endif #ifdef HAVE_WEBKIT2 - /* TODO: Load errors */ + g_signal_connect (web_view, "load-failed", + G_CALLBACK (load_failed_cb), + NULL); #else g_signal_connect (web_view, "load-error", G_CALLBACK (load_error_cb), @@ -3138,8 +3315,7 @@ gboolean ephy_web_view_is_loading (EphyWebView *view) { #ifdef HAVE_WEBKIT2 - /* Loader */ - return FALSE; + return view->priv->is_loading; #else WebKitLoadStatus status; diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c index cafeb8e18..1b8eeb0b3 100644 --- a/src/ephy-notebook.c +++ b/src/ephy-notebook.c @@ -499,6 +499,14 @@ sync_load_status (EphyWebView *view, GParamSpec *pspec, GtkWidget *proxy) } } +#ifdef HAVE_WEBKIT2 +static void +load_changed_cb (EphyWebView *view, WebKitLoadEvent load_event, GtkWidget *proxy) +{ + sync_load_status (view, NULL, proxy); +} +#endif + static void sync_icon (EphyWebView *view, GParamSpec *pspec, @@ -632,8 +640,13 @@ build_tab_label (EphyNotebook *nb, EphyEmbed *embed) G_CALLBACK (sync_icon), icon, 0); g_signal_connect_object (view, "notify::embed-title", G_CALLBACK (sync_label), label, 0); +#ifdef HAVE_WEBKIT2 + g_signal_connect_object (view, "load-changed", + G_CALLBACK (load_changed_cb), hbox, 0); +#else g_signal_connect_object (view, "notify::load-status", G_CALLBACK (sync_load_status), hbox, 0); +#endif return hbox; } diff --git a/src/ephy-session.c b/src/ephy-session.c index 82db6f17d..0c67712cb 100644 --- a/src/ephy-session.c +++ b/src/ephy-session.c @@ -129,7 +129,14 @@ session_delete (EphySession *session, } #ifdef HAVE_WEBKIT2 -/* TODO: Loader */ +static void +load_changed_cb (WebKitWebView *view, + WebKitLoadEvent load_event, + EphySession *session) +{ + if (!ephy_web_view_load_failed (EPHY_WEB_VIEW (view))) + ephy_session_save (session, SESSION_STATE); +} #else static void load_status_notify_cb (EphyWebView *view, @@ -154,7 +161,8 @@ notebook_page_added_cb (GtkWidget *notebook, EphySession *session) { #ifdef HAVE_WEBKIT2 - /* TODO: Loader */ + g_signal_connect (ephy_embed_get_web_view (embed), "load-changed", + G_CALLBACK (load_changed_cb), session); #else g_signal_connect (ephy_embed_get_web_view (embed), "notify::load-status", G_CALLBACK (load_status_notify_cb), session); @@ -170,7 +178,9 @@ notebook_page_removed_cb (GtkWidget *notebook, ephy_session_save (session, SESSION_STATE); #ifdef HAVE_WEBKIT2 - /* TODO: Loader */ + g_signal_handlers_disconnect_by_func + (ephy_embed_get_web_view (embed), G_CALLBACK (load_changed_cb), + session); #else g_signal_handlers_disconnect_by_func (ephy_embed_get_web_view (embed), G_CALLBACK (load_status_notify_cb), diff --git a/tests/ephy-web-view-test.c b/tests/ephy-web-view-test.c index 31b6f78f8..0d5f627bd 100644 --- a/tests/ephy-web-view-test.c +++ b/tests/ephy-web-view-test.c @@ -64,7 +64,26 @@ server_callback (SoupServer *server, } #ifdef HAVE_WEBKIT2 -/* TODO: loader */ +static void +load_changed_cb (WebKitWebView *view, WebKitLoadEvent load_event, GMainLoop *loop) +{ + char *expected_url; + const char *loaded_url; + + if (load_event != WEBKIT_LOAD_FINISHED) + return; + + expected_url = g_object_get_data (G_OBJECT (view), "test.expected_url"); + g_assert (expected_url != NULL); + + loaded_url = webkit_web_view_get_uri (view); + g_assert_cmpstr (loaded_url, ==, expected_url); + + g_signal_handlers_disconnect_by_func (view, load_changed_cb, loop); + + g_free (expected_url); + g_main_loop_quit (loop); +} #else static void notify_load_status_cb (WebKitWebView *view, GParamSpec *spec, GMainLoop *loop) @@ -162,7 +181,8 @@ test_ephy_web_view_load_url () g_test_message ("[%s] \t-> %s", test.url, test.expected_url); #ifdef HAVE_WEBKIT2 - /* TODO: loader */ + g_signal_connect (view, "load-changed", + G_CALLBACK (load_changed_cb), loop); #else g_signal_connect (view, "notify::load-status", G_CALLBACK (notify_load_status_cb), loop); |