diff options
author | Xan Lopez <xan@src.gnome.org> | 2007-11-06 03:54:57 +0800 |
---|---|---|
committer | Xan Lopez <xan@src.gnome.org> | 2007-11-06 03:54:57 +0800 |
commit | d73b100991cd2b294365bf5cc5f9627fdaa979a9 (patch) | |
tree | cd096d98d921e1ea18bdd6e3f2d80a7bdb64bb07 | |
parent | d166fac07ccf16fba79aadb092d9c0ad95d3ab02 (diff) | |
download | gsoc2013-epiphany-d73b100991cd2b294365bf5cc5f9627fdaa979a9.tar gsoc2013-epiphany-d73b100991cd2b294365bf5cc5f9627fdaa979a9.tar.gz gsoc2013-epiphany-d73b100991cd2b294365bf5cc5f9627fdaa979a9.tar.bz2 gsoc2013-epiphany-d73b100991cd2b294365bf5cc5f9627fdaa979a9.tar.lz gsoc2013-epiphany-d73b100991cd2b294365bf5cc5f9627fdaa979a9.tar.xz gsoc2013-epiphany-d73b100991cd2b294365bf5cc5f9627fdaa979a9.tar.zst gsoc2013-epiphany-d73b100991cd2b294365bf5cc5f9627fdaa979a9.zip |
Move all common functionality from MozillaEmbed to EphyBaseEmbed.
svn path=/trunk/; revision=7628
-rw-r--r-- | embed/ephy-base-embed.c | 1438 | ||||
-rw-r--r-- | embed/ephy-base-embed.h | 28 | ||||
-rw-r--r-- | embed/mozilla/mozilla-embed.cpp | 1531 |
3 files changed, 1460 insertions, 1537 deletions
diff --git a/embed/ephy-base-embed.c b/embed/ephy-base-embed.c index ade799d82..5c6167aa8 100644 --- a/embed/ephy-base-embed.c +++ b/embed/ephy-base-embed.c @@ -1,5 +1,7 @@ /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* + * Copyright © 2000-2004 Marco Pesenti Gritti + * Copyright © 2003-2007 Christian Persch * Copyright © 2007 Xan Lopez * * This program is free software; you can redistribute it and/or modify @@ -19,43 +21,96 @@ */ #include "config.h" + +#include <glib/gi18n.h> +#include <libgnomevfs/gnome-vfs.h> +#include <libgnomevfs/gnome-vfs-uri.h> +#include <string.h> + +#include "ephy-debug.h" #include "ephy-embed.h" +#include "ephy-embed-shell.h" #include "ephy-embed-type-builtins.h" +#include "ephy-embed-utils.h" +#include "ephy-favicon-cache.h" +#include "ephy-history.h" +#include "ephy-string.h" #include "ephy-zoom.h" #include "ephy-base-embed.h" +#define MAX_TITLE_LENGTH 512 /* characters */ +#define RELOAD_DELAY 250 /* ms */ +#define RELOAD_DELAY_MAX_TICKS 40 /* RELOAD_DELAY * RELOAD_DELAY_MAX_TICKS = 10 s */ + struct _EphyBaseEmbedPrivate { + EphyEmbedAddressExpire address_expire; + /* guint address_expire : 2; ? */ + EphyEmbedSecurityLevel security_level; + /* guint security_level : 3; ? */ + EphyEmbedDocumentType document_type; + EphyEmbedNavigationFlags nav_flags; + float zoom; + /* Flags */ guint is_blank : 1; + guint is_loading : 1; + guint is_setting_zoom : 1; + gint8 load_percent; char *address; char *typed_address; char *title; char *loading_title; + int cur_requests; + int total_requests; + char *status_message; + char *link_message; + char *icon_address; + GdkPixbuf *icon; + + /* File watch */ + GnomeVFSMonitorHandle *monitor; + guint reload_scheduled_id; + guint reload_delay_ticks; + + GSList *hidden_popups; + GSList *shown_popups; }; -enum +#if 0 +typedef struct { - PROP_0, - PROP_ADDRESS, - PROP_DOCUMENT_TYPE, - PROP_HIDDEN_POPUP_COUNT, - PROP_ICON, - PROP_ICON_ADDRESS, - PROP_LINK_MESSAGE, - PROP_LOAD_PROGRESS, - PROP_LOAD_STATUS, - PROP_NAVIGATION, - PROP_POPUPS_ALLOWED, - PROP_SECURITY, - PROP_STATUS_MESSAGE, - PROP_TITLE, - PROP_TYPED_ADDRESS, - PROP_ZOOM -}; + char *url; + char *name; + char *features; +} PopupInfo; +#endif +enum + { + PROP_0, + PROP_ADDRESS, + PROP_DOCUMENT_TYPE, + PROP_HIDDEN_POPUP_COUNT, + PROP_ICON, + PROP_ICON_ADDRESS, + PROP_LINK_MESSAGE, + PROP_LOAD_PROGRESS, + PROP_LOAD_STATUS, + PROP_NAVIGATION, + PROP_POPUPS_ALLOWED, + PROP_SECURITY, + PROP_STATUS_MESSAGE, + PROP_TITLE, + PROP_TYPED_ADDRESS, + PROP_ZOOM + }; + +#define EPHY_BASE_EMBED_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BASE_EMBED, EphyBaseEmbedPrivate)) + +static void ephy_base_embed_file_monitor_cancel (EphyBaseEmbed *embed); static void ephy_base_embed_dispose (GObject *object); static void ephy_base_embed_finalize (GObject *object); static void ephy_embed_iface_init (EphyEmbedIface *iface); @@ -73,7 +128,7 @@ ephy_base_embed_size_request (GtkWidget *widget, GTK_WIDGET_CLASS (ephy_base_embed_parent_class)->size_request (widget, requisition); child = GTK_BIN (widget)->child; - + if (child && GTK_WIDGET_VISIBLE (child)) { GtkRequisition child_requisition; @@ -96,11 +151,122 @@ ephy_base_embed_size_allocate (GtkWidget *widget, } static void -ephy_base_embed_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +impl_set_typed_address (EphyEmbed *embed, + const char *address, + EphyEmbedAddressExpire expire) +{ + EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (embed)->priv; + + g_free (priv->typed_address); + priv->typed_address = g_strdup (address); + + if (expire == EPHY_EMBED_ADDRESS_EXPIRE_CURRENT && + !priv->is_loading) + { + priv->address_expire = EPHY_EMBED_ADDRESS_EXPIRE_NOW; + } + else + { + priv->address_expire = expire; + } + + g_object_notify (G_OBJECT (embed), "typed-address"); +} + +static const char* +impl_get_typed_address (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->typed_address; +} + +static const char* +impl_get_loading_title (EphyEmbed *embed) +{ + EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (embed)->priv; + + return priv->loading_title; +} + +static gboolean +impl_get_is_blank (EphyEmbed *embed) +{ + EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (embed)->priv; + + return priv->is_blank; +} + +static const char* +impl_get_icon_address (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->icon_address; +} + +static GdkPixbuf* +impl_get_icon (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->icon; +} + +static const char * +impl_get_title (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->title; +} + +static EphyEmbedDocumentType +impl_get_document_type (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->document_type; +} + +static int +impl_get_load_percent (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->load_percent; +} + +static gboolean +impl_get_load_status (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->is_loading; +} + +static EphyEmbedNavigationFlags +impl_get_navigation_flags (EphyEmbed *embed) +{ + return EPHY_BASE_EMBED (embed)->priv->nav_flags; +} + +static const char* +impl_get_address (EphyEmbed *embed) +{ + EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (embed)->priv; + return priv->address ? priv->address : "about:blank"; +} + +static const char* +impl_get_status_message (EphyEmbed *embed) +{ + EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (embed)->priv; + + if (priv->link_message && priv->link_message[0] != '\0') + { + return priv->link_message; + } + else if (priv->status_message) + { + return priv->status_message; + } + else + { + return NULL; + } +} + +static const char* +impl_get_link_message (EphyEmbed *embed) { + return EPHY_BASE_EMBED (embed)->priv->link_message; } static void @@ -109,6 +275,97 @@ ephy_base_embed_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { + switch (prop_id) + { + case PROP_ICON_ADDRESS: + ephy_base_embed_set_icon_address (EPHY_BASE_EMBED (object), g_value_get_string (value)); + break; + case PROP_TYPED_ADDRESS: + impl_set_typed_address (EPHY_EMBED (object), g_value_get_string (value), + EPHY_EMBED_ADDRESS_EXPIRE_NOW); + break; + case PROP_POPUPS_ALLOWED: + //ephy_base_embed_set_popups_allowed (MOZILLA_EMBED (object), g_value_get_boolean (value)); + break; + case PROP_ADDRESS: + case PROP_TITLE: + case PROP_DOCUMENT_TYPE: + case PROP_HIDDEN_POPUP_COUNT: + case PROP_ICON: + case PROP_LOAD_PROGRESS: + case PROP_LOAD_STATUS: + case PROP_LINK_MESSAGE: + case PROP_NAVIGATION: + case PROP_SECURITY: + case PROP_STATUS_MESSAGE: + case PROP_ZOOM: + /* read only */ + break; + default: + break; + } +} + +static void +ephy_base_embed_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (object)->priv; + + switch (prop_id) + { + case PROP_ADDRESS: + g_value_set_string (value, priv->address); + break; + case PROP_DOCUMENT_TYPE: + g_value_set_enum (value, priv->document_type); + break; + case PROP_HIDDEN_POPUP_COUNT: + g_value_set_int (value, 0); + //g_value_set_int (value, popup_blocker_n_hidden (embed)); + break; + case PROP_ICON: + g_value_set_object (value, priv->icon); + break; + case PROP_ICON_ADDRESS: + g_value_set_string (value, priv->icon_address); + break; + case PROP_LINK_MESSAGE: + g_value_set_string (value, priv->link_message); + break; + case PROP_LOAD_PROGRESS: + g_value_set_int (value, priv->load_percent); + break; + case PROP_LOAD_STATUS: + g_value_set_boolean (value, priv->is_loading); + break; + case PROP_NAVIGATION: + g_value_set_flags (value, priv->nav_flags); + break; + case PROP_POPUPS_ALLOWED: + g_value_set_boolean (value, FALSE); + //g_value_set_boolean (value, mozilla_embed_get_popups_allowed (embed)); + break; + case PROP_SECURITY: + g_value_set_enum (value, priv->security_level); + break; + case PROP_STATUS_MESSAGE: + g_value_set_string (value, priv->status_message); + break; + case PROP_TITLE: + g_value_set_string (value, priv->title); + break; + case PROP_TYPED_ADDRESS: + g_value_set_string (value, priv->typed_address); + break; + case PROP_ZOOM: + g_value_set_float (value, priv->zoom); + break; + default: + break; + } } static void @@ -246,14 +503,139 @@ ephy_base_embed_class_init (EphyBaseEmbedClass *klass) } static void +icon_cache_changed_cb (EphyFaviconCache *cache, + const char *address, + EphyBaseEmbed *embed) +{ + const char *icon_address; + + g_return_if_fail (address != NULL); + + icon_address = ephy_embed_get_icon_address (EPHY_EMBED (embed)); + + /* is this for us? */ + if (icon_address != NULL && + strcmp (icon_address, address) == 0) + { + ephy_base_embed_load_icon (EPHY_BASE_EMBED (embed)); + } +} + +static void +ge_document_type_cb (EphyEmbed *embed, + EphyEmbedDocumentType type, + EphyBaseEmbed *bembed) +{ + if (bembed->priv->document_type != type) + { + bembed->priv->document_type = type; + + g_object_notify (G_OBJECT (embed), "document-type"); + } +} + +static gboolean +address_has_web_scheme (const char *address) +{ + gboolean has_web_scheme; + + if (address == NULL) return FALSE; + + has_web_scheme = (g_str_has_prefix (address, "http:") || + g_str_has_prefix (address, "https:") || + g_str_has_prefix (address, "ftp:") || + g_str_has_prefix (address, "file:") || + g_str_has_prefix (address, "data:") || + g_str_has_prefix (address, "about:") || + g_str_has_prefix (address, "gopher:")); + + return has_web_scheme; +} + +static void +ge_zoom_change_cb (EphyEmbed *embed, + float zoom, + EphyBaseEmbed *bembed) +{ + char *address; + + if (bembed->priv->zoom != zoom) + { + if (bembed->priv->is_setting_zoom) + { + return; + } + + address = ephy_embed_get_location (embed, TRUE); + if (address_has_web_scheme (address)) + { + EphyHistory *history; + EphyNode *host; + history = EPHY_HISTORY + (ephy_embed_shell_get_global_history (embed_shell)); + host = ephy_history_get_host (history, address); + + if (host != NULL) + { + ephy_node_set_property_float (host, + EPHY_NODE_HOST_PROP_ZOOM, + zoom); + } + } + + g_free (address); + + bembed->priv->zoom = zoom; + + g_object_notify (G_OBJECT (embed), "zoom"); + } +} + +static void +ge_favicon_cb (EphyEmbed *membed, + const char *address, + EphyBaseEmbed *bembed) +{ + ephy_base_embed_set_icon_address (bembed, address); +} + +static void ephy_base_embed_init (EphyBaseEmbed *self) { + EphyBaseEmbedPrivate *priv; + EphyFaviconCache *cache; + + priv = self->priv = EPHY_BASE_EMBED_GET_PRIVATE (self); + + g_signal_connect_object (self, "ge_document_type", + G_CALLBACK (ge_document_type_cb), + self, (GConnectFlags) 0); + + g_signal_connect_object (self, "ge_zoom_change", + G_CALLBACK (ge_zoom_change_cb), + self, (GConnectFlags) 0); + + g_signal_connect_object (self, "ge_favicon", + G_CALLBACK (ge_favicon_cb), + self, (GConnectFlags)0); + + cache = EPHY_FAVICON_CACHE + (ephy_embed_shell_get_favicon_cache (embed_shell)); + g_signal_connect_object (G_OBJECT (cache), "changed", + G_CALLBACK (icon_cache_changed_cb), + self, (GConnectFlags)0); + + priv->document_type = EPHY_EMBED_DOCUMENT_HTML; + priv->security_level = EPHY_EMBED_STATE_IS_UNKNOWN; + priv->zoom = 1.0; + priv->address_expire = EPHY_EMBED_ADDRESS_EXPIRE_NOW; + priv->is_blank = TRUE; } static void ephy_base_embed_dispose (GObject *object) { - EphyBaseEmbed *self = (EphyBaseEmbed *)object; + ephy_base_embed_file_monitor_cancel (EPHY_BASE_EMBED (object)); G_OBJECT_CLASS (ephy_base_embed_parent_class)->dispose (object); } @@ -261,7 +643,25 @@ ephy_base_embed_dispose (GObject *object) static void ephy_base_embed_finalize (GObject *object) { - EphyBaseEmbed *self = (EphyBaseEmbed *)object; + EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (object)->priv; + + if (priv->icon != NULL) + { + g_object_unref (priv->icon); + priv->icon = NULL; + } + +#if 0 + popups_manager_reset (embed); +#endif + + g_free (priv->icon_address); + g_free (priv->status_message); + g_free (priv->link_message); + g_free (priv->address); + g_free (priv->typed_address); + g_free (priv->title); + g_free (priv->loading_title); G_OBJECT_CLASS (ephy_base_embed_parent_class)->finalize (object); } @@ -269,4 +669,992 @@ ephy_base_embed_finalize (GObject *object) static void ephy_embed_iface_init (EphyEmbedIface *iface) { + iface->get_title = impl_get_title; + iface->get_address = impl_get_address; + iface->get_typed_address = impl_get_typed_address; + iface->set_typed_address = impl_set_typed_address; + iface->get_loading_title = impl_get_loading_title; + iface->get_is_blank = impl_get_is_blank; + iface->get_icon = impl_get_icon; + iface->get_icon_address = impl_get_icon_address; + iface->get_document_type = impl_get_document_type; + iface->get_load_status = impl_get_load_status; + iface->get_load_percent = impl_get_load_percent; + iface->get_navigation_flags = impl_get_navigation_flags; + iface->get_link_message = impl_get_link_message; + iface->get_status_message = impl_get_status_message; +} + +void +ephy_base_embed_set_address (EphyBaseEmbed *embed, char *address) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + GObject *object = G_OBJECT (embed); + + g_free (priv->address); + priv->address = address; + + priv->is_blank = address == NULL || + strcmp (address, "about:blank") == 0; + + if (priv->is_loading && + priv->address_expire == EPHY_EMBED_ADDRESS_EXPIRE_NOW && + priv->typed_address != NULL) + { + g_free (priv->typed_address); + priv->typed_address = NULL; + + g_object_notify (object, "typed-address"); + } + + g_object_notify (object, "address"); +} + +static char * +get_title_from_address (const char *address) +{ + GnomeVFSURI *uri; + char *title; + + if (address == NULL) return NULL; + + uri = gnome_vfs_uri_new (address); + if (uri == NULL) return g_strdup (address); + + title = gnome_vfs_uri_to_string (uri, + (GnomeVFSURIHideOptions) + (GNOME_VFS_URI_HIDE_USER_NAME | + GNOME_VFS_URI_HIDE_PASSWORD | + GNOME_VFS_URI_HIDE_HOST_PORT | + GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD | + GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER)); + gnome_vfs_uri_unref (uri); + + return title; +} + +void +ephy_base_embed_set_title (EphyBaseEmbed *embed, + char *title) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + if (!priv->is_blank && (title == NULL || g_strstrip (title)[0] == '\0')) + { + g_free (title); + title = get_title_from_address (priv->address); + + /* Fallback */ + if (title == NULL || title[0] == '\0') + { + g_free (title); + title = NULL; + priv->is_blank = TRUE; + } + } + else if (priv->is_blank && title != NULL) + { + g_free (title); + title = NULL; + } + + g_free (priv->title); + priv->title = ephy_string_shorten (title, MAX_TITLE_LENGTH); + + g_object_notify (G_OBJECT (embed), "title"); +} + +static void +ensure_page_info (EphyBaseEmbed *embed, const char *address) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + if ((priv->address == NULL || priv->address[0] == '\0') && + priv->address_expire == EPHY_EMBED_ADDRESS_EXPIRE_NOW) + { + ephy_base_embed_set_address (embed, g_strdup (address)); + } + + /* FIXME huh?? */ + if (priv->title == NULL || priv->title[0] == '\0') + { + ephy_base_embed_set_title (embed, NULL); + } +} +static void +update_net_state_message (EphyBaseEmbed *embed, const char *uri, EphyEmbedNetState flags) +{ + GnomeVFSURI *vfs_uri = NULL; + const char *msg = NULL; + const char *host = NULL; + + if (uri != NULL) + { + vfs_uri = gnome_vfs_uri_new (uri); + } + + if (vfs_uri != NULL) + { + host = gnome_vfs_uri_get_host_name (vfs_uri); + } + + if (host == NULL || host[0] == '\0') goto out; + + /* IS_REQUEST and IS_NETWORK can be both set */ + if (flags & EPHY_EMBED_STATE_IS_REQUEST) + { + if (flags & EPHY_EMBED_STATE_REDIRECTING) + { + msg = _("Redirecting to “%s”…"); + } + else if (flags & EPHY_EMBED_STATE_TRANSFERRING) + { + msg = _("Transferring data from “%s”…"); + } + else if (flags & EPHY_EMBED_STATE_NEGOTIATING) + { + msg = _("Waiting for authorization from “%s”…"); + } + } + + if (flags & EPHY_EMBED_STATE_IS_NETWORK) + { + if (flags & EPHY_EMBED_STATE_START) + { + msg = _("Loading “%s”…"); + } + } + + if ((flags & EPHY_EMBED_STATE_IS_NETWORK) && + (flags & EPHY_EMBED_STATE_STOP)) + { + g_free (embed->priv->status_message); + embed->priv->status_message = NULL; + g_object_notify (G_OBJECT (embed), "status-message"); + + } + else if (msg != NULL) + { + g_free (embed->priv->status_message); + g_free (embed->priv->loading_title); + embed->priv->status_message = g_strdup_printf (msg, host); + embed->priv->loading_title = g_strdup_printf (msg, host); + g_object_notify (G_OBJECT (embed), "status-message"); + g_object_notify (G_OBJECT (embed), "title"); + } + + out: + if (vfs_uri != NULL) + { + gnome_vfs_uri_unref (vfs_uri); + } +} + +static void +update_navigation_flags (EphyBaseEmbed *membed) +{ + EphyBaseEmbedPrivate *priv = membed->priv; + EphyEmbed *embed = EPHY_EMBED (membed); + guint flags = 0; + + if (ephy_embed_can_go_up (embed)) + { + flags |= EPHY_EMBED_NAV_UP; + } + + if (ephy_embed_can_go_back (embed)) + { + flags |= EPHY_EMBED_NAV_BACK; + } + + if (ephy_embed_can_go_forward (embed)) + { + flags |= EPHY_EMBED_NAV_FORWARD; + } + + if (priv->nav_flags != (EphyEmbedNavigationFlags)flags) + { + priv->nav_flags = (EphyEmbedNavigationFlags)flags; + + g_object_notify (G_OBJECT (embed), "navigation"); + } +} + +static int +build_load_percent (int requests_done, int requests_total) +{ + int percent= 0; + + if (requests_total > 0) + { + percent = (requests_done * 100) / requests_total; + percent = CLAMP (percent, 0, 100); + } + + return percent; +} + +static void +ephy_base_embed_set_load_percent (EphyBaseEmbed *embed, int percent) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + if (percent != priv->load_percent) + { + priv->load_percent = percent; + + g_object_notify (G_OBJECT (embed), "load-progress"); + } +} + +static void +build_progress_from_requests (EphyBaseEmbed *embed, EphyEmbedNetState state) +{ + int load_percent; + + if (state & EPHY_EMBED_STATE_IS_REQUEST) + { + if (state & EPHY_EMBED_STATE_START) + { + embed->priv->total_requests ++; + } + else if (state & EPHY_EMBED_STATE_STOP) + { + embed->priv->cur_requests ++; + } + + load_percent = build_load_percent (embed->priv->cur_requests, + embed->priv->total_requests); + + ephy_base_embed_set_load_percent (embed, load_percent); + } +} + +static void +ephy_base_embed_set_load_status (EphyBaseEmbed *embed, gboolean status) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + guint is_loading; + + is_loading = status != FALSE; + + if (is_loading != priv->is_loading) + { + priv->is_loading = is_loading; + + g_object_notify (G_OBJECT (embed), "load-status"); + } +} + +void +ephy_base_embed_update_from_net_state (EphyBaseEmbed *embed, + const char *uri, + EphyEmbedNetState state) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + update_net_state_message (embed, uri, state); + + if (state & EPHY_EMBED_STATE_IS_NETWORK) + { + if (state & EPHY_EMBED_STATE_START) + { + GObject *object = G_OBJECT (embed); + + g_object_freeze_notify (object); + + priv->total_requests = 0; + priv->cur_requests = 0; + + ephy_base_embed_set_load_percent (embed, 0); + ephy_base_embed_set_load_status (embed, TRUE); + + ensure_page_info (embed, uri); + + g_object_notify (object, "title"); + + g_object_thaw_notify (object); + } + else if (state & EPHY_EMBED_STATE_STOP) + { + GObject *object = G_OBJECT (embed); + + g_object_freeze_notify (object); + + ephy_base_embed_set_load_percent (embed, 100); + ephy_base_embed_set_load_status (embed, FALSE); + + g_free (priv->loading_title); + priv->loading_title = NULL; + + priv->address_expire = EPHY_EMBED_ADDRESS_EXPIRE_NOW; + + g_object_notify (object, "title"); + + g_object_thaw_notify (object); + } + + update_navigation_flags (embed); + } + + build_progress_from_requests (embed, state); +} + +void +ephy_base_embed_set_loading_title (EphyBaseEmbed *embed, + const char *title, + gboolean is_address) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + char *freeme = NULL; + + g_free (priv->loading_title); + priv->loading_title = NULL; + + if (is_address) + { + title = freeme = get_title_from_address (title); + } + + if (title != NULL && title[0] != '\0') + { + /* translators: %s here is the address of the web page */ + priv->loading_title = g_strdup_printf (_("Loading “%s”…"), title); + } + else + { + priv->loading_title = g_strdup (_("Loading…")); + } + + g_free (freeme); +} + +static void +ephy_base_embed_file_monitor_cancel (EphyBaseEmbed *embed) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + if (priv->monitor != NULL) + { + LOG ("Cancelling file monitor"); + + gnome_vfs_monitor_cancel (priv->monitor); + priv->monitor = NULL; + } + + if (priv->reload_scheduled_id != 0) + { + LOG ("Cancelling scheduled reload"); + + g_source_remove (priv->reload_scheduled_id); + priv->reload_scheduled_id = 0; + } + + priv->reload_delay_ticks = 0; +} + +static gboolean +ephy_base_embed_file_monitor_reload_cb (EphyBaseEmbed *embed) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + if (priv->reload_delay_ticks > 0) + { + priv->reload_delay_ticks--; + + /* Run again */ + return TRUE; + } + + if (priv->is_loading) + { + /* Wait a bit to reload if we're still loading! */ + priv->reload_delay_ticks = RELOAD_DELAY_MAX_TICKS / 2; + + /* Run again */ + return TRUE; + } + + priv->reload_scheduled_id = 0; + + LOG ("Reloading file '%s'", ephy_embed_get_address (EPHY_EMBED (embed))); + + ephy_embed_reload (EPHY_EMBED (embed), TRUE); + + /* don't run again */ + return FALSE; +} + +static void +ephy_base_embed_file_monitor_cb (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + EphyBaseEmbed *embed) +{ + gboolean uri_is_directory; + gboolean should_reload; + char* local_path; + EphyBaseEmbedPrivate *priv = embed->priv; + + LOG ("File '%s' has changed, scheduling reload", monitor_uri); + + local_path = gnome_vfs_get_local_path_from_uri(monitor_uri); + uri_is_directory = g_file_test(local_path, G_FILE_TEST_IS_DIR); + g_free(local_path); + + switch (event_type) + { + /* These events will always trigger a reload: */ + case GNOME_VFS_MONITOR_EVENT_CHANGED: + case GNOME_VFS_MONITOR_EVENT_CREATED: + should_reload = TRUE; + break; + + /* These events will only trigger a reload for directories: */ + case GNOME_VFS_MONITOR_EVENT_DELETED: + case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: + should_reload = uri_is_directory; + break; + + /* These events don't trigger a reload: */ + case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: + case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: + default: + should_reload = FALSE; + break; + } + + if (should_reload) { + /* We make a lot of assumptions here, but basically we know + * that we just have to reload, by construction. + * Delay the reload a little bit so we don't endlessly + * reload while a file is written. + */ + if (priv->reload_delay_ticks == 0) + { + priv->reload_delay_ticks = 1; + } + else + { + /* Exponential backoff */ + priv->reload_delay_ticks = MIN (priv->reload_delay_ticks * 2, + RELOAD_DELAY_MAX_TICKS); + } + + if (priv->reload_scheduled_id == 0) + { + priv->reload_scheduled_id = + g_timeout_add (RELOAD_DELAY, + (GSourceFunc) ephy_base_embed_file_monitor_reload_cb, embed); + } + } +} + +static void +ephy_base_embed_update_file_monitor (EphyBaseEmbed *embed, + const gchar *address) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + GnomeVFSMonitorHandle *handle = NULL; + gboolean local; + char* local_path; + GnomeVFSMonitorType monitor_type; + + if (priv->monitor != NULL && + priv->address != NULL && address != NULL && + strcmp (priv->address, address) == 0) + + { + /* same address, no change needed */ + return; + } + + ephy_base_embed_file_monitor_cancel (embed); + + local = g_str_has_prefix (address, "file://"); + if (local == FALSE) return; + + local_path = gnome_vfs_get_local_path_from_uri(address); + monitor_type = g_file_test(local_path, G_FILE_TEST_IS_DIR) + ? GNOME_VFS_MONITOR_DIRECTORY + : GNOME_VFS_MONITOR_FILE; + g_free(local_path); + + if (gnome_vfs_monitor_add (&handle, address, + monitor_type, + (GnomeVFSMonitorCallback) ephy_base_embed_file_monitor_cb, + embed) == GNOME_VFS_OK) + { + LOG ("Installed monitor for file '%s'", address); + + priv->monitor = handle; + } +} + +void +ephy_base_embed_location_changed (EphyBaseEmbed *embed, + char *location) +{ + GObject *object = G_OBJECT (embed); + + g_object_freeze_notify (object); + + /* do this up here so we still have the old address around */ + ephy_base_embed_update_file_monitor (embed, location); + + /* Do not expose about:blank to the user, an empty address + bar will do better */ + if (location == NULL || location[0] == '\0' || + strcmp (location, "about:blank") == 0) + { + ephy_base_embed_set_address (embed, NULL); + ephy_base_embed_set_title (embed, NULL); + } + else + { + char *embed_address; + + /* we do this to get rid of an eventual password in the URL */ + embed_address = ephy_embed_get_location (EPHY_EMBED (embed), TRUE); + ephy_base_embed_set_address (embed, embed_address); + ephy_base_embed_set_loading_title (embed, embed_address, TRUE); + } + + ephy_base_embed_set_link_message (embed, NULL); + ephy_base_embed_set_icon_address (embed, NULL); + update_navigation_flags (embed); + + g_object_notify (object, "title"); + + g_object_thaw_notify (object); +} + +void +ephy_base_embed_set_link_message (EphyBaseEmbed *embed, + char *link_message) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + g_free (priv->link_message); + + priv->link_message = ephy_embed_utils_link_message_parse (link_message); + + g_object_notify (G_OBJECT (embed), "status-message"); + g_object_notify (G_OBJECT (embed), "link-message"); +} + +void +ephy_base_embed_load_icon (EphyBaseEmbed *embed) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + EphyEmbedShell *shell; + EphyFaviconCache *cache; + + if (priv->icon_address == NULL || priv->icon != NULL) return; + + shell = ephy_embed_shell_get_default (); + cache = EPHY_FAVICON_CACHE (ephy_embed_shell_get_favicon_cache (shell)); + + /* ephy_favicon_cache_get returns a reference already */ + priv->icon = ephy_favicon_cache_get (cache, priv->icon_address); + + g_object_notify (G_OBJECT (embed), "icon"); +} + +void +ephy_base_embed_set_icon_address (EphyBaseEmbed *embed, + const char *address) +{ + GObject *object = G_OBJECT (embed); + EphyBaseEmbedPrivate *priv = embed->priv; + /* EphyHistory *history; + EphyBookmarks *eb;*/ + + g_free (priv->icon_address); + priv->icon_address = g_strdup (address); + + if (priv->icon != NULL) + { + g_object_unref (priv->icon); + priv->icon = NULL; + + g_object_notify (object, "icon"); + } + + if (priv->icon_address) + { + /* FIXME: we need to put this somewhere inside src?/ + history = EPHY_HISTORY + (ephy_embed_shell_get_global_history (embed_shell)); + ephy_history_set_icon (history, priv->address, + priv->icon_address); + + eb = ephy_shell_get_bookmarks (ephy_shell); + ephy_bookmarks_set_icon (eb, priv->address, + priv->icon_address);*/ + + ephy_base_embed_load_icon (embed); + } + + g_object_notify (object, "icon-address"); +} + +void +ephy_base_embed_set_security_level (EphyBaseEmbed *embed, + EphyEmbedSecurityLevel level) +{ + EphyBaseEmbedPrivate *priv = embed->priv; + + if (priv->security_level != level) + { + priv->security_level = level; + + g_object_notify (G_OBJECT (embed), "security-level"); + } +} + +void +ephy_base_embed_restore_zoom_level (EphyBaseEmbed *membed, + const char *address) +{ + EphyBaseEmbedPrivate *priv = membed->priv; + + /* restore zoom level */ + if (address_has_web_scheme (address)) + { + EphyHistory *history; + EphyNode *host; + GValue value = { 0, }; + float zoom = 1.0, current_zoom; + + history = EPHY_HISTORY + (ephy_embed_shell_get_global_history (embed_shell)); + host = ephy_history_get_host (history, address); + + if (host != NULL && ephy_node_get_property + (host, EPHY_NODE_HOST_PROP_ZOOM, &value)) + { + zoom = g_value_get_float (&value); + g_value_unset (&value); + } + + current_zoom = ephy_embed_get_zoom (EPHY_EMBED (membed)); + if (zoom != current_zoom) + { + priv->is_setting_zoom = TRUE; + ephy_embed_set_zoom (EPHY_EMBED (membed), zoom); + priv->is_setting_zoom = FALSE; + } + } +} + +/* Popup stuff if zeroed for now */ + +#if 0 +static void +ephy_tab_content_change_cb (EphyEmbed *embed, const char *address, EphyTab *tab) +{ + popups_manager_reset (tab); + g_object_notify (G_OBJECT (tab), "popups-allowed"); +} + +static void +ephy_tab_new_window_cb (EphyEmbed *embed, + EphyEmbed *new_embed, + EphyTab *tab) +{ + EphyWindow *window; + + g_return_if_fail (new_embed != NULL); + + window = EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (new_embed))); + g_return_if_fail (window != NULL); + + popups_manager_add_window (tab, window); +} + +static void +ephy_tab_popup_blocked_cb (EphyEmbed *embed, + const char *url, + const char *name, + const char *features, + EphyTab *tab) +{ + popups_manager_add (tab, url, name, features); +} + +static void +popups_manager_free_info (PopupInfo *popup) +{ + g_free (popup->url); + g_free (popup->name); + g_free (popup->features); + g_free (popup); +} + +static void +popups_manager_add (MozillaEmbed *embed, + const char *url, + const char *name, + const char *features) +{ + MozillaEmbedPrivate *priv = embed->priv; + PopupInfo *popup; + + LOG ("popups_manager_add: embed %p, url %s, features %s", + embed, url, features); + + popup = g_new0 (PopupInfo, 1); + + popup->url = (url == NULL) ? NULL : g_strdup (url); + popup->name = g_strdup (name); + popup->features = g_strdup (features); + + priv->hidden_popups = g_slist_prepend (priv->hidden_popups, popup); + + if (popup_blocker_n_hidden (embed) > MAX_HIDDEN_POPUPS) /* bug #160863 */ + { + /* Remove the oldest popup */ + GSList *l = embed->priv->hidden_popups; + + while (l->next->next != NULL) + { + l = l->next; + } + + popup = (PopupInfo *) l->next->data; + popups_manager_free_info (popup); + + l->next = NULL; + } + else + { + g_object_notify (G_OBJECT (embed), "hidden-popup-count"); + } +} + +static gboolean +popups_manager_remove_window (MozillaEmbed *embed, + EphyWindow *window) +{ + embed->priv->shown_popups = g_slist_remove (embed->priv->shown_popups, + window); + + return FALSE; +} + +static void +disconnect_popup (EphyWindow *window, + MozillaEmbed *embed) +{ + g_signal_handlers_disconnect_by_func + (window, G_CALLBACK (popups_manager_remove_window), embed); +} + +static void +popups_manager_add_window (MozillaEmbed *embed, + EphyWindow *window) +{ + LOG ("popups_manager_add_window: embed %p, window %p", embed, window); + + embed->priv->shown_popups = g_slist_prepend + (embed->priv->shown_popups, window); + + g_signal_connect_swapped (window, "destroy", + G_CALLBACK (popups_manager_remove_window), + embed); +} + +static gboolean +mozilla_embed_get_popups_allowed (MozillaEmbed *embed) +{ + EphyPermissionManager *permission_manager; + EphyPermission response; + EphyEmbed *embed; + char *location; + gboolean allow; + + permission_manager = EPHY_PERMISSION_MANAGER + (ephy_embed_shell_get_embed_single (embed_shell)); + g_return_val_if_fail (EPHY_IS_PERMISSION_MANAGER (permission_manager), + FALSE); + + location = ephy_embed_get_location (embed, TRUE); + if (location == NULL) return FALSE; /* FALSE, TRUE… same thing */ + + response = ephy_permission_manager_test_permission + (permission_manager, location, EPT_POPUP); + + switch (response) + { + case EPHY_PERMISSION_ALLOWED: + allow = TRUE; + break; + case EPHY_PERMISSION_DENIED: + allow = FALSE; + break; + case EPHY_PERMISSION_DEFAULT: + default: + allow = eel_gconf_get_boolean + (CONF_SECURITY_ALLOW_POPUPS); + break; + } + + g_free (location); + + LOG ("mozilla_embed_get_popups_allowed: embed %p, allowed: %d", embed, allow); + + return allow; +} + +static void +popups_manager_show (PopupInfo *popup, + MozillaEmbed *embed) +{ + EphyEmbed *embed; + EphyEmbedSingle *single; + + /* Only show popup with non NULL url */ + if (popup->url != NULL) + { + embed = ephy_embed_get_embed (embed); + + single = EPHY_EMBED_SINGLE + (ephy_embed_shell_get_embed_single (embed_shell)); + + ephy_embed_single_open_window (single, embed, popup->url, + popup->name, popup->features); + } + popups_manager_free_info (popup); +} + +static void +popups_manager_show_all (MozillaEmbed *embed) +{ + LOG ("popup_blocker_show_all: embed %p", embed); + + g_slist_foreach (embed->priv->hidden_popups, + (GFunc) popups_manager_show, embed); + g_slist_free (embed->priv->hidden_popups); + embed->priv->hidden_popups = NULL; + + g_object_notify (G_OBJECT (embed), "hidden-popup-count"); +} + +static char * +popups_manager_new_window_info (EphyWindow *window) +{ + MozillaEmbed *embed; + EphyEmbedChrome chrome; + gboolean is_popup; + char *features; + + g_object_get (window, "chrome", &chrome, "is-popup", &is_popup, NULL); + g_return_val_if_fail (is_popup, g_strdup ("")); + + embed = ephy_window_get_active_embed (window); + g_return_val_if_fail (embed != NULL, g_strdup ("")); + + features = g_strdup_printf + ("width=%d,height=%d,menubar=%d,status=%d,toolbar=%d", + embed->priv->width, embed->priv->height, + (chrome & EPHY_EMBED_CHROME_MENUBAR) > 0, + (chrome & EPHY_EMBED_CHROME_STATUSBAR) > 0, + (chrome & EPHY_EMBED_CHROME_TOOLBAR) > 0); + + return features; +} + +static void +popups_manager_hide (EphyWindow *window, + MozillaEmbed *parent_embed) +{ + EphyEmbed *embed; + char *location; + char *features; + + embed = ephy_window_get_active_embed (window); + g_return_if_fail (EPHY_IS_EMBED (embed)); + + location = ephy_embed_get_location (embed, TRUE); + if (location == NULL) return; + + features = popups_manager_new_window_info (window); + + popups_manager_add (parent_embed, location, "" /* FIXME? maybe _blank? */, features); + + gtk_widget_destroy (GTK_WIDGET (window)); + + g_free (location); + g_free (features); +} + +static void +popups_manager_hide_all (MozillaEmbed *embed) +{ + LOG ("popup_blocker_hide_all: embed %p", embed); + + g_slist_foreach (embed->priv->shown_popups, + (GFunc) popups_manager_hide, embed); + g_slist_free (embed->priv->shown_popups); + embed->priv->shown_popups = NULL; +} + +static void +mozilla_embed_set_popups_allowed (MozillaEmbed *embed, + gboolean allowed) +{ + char *location; + EphyEmbed *embed; + EphyPermissionManager *manager; + EphyPermission permission; + + embed = ephy_embed_get_embed (embed); + + location = ephy_embed_get_location (embed, TRUE); + g_return_if_fail (location != NULL); + + manager = EPHY_PERMISSION_MANAGER + (ephy_embed_shell_get_embed_single (embed_shell)); + g_return_if_fail (EPHY_IS_PERMISSION_MANAGER (manager)); + + permission = allowed ? EPHY_PERMISSION_ALLOWED + : EPHY_PERMISSION_DENIED; + + ephy_permission_manager_add_permission (manager, location, EPT_POPUP, permission); + + if (allowed) + { + popups_manager_show_all (embed); + } + else + { + popups_manager_hide_all (embed); + } + + g_free (location); +} + +static guint +popup_blocker_n_hidden (MozillaEmbed *embed) +{ + return g_slist_length (embed->priv->hidden_popups); +} + +static void +popups_manager_reset (MozillaEmbed *embed) +{ + g_slist_foreach (embed->priv->hidden_popups, + (GFunc) popups_manager_free_info, NULL); + g_slist_free (embed->priv->hidden_popups); + embed->priv->hidden_popups = NULL; + + g_slist_foreach (embed->priv->shown_popups, + (GFunc) disconnect_popup, embed); + g_slist_free (embed->priv->shown_popups); + embed->priv->shown_popups = NULL; + + g_object_notify (G_OBJECT (embed), "hidden-popup-count"); } +#endif diff --git a/embed/ephy-base-embed.h b/embed/ephy-base-embed.h index 4fe5b120d..520dc8520 100644 --- a/embed/ephy-base-embed.h +++ b/embed/ephy-base-embed.h @@ -19,16 +19,38 @@ typedef struct _EphyBaseEmbedPrivate EphyBaseEmbedPrivate; struct _EphyBaseEmbedClass { - GtkBinClass parent_class; + GtkBinClass parent_class; }; struct _EphyBaseEmbed { - GtkBin parent_instance; + GtkBin parent_instance; + + /*< private >*/ + EphyBaseEmbedPrivate *priv; }; GType ephy_base_embed_get_type (void) G_GNUC_CONST; - +void ephy_base_embed_set_title (EphyBaseEmbed *embed, + char *title); +void ephy_base_embed_set_loading_title (EphyBaseEmbed *embed, + const char *title, + gboolean is_address); +void ephy_base_embed_set_address (EphyBaseEmbed *embed, char *address); +void ephy_base_embed_location_changed (EphyBaseEmbed *embed, + char *location); +void ephy_base_embed_load_icon (EphyBaseEmbed *embed); +void ephy_base_embed_set_icon_address (EphyBaseEmbed *embed, + const char *address); +void ephy_base_embed_set_link_message (EphyBaseEmbed *embed, + char *link_message); +void ephy_base_embed_set_security_level (EphyBaseEmbed *embed, + EphyEmbedSecurityLevel level); +void ephy_base_embed_restore_zoom_level (EphyBaseEmbed *membed, + const char *address); +void ephy_base_embed_update_from_net_state (EphyBaseEmbed *embed, + const char *uri, + EphyEmbedNetState state); G_END_DECLS #endif /* __EPHY_BASE_EMBED_H__ */ diff --git a/embed/mozilla/mozilla-embed.cpp b/embed/mozilla/mozilla-embed.cpp index e0622ccad..62cbd6adf 100644 --- a/embed/mozilla/mozilla-embed.cpp +++ b/embed/mozilla/mozilla-embed.cpp @@ -34,8 +34,6 @@ #include <nsMemory.h> #include <glib/gi18n.h> -#include <libgnomevfs/gnome-vfs.h> -#include <libgnomevfs/gnome-vfs-uri.h> #include "EphyBrowser.h" #include "EphyUtils.h" @@ -46,10 +44,6 @@ #include "ephy-debug.h" #include "ephy-embed-shell.h" #include "ephy-embed-single.h" -#include "ephy-embed-utils.h" -#include "ephy-favicon-cache.h" -#include "ephy-history.h" -#include "ephy-string.h" #include "mozilla-embed-event.h" #include "mozilla-embed.h" @@ -58,7 +52,6 @@ static void mozilla_embed_class_init (MozillaEmbedClass *klass); static void mozilla_embed_init (MozillaEmbed *gs); static void mozilla_embed_destroy (GtkObject *object); static void mozilla_embed_finalize (GObject *object); -static void mozilla_embed_dispose (GObject *object); static void ephy_embed_iface_init (EphyEmbedIface *iface); static void mozilla_embed_location_changed_cb (GtkMozEmbed *embed, @@ -71,7 +64,7 @@ static void mozilla_embed_net_state_all_cb (GtkMozEmbed *embed, static gboolean mozilla_embed_dom_mouse_click_cb(GtkMozEmbed *embed, gpointer dom_event, MozillaEmbed *membed); -static gboolean mozilla_embed_dom_mouse_down_cb (GtkMozEmbed *embed, +static gboolean mozilla_embed_dom_mouse_down_cb (GtkMozEmbed *embed, gpointer dom_event, MozillaEmbed *membed); static gboolean mozilla_embed_dom_key_press_cb (GtkMozEmbed *embed, @@ -85,44 +78,16 @@ static void mozilla_embed_security_change_cb (GtkMozEmbed *embed, gpointer request, PRUint32 state, MozillaEmbed *membed); -static void mozilla_embed_document_type_cb (EphyEmbed *embed, - EphyEmbedDocumentType type, - MozillaEmbed *membed); -static void mozilla_embed_zoom_change_cb (EphyEmbed *embed, - float zoom, - MozillaEmbed *membed); static void mozilla_embed_title_change_cb (GtkMozEmbed *embed, MozillaEmbed *membed); static void mozilla_embed_link_message_cb (GtkMozEmbed *embed, MozillaEmbed *membed); -static void mozilla_embed_set_title (MozillaEmbed *embed, - char *title); -static void mozilla_embed_set_loading_title (MozillaEmbed *embed, - const char *title, - gboolean is_address); -static void mozilla_embed_icon_cache_changed_cb (EphyFaviconCache *cache, - const char *address, - MozillaEmbed *embed); -static void mozilla_embed_set_icon_address (MozillaEmbed *embed, - const char *address); static void mozilla_embed_favicon_cb (MozillaEmbed *membed, const char *address, GtkMozEmbed *embed); -static gboolean mozilla_embed_open_uri_cb (EphyEmbed *embed, +static gboolean mozilla_embed_open_uri_cb (GtkMozEmbed *embed, const char *uri, MozillaEmbed *membed); -static void mozilla_embed_file_monitor_cancel (MozillaEmbed *embed); -#if 0 -static guint popup_blocker_n_hidden (MozillaEmbed *embed); -static gboolean mozilla_embed_get_popups_allowed (MozillaEmbed *embed); -static void mozilla_embed_set_popups_allowed (MozillaEmbed *embed, - gboolean allowed); -#endif -static void mozilla_embed_file_monitor_cancel (MozillaEmbed *embed); -static void impl_set_typed_address (EphyEmbed *embed, - const char *address, - EphyEmbedAddressExpire expire); - static EphyEmbedSecurityLevel mozilla_embed_security_level (PRUint32 state); #define MOZILLA_EMBED_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), MOZILLA_TYPE_EMBED, MozillaEmbedPrivate)) @@ -135,80 +100,15 @@ typedef enum MOZILLA_EMBED_LOAD_STOPPED } MozillaEmbedLoadState; -#define MAX_HIDDEN_POPUPS 5 -#define MAX_TITLE_LENGTH 512 /* characters */ -#define RELOAD_DELAY 250 /* ms */ -#define RELOAD_DELAY_MAX_TICKS 40 /* RELOAD_DELAY * RELOAD_DELAY_MAX_TICKS = 10 s */ - struct MozillaEmbedPrivate { EphyBrowser *browser; GtkMozEmbed *moz_embed; MozillaEmbedLoadState load_state; - - EphyEmbedAddressExpire address_expire; - /* guint address_expire : 2; ? */ - EphyEmbedSecurityLevel security_level; - /* guint security_level : 3; ? */ - EphyEmbedDocumentType document_type; - EphyEmbedNavigationFlags nav_flags; - float zoom; - - /* Flags */ - guint is_blank : 1; - guint is_loading : 1; - guint is_setting_zoom : 1; - - gint8 load_percent; - char *address; - char *typed_address; - char *title; - char *loading_title; - int cur_requests; - int total_requests; - char *status_message; - char *link_message; - char *icon_address; - GdkPixbuf *icon; - - /* File watch */ - GnomeVFSMonitorHandle *monitor; - guint reload_scheduled_id; - guint reload_delay_ticks; - - GSList *hidden_popups; - GSList *shown_popups; }; #define WINDOWWATCHER_CONTRACTID "@mozilla.org/embedcomp/window-watcher;1" -enum -{ - PROP_0, - PROP_ADDRESS, - PROP_DOCUMENT_TYPE, - PROP_HIDDEN_POPUP_COUNT, - PROP_ICON, - PROP_ICON_ADDRESS, - PROP_LINK_MESSAGE, - PROP_LOAD_PROGRESS, - PROP_LOAD_STATUS, - PROP_NAVIGATION, - PROP_POPUPS_ALLOWED, - PROP_SECURITY, - PROP_STATUS_MESSAGE, - PROP_TITLE, - PROP_TYPED_ADDRESS, - PROP_ZOOM -}; - -typedef struct -{ - char *url; - char *name; - char *features; -} PopupInfo; - static void impl_manager_do_command (EphyCommandManager *manager, const char *command) @@ -301,108 +201,6 @@ mozilla_embed_constructor (GType type, guint n_construct_properties, } static void -mozilla_embed_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MozillaEmbed *embed = MOZILLA_EMBED (object); - MozillaEmbedPrivate *priv = embed->priv; - - switch (prop_id) - { - case PROP_ADDRESS: - g_value_set_string (value, priv->address); - break; - case PROP_DOCUMENT_TYPE: - g_value_set_enum (value, priv->document_type); - break; - case PROP_HIDDEN_POPUP_COUNT: - g_value_set_int (value, 0); - // g_value_set_int (value, popup_blocker_n_hidden (embed)); - break; - case PROP_ICON: - g_value_set_object (value, priv->icon); - break; - case PROP_ICON_ADDRESS: - g_value_set_string (value, priv->icon_address); - break; - case PROP_LINK_MESSAGE: - g_value_set_string (value, priv->link_message); - break; - case PROP_LOAD_PROGRESS: - g_value_set_int (value, priv->load_percent); - break; - case PROP_LOAD_STATUS: - g_value_set_boolean (value, priv->is_loading); - break; - case PROP_NAVIGATION: - g_value_set_flags (value, priv->nav_flags); - break; - case PROP_POPUPS_ALLOWED: - g_value_set_boolean (value, FALSE); - // g_value_set_boolean (value, mozilla_embed_get_popups_allowed (embed)); - break; - case PROP_SECURITY: - g_value_set_enum (value, priv->security_level); - break; - case PROP_STATUS_MESSAGE: - g_value_set_string (value, priv->status_message); - break; - case PROP_TITLE: - g_value_set_string (value, priv->title); - break; - case PROP_TYPED_ADDRESS: - g_value_set_string (value, priv->typed_address); - break; - case PROP_ZOOM: - g_value_set_float (value, priv->zoom); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - -} - -static void -mozilla_embed_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - case PROP_ICON_ADDRESS: - mozilla_embed_set_icon_address (MOZILLA_EMBED (object), g_value_get_string (value)); - break; - case PROP_TYPED_ADDRESS: - impl_set_typed_address (EPHY_EMBED (object), g_value_get_string (value), - EPHY_EMBED_ADDRESS_EXPIRE_NOW); - break; - case PROP_POPUPS_ALLOWED: - //mozilla_embed_set_popups_allowed (MOZILLA_EMBED (object), g_value_get_boolean (value)); - break; - case PROP_ADDRESS: - case PROP_DOCUMENT_TYPE: - case PROP_HIDDEN_POPUP_COUNT: - case PROP_ICON: - case PROP_LOAD_PROGRESS: - case PROP_LOAD_STATUS: - case PROP_LINK_MESSAGE: - case PROP_NAVIGATION: - case PROP_SECURITY: - case PROP_STATUS_MESSAGE: - case PROP_ZOOM: - /* read only */ - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void mozilla_embed_class_init (MozillaEmbedClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -411,38 +209,18 @@ mozilla_embed_class_init (MozillaEmbedClass *klass) object_class->constructor = mozilla_embed_constructor; object_class->finalize = mozilla_embed_finalize; - object_class->dispose = mozilla_embed_dispose; - object_class->get_property = mozilla_embed_get_property; - object_class->set_property = mozilla_embed_set_property; gtk_object_class->destroy = mozilla_embed_destroy; widget_class->grab_focus = mozilla_embed_grab_focus; widget_class->realize = mozilla_embed_realize; - g_object_class_override_property (object_class, PROP_DOCUMENT_TYPE, "document-type"); - g_object_class_override_property (object_class, PROP_SECURITY, "security-level"); - g_object_class_override_property (object_class, PROP_ZOOM, "zoom"); - g_object_class_override_property (object_class, PROP_LOAD_PROGRESS, "load-progress"); - g_object_class_override_property (object_class, PROP_LOAD_STATUS, "load-status"); - g_object_class_override_property (object_class, PROP_NAVIGATION, "navigation"); - g_object_class_override_property (object_class, PROP_ADDRESS, "address"); - g_object_class_override_property (object_class, PROP_TYPED_ADDRESS, "typed-address"); - g_object_class_override_property (object_class, PROP_TITLE, "title"); - g_object_class_override_property (object_class, PROP_STATUS_MESSAGE, "status-message"); - g_object_class_override_property (object_class, PROP_LINK_MESSAGE, "link-message"); - g_object_class_override_property (object_class, PROP_ICON, "icon"); - g_object_class_override_property (object_class, PROP_ICON_ADDRESS, "icon-address"); - g_object_class_override_property (object_class, PROP_POPUPS_ALLOWED, "popups-allowed"); - g_object_class_override_property (object_class, PROP_HIDDEN_POPUP_COUNT, "hidden-popup-count"); - g_type_class_add_private (object_class, sizeof(MozillaEmbedPrivate)); } static void mozilla_embed_init (MozillaEmbed *membed) { - EphyFaviconCache *cache; MozillaEmbedPrivate *priv; GtkWidget *embed; @@ -477,49 +255,15 @@ mozilla_embed_init (MozillaEmbed *membed) g_signal_connect_object (embed, "security_change", G_CALLBACK (mozilla_embed_security_change_cb), membed, (GConnectFlags) 0); - g_signal_connect_object (membed, "ge_document_type", - G_CALLBACK (mozilla_embed_document_type_cb), - membed, (GConnectFlags) 0); - g_signal_connect_object (membed, "ge_zoom_change", - G_CALLBACK (mozilla_embed_zoom_change_cb), - embed, (GConnectFlags) 0); g_signal_connect_object (embed, "title", G_CALLBACK (mozilla_embed_title_change_cb), membed, (GConnectFlags) 0); g_signal_connect_object (embed, "link_message", G_CALLBACK (mozilla_embed_link_message_cb), membed, (GConnectFlags)0); - g_signal_connect_object (membed, "ge_favicon", - G_CALLBACK (mozilla_embed_favicon_cb), - embed, (GConnectFlags)0); g_signal_connect_object (embed, "open_uri", G_CALLBACK (mozilla_embed_open_uri_cb), membed,(GConnectFlags) 0); - - cache = EPHY_FAVICON_CACHE - (ephy_embed_shell_get_favicon_cache (embed_shell)); - g_signal_connect_object (G_OBJECT (cache), "changed", - G_CALLBACK (mozilla_embed_icon_cache_changed_cb), - membed, (GConnectFlags)0); - - priv->document_type = EPHY_EMBED_DOCUMENT_HTML; - priv->security_level = EPHY_EMBED_STATE_IS_UNKNOWN; - priv->zoom = 1.0; - priv->is_setting_zoom = FALSE; - priv->load_percent = 0; - priv->is_loading = FALSE; - priv->typed_address = NULL; - priv->address = NULL; - priv->address_expire = EPHY_EMBED_ADDRESS_EXPIRE_NOW; - priv->title = NULL; - priv->loading_title = NULL; - priv->is_blank = TRUE; - priv->total_requests = 0; - priv->cur_requests = 0; - priv->icon_address = NULL; - priv->icon = NULL; - priv->status_message = NULL; - priv->link_message = NULL; } gpointer @@ -544,14 +288,6 @@ mozilla_embed_destroy (GtkObject *object) } static void -mozilla_embed_dispose (GObject *object) -{ - mozilla_embed_file_monitor_cancel (MOZILLA_EMBED (object)); - - G_OBJECT_CLASS (mozilla_embed_parent_class)->dispose (object); -} - -static void mozilla_embed_finalize (GObject *object) { MozillaEmbed *embed = MOZILLA_EMBED (object); @@ -562,337 +298,11 @@ mozilla_embed_finalize (GObject *object) embed->priv->browser = nsnull; } - if (embed->priv->icon != NULL) - { - g_object_unref (embed->priv->icon); - embed->priv->icon = NULL; - } - -#if 0 - popups_manager_reset (embed); -#endif - - g_free (embed->priv->icon_address); - g_free (embed->priv->address); - g_free (embed->priv->typed_address); - g_free (embed->priv->title); - g_free (embed->priv->loading_title); - g_free (embed->priv->status_message); - g_free (embed->priv->link_message); - G_OBJECT_CLASS (mozilla_embed_parent_class)->finalize (object); g_object_unref (embed_shell); } -#if 0 -static void -ephy_tab_content_change_cb (EphyEmbed *embed, const char *address, EphyTab *tab) -{ - popups_manager_reset (tab); - g_object_notify (G_OBJECT (tab), "popups-allowed"); -} - -static void -ephy_tab_new_window_cb (EphyEmbed *embed, - EphyEmbed *new_embed, - EphyTab *tab) -{ - EphyWindow *window; - - g_return_if_fail (new_embed != NULL); - - window = EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (new_embed))); - g_return_if_fail (window != NULL); - - popups_manager_add_window (tab, window); -} - -static void -ephy_tab_popup_blocked_cb (EphyEmbed *embed, - const char *url, - const char *name, - const char *features, - EphyTab *tab) -{ - popups_manager_add (tab, url, name, features); -} - -static void -popups_manager_free_info (PopupInfo *popup) -{ - g_free (popup->url); - g_free (popup->name); - g_free (popup->features); - g_free (popup); -} - -static void -popups_manager_add (MozillaEmbed *embed, - const char *url, - const char *name, - const char *features) -{ - MozillaEmbedPrivate *priv = embed->priv; - PopupInfo *popup; - - LOG ("popups_manager_add: embed %p, url %s, features %s", - embed, url, features); - - popup = g_new0 (PopupInfo, 1); - - popup->url = (url == NULL) ? NULL : g_strdup (url); - popup->name = g_strdup (name); - popup->features = g_strdup (features); - - priv->hidden_popups = g_slist_prepend (priv->hidden_popups, popup); - - if (popup_blocker_n_hidden (embed) > MAX_HIDDEN_POPUPS) /* bug #160863 */ - { - /* Remove the oldest popup */ - GSList *l = embed->priv->hidden_popups; - - while (l->next->next != NULL) - { - l = l->next; - } - - popup = (PopupInfo *) l->next->data; - popups_manager_free_info (popup); - - l->next = NULL; - } - else - { - g_object_notify (G_OBJECT (embed), "hidden-popup-count"); - } -} - -static gboolean -popups_manager_remove_window (MozillaEmbed *embed, - EphyWindow *window) -{ - embed->priv->shown_popups = g_slist_remove (embed->priv->shown_popups, - window); - - return FALSE; -} - -static void -disconnect_popup (EphyWindow *window, - MozillaEmbed *embed) -{ - g_signal_handlers_disconnect_by_func - (window, G_CALLBACK (popups_manager_remove_window), embed); -} - -static void -popups_manager_add_window (MozillaEmbed *embed, - EphyWindow *window) -{ - LOG ("popups_manager_add_window: embed %p, window %p", embed, window); - - embed->priv->shown_popups = g_slist_prepend - (embed->priv->shown_popups, window); - - g_signal_connect_swapped (window, "destroy", - G_CALLBACK (popups_manager_remove_window), - embed); -} - -static gboolean -mozilla_embed_get_popups_allowed (MozillaEmbed *embed) -{ - EphyPermissionManager *permission_manager; - EphyPermission response; - EphyEmbed *embed; - char *location; - gboolean allow; - - permission_manager = EPHY_PERMISSION_MANAGER - (ephy_embed_shell_get_embed_single (embed_shell)); - g_return_val_if_fail (EPHY_IS_PERMISSION_MANAGER (permission_manager), - FALSE); - - location = ephy_embed_get_location (embed, TRUE); - if (location == NULL) return FALSE; /* FALSE, TRUE… same thing */ - - response = ephy_permission_manager_test_permission - (permission_manager, location, EPT_POPUP); - - switch (response) - { - case EPHY_PERMISSION_ALLOWED: - allow = TRUE; - break; - case EPHY_PERMISSION_DENIED: - allow = FALSE; - break; - case EPHY_PERMISSION_DEFAULT: - default: - allow = eel_gconf_get_boolean - (CONF_SECURITY_ALLOW_POPUPS); - break; - } - - g_free (location); - - LOG ("mozilla_embed_get_popups_allowed: embed %p, allowed: %d", embed, allow); - - return allow; -} - -static void -popups_manager_show (PopupInfo *popup, - MozillaEmbed *embed) -{ - EphyEmbed *embed; - EphyEmbedSingle *single; - - /* Only show popup with non NULL url */ - if (popup->url != NULL) - { - embed = ephy_embed_get_embed (embed); - - single = EPHY_EMBED_SINGLE - (ephy_embed_shell_get_embed_single (embed_shell)); - - ephy_embed_single_open_window (single, embed, popup->url, - popup->name, popup->features); - } - popups_manager_free_info (popup); -} - -static void -popups_manager_show_all (MozillaEmbed *embed) -{ - LOG ("popup_blocker_show_all: embed %p", embed); - - g_slist_foreach (embed->priv->hidden_popups, - (GFunc) popups_manager_show, embed); - g_slist_free (embed->priv->hidden_popups); - embed->priv->hidden_popups = NULL; - - g_object_notify (G_OBJECT (embed), "hidden-popup-count"); -} - -static char * -popups_manager_new_window_info (EphyWindow *window) -{ - MozillaEmbed *embed; - EphyEmbedChrome chrome; - gboolean is_popup; - char *features; - - g_object_get (window, "chrome", &chrome, "is-popup", &is_popup, NULL); - g_return_val_if_fail (is_popup, g_strdup ("")); - - embed = ephy_window_get_active_embed (window); - g_return_val_if_fail (embed != NULL, g_strdup ("")); - - features = g_strdup_printf - ("width=%d,height=%d,menubar=%d,status=%d,toolbar=%d", - embed->priv->width, embed->priv->height, - (chrome & EPHY_EMBED_CHROME_MENUBAR) > 0, - (chrome & EPHY_EMBED_CHROME_STATUSBAR) > 0, - (chrome & EPHY_EMBED_CHROME_TOOLBAR) > 0); - - return features; -} - -static void -popups_manager_hide (EphyWindow *window, - MozillaEmbed *parent_embed) -{ - EphyEmbed *embed; - char *location; - char *features; - - embed = ephy_window_get_active_embed (window); - g_return_if_fail (EPHY_IS_EMBED (embed)); - - location = ephy_embed_get_location (embed, TRUE); - if (location == NULL) return; - - features = popups_manager_new_window_info (window); - - popups_manager_add (parent_embed, location, "" /* FIXME? maybe _blank? */, features); - - gtk_widget_destroy (GTK_WIDGET (window)); - - g_free (location); - g_free (features); -} - -static void -popups_manager_hide_all (MozillaEmbed *embed) -{ - LOG ("popup_blocker_hide_all: embed %p", embed); - - g_slist_foreach (embed->priv->shown_popups, - (GFunc) popups_manager_hide, embed); - g_slist_free (embed->priv->shown_popups); - embed->priv->shown_popups = NULL; -} - -static void -mozilla_embed_set_popups_allowed (MozillaEmbed *embed, - gboolean allowed) -{ - char *location; - EphyEmbed *embed; - EphyPermissionManager *manager; - EphyPermission permission; - - embed = ephy_embed_get_embed (embed); - - location = ephy_embed_get_location (embed, TRUE); - g_return_if_fail (location != NULL); - - manager = EPHY_PERMISSION_MANAGER - (ephy_embed_shell_get_embed_single (embed_shell)); - g_return_if_fail (EPHY_IS_PERMISSION_MANAGER (manager)); - - permission = allowed ? EPHY_PERMISSION_ALLOWED - : EPHY_PERMISSION_DENIED; - - ephy_permission_manager_add_permission (manager, location, EPT_POPUP, permission); - - if (allowed) - { - popups_manager_show_all (embed); - } - else - { - popups_manager_hide_all (embed); - } - - g_free (location); -} - -static guint -popup_blocker_n_hidden (MozillaEmbed *embed) -{ - return g_slist_length (embed->priv->hidden_popups); -} - -static void -popups_manager_reset (MozillaEmbed *embed) -{ - g_slist_foreach (embed->priv->hidden_popups, - (GFunc) popups_manager_free_info, NULL); - g_slist_free (embed->priv->hidden_popups); - embed->priv->hidden_popups = NULL; - - g_slist_foreach (embed->priv->shown_popups, - (GFunc) disconnect_popup, embed); - g_slist_free (embed->priv->shown_popups); - embed->priv->shown_popups = NULL; - - g_object_notify (G_OBJECT (embed), "hidden-popup-count"); -} -#endif - static void impl_load_url (EphyEmbed *embed, const char *url) @@ -934,7 +344,7 @@ impl_load (EphyEmbed *embed, else #endif /* HAVE_GECKO_1_8_1 */ { - browser->LoadURI (url, nsIWebNavigation::LOAD_FLAGS_NONE, uri); + browser->LoadURI (url, nsIWebNavigation::LOAD_FLAGS_NONE, uri); } } @@ -1078,12 +488,6 @@ impl_go_up (EphyEmbed *embed) ephy_embed_load_url (embed, parent_uri.get ()); } -static const char * -impl_get_title (EphyEmbed *embed) -{ - return MOZILLA_EMBED (embed)->priv->title; -} - static char * impl_get_js_status (EphyEmbed *embed) { @@ -1426,436 +830,19 @@ impl_has_modified_forms (EphyEmbed *embed) return NS_SUCCEEDED (rv) ? modified : FALSE; } -static EphyEmbedDocumentType -impl_get_document_type (EphyEmbed *embed) -{ - MozillaEmbedPrivate *mpriv = MOZILLA_EMBED(embed)->priv; - - return mpriv->document_type; -} - -static int -impl_get_load_percent (EphyEmbed *embed) -{ - MozillaEmbedPrivate *mpriv = MOZILLA_EMBED(embed)->priv; - - return mpriv->load_percent; -} - -static void -mozilla_embed_set_load_percent (MozillaEmbed *embed, int percent) -{ - MozillaEmbedPrivate *mpriv = embed->priv; - - if (percent != mpriv->load_percent) - { - mpriv->load_percent = percent; - - g_object_notify (G_OBJECT (embed), "load-progress"); - } -} - -static gboolean -impl_get_load_status (EphyEmbed *embed) -{ - MozillaEmbedPrivate *mpriv = MOZILLA_EMBED(embed)->priv; - - return mpriv->is_loading; -} - -static void -mozilla_embed_set_load_status (MozillaEmbed *embed, gboolean status) -{ - MozillaEmbedPrivate *mpriv = embed->priv; - guint is_loading; - - is_loading = status != FALSE; - - if (is_loading != mpriv->is_loading) - { - mpriv->is_loading = is_loading; - - g_object_notify (G_OBJECT (embed), "load-status"); - } -} - -static void -mozilla_embed_update_navigation_flags (MozillaEmbed *membed) -{ - MozillaEmbedPrivate *priv = membed->priv; - EphyEmbed *embed = EPHY_EMBED (membed); - guint flags = 0; - - if (impl_can_go_up (embed)) - { - flags |= EPHY_EMBED_NAV_UP; - } - - if (impl_can_go_back (embed)) - { - flags |= EPHY_EMBED_NAV_BACK; - } - - if (impl_can_go_forward (embed)) - { - flags |= EPHY_EMBED_NAV_FORWARD; - } - - if (priv->nav_flags != (EphyEmbedNavigationFlags)flags) - { - priv->nav_flags = (EphyEmbedNavigationFlags)flags; - - g_object_notify (G_OBJECT (embed), "navigation"); - } -} - -static EphyEmbedNavigationFlags -impl_get_navigation_flags (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - return priv->nav_flags; -} - -static const char* -impl_get_typed_address (EphyEmbed *embed) -{ - return MOZILLA_EMBED (embed)->priv->typed_address; -} - -static void -impl_set_typed_address (EphyEmbed *embed, - const char *address, - EphyEmbedAddressExpire expire) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - g_free (priv->typed_address); - priv->typed_address = g_strdup (address); - - if (expire == EPHY_EMBED_ADDRESS_EXPIRE_CURRENT && - !priv->is_loading) - { - priv->address_expire = EPHY_EMBED_ADDRESS_EXPIRE_NOW; - } - else - { - priv->address_expire = expire; - } - - g_object_notify (G_OBJECT (embed), "typed-address"); -} - -static const char* -impl_get_address (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - return priv->address ? priv->address : "about:blank"; -} - -static const char* -impl_get_status_message (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - if (priv->link_message && priv->link_message[0] != '\0') - { - return priv->link_message; - } - else if (priv->status_message) - { - return priv->status_message; - } - else - { - return NULL; - } -} - -static const char* -impl_get_link_message (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - return priv->link_message; -} - -static gboolean -impl_get_is_blank (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - return priv->is_blank; -} - -static const char* -impl_get_loading_title (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - return priv->loading_title; -} - -static const char* -impl_get_icon_address (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - return priv->icon_address; -} - -static GdkPixbuf* -impl_get_icon (EphyEmbed *embed) -{ - MozillaEmbedPrivate *priv = MOZILLA_EMBED (embed)->priv; - - return priv->icon; -} - -static void -mozilla_embed_set_address (MozillaEmbed *embed, char *address) -{ - MozillaEmbedPrivate *priv = embed->priv; - GObject *object = G_OBJECT (embed); - - g_free (priv->address); - priv->address = address; - - priv->is_blank = address == NULL || - strcmp (address, "about:blank") == 0; - - if (priv->is_loading && - priv->address_expire == EPHY_EMBED_ADDRESS_EXPIRE_NOW && - priv->typed_address != NULL) - { - g_free (priv->typed_address); - priv->typed_address = NULL; - - g_object_notify (object, "typed-address"); - } - - g_object_notify (object, "address"); -} - -static void -mozilla_embed_file_monitor_cancel (MozillaEmbed *embed) -{ - MozillaEmbedPrivate *priv = embed->priv; - - if (priv->monitor != NULL) - { - LOG ("Cancelling file monitor"); - - gnome_vfs_monitor_cancel (priv->monitor); - priv->monitor = NULL; - } - - if (priv->reload_scheduled_id != 0) - { - LOG ("Cancelling scheduled reload"); - - g_source_remove (priv->reload_scheduled_id); - priv->reload_scheduled_id = 0; - } - - priv->reload_delay_ticks = 0; -} - -static gboolean -ephy_file_monitor_reload_cb (MozillaEmbed *embed) -{ - MozillaEmbedPrivate *priv = embed->priv; - - if (priv->reload_delay_ticks > 0) - { - priv->reload_delay_ticks--; - - /* Run again */ - return TRUE; - } - - if (priv->is_loading) - { - /* Wait a bit to reload if we're still loading! */ - priv->reload_delay_ticks = RELOAD_DELAY_MAX_TICKS / 2; - - /* Run again */ - return TRUE; - } - - priv->reload_scheduled_id = 0; - - //LOG ("Reloading file '%s'", impl_get_address (embed)); - - impl_reload (EPHY_EMBED (embed), TRUE); - - /* don't run again */ - return FALSE; -} - -static void -mozilla_embed_file_monitor_cb (GnomeVFSMonitorHandle *handle, - const gchar *monitor_uri, - const gchar *info_uri, - GnomeVFSMonitorEventType event_type, - MozillaEmbed *embed) -{ - gboolean uri_is_directory; - gboolean should_reload; - char* local_path; - MozillaEmbedPrivate *priv = embed->priv; - - LOG ("File '%s' has changed, scheduling reload", monitor_uri); - - local_path = gnome_vfs_get_local_path_from_uri(monitor_uri); - uri_is_directory = g_file_test(local_path, G_FILE_TEST_IS_DIR); - g_free(local_path); - - switch (event_type) - { - /* These events will always trigger a reload: */ - case GNOME_VFS_MONITOR_EVENT_CHANGED: - case GNOME_VFS_MONITOR_EVENT_CREATED: - should_reload = TRUE; - break; - - /* These events will only trigger a reload for directories: */ - case GNOME_VFS_MONITOR_EVENT_DELETED: - case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: - should_reload = uri_is_directory; - break; - - /* These events don't trigger a reload: */ - case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: - case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: - default: - should_reload = FALSE; - break; - } - - if (should_reload) { - /* We make a lot of assumptions here, but basically we know - * that we just have to reload, by construction. - * Delay the reload a little bit so we don't endlessly - * reload while a file is written. - */ - if (priv->reload_delay_ticks == 0) - { - priv->reload_delay_ticks = 1; - } - else - { - /* Exponential backoff */ - priv->reload_delay_ticks = MIN (priv->reload_delay_ticks * 2, - RELOAD_DELAY_MAX_TICKS); - } - - if (priv->reload_scheduled_id == 0) - { - priv->reload_scheduled_id = - g_timeout_add (RELOAD_DELAY, - (GSourceFunc) ephy_file_monitor_reload_cb, embed); - } - } -} - -static void -mozilla_embed_update_file_monitor (MozillaEmbed *embed, - const gchar *address) -{ - MozillaEmbedPrivate *priv = embed->priv; - GnomeVFSMonitorHandle *handle = NULL; - gboolean local; - char* local_path; - GnomeVFSMonitorType monitor_type; - - if (priv->monitor != NULL && - priv->address != NULL && address != NULL && - strcmp (priv->address, address) == 0) - - { - /* same address, no change needed */ - return; - } - - mozilla_embed_file_monitor_cancel (embed); - - local = g_str_has_prefix (address, "file://"); - if (local == FALSE) return; - - local_path = gnome_vfs_get_local_path_from_uri(address); - monitor_type = g_file_test(local_path, G_FILE_TEST_IS_DIR) - ? GNOME_VFS_MONITOR_DIRECTORY - : GNOME_VFS_MONITOR_FILE; - g_free(local_path); - - if (gnome_vfs_monitor_add (&handle, address, - monitor_type, - (GnomeVFSMonitorCallback) mozilla_embed_file_monitor_cb, - embed) == GNOME_VFS_OK) - { - LOG ("Installed monitor for file '%s'", address); - - priv->monitor = handle; - } -} - -static void -mozilla_embed_set_link_message (MozillaEmbed *embed, - char *link_message) -{ - MozillaEmbedPrivate *priv = embed->priv; - - g_free (priv->link_message); - - priv->link_message = ephy_embed_utils_link_message_parse (link_message); - - g_object_notify (G_OBJECT (embed), "status-message"); - g_object_notify (G_OBJECT (embed), "link-message"); -} - static void mozilla_embed_location_changed_cb (GtkMozEmbed *embed, MozillaEmbed *membed) { char *location; - GObject *object = G_OBJECT (membed); + EphyBaseEmbed *bembed = EPHY_BASE_EMBED (membed); location = gtk_moz_embed_get_location (embed); g_signal_emit_by_name (membed, "ge_location", location); - g_object_freeze_notify (object); - - /* do this up here so we still have the old address around */ - mozilla_embed_update_file_monitor (membed, location); - - /* Do not expose about:blank to the user, an empty address - bar will do better */ - if (location == NULL || location[0] == '\0' || - strcmp (location, "about:blank") == 0) - { - mozilla_embed_set_address (membed, NULL); - mozilla_embed_set_title (membed, NULL); - } - else - { - char *embed_address; - - /* we do this to get rid of an eventual password in the URL */ - embed_address = impl_get_location (EPHY_EMBED (membed), TRUE); - mozilla_embed_set_address (membed, embed_address); - mozilla_embed_set_loading_title (membed, embed_address, TRUE); - } + ephy_base_embed_location_changed (bembed, location); g_free (location); - - mozilla_embed_set_link_message (membed, NULL); - mozilla_embed_set_icon_address (membed, NULL); - mozilla_embed_update_navigation_flags (membed); - - g_object_notify (object, "title"); - - g_object_thaw_notify (object); } static void @@ -1863,144 +850,11 @@ mozilla_embed_link_message_cb (GtkMozEmbed *embed, MozillaEmbed *membed) { char *link_message = gtk_moz_embed_get_link_message (embed); - mozilla_embed_set_link_message (membed, link_message); + ephy_base_embed_set_link_message (EPHY_BASE_EMBED (membed), link_message); g_free (link_message); } static void -mozilla_embed_load_icon (MozillaEmbed *embed) -{ - MozillaEmbedPrivate *priv = embed->priv; - EphyEmbedShell *shell; - EphyFaviconCache *cache; - - if (priv->icon_address == NULL || priv->icon != NULL) return; - - shell = ephy_embed_shell_get_default (); - cache = EPHY_FAVICON_CACHE (ephy_embed_shell_get_favicon_cache (shell)); - - /* ephy_favicon_cache_get returns a reference already */ - priv->icon = ephy_favicon_cache_get (cache, priv->icon_address); - - g_object_notify (G_OBJECT (embed), "icon"); -} - -static void -mozilla_embed_icon_cache_changed_cb (EphyFaviconCache *cache, - const char *address, - MozillaEmbed *embed) -{ - MozillaEmbedPrivate *priv = embed->priv; - - g_return_if_fail (address != NULL); - - /* is this for us? */ - if (priv->icon_address != NULL && - strcmp (priv->icon_address, address) == 0) - { - mozilla_embed_load_icon (embed); - } -} - -static void -mozilla_embed_set_icon_address (MozillaEmbed *embed, - const char *address) -{ - GObject *object = G_OBJECT (embed); - MozillaEmbedPrivate *priv = embed->priv; - /* EphyBookmarks *eb;*/ - EphyHistory *history; - - g_free (priv->icon_address); - priv->icon_address = g_strdup (address); - - if (priv->icon != NULL) - { - g_object_unref (priv->icon); - priv->icon = NULL; - - g_object_notify (object, "icon"); - } - - if (priv->icon_address) - { - /* FIXME: we need to put this somewhere inside src?/ - history = EPHY_HISTORY - (ephy_embed_shell_get_global_history (embed_shell)); - ephy_history_set_icon (history, priv->address, - priv->icon_address); - - eb = ephy_shell_get_bookmarks (ephy_shell); - ephy_bookmarks_set_icon (eb, priv->address, - priv->icon_address);*/ - - mozilla_embed_load_icon (embed); - } - - g_object_notify (object, "icon-address"); -} - -static void -mozilla_embed_favicon_cb (MozillaEmbed *membed, - const char *address, - GtkMozEmbed *embed) -{ - mozilla_embed_set_icon_address (membed, address); -} - -static gboolean -address_has_web_scheme (const char *address) -{ - gboolean has_web_scheme; - - if (address == NULL) return FALSE; - - has_web_scheme = (g_str_has_prefix (address, "http:") || - g_str_has_prefix (address, "https:") || - g_str_has_prefix (address, "ftp:") || - g_str_has_prefix (address, "file:") || - g_str_has_prefix (address, "data:") || - g_str_has_prefix (address, "about:") || - g_str_has_prefix (address, "gopher:")); - - return has_web_scheme; -} - -static void -mozilla_embed_restore_zoom_level (MozillaEmbed *membed, const char *address) -{ - MozillaEmbedPrivate *priv = membed->priv; - - /* restore zoom level */ - if (address_has_web_scheme (address)) - { - EphyHistory *history; - EphyNode *host; - GValue value = { 0, }; - float zoom = 1.0, current_zoom; - - history = EPHY_HISTORY - (ephy_embed_shell_get_global_history (embed_shell)); - host = ephy_history_get_host (history, address); - - if (host != NULL && ephy_node_get_property - (host, EPHY_NODE_HOST_PROP_ZOOM, &value)) - { - zoom = g_value_get_float (&value); - g_value_unset (&value); - } - - current_zoom = ephy_embed_get_zoom (EPHY_EMBED (membed)); - if (zoom != current_zoom) - { - priv->is_setting_zoom = TRUE; - ephy_embed_set_zoom (EPHY_EMBED (membed), zoom); - priv->is_setting_zoom = FALSE; - } - } -} - -static void update_load_state (MozillaEmbed *membed, gint state) { MozillaEmbedPrivate *priv = membed->priv; @@ -2021,7 +875,7 @@ update_load_state (MozillaEmbed *membed, gint state) char *address; address = gtk_moz_embed_get_location (moz_embed); g_signal_emit_by_name (membed, "ge-content-change", address); - mozilla_embed_restore_zoom_level (membed, address); + ephy_base_embed_restore_zoom_level (EPHY_BASE_EMBED (membed), address); g_free (address); } @@ -2050,7 +904,7 @@ update_load_state (MozillaEmbed *membed, gint state) char *address; address = gtk_moz_embed_get_location (moz_embed); g_signal_emit_by_name (membed, "ge_content_change", address); - mozilla_embed_restore_zoom_level (membed, address); + ephy_base_embed_restore_zoom_level (EPHY_BASE_EMBED (membed), address); g_free (address); } } @@ -2062,187 +916,6 @@ update_load_state (MozillaEmbed *membed, gint state) } static void -update_net_state_message (MozillaEmbed *embed, const char *uri, EphyEmbedNetState flags) -{ - GnomeVFSURI *vfs_uri = NULL; - const char *msg = NULL; - const char *host = NULL; - - if (uri != NULL) - { - vfs_uri = gnome_vfs_uri_new (uri); - } - - if (vfs_uri != NULL) - { - host = gnome_vfs_uri_get_host_name (vfs_uri); - } - - if (host == NULL || host[0] == '\0') goto out; - - /* IS_REQUEST and IS_NETWORK can be both set */ - if (flags & EPHY_EMBED_STATE_IS_REQUEST) - { - if (flags & EPHY_EMBED_STATE_REDIRECTING) - { - msg = _("Redirecting to “%s”…"); - } - else if (flags & EPHY_EMBED_STATE_TRANSFERRING) - { - msg = _("Transferring data from “%s”…"); - } - else if (flags & EPHY_EMBED_STATE_NEGOTIATING) - { - msg = _("Waiting for authorization from “%s”…"); - } - } - - if (flags & EPHY_EMBED_STATE_IS_NETWORK) - { - if (flags & EPHY_EMBED_STATE_START) - { - msg = _("Loading “%s”…"); - } - } - - if ((flags & EPHY_EMBED_STATE_IS_NETWORK) && - (flags & EPHY_EMBED_STATE_STOP)) - { - g_free (embed->priv->status_message); - embed->priv->status_message = NULL; - g_object_notify (G_OBJECT (embed), "status-message"); - - } - else if (msg != NULL) - { - g_free (embed->priv->status_message); - g_free (embed->priv->loading_title); - embed->priv->status_message = g_strdup_printf (msg, host); - embed->priv->loading_title = g_strdup_printf (msg, host); - g_object_notify (G_OBJECT (embed), "status-message"); - g_object_notify (G_OBJECT (embed), "title"); - } - -out: - if (vfs_uri != NULL) - { - gnome_vfs_uri_unref (vfs_uri); - } -} - -static int -build_load_percent (int requests_done, int requests_total) -{ - int percent= 0; - - if (requests_total > 0) - { - percent = (requests_done * 100) / requests_total; - - /* Mozilla sometimes report more done requests than - total requests. Their progress widget clamp the value */ - percent = CLAMP (percent, 0, 100); - } - - return percent; -} - -static void -build_progress_from_requests (MozillaEmbed *embed, EphyEmbedNetState state) -{ - int load_percent; - - if (state & EPHY_EMBED_STATE_IS_REQUEST) - { - if (state & EPHY_EMBED_STATE_START) - { - embed->priv->total_requests ++; - } - else if (state & EPHY_EMBED_STATE_STOP) - { - embed->priv->cur_requests ++; - } - - load_percent = build_load_percent (embed->priv->cur_requests, - embed->priv->total_requests); - - mozilla_embed_set_load_percent (embed, load_percent); - } -} - -static void -ensure_page_info (MozillaEmbed *embed, const char *address) -{ - MozillaEmbedPrivate *priv = embed->priv; - - if ((priv->address == NULL || priv->address[0] == '\0') && - priv->address_expire == EPHY_EMBED_ADDRESS_EXPIRE_NOW) - { - mozilla_embed_set_address (embed, g_strdup (address)); - } - - /* FIXME huh?? */ - if (priv->title == NULL || priv->title[0] == '\0') - { - mozilla_embed_set_title (embed, NULL); - } -} - -static void -update_embed_from_net_state (MozillaEmbed *embed, - const char *uri, - EphyEmbedNetState state) -{ - MozillaEmbedPrivate *priv = embed->priv; - - update_net_state_message (embed, uri, state); - - if (state & EPHY_EMBED_STATE_IS_NETWORK) - { - if (state & EPHY_EMBED_STATE_START) - { - GObject *object = G_OBJECT (embed); - - g_object_freeze_notify (object); - - priv->total_requests = 0; - priv->cur_requests = 0; - - mozilla_embed_set_load_percent (embed, 0); - mozilla_embed_set_load_status (embed, TRUE); - - ensure_page_info (embed, uri); - - g_object_notify (object, "title"); - - g_object_thaw_notify (object); - } - else if (state & EPHY_EMBED_STATE_STOP) - { - GObject *object = G_OBJECT (embed); - - g_object_freeze_notify (object); - - mozilla_embed_set_load_percent (embed, 100); - mozilla_embed_set_load_status (embed, FALSE); - - g_free (priv->loading_title); - priv->loading_title = NULL; - - priv->address_expire = EPHY_EMBED_ADDRESS_EXPIRE_NOW; - - g_object_notify (object, "title"); - - g_object_thaw_notify (object); - } - - mozilla_embed_update_navigation_flags (embed); - } - - build_progress_from_requests (embed, state); -} - -static void mozilla_embed_net_state_all_cb (GtkMozEmbed *embed, const char *aURI, gint state, guint status, MozillaEmbed *membed) @@ -2278,7 +951,7 @@ mozilla_embed_net_state_all_cb (GtkMozEmbed *embed, const char *aURI, } update_load_state (membed, state); - update_embed_from_net_state (membed, aURI, (EphyEmbedNetState)estate); + ephy_base_embed_update_from_net_state (EPHY_BASE_EMBED (membed), aURI, (EphyEmbedNetState)estate); g_signal_emit_by_name (membed, "ge_net_state", aURI, /* FIXME: (gulong) */ estate); } @@ -2432,161 +1105,13 @@ mozilla_embed_new_window_cb (GtkMozEmbed *embed, } static void -mozilla_embed_set_security_level (MozillaEmbed *embed, EphyEmbedSecurityLevel level) -{ - MozillaEmbedPrivate *priv = embed->priv; - - if (priv->security_level != level) - { - priv->security_level = level; - - g_object_notify (G_OBJECT (embed), "security-level"); - } -} - -static void mozilla_embed_security_change_cb (GtkMozEmbed *embed, gpointer requestptr, PRUint32 state, MozillaEmbed *membed) { - mozilla_embed_set_security_level (membed, mozilla_embed_security_level (state)); -} - -static void -mozilla_embed_document_type_cb (EphyEmbed *embed, - EphyEmbedDocumentType type, - MozillaEmbed *membed) -{ - if (membed->priv->document_type != type) - { - membed->priv->document_type = type; - - g_object_notify (G_OBJECT (membed), "document-type"); - } -} - -static void -mozilla_embed_zoom_change_cb (EphyEmbed *embed, - float zoom, - MozillaEmbed *membed) -{ - char *address; - - if (membed->priv->zoom != zoom) - { - if (membed->priv->is_setting_zoom) - { - return; - } - - address = ephy_embed_get_location (embed, TRUE); - if (address_has_web_scheme (address)) - { - EphyHistory *history; - EphyNode *host; - history = EPHY_HISTORY - (ephy_embed_shell_get_global_history (embed_shell)); - host = ephy_history_get_host (history, address); - - if (host != NULL) - { - ephy_node_set_property_float (host, - EPHY_NODE_HOST_PROP_ZOOM, - zoom); - } - } - - g_free (address); - - membed->priv->zoom = zoom; - - g_object_notify (G_OBJECT (membed), "zoom"); - } -} - -static char * -get_title_from_address (const char *address) -{ - GnomeVFSURI *uri; - char *title; - - if (address == NULL) return NULL; - - uri = gnome_vfs_uri_new (address); - if (uri == NULL) return g_strdup (address); - - title = gnome_vfs_uri_to_string (uri, - (GnomeVFSURIHideOptions) - (GNOME_VFS_URI_HIDE_USER_NAME | - GNOME_VFS_URI_HIDE_PASSWORD | - GNOME_VFS_URI_HIDE_HOST_PORT | - GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD | - GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER)); - gnome_vfs_uri_unref (uri); - - return title; -} - -static void -mozilla_embed_set_loading_title (MozillaEmbed *embed, - const char *title, - gboolean is_address) -{ - MozillaEmbedPrivate *priv = embed->priv; - char *freeme = NULL; - - g_free (priv->loading_title); - priv->loading_title = NULL; - - if (is_address) - { - title = freeme = get_title_from_address (title); - } - - if (title != NULL && title[0] != '\0') - { - /* translators: %s here is the address of the web page */ - priv->loading_title = g_strdup_printf (_("Loading “%s”…"), title); - } - else - { - priv->loading_title = g_strdup (_("Loading…")); - } - - g_free (freeme); -} - -static void -mozilla_embed_set_title (MozillaEmbed *embed, - char *title) -{ - MozillaEmbedPrivate *priv = embed->priv; - - if (!priv->is_blank && (title == NULL || g_strstrip (title)[0] == '\0')) - { - - g_free (title); - title = get_title_from_address (priv->address); - - /* Fallback */ - if (title == NULL || title[0] == '\0') - { - g_free (title); - title = NULL; - priv->is_blank = TRUE; - } - } - else if (priv->is_blank && title != NULL) - { - g_free (title); - title = NULL; - } - - g_free (priv->title); - priv->title = ephy_string_shorten (title, MAX_TITLE_LENGTH); - - g_object_notify (G_OBJECT (embed), "title"); + ephy_base_embed_set_security_level (EPHY_BASE_EMBED (membed), + mozilla_embed_security_level (state)); } static void @@ -2600,26 +1125,28 @@ mozilla_embed_title_change_cb (GtkMozEmbed *embed, g_object_freeze_notify (object); - mozilla_embed_set_title (membed, title); - mozilla_embed_set_loading_title (membed, title, FALSE); + ephy_base_embed_set_title (EPHY_BASE_EMBED (membed), title); + ephy_base_embed_set_loading_title (EPHY_BASE_EMBED (membed), + title, FALSE); g_object_thaw_notify (object); } static gboolean -mozilla_embed_open_uri_cb (EphyEmbed *embed, +mozilla_embed_open_uri_cb (GtkMozEmbed *embed, const char *uri, MozillaEmbed *membed) { - MozillaEmbedPrivate *priv = membed->priv; - /* Set the address here if we have a blank page. * See bug #147840. */ - if (priv->is_blank) + if (ephy_embed_get_is_blank (EPHY_EMBED (membed))) { - mozilla_embed_set_address (membed, g_strdup (uri)); - mozilla_embed_set_loading_title (membed, uri, TRUE); + EphyBaseEmbed *bembed = EPHY_BASE_EMBED (membed); + + + ephy_base_embed_set_address (bembed, g_strdup (uri)); + ephy_base_embed_set_loading_title (bembed, uri, TRUE); } /* allow load to proceed */ @@ -2671,9 +1198,7 @@ ephy_embed_iface_init (EphyEmbedIface *iface) iface->go_back = impl_go_back; iface->go_forward = impl_go_forward; iface->go_up = impl_go_up; - iface->get_title = impl_get_title; iface->get_location = impl_get_location; - iface->get_link_message = impl_get_link_message; iface->get_js_status = impl_get_js_status; iface->reload = impl_reload; iface->set_zoom = impl_set_zoom; @@ -2686,7 +1211,6 @@ ephy_embed_iface_init (EphyEmbedIface *iface) iface->shistory_get_pos = impl_shistory_get_pos; iface->shistory_go_nth = impl_shistory_go_nth; iface->shistory_copy = impl_shistory_copy; - iface->get_security_level = impl_get_security_level; iface->show_page_certificate = impl_show_page_certificate; iface->close = impl_close; iface->set_encoding = impl_set_encoding; @@ -2697,18 +1221,7 @@ ephy_embed_iface_init (EphyEmbedIface *iface) iface->print_preview_n_pages = impl_print_preview_n_pages; iface->print_preview_navigate = impl_print_preview_navigate; iface->has_modified_forms = impl_has_modified_forms; - iface->get_document_type = impl_get_document_type; - iface->get_load_percent = impl_get_load_percent; - iface->get_load_status = impl_get_load_status; - iface->get_navigation_flags = impl_get_navigation_flags; - iface->get_typed_address = impl_get_typed_address; - iface->set_typed_address = impl_set_typed_address; - iface->get_address = impl_get_address; - iface->get_status_message = impl_get_status_message; - iface->get_is_blank = impl_get_is_blank; - iface->get_loading_title = impl_get_loading_title; - iface->get_icon = impl_get_icon; - iface->get_icon_address = impl_get_icon_address; + iface->get_security_level = impl_get_security_level; } static void |