[epiphany/peas] Port Epiphany to libpeas



commit d05b6f07d416cd1fcc050bb1a8f9d0eeb1696869
Author: Diego Escalante Urrelo <descalante igalia com>
Date:   Sat Apr 2 12:36:43 2011 -0500

    Port Epiphany to libpeas
    
    This removes the old extension loaders, the extensions manager and does a minor
    refactor of how ephy-shell and ephy-session were hoooking into the session.
    
    THIS BREAKS EPHY EXTENSIONS. A wip 'peas' branch is available in git.gnome.org.
    It's really simple to migrate.
    
    Bug #646597

 configure.ac                  |   29 +-
 data/epiphany.pc.in           |    2 +-
 data/ui/epiphany-ui.xml       |    4 +-
 doc/reference/Makefile.am     |    5 -
 lib/Makefile.am               |    4 -
 lib/ephy-loader.c             |   68 ---
 lib/ephy-loader.h             |   69 ---
 lib/ephy-shlib-loader.c       |  245 ---------
 lib/ephy-shlib-loader.h       |   60 ---
 src/Makefile.am               |   22 +-
 src/ephy-extensions-manager.c | 1146 ++---------------------------------------
 src/ephy-extensions-manager.h |   40 +--
 src/ephy-lockdown.c           |   19 +-
 src/ephy-lockdown.h           |    5 +
 src/ephy-seed-extension.c     |  276 ----------
 src/ephy-seed-extension.h     |   61 ---
 src/ephy-seed-loader.c        |  107 ----
 src/ephy-seed-loader.h        |   61 ---
 src/ephy-session.c            |   37 +-
 src/ephy-session.h            |    6 +
 src/ephy-shell.c              |   23 +-
 src/ephy-shell.h              |    2 +
 src/ephy-window.c             |   78 +++-
 src/window-commands.c         |   29 +
 src/window-commands.h         |    3 +
 tests/Makefile.am             |    7 -
 26 files changed, 168 insertions(+), 2240 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c21112e..01d9aab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,7 @@ WEBKIT_GTK_REQUIRED=1.4.0
 LIBSOUP_GNOME_REQUIRED=2.33.1
 GNOME_KEYRING_REQUIRED=2.26.0
 GSETTINGS_DESKTOP_SCHEMAS_REQUIRED=0.0.1
+PEAS_REQUIRED=1.0.0
 
 # Tests
 
@@ -125,6 +126,8 @@ PKG_CHECK_MODULES([DEPENDENCIES], [
 		  libsoup-gnome-2.4 >= $LIBSOUP_GNOME_REQUIRED
 		  gnome-keyring-1 >= $GNOME_KEYRING_REQUIRED
                   gsettings-desktop-schemas >= $GSETTINGS_DESKTOP_SCHEMAS_REQUIRED
+		  libpeas-1.0 >= $PEAS_REQUIRED
+		  libpeas-gtk-1.0 >= $PEAS_REQUIRED
 		  ])
 
 # ****
@@ -195,31 +198,6 @@ if test "$found_introspection" = "yes"; then
   AC_DEFINE([ENABLE_INTROSPECTION], [1], [Define to enable introspection support])
 fi
 
-# ****
-# Seed
-# ****
-
-AC_MSG_CHECKING([whether Seed support is requested])
-AC_ARG_ENABLE([seed],
-  [AS_HELP_STRING([--enable-seed],[Enable Seed support (default: disabled)])],
-  [],[enable_seed=no])
-AC_MSG_RESULT([$enable_seed])
-
-if test "$enable_seed" = "yes" -a "$found_introspection" != "yes"; then
-  AC_MSG_ERROR([GObject introspection support must be enabled for Seed])
-fi
-
-if test "$enable_seed" = "yes"; then
-  EPIPHANY_FEATURES="$EPIPHANY_FEATURES seed"
-
-  SEED_REQUIRED=2.27.91
-  PKG_CHECK_MODULES([SEED],[seed >= $SEED_REQUIRED])
-
-  AC_DEFINE([ENABLE_SEED],[1],[Define to compile with Seed support])
-fi
-
-AM_CONDITIONAL([ENABLE_SEED],[test "$enable_seed" = "yes"])
-
 # *********************
 # CA Certificate file
 # Stolen from GIO's TLS
@@ -461,7 +439,6 @@ Epiphany was configured with the following options:
  	Zeroconf bookmarks support : $enable_zeroconf
  	NetworkManager support     : $enable_network_manager
  	GObject introspection      : $found_introspection
- 	Seed support               : $enable_seed
  	NSS support                : $enable_nss
 	Build tests		   : $enable_tests
 	CA Certificates file	   : $GTLS_SYSTEM_CA_FILE
diff --git a/data/epiphany.pc.in b/data/epiphany.pc.in
index e06bd5b..00f5290 100644
--- a/data/epiphany.pc.in
+++ b/data/epiphany.pc.in
@@ -12,6 +12,6 @@ features= EPIPHANY_FEATURES@
 Name: Epiphany Browser
 Description: GNOME Web Browser
 Version: @VERSION@
-Requires: gtk+-3.0, libxml-2.0, webkitgtk-3.0
+Requires: gtk+-3.0, libpeas-1.0, libpeas-gtk-1.0, libxml-2.0, webkitgtk-3.0
 Libs: -L${libdir}
 Cflags: -I${includedir}
diff --git a/data/ui/epiphany-ui.xml b/data/ui/epiphany-ui.xml
index 90ae367..140d034 100644
--- a/data/ui/epiphany-ui.xml
+++ b/data/ui/epiphany-ui.xml
@@ -85,7 +85,9 @@
 			<separator name="BookmarksSep1"/>
 		</menu>
 
-		<menu name="ToolsMenu" action="Tools"/>
+		<menu name="ToolsMenu" action="Tools">
+			<menuitem name="ToolsExtensionsManager"	action="ToolsExtensionsManager"/>
+		</menu>
 
 		<menu name="TabsMenu" action="Tabs">
 			<menuitem name="TabsPreviousMenu" action="TabsPrevious"/>
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
index 9b5de96..3227c38 100644
--- a/doc/reference/Makefile.am
+++ b/doc/reference/Makefile.am
@@ -132,11 +132,6 @@ GTKDOC_LIBS = \
 	$(DBUS_LIBS) \
 	$(LIBINTL)
 
-if ENABLE_SEED
-GTKDOC_LIBS += \
-	$(SEED_LIBS)
-endif
-
 # If you need to override some of the declarations, place them in the
 # $(DOC_MODULE)-overrides.txt file and uncomment the second line here.
 DOC_OVERRIDES =
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 6be8ef7..fc15646 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -21,7 +21,6 @@ NOINST_H_FILES = \
 	ephy-prefs.h				\
 	ephy-profile-utils.h				\
 	ephy-print-utils.h			\
-	ephy-shlib-loader.h			\
 	ephy-signal-accumulator.h		\
 	ephy-string.h				\
 	ephy-stock-icons.h			\
@@ -34,7 +33,6 @@ TYPES_H_FILES = \
 
 INST_H_FILES = \
 	ephy-dialog.h				\
-	ephy-loader.h				\
 	ephy-node.h				\
 	ephy-node-db.h				\
 	ephy-settings.h				\
@@ -48,7 +46,6 @@ libephymisc_la_SOURCES = \
 	ephy-file-helpers.c			\
 	ephy-gui.c				\
 	ephy-langs.c				\
-	ephy-loader.c				\
 	ephy-module.c				\
 	ephy-node.c				\
 	ephy-node.h				\
@@ -61,7 +58,6 @@ libephymisc_la_SOURCES = \
 	ephy-profile-utils.h			\
 	ephy-print-utils.c			\
 	ephy-settings.c				\
-	ephy-shlib-loader.c			\
 	ephy-signal-accumulator.c		\
 	ephy-state.c				\
 	ephy-string.c				\
diff --git a/src/Makefile.am b/src/Makefile.am
index f399505..332d7f8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -124,20 +124,6 @@ libephymain_la_SOURCES += \
 libephymain_la_CFLAGS += $(NETWORK_MANAGER_CFLAGS)
 endif
 
-if ENABLE_SEED
-NOINST_H_FILES += \
-	ephy-seed-extension.h \
-	ephy-seed-loader.h \
-	$(NULL)
-
-libephymain_la_SOURCES += \
-	ephy-seed-loader.c \
-	ephy-seed-extension.c \
-	$(NULL)
-
-libephymain_la_CFLAGS += $(SEED_CFLAGS)
-endif # ENABLE_SEED
-
 epiphany_SOURCES = ephy-main.c
 
 epiphany_CPPFLAGS = \
@@ -175,10 +161,6 @@ epiphany_CFLAGS += $(INTROSPECTION_CFLAGS)
 epiphany_LDADD += $(INTROSPECTION_LIBS)
 endif
 
-if ENABLE_SEED
-epiphany_LDADD += $(SEED_LIBS)
-endif # ENABLE_SEED
-
 if ENABLE_NETWORK_MANAGER
 epiphany_LDADD += \
 	$(NETWORK_MANAGER_LIBS)
@@ -312,7 +294,7 @@ EPHY_GIR_C_FILES = \
 	$(top_srcdir)/lib/widgets/ephy-download-widget.c \
 	$(top_srcdir)/lib/widgets/ephy-search-entry.c \
 	$(top_srcdir)/src/bookmarks/ephy-bookmarks.c \
-	$(top_srcdir)/src/ephy-extension.c \
+	$(top_srcdir)/src/ephy-extension.h \
 	$(top_srcdir)/src/ephy-extensions-manager.c \
 	$(top_srcdir)/src/ephy-find-toolbar.c \
 	$(top_srcdir)/src/ephy-link-action.c \
@@ -358,6 +340,8 @@ Epiphany-$(EPIPHANY_API_VERSION).gir: EphyEgg-$(EPIPHANY_API_VERSION).gir $(INTR
 		--include=Gtk-3.0 \
 		--include=libxml2-2.0 \
 		--include=WebKit-3.0 \
+		--include=Peas-1.0 \
+		--include=PeasGtk-1.0 \
 		--include-uninstalled=EphyEgg-$(EPIPHANY_API_VERSION).gir \
 		--program=./epiphany \
 		--output=$@ \
diff --git a/src/ephy-extensions-manager.c b/src/ephy-extensions-manager.c
index c50d25a..dddfdf8 100644
--- a/src/ephy-extensions-manager.c
+++ b/src/ephy-extensions-manager.c
@@ -25,1155 +25,75 @@
 
 #include "ephy-extensions-manager.h"
 
-#include "ephy-loader.h"
-#include "ephy-shlib-loader.h"
-
 #include "ephy-embed-container.h"
 
-#include "ephy-node-db.h"
 #include "ephy-shell.h"
 #include "ephy-file-helpers.h"
-#include "ephy-object-helpers.h"
 #include "ephy-debug.h"
 #include "ephy-prefs.h"
 #include "ephy-settings.h"
 
-#include <gio/gio.h>
-#include <gmodule.h>
-#include <string.h>
-
-#ifdef ENABLE_SEED
-#include "ephy-seed-loader.h"
-#endif
-
-#define EE_GROUP		"Epiphany Extension"
-#define DOT_INI			".ephy-extension"
-#define RELOAD_DELAY		333 /* ms */
-#define RELOAD_SYNC_DELAY	1 /* seconds */
+#include <libpeas/peas.h>
 
 #define EPHY_EXTENSIONS_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerPrivate))
 
-struct _EphyExtensionsManagerPrivate
-{
-	gboolean initialised;
-
-	GList *data;
-	GList *factories;
-	GList *extensions;
-	GList *dir_monitors;
-	GList *windows;
-	guint sync_timeout_id;
-	GHashTable *reload_hash;
-};
-
-typedef struct
-{
-	EphyExtensionInfo info;
-	gboolean load_failed;
-
-	char *loader_type;
-
-	EphyLoader *loader; /* NULL if never loaded */
-	GObject *extension; /* NULL if unloaded */
-} ExtensionInfo;
-
-typedef struct
-{
-	char *type;
-	EphyLoader *loader;
-} LoaderInfo;
-
-typedef enum
-{
-	FORMAT_UNKNOWN,
-	FORMAT_INI
-} ExtensionFormat;
-
-enum
-{
-	CHANGED,
-	ADDED,
-	REMOVED,
-	LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
 static void ephy_extensions_manager_class_init	(EphyExtensionsManagerClass *klass);
-static void ephy_extensions_manager_iface_init	(EphyExtensionIface *iface);
 static void ephy_extensions_manager_init	(EphyExtensionsManager *manager);
 
-G_DEFINE_TYPE_WITH_CODE (EphyExtensionsManager, ephy_extensions_manager, G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (EPHY_TYPE_EXTENSION,
-						ephy_extensions_manager_iface_init))
-
-static void
-ephy_extensions_manager_toggle_load (EphyExtensionsManager *manager,
-				     const char *identifier,
-				     gboolean status)
-{
-	char **exts;
-	GVariantBuilder builder;
-	int i;
-	gboolean found = FALSE;
-
-	g_return_if_fail (EPHY_IS_EXTENSIONS_MANAGER (manager));
-	g_return_if_fail (identifier != NULL);
-
-	if (status)
-		LOG ("Adding '%s' to extensions", identifier);
-	else
-		LOG ("Removing '%s' from extensions", identifier);
-
-	exts = g_settings_get_strv (EPHY_SETTINGS_MAIN,
-				    EPHY_PREFS_ENABLED_EXTENSIONS);
-
-	g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
-	for (i = 0; exts[i]; i++)
-	{
-		/* Ignore the extension if we are removing it. */
-		if (g_strcmp0 (exts[i], identifier) == 0)
-		{
-			found = TRUE;
-			if (!status)
-				continue;
-		}
+G_DEFINE_TYPE (EphyExtensionsManager, ephy_extensions_manager, PEAS_TYPE_ENGINE)
 
-		g_variant_builder_add (&builder, "s", exts[i]);
-	}
-
-	if (status && !found)
-		g_variant_builder_add (&builder, "s", identifier);
-
-	g_settings_set (EPHY_SETTINGS_MAIN,
-			EPHY_PREFS_ENABLED_EXTENSIONS,
-			"as", &builder);
-}
-
-/**
- * ephy_extensions_manager_load:
- * @manager: an #EphyExtensionsManager
- * @identifier: identifier of the extension to load
- *
- * Loads the extension corresponding to @identifier.
- **/
 void
-ephy_extensions_manager_load (EphyExtensionsManager *manager,
-			      const char *identifier)
-{
-	ephy_extensions_manager_toggle_load (manager, identifier, TRUE);
-}
-
-/**
- * ephy_extensions_manager_unload:
- * @manager: an #EphyExtensionsManager
- * @identifier: filename of extension to unload, minus "lib" and "extension.so"
- *
- * Unloads the extension specified by @identifier.
- *
- * The extension with the same filename can afterwards be reloaded. However,
- * if any GTypes within the extension have changed parent types, Epiphany must
- * be restarted.
- **/
-void
-ephy_extensions_manager_unload (EphyExtensionsManager *manager,
-				const char *identifier)
-{
-	ephy_extensions_manager_toggle_load (manager, identifier, FALSE);
-}
-
-/**
- * ephy_extensions_manager_register:
- * @manager: an #EphyExtensionsManager
- * @object: an Extension
- *
- * Registers @object with the extensions manager. @object must implement the
- * #EphyExtension interface.
- **/
-void
-ephy_extensions_manager_register (EphyExtensionsManager *manager,
-				  GObject *object)
-{
-	g_return_if_fail (EPHY_IS_EXTENSIONS_MANAGER (manager));
-	g_return_if_fail (EPHY_IS_EXTENSION (object));
-
-	manager->priv->extensions = g_list_prepend (manager->priv->extensions,
-						    g_object_ref (object));
-}
-
-
-/**
- * ephy_extensions_manager_get_extensions:
- * @manager: an #EphyExtensionsManager
- *
- * Returns the list of known extensions.
- *
- * Returns: (element-type EphyEmbed) (transfer container): a list of
- *          #EphyExtensionInfo
- **/
-GList *
-ephy_extensions_manager_get_extensions (EphyExtensionsManager *manager)
-{
-	return g_list_copy (manager->priv->data);
-}
-
-static void
-free_extension_info (ExtensionInfo *info)
-{
-	EphyExtensionInfo *einfo = (EphyExtensionInfo *) info;
-
-	g_free (einfo->identifier);
-	g_key_file_free (einfo->keyfile);
-	g_free (info->loader_type);
-
-	if (info->extension != NULL)
-	{
-		g_return_if_fail (info->loader != NULL);
-
-		ephy_loader_release_object (info->loader, info->extension);
-	}
-	if (info->loader != NULL)
-	{
-		g_object_unref (info->loader);
-	}
-
-	g_free (info);
-}
-
-static void
-free_loader_info (LoaderInfo *info)
-{
-	g_free (info->type);
-	g_object_unref (info->loader);
-	g_free (info);
-}
-
-static int
-find_extension_info (const ExtensionInfo *info,
-		     const char *identifier)
-{
-	return strcmp (info->info.identifier, identifier);
-}
-
-static ExtensionInfo *
-ephy_extensions_manager_parse_keyfile (EphyExtensionsManager *manager,
-				       GKeyFile *key_file,
-				       const char *identifier)
-{
-	ExtensionInfo *info;
-	EphyExtensionInfo *einfo;
-	char *start_group;
-
-	LOG ("Parsing INI description file for '%s'", identifier);
-
-	start_group = g_key_file_get_start_group (key_file);
-	if (start_group == NULL ||
-	    strcmp (start_group, EE_GROUP) != 0 ||
-	    !g_key_file_has_group (key_file, "Loader"))
-	{
-		g_warning ("Invalid extension description file for '%s'; "
-			   "missing 'Epiphany Extension' or 'Loader' group",
-			   identifier);
-		
-		g_key_file_free (key_file);
-		g_free (start_group);
-		return NULL;
-	}
-	g_free (start_group);
-
-	if (!g_key_file_has_key (key_file, EE_GROUP, "Name", NULL) ||
-	    !g_key_file_has_key (key_file, EE_GROUP, "Description", NULL))
-	{
-		g_warning ("Invalid extension description file for '%s'; "
-			   "missing 'Name' or 'Description' keys.",
-			   identifier);
-		
-		g_key_file_free (key_file);
-		return NULL;
-	}
-
-	info = g_new0 (ExtensionInfo, 1);
-	einfo = (EphyExtensionInfo *) info;
-	einfo->identifier = g_strdup (identifier);
-	einfo->keyfile = key_file;
-
-	info->loader_type = g_key_file_get_string (key_file, "Loader", "Type", NULL);
-
-	/* sanity check */
-	if (info->loader_type == NULL || info->loader_type[0] == '\0')
-	{
-		free_extension_info (info);
-		return NULL;
-	}
-
-	manager->priv->data = g_list_prepend (manager->priv->data, info);
-
-	g_signal_emit (manager, signals[ADDED], 0, info);
-
-	return info;
-}
-
-static void
-ephy_extensions_manager_load_ini_file (EphyExtensionsManager *manager,
-				       const char *identifier,
-				       const char *path)
-{
-	GKeyFile *keyfile;
-	GError *err = NULL;
-
-	keyfile = g_key_file_new ();
-	if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &err))
-	{
-		g_warning ("Could load key file for '%s': '%s'",
-			   identifier, err->message);
-		g_error_free (err);
-		g_key_file_free (keyfile);
-		return;
-	}
-
-	ephy_extensions_manager_parse_keyfile (manager, keyfile, identifier);
-}
-
-static char *
-path_to_identifier (const char *path)
-{
-	char *identifier, *dot;
-
-	identifier = g_path_get_basename (path);
-	dot = strstr (identifier, DOT_INI);
-
-	g_return_val_if_fail (dot != NULL, NULL);
-
-	*dot = '\0';
-
-	return identifier;
-}
-
-static ExtensionFormat
-format_from_path (const char *path)
-{
-	ExtensionFormat format = FORMAT_UNKNOWN;
-
-	if (g_str_has_suffix (path, DOT_INI))
-	{
-		format = FORMAT_INI;
-	}
-
-	return format;
-}
-
-static void
-ephy_extensions_manager_load_file (EphyExtensionsManager *manager,
-				   const char *path)
-{
-	GList *element;
-	char *identifier;
-	ExtensionFormat format;
-
-	identifier = path_to_identifier (path);
-	g_return_if_fail (identifier != NULL);
-	if (identifier == NULL) return;
-
-	format = format_from_path (path);
-	g_return_if_fail (format != FORMAT_UNKNOWN);
-
-	element = g_list_find_custom (manager->priv->data, identifier,
-				      (GCompareFunc) find_extension_info);
-	if (element != NULL)
-	{
-		g_warning ("Extension description for '%s' already read!",
-			   identifier);
-
-		g_free (identifier);
-		return;
-	}
-
-	if (format == FORMAT_INI)
-	{
-		ephy_extensions_manager_load_ini_file (manager, identifier,
-						       path);
-	}
-
-	g_free (identifier);
-}
-
-
-static int
-find_loader (const LoaderInfo *info,
-	      const char *type)
-{
-	return strcmp (info->type, type);
-}
-
-static char *
-sanitise_type (const char *string)
-{
-	char *str, *p;
-
-	str = g_strdup (string);
-	for (p = str; *p != '\0'; p++)
-	{
-		if (!g_ascii_isalpha (*p)) *p = '-';
-	}
-
-	return str;
-}
-
-static EphyLoader *
-get_loader_for_type (EphyExtensionsManager *manager,
-		     const char *type)
-{
-	LoaderInfo *info;
-	GList *l;
-	char *path, *name, *stype, *data;
-	GKeyFile *keyfile;
-	EphyLoader *shlib_loader;
-	GObject *loader;
-
-	LOG ("Looking for loader for type '%s'", type);
-
-	l = g_list_find_custom (manager->priv->factories, type,
-				(GCompareFunc) find_loader);
-	if (l != NULL)
-	{
-		info = (LoaderInfo *) l->data;
-		return g_object_ref (info->loader);
-	}
-
-	if (strcmp (type, "shlib") == 0)
-	{
-		info = g_new (LoaderInfo, 1);
-		info->type = g_strdup (type);
-		info->loader = g_object_new (EPHY_TYPE_SHLIB_LOADER, NULL);
-
-		manager->priv->factories =
-			g_list_append (manager->priv->factories, info);
-
-		return g_object_ref (info->loader);
-	}
-	if (strcmp (type, "python") == 0)
-	{
-		return NULL;
-	}
-
-#ifdef ENABLE_SEED
-	if (strcmp (type, "seed") == 0)
-	{
-		info = g_new (LoaderInfo, 1);
-		info->type = g_strdup (type);
-		info->loader = g_object_new (EPHY_TYPE_SEED_LOADER, NULL);
-
-		manager->priv->factories =
-				g_list_append (manager->priv->factories, info);
-
-		return g_object_ref (info->loader);
-		return NULL;
-	}
-#endif
-	shlib_loader = get_loader_for_type (manager, "shlib");
-	g_return_val_if_fail (shlib_loader != NULL, NULL);
-
-	stype = sanitise_type (type);
-	name = g_strconcat ("lib", stype, "loader.", G_MODULE_SUFFIX, NULL);
-	path = g_build_filename (LOADER_DIR, name, NULL);
-	data = g_strconcat ("[Loader]\nType=shlib\nLibrary=", path, "\n", NULL);
-	g_free (stype);
-	g_free (name);
-	g_free (path);
-
-	keyfile = g_key_file_new ();
-	if (!g_key_file_load_from_data (keyfile, data, strlen (data), 0, NULL))
-	{
-		g_free (data);
-		return NULL;
-	}
-
-	loader = ephy_loader_get_object (shlib_loader, keyfile);
-	g_key_file_free (keyfile);
-
-	if (EPHY_IS_LOADER (loader))
-	{
-		info = g_new (LoaderInfo, 1);
-		info->type = g_strdup (type);
-		info->loader = EPHY_LOADER (loader);
-
-		manager->priv->factories =
-			g_list_append (manager->priv->factories, info);
-
-		return g_object_ref (info->loader);
-	}
-
-	g_return_val_if_reached (NULL);
-
-	return NULL;
-}
-
-static void
-attach_window (EphyWindow *window,
-	       EphyExtension *extension)
-{
-	GList *tabs, *l;
-
-	ephy_extension_attach_window (extension, window);
-
-	tabs = ephy_embed_container_get_children 
-          (EPHY_EMBED_CONTAINER (window));
-	for (l = tabs; l; l = l->next)
-	{
-		ephy_extension_attach_tab (extension, window,
-					   EPHY_EMBED (l->data));
-	}
-	g_list_free (tabs);
-}
-
-static void
-load_extension (EphyExtensionsManager *manager,
-		ExtensionInfo *info)
-{
-	EphyLoader *loader;
-
-	g_return_if_fail (info->extension == NULL);
-
-	LOG ("Loading extension '%s'", info->info.identifier);
-
-	/* don't try again */
-	if (info->load_failed) return;
-
-	/* get a loader */
-	loader = get_loader_for_type (manager, info->loader_type);
-	if (loader == NULL)
-	{
-		g_message ("No loader found for extension '%s' of type '%s'\n",
-			   info->info.identifier, info->loader_type);
-		return;
-	}
-
-	info->loader = loader;
-
-	info->extension = ephy_loader_get_object (loader, info->info.keyfile);
-
-	/* attach if the extension implements EphyExtensionIface */
-	if (EPHY_IS_EXTENSION (info->extension))
-	{
-		manager->priv->extensions =
-			g_list_prepend (manager->priv->extensions,
-					g_object_ref (info->extension));
-
-		g_list_foreach (manager->priv->windows, (GFunc) attach_window,
-				info->extension);
-	}
-
-	if (info->extension != NULL)
-	{
-		info->info.active = TRUE;
-	}
-	else
-	{
-		info->info.active = FALSE;
-		info->load_failed = TRUE;
-	}
-}
-
-static void
-detach_window (EphyWindow *window,
-	       EphyExtension *extension)
-{
-	GList *tabs, *l;
-
-	tabs = ephy_embed_container_get_children 
-          (EPHY_EMBED_CONTAINER (window));
-	for (l = tabs; l; l = l->next)
-	{
-		ephy_extension_detach_tab (extension, window,
-					   EPHY_EMBED (l->data));
-	}
-	g_list_free (tabs);
-
-	ephy_extension_detach_window (extension, window);
-}
-
-static void
-unload_extension (EphyExtensionsManager *manager,
-		  ExtensionInfo *info)
-{
-	g_return_if_fail (info->loader != NULL);
-	g_return_if_fail (info->extension != NULL || info->load_failed);
-
-	LOG ("Unloading extension '%s'", info->info.identifier);
-
-	if (info->load_failed) return;
-
-	/* detach if the extension implements EphyExtensionIface */
-	if (EPHY_IS_EXTENSION (info->extension))
-	{
-		g_list_foreach (manager->priv->windows, (GFunc) detach_window,
-				info->extension);
-
-		manager->priv->extensions =
-			g_list_remove (manager->priv->extensions, info->extension);
-
-		/* we own two refs to the extension, the one we added when
-		 * we added it to the priv->extensions list, and the one returned
-		 * from get_object. Release object, and queue a unref, since if the
-		 * extension has its own functions queued in the idle loop, the
-		 * functions must exist in memory before being called.
-		 */
-		ephy_object_idle_unref (info->extension);
-	}
-
-	ephy_loader_release_object (info->loader, G_OBJECT (info->extension));
-
-	info->info.active = FALSE;
-	info->extension = NULL;
-}
-
-static void
-sync_loaded_extensions (EphyExtensionsManager *manager)
-{
-	char **extensions;
-	GVariantBuilder builder;
-	int i;
-	gboolean has_ui = FALSE;
-	GList *l;
-	ExtensionInfo *info;
-
-	LOG ("Synching changed list of active extensions");
-
-	extensions = g_settings_get_strv (EPHY_SETTINGS_MAIN,
-					  EPHY_PREFS_ENABLED_EXTENSIONS);
-
-	g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
-
-	/* Make sure the extensions-manager-ui is always loaded. */
-	for (i = 0; extensions[i]; i++)
-	{
-		if (g_strcmp0 (extensions[i], "extensions-manager-ui") == 0)
-			has_ui = TRUE;
-
-		g_variant_builder_add (&builder, "s", extensions[i]);
-	}
-
-	if (!has_ui)
-	{
-		g_variant_builder_add (&builder, "s", "extensions-manager-ui");
-		g_settings_set (EPHY_SETTINGS_MAIN,
-				EPHY_PREFS_ENABLED_EXTENSIONS,
-				"as", &builder);
-
-		g_strfreev (extensions);
-		extensions = g_settings_get_strv
-					(EPHY_SETTINGS_MAIN,
-					 EPHY_PREFS_ENABLED_EXTENSIONS);
-	}
-	else
-	{
-		g_variant_builder_clear (&builder);
-	}
-
-	for (l = manager->priv->data; l != NULL; l = l->next)
-	{
-		gboolean changed;
-		gboolean active = FALSE;
-		int j;
-		
-		info = (ExtensionInfo *) l->data;
-
-		for (j = 0; extensions[j]; j++)
-		{
-			if (!active && g_strcmp0 (extensions[j],
-						  info->info.identifier) == 0)
-				active = TRUE;
-		}
-
-		LOG ("Extension '%s' is %sactive and %sloaded",
-		     info->info.identifier,
-		     active ? "" : "not ",
-		     info->info.active ? "" : "not ");
-
-		changed = (info->info.enabled != active);
-
-		info->info.enabled = active;
-
-		if (active != info->info.active)
-		{
-			if (active)
-			{
-				load_extension (manager, info);
-			}
-			else
-			{
-				unload_extension (manager, info);
-			}
-
-			if (active == info->info.active)
-			{
-				changed = TRUE;
-			}
-		}
-		
-		if (changed)
-		{
-			g_signal_emit (manager, signals[CHANGED], 0, info);
-		}
-	}
-
-	g_strfreev (extensions);
-}
-
-static void
-ephy_extensions_manager_unload_file (EphyExtensionsManager *manager,
-				     const char *path)
-{
-	GList *l;
-	ExtensionInfo *info;
-	char *identifier;
-
-	identifier = path_to_identifier (path);
-
-	l = g_list_find_custom (manager->priv->data, identifier,
-				(GCompareFunc) find_extension_info);
-
-	if (l != NULL)
-	{
-		info = (ExtensionInfo *) l->data;
-
-		manager->priv->data = g_list_remove (manager->priv->data, info);
-
-		if (info->info.active == TRUE)
-		{
-			unload_extension (manager, info);
-		}
-
-		g_signal_emit (manager, signals[REMOVED], 0, info);
-
-		free_extension_info (info);
-	}
-
-	g_free (identifier);
-}
-
-static gboolean
-reload_sync_cb (EphyExtensionsManager *manager)
-{
-	EphyExtensionsManagerPrivate *priv = manager->priv;
-
-	if (priv->sync_timeout_id != 0)
-	{
-		g_source_remove (priv->sync_timeout_id);
-		priv->sync_timeout_id = 0;
-	}
-
-	sync_loaded_extensions (manager);
-
-	return FALSE;
-}
-
-static gboolean
-reload_cb (gpointer *data)
-{
-	EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (data[0]);
-	EphyExtensionsManagerPrivate *priv = manager->priv;
-	char *path = data[1];
-
-	LOG ("Reloading %s", path);
-
-	/* We still need path and don't want to remove the timeout
-	 * which will be removed automatically when we return, so 
-	 * just use _steal instead of _remove.
-	 */
-	g_hash_table_steal (priv->reload_hash, path);
-
-	ephy_extensions_manager_load_file (manager, path);
-	g_free (path);
-
-	/* Schedule a sync of active extensions */
-	/* FIXME: just look if we need to activate *this* extension? */
-
-	if (priv->sync_timeout_id != 0)
-	{
-		g_source_remove (priv->sync_timeout_id);
-	}
-
-	priv->sync_timeout_id = g_timeout_add_seconds (RELOAD_SYNC_DELAY,
-					       (GSourceFunc) reload_sync_cb,
-					       manager);
-	return FALSE;
-}
-
-static void
-schedule_load_from_monitor (EphyExtensionsManager *manager,
-			    const char *path)
-{
-	EphyExtensionsManagerPrivate *priv = manager->priv;
-	char *identifier, *copy;
-	gpointer *data;
-	guint timeout_id;
-
-	/* When a file is installed, it sometimes gets CREATED empty and then
-	 * gets its contents filled later (for a CHANGED signal). Theoretically
-	 * I suppose we could get a CHANGED signal when the file is half-full,
-	 * but I doubt that'll happen much (the files are <1000 bytes). We
-	 * don't want warnings all over the place, so we just wait a bit before
-	 * actually reloading the file. (We're assuming that if a file is
-	 * empty it'll be filled soon and this function will be called again.)
-	 *
-	 * Oh, and we return if the extension is already loaded, too.
-	 */
-
-	identifier = path_to_identifier (path);
-	g_return_if_fail (identifier != NULL);
-	if (identifier == NULL) return;
-
-	if (g_list_find_custom (manager->priv->data, identifier,
-				(GCompareFunc) find_extension_info) != NULL)
-	{
-		g_free (identifier);
-		return;
-	}
-	g_free (identifier);
-
-	g_return_if_fail (priv->reload_hash != NULL);
-
-	data = g_new (gpointer, 2);
-	data[0] = (gpointer) manager;
-	data[1] = copy = g_strdup (path);
-	timeout_id = g_timeout_add_full (G_PRIORITY_LOW, RELOAD_DELAY,
-					 (GSourceFunc) reload_cb,
-					 data, (GDestroyNotify) g_free);
-	g_hash_table_replace (priv->reload_hash, copy /* owns it */,
-			      GUINT_TO_POINTER (timeout_id));
-}
-
-static void
-dir_changed_cb (GFileMonitor *monitor,
-		GFile *child,
-		GFile *other_child,
-		GFileMonitorEvent event_type,
-		EphyExtensionsManager *manager)
-{
-	char *path;
-	
-	path = g_file_get_path (child);
-
-	/*
-	 * We only deal with XML and INI files:
-	 * Add them to the manager when created, remove them when deleted.
-	 */
-	if (format_from_path (path) == FORMAT_UNKNOWN) return;
-
-	switch (event_type)
-	{
-		case G_FILE_MONITOR_EVENT_CREATED:
-		case G_FILE_MONITOR_EVENT_CHANGED:
-			schedule_load_from_monitor (manager, path);
-			break;
-		case G_FILE_MONITOR_EVENT_DELETED:
-			ephy_extensions_manager_unload_file (manager, path);
-			break;
-		default:
-			break;
-	}
-	
-	g_free (path);
-}
-
-static void
-ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
-				  const char *path)
-{
-	char *file_path;
-	GError *error = NULL;
-	GDir *dir;
-	const char *dir_elem;
-	GFile *directory;
-	GFileMonitor *monitor;
-
-	LOG ("Scanning directory '%s'", path);
-
-	START_PROFILER ("Scanning directory")
-
-	dir = g_dir_open (path, 0, &error);
-	if (error)
-	{
-		LOG ("Failed to open extension directory %s: %s",
-		     path, error->message);
-		g_error_free (error);
-		return;
-	}
-
-	dir_elem = g_dir_read_name (dir);
-	while (dir_elem)
-	{
-		if (format_from_path (dir_elem) != FORMAT_UNKNOWN)
-		{
-			file_path = g_build_filename (path, dir_elem, NULL);
-			ephy_extensions_manager_load_file (manager, file_path);
-			g_free (file_path);
-		}
-
-		dir_elem = g_dir_read_name (dir);
-	}
-	g_dir_close (dir);
-
-	directory = g_file_new_for_path (path);
-	monitor = g_file_monitor_directory (directory, 0, NULL, NULL);
-
-	if (monitor != NULL)
-	{
-		g_signal_connect (monitor, "changed",
-				  G_CALLBACK (dir_changed_cb),
-				  manager);
-		manager->priv->dir_monitors = g_list_prepend
-			(manager->priv->dir_monitors, monitor);
-	}
-
-	STOP_PROFILER ("Scanning directory")
-}
-
-static void
-active_extensions_cb (GSettings *settings,
-		      char *key,
-		      EphyExtensionsManager *manager)
-{
-	sync_loaded_extensions (manager);
-}
-
-static void
-cancel_timeout (gpointer data)
-{
-	guint id = GPOINTER_TO_UINT (data);
-
-	g_source_remove (id);
-}
-
-static void
 ephy_extensions_manager_init (EphyExtensionsManager *manager)
 {
-	EphyExtensionsManagerPrivate *priv;
-
-	priv = manager->priv = EPHY_EXTENSIONS_MANAGER_GET_PRIVATE (manager);
-
-	priv->reload_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
-						   (GDestroyNotify) g_free,
-						   (GDestroyNotify) cancel_timeout);
-}
-
-void
-ephy_extensions_manager_startup (EphyExtensionsManager *manager)
-{
-	char *path;
-
-	g_return_if_fail (EPHY_IS_EXTENSIONS_MANAGER (manager));
+	char *userdir;
+	GError *error = NULL;
 
 	LOG ("EphyExtensionsManager startup");
 
-	/* load the extensions descriptions */
-	path = g_build_filename (ephy_dot_dir (), "extensions", NULL);
-	ephy_extensions_manager_load_dir (manager, path);
-	g_free (path);
+	peas_engine_enable_loader (PEAS_ENGINE (manager), "seed");
 
-	ephy_extensions_manager_load_dir (manager, EXTENSIONS_DIR);
+	peas_engine_add_search_path (PEAS_ENGINE (manager),
+				     EXTENSIONS_DIR, EXTENSIONS_DIR);
 
-	sync_loaded_extensions (manager);
+	userdir = g_build_filename (ephy_dot_dir (), "extensions", NULL);
+	peas_engine_add_search_path (PEAS_ENGINE (manager), userdir, userdir);
+	g_free (userdir);
 
-	g_signal_connect (EPHY_SETTINGS_MAIN,
-			  "changed::" EPHY_PREFS_ENABLED_EXTENSIONS,
-			  G_CALLBACK (active_extensions_cb),
-			  manager);
-}
-
-static void
-ephy_extensions_manager_dispose (GObject *object)
-{
-	EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (object);
-	EphyExtensionsManagerPrivate *priv = manager->priv;
-
-	if (priv->reload_hash != NULL)
+	if (!g_irepository_require (g_irepository_get_default (),
+	                            "Epiphany", "2.31", 0, &error))
 	{
-		g_hash_table_destroy (priv->reload_hash);
-		priv->reload_hash = NULL;
-	}
-
-	if (priv->sync_timeout_id != 0)
-	{
-		g_source_remove (priv->sync_timeout_id);
-		priv->sync_timeout_id = 0;
-	}
-
-	if (priv->dir_monitors != NULL)
-	{
-		g_list_foreach (priv->dir_monitors, (GFunc) g_file_monitor_cancel, NULL);
-		g_list_free (priv->dir_monitors);
-		priv->dir_monitors = NULL;
-	}
-
-	if (priv->extensions != NULL)
-	{
-		g_list_foreach (priv->extensions, (GFunc) g_object_unref, NULL);
-		g_list_free (priv->extensions);
-		priv->extensions = NULL;
-	}
-
-	if (priv->factories != NULL)
-	{
-		/* FIXME release loaded loaders */
-		g_list_foreach (priv->factories, (GFunc) free_loader_info, NULL);
-		g_list_free (priv->factories);
-		priv->factories = NULL;
-	}
-
-	if (priv->data != NULL)
-	{
-		g_list_foreach (priv->data, (GFunc) free_extension_info, NULL);
-		g_list_free (priv->data);
-		priv->data = NULL;
-	}
-
-	if (priv->windows != NULL)
-	{
-		g_list_free (priv->windows);
-		priv->windows = NULL;
-	}
-
-	G_OBJECT_CLASS (ephy_extensions_manager_parent_class)->dispose (object);
-}
-
-static void
-attach_extension_to_window (EphyExtension *extension,
-			    EphyWindow *window)
-{
-	attach_window (window, extension);
-}
-
-static void
-impl_attach_window (EphyExtension *extension,
-		    EphyWindow *window)
-{
-	EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
-
-	LOG ("Attach window %p", window);
-
-	g_list_foreach (manager->priv->extensions,
-			(GFunc) attach_extension_to_window, window);
-
-	manager->priv->windows = g_list_prepend (manager->priv->windows, window);
-}
-
-static void
-impl_detach_window (EphyExtension *extension,
-		    EphyWindow *window)
-{
-	EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
-	GList *tabs, *l;
-
-	LOG ("Detach window %p", window);
-
-	manager->priv->windows = g_list_remove (manager->priv->windows, window);
-
-	g_object_ref (window);
-
-	/* Detach tabs (uses impl_detach_tab) */
-	tabs = ephy_embed_container_get_children (EPHY_EMBED_CONTAINER (window));
-	for (l = tabs; l; l = l->next)
-	{
-		ephy_extension_detach_tab (extension, window,
-					   EPHY_EMBED (l->data));
+		g_warning ("Could not load Epiphany gir: %s", error->message);
+		g_error_free (error);
+		error = NULL;
 	}
-	g_list_free (tabs);
-
-	/* Then detach the window */
-	g_list_foreach (manager->priv->extensions,
-			(GFunc) ephy_extension_detach_window, window);
 
-	g_object_unref (window);
-}
-
-static void
-impl_attach_tab (EphyExtension *extension,
-		 EphyWindow *window,
-		 EphyEmbed *embed)
-{
-	EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
-	GList *l;
-
-	LOG ("Attach window %p embed %p", window, embed);
-
-	for (l = manager->priv->extensions; l; l = l->next)
+#if 0
+	/* This should be moved to libpeas */
+	if (!g_irepository_require (g_irepository_get_default (),
+	                            "Peas", "1.0", 0, &error))
 	{
-		ephy_extension_attach_tab (EPHY_EXTENSION (l->data),
-					   window, embed);
+		g_warning ("Could not load Peas repository: %s", error->message);
+		g_error_free (error);
+		error = NULL;
 	}
-}
 
-static void
-impl_detach_tab (EphyExtension *extension,
-		 EphyWindow *window,
-		 EphyEmbed *embed)
-{
-	EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
-	GList *l;
-
-	LOG ("Detach window %p embed %p", window, embed);
-
-	g_object_ref (window);
-	g_object_ref (embed);
-
-	for (l = manager->priv->extensions; l; l = l->next)
+	if (!g_irepository_require (g_irepository_get_default (),
+	                            "PeasGtk", "1.0", 0, &error))
 	{
-		ephy_extension_detach_tab (EPHY_EXTENSION (l->data),
-					   window, embed);
+		g_warning ("Could not load PeasGtk repository: %s", error->message);
+		g_error_free (error);
+		error = NULL;
 	}
+#endif
 
-	g_object_unref (embed);
-	g_object_unref (window);
-}
-
-static void
-ephy_extensions_manager_iface_init (EphyExtensionIface *iface)
-{
-	iface->attach_window = impl_attach_window;
-	iface->detach_window = impl_detach_window;
-	iface->attach_tab    = impl_attach_tab;
-	iface->detach_tab    = impl_detach_tab;
+	g_settings_bind (EPHY_SETTINGS_MAIN,
+	                 EPHY_PREFS_ENABLED_EXTENSIONS,
+	                 manager,
+	                 "loaded-plugins",
+	                 G_SETTINGS_BIND_DEFAULT);
 }
 
 static void
 ephy_extensions_manager_class_init (EphyExtensionsManagerClass *class)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-	object_class->dispose = ephy_extensions_manager_dispose;
-
-	signals[CHANGED] =
-		g_signal_new ("changed",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_FIRST,
-			      G_STRUCT_OFFSET (EphyExtensionsManagerClass, changed),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__POINTER,
-			      G_TYPE_NONE,
-			      1,
-			      G_TYPE_POINTER);
-	signals[ADDED] =
-		g_signal_new ("added",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_FIRST,
-			      G_STRUCT_OFFSET (EphyExtensionsManagerClass, added),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__POINTER,
-			      G_TYPE_NONE,
-			      1,
-			      G_TYPE_POINTER);
-	signals[REMOVED] =
-		g_signal_new ("removed",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_FIRST,
-			      G_STRUCT_OFFSET (EphyExtensionsManagerClass, removed),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__POINTER,
-			      G_TYPE_NONE,
-			      1,
-			      G_TYPE_POINTER);
-	
-	g_type_class_add_private (object_class, sizeof (EphyExtensionsManagerPrivate));
 }
diff --git a/src/ephy-extensions-manager.h b/src/ephy-extensions-manager.h
index 9613ad6..03f24f2 100644
--- a/src/ephy-extensions-manager.h
+++ b/src/ephy-extensions-manager.h
@@ -25,11 +25,9 @@
 #ifndef EPHY_EXTENSIONS_MANAGER_H
 #define EPHY_EXTENSIONS_MANAGER_H
 
-#include "ephy-extension.h"
-#include "ephy-node.h"
-
 #include <glib.h>
 #include <glib-object.h>
+#include <libpeas/peas.h>
 
 G_BEGIN_DECLS
 
@@ -43,51 +41,19 @@ G_BEGIN_DECLS
 typedef struct _EphyExtensionsManager		EphyExtensionsManager;
 typedef struct _EphyExtensionsManagerClass	EphyExtensionsManagerClass;
 typedef struct _EphyExtensionsManagerPrivate	EphyExtensionsManagerPrivate;
-
-typedef struct
-{
-	char *identifier;
-	GKeyFile *keyfile;
-	guint active  :1;
-	guint enabled :1;
-} EphyExtensionInfo;
 	
 struct _EphyExtensionsManagerClass
 {
-	GObjectClass parent_class;
-
-	/* Signals */
-	void	(* added)	(EphyExtensionsManager *manager,
-				 EphyExtensionInfo *info);
-	void	(* changed)	(EphyExtensionsManager *manager,
-				 EphyExtensionInfo *info);
-	void	(* removed)	(EphyExtensionsManager *manager,
-				 EphyExtensionInfo *info);
+	PeasEngineClass parent_class;
 };
 
 struct _EphyExtensionsManager
 {
-	GObject parent_instance;
-
-	/*< private >*/
-	EphyExtensionsManagerPrivate *priv;
+	PeasEngine parent_instance;
 };
 
 GType	  ephy_extensions_manager_get_type	 (void);
 
-void	  ephy_extensions_manager_startup	 (EphyExtensionsManager *manager);
-
-void	  ephy_extensions_manager_load		 (EphyExtensionsManager *manager,
-						  const char *identifier);
-
-void	  ephy_extensions_manager_unload	 (EphyExtensionsManager *manager,
-						  const char *identifier);
-
-void	  ephy_extensions_manager_register	 (EphyExtensionsManager *manager,
-						  GObject *object);
-
-GList	 *ephy_extensions_manager_get_extensions (EphyExtensionsManager *manager);
-
 G_END_DECLS
 
 #endif
diff --git a/src/ephy-lockdown.c b/src/ephy-lockdown.c
index 61aec8d..4cfae89 100644
--- a/src/ephy-lockdown.c
+++ b/src/ephy-lockdown.c
@@ -28,7 +28,6 @@
 #include "ephy-embed-utils.h"
 #include "ephy-web-view.h"
 #include "ephy-lockdown.h"
-#include "ephy-extension.h"
 #include "ephy-settings.h"
 #include "ephy-toolbar.h"
 #include "ephy-prefs.h"
@@ -40,7 +39,7 @@
 
 #define LOCKDOWN_FLAG 1 << 8
 
-static void ephy_lockdown_iface_init (EphyExtensionIface *iface);
+G_DEFINE_TYPE (EphyLockdown, ephy_lockdown, G_TYPE_OBJECT)
 
 static int
 find_name (GtkActionGroup *action_group,
@@ -210,9 +209,9 @@ bind_settings_and_actions (GSettings *settings,
 	}
 }
 
-static void
-impl_attach_window (EphyExtension *extension,
-		    EphyWindow *window)
+void
+ephy_lockdown_attach_window (EphyLockdown *lockdown,
+			     EphyWindow *window)
 {
 	GtkUIManager *manager;
 	GtkActionGroup *action_group;
@@ -272,16 +271,6 @@ ephy_lockdown_init (EphyLockdown *lockdown)
 	LOG ("EphyLockdown initialising");
 }
 
-G_DEFINE_TYPE_WITH_CODE (EphyLockdown, ephy_lockdown, G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (EPHY_TYPE_EXTENSION,
-						ephy_lockdown_iface_init))
-
-static void
-ephy_lockdown_iface_init (EphyExtensionIface *iface)
-{
-	iface->attach_window = impl_attach_window;
-}
-
 static void
 ephy_lockdown_class_init (EphyLockdownClass *klass)
 {
diff --git a/src/ephy-lockdown.h b/src/ephy-lockdown.h
index 3fd9238..adb93a6 100644
--- a/src/ephy-lockdown.h
+++ b/src/ephy-lockdown.h
@@ -28,6 +28,8 @@
 #include <glib.h>
 #include <glib-object.h>
 
+#include "ephy-window.h"
+
 G_BEGIN_DECLS
 
 #define EPHY_TYPE_LOCKDOWN		(ephy_lockdown_get_type ())
@@ -56,6 +58,9 @@ struct _EphyLockdown
 
 GType	ephy_lockdown_get_type		(void);
 
+void	ephy_lockdown_attach_window	(EphyLockdown *lockdown,
+					 EphyWindow *window);
+
 G_END_DECLS
 
 #endif
diff --git a/src/ephy-session.c b/src/ephy-session.c
index acd48df..a869935 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -30,7 +30,6 @@
 #include "ephy-embed.h"
 #include "ephy-embed-utils.h"
 #include "ephy-embed-container.h"
-#include "ephy-extension.h"
 #include "ephy-file-helpers.h"
 #include "ephy-gui.h"
 #include "ephy-history-window.h"
@@ -83,20 +82,17 @@ struct _EphySessionPrivate
 #define SESSION_CRASHED		"type:session_crashed"
 
 static void ephy_session_class_init	(EphySessionClass *klass);
-static void ephy_session_iface_init	(EphyExtensionIface *iface);
 static void ephy_session_init		(EphySession *session);
 static void session_command_queue_next	(EphySession *session);
 
+G_DEFINE_TYPE (EphySession, ephy_session, G_TYPE_OBJECT)
+
 enum
 {
 	PROP_0,
 	PROP_ACTIVE_WINDOW
 };
 
-G_DEFINE_TYPE_WITH_CODE (EphySession, ephy_session, G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (EPHY_TYPE_EXTENSION,
-						ephy_session_iface_init))
-
 /* Gnome session client */
 
 typedef struct
@@ -858,17 +854,12 @@ session_command_queue_clear (EphySession *session)
 	}
 }
 
-/* EphyExtensionIface implementation */
-
-static void
-impl_attach_window (EphyExtension *extension,
-		    EphyWindow *window)
+void
+ephy_session_attach_window (EphySession *session,
+			    EphyWindow *window)
 {
-	EphySession *session = EPHY_SESSION (extension);
 	GtkWidget *notebook;
 
-	LOG ("impl_attach_window");
-
 	session->priv->windows = g_list_append (session->priv->windows, window);
 	ephy_session_save (session, SESSION_CRASHED);
 
@@ -886,7 +877,6 @@ impl_attach_window (EphyExtension *extension,
 	/* Set unique identifier as role, so that on restore, the WM can
 	 * place the window on the right workspace
 	 */
-
 	if (gtk_window_get_role (GTK_WINDOW (window)) == NULL)
 	{
 		/* I guess rand() is unique enough, otherwise we could use
@@ -900,14 +890,10 @@ impl_attach_window (EphyExtension *extension,
 	}
 }
 
-static void
-impl_detach_window (EphyExtension *extension,
-		    EphyWindow *window)
+void
+ephy_session_detach_window (EphySession *session,
+			    EphyWindow *window)
 {
-	EphySession *session = EPHY_SESSION (extension);
-
-	LOG ("impl_detach_window");
-
 	session->priv->windows = g_list_remove (session->priv->windows, window);
 	ephy_session_save (session, SESSION_CRASHED);
 
@@ -982,13 +968,6 @@ ephy_session_finalize (GObject *object)
 }
 
 static void
-ephy_session_iface_init (EphyExtensionIface *iface)
-{
-	iface->attach_window = impl_attach_window;
-	iface->detach_window = impl_detach_window;
-}
-
-static void
 ephy_session_set_property (GObject *object,
 			   guint prop_id,
 			   const GValue *value,
diff --git a/src/ephy-session.h b/src/ephy-session.h
index 4dbb496..4d1935b 100644
--- a/src/ephy-session.h
+++ b/src/ephy-session.h
@@ -96,6 +96,12 @@ void		 ephy_session_queue_command	(EphySession *session,
 						 guint32 user_time,
 						 gboolean priority);
 
+void		ephy_session_attach_window      (EphySession *session,
+						 EphyWindow *window);
+
+void		ephy_session_detach_window      (EphySession *session,
+						 EphyWindow *window);
+
 G_END_DECLS
 
 #endif
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index ef45fb4..84b9dd1 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -524,14 +524,7 @@ ephy_shell_get_session (EphyShell *shell)
 
 	if (shell->priv->session == NULL)
 	{
-		EphyExtensionsManager *manager;
-
 		shell->priv->session = g_object_new (EPHY_TYPE_SESSION, NULL);
-
-		manager = EPHY_EXTENSIONS_MANAGER
-			(ephy_shell_get_extensions_manager (shell));
-		ephy_extensions_manager_register (manager,
-						  G_OBJECT (shell->priv->session));
 	}
 
 	return G_OBJECT (shell->priv->session);
@@ -543,26 +536,19 @@ ephy_shell_get_session (EphyShell *shell)
  *
  * Returns the lockdown controller.
  *
- * Return value: the lockdown controller
+ * Return value: (transfer none): the lockdown controller
  **/
-static GObject *
+GObject *
 ephy_shell_get_lockdown (EphyShell *shell)
 {
 	g_return_val_if_fail (EPHY_IS_SHELL (shell), NULL);
 
 	if (shell->priv->lockdown == NULL)
 	{
-		EphyExtensionsManager *manager;
-
 		shell->priv->lockdown = g_object_new (EPHY_TYPE_LOCKDOWN, NULL);
-
-		manager = EPHY_EXTENSIONS_MANAGER
-			(ephy_shell_get_extensions_manager (shell));
-		ephy_extensions_manager_register (manager,
-						  G_OBJECT (shell->priv->lockdown));
 	}
 
-	return G_OBJECT (shell->priv->session);
+	return G_OBJECT (shell->priv->lockdown);
 }
 
 /**
@@ -648,10 +634,7 @@ ephy_shell_get_extensions_manager (EphyShell *es)
 		es->priv->extensions_manager =
 			g_object_new (EPHY_TYPE_EXTENSIONS_MANAGER, NULL);
 
-		ephy_extensions_manager_startup (es->priv->extensions_manager);
-
 		/* FIXME */
-		ephy_shell_get_lockdown (es);
 		ephy_embed_shell_get_adblock_manager (embed_shell);
 	}
 
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index 895c91d..ed2ae3f 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -126,6 +126,8 @@ GObject        *ephy_shell_get_pdm_dialog		(EphyShell *shell);
 
 GObject        *ephy_shell_get_prefs_dialog		(EphyShell *shell);
 
+GObject	       *ephy_shell_get_lockdown			(EphyShell *shell);
+
 /* private API */
 void	       _ephy_shell_create_instance		(void);
 
diff --git a/src/ephy-window.c b/src/ephy-window.c
index b4e2a28..b2d6cf8 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -44,9 +44,12 @@
 #include "ephy-toolbar.h"
 #include "popup-commands.h"
 #include "ephy-encoding-menu.h"
+#include "ephy-extension.h"
+#include "ephy-extensions-manager.h"
+#include "ephy-session.h"
+#include "ephy-lockdown.h"
 #include "ephy-tabs-menu.h"
 #include "ephy-stock-icons.h"
-#include "ephy-extension.h"
 #include "ephy-bookmarks-ui.h"
 #include "ephy-link.h"
 #include "ephy-gui.h"
@@ -241,6 +244,11 @@ static const GtkActionEntry ephy_menu_entries [] = {
 	  N_("Open the history window"),
 	  G_CALLBACK (window_cmd_go_history) },
 
+	/* Tools menu */
+	{ "ToolsExtensionsManager", NULL, N_("_Extensions"), "<control>Y",
+	  N_("Open the extensions manager"),
+	  G_CALLBACK (window_cmd_extensions_manager) },
+
 	/* Tabs menu */
 
 	{ "TabsPrevious", NULL, N_("_Previous Tab"), "<control>Page_Up",
@@ -454,6 +462,7 @@ struct _EphyWindowPrivate
 	guint idle_worker;
 	GtkWidget *entry;
 	GtkWidget *downloads_box;
+	PeasExtensionSet *extensions;
 
 	guint clear_progress_timeout_id;
 
@@ -2963,7 +2972,6 @@ notebook_page_added_cb (EphyNotebook *notebook,
 			EphyWindow *window)
 {
 	EphyWindowPrivate *priv = window->priv;
-	EphyExtension *manager;
 
 	LOG ("page-added   notebook %p embed %p position %u\n", notebook, embed, position);
 
@@ -2986,8 +2994,7 @@ notebook_page_added_cb (EphyNotebook *notebook,
 				 G_CALLBACK (embed_modal_alert_cb), window, G_CONNECT_AFTER);
 
 	/* Let the extensions attach themselves to the tab */
-	manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell));
-	ephy_extension_attach_tab (manager, window, embed);
+	peas_extension_set_call (priv->extensions, "attach_tab", window, embed);
 
         if (priv->present_on_insert)
         {
@@ -3003,7 +3010,6 @@ notebook_page_removed_cb (EphyNotebook *notebook,
 			  EphyWindow *window)
 {
 	EphyWindowPrivate *priv = window->priv;
-	EphyExtension *manager;
 
 	LOG ("page-removed notebook %p embed %p position %u\n", notebook, embed, position);
 
@@ -3011,9 +3017,8 @@ notebook_page_removed_cb (EphyNotebook *notebook,
 
 	g_return_if_fail (EPHY_IS_EMBED (embed));
 
-	/* Let the extensions remove themselves from the tab */
-	manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell));
-	ephy_extension_detach_tab (manager, window, embed);
+	peas_extension_set_call (priv->extensions, "detach_tab", window, embed);
+	peas_engine_garbage_collect (PEAS_ENGINE (ephy_shell_get_extensions_manager (ephy_shell)));
 
 #if 0
 	g_signal_handlers_disconnect_by_func (G_OBJECT (embed),
@@ -3237,16 +3242,18 @@ ephy_window_dispose (GObject *object)
 
 	LOG ("EphyWindow dispose %p", window);
 
+	peas_engine_garbage_collect (PEAS_ENGINE (ephy_shell_get_extensions_manager (ephy_shell)));
+
 	/* Only do these once */
 	if (window->priv->closing == FALSE)
 	{
-		EphyExtension *manager;
-
 		window->priv->closing = TRUE;
 
-		/* Let the extensions detach themselves from the window */
-		manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell));
-		ephy_extension_detach_window (manager, window);
+		peas_extension_set_call (priv->extensions, "detach_window", window);
+		g_object_unref (priv->extensions);
+		peas_engine_garbage_collect (PEAS_ENGINE (ephy_shell_get_extensions_manager (ephy_shell)));
+
+		ephy_session_detach_window (EPHY_SESSION (ephy_shell_get_session (ephy_shell)), window);
 		ephy_bookmarks_ui_detach_window (window);
 
 		g_signal_handlers_disconnect_by_func
@@ -3283,6 +3290,7 @@ ephy_window_dispose (GObject *object)
 
 		_ephy_window_set_context_event (window, NULL);
 	}
+	peas_engine_garbage_collect (PEAS_ENGINE (ephy_shell_get_extensions_manager (ephy_shell)));
 
 	destroy_fullscreen_popup (window);
 
@@ -3556,6 +3564,34 @@ cancel_handler (gpointer idptr)
 	g_source_remove (id);
 }
 
+static void
+extension_added_cb (PeasExtensionSet *extensions,
+		    PeasPluginInfo *info,
+		    PeasExtension *exten,
+		    EphyWindow *window)
+{
+	peas_extension_call (exten, "activate");
+	peas_extension_call (exten, "attach_window", window);
+	peas_extension_call (exten, "attach_tab", window->priv->active_embed);
+}
+
+static void
+extension_removed_cb (PeasExtensionSet *extensions,
+		      PeasPluginInfo *info,
+		      PeasExtension *exten,
+		      EphyWindow *window)
+{
+	peas_extension_call (exten, "detach_window", window);
+	peas_extension_call (exten, "deactivate");
+
+	/* Ensure update of ui manager, because we suspect it does something
+	 * with expected static strings in the type module (when unloaded the
+	 * strings don't exist anymore, and ui manager updates in an idle
+	 * func) */
+	gtk_ui_manager_ensure_update (window->priv->manager);
+}
+
+
 
 static void
 ephy_window_init (EphyWindow *window)
@@ -3579,7 +3615,6 @@ ephy_window_constructor (GType type,
 	GObject *object;
 	EphyWindow *window;
 	EphyWindowPrivate *priv;
-	EphyExtension *manager;
 	EphyEmbedSingle *single;
 	EggToolbarsModel *model;
 	GtkSettings *settings;
@@ -3695,8 +3730,19 @@ ephy_window_constructor (GType type,
 			  FALSE, FALSE, 0);
 
 	/* Once the window is sufficiently created let the extensions attach to it */
-	manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell));
-	ephy_extension_attach_window (manager, window);
+	priv->extensions = peas_extension_set_new (PEAS_ENGINE (ephy_shell_get_extensions_manager (ephy_shell)),
+						   EPHY_TYPE_EXTENSION,
+						   NULL);
+	peas_extension_set_call (priv->extensions, "attach_window", window);
+
+	g_signal_connect (priv->extensions, "extension-added",
+			  G_CALLBACK (extension_added_cb), window);
+	g_signal_connect (priv->extensions, "extension-removed",
+			  G_CALLBACK (extension_removed_cb), window);
+
+
+	ephy_session_attach_window (EPHY_SESSION (ephy_shell_get_session (ephy_shell)), window);
+	ephy_lockdown_attach_window (EPHY_LOCKDOWN (ephy_shell_get_lockdown (ephy_shell)), window);
 	ephy_bookmarks_ui_attach_window (window);
 
 	/* We only set the model now after attaching the extensions, so that
diff --git a/src/window-commands.c b/src/window-commands.c
index 61d6080..6d68e4c 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -56,6 +56,7 @@
 #include <gio/gio.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
+#include <libpeas-gtk/peas-gtk.h>
 #include <webkit/webkit.h>
 
 static void
@@ -1253,3 +1254,31 @@ window_cmd_browse_with_caret (GtkAction *action,
 	g_settings_set_boolean (EPHY_SETTINGS_MAIN,
 				EPHY_PREFS_ENABLE_CARET_BROWSING, active);
 }
+
+static void
+extensions_manager_delete_cb (GtkWidget *widget,
+			      GdkEvent *event,
+			      gpointer data)
+{
+	gtk_widget_destroy (widget);
+}
+
+void
+window_cmd_extensions_manager (GtkAction *action,
+			       EphyWindow *window)
+{
+	GtkWidget *manager;
+	GtkWidget *dialog;
+
+	manager = peas_gtk_plugin_manager_new (NULL);
+	dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+	gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
+
+	gtk_container_add (GTK_CONTAINER (dialog), manager);
+
+	g_signal_connect (dialog, "delete-event",
+			  G_CALLBACK (extensions_manager_delete_cb), NULL);
+
+	gtk_widget_show_all (dialog);
+}
diff --git a/src/window-commands.h b/src/window-commands.h
index 5b37585..07a4779 100644
--- a/src/window-commands.h
+++ b/src/window-commands.h
@@ -159,3 +159,6 @@ void window_cmd_load_location   (GtkAction *action,
 void window_cmd_browse_with_caret (GtkAction *action,
 				   EphyWindow *window);
 
+void window_cmd_extensions_manager (GtkAction *action,
+				    EphyWindow *window);
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bb538d8..45e387d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -26,13 +26,6 @@ LDADD = \
 	$(DBUS_LIBS) \
 	$(DEPENDENCIES_LIBS) 
 
-if ENABLE_SEED
-CFLAGS += \
-	$(SEED_CFLAGS)
-LDADD += \
-	$(SEED_LIBS)
-endif
-
 test_ephy_download_SOURCES = \
 	ephy-download.c
 



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