[epiphany] Added about:plugins support.
- From: Sergio Villar Senin <svillar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany] Added about:plugins support.
- Date: Wed, 1 Jun 2011 16:03:34 +0000 (UTC)
commit 89cd6749b82686ca78e8d44c5b3fb18fead02363
Author: Sergio Villar Senin <svillar igalia com>
Date: Wed Mar 30 09:36:08 2011 +0200
Added about:plugins support.
We are now able to show a page with the list of installed plugins.
Bug #575498
data/pages/Makefile.am | 6 +-
data/pages/about.css | 31 ++++++++
embed/ephy-embed-single.c | 9 ++
embed/ephy-embed-utils.c | 19 ++++-
embed/ephy-history.c | 12 +++-
embed/ephy-web-view.c | 8 ++
lib/Makefile.am | 4 +-
lib/ephy-request-about.c | 149 +++++++++++++++++++++++++++++++++++++
lib/ephy-request-about.h | 37 +++++++++
lib/widgets/ephy-location-entry.c | 17 ++++-
10 files changed, 282 insertions(+), 10 deletions(-)
---
diff --git a/data/pages/Makefile.am b/data/pages/Makefile.am
index f2b879a..5062f09 100644
--- a/data/pages/Makefile.am
+++ b/data/pages/Makefile.am
@@ -3,4 +3,8 @@ errorpages_DATA = \
recovery.html \
error.html
-EXTRA_DIST = $(errorpages_DATA)
+stylepagesdir = $(pkgdatadir)/pages
+stylepages_DATA = \
+ about.css
+
+EXTRA_DIST = $(errorpages_DATA) $(stylepages_DATA)
diff --git a/data/pages/about.css b/data/pages/about.css
new file mode 100644
index 0000000..2937047
--- /dev/null
+++ b/data/pages/about.css
@@ -0,0 +1,31 @@
+#plugin-table
+{
+ margin: 14px;
+ width: 80%;
+ text-align: left;
+ border-collapse: collapse;
+}
+
+#plugin-table th
+{
+ padding: 8px;
+ background:#b9c9ff;
+ border-top: 4px solid #aabcff;
+ border-bottom: 1px solid #fff;
+ color: #039;
+}
+
+#plugin-table td
+{
+ padding: 8px;
+ background: #e8edff;
+ border-bottom: 1px solid #fff;
+ color: #669;
+ border-top: 1px solidtransparent;
+}
+
+#plugin-table tr:hover td
+{
+ background: #d0dafd;
+ color:#339;
+}
\ No newline at end of file
diff --git a/embed/ephy-embed-single.c b/embed/ephy-embed-single.c
index 2353a12..a214f82 100644
--- a/embed/ephy-embed-single.c
+++ b/embed/ephy-embed-single.c
@@ -36,6 +36,7 @@
#include "ephy-profile-utils.h"
#include "ephy-prefs.h"
#include "ephy-settings.h"
+#include "ephy-request-about.h"
#ifdef ENABLE_CERTIFICATE_MANAGER
#include "ephy-certificate-manager.h"
@@ -45,6 +46,7 @@
#include <glib/gi18n.h>
#include <libsoup/soup-gnome.h>
#include <libsoup/soup-cache.h>
+#include <libsoup/soup-requester.h>
#include <gnome-keyring.h>
#define EPHY_EMBED_SINGLE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EMBED_SINGLE, EphyEmbedSinglePrivate))
@@ -484,6 +486,7 @@ ephy_embed_single_initialize (EphyEmbedSingle *single)
char *cookie_policy;
char *cache_dir;
EphyEmbedSinglePrivate *priv = single->priv;
+ SoupSessionFeature *requester;
/* Initialise nspluginwrapper's plugins if available */
if (g_file_test (NSPLUGINWRAPPER_SETUP, G_FILE_TEST_EXISTS) != FALSE)
@@ -537,6 +540,12 @@ ephy_embed_single_initialize (EphyEmbedSingle *single)
G_CALLBACK (cache_size_cb),
single);
+ /* about: URIs handler */
+ requester = SOUP_SESSION_FEATURE (soup_requester_new());
+ soup_session_add_feature (session, requester);
+ soup_session_feature_add_feature (requester, EPHY_TYPE_REQUEST_ABOUT);
+ g_object_unref (requester);
+
#ifdef SOUP_TYPE_PASSWORD_MANAGER
/* Use GNOME keyring to store passwords. Only add the manager if we
are not using a private session, otherwise we want any new
diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c
index d0e3690..2ca6d76 100644
--- a/embed/ephy-embed-utils.c
+++ b/embed/ephy-embed-utils.c
@@ -29,6 +29,7 @@
#include "ephy-string.h"
#include "ephy-embed-utils.h"
+#include "ephy-request-about.h"
char*
ephy_embed_utils_link_message_parse (char *message)
@@ -105,15 +106,25 @@ ephy_embed_utils_address_has_web_scheme (const char *address)
char*
ephy_embed_utils_normalize_address (const char *address)
{
- char *effective_address;
+ char *effective_address = NULL;
g_return_val_if_fail (address, NULL);
if (ephy_embed_utils_address_has_web_scheme (address) == FALSE)
effective_address = g_strconcat ("http://", address, NULL);
- else
- effective_address = g_strdup (address);
-
+ else {
+ /* Convert about: schemes to ephy-about: in order to
+ * force WebKit to delegate its handling to our
+ * EphyRequestAbout. In general about: schemes are
+ * handled internally by WebKit and mean "empty
+ * document".
+ */
+ if (!g_ascii_strcasecmp (address, "about:plugins"))
+ effective_address = g_strdup (EPHY_ABOUT_SCHEME":plugins");
+ else
+ effective_address = g_strdup (address);
+ }
+
return effective_address;
}
diff --git a/embed/ephy-history.c b/embed/ephy-history.c
index 86a4aaa..b6fe5dc 100644
--- a/embed/ephy-history.c
+++ b/embed/ephy-history.c
@@ -27,6 +27,7 @@
#include "ephy-node-db.h"
#include "ephy-node-common.h"
#include "ephy-prefs.h"
+#include "ephy-request-about.h"
#include "ephy-settings.h"
#include "ephy-string.h"
@@ -823,22 +824,30 @@ ephy_history_add_page (EphyHistory *eh,
static gboolean
impl_add_page (EphyHistory *eb,
- const char *url,
+ const char *orig_url,
gboolean redirect,
gboolean toplevel)
{
EphyNode *bm, *node, *host;
gulong flags = 0;
+ char *url;
if (eb->priv->enabled == FALSE)
{
return FALSE;
}
+ /* Do not show internal ephy-about: protocol to users */
+ if (g_str_has_prefix (orig_url, EPHY_ABOUT_SCHEME))
+ url = g_strdup_printf ("about:%s", orig_url + EPHY_ABOUT_SCHEME_LEN + 1);
+ else
+ url = g_strdup (orig_url);
+
node = ephy_history_get_page (eb, url);
if (node)
{
ephy_history_visited (eb, node);
+ g_free (url);
return TRUE;
}
@@ -846,6 +855,7 @@ impl_add_page (EphyHistory *eb,
ephy_node_set_property_string (bm, EPHY_NODE_PAGE_PROP_LOCATION, url);
ephy_node_set_property_string (bm, EPHY_NODE_PAGE_PROP_TITLE, url);
+ g_free (url);
if (redirect) flags |= REDIRECT_FLAG;
if (toplevel) flags |= TOPLEVEL_FLAG;
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 64ddc69..8cd73a7 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -44,6 +44,7 @@
#include "ephy-profile-utils.h"
#include "ephy-favicon-cache.h"
#include "ephy-history.h"
+#include "ephy-request-about.h"
#include "ephy-settings.h"
#include "ephy-string.h"
#include "ephy-web-view.h"
@@ -2455,6 +2456,8 @@ get_title_from_address (const char *address)
{
if (g_str_has_prefix (address, "file://"))
return g_strdup (address + 7);
+ else if (!strcmp (address, EPHY_ABOUT_SCHEME":plugins"))
+ return g_strdup (_("Plugins"));
else
return ephy_string_get_host_name (address);
}
@@ -2744,6 +2747,11 @@ ephy_web_view_location_changed (EphyWebView *view,
strcmp (location, "about:blank") == 0) {
ephy_web_view_set_address (view, NULL);
ephy_web_view_set_title (view, EMPTY_PAGE);
+ } else if (g_str_has_prefix (location, EPHY_ABOUT_SCHEME)) {
+ char *new_address = g_strdup_printf ("about:%s", location + EPHY_ABOUT_SCHEME_LEN + 1);
+ ephy_web_view_set_address (view, new_address);
+ g_free (new_address);
+ ephy_web_view_set_title (view, EMPTY_PAGE);
} else {
char *view_address;
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 6be8ef7..63d58db 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -19,8 +19,9 @@ NOINST_H_FILES = \
ephy-node-common.h \
ephy-object-helpers.h \
ephy-prefs.h \
- ephy-profile-utils.h \
+ ephy-profile-utils.h \
ephy-print-utils.h \
+ ephy-request-about.h \
ephy-shlib-loader.h \
ephy-signal-accumulator.h \
ephy-string.h \
@@ -60,6 +61,7 @@ libephymisc_la_SOURCES = \
ephy-profile-utils.c \
ephy-profile-utils.h \
ephy-print-utils.c \
+ ephy-request-about.c \
ephy-settings.c \
ephy-shlib-loader.c \
ephy-signal-accumulator.c \
diff --git a/lib/ephy-request-about.c b/lib/ephy-request-about.c
new file mode 100644
index 0000000..167f2ec
--- /dev/null
+++ b/lib/ephy-request-about.c
@@ -0,0 +1,149 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * ephy-request-about.c: about: URI request object
+ *
+ * Copyright (C) 2011, Igalia S.L.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+#include <libsoup/soup-uri.h>
+#include <webkit/webkit.h>
+
+#include "ephy-file-helpers.h"
+#include "ephy-request-about.h"
+
+G_DEFINE_TYPE (EphyRequestAbout, ephy_request_about, SOUP_TYPE_REQUEST)
+
+struct _EphyRequestAboutPrivate {
+ gssize content_length;
+ gchar *css_style;
+};
+
+static void
+ephy_request_about_init (EphyRequestAbout *about)
+{
+ about->priv = G_TYPE_INSTANCE_GET_PRIVATE (about, EPHY_TYPE_REQUEST_ABOUT, EphyRequestAboutPrivate);
+ about->priv->content_length = 0;
+ about->priv->css_style = NULL;
+}
+
+static void
+ephy_request_about_finalize (GObject *obj)
+{
+ g_free (EPHY_REQUEST_ABOUT(obj)->priv->css_style);
+
+ G_OBJECT_CLASS (ephy_request_about_parent_class)->finalize (obj);
+}
+
+static gboolean
+ephy_request_about_check_uri (SoupRequest *request,
+ SoupURI *uri,
+ GError **error)
+{
+ return uri->host == NULL;
+}
+
+static void
+read_css_style (EphyRequestAbout *about)
+{
+ GError *error = NULL;
+
+ if (!g_file_get_contents (ephy_file("about.css"), &(about->priv->css_style), NULL, &error))
+ g_debug (error->message);
+}
+
+static GInputStream *
+ephy_request_about_send (SoupRequest *request,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EphyRequestAbout *about = EPHY_REQUEST_ABOUT (request);
+ SoupURI *uri = soup_request_get_uri (request);
+ GString *data_str = g_string_new("<html>");
+
+ if (!about->priv->css_style)
+ read_css_style (about);
+
+ g_string_append_printf (data_str, "<head><title>%s</title>" \
+ "<style type=\"text/css\">%s</style></head><body>",
+ _("Installed plugins"),
+ about->priv->css_style);
+
+ if (!g_strcmp0 (uri->path, "plugins")) {
+ WebKitWebPluginDatabase* database = webkit_get_web_plugin_database ();
+ GSList *plugin_list, *p;
+
+ g_string_append_printf(data_str, "<h1>%s</h1>", _("Installed plugins"));
+ plugin_list = webkit_web_plugin_database_get_plugins (database);
+ for (p = plugin_list; p; p = p->next) {
+ WebKitWebPlugin *plugin = WEBKIT_WEB_PLUGIN (p->data);
+ GSList *m, *mime_types;
+
+ g_string_append_printf(data_str, "<h2>%s</h2>%s<br>%s: <b>%s</b>"\
+ "<table id=\"plugin-table\">" \
+ "<thead><tr><th>%s</th><th>%s</th><th>%s</th></tr></thead><tbody>",
+ webkit_web_plugin_get_name (plugin),
+ webkit_web_plugin_get_description (plugin),
+ _("Enabled"), webkit_web_plugin_get_enabled (plugin) ? _("Yes") : _("No"),
+ _("MIME type"), _("Description"), _("Suffixes"));
+
+ mime_types = webkit_web_plugin_get_mimetypes (plugin);
+ for (m = mime_types; m; m = m->next) {
+ WebKitWebPluginMIMEType *mime_type = (WebKitWebPluginMIMEType*) m->data;
+ guint extensions_len = g_strv_length (mime_type->extensions);
+ guint i;
+
+ g_string_append_printf (data_str, "<tr><td>%s</td><td>%s</td><td>",
+ mime_type->name, mime_type->description);
+
+ for (i = 0; i < extensions_len; i++)
+ g_string_append_printf (data_str, "%s%c", mime_type->extensions[i],
+ i == (extensions_len - 1) ? ' ' : ',');
+
+ g_string_append(data_str, "</td></tr>");
+ }
+ g_string_append(data_str, "</tbody></table>");
+ }
+ webkit_web_plugin_database_plugins_list_free (plugin_list);
+ }
+
+ g_string_append(data_str, "</body></html>");
+ about->priv->content_length = data_str->len;
+ return g_memory_input_stream_new_from_data (g_string_free(data_str, false), about->priv->content_length, g_free);
+}
+
+static goffset
+ephy_request_about_get_content_length (SoupRequest *request)
+{
+ return EPHY_REQUEST_ABOUT (request)->priv->content_length;
+}
+
+static const char *
+ephy_request_about_get_content_type (SoupRequest *request)
+{
+ return "text/html";
+}
+
+static const char *about_schemes[] = { EPHY_ABOUT_SCHEME, NULL };
+
+static void
+ephy_request_about_class_init (EphyRequestAboutClass *request_about_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (request_about_class);
+ SoupRequestClass *request_class = SOUP_REQUEST_CLASS (request_about_class);
+
+ gobject_class->finalize = ephy_request_about_finalize;
+
+ request_class->schemes = about_schemes;
+ request_class->check_uri = ephy_request_about_check_uri;
+ request_class->send = ephy_request_about_send;
+ request_class->get_content_length = ephy_request_about_get_content_length;
+ request_class->get_content_type = ephy_request_about_get_content_type;
+
+ g_type_class_add_private (request_about_class, sizeof (EphyRequestAboutPrivate));
+}
diff --git a/lib/ephy-request-about.h b/lib/ephy-request-about.h
new file mode 100644
index 0000000..bb16eda
--- /dev/null
+++ b/lib/ephy-request-about.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2011, Igalia S.L.
+ */
+
+#ifndef EPHY_REQUEST_ABOUT_H
+#define EPHY_REQUEST_ABOUT_H 1
+
+#define LIBSOUP_USE_UNSTABLE_REQUEST_API
+#include <libsoup/soup-request.h>
+
+#define EPHY_TYPE_REQUEST_ABOUT (ephy_request_about_get_type ())
+#define EPHY_REQUEST_ABOUT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), EPHY_TYPE_REQUEST_ABOUT, EphyRequestAbout))
+#define EPHY_REQUEST_ABOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_REQUEST_ABOUT, EphyRequestAboutClass))
+#define EPHY_IS_REQUEST_ABOUT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), EPHY_TYPE_REQUEST_ABOUT))
+#define EPHY_IS_REQUEST_ABOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EPHY_TYPE_REQUEST_ABOUT))
+#define EPHY_REQUEST_ABOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_TYPE_REQUEST_ABOUT, EphyRequestAboutClass))
+
+#define EPHY_ABOUT_SCHEME "ephy-about"
+#define EPHY_ABOUT_SCHEME_LEN 10
+
+typedef struct _EphyRequestAboutPrivate EphyRequestAboutPrivate;
+
+typedef struct {
+ SoupRequest parent;
+
+ EphyRequestAboutPrivate *priv;
+} EphyRequestAbout;
+
+typedef struct {
+ SoupRequestClass parent;
+
+} EphyRequestAboutClass;
+
+GType ephy_request_about_get_type (void);
+
+#endif /* EPHY_REQUEST_ABOUT_H */
diff --git a/lib/widgets/ephy-location-entry.c b/lib/widgets/ephy-location-entry.c
index 79c921f..cb8d9b3 100644
--- a/lib/widgets/ephy-location-entry.c
+++ b/lib/widgets/ephy-location-entry.c
@@ -32,6 +32,7 @@
#include "ephy-stock-icons.h"
#include "ephy-debug.h"
#include "ephy-gui.h"
+#include "ephy-request-about.h"
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
@@ -1049,6 +1050,12 @@ textcell_data_func (GtkCellLayout *cell_layout,
if (url)
{
+ /* Do not show internal ephy-about: protocol to users */
+ if (g_str_has_prefix (url, EPHY_ABOUT_SCHEME)) {
+ g_free (url);
+ url = g_strdup_printf ("about:%s", url + strlen (EPHY_ABOUT_SCHEME) + 1);
+ }
+
ctext = g_strdup_printf ("%s\n%s", title, url);
style = gtk_widget_get_style_context (priv->entry);
@@ -1278,7 +1285,7 @@ ephy_location_entry_set_location (EphyLocationEntry *entry,
EphyLocationEntryPrivate *priv = entry->priv;
GtkClipboard *clipboard;
const char *text;
- char* selection = NULL;
+ char *effective_text = NULL, *selection = NULL;
int start, end;
/* Setting a new text will clear the clipboard. This makes it impossible
@@ -1303,6 +1310,9 @@ ephy_location_entry_set_location (EphyLocationEntry *entry,
if (address != NULL && strcmp (address, "about:blank") != 0)
{
+ if (g_str_has_prefix (address, EPHY_ABOUT_SCHEME))
+ effective_text = g_strdup_printf ("about:%s",
+ address + strlen (EPHY_ABOUT_SCHEME) + 1);
text = address;
}
else
@@ -1311,11 +1321,12 @@ ephy_location_entry_set_location (EphyLocationEntry *entry,
}
/* First record the new hash, then update the entry text */
- priv->hash = g_str_hash (text);
+ priv->hash = g_str_hash (effective_text ? effective_text : text);
priv->block_update = TRUE;
- gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
+ gtk_entry_set_text (GTK_ENTRY (priv->entry), effective_text ? effective_text : text);
priv->block_update = FALSE;
+ g_free (effective_text);
/* We need to call update_address_state() here, as the 'changed' signal
* may not get called if the user has typed in the exact correct url */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]