[epiphany] Make ephy-about-handler a GObject and handle all request using the same API



commit 4e3ff1b24118a1913a77285efc33ca38685a3ea5
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Wed Mar 27 17:58:32 2013 +0100

    Make ephy-about-handler a GObject and handle all request using the same API
    
    about:plugins was handled differently because it's asynchrounous, now
    all handlers can be implemented asynchronously too.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=696728

 embed/ephy-about-handler.c |  287 +++++++++++++++++++++++++++++++++-----------
 embed/ephy-about-handler.h |   35 +++++-
 embed/ephy-embed-shell.c   |   56 +--------
 3 files changed, 250 insertions(+), 128 deletions(-)
---
diff --git a/embed/ephy-about-handler.c b/embed/ephy-about-handler.c
index 31eb775..ef15a12 100644
--- a/embed/ephy-about-handler.c
+++ b/embed/ephy-about-handler.c
@@ -28,40 +28,123 @@
 
 #include <gio/gio.h>
 #include <glib/gi18n.h>
-#include <webkit2/webkit2.h>
 
-static gchar *css_style = NULL;
+struct _EphyAboutHandlerPrivate {
+  char *style_sheet;
+  EphySMaps *smaps;
+};
+
+G_DEFINE_TYPE (EphyAboutHandler, ephy_about_handler, G_TYPE_OBJECT)
+
+static void
+ephy_about_handler_finalize (GObject *object)
+{
+  EphyAboutHandler *handler = EPHY_ABOUT_HANDLER (object);
+
+  g_free (handler->priv->style_sheet);
+  g_clear_object (&handler->priv->smaps);
+
+  G_OBJECT_CLASS (ephy_about_handler_parent_class)->finalize (object);
+}
+
+static void
+ephy_about_handler_init (EphyAboutHandler *handler)
+{
+  handler->priv = G_TYPE_INSTANCE_GET_PRIVATE (handler, EPHY_TYPE_ABOUT_HANDLER, EphyAboutHandlerPrivate);
+}
 
 static void
-read_css_style (void)
+ephy_about_handler_class_init (EphyAboutHandlerClass *klass)
 {
-  GError *error = NULL;
-  const gchar *file;
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  if (css_style)
-    return;
+  object_class->finalize = ephy_about_handler_finalize;
+  g_type_class_add_private (object_class, sizeof (EphyAboutHandlerPrivate));
+}
 
-  file = ephy_file ("about.css");
-  if (file && !g_file_get_contents (file, &css_style, NULL, &error)) {
-    g_debug ("%s", error->message);
-    g_error_free (error);
+static const char *
+ephy_about_handler_get_style_sheet (EphyAboutHandler *handler)
+{
+  if (!handler->priv->style_sheet) {
+    const gchar *file;
+    GError *error = NULL;
+
+    file = ephy_file ("about.css");
+    if (file && !g_file_get_contents (file, &handler->priv->style_sheet, NULL, &error)) {
+      g_debug ("%s", error->message);
+      g_error_free (error);
+    }
   }
+
+  return handler->priv->style_sheet;
 }
 
-void
-_ephy_about_handler_handle_plugins (GString *data_str, GList *plugin_list)
+static EphySMaps *
+ephy_about_handler_get_smaps (EphyAboutHandler *handler)
 {
-  GList *p;
+  if (!handler->priv->smaps)
+    handler->priv->smaps = ephy_smaps_new ();
 
-  read_css_style ();
+  return handler->priv->smaps;
+}
 
+static void
+ephy_about_handler_finish_request (WebKitURISchemeRequest *request,
+                                   gchar *data,
+                                   gsize data_length)
+{
+  GInputStream *stream;
+
+  data_length = data_length != -1 ? data_length : strlen (data);
+  stream = g_memory_input_stream_new_from_data (data, data_length, g_free);
+  webkit_uri_scheme_request_finish (request, stream, data_length, "text/html");
+  g_object_unref (stream);
+}
+
+typedef struct {
+  EphyAboutHandler *handler;
+  WebKitURISchemeRequest *request;
+} EphyAboutRequest;
+
+static EphyAboutRequest *
+ephy_about_request_new (EphyAboutHandler *handler,
+                        WebKitURISchemeRequest *request)
+{
+  EphyAboutRequest *about_request;
+
+  about_request = g_slice_new (EphyAboutRequest);
+  about_request->handler = g_object_ref (handler);
+  about_request->request = g_object_ref (request);
+
+  return about_request;
+}
+
+static void
+ephy_about_request_free (EphyAboutRequest *about_request)
+{
+  g_object_unref (about_request->handler);
+  g_object_unref (about_request->request);
+
+  g_slice_free (EphyAboutRequest, about_request);
+}
+
+static void
+get_plugins_cb (WebKitWebContext *web_context,
+                GAsyncResult *result,
+                EphyAboutRequest *about_request)
+{
+  GString *data_str;
+  gsize data_length;
+  GList *plugin_list, *p;
+
+  data_str = g_string_new ("<html>");
   g_string_append_printf (data_str, "<head><title>%s</title>"           \
                           "<style type=\"text/css\">%s</style></head><body>",
                           _("Installed plugins"),
-                          css_style);
-
+                          ephy_about_handler_get_style_sheet (about_request->handler));
   g_string_append_printf (data_str, "<h1>%s</h1>", _("Installed plugins"));
 
+  plugin_list = webkit_web_context_get_plugins_finish (web_context, result, NULL);
   for (p = plugin_list; p; p = p->next) {
     WebKitPlugin *plugin = WEBKIT_PLUGIN (p->data);
     GList *m, *mime_types;
@@ -96,67 +179,97 @@ _ephy_about_handler_handle_plugins (GString *data_str, GList *plugin_list)
 
     g_string_append (data_str, "</tbody></table>");
   }
+  g_string_append (data_str, "</body></html>");
 
-  g_string_append (data_str, "</body>");
+  g_list_free_full (plugin_list, g_object_unref);
+
+  data_length = data_str->len;
+  ephy_about_handler_finish_request (about_request->request, g_string_free (data_str, FALSE), data_length);
+  ephy_about_request_free (about_request);
 }
 
-static void
-ephy_about_handler_handle_plugins (GString *data_str)
+static gboolean
+ephy_about_handler_handle_plugins (EphyAboutHandler *handler,
+                                   WebKitURISchemeRequest *request)
 {
-  g_string_append (data_str, "</body>");
+  webkit_web_context_get_plugins (webkit_web_context_get_default (),
+                                  NULL,
+                                  (GAsyncReadyCallback)get_plugins_cb,
+                                  ephy_about_request_new (handler, request));
+
+  return TRUE;
 }
 
-static void
-ephy_about_handler_handle_memory (GString *data_str)
+static gboolean
+ephy_about_handler_handle_memory (EphyAboutHandler *handler,
+                                  WebKitURISchemeRequest *request)
 {
+  GString *data_str;
+  gsize data_length;
   char *memory;
-  static EphySMaps *smaps = NULL;
-  if (!smaps)
-    smaps = ephy_smaps_new ();
 
-  memory = ephy_smaps_to_html (smaps);
+  memory = ephy_smaps_to_html (ephy_about_handler_get_smaps (handler));
+
+  data_str = g_string_new ("<html>");
 
   if (memory) {
     g_string_append_printf (data_str, "<head><title>%s</title>"         \
                             "<style type=\"text/css\">%s</style></head><body>",
                             _("Memory usage"),
-                            css_style);
+                            ephy_about_handler_get_style_sheet (handler));
 
     g_string_append_printf (data_str, "<h1>%s</h1>", _("Memory usage"));
     g_string_append (data_str, memory);
     g_free (memory);
   }
+
+  g_string_append (data_str, "</html>");
+
+  data_length = data_str->len;
+  ephy_about_handler_finish_request (request, g_string_free (data_str, FALSE), data_length);
+
+  return TRUE;
 }
 
-static void
-ephy_about_handler_handle_epiphany (GString *data_str)
+static gboolean
+ephy_about_handler_handle_epiphany (EphyAboutHandler *handler,
+                                    WebKitURISchemeRequest *request)
 {
-  g_string_append_printf (data_str, "<head><title>Epiphany</title>"     \
-                          "<style type=\"text/css\">%s</style></head>"  \
-                          "<body style=\"background: #3369FF; color: white; font-style: italic;\">",
-                          css_style);
-
-  g_string_append (data_str, "<div id=\"ephytext\">"                    \
-                   "Il semble que la perfection soit atteinte non quand il n'y a plus rien à" \
-                   " ajouter, mais quand il n'y a plus rien à retrancher." \
-                   "</div>"                                             \
-                   "<div id=\"from\">"                                  \
-                   "<!-- Terre des Hommes, III: L'Avion, p. 60 -->"     \
-                   "Antoine de Saint-Exupéry"                           \
-                   "</div></body>");
+  char *data;
+
+  data = g_strdup_printf ("<html><head><title>Epiphany</title>"
+                          "<style type=\"text/css\">%s</style></head>"
+                          "<body style=\"background: #3369FF; color: white; font-style: italic;\">"
+                          "<div id=\"ephytext\">"
+                          "Il semble que la perfection soit atteinte non quand il n'y a plus rien à"
+                          " ajouter, mais quand il n'y a plus rien à retrancher."
+                          "</div>"
+                          "<div id=\"from\">"
+                          "<!-- Terre des Hommes, III: L'Avion, p. 60 -->"
+                          "Antoine de Saint-Exupéry"
+                          "</div></body></html>",
+                          ephy_about_handler_get_style_sheet (handler));
+
+  ephy_about_handler_finish_request (request, data, -1);
+
+  return TRUE;
 }
 
-static void
-ephy_about_handler_handle_applications (GString *data_str)
+static gboolean
+ephy_about_handler_handle_applications (EphyAboutHandler *handler,
+                                        WebKitURISchemeRequest *request)
 {
+  GString *data_str;
+  gsize data_length;
   GList *applications, *p;
 
-  g_string_append_printf (data_str, "<head><title>%s</title>"           \
+  data_str = g_string_new (NULL);
+  g_string_append_printf (data_str, "<html><head><title>%s</title>" \
                           "<style type=\"text/css\">%s</style></head>"  \
                           "<body class=\"applications-body\"><h1>%s</h1>" \
                           "<p>%s</p>",
                           _("Applications"),
-                          css_style,
+                          ephy_about_handler_get_style_sheet (handler),
                           _("Applications"),
                           _("List of installed web applications"));
 
@@ -184,24 +297,35 @@ ephy_about_handler_handle_applications (GString *data_str)
     g_free (img_data);
   }
 
-  g_string_append (data_str, "</table></body>");
+  g_string_append (data_str, "</table></body></html>");
 
   ephy_web_application_free_application_list (applications);
+
+  data_length = data_str->len;
+  ephy_about_handler_finish_request (request, g_string_free (data_str, FALSE), data_length);
+
+  return TRUE;
 }
 
-static void
-ephy_about_handler_handle_incognito (GString *data_str)
+static gboolean
+ephy_about_handler_handle_incognito (EphyAboutHandler *handler,
+                                     WebKitURISchemeRequest *request)
 {
   const char *filename;
   char *img_data = NULL, *img_data_base64 = NULL;
+  char *data;
   gsize data_length;
 
+  if (ephy_embed_shell_get_mode (ephy_embed_shell_get_default ()) != EPHY_EMBED_SHELL_MODE_INCOGNITO)
+    return FALSE;
+
   filename = ephy_file ("incognito.png");
   if (filename) {
     g_file_get_contents (filename, &img_data, &data_length, NULL);
     img_data_base64 = g_base64_encode ((guchar*)img_data, data_length);
   }
-  g_string_append_printf (data_str,                                    \
+
+  data = g_strdup_printf ("<html>\n"                                   \
                           "<head>\n"                                   \
                           "<title>%s</title>\n"                        \
                           "<style type=\"text/css\">%s</style>\n"      \
@@ -213,9 +337,11 @@ ephy_about_handler_handle_incognito (GString *data_str)
                           "      <p>%s</p>\n"                          \
                           "    </div>\n"                               \
                           "  </div>\n"                                 \
-                          "</body>\n",
+                          "</body>\n"                                  \
+                          "</html>\n",
                           _("Private Browsing"),
-                          css_style, img_data_base64 ? img_data_base64 : "",
+                          ephy_about_handler_get_style_sheet (handler),
+                          img_data_base64 ? img_data_base64 : "",
                           _("Private Browsing"),
                           _("You are currently browsing <em>incognito</em>. Pages viewed in this "
                             "mode will not show up in your browsing history and all stored "
@@ -224,29 +350,44 @@ ephy_about_handler_handle_incognito (GString *data_str)
   g_free (img_data_base64);
   g_free (img_data);
 
+  ephy_about_handler_finish_request (request, data, -1);
+
+  return TRUE;
 }
 
-GString *
-ephy_about_handler_handle (const char *about)
+static void
+ephy_about_handler_handle_blank (EphyAboutHandler *handler,
+                                 WebKitURISchemeRequest *request)
 {
-  GString *data_str = g_string_new("<html>");
-
-  read_css_style ();
-
-  if (!g_strcmp0 (about, "plugins"))
-    ephy_about_handler_handle_plugins (data_str);
-  else if (!g_strcmp0 (about, "memory"))
-    ephy_about_handler_handle_memory (data_str);
-  else if (!g_strcmp0 (about, "epiphany"))
-    ephy_about_handler_handle_epiphany (data_str);
-  else if (!g_strcmp0 (about, "applications"))
-    ephy_about_handler_handle_applications (data_str);
-  else if (!g_strcmp0 (about, "incognito") &&
-           ephy_embed_shell_get_mode (ephy_embed_shell_get_default ())
-           == EPHY_EMBED_SHELL_MODE_INCOGNITO)
-    ephy_about_handler_handle_incognito (data_str);
+  ephy_about_handler_finish_request (request, g_strdup ("<html></html>"), -1);
+}
 
-  g_string_append (data_str, "</html>");
+EphyAboutHandler *
+ephy_about_handler_new (void)
+{
+  return EPHY_ABOUT_HANDLER (g_object_new (EPHY_TYPE_ABOUT_HANDLER, NULL));
+}
 
-  return data_str;
+void
+ephy_about_handler_handle_request (EphyAboutHandler *handler,
+                                   WebKitURISchemeRequest *request)
+{
+  const char *path;
+  gboolean    handled = FALSE;
+
+  path = webkit_uri_scheme_request_get_path (request);
+
+  if (!g_strcmp0 (path, "plugins"))
+    handled = ephy_about_handler_handle_plugins (handler, request);
+  else if (!g_strcmp0 (path, "memory"))
+    handled = ephy_about_handler_handle_memory (handler, request);
+  else if (!g_strcmp0 (path, "epiphany"))
+    handled =  ephy_about_handler_handle_epiphany (handler, request);
+  else if (!g_strcmp0 (path, "applications"))
+    handled = ephy_about_handler_handle_applications (handler, request);
+  else if (!g_strcmp0 (path, "incognito"))
+    handled = ephy_about_handler_handle_incognito (handler, request);
+
+  if (!handled)
+    ephy_about_handler_handle_blank (handler, request);
 }
diff --git a/embed/ephy-about-handler.h b/embed/ephy-about-handler.h
index 1b9fa6c..ae4fdb8 100644
--- a/embed/ephy-about-handler.h
+++ b/embed/ephy-about-handler.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
- *  Copyright © 2012 Igalia S.L.
+ *  Copyright © 2012, 2013 Igalia S.L.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -21,16 +21,41 @@
 #ifndef EPHY_ABOUT_HANDLER_H
 #define EPHY_ABOUT_HANDLER_H
 
-#include <glib.h>
+#include <webkit2/webkit2.h>
 
 G_BEGIN_DECLS
 
+#define EPHY_TYPE_ABOUT_HANDLER         (ephy_about_handler_get_type ())
+#define EPHY_ABOUT_HANDLER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_ABOUT_HANDLER, 
EphyAboutHandler))
+#define EPHY_ABOUT_HANDLER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_ABOUT_HANDLER, 
EphyAboutHandlerClass))
+#define EPHY_IS_ABOUT_HANDLER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_ABOUT_HANDLER))
+#define EPHY_IS_ABOUT_HANDLER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_ABOUT_HANDLER))
+#define EPHY_ABOUT_HANDLER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_ABOUT_HANDLER, 
EphyAboutHandlerClass))
+
 #define EPHY_ABOUT_SCHEME "ephy-about"
 #define EPHY_ABOUT_SCHEME_LEN 10
 
-GString * ephy_about_handler_handle          (const char *about);
-void      _ephy_about_handler_handle_plugins (GString    *data_str,
-                                              GList      *plugin_list);
+typedef struct _EphyAboutHandlerClass   EphyAboutHandlerClass;
+typedef struct _EphyAboutHandler        EphyAboutHandler;
+typedef struct _EphyAboutHandlerPrivate EphyAboutHandlerPrivate;
+
+struct _EphyAboutHandler
+{
+  GObject parent;
+
+  EphyAboutHandlerPrivate *priv;
+};
+
+struct _EphyAboutHandlerClass
+{
+  GObjectClass parent_class;
+};
+
+GType             ephy_about_handler_get_type       (void);
+
+EphyAboutHandler *ephy_about_handler_new            (void);
+void              ephy_about_handler_handle_request (EphyAboutHandler       *handler,
+                                                     WebKitURISchemeRequest *request);
 G_END_DECLS
 
 #endif /* EPHY_ABOUT_HANDLER_H */
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 85cce56..7fd8f79 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -55,6 +55,7 @@ struct _EphyEmbedShellPrivate
   GtkPrintSettings *print_settings;
   EphyEmbedShellMode mode;
   EphyFrecentStore *frecent_store;
+  EphyAboutHandler *about_handler;
   GDBusProxy *web_extension;
   guint web_extension_watch_name_id;
   guint web_extension_form_auth_save_signal_id;
@@ -104,6 +105,8 @@ ephy_embed_shell_dispose (GObject *object)
     priv->downloads = NULL;
   }
 
+  g_clear_object (&priv->about_handler);
+
   G_OBJECT_CLASS (ephy_embed_shell_parent_class)->dispose (object);
 }
 
@@ -315,57 +318,10 @@ ephy_embed_shell_setup_environment (EphyEmbedShell *shell)
 }
 
 static void
-complete_about_request_for_contents (WebKitURISchemeRequest *request,
-                                     gchar *data,
-                                     gsize data_length)
-{
-  GInputStream *stream;
-
-  stream = g_memory_input_stream_new_from_data (data, data_length, g_free);
-  webkit_uri_scheme_request_finish (request, stream, data_length, "text/html");
-  g_object_unref (stream);
-}
-
-static void
-get_plugins_cb (WebKitWebContext *web_context,
-                GAsyncResult *result,
-                WebKitURISchemeRequest *request)
-{
-  GList *plugins;
-  GString *data_str;
-  gsize data_length;
-
-  data_str = g_string_new("<html>");
-  plugins = webkit_web_context_get_plugins_finish (web_context, result, NULL);
-  _ephy_about_handler_handle_plugins (data_str, plugins);
-  g_string_append (data_str, "</html>");
-
-  data_length = data_str->len;
-  complete_about_request_for_contents (request, g_string_free (data_str, FALSE), data_length);
-  g_object_unref (request);
-}
-
-static void
 about_request_cb (WebKitURISchemeRequest *request,
-                  gpointer user_data)
+                  EphyEmbedShell *shell)
 {
-  const gchar *path;
-
-  path = webkit_uri_scheme_request_get_path (request);
-  if (!g_strcmp0 (path, "plugins")) {
-    /* Plugins API is async in WebKit2 */
-    webkit_web_context_get_plugins (webkit_web_context_get_default (),
-                                    NULL,
-                                    (GAsyncReadyCallback)get_plugins_cb,
-                                    g_object_ref (request));
-  } else {
-    GString *contents;
-    gsize data_length;
-
-    contents = ephy_about_handler_handle (path);
-    data_length = contents->len;
-    complete_about_request_for_contents (request, g_string_free (contents, FALSE), data_length);
-  }
+  ephy_about_handler_handle_request (shell->priv->about_handler, request);
 }
 
 static void
@@ -399,6 +355,7 @@ ephy_embed_shell_startup (GApplication* application)
   g_free (disk_cache_dir);
 
   /* about: URIs handler */
+  shell->priv->about_handler = ephy_about_handler_new ();
   webkit_web_context_register_uri_scheme (web_context,
                                           EPHY_ABOUT_SCHEME,
                                           (WebKitURISchemeRequestCallback)about_request_cb,
@@ -416,7 +373,6 @@ ephy_embed_shell_startup (GApplication* application)
   ephy_embed_prefs_set_cookie_accept_policy (cookie_manager, cookie_policy);
   g_free (cookie_policy);
 
-
   ephy_embed_prefs_init ();
 }
 


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