[epiphany/webkit2: 2/17] Port web view loading progress and feedback to WebKit2



commit b98fa9ad20008beac075fcfc5fbbb2cdb2e173b6
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Tue May 29 13:19:35 2012 +0200

    Port web view loading progress and feedback to WebKit2

 doc/reference/epiphany-sections.txt |    1 +
 embed/ephy-embed.c                  |   24 +++-
 embed/ephy-web-view.c               |  216 +++++++++++++++++++++++++++++++++--
 embed/ephy-web-view.h               |    1 +
 src/ephy-notebook.c                 |   13 ++
 src/ephy-session.c                  |   16 ++-
 tests/ephy-web-view-test.c          |   24 ++++-
 7 files changed, 273 insertions(+), 22 deletions(-)
---
diff --git a/doc/reference/epiphany-sections.txt b/doc/reference/epiphany-sections.txt
index 2a02e37..4ea6859 100644
--- a/doc/reference/epiphany-sections.txt
+++ b/doc/reference/epiphany-sections.txt
@@ -30,6 +30,7 @@ ephy_web_view_get_visibility
 ephy_web_view_go_up
 ephy_web_view_has_modified_forms
 ephy_web_view_is_loading
+ephy_web_view_load_failed
 ephy_web_view_load_request
 ephy_web_view_load_url
 ephy_web_view_location_changed
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 99377d8..5136b6e 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,8 +689,6 @@ clear_progress_cb (EphyEmbed *embed)
   return FALSE;
 }
 
-#ifdef HAVE_WEBKIT2
-/* TODO: Load progress */
 static void
 progress_update (EphyWebView *view, GParamSpec *pspec, EphyEmbed *embed)
 {
@@ -702,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)
@@ -715,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)
@@ -777,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);
@@ -800,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 c0350a3..bedcfcb 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,10 @@ 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;
   char *typed_address;
@@ -1920,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,
@@ -1943,6 +2102,7 @@ load_status_cb (WebKitWebView *web_view,
     WebKitWebDataSource *source;
     WebKitNetworkRequest *request;
 
+    priv->load_failed = FALSE;
     frame = webkit_web_view_get_main_frame (web_view);
 
     source = webkit_web_frame_get_provisional_data_source (frame);
@@ -2074,6 +2234,7 @@ load_status_cb (WebKitWebView *web_view,
     break;
   }
   case WEBKIT_LOAD_FAILED:
+    priv->load_failed = TRUE;
     ephy_web_view_set_link_message (view, NULL);
     ephy_web_view_set_loading_title (view, NULL, FALSE);
 
@@ -2214,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);
@@ -2223,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,
@@ -2231,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);
@@ -2253,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:
@@ -2286,7 +2463,6 @@ load_error_cb (WebKitWebView *web_view,
 
   return FALSE;
 }
-#endif
 
 #ifdef HAVE_WEBKIT2
 /* TODO: WebKitWebView::close */
@@ -2418,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),
@@ -2434,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),
@@ -3135,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;
 
@@ -3160,6 +3339,21 @@ ephy_web_view_is_loading (EphyWebView *view)
 }
 
 /**
+ * ephy_web_view_load_failed:
+ * @view: an #EphyWebView
+ *
+ * Returns whether the web page in @view has failed to load.
+ *
+ * Return value: %TRUE if the page failed to load, %FALSE if it's loading
+ *  or load finished successfully
+ **/
+gboolean
+ephy_web_view_load_failed (EphyWebView *view)
+{
+  return view->priv->load_failed;
+}
+
+/**
  * ephy_web_view_get_loading_title:
  * @view: an #EphyWebView
  *
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index 28203b2..398285a 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -137,6 +137,7 @@ void                       ephy_web_view_load_url                 (EphyWebView
 void                       ephy_web_view_copy_back_history        (EphyWebView               *source,
                                                                    EphyWebView               *dest);
 gboolean                   ephy_web_view_is_loading               (EphyWebView               *view);
+gboolean                   ephy_web_view_load_failed              (EphyWebView               *view);
 const char *               ephy_web_view_get_loading_title        (EphyWebView               *view);
 GdkPixbuf *                ephy_web_view_get_icon                 (EphyWebView               *view);
 EphyWebViewDocumentType    ephy_web_view_get_document_type        (EphyWebView               *view);
diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c
index cafeb8e..1b8eeb0 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 82db6f1..0c67712 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 31b6f78..0d5f627 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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]