From 8f3aa835aa3fb12e8f9805c3ecb454027398102c Mon Sep 17 00:00:00 2001 From: Xan Lopez Date: Fri, 5 Jun 2009 16:32:55 +0300 Subject: Move all methods, signals and properties from EphyEmbed and EphyBaseEmbed to EphyWebView. Those two embed classes are pretty much dummy leftovers, so it should be easier to remove them now. --- embed/ephy-base-embed.c | 1402 +---------------------------- embed/ephy-base-embed.h | 25 - embed/ephy-embed-container.c | 10 +- embed/ephy-embed-container.h | 5 +- embed/ephy-embed-single.c | 2 +- embed/ephy-embed-single.h | 3 +- embed/ephy-embed-utils.c | 16 +- embed/ephy-embed-utils.h | 5 +- embed/ephy-embed.c | 771 ---------------- embed/ephy-embed.h | 276 ------ embed/ephy-web-view.c | 1993 +++++++++++++++++++++++++++++++++++++++++- embed/ephy-web-view.h | 192 +++- embed/webkit/webkit-embed.c | 184 +--- 13 files changed, 2239 insertions(+), 2645 deletions(-) delete mode 100644 embed/ephy-embed.c delete mode 100644 embed/ephy-embed.h (limited to 'embed') diff --git a/embed/ephy-base-embed.c b/embed/ephy-base-embed.c index c87af20dc..1d11439c9 100644 --- a/embed/ephy-base-embed.c +++ b/embed/ephy-base-embed.c @@ -42,82 +42,7 @@ #include "ephy-string.h" #include "ephy-zoom.h" -#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 */ -#define EMPTY_PAGE _("Blank page") /* Title for the empty page */ - -struct _EphyBaseEmbedPrivate { - EphyEmbedAddressExpire address_expire; - /* guint address_expire : 2; ? */ - EphyEmbedSecurityLevel security_level; - /* guint security_level : 3; ? */ - EphyEmbedDocumentType document_type; - EphyEmbedNavigationFlags nav_flags; - - /* Flags */ - guint is_blank : 1; - guint is_loading : 1; - guint visibility : 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 */ - GFileMonitor *monitor; - gboolean monitor_directory; - guint reload_scheduled_id; - guint reload_delay_ticks; - - GSList *hidden_popups; - GSList *shown_popups; -}; - -typedef struct { - char *url; - char *name; - char *features; -} PopupInfo; - -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_VISIBLE, - PROP_TYPED_ADDRESS, -}; - -#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); - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (EphyBaseEmbed, ephy_base_embed, GTK_TYPE_BIN, - G_IMPLEMENT_INTERFACE (EPHY_TYPE_EMBED, - ephy_embed_iface_init)) +G_DEFINE_TYPE (EphyBaseEmbed, ephy_base_embed, GTK_TYPE_BIN) static void ephy_base_embed_size_request (GtkWidget *widget, @@ -160,1342 +85,17 @@ ephy_base_embed_grab_focus (GtkWidget *widget) gtk_widget_grab_focus (child); } -static void -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 gboolean -impl_get_visibility (EphyEmbed *embed) -{ - return EPHY_BASE_EMBED (embed)->priv->visibility; -} - -static void -popups_manager_free_info (PopupInfo *popup) -{ - g_free (popup->url); - g_free (popup->name); - g_free (popup->features); - g_slice_free (PopupInfo, popup); -} - -static void -popups_manager_show (PopupInfo *popup, - EphyBaseEmbed *embed) -{ - EphyEmbedSingle *single; - - /* Only show popup with non NULL url */ - if (popup->url != NULL) { - single = EPHY_EMBED_SINGLE - (ephy_embed_shell_get_embed_single (embed_shell)); - - ephy_embed_single_open_window (single, EPHY_EMBED (embed), popup->url, - popup->name, popup->features); - } - popups_manager_free_info (popup); -} - -static void -popups_manager_show_all (EphyBaseEmbed *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 (EphyEmbedContainer *container) -{ - EphyEmbed *embed; - EphyEmbedChrome chrome; - gboolean is_popup; - char *features; - - g_object_get (container, "chrome", &chrome, "is-popup", &is_popup, NULL); - g_return_val_if_fail (is_popup, g_strdup ("")); - - embed = ephy_embed_container_get_active_child (container); - g_return_val_if_fail (embed != NULL, g_strdup ("")); - - features = g_strdup_printf - ("width=%d,height=%d,menubar=%d,status=%d,toolbar=%d", - GTK_WIDGET (embed)->allocation.width, - GTK_WIDGET (embed)->allocation.height, - (chrome & EPHY_EMBED_CHROME_MENUBAR) > 0, - (chrome & EPHY_EMBED_CHROME_STATUSBAR) > 0, - (chrome & EPHY_EMBED_CHROME_TOOLBAR) > 0); - - return features; -} - -static guint -popup_blocker_n_hidden (EphyBaseEmbed *embed) -{ - return g_slist_length (embed->priv->hidden_popups); -} - -static void -popups_manager_add (EphyBaseEmbed *embed, - const char *url, - const char *name, - const char *features) -{ - EphyBaseEmbedPrivate *priv = embed->priv; - PopupInfo *popup; - - LOG ("popups_manager_add: embed %p, url %s, features %s", - embed, url, features); - - popup = g_slice_new (PopupInfo); - - popup->url = 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 void -popups_manager_hide (EphyEmbedContainer *container, - EphyBaseEmbed *parent_embed) -{ - EphyEmbed *embed; - char *location; - char *features; - - embed = ephy_embed_container_get_active_child (container); - 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 (container); - - popups_manager_add (parent_embed, location, "" /* FIXME? maybe _blank? */, features); - - gtk_widget_destroy (GTK_WIDGET (container)); - - g_free (location); - g_free (features); -} - -static void -popups_manager_hide_all (EphyBaseEmbed *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 -ephy_base_embed_set_popups_allowed (EphyBaseEmbed *embed, - gboolean allowed) -{ - char *location; - EphyPermissionManager *manager; - EphyPermission permission; - - location = ephy_embed_get_location (EPHY_EMBED (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 void -ephy_base_embed_set_property (GObject *object, - guint prop_id, - 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 (EPHY_BASE_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_VISIBLE: - /* read only */ - break; - default: - break; - } -} - -static gboolean -ephy_base_embed_get_popups_allowed (EphyBaseEmbed *embed) -{ - EphyPermissionManager *permission_manager; - EphyPermission response; - 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 (EPHY_EMBED (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 ("ephy_base_embed_get_popups_allowed: embed %p, allowed: %d", embed, allow); - - return allow; -} - -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, popup_blocker_n_hidden - (EPHY_BASE_EMBED (object))); - 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, ephy_base_embed_get_popups_allowed - (EPHY_BASE_EMBED (object))); - 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_VISIBLE: - g_value_set_boolean (value, priv->visibility); - break; - default: - break; - } -} - static void ephy_base_embed_class_init (EphyBaseEmbedClass *klass) { - GObjectClass *gobject_class = (GObjectClass *)klass; GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - gobject_class->dispose = ephy_base_embed_dispose; - gobject_class->finalize = ephy_base_embed_finalize; - gobject_class->get_property = ephy_base_embed_get_property; - gobject_class->set_property = ephy_base_embed_set_property; - widget_class->size_request = ephy_base_embed_size_request; widget_class->size_allocate = ephy_base_embed_size_allocate; widget_class->grab_focus = ephy_base_embed_grab_focus; - - g_object_class_install_property (gobject_class, - PROP_SECURITY, - g_param_spec_enum ("security-level", - "Security Level", - "The embed's security level", - EPHY_TYPE_EMBED_SECURITY_LEVEL, - EPHY_EMBED_STATE_IS_UNKNOWN, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_DOCUMENT_TYPE, - g_param_spec_enum ("document-type", - "Document Type", - "The embed's documen type", - EPHY_TYPE_EMBED_DOCUMENT_TYPE, - EPHY_EMBED_DOCUMENT_HTML, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - - g_object_class_install_property (gobject_class, - PROP_LOAD_PROGRESS, - g_param_spec_int ("load-progress", - "Load progress", - "The embed's load progress in percent", - 0, - 100, - 0, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_LOAD_STATUS, - g_param_spec_boolean ("load-status", - "Load status", - "The embed's load status", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_NAVIGATION, - g_param_spec_flags ("navigation", - "Navigation flags", - "The embed's navigation flags", - EPHY_TYPE_EMBED_NAVIGATION_FLAGS, - 0, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_ADDRESS, - g_param_spec_string ("address", - "Address", - "The embed's address", - "", - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_TYPED_ADDRESS, - g_param_spec_string ("typed-address", - "Typed Address", - "The typed address", - "", - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_TITLE, - g_param_spec_string ("title", - "Title", - "The embed's title", - EMPTY_PAGE, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_STATUS_MESSAGE, - g_param_spec_string ("status-message", - "Status Message", - "The embed's statusbar message", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_LINK_MESSAGE, - g_param_spec_string ("link-message", - "Link Message", - "The embed's link message", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (gobject_class, - PROP_ICON, - g_param_spec_object ("icon", - "Icon", - "The embed icon's", - GDK_TYPE_PIXBUF, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - - g_object_class_install_property (gobject_class, - PROP_ICON_ADDRESS, - g_param_spec_string ("icon-address", - "Icon address", - "The embed icon's address", - NULL, - (G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB))); - g_object_class_install_property (gobject_class, - PROP_HIDDEN_POPUP_COUNT, - g_param_spec_int ("hidden-popup-count", - "Number of Blocked Popups", - "The embed's number of blocked popup windows", - 0, - G_MAXINT, - 0, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - - g_object_class_install_property (gobject_class, - PROP_POPUPS_ALLOWED, - g_param_spec_boolean ("popups-allowed", - "Popups Allowed", - "Whether popup windows are to be displayed", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - - g_object_class_install_property (gobject_class, - PROP_VISIBLE, - g_param_spec_boolean ("visibility", - "Visibility", - "The embed's visibility", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - - g_type_class_add_private (gobject_class, sizeof (EphyBaseEmbedPrivate)); -} - -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 void -ge_favicon_cb (EphyEmbed *membed, - const char *address, - EphyBaseEmbed *bembed) -{ - ephy_base_embed_set_icon_address (bembed, address); -} - -static gboolean -popups_manager_remove_window (EphyBaseEmbed *embed, - EphyEmbedContainer *container) -{ - embed->priv->shown_popups = g_slist_remove (embed->priv->shown_popups, - container); - - return FALSE; -} - -static void -popups_manager_add_window (EphyBaseEmbed *embed, - EphyEmbedContainer *container) -{ - LOG ("popups_manager_add_window: embed %p, container %p", embed, container); - - embed->priv->shown_popups = g_slist_prepend - (embed->priv->shown_popups, container); - - g_signal_connect_swapped (container, "destroy", - G_CALLBACK (popups_manager_remove_window), - embed); -} - -static void -ge_new_window_cb (EphyEmbed *embed, - EphyEmbed *new_embed, - EphyBaseEmbed *bembed) -{ - EphyEmbedContainer *container; - - g_return_if_fail (new_embed != NULL); - - container = EPHY_EMBED_CONTAINER (gtk_widget_get_toplevel (GTK_WIDGET (new_embed))); - g_return_if_fail (container != NULL || !GTK_WIDGET_TOPLEVEL (container)); - - popups_manager_add_window (bembed, container); -} - -static void -disconnect_popup (EphyEmbedContainer *container, - EphyBaseEmbed *embed) -{ - g_signal_handlers_disconnect_by_func - (container, G_CALLBACK (popups_manager_remove_window), embed); -} - -void -ephy_base_embed_popups_manager_reset (EphyBaseEmbed *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"); - g_object_notify (G_OBJECT (embed), "popups-allowed"); -} - -static void -ge_popup_blocked_cb (EphyEmbed *embed, - const char *url, - const char *name, - const char *features, - EphyBaseEmbed *bembed) -{ - popups_manager_add (bembed, url, name, features); } 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_favicon", - G_CALLBACK (ge_favicon_cb), - self, (GConnectFlags)0); - - g_signal_connect_object (self, "ge_new_window", - G_CALLBACK (ge_new_window_cb), - self, (GConnectFlags)0); - - g_signal_connect_object (self, "ge_popup_blocked", - G_CALLBACK (ge_popup_blocked_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->address_expire = EPHY_EMBED_ADDRESS_EXPIRE_NOW; - priv->is_blank = TRUE; - priv->title = g_strdup (EMPTY_PAGE); - priv->monitor_directory = FALSE; -} - -static void -ephy_base_embed_dispose (GObject *object) -{ - ephy_base_embed_file_monitor_cancel (EPHY_BASE_EMBED (object)); - - G_OBJECT_CLASS (ephy_base_embed_parent_class)->dispose (object); -} - -static void -ephy_base_embed_finalize (GObject *object) -{ - EphyBaseEmbedPrivate *priv = EPHY_BASE_EMBED (object)->priv; - - if (priv->icon != NULL) { - g_object_unref (priv->icon); - priv->icon = NULL; - } - - ephy_base_embed_popups_manager_reset (EPHY_BASE_EMBED (object)); - - 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); -} - -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; - iface->get_visibility = impl_get_visibility; -} - -void -ephy_base_embed_set_address (EphyBaseEmbed *embed, - const char *address) -{ - EphyBaseEmbedPrivate *priv = embed->priv; - GObject *object = G_OBJECT (embed); - - g_free (priv->address); - priv->address = g_strdup (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) -{ - if (g_str_has_prefix (address, "file://")) - return g_strdup (address + 7); - else - return ephy_string_get_host_name (address); -} - -void -ephy_base_embed_set_title (EphyBaseEmbed *embed, - const char *embed_title) -{ - EphyBaseEmbedPrivate *priv = embed->priv; - char *title = g_strdup (embed_title); - - 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 = g_strdup (EMPTY_PAGE); - priv->is_blank = TRUE; - } - } else if (priv->is_blank) { - g_free (title); - title = g_strdup (EMPTY_PAGE); - } - - 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, 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) -{ - const char *msg = NULL; - char *host = NULL; - - if (uri != NULL) - host = ephy_string_get_host_name (uri); - - if (host == NULL) 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: - g_free (host); -} - -static void -update_navigation_flags (EphyBaseEmbed *membed) -{ - EphyBaseEmbedPrivate *priv = membed->priv; - EphyEmbed *embed = EPHY_EMBED (membed); - guint flags = 0; - WebKitWebView *web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed); - - if (ephy_embed_can_go_up (embed)) { - flags |= EPHY_EMBED_NAV_UP; - } - - if (webkit_web_view_can_go_back (web_view)) { - flags |= EPHY_EMBED_NAV_BACK; - } - - if (webkit_web_view_can_go_forward (web_view)) { - 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; -} - -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"); - - g_file_monitor_cancel (G_FILE_MONITOR (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))); - webkit_web_view_reload (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed)); - - /* don't run again */ - return FALSE; -} - -static void -ephy_base_embed_file_monitor_cb (GFileMonitor *monitor, - GFile *file, - GFile *other_file, - GFileMonitorEvent event_type, - EphyBaseEmbed *embed) -{ - gboolean should_reload; - EphyBaseEmbedPrivate *priv = embed->priv; - - switch (event_type) { - /* These events will always trigger a reload: */ - case G_FILE_MONITOR_EVENT_CHANGED: - case G_FILE_MONITOR_EVENT_CREATED: - should_reload = TRUE; - break; - - /* These events will only trigger a reload for directories: */ - case G_FILE_MONITOR_EVENT_DELETED: - case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: - should_reload = priv->monitor_directory; - break; - - /* These events don't trigger a reload: */ - case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: - case G_FILE_MONITOR_EVENT_UNMOUNTED: - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - 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; - gboolean local; - gchar *anchor; - gchar *url; - GFile *file; - GFileType file_type; - GFileInfo *file_info; - GFileMonitor *monitor = NULL; - - 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; - - /* strip off anchors */ - anchor = strchr (address, '#'); - if (anchor != NULL) { - url = g_strndup (address, anchor - address); - } else { - url = g_strdup (address); - } - - file = g_file_new_for_uri (url); - file_info = g_file_query_info (file, - G_FILE_ATTRIBUTE_STANDARD_TYPE, - 0, NULL, NULL); - if (file_info == NULL) { - g_object_unref (file); - g_free (url); - return; - } - - file_type = g_file_info_get_file_type (file_info); - g_object_unref (file_info); - - if (file_type == G_FILE_TYPE_DIRECTORY) { - monitor = g_file_monitor_directory (file, 0, NULL, NULL); - g_signal_connect (monitor, "changed", - G_CALLBACK (ephy_base_embed_file_monitor_cb), - embed); - priv->monitor_directory = TRUE; - LOG ("Installed monitor for directory '%s'", url); - } - else if (file_type == G_FILE_TYPE_REGULAR) { - monitor = g_file_monitor_file (file, 0, NULL, NULL); - g_signal_connect (monitor, "changed", - G_CALLBACK (ephy_base_embed_file_monitor_cb), - embed); - priv->monitor_directory = FALSE; - LOG ("Installed monitor for file '%s'", url); - } - priv->monitor = monitor; - g_object_unref (file); - g_free (url); -} - -void -ephy_base_embed_location_changed (EphyBaseEmbed *embed, - const 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, EMPTY_PAGE); - } 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); - g_free (embed_address); - } - - 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; - - 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) { - history = EPHY_HISTORY (ephy_embed_shell_get_global_history (embed_shell)); - ephy_history_set_icon (history, 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_set_visibility (EphyBaseEmbed *embed, - gboolean visibility) -{ - EphyBaseEmbedPrivate *priv = embed->priv; - - if (priv->visibility != visibility) { - priv->visibility = visibility; - - g_object_notify (G_OBJECT (embed), "visibility"); - } } diff --git a/embed/ephy-base-embed.h b/embed/ephy-base-embed.h index d2043a8b9..9e34007e8 100644 --- a/embed/ephy-base-embed.h +++ b/embed/ephy-base-embed.h @@ -53,31 +53,6 @@ struct _EphyBaseEmbed { }; GType ephy_base_embed_get_type (void) G_GNUC_CONST; -void ephy_base_embed_set_title (EphyBaseEmbed *embed, - const 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, - const char *address); -void ephy_base_embed_location_changed (EphyBaseEmbed *embed, - const 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); -void ephy_base_embed_set_load_percent (EphyBaseEmbed *embed, int percent); -void ephy_base_embed_popups_manager_reset (EphyBaseEmbed *embed); -void ephy_base_embed_set_visibility (EphyBaseEmbed *embed, - gboolean visibility); G_END_DECLS diff --git a/embed/ephy-embed-container.c b/embed/ephy-embed-container.c index c2a6ad9cd..1a55eb66a 100644 --- a/embed/ephy-embed-container.c +++ b/embed/ephy-embed-container.c @@ -33,8 +33,8 @@ ephy_embed_container_base_init (gpointer g_class) g_object_interface_install_property (g_class, g_param_spec_flags ("chrome", NULL, NULL, - EPHY_TYPE_EMBED_CHROME, - EPHY_EMBED_CHROME_ALL, + EPHY_TYPE_WEB_VIEW_CHROME, + EPHY_WEB_VIEW_CHROME_ALL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); @@ -205,12 +205,12 @@ ephy_embed_container_get_is_popup (EphyEmbedContainer *container) * ephy_embed_container_get_chrome: * @container: an #EphyEmbedContainer * - * Returns the #EphyEmbedChrome flags indicating the visibility of several parts + * Returns the #EphyWebViewChrome flags indicating the visibility of several parts * of the UI. * - * Return value: #EphyEmbedChrome flags. + * Return value: #EphyWebViewChrome flags. **/ -EphyEmbedChrome +EphyWebViewChrome ephy_embed_container_get_chrome (EphyEmbedContainer *container) { EphyEmbedContainerIface *iface; diff --git a/embed/ephy-embed-container.h b/embed/ephy-embed-container.h index 8a502fdd0..13c602a18 100644 --- a/embed/ephy-embed-container.h +++ b/embed/ephy-embed-container.h @@ -25,6 +25,7 @@ #define EPHY_EMBED_CONTAINER_H #include "ephy-embed.h" +#include "ephy-web-view.h" #include #include @@ -62,7 +63,7 @@ struct _EphyEmbedContainerIface gboolean (* get_is_popup) (EphyEmbedContainer *container); - EphyEmbedChrome (* get_chrome) (EphyEmbedContainer *container); + EphyWebViewChrome (* get_chrome) (EphyEmbedContainer *container); }; GType ephy_embed_container_get_type (void); @@ -84,7 +85,7 @@ GList *ephy_embed_container_get_children (EphyEmbedContainer *container); gboolean ephy_embed_container_get_is_popup (EphyEmbedContainer *container); -EphyEmbedChrome ephy_embed_container_get_chrome (EphyEmbedContainer *container); +EphyWebViewChrome ephy_embed_container_get_chrome (EphyEmbedContainer *container); G_END_DECLS diff --git a/embed/ephy-embed-single.c b/embed/ephy-embed-single.c index f24fef1c6..9b0e8178f 100644 --- a/embed/ephy-embed-single.c +++ b/embed/ephy-embed-single.c @@ -76,7 +76,7 @@ ephy_embed_single_iface_init (gpointer g_iface) GTK_TYPE_WIDGET, 2, GTK_TYPE_WIDGET, - EPHY_TYPE_EMBED_CHROME); + EPHY_TYPE_WEB_VIEW_CHROME); /** * EphyEmbedSingle::handle_content: diff --git a/embed/ephy-embed-single.h b/embed/ephy-embed-single.h index 8ae5d92cb..cbd253ab3 100644 --- a/embed/ephy-embed-single.h +++ b/embed/ephy-embed-single.h @@ -25,6 +25,7 @@ #define EPHY_EMBED_SINGLE_H #include "ephy-embed.h" +#include "ephy-web-view.h" G_BEGIN_DECLS @@ -46,7 +47,7 @@ struct _EphyEmbedSingleIface EphyEmbed * (* new_window) (EphyEmbedSingle *single, EphyEmbed *parent_embed, - EphyEmbedChrome chromemask); + EphyWebViewChrome chromemask); gboolean (* handle_content) (EphyEmbedSingle *shell, char *mime_type, diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c index e00e23528..672c46bc3 100644 --- a/embed/ephy-embed-utils.c +++ b/embed/ephy-embed-utils.c @@ -80,28 +80,28 @@ ephy_embed_utils_link_message_parse (char *message) /** * ephy_embed_utils_get_title_composite: - * @embed: an #EphyEmbed + * @view: an #EphyView * * Returns the title of the web page loaded in @embed. * * This differs from #ephy_embed_utils_get_title in that this function * will return a special title while the page is still loading. * - * Return value: @embed's web page's title. Will never be %NULL. + * Return value: @view's web page's title. Will never be %NULL. **/ const char * -ephy_embed_utils_get_title_composite (EphyEmbed *embed) +ephy_embed_utils_get_title_composite (EphyWebView *view) { const char *title = ""; const char *loading_title; gboolean is_loading, is_blank; - g_return_val_if_fail (EPHY_IS_EMBED (embed), NULL); + g_return_val_if_fail (EPHY_IS_WEB_VIEW (view), NULL); - is_loading = ephy_embed_get_load_status (embed); - is_blank = ephy_embed_get_is_blank (embed); - loading_title = ephy_embed_get_loading_title (embed); - title = ephy_embed_get_title (embed); + is_loading = ephy_web_view_get_load_status (view); + is_blank = ephy_web_view_get_is_blank (view); + loading_title = ephy_web_view_get_loading_title (view); + title = ephy_web_view_get_title (view); if (is_blank) { diff --git a/embed/ephy-embed-utils.h b/embed/ephy-embed-utils.h index e98860ed8..226eff3f7 100644 --- a/embed/ephy-embed-utils.h +++ b/embed/ephy-embed-utils.h @@ -36,10 +36,13 @@ G_BEGIN_DECLS #define EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED(embed) (WEBKIT_WEB_VIEW (gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (embed)))))) +#define EPHY_GET_EPHY_WEB_VIEW_FROM_EMBED(embed) (EPHY_WEB_VIEW (gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (embed)))))) +#define EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW(view) (EPHY_EMBED (gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (view))))) + #define EPHY_WEBKIT_BACK_FORWARD_LIMIT 100 char * ephy_embed_utils_link_message_parse (char *message); -const char * ephy_embed_utils_get_title_composite (EphyEmbed *embed); +const char * ephy_embed_utils_get_title_composite (EphyWebView *view); gboolean ephy_embed_utils_address_has_web_scheme (const char *address); G_END_DECLS diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c deleted file mode 100644 index 29ecfed9d..000000000 --- a/embed/ephy-embed.c +++ /dev/null @@ -1,771 +0,0 @@ -/* - * Copyright © 2000-2003 Marco Pesenti Gritti - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include - -#include "ephy-embed.h" - -#include "ephy-embed-type-builtins.h" -#include "ephy-marshal.h" - -static void ephy_embed_base_init (gpointer g_class); - -GType -ephy_embed_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - const GTypeInfo our_info = - { - sizeof (EphyEmbedIface), - ephy_embed_base_init, - NULL, - }; - - type = g_type_register_static (G_TYPE_INTERFACE, - "EphyEmbed", - &our_info, (GTypeFlags)0); - } - - return type; -} - -static void -ephy_embed_base_init (gpointer g_class) -{ - static gboolean initialized = FALSE; - - if (!initialized) - { -/** - * EphyEmbed::ge-new-window: - * @embed: - * @new_embed: the newly opened #EphyEmbed - * - * The ::ge_new_window signal is emitted after a new window has been opened by - * the embed. For example, when a JavaScript popup window is opened. - **/ - g_signal_new ("ge_new_window", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, new_window), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - GTK_TYPE_WIDGET); -/** - * EphyEmbed::ge-popup-blocked: - * @embed: - * @address: The requested URL - * @target: The requested window name, e.g. "_blank" - * @features: The requested features: for example, "height=400,width=200" - * - * The ::ge_popup_blocked signal is emitted when the viewed web page requests - * a popup window (with javascript:open()) but popup windows are not allowed. - **/ - g_signal_new ("ge_popup_blocked", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EphyEmbedIface, popup_blocked), - NULL, NULL, - ephy_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, - 3, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); -/** - * EphyEmbed::ge-context-menu: - * @embed: - * @event: the #EphyEmbedEvent which triggered this signal - * - * The ::ge_context_menu signal is emitted when a context menu is to be - * displayed. This will usually happen when the user right-clicks on a part of - * @embed. - **/ - g_signal_new ("ge_context_menu", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, context_menu), - g_signal_accumulator_true_handled, NULL, - ephy_marshal_BOOLEAN__OBJECT, - G_TYPE_BOOLEAN, - 1, - G_TYPE_OBJECT); -/** - * EphyEmbed::ge-favicon: - * @embed: - * @address: the URL to @embed's web site's favicon - * - * The ::ge_favicon signal is emitted when @embed discovers that a favourite - * icon (favicon) is available for the site it is visiting. - **/ - g_signal_new ("ge_favicon", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EphyEmbedIface, favicon), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); -/** - * EphyEmbed::ge-search-link: - * @embed: - * @type: the mime-type of the search description - * @title: the title of the news feed - * @address: the URL to @embed's web site's search description - * - * The ::ge_rss signal is emitted when @embed discovers that a search - * description is available for the site it is visiting. - **/ - g_signal_new ("ge_search_link", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EphyEmbedIface, search_link), - NULL, NULL, - ephy_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, - 3, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); - -/** - * EphyEmbed::ge-feed-link: - * @embed: - * @type: the mime-type of the news feed - * @title: the title of the news feed - * @address: the URL to @embed's web site's news feed - * - * The ::ge_rss signal is emitted when @embed discovers that a news feed - * is available for the site it is visiting. - **/ - g_signal_new ("ge_feed_link", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EphyEmbedIface, feed_link), - NULL, NULL, - ephy_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, - 3, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); -/** - * EphyEmbed::ge-dom-mouse-click: - * @embed: - * @event: the #EphyEmbedEvent which triggered this signal - * - * The ::ge_dom_mouse_click signal is emitted when the user clicks in @embed. - **/ - g_signal_new ("ge_dom_mouse_click", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, dom_mouse_click), - g_signal_accumulator_true_handled, NULL, - ephy_marshal_BOOLEAN__OBJECT, - G_TYPE_BOOLEAN, - 1, - G_TYPE_OBJECT); -/** - * EphyEmbed::ge-dom-mouse-down: - * @embed: - * @event: the #EphyEmbedEvent which triggered this signal - * - * The ::ge_dom_mouse_down signal is emitted when the user depresses a mouse - * button. - **/ - g_signal_new ("ge_dom_mouse_down", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, dom_mouse_down), - g_signal_accumulator_true_handled, NULL, - ephy_marshal_BOOLEAN__OBJECT, - G_TYPE_BOOLEAN, - 1, - G_TYPE_OBJECT); -/** - * EphyEmbed::ge-modal-alert: - * @embed: - * - * The ::ge-modal-alert signal is emitted when a DOM event will open a - * modal alert. - * - * Return %TRUE to prevent the dialog from being opened. - **/ - g_signal_new ("ge_modal_alert", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, modal_alert), - g_signal_accumulator_true_handled, NULL, - ephy_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, - 0); -/** - * EphyEmbed::ge-modal-alert-closed: - * @embed: - * - * The ::ge-modal-alert-closed signal is emitted when a modal alert put up by a - * DOM event was closed. - **/ - g_signal_new ("ge_modal_alert_closed", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, modal_alert_closed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - -/** - * EphyEmbed::ge-document-type: - * @embed: - * @type: the new document type - * - * The ::ge-document-type signal is emitted when @embed determines the type of its document. - **/ - g_signal_new ("ge_document_type", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EphyEmbedIface, document_type), - NULL, NULL, - g_cclosure_marshal_VOID__ENUM, - G_TYPE_NONE, - 1, - EPHY_TYPE_EMBED_DOCUMENT_TYPE); -/** - * EphyEmbed::dom-content-loaded: - * @embed: - * - * The ::dom-content-loaded signal is emitted when - * the document has been loaded (excluding images and other loads initiated by this document). - * That's true also for frameset and all the frames within it. - **/ - g_signal_new ("dom_content_loaded", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EphyEmbedIface, dom_content_loaded), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, - G_TYPE_POINTER); - -/** - * EphyEmbed::ge-search-key-press: - * @embed: - * @event: the #GdkEventKey which triggered this signal - * - * The ::ge-search-key-press signal is emitted for keypresses which - * should be used for find implementations. - **/ - g_signal_new ("ge-search-key-press", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, search_key_press), - g_signal_accumulator_true_handled, NULL, - ephy_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, - 1, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); - -/** - * EphyEmbed::close-request - * @embed: - * - * The ::close signal is emitted when the embed request closing. - * Return %TRUE to prevent closing. You HAVE to process removal of the embed - * as soon as possible after that. - **/ - g_signal_new ("close-request", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, close_request), - g_signal_accumulator_true_handled, NULL, - ephy_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, - 0); -/** - * EphyEmbed::content-blocked: - * @embed: - * @uri: blocked URI - * - * The ::content-blocked signal is emitted when an url has been blocked. - **/ - g_signal_new ("content-blocked", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EphyEmbedIface, content_blocked), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); -/** - * EphyEmbed::new-document-now: - * @embed: - * @uri: URI of the new content - * - * The ::new-document-now signal is emitted when a new page content - * is being loaded into the browser. It's a good place to do view - * related changes, for example to restore the zoom level of a page - * or to set an user style sheet. - **/ - g_signal_new ("new-document-now", - EPHY_TYPE_EMBED, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EphyEmbedIface, new_document_now), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); - - - initialized = TRUE; - } - -} - -/** - * ephy_embed_can_go_up: - * @embed: an #EphyEmbed - * - * Returns whether @embed can travel to a higher-level directory on the server. - * For example, for http://www.example.com/subdir/index.html, returns %TRUE; for - * http://www.example.com/index.html, returns %FALSE. - * - * Return value: %TRUE if @embed can browse to a higher-level directory - **/ -gboolean -ephy_embed_can_go_up (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->can_go_up (embed); -} - -/** - * ephy_embed_get_go_up_list: - * @embed: an #EphyEmbed - * - * Returns a list of (%char *) URLs to higher-level directories on the same - * server, in order of deepest to shallowest. For example, given - * "http://www.example.com/dir/subdir/file.html", will return a list containing - * "http://www.example.com/dir/subdir/", "http://www.example.com/dir/" and - * "http://www.example.com/". - * - * Return value: a list of URLs higher up in @embed's web page's directory - * hierarchy - **/ -GSList * -ephy_embed_get_go_up_list (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_go_up_list (embed); -} - -/** - * ephy_embed_go_up: - * @embed: an #EphyEmbed - * - * Moves @embed one level up in its web page's directory hierarchy. - **/ -void -ephy_embed_go_up (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - iface->go_up (embed); -} - -/** - * ephy_embed_get_title: - * @embed: an #EphyEmbed - * - * Return value: the title of the web page displayed in @embed - **/ -const char * -ephy_embed_get_title (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_title (embed); -} - -/** - * ephy_embed_get_location: - * @embed: an #EphyEmbed - * @toplevel: %FALSE to return the location of the focused frame only - * - * Returns the URL of the web page displayed in @embed. - * - * If the web page contains frames, @toplevel will determine which location to - * retrieve. If @toplevel is %TRUE, the return value will be the location of the - * frameset document. If @toplevel is %FALSE, the return value will be the - * location of the currently-focused frame. - * - * Return value: the URL of the web page displayed in @embed - **/ -char * -ephy_embed_get_location (EphyEmbed *embed, - gboolean toplevel) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_location (embed, toplevel); -} - -/** - * ephy_embed_get_link_message: - * @embed: an #EphyEmbed - * - * When the user is hovering the mouse over a hyperlink, returns the URL of the - * hyperlink. - * - * Return value: the URL of the link over which the mouse is hovering - **/ -const char * -ephy_embed_get_link_message (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_link_message (embed); -} - -/** - * ephy_embed_get_js_status: - * @embed: an #EphyEmbed - * - * Displays the message JavaScript is attempting to display in the statusbar. - * - * Note that Epiphany does not display JavaScript statusbar messages. - * - * Return value: a message from JavaScript meant to be displayed in the - * statusbar - **/ -char * -ephy_embed_get_js_status (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_js_status (embed); -} - -/** - * ephy_embed_get_security_level: - * @embed: an #EphyEmbed - * @level: return value of security level - * @description: return value of the description of the security level - * - * Fetches the #EphyEmbedSecurityLevel and a newly-allocated string description - * of the security state of @embed. - **/ -void -ephy_embed_get_security_level (EphyEmbed *embed, - EphyEmbedSecurityLevel *level, - char **description) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - iface->get_security_level (embed, level, description); -} -/** - * ephy_embed_show_page_certificate: - * @embed: an #EphyEmbed - * - * Shows a dialogue displaying the certificate of the currently loaded page - * of @embed, if it was loaded over a secure connection; else does nothing. - **/ -void -ephy_embed_show_page_certificate (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - iface->show_page_certificate (embed); -} - -/** - * ephy_embed_set_print_preview_mode: - * @embed: an #EphyEmbed - * @preview_mode: Whether the print preview mode is enabled. - * - * Enable and disable the print preview mode. - **/ -void -ephy_embed_set_print_preview_mode (EphyEmbed *embed, - gboolean preview_mode) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - iface->set_print_preview_mode (embed, preview_mode); -} - -/** - * ephy_embed_print_preview_n_pages: - * @embed: an #EphyEmbed - * - * Returns the number of pages which would appear in @embed's loaded document - * if it were to be printed. - * - * Return value: the number of pages in @embed's loaded document - **/ -int -ephy_embed_print_preview_n_pages (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->print_preview_n_pages (embed); -} - -/** - * ephy_embed_print_preview_navigate: - * @embed: an #EphyEmbed - * @type: an #EphyPrintPreviewNavType which determines where to navigate - * @page: if @type is %EPHY_EMBED_PRINTPREVIEW_GOTO_PAGENUM, the desired page number - * - * Navigates @embed's print preview. - **/ -void -ephy_embed_print_preview_navigate (EphyEmbed *embed, - EphyEmbedPrintPreviewNavType type, - int page) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - iface->print_preview_navigate (embed, type, page); -} - -/** - * ephy_embed_has_modified_forms: - * @embed: an #EphyEmbed - * - * Returns %TRUE if the user has modified <input> or <textarea> - * values in @embed's loaded document. - * - * Return value: %TRUE if @embed has user-modified forms - **/ -gboolean -ephy_embed_has_modified_forms (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->has_modified_forms (embed); -} - -/** - * ephy_embed_get_document_type: - * @embed: an #EphyEmbed - * - * Returns the type of document loaded in the @embed - * - * Return value: the #EphyEmbedDocumentType - **/ -EphyEmbedDocumentType -ephy_embed_get_document_type (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_document_type (embed); -} - -/** - * ephy_embed_get_load_percent: - * @embed: an #EphyEmbed - * - * Returns the page load percentage (displayed in the progressbar). - * - * Return value: a percentage from 0 to 100. - **/ -int -ephy_embed_get_load_percent (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_load_percent (embed); -} - -/** - * ephy_embed_get_load_status: - * @embed: an #EphyEmbed - * - * Returns whether the web page in @embed has finished loading. A web page is - * only finished loading after all images, styles, and other dependencies have - * been downloaded and rendered. - * - * Return value: %TRUE if the page is still loading, %FALSE if complete - **/ -gboolean -ephy_embed_get_load_status (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_load_status (embed); -} - -/** - * ephy_embed_get_navigation_flags: - * @embed: an #EphyEmbed - * - * Returns @embed's navigation flags. - * - * Return value: @embed's navigation flags - **/ -EphyEmbedNavigationFlags -ephy_embed_get_navigation_flags (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_navigation_flags (embed); -} - -/** - * ephy_embed_get_typed_address: - * @embed: an #EphyEmbed - * - * Returns the text that @embed's #EphyWindow will display in its location toolbar - * entry when @embed is selected. - * - * This is not guaranteed to be the same as @embed's location, - * available through ephy_embed_get_location(). As the user types a new address - * into the location entry, ephy_embed_get_location()'s returned string will - * change. - * - * Return value: @embed's #EphyWindow's location entry when @embed is selected - **/ -const char * -ephy_embed_get_typed_address (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_typed_address (embed); -} - -/** - * ephy_embed_set_typed_address: - * @embed: an #EphyEmbed - * @address: the new typed address, or %NULL to clear it - * @expire: when to expire this address_expire - * - * Sets the text that @embed's #EphyWindow will display in its location toolbar - * entry when @embed is selected. - **/ -void -ephy_embed_set_typed_address (EphyEmbed *embed, - const char *address, - EphyEmbedAddressExpire expire) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->set_typed_address (embed, address, expire); -} - -/** - * ephy_embed_get_address: - * @embed: an #EphyEmbed - * - * Returns the address of the currently loaded page. - * - * Return value: @embed's address. Will never be %NULL. - **/ -const char * -ephy_embed_get_address (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_address (embed); -} - -/** - * ephy_embed_get_status_message: - * @embed: an #EphyEmbed - * - * Returns the message displayed in @embed's #EphyWindow's - * #EphyStatusbar. If the user is hovering the mouse over a hyperlink, - * this function will return the same value as - * ephy_embed_get_link_message(). Otherwise, it will return a network - * status message, or NULL. - * - * The message returned has a limited lifetime, and so should be copied with - * g_strdup() if it must be stored. - * - * Return value: The current statusbar message - **/ -const char * -ephy_embed_get_status_message (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_status_message (embed); -} - -/** - * ephy_embed_get_icon: - * @embed: an #EphyEmbed - * - * Returns the embed's site icon as a #GdkPixbuf, - * or %NULL if it is not available. - * - * Return value: a the embed's site icon - **/ -GdkPixbuf * -ephy_embed_get_icon (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_icon (embed); -} - -/** - * ephy_embed_get_icon_address: - * @embed: an #EphyEmbed - * - * Returns a URL which points to @embed's site icon. - * - * Return value: the URL of @embed's site icon - **/ -const char * -ephy_embed_get_icon_address (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_icon_address (embed); -} - -/** - * ephy_embed_get_is_blank: - * @embed: an #EphyEmbed - * - * Returns whether the @embed's address is "blank". - * - * Return value: %TRUE if the @embed's address is "blank" - **/ -gboolean -ephy_embed_get_is_blank (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_is_blank (embed); -} - -const char * -ephy_embed_get_loading_title (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_loading_title (embed); -} - -/** - * ephy_embed_get_visibility: - * @embed: an #EphyEmbed - * - * Returns whether the @embed's toplevel is visible or not. Used - * mostly for popup visibility management. - * - * Return value: %TRUE if @embed's "visibility" property is set - **/ -gboolean -ephy_embed_get_visibility (EphyEmbed *embed) -{ - EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed); - return iface->get_visibility (embed); -} diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h deleted file mode 100644 index 2f48763c4..000000000 --- a/embed/ephy-embed.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright © 2000-2003 Marco Pesenti Gritti - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#if !defined (__EPHY_EPIPHANY_H_INSIDE__) && !defined (EPIPHANY_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef EPHY_EMBED_H -#define EPHY_EMBED_H - -#include "ephy-embed-event.h" - -#include -#include -#include - -G_BEGIN_DECLS - -#define EPHY_TYPE_EMBED (ephy_embed_get_type ()) -#define EPHY_EMBED(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_EMBED, EphyEmbed)) -#define EPHY_EMBED_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_EMBED, EphyEmbedIface)) -#define EPHY_IS_EMBED(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_EMBED)) -#define EPHY_IS_EMBED_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_EMBED)) -#define EPHY_EMBED_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EPHY_TYPE_EMBED, EphyEmbedIface)) - -typedef struct _EphyEmbed EphyEmbed; -typedef struct _EphyEmbedIface EphyEmbedIface; - -typedef enum -{ - EPHY_EMBED_STATE_UNKNOWN = 0, - EPHY_EMBED_STATE_START = 1 << 0, - EPHY_EMBED_STATE_REDIRECTING = 1 << 1, - EPHY_EMBED_STATE_TRANSFERRING = 1 << 2, - EPHY_EMBED_STATE_NEGOTIATING = 1 << 3, - EPHY_EMBED_STATE_STOP = 1 << 4, - - EPHY_EMBED_STATE_IS_REQUEST = 1 << 5, - EPHY_EMBED_STATE_IS_DOCUMENT = 1 << 6, - EPHY_EMBED_STATE_IS_NETWORK = 1 << 7, - EPHY_EMBED_STATE_IS_WINDOW = 1 << 8, - EPHY_EMBED_STATE_RESTORING = 1 << 9 -} EphyEmbedNetState; - -typedef enum -{ - EPHY_EMBED_CHROME_MENUBAR = 1 << 0, - EPHY_EMBED_CHROME_TOOLBAR = 1 << 1, - EPHY_EMBED_CHROME_STATUSBAR = 1 << 2, - EPHY_EMBED_CHROME_BOOKMARKSBAR = 1 << 3 -} EphyEmbedChrome; - -#define EPHY_EMBED_CHROME_ALL (EPHY_EMBED_CHROME_MENUBAR | \ - EPHY_EMBED_CHROME_TOOLBAR | \ - EPHY_EMBED_CHROME_STATUSBAR | \ - EPHY_EMBED_CHROME_BOOKMARKSBAR) - -typedef enum -{ - EPHY_EMBED_PRINTPREVIEW_GOTO_PAGENUM = 0, - EPHY_EMBED_PRINTPREVIEW_PREV_PAGE = 1, - EPHY_EMBED_PRINTPREVIEW_NEXT_PAGE = 2, - EPHY_EMBED_PRINTPREVIEW_HOME = 3, - EPHY_EMBED_PRINTPREVIEW_END = 4 -} EphyEmbedPrintPreviewNavType; - -typedef enum -{ - EPHY_EMBED_STATE_IS_UNKNOWN, - EPHY_EMBED_STATE_IS_INSECURE, - EPHY_EMBED_STATE_IS_BROKEN, - EPHY_EMBED_STATE_IS_SECURE_LOW, - EPHY_EMBED_STATE_IS_SECURE_MED, - EPHY_EMBED_STATE_IS_SECURE_HIGH -} EphyEmbedSecurityLevel; - -typedef enum -{ - EPHY_EMBED_DOCUMENT_HTML, - EPHY_EMBED_DOCUMENT_XML, - EPHY_EMBED_DOCUMENT_IMAGE, - EPHY_EMBED_DOCUMENT_OTHER -} EphyEmbedDocumentType; - -typedef enum -{ - EPHY_EMBED_NAV_UP = 1 << 0, - EPHY_EMBED_NAV_BACK = 1 << 1, - EPHY_EMBED_NAV_FORWARD = 1 << 2 -} EphyEmbedNavigationFlags; - -typedef enum -{ - EPHY_EMBED_ADDRESS_EXPIRE_NOW, - EPHY_EMBED_ADDRESS_EXPIRE_NEXT, - EPHY_EMBED_ADDRESS_EXPIRE_CURRENT -} EphyEmbedAddressExpire; - -struct _EphyEmbedIface -{ - GTypeInterface base_iface; - - int (* context_menu) (EphyEmbed *embed, - EphyEmbedEvent *event); - void (* favicon) (EphyEmbed *embed, - const char *location); - void (* feed_link) (EphyEmbed *embed, - const char *type, - const char *title, - const char *address); - void (* search_link) (EphyEmbed *embed, - const char *type, - const char *title, - const char *address); - gboolean (* dom_mouse_click) (EphyEmbed *embed, - EphyEmbedEvent *event); - gboolean (* dom_mouse_down) (EphyEmbed *embed, - EphyEmbedEvent *event); - void (* dom_content_loaded) (EphyEmbed *embed, - gpointer event); - void (* popup_blocked) (EphyEmbed *embed, - const char *address, - const char *target, - const char *features); - void (* content_blocked) (EphyEmbed *embed, - const char *uri); - gboolean (* modal_alert) (EphyEmbed *embed); - void (* modal_alert_closed) (EphyEmbed *embed); - void (* document_type) (EphyEmbed *embed, - EphyEmbedDocumentType type); - void (* new_window) (EphyEmbed *embed, - EphyEmbed *new_embed); - gboolean (* search_key_press) (EphyEmbed *embed, - GdkEventKey *event); - gboolean (* close_request) (EphyEmbed *embed); - - void (* new_document_now) (EphyEmbed *embed, - const char *uri); - - /* Methods */ - gboolean (* can_go_up) (EphyEmbed *embed); - GSList * (* get_go_up_list) (EphyEmbed *embed); - void (* go_up) (EphyEmbed *embed); - const char * (* get_title) (EphyEmbed *embed); - char * (* get_location) (EphyEmbed *embed, - gboolean toplevel); - const char * (* get_link_message) (EphyEmbed *embed); - char * (* get_js_status) (EphyEmbed *embed); - void (* get_security_level) (EphyEmbed *embed, - EphyEmbedSecurityLevel *level, - char **description); - void (* show_page_certificate) (EphyEmbed *embed); - void (* set_print_preview_mode) (EphyEmbed *embed, - gboolean mode); - int (* print_preview_n_pages) (EphyEmbed *embed); - void (* print_preview_navigate) (EphyEmbed *embed, - EphyEmbedPrintPreviewNavType type, - int page); - gboolean (* has_modified_forms) (EphyEmbed *embed); - EphyEmbedDocumentType (* get_document_type) (EphyEmbed *embed); - int (* get_load_percent) (EphyEmbed *embed); - gboolean (* get_load_status) (EphyEmbed *embed); - EphyEmbedNavigationFlags (* get_navigation_flags) (EphyEmbed *embed); - const char * (* get_typed_address) (EphyEmbed *embed); - void (* set_typed_address) (EphyEmbed *embed, - const char *address, - EphyEmbedAddressExpire expire); - const char * (* get_address) (EphyEmbed *embed); - const char * (* get_status_message) (EphyEmbed *embed); - GdkPixbuf * (* get_icon) (EphyEmbed *embed); - const char * (* get_icon_address) (EphyEmbed *embed); - gboolean (* get_is_blank) (EphyEmbed *embed); - const char * (* get_loading_title) (EphyEmbed *embed); - gboolean (* get_visibility) (EphyEmbed *embed); -}; - -GType ephy_embed_net_state_get_type (void); - -GType ephy_embed_chrome_get_type (void); - -GType ephy_embed_security_level_get_type (void); - -GType ephy_embed_document_type_get_type (void); - -GType ephy_embed_get_type (void); - -/* Base */ -const char *ephy_embed_get_title (EphyEmbed *embed); - -char *ephy_embed_get_location (EphyEmbed *embed, - gboolean toplevel); -const char *ephy_embed_get_link_message (EphyEmbed *embed); - -char *ephy_embed_get_js_status (EphyEmbed *embed); - -/* Navigation */ -gboolean ephy_embed_can_go_up (EphyEmbed *embed); - -GSList *ephy_embed_get_go_up_list (EphyEmbed *embed); - -void ephy_embed_go_up (EphyEmbed *embed); - -void ephy_embed_get_security_level (EphyEmbed *embed, - EphyEmbedSecurityLevel *level, - char **description); - -void ephy_embed_show_page_certificate (EphyEmbed *embed); - -/* Document type */ -EphyEmbedDocumentType ephy_embed_get_document_type (EphyEmbed *embed); - -/* Progress */ -int ephy_embed_get_load_percent (EphyEmbed *embed); - -/* Load status */ -gboolean ephy_embed_get_load_status (EphyEmbed *embed); - -/* Navigation flags */ - -EphyEmbedNavigationFlags ephy_embed_get_navigation_flags (EphyEmbed *embed); - -/* Typed address */ -const char *ephy_embed_get_typed_address (EphyEmbed *embed); -void ephy_embed_set_typed_address (EphyEmbed *embed, - const char *address, - EphyEmbedAddressExpire expire); -/* Address */ -const char * ephy_embed_get_address (EphyEmbed *embed); - -/* Status messages */ -const char * ephy_embed_get_status_message (EphyEmbed *embed); - -/* Icon and Icon Address */ - -GdkPixbuf * ephy_embed_get_icon (EphyEmbed *embed); -const char * ephy_embed_get_icon_address (EphyEmbed *embed); - -/* Is blank */ -gboolean ephy_embed_get_is_blank (EphyEmbed *embed); - -const char * ephy_embed_get_loading_title (EphyEmbed *embed); - -gboolean ephy_embed_get_visibility (EphyEmbed *embed); - -/* Print */ -void ephy_embed_set_print_preview_mode (EphyEmbed *embed, - gboolean preview_mode); - -int ephy_embed_print_preview_n_pages (EphyEmbed *embed); - -void ephy_embed_print_preview_navigate (EphyEmbed *embed, - EphyEmbedPrintPreviewNavType type, - int page); - -/* Misc. utility */ -gboolean ephy_embed_has_modified_forms (EphyEmbed *embed); - -G_END_DECLS - -#endif diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c index 10e6d3475..3f1c40179 100644 --- a/embed/ephy-web-view.c +++ b/embed/ephy-web-view.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * Copyright © 2008 Gustavo Noronha Silva + * Copyright © 2009 Igalia S.L. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,26 +21,1027 @@ #include "config.h" -#include "ephy-web-view.h" -#include "ephy-debug.h" -#include "ephy-embed-utils.h" - +#include +#include #include +#include #include +#include "eel-gconf-extensions.h" +#include "ephy-base-embed.h" +#include "ephy-debug.h" +#include "ephy-embed.h" +#include "ephy-embed-container.h" +#include "ephy-embed-prefs.h" +#include "ephy-embed-shell.h" +#include "ephy-embed-single.h" +#include "ephy-embed-type-builtins.h" +#include "ephy-embed-utils.h" +#include "ephy-marshal.h" +#include "ephy-permission-manager.h" +#include "ephy-favicon-cache.h" +#include "ephy-history.h" +#include "ephy-string.h" +#include "ephy-web-view.h" +#include "ephy-zoom.h" + static void ephy_web_view_class_init (EphyWebViewClass *klass); static void ephy_web_view_init (EphyWebView *gs); +#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 */ +#define EMPTY_PAGE _("Blank page") /* Title for the empty page */ + +struct _EphyWebViewPrivate { + EphyWebViewAddressExpire address_expire; + EphyWebViewSecurityLevel security_level; + EphyWebViewDocumentType document_type; + EphyWebViewNavigationFlags nav_flags; + + /* Flags */ + guint is_blank : 1; + guint is_loading : 1; + guint visibility : 1; + + char *address; + char *typed_address; + char *title; + int cur_requests; + int total_requests; + gint8 load_percent; + char *loading_title; + char *status_message; + char *link_message; + char *icon_address; + GdkPixbuf *icon; + + /* File watch */ + GFileMonitor *monitor; + gboolean monitor_directory; + guint reload_scheduled_id; + guint reload_delay_ticks; + + GSList *hidden_popups; + GSList *shown_popups; +}; + +typedef struct { + char *url; + char *name; + char *features; +} PopupInfo; + +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_EMBED_TITLE, + PROP_TYPED_ADDRESS, + PROP_VISIBLE, +}; + +#define EPHY_WEB_VIEW_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_WEB_VIEW, EphyWebViewPrivate)) + G_DEFINE_TYPE (EphyWebView, ephy_web_view, WEBKIT_TYPE_WEB_VIEW) +static guint +popup_blocker_n_hidden (EphyWebView *view) +{ + return g_slist_length (view->priv->hidden_popups); +} + +static void +popups_manager_free_info (PopupInfo *popup) +{ + g_free (popup->url); + g_free (popup->name); + g_free (popup->features); + g_slice_free (PopupInfo, popup); +} + +static void +popups_manager_show (PopupInfo *popup, + EphyWebView *view) +{ + EphyEmbedSingle *single; + + /* Only show popup with non NULL url */ + if (popup->url != NULL) { + single = EPHY_EMBED_SINGLE + (ephy_embed_shell_get_embed_single (embed_shell)); + + ephy_embed_single_open_window (single, EPHY_EMBED (view), popup->url, + popup->name, popup->features); + } + popups_manager_free_info (popup); +} + +static void +popups_manager_show_all (EphyWebView *view) +{ + LOG ("popup_blocker_show_all: view %p", view); + + g_slist_foreach (view->priv->hidden_popups, + (GFunc)popups_manager_show, view); + g_slist_free (view->priv->hidden_popups); + view->priv->hidden_popups = NULL; + + g_object_notify (G_OBJECT (view), "hidden-popup-count"); +} + +static char * +popups_manager_new_window_info (EphyEmbedContainer *container) +{ + EphyEmbed *embed; + EphyWebViewChrome chrome; + gboolean is_popup; + char *features; + + g_object_get (container, "chrome", &chrome, "is-popup", &is_popup, NULL); + g_return_val_if_fail (is_popup, g_strdup ("")); + + embed = ephy_embed_container_get_active_child (container); + g_return_val_if_fail (embed != NULL, g_strdup ("")); + + features = g_strdup_printf + ("width=%d,height=%d,menubar=%d,status=%d,toolbar=%d", + GTK_WIDGET (embed)->allocation.width, + GTK_WIDGET (embed)->allocation.height, + (chrome & EPHY_WEB_VIEW_CHROME_MENUBAR) > 0, + (chrome & EPHY_WEB_VIEW_CHROME_STATUSBAR) > 0, + (chrome & EPHY_WEB_VIEW_CHROME_TOOLBAR) > 0); + + return features; +} + +static void +popups_manager_add (EphyWebView *view, + const char *url, + const char *name, + const char *features) +{ + EphyWebViewPrivate *priv = view->priv; + PopupInfo *popup; + + LOG ("popups_manager_add: view %p, url %s, features %s", + view, url, features); + + popup = g_slice_new (PopupInfo); + + popup->url = 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 (view) > MAX_HIDDEN_POPUPS) {/* bug #160863 */ + /* Remove the oldest popup */ + GSList *l = view->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 (view), "hidden-popup-count"); + } +} + +static void +popups_manager_hide (EphyEmbedContainer *container, + EphyWebView *parent_view) +{ + EphyEmbed *embed; + char *location; + char *features; + + embed = ephy_embed_container_get_active_child (container); + g_return_if_fail (EPHY_IS_EMBED (embed)); + + location = ephy_web_view_get_location (EPHY_GET_EPHY_WEB_VIEW_FROM_EMBED (embed), TRUE); + if (location == NULL) return; + + features = popups_manager_new_window_info (container); + + popups_manager_add (parent_view, location, "" /* FIXME? maybe _blank? */, features); + + gtk_widget_destroy (GTK_WIDGET (container)); + + g_free (location); + g_free (features); +} + +static void +popups_manager_hide_all (EphyWebView *view) +{ + LOG ("popup_blocker_hide_all: view %p", view); + + g_slist_foreach (view->priv->shown_popups, + (GFunc)popups_manager_hide, view); + g_slist_free (view->priv->shown_popups); + view->priv->shown_popups = NULL; +} + +static void +ephy_web_view_set_popups_allowed (EphyWebView *view, + gboolean allowed) +{ + char *location; + EphyPermissionManager *manager; + EphyPermission permission; + + location = ephy_web_view_get_location (view, 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 (view); + } else { + popups_manager_hide_all (view); + } + + g_free (location); +} + +static gboolean +ephy_web_view_get_popups_allowed (EphyWebView *view) +{ + EphyPermissionManager *permission_manager; + EphyPermission response; + 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_web_view_get_location (view, 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 ("ephy_web_view_get_popups_allowed: view %p, allowed: %d", view, allow); + + return allow; +} + +static gboolean +popups_manager_remove_window (EphyWebView *view, + EphyEmbedContainer *container) +{ + view->priv->shown_popups = g_slist_remove (view->priv->shown_popups, + container); + + return FALSE; +} + +static void +popups_manager_add_window (EphyWebView *view, + EphyEmbedContainer *container) +{ + LOG ("popups_manager_add_window: view %p, container %p", view, container); + + view->priv->shown_popups = g_slist_prepend (view->priv->shown_popups, container); + + g_signal_connect_swapped (container, "destroy", + G_CALLBACK (popups_manager_remove_window), + view); +} + +static void +disconnect_popup (EphyEmbedContainer *container, + EphyWebView *view) +{ + g_signal_handlers_disconnect_by_func + (container, G_CALLBACK (popups_manager_remove_window), view); +} + +void +ephy_web_view_popups_manager_reset (EphyWebView *view) +{ + g_slist_foreach (view->priv->hidden_popups, + (GFunc)popups_manager_free_info, NULL); + g_slist_free (view->priv->hidden_popups); + view->priv->hidden_popups = NULL; + + g_slist_foreach (view->priv->shown_popups, + (GFunc)disconnect_popup, view); + g_slist_free (view->priv->shown_popups); + view->priv->shown_popups = NULL; + + g_object_notify (G_OBJECT (view), "hidden-popup-count"); + g_object_notify (G_OBJECT (view), "popups-allowed"); +} + +static void +ephy_web_view_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyWebViewPrivate *priv = EPHY_WEB_VIEW (object)->priv; + + switch (prop_id) { + case PROP_ADDRESS: + g_value_set_string (value, priv->address); + break; + case PROP_LOAD_STATUS: + g_value_set_boolean (value, priv->is_loading); + break; + case PROP_EMBED_TITLE: + g_value_set_string (value, priv->title); + break; + case PROP_TYPED_ADDRESS: + g_value_set_string (value, priv->typed_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, popup_blocker_n_hidden + (EPHY_WEB_VIEW (object))); + 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_NAVIGATION: + g_value_set_flags (value, priv->nav_flags); + break; + case PROP_POPUPS_ALLOWED: + g_value_set_boolean (value, ephy_web_view_get_popups_allowed + (EPHY_WEB_VIEW (object))); + 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_VISIBLE: + g_value_set_boolean (value, priv->visibility); + break; + default: + break; + } +} + +static void +ephy_web_view_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_ICON_ADDRESS: + ephy_web_view_set_icon_address (EPHY_WEB_VIEW (object), g_value_get_string (value)); + break; + case PROP_POPUPS_ALLOWED: + ephy_web_view_set_popups_allowed (EPHY_WEB_VIEW (object), g_value_get_boolean (value)); + break; + case PROP_TYPED_ADDRESS: + ephy_web_view_set_typed_address (EPHY_WEB_VIEW (object), g_value_get_string (value), + EPHY_WEB_VIEW_ADDRESS_EXPIRE_NOW); + break; + break; + case PROP_ADDRESS: + case PROP_DOCUMENT_TYPE: + case PROP_HIDDEN_POPUP_COUNT: + case PROP_ICON: + case PROP_LINK_MESSAGE: + case PROP_LOAD_PROGRESS: + case PROP_LOAD_STATUS: + case PROP_NAVIGATION: + case PROP_SECURITY: + case PROP_STATUS_MESSAGE: + case PROP_EMBED_TITLE: + case PROP_VISIBLE: + /* read only */ + break; + default: + break; + } +} + +static void +ephy_web_view_file_monitor_cancel (EphyWebView *view) +{ + EphyWebViewPrivate *priv = view->priv; + + if (priv->monitor != NULL) { + LOG ("Cancelling file monitor"); + + g_file_monitor_cancel (G_FILE_MONITOR (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 void +ephy_web_view_dispose (GObject *object) +{ + ephy_web_view_file_monitor_cancel (EPHY_WEB_VIEW (object)); + + G_OBJECT_CLASS (ephy_web_view_parent_class)->dispose (object); +} + +static void +ephy_web_view_finalize (GObject *object) +{ + EphyWebViewPrivate *priv = EPHY_WEB_VIEW (object)->priv; + + if (priv->icon != NULL) { + g_object_unref (priv->icon); + priv->icon = NULL; + } + + ephy_web_view_popups_manager_reset (EPHY_WEB_VIEW (object)); + + g_free (priv->address); + g_free (priv->typed_address); + g_free (priv->title); + g_free (priv->icon_address); + g_free (priv->status_message); + g_free (priv->link_message); + g_free (priv->loading_title); + + G_OBJECT_CLASS (ephy_web_view_parent_class)->finalize (object); +} + static void ephy_web_view_class_init (EphyWebViewClass *klass) { + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = ephy_web_view_dispose; + gobject_class->finalize = ephy_web_view_finalize; + gobject_class->get_property = ephy_web_view_get_property; + gobject_class->set_property = ephy_web_view_set_property; + + g_object_class_install_property (gobject_class, + PROP_ADDRESS, + g_param_spec_string ("address", + "Address", + "The view's address", + "", + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_TYPED_ADDRESS, + g_param_spec_string ("typed-address", + "Typed Address", + "The typed address", + "", + G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_EMBED_TITLE, + g_param_spec_string ("embed-title", + "Title", + "The view's title", + EMPTY_PAGE, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_SECURITY, + g_param_spec_enum ("security-level", + "Security Level", + "The view's security level", + EPHY_TYPE_WEB_VIEW_SECURITY_LEVEL, + EPHY_WEB_VIEW_STATE_IS_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_DOCUMENT_TYPE, + g_param_spec_enum ("document-type", + "Document Type", + "The view's documen type", + EPHY_TYPE_WEB_VIEW_DOCUMENT_TYPE, + EPHY_WEB_VIEW_DOCUMENT_HTML, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_LOAD_PROGRESS, + g_param_spec_int ("load-progress", + "Load progress", + "The view's load progress in percent", + 0, + 100, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_LOAD_STATUS, + g_param_spec_boolean ("load-status", + "Load status", + "The view's load status", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_NAVIGATION, + g_param_spec_flags ("navigation", + "Navigation flags", + "The view's navigation flags", + EPHY_TYPE_WEB_VIEW_NAVIGATION_FLAGS, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_STATUS_MESSAGE, + g_param_spec_string ("status-message", + "Status Message", + "The view's statusbar message", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_LINK_MESSAGE, + g_param_spec_string ("link-message", + "Link Message", + "The view's link message", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_ICON, + g_param_spec_object ("icon", + "Icon", + "The view icon's", + GDK_TYPE_PIXBUF, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_ICON_ADDRESS, + g_param_spec_string ("icon-address", + "Icon address", + "The view icon's address", + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB))); + g_object_class_install_property (gobject_class, + PROP_HIDDEN_POPUP_COUNT, + g_param_spec_int ("hidden-popup-count", + "Number of Blocked Popups", + "The view's number of blocked popup windows", + 0, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_POPUPS_ALLOWED, + g_param_spec_boolean ("popups-allowed", + "Popups Allowed", + "Whether popup windows are to be displayed", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_VISIBLE, + g_param_spec_boolean ("visibility", + "Visibility", + "The view's visibility", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + +/** + * EphyWebView::ge-new-window: + * @view: + * @new_view: the newly opened #EphyWebView + * + * The ::ge_new_window signal is emitted after a new window has been opened by + * the view. For example, when a JavaScript popup window is opened. + **/ + g_signal_new ("ge_new_window", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, new_window), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GTK_TYPE_WIDGET); +/** + * EphyWebView::ge-popup-blocked: + * @view: + * @address: The requested URL + * @target: The requested window name, e.g. "_blank" + * @features: The requested features: for example, "height=400,width=200" + * + * The ::ge_popup_blocked signal is emitted when the viewed web page requests + * a popup window (with javascript:open()) but popup windows are not allowed. + **/ + g_signal_new ("ge_popup_blocked", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyWebViewClass, popup_blocked), + NULL, NULL, + ephy_marshal_VOID__STRING_STRING_STRING, + G_TYPE_NONE, + 3, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); +/** + * EphyWebView::ge-context-menu: + * @embed: + * @event: the #EphyEmbedEvent which triggered this signal + * + * The ::ge_context_menu signal is emitted when a context menu is to be + * displayed. This will usually happen when the user right-clicks on a part of + * @embed. + **/ + g_signal_new ("ge_context_menu", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, context_menu), + g_signal_accumulator_true_handled, NULL, + ephy_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, + 1, + G_TYPE_OBJECT); +/** + * EphyWebView::ge-favicon: + * @embed: + * @address: the URL to @embed's web site's favicon + * + * The ::ge_favicon signal is emitted when @embed discovers that a favourite + * icon (favicon) is available for the site it is visiting. + **/ + g_signal_new ("ge_favicon", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyWebViewClass, favicon), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); +/** + * EphyWebView::ge-search-link: + * @embed: + * @type: the mime-type of the search description + * @title: the title of the news feed + * @address: the URL to @embed's web site's search description + * + * The ::ge_rss signal is emitted when @embed discovers that a search + * description is available for the site it is visiting. + **/ + g_signal_new ("ge_search_link", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyWebViewClass, search_link), + NULL, NULL, + ephy_marshal_VOID__STRING_STRING_STRING, + G_TYPE_NONE, + 3, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); + +/** + * EphyWebView::ge-feed-link: + * @embed: + * @type: the mime-type of the news feed + * @title: the title of the news feed + * @address: the URL to @embed's web site's news feed + * + * The ::ge_rss signal is emitted when @embed discovers that a news feed + * is available for the site it is visiting. + **/ + g_signal_new ("ge_feed_link", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyWebViewClass, feed_link), + NULL, NULL, + ephy_marshal_VOID__STRING_STRING_STRING, + G_TYPE_NONE, + 3, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); +/** + * EphyWebView::ge-dom-mouse-click: + * @embed: + * @event: the #EphyEmbedEvent which triggered this signal + * + * The ::ge_dom_mouse_click signal is emitted when the user clicks in @embed. + **/ + g_signal_new ("ge_dom_mouse_click", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, dom_mouse_click), + g_signal_accumulator_true_handled, NULL, + ephy_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, + 1, + G_TYPE_OBJECT); +/** + * EphyWebView::ge-dom-mouse-down: + * @embed: + * @event: the #EphyEmbedEvent which triggered this signal + * + * The ::ge_dom_mouse_down signal is emitted when the user depresses a mouse + * button. + **/ + g_signal_new ("ge_dom_mouse_down", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, dom_mouse_down), + g_signal_accumulator_true_handled, NULL, + ephy_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, + 1, + G_TYPE_OBJECT); +/** + * EphyWebView::ge-modal-alert: + * @embed: + * + * The ::ge-modal-alert signal is emitted when a DOM event will open a + * modal alert. + * + * Return %TRUE to prevent the dialog from being opened. + **/ + g_signal_new ("ge_modal_alert", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, modal_alert), + g_signal_accumulator_true_handled, NULL, + ephy_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, + 0); +/** + * EphyWebView::ge-modal-alert-closed: + * @embed: + * + * The ::ge-modal-alert-closed signal is emitted when a modal alert put up by a + * DOM event was closed. + **/ + g_signal_new ("ge_modal_alert_closed", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, modal_alert_closed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + +/** + * EphyWebView::ge-document-type: + * @embed: + * @type: the new document type + * + * The ::ge-document-type signal is emitted when @embed determines the type of its document. + **/ + g_signal_new ("ge_document_type", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyWebViewClass, document_type), + NULL, NULL, + g_cclosure_marshal_VOID__ENUM, + G_TYPE_NONE, + 1, + EPHY_TYPE_WEB_VIEW_DOCUMENT_TYPE); +/** + * EphyWebView::dom-content-loaded: + * @embed: + * + * The ::dom-content-loaded signal is emitted when + * the document has been loaded (excluding images and other loads initiated by this document). + * That's true also for frameset and all the frames within it. + **/ + g_signal_new ("dom_content_loaded", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyWebViewClass, dom_content_loaded), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); + +/** + * EphyWebView::ge-search-key-press: + * @embed: + * @event: the #GdkEventKey which triggered this signal + * + * The ::ge-search-key-press signal is emitted for keypresses which + * should be used for find implementations. + **/ + g_signal_new ("ge-search-key-press", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, search_key_press), + g_signal_accumulator_true_handled, NULL, + ephy_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, + 1, + GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + +/** + * EphyWebView::close-request + * @embed: + * + * The ::close signal is emitted when the embed request closing. + * Return %TRUE to prevent closing. You HAVE to process removal of the embed + * as soon as possible after that. + **/ + g_signal_new ("close-request", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, close_request), + g_signal_accumulator_true_handled, NULL, + ephy_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, + 0); +/** + * EphyWebView::content-blocked: + * @embed: + * @uri: blocked URI + * + * The ::content-blocked signal is emitted when an url has been blocked. + **/ + g_signal_new ("content-blocked", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyWebViewClass, content_blocked), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); +/** + * EphyWebView::new-document-now: + * @embed: + * @uri: URI of the new content + * + * The ::new-document-now signal is emitted when a new page content + * is being loaded into the browser. It's a good place to do view + * related changes, for example to restore the zoom level of a page + * or to set an user style sheet. + **/ + g_signal_new ("new-document-now", + EPHY_TYPE_WEB_VIEW, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyWebViewClass, new_document_now), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); + + g_type_class_add_private (gobject_class, sizeof (EphyWebViewPrivate)); +} + +static void +icon_cache_changed_cb (EphyFaviconCache *cache, + const char *address, + EphyWebView *view) +{ + const char *icon_address; + + g_return_if_fail (address != NULL); + + icon_address = ephy_web_view_get_icon_address (view); + + /* is this for us? */ + if (icon_address != NULL && + strcmp (icon_address, address) == 0) { + ephy_web_view_load_icon (view); + } +} + +static void +ge_document_type_cb (EphyWebView *view, + EphyWebViewDocumentType type, + gpointer user_data) +{ + if (view->priv->document_type != type) { + view->priv->document_type = type; + + g_object_notify (G_OBJECT (view), "document-type"); + } +} + +static void +ge_favicon_cb (EphyWebView *view, + const char *address, + gpointer user_data) +{ + ephy_web_view_set_icon_address (view, address); +} + +static void +ge_new_window_cb (EphyWebView *view, + EphyWebView *new_view, + gpointer user_data) +{ + EphyEmbedContainer *container; + + g_return_if_fail (new_view != NULL); + + container = EPHY_EMBED_CONTAINER (gtk_widget_get_toplevel (GTK_WIDGET (new_view))); + g_return_if_fail (container != NULL || !GTK_WIDGET_TOPLEVEL (container)); + + popups_manager_add_window (view, container); +} + +static void +ge_popup_blocked_cb (EphyWebView *view, + const char *url, + const char *name, + const char *features, + gpointer user_data) +{ + popups_manager_add (view, url, name, features); } static void ephy_web_view_init (EphyWebView *web_view) { + EphyWebViewPrivate *priv; + EphyFaviconCache *cache; + + priv = web_view->priv = EPHY_WEB_VIEW_GET_PRIVATE (web_view); + + priv->address_expire = EPHY_WEB_VIEW_ADDRESS_EXPIRE_NOW; + priv->is_blank = TRUE; + priv->title = g_strdup (EMPTY_PAGE); + priv->document_type = EPHY_WEB_VIEW_DOCUMENT_HTML; + priv->security_level = EPHY_WEB_VIEW_STATE_IS_UNKNOWN; + priv->monitor_directory = FALSE; + + g_signal_connect_object (web_view, "ge_document_type", + G_CALLBACK (ge_document_type_cb), + web_view, (GConnectFlags)0); + + g_signal_connect_object (web_view, "ge_favicon", + G_CALLBACK (ge_favicon_cb), + web_view, (GConnectFlags)0); + + g_signal_connect_object (web_view, "ge_new_window", + G_CALLBACK (ge_new_window_cb), + web_view, (GConnectFlags)0); + + g_signal_connect_object (web_view, "ge_popup_blocked", + G_CALLBACK (ge_popup_blocked_cb), + web_view, (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), + web_view, (GConnectFlags)0); } /** @@ -137,3 +1139,986 @@ ephy_web_view_copy_back_history (EphyWebView *source, item = webkit_web_back_forward_list_get_current_item (source_bflist); webkit_web_back_forward_list_add_item (dest_bflist, g_object_ref (item)); } + +void +ephy_web_view_set_address (EphyWebView *embed, + const char *address) +{ + EphyWebViewPrivate *priv = embed->priv; + GObject *object = G_OBJECT (embed); + + g_free (priv->address); + priv->address = g_strdup (address); + + priv->is_blank = address == NULL || + strcmp (address, "about:blank") == 0; + + if (priv->is_loading && + priv->address_expire == EPHY_WEB_VIEW_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) +{ + if (g_str_has_prefix (address, "file://")) + return g_strdup (address + 7); + else + return ephy_string_get_host_name (address); +} + +void +ephy_web_view_set_title (EphyWebView *view, + const char *view_title) +{ + EphyWebViewPrivate *priv = view->priv; + char *title = g_strdup (view_title); + + 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 = g_strdup (EMPTY_PAGE); + priv->is_blank = TRUE; + } + } else if (priv->is_blank) { + g_free (title); + title = g_strdup (EMPTY_PAGE); + } + + g_free (priv->title); + priv->title = ephy_string_shorten (title, MAX_TITLE_LENGTH); + + g_object_notify (G_OBJECT (view), "embed-title"); +} + +/** + * ephy_web_view_get_is_blank: + * @view: an #EphyWebView + * + * Returns whether the @view's address is "blank". + * + * Return value: %TRUE if the @view's address is "blank" + **/ +gboolean +ephy_web_view_get_is_blank (EphyWebView *view) +{ + return view->priv->is_blank; +} + +/** + * ephy_web_view_get_address: + * @view: an #EphyWebView + * + * Returns the address of the currently loaded page. + * + * Return value: @view's address. Will never be %NULL. + **/ +const char * +ephy_web_view_get_address (EphyWebView *view) +{ + EphyWebViewPrivate *priv = view->priv; + return priv->address ? priv->address : "about:blank"; +} + +/** + * ephy_web_view_get_title: + * @view: an #EphyWebView + * + * Return value: the title of the web page displayed in @view + **/ +const char * +ephy_web_view_get_title (EphyWebView *view) +{ + return view->priv->title; +} + +static void +ensure_page_info (EphyWebView *view, const char *address) +{ + EphyWebViewPrivate *priv = view->priv; + + if ((priv->address == NULL || priv->address[0] == '\0') && + priv->address_expire == EPHY_WEB_VIEW_ADDRESS_EXPIRE_NOW) { + ephy_web_view_set_address (view, address); + } + + /* FIXME huh?? */ + if (priv->title == NULL || priv->title[0] == '\0') { + ephy_web_view_set_title (view, NULL); + } +} + +static void +update_net_state_message (EphyWebView *view, const char *uri, EphyWebViewNetState flags) +{ + const char *msg = NULL; + char *host = NULL; + + if (uri != NULL) + host = ephy_string_get_host_name (uri); + + if (host == NULL) goto out; + + /* IS_REQUEST and IS_NETWORK can be both set */ + if (flags & EPHY_WEB_VIEW_STATE_IS_REQUEST) { + if (flags & EPHY_WEB_VIEW_STATE_REDIRECTING) { + msg = _ ("Redirecting to “%s”…"); + } else if (flags & EPHY_WEB_VIEW_STATE_TRANSFERRING) { + msg = _ ("Transferring data from “%s”…"); + } else if (flags & EPHY_WEB_VIEW_STATE_NEGOTIATING) { + msg = _ ("Waiting for authorization from “%s”…"); + } + } + + if (flags & EPHY_WEB_VIEW_STATE_IS_NETWORK) { + if (flags & EPHY_WEB_VIEW_STATE_START) { + msg = _ ("Loading “%s”…"); + } + } + + if ((flags & EPHY_WEB_VIEW_STATE_IS_NETWORK) && + (flags & EPHY_WEB_VIEW_STATE_STOP)) { + g_free (view->priv->status_message); + view->priv->status_message = NULL; + g_object_notify (G_OBJECT (view), "status-message"); + + } else if (msg != NULL) { + g_free (view->priv->status_message); + g_free (view->priv->loading_title); + view->priv->status_message = g_strdup_printf (msg, host); + view->priv->loading_title = g_strdup_printf (msg, host); + g_object_notify (G_OBJECT (view), "status-message"); + g_object_notify (G_OBJECT (view), "embed-title"); + } + + out: + g_free (host); +} + +static void +update_navigation_flags (EphyWebView *view) +{ + EphyWebViewPrivate *priv = view->priv; + guint flags = 0; + WebKitWebView *web_view = WEBKIT_WEB_VIEW (view); + + if (ephy_web_view_can_go_up (view)) { + flags |= EPHY_WEB_VIEW_NAV_UP; + } + + if (webkit_web_view_can_go_back (web_view)) { + flags |= EPHY_WEB_VIEW_NAV_BACK; + } + + if (webkit_web_view_can_go_forward (web_view)) { + flags |= EPHY_WEB_VIEW_NAV_FORWARD; + } + + if (priv->nav_flags != (EphyWebViewNavigationFlags)flags) { + priv->nav_flags = (EphyWebViewNavigationFlags)flags; + + g_object_notify (G_OBJECT (view), "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; +} + +void +ephy_web_view_set_load_percent (EphyWebView *view, int percent) +{ + EphyWebViewPrivate *priv = view->priv; + + if (percent != priv->load_percent) { + priv->load_percent = percent; + + g_object_notify (G_OBJECT (view), "load-progress"); + } +} + +static void +build_progress_from_requests (EphyWebView *view, EphyWebViewNetState state) +{ + int load_percent; + + if (state & EPHY_WEB_VIEW_STATE_IS_REQUEST) { + if (state & EPHY_WEB_VIEW_STATE_START) { + view->priv->total_requests++; + } else if (state & EPHY_WEB_VIEW_STATE_STOP) { + view->priv->cur_requests++; + } + + load_percent = build_load_percent (view->priv->cur_requests, + view->priv->total_requests); + + ephy_web_view_set_load_percent (view, load_percent); + } +} + +static void +ephy_web_view_set_load_status (EphyWebView *view, gboolean status) +{ + EphyWebViewPrivate *priv = view->priv; + guint is_loading; + + is_loading = status != FALSE; + + if (is_loading != priv->is_loading) { + priv->is_loading = is_loading; + + g_object_notify (G_OBJECT (view), "load-status"); + } +} + +void +ephy_web_view_update_from_net_state (EphyWebView *view, + const char *uri, + EphyWebViewNetState state) +{ + EphyWebViewPrivate *priv = view->priv; + + update_net_state_message (view, uri, state); + + if (state & EPHY_WEB_VIEW_STATE_IS_NETWORK) { + if (state & EPHY_WEB_VIEW_STATE_START) { + GObject *object = G_OBJECT (view); + + g_object_freeze_notify (object); + + priv->total_requests = 0; + priv->cur_requests = 0; + + ephy_web_view_set_load_percent (view, 0); + ephy_web_view_set_load_status (view, TRUE); + + ensure_page_info (view, uri); + + g_object_notify (object, "embed-title"); + + g_object_thaw_notify (object); + } else if (state & EPHY_WEB_VIEW_STATE_STOP) { + GObject *object = G_OBJECT (view); + + g_object_freeze_notify (object); + + ephy_web_view_set_load_percent (view, 100); + ephy_web_view_set_load_status (view, FALSE); + + g_free (priv->loading_title); + priv->loading_title = NULL; + + priv->address_expire = EPHY_WEB_VIEW_ADDRESS_EXPIRE_NOW; + + g_object_notify (object, "embed-title"); + + g_object_thaw_notify (object); + } + + update_navigation_flags (view); + } + + build_progress_from_requests (view, state); +} + +void +ephy_web_view_set_loading_title (EphyWebView *view, + const char *title, + gboolean is_address) +{ + EphyWebViewPrivate *priv = view->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 gboolean +ephy_web_view_file_monitor_reload_cb (EphyWebView *view) +{ + EphyWebViewPrivate *priv = view->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_web_view_get_address (view)); + webkit_web_view_reload (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (view)); + + /* don't run again */ + return FALSE; +} + +static void +ephy_web_view_file_monitor_cb (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + EphyWebView *view) +{ + gboolean should_reload; + EphyWebViewPrivate *priv = view->priv; + + switch (event_type) { + /* These events will always trigger a reload: */ + case G_FILE_MONITOR_EVENT_CHANGED: + case G_FILE_MONITOR_EVENT_CREATED: + should_reload = TRUE; + break; + + /* These events will only trigger a reload for directories: */ + case G_FILE_MONITOR_EVENT_DELETED: + case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: + should_reload = priv->monitor_directory; + break; + + /* These events don't trigger a reload: */ + case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: + case G_FILE_MONITOR_EVENT_UNMOUNTED: + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + 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_web_view_file_monitor_reload_cb, view); + } + } +} + +static void +ephy_web_view_update_file_monitor (EphyWebView *view, + const gchar *address) +{ + EphyWebViewPrivate *priv = view->priv; + gboolean local; + gchar *anchor; + gchar *url; + GFile *file; + GFileType file_type; + GFileInfo *file_info; + GFileMonitor *monitor = NULL; + + if (priv->monitor != NULL && + priv->address != NULL && address != NULL && + strcmp (priv->address, address) == 0) { + /* same address, no change needed */ + return; + } + + ephy_web_view_file_monitor_cancel (view); + + local = g_str_has_prefix (address, "file://"); + if (local == FALSE) return; + + /* strip off anchors */ + anchor = strchr (address, '#'); + if (anchor != NULL) { + url = g_strndup (address, anchor - address); + } else { + url = g_strdup (address); + } + + file = g_file_new_for_uri (url); + file_info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_TYPE, + 0, NULL, NULL); + if (file_info == NULL) { + g_object_unref (file); + g_free (url); + return; + } + + file_type = g_file_info_get_file_type (file_info); + g_object_unref (file_info); + + if (file_type == G_FILE_TYPE_DIRECTORY) { + monitor = g_file_monitor_directory (file, 0, NULL, NULL); + g_signal_connect (monitor, "changed", + G_CALLBACK (ephy_web_view_file_monitor_cb), + view); + priv->monitor_directory = TRUE; + LOG ("Installed monitor for directory '%s'", url); + } + else if (file_type == G_FILE_TYPE_REGULAR) { + monitor = g_file_monitor_file (file, 0, NULL, NULL); + g_signal_connect (monitor, "changed", + G_CALLBACK (ephy_web_view_file_monitor_cb), + view); + priv->monitor_directory = FALSE; + LOG ("Installed monitor for file '%s'", url); + } + priv->monitor = monitor; + g_object_unref (file); + g_free (url); +} + +void +ephy_web_view_location_changed (EphyWebView *view, + const char *location) +{ + GObject *object = G_OBJECT (view); + + g_object_freeze_notify (object); + + /* do this up here so we still have the old address around */ + ephy_web_view_update_file_monitor (view, 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_web_view_set_address (view, NULL); + ephy_web_view_set_title (view, EMPTY_PAGE); + } else { + char *view_address; + + /* we do this to get rid of an eventual password in the URL */ + view_address = ephy_web_view_get_location (view, TRUE); + ephy_web_view_set_address (view, view_address); + ephy_web_view_set_loading_title (view, view_address, TRUE); + g_free (view_address); + } + + ephy_web_view_set_link_message (view, NULL); + ephy_web_view_set_icon_address (view, NULL); + update_navigation_flags (view); + + g_object_notify (object, "embed-title"); + + g_object_thaw_notify (object); +} + +void +ephy_web_view_set_icon_address (EphyWebView *view, + const char *address) +{ + GObject *object = G_OBJECT (view); + EphyWebViewPrivate *priv = view->priv; + 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) { + history = EPHY_HISTORY (ephy_embed_shell_get_global_history (embed_shell)); + ephy_history_set_icon (history, priv->address, priv->icon_address); + + ephy_web_view_load_icon (view); + } + + g_object_notify (object, "icon-address"); +} + +/** + * ephy_web_view_can_go_up: + * @view: an #EphyWebView + * + * Returns whether @view can travel to a higher-level directory on the server. + * For example, for http://www.example.com/subdir/index.html, returns %TRUE; for + * http://www.example.com/index.html, returns %FALSE. + * + * Return value: %TRUE if @view can browse to a higher-level directory + **/ +gboolean +ephy_web_view_can_go_up (EphyWebView *view) +{ + return FALSE; +} + +/** + * ephy_web_view_get_load_status: + * @view: an #EphyWebView + * + * Returns whether the web page in @view has finished loading. A web page is + * only finished loading after all images, styles, and other dependencies have + * been downloaded and rendered. + * + * Return value: %TRUE if the page is still loading, %FALSE if complete + **/ +gboolean +ephy_web_view_get_load_status (EphyWebView *view) +{ + return view->priv->is_loading; +} + +const char * +ephy_web_view_get_loading_title (EphyWebView *view) +{ + return view->priv->loading_title; +} + +/** + * ephy_web_view_get_icon_address: + * @view: an #EphyWebView + * + * Returns a URL which points to @view's site icon. + * + * Return value: the URL of @view's site icon + **/ +const char * +ephy_web_view_get_icon_address (EphyWebView *view) +{ + return view->priv->icon_address; +} + +/** + * ephy_wew_view_get_icon: + * @view: an #EphyWebView + * + * Returns the view's site icon as a #GdkPixbuf, + * or %NULL if it is not available. + * + * Return value: a the view's site icon + **/ +GdkPixbuf * +ephy_web_view_get_icon (EphyWebView *view) +{ + return view->priv->icon; +} + +/** + * ephy_web_view_get_document_type: + * @view: an #EphyWebView + * + * Returns the type of document loaded in the @view + * + * Return value: the #EphyWebViewDocumentType + **/ +EphyWebViewDocumentType +ephy_web_view_get_document_type (EphyWebView *view) +{ + return view->priv->document_type; +} + +/** + * ephy_web_view_get_load_percent: + * @view: an #EphyWebView + * + * Returns the page load percentage (displayed in the progressbar). + * + * Return value: a percentage from 0 to 100. + **/ +int +ephy_web_view_get_load_percent (EphyWebView *view) +{ + return view->priv->load_percent; +} + +/** + * ephy_web_view_get_navigation_flags: + * @view: an #EphyWebView + * + * Returns @view's navigation flags. + * + * Return value: @view's navigation flags + **/ +EphyWebViewNavigationFlags +ephy_web_view_get_navigation_flags (EphyWebView *view) +{ + return view->priv->nav_flags; +} + +/** + * ephy_web_view_get_status_message: + * @view: an #EphyWebView + * + * Returns the message displayed in @view's #EphyWindow's + * #EphyStatusbar. If the user is hovering the mouse over a hyperlink, + * this function will return the same value as + * ephy_web_view_get_link_message(). Otherwise, it will return a network + * status message, or NULL. + * + * The message returned has a limited lifetime, and so should be copied with + * g_strdup() if it must be stored. + * + * Return value: The current statusbar message + **/ +const char * +ephy_web_view_get_status_message (EphyWebView *view) +{ + EphyWebViewPrivate *priv = view->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; + } +} + +/** + * ephy_web_view_get_link_message: + * @view: an #EphyWebView + * + * When the user is hovering the mouse over a hyperlink, returns the URL of the + * hyperlink. + * + * Return value: the URL of the link over which the mouse is hovering + **/ +const char * +ephy_web_view_get_link_message (EphyWebView *view) +{ + g_return_val_if_fail (EPHY_IS_WEB_VIEW (view), NULL); + + return view->priv->link_message; +} + +/** + * ephy_web_view_get_visibility: + * @view: an #EphyWebView + * + * Returns whether the @view's toplevel is visible or not. Used + * mostly for popup visibility management. + * + * Return value: %TRUE if @view's "visibility" property is set + **/ +gboolean +ephy_web_view_get_visibility (EphyWebView *view) +{ + return view->priv->visibility; +} + +void +ephy_web_view_set_link_message (EphyWebView *view, + char *link_message) +{ + EphyWebViewPrivate *priv = view->priv; + + g_free (priv->link_message); + + priv->link_message = ephy_embed_utils_link_message_parse (link_message); + + g_object_notify (G_OBJECT (view), "status-message"); + g_object_notify (G_OBJECT (view), "link-message"); +} + +void +ephy_web_view_load_icon (EphyWebView *view) +{ + EphyWebViewPrivate *priv = view->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 (view), "icon"); +} + +void +ephy_web_view_set_security_level (EphyWebView *view, + EphyWebViewSecurityLevel level) +{ + EphyWebViewPrivate *priv = view->priv; + + if (priv->security_level != level) { + priv->security_level = level; + + g_object_notify (G_OBJECT (view), "security-level"); + } +} + +void +ephy_web_view_set_visibility (EphyWebView *view, + gboolean visibility) +{ + EphyWebViewPrivate *priv = view->priv; + + if (priv->visibility != visibility) { + priv->visibility = visibility; + + g_object_notify (G_OBJECT (view), "visibility"); + } +} + +/** + * ephy_web_view_get_typed_address: + * @view: an #EphyWebView + * + * Returns the text that @view's #EphyWindow will display in its location toolbar + * entry when @view is selected. + * + * This is not guaranteed to be the same as @view's location, + * available through ephy_web_view_get_location(). As the user types a new address + * into the location entry, ephy_web_view_get_location()'s returned string will + * change. + * + * Return value: @view's #EphyWindow's location entry when @view is selected + **/ +const char * +ephy_web_view_get_typed_address (EphyWebView *view) +{ + return view->priv->typed_address; +} + +/** + * ephy_web_view_set_typed_address: + * @view: an #EphyWebView + * @address: the new typed address, or %NULL to clear it + * @expire: when to expire this address_expire + * + * Sets the text that @view's #EphyWindow will display in its location toolbar + * entry when @view is selected. + **/ +void +ephy_web_view_set_typed_address (EphyWebView *view, + const char *address, + EphyWebViewAddressExpire expire) +{ + EphyWebViewPrivate *priv = EPHY_WEB_VIEW (view)->priv; + + g_free (priv->typed_address); + priv->typed_address = g_strdup (address); + + if (expire == EPHY_WEB_VIEW_ADDRESS_EXPIRE_CURRENT && + !priv->is_loading) { + priv->address_expire = EPHY_WEB_VIEW_ADDRESS_EXPIRE_NOW; + } else { + priv->address_expire = expire; + } + + g_object_notify (G_OBJECT (view), "typed-address"); +} + +/** + * ephy_web_view_has_modified_forms: + * @view: an #EphyWebView + * + * Returns %TRUE if the user has modified <input> or <textarea> + * values in @view's loaded document. + * + * Return value: %TRUE if @view has user-modified forms + **/ +gboolean +ephy_web_view_has_modified_forms (EphyWebView *view) +{ + return FALSE; +} + +/** + * ephy_web_view_get_location: + * @view: an #EphyWebView + * @toplevel: %FALSE to return the location of the focused frame only + * + * Returns the URL of the web page displayed in @view. + * + * If the web page contains frames, @toplevel will determine which location to + * retrieve. If @toplevel is %TRUE, the return value will be the location of the + * frameset document. If @toplevel is %FALSE, the return value will be the + * location of the currently-focused frame. + * + * Return value: the URL of the web page displayed in @view + **/ +char * +ephy_web_view_get_location (EphyWebView *view, + gboolean toplevel) +{ + /* FIXME: follow the toplevel parameter */ + WebKitWebFrame *web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (view)); + return g_strdup (webkit_web_frame_get_uri (web_frame)); +} + +/** + * ephy_web_view_go_up: + * @view: an #EphyWebView + * + * Moves @view one level up in its web page's directory hierarchy. + **/ +void +ephy_web_view_go_up (EphyWebView *view) +{ +} + +/** + * ephy_web_view_get_js_status: + * @view: an #EphyWebView + * + * Displays the message JavaScript is attempting to display in the statusbar. + * + * Note that Epiphany does not display JavaScript statusbar messages. + * + * Return value: a message from JavaScript meant to be displayed in the + * statusbar + **/ +char * +ephy_web_view_get_js_status (EphyWebView *view) +{ + return NULL; +} + +/** + * ephy_web_view_get_security_level: + * @view: an #EphyWebView + * @level: return value of security level + * @description: return value of the description of the security level + * + * Fetches the #EphyWebViewSecurityLevel and a newly-allocated string description + * of the security state of @view. + **/ +void +ephy_web_view_get_security_level (EphyWebView *view, + EphyWebViewSecurityLevel *level, + char **description) +{ + if (level) { + const gchar *uri = ephy_web_view_get_address (view); + + /* FIXME: as a temporary workaround, determine security level + based on the existence of a 'https' prefix for the URI */ + if (uri && g_str_has_prefix(uri, "https")) + *level = EPHY_WEB_VIEW_STATE_IS_SECURE_HIGH; + else + *level = EPHY_WEB_VIEW_STATE_IS_UNKNOWN; + } +} + +/** + * ephy_web_view_show_page_certificate: + * @view: an #EphyWebView + * + * Shows a dialogue displaying the certificate of the currently loaded page + * of @view, if it was loaded over a secure connection; else does nothing. + **/ +void +ephy_web_view_show_page_certificate (EphyWebView *view) +{ +} + +/** + * ephy_web_view_set_print_preview_mode: + * @view: an #EphyWebView + * @preview_mode: Whether the print preview mode is enabled. + * + * Enable and disable the print preview mode. + **/ +void +ephy_web_view_set_print_preview_mode (EphyWebView *view, + gboolean preview_mode) +{ +} + +/** + * ephy_web_view_print_preview_n_pages: + * @view: an #EphyWebView + * + * Returns the number of pages which would appear in @view's loaded document + * if it were to be printed. + * + * Return value: the number of pages in @view's loaded document + **/ +int +ephy_web_view_print_preview_n_pages (EphyWebView *view) +{ + return 0; +} + +/** + * ephy_web_view_print_preview_navigate: + * @view: an #EphyWebView + * @type: an #EphyPrintPreviewNavType which determines where to navigate + * @page: if @type is %EPHY_WEB_VIEW_PRINTPREVIEW_GOTO_PAGENUM, the desired page number + * + * Navigates @view's print preview. + **/ +void +ephy_web_view_print_preview_navigate (EphyWebView *view, + EphyWebViewPrintPreviewNavType type, + int page) +{ +} + +/** + * ephy_web_view_get_go_up_list: + * @view: an #EphyWebView + * + * Returns a list of (%char *) URLs to higher-level directories on the same + * server, in order of deepest to shallowest. For example, given + * "http://www.example.com/dir/subdir/file.html", will return a list containing + * "http://www.example.com/dir/subdir/", "http://www.example.com/dir/" and + * "http://www.example.com/". + * + * Return value: a list of URLs higher up in @view's web page's directory + * hierarchy + **/ +GSList * +ephy_web_view_get_go_up_list (EphyWebView *view) +{ + return NULL; +} diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h index 898133040..b804670a0 100644 --- a/embed/ephy-web-view.h +++ b/embed/ephy-web-view.h @@ -43,6 +43,76 @@ typedef struct _EphyWebViewClass EphyWebViewClass; typedef struct _EphyWebView EphyWebView; typedef struct _EphyWebViewPrivate EphyWebViewPrivate; +typedef enum +{ + EPHY_WEB_VIEW_NAV_UP = 1 << 0, + EPHY_WEB_VIEW_NAV_BACK = 1 << 1, + EPHY_WEB_VIEW_NAV_FORWARD = 1 << 2 +} EphyWebViewNavigationFlags; + +typedef enum +{ + EPHY_WEB_VIEW_STATE_UNKNOWN = 0, + EPHY_WEB_VIEW_STATE_START = 1 << 0, + EPHY_WEB_VIEW_STATE_REDIRECTING = 1 << 1, + EPHY_WEB_VIEW_STATE_TRANSFERRING = 1 << 2, + EPHY_WEB_VIEW_STATE_NEGOTIATING = 1 << 3, + EPHY_WEB_VIEW_STATE_STOP = 1 << 4, + + EPHY_WEB_VIEW_STATE_IS_REQUEST = 1 << 5, + EPHY_WEB_VIEW_STATE_IS_DOCUMENT = 1 << 6, + EPHY_WEB_VIEW_STATE_IS_NETWORK = 1 << 7, + EPHY_WEB_VIEW_STATE_IS_WINDOW = 1 << 8, + EPHY_WEB_VIEW_STATE_RESTORING = 1 << 9 +} EphyWebViewNetState; + +typedef enum +{ + EPHY_WEB_VIEW_CHROME_MENUBAR = 1 << 0, + EPHY_WEB_VIEW_CHROME_TOOLBAR = 1 << 1, + EPHY_WEB_VIEW_CHROME_STATUSBAR = 1 << 2, + EPHY_WEB_VIEW_CHROME_BOOKMARKSBAR = 1 << 3 +} EphyWebViewChrome; + +#define EPHY_WEB_VIEW_CHROME_ALL (EPHY_WEB_VIEW_CHROME_MENUBAR | \ + EPHY_WEB_VIEW_CHROME_TOOLBAR | \ + EPHY_WEB_VIEW_CHROME_STATUSBAR | \ + EPHY_WEB_VIEW_CHROME_BOOKMARKSBAR) + +typedef enum +{ + EPHY_WEB_VIEW_PRINTPREVIEW_GOTO_PAGENUM = 0, + EPHY_WEB_VIEW_PRINTPREVIEW_PREV_PAGE = 1, + EPHY_WEB_VIEW_PRINTPREVIEW_NEXT_PAGE = 2, + EPHY_WEB_VIEW_PRINTPREVIEW_HOME = 3, + EPHY_WEB_VIEW_PRINTPREVIEW_END = 4 +} EphyWebViewPrintPreviewNavType; + +typedef enum +{ + EPHY_WEB_VIEW_STATE_IS_UNKNOWN, + EPHY_WEB_VIEW_STATE_IS_INSECURE, + EPHY_WEB_VIEW_STATE_IS_BROKEN, + EPHY_WEB_VIEW_STATE_IS_SECURE_LOW, + EPHY_WEB_VIEW_STATE_IS_SECURE_MED, + EPHY_WEB_VIEW_STATE_IS_SECURE_HIGH +} EphyWebViewSecurityLevel; + +typedef enum +{ + EPHY_WEB_VIEW_DOCUMENT_HTML, + EPHY_WEB_VIEW_DOCUMENT_XML, + EPHY_WEB_VIEW_DOCUMENT_IMAGE, + EPHY_WEB_VIEW_DOCUMENT_OTHER +} EphyWebViewDocumentType; + +typedef enum +{ + EPHY_WEB_VIEW_ADDRESS_EXPIRE_NOW, + EPHY_WEB_VIEW_ADDRESS_EXPIRE_NEXT, + EPHY_WEB_VIEW_ADDRESS_EXPIRE_CURRENT +} EphyWebViewAddressExpire; + struct _EphyWebView { WebKitWebView parent; @@ -54,20 +124,120 @@ struct _EphyWebView struct _EphyWebViewClass { WebKitWebViewClass parent_class; -}; -GType ephy_web_view_get_type (void); - -GtkWidget *ephy_web_view_new (void); - -void ephy_web_view_load_request (EphyWebView *web_view, - WebKitNetworkRequest *request); + /* Signals */ + int (* context_menu) (EphyWebView *view, + EphyEmbedEvent *event); + void (* favicon) (EphyWebView *view, + const char *location); + void (* feed_link) (EphyWebView *view, + const char *type, + const char *title, + const char *address); + void (* search_link) (EphyWebView *view, + const char *type, + const char *title, + const char *address); + gboolean (* dom_mouse_click) (EphyWebView *view, + EphyEmbedEvent *event); + gboolean (* dom_mouse_down) (EphyWebView *view, + EphyEmbedEvent *event); + void (* dom_content_loaded) (EphyWebView *view, + gpointer event); + void (* popup_blocked) (EphyWebView *view, + const char *address, + const char *target, + const char *features); + void (* content_blocked) (EphyWebView *view, + const char *uri); + gboolean (* modal_alert) (EphyWebView *view); + void (* modal_alert_closed) (EphyWebView *view); + void (* document_type) (EphyWebView *view, + EphyWebViewDocumentType type); + void (* new_window) (EphyWebView *view, + EphyWebView *new_view); + gboolean (* search_key_press) (EphyWebView *view, + GdkEventKey *event); + gboolean (* close_request) (EphyWebView *view); + + void (* new_document_now) (EphyWebView *view, + const char *uri); +}; -void ephy_web_view_load_url (EphyWebView *web_view, - const char *url); +GType ephy_web_view_get_type (void); +GType ephy_web_view_net_state_get_type (void); +GType ephy_web_view_chrome_get_type (void); +GType ephy_web_view_security_level_get_type (void); +GtkWidget * ephy_web_view_new (void); +void ephy_web_view_load_request (EphyWebView *view, + WebKitNetworkRequest *request); +void ephy_web_view_load_url (EphyWebView *view, + const char *url); +void ephy_web_view_copy_back_history (EphyWebView *source, + EphyWebView *dest); +gboolean ephy_web_view_get_load_status (EphyWebView *view); +const char * ephy_web_view_get_loading_title (EphyWebView *view); +GdkPixbuf * ephy_web_view_get_icon (EphyWebView *view); +EphyWebViewDocumentType ephy_web_view_get_document_type (EphyWebView *view); +int ephy_web_view_get_load_percent (EphyWebView *view); +EphyWebViewNavigationFlags ephy_web_view_get_navigation_flags (EphyWebView *view); +const char * ephy_web_view_get_status_message (EphyWebView *view); +const char * ephy_web_view_get_link_message (EphyWebView *view); +gboolean ephy_web_view_get_visibility (EphyWebView *view); +void ephy_web_view_set_link_message (EphyWebView *view, + char *link_message); +void ephy_web_view_load_icon (EphyWebView *view); +void ephy_web_view_load_icon (EphyWebView *view); +void ephy_web_view_set_security_level (EphyWebView *view, + EphyWebViewSecurityLevel level); +void ephy_web_view_set_visibility (EphyWebView *view, + gboolean visibility); +const char * ephy_web_view_get_typed_address (EphyWebView *view); +void ephy_web_view_set_typed_address (EphyWebView *view, + const char *address, + EphyWebViewAddressExpire expire); +gboolean ephy_web_view_get_is_blank (EphyWebView *view); +gboolean ephy_web_view_has_modified_forms (EphyWebView *view); +char * ephy_web_view_get_location (EphyWebView *view, + gboolean toplevel); +void ephy_web_view_go_up (EphyWebView *view); +char * ephy_web_view_get_js_status (EphyWebView *view); +void ephy_web_view_get_security_level (EphyWebView *view, + EphyWebViewSecurityLevel *level, + char **description); +void ephy_web_view_show_page_certificate (EphyWebView *view); +void ephy_web_view_set_print_preview_mode (EphyWebView *view, + gboolean preview_mode); +int ephy_web_view_print_preview_n_pages (EphyWebView *view); +void ephy_web_view_print_preview_navigate (EphyWebView *view, + EphyWebViewPrintPreviewNavType type, + int page); +GSList * ephy_web_view_get_go_up_list (EphyWebView *view); +void ephy_web_view_set_title (EphyWebView *view, + const char *view_title); +const char * ephy_web_view_get_icon_address (EphyWebView *view); +const char * ephy_web_view_get_title (EphyWebView *view); +gboolean ephy_web_view_can_go_up (EphyWebView *view); +const char * ephy_web_view_get_address (EphyWebView *view); + + +/* These should be private */ +void ephy_web_view_set_address (EphyWebView *embed, + const char *address); +void ephy_web_view_set_icon_address (EphyWebView *view, + const char *address); +void ephy_web_view_update_from_net_state (EphyWebView *view, + const char *uri, + EphyWebViewNetState state); +void ephy_web_view_location_changed (EphyWebView *view, + const char *location); +void ephy_web_view_set_load_percent (EphyWebView *view, + int percent); +void ephy_web_view_set_loading_title (EphyWebView *view, + const char *title, + gboolean is_address); +void ephy_web_view_popups_manager_reset (EphyWebView *view); -void ephy_web_view_copy_back_history (EphyWebView *source, - EphyWebView *dest); G_END_DECLS diff --git a/embed/webkit/webkit-embed.c b/embed/webkit/webkit-embed.c index c7e5f9f54..cff761572 100644 --- a/embed/webkit/webkit-embed.c +++ b/embed/webkit/webkit-embed.c @@ -55,7 +55,6 @@ static void webkit_embed_class_init (WebKitEmbedClass *klass); static void webkit_embed_init (WebKitEmbed *gs); -static void ephy_embed_iface_init (EphyEmbedIface *iface); #define WEBKIT_EMBED_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), WEBKIT_TYPE_EMBED, WebKitEmbedPrivate)) @@ -116,6 +115,11 @@ ephy_command_manager_iface_init (EphyCommandManagerIface *iface) iface->can_do_command = impl_manager_can_do_command; } +static void +ephy_embed_iface_init (EphyEmbedIface *iface) +{ +} + G_DEFINE_TYPE_WITH_CODE (WebKitEmbed, webkit_embed, EPHY_TYPE_BASE_EMBED, G_IMPLEMENT_INTERFACE (EPHY_TYPE_EMBED, ephy_embed_iface_init) @@ -133,8 +137,8 @@ title_changed_cb (WebKitWebView *web_view, g_object_get (web_view, "title", &title, NULL); - ephy_base_embed_set_title (EPHY_BASE_EMBED (embed), - title); + ephy_web_view_set_title (EPHY_WEB_VIEW (web_view), + title); frame = webkit_web_view_get_main_frame (web_view); uri = webkit_web_frame_get_uri (frame); @@ -148,35 +152,35 @@ title_changed_cb (WebKitWebView *web_view, static void update_load_state (WebKitEmbed *embed, WebKitWebView *web_view) { - EphyEmbedNetState estate = EPHY_EMBED_STATE_UNKNOWN; - const char *loading_uri = ephy_embed_get_typed_address (embed); + EphyWebViewNetState estate = EPHY_WEB_VIEW_STATE_UNKNOWN; + const char *loading_uri = ephy_web_view_get_typed_address (EPHY_WEB_VIEW (web_view)); if (embed->priv->load_state == WEBKIT_EMBED_LOAD_STARTED) { - estate = (EphyEmbedNetState) (estate | - EPHY_EMBED_STATE_START | - EPHY_EMBED_STATE_NEGOTIATING | - EPHY_EMBED_STATE_IS_REQUEST | - EPHY_EMBED_STATE_IS_NETWORK); + estate = (EphyWebViewNetState) (estate | + EPHY_WEB_VIEW_STATE_START | + EPHY_WEB_VIEW_STATE_NEGOTIATING | + EPHY_WEB_VIEW_STATE_IS_REQUEST | + EPHY_WEB_VIEW_STATE_IS_NETWORK); - g_signal_emit_by_name (embed, "new-document-now", loading_uri); + g_signal_emit_by_name (EPHY_WEB_VIEW (web_view), "new-document-now", loading_uri); } if (embed->priv->load_state == WEBKIT_EMBED_LOAD_LOADING) - estate = (EphyEmbedNetState) (estate | - EPHY_EMBED_STATE_TRANSFERRING | - EPHY_EMBED_STATE_IS_REQUEST | - EPHY_EMBED_STATE_IS_NETWORK); + estate = (EphyWebViewNetState) (estate | + EPHY_WEB_VIEW_STATE_TRANSFERRING | + EPHY_WEB_VIEW_STATE_IS_REQUEST | + EPHY_WEB_VIEW_STATE_IS_NETWORK); if (embed->priv->load_state == WEBKIT_EMBED_LOAD_STOPPED) - estate = (EphyEmbedNetState) (estate | - EPHY_EMBED_STATE_STOP | - EPHY_EMBED_STATE_IS_DOCUMENT | - EPHY_EMBED_STATE_IS_NETWORK); - - ephy_base_embed_update_from_net_state (EPHY_BASE_EMBED (embed), - loading_uri, - (EphyEmbedNetState)estate); + estate = (EphyWebViewNetState) (estate | + EPHY_WEB_VIEW_STATE_STOP | + EPHY_WEB_VIEW_STATE_IS_DOCUMENT | + EPHY_WEB_VIEW_STATE_IS_NETWORK); + + ephy_web_view_update_from_net_state (EPHY_WEB_VIEW (web_view), + loading_uri, + (EphyWebViewNetState)estate); } static void @@ -219,17 +223,17 @@ restore_zoom_level (WebKitEmbed *embed, static void load_committed_cb (WebKitWebView *web_view, WebKitWebFrame *web_frame, - EphyEmbed *embed) + WebKitEmbed *embed) { const gchar* uri; - EphyEmbedSecurityLevel security_level; + EphyWebViewSecurityLevel security_level; uri = webkit_web_frame_get_uri (web_frame); - ephy_base_embed_location_changed (EPHY_BASE_EMBED (embed), - uri); + ephy_web_view_location_changed (EPHY_WEB_VIEW (web_view), + uri); - restore_zoom_level (WEBKIT_EMBED (embed), uri); - ephy_history_add_page (WEBKIT_EMBED (embed)->priv->history, + restore_zoom_level (embed, uri); + ephy_history_add_page (embed->priv->history, uri, FALSE, FALSE); @@ -240,11 +244,11 @@ load_committed_cb (WebKitWebView *web_view, * a 'https' prefix for the URI */ if (uri && g_str_has_prefix (uri, "https")) - security_level = EPHY_EMBED_STATE_IS_SECURE_HIGH; + security_level = EPHY_WEB_VIEW_STATE_IS_SECURE_HIGH; else - security_level = EPHY_EMBED_STATE_IS_UNKNOWN; + security_level = EPHY_WEB_VIEW_STATE_IS_UNKNOWN; - ephy_base_embed_set_security_level (EPHY_BASE_EMBED (embed), security_level); + ephy_web_view_set_security_level (EPHY_WEB_VIEW (web_view), security_level); } static void @@ -268,7 +272,7 @@ load_progress_changed_cb (WebKitWebView *web_view, if (wembed->priv->load_state == WEBKIT_EMBED_LOAD_STARTED) wembed->priv->load_state = WEBKIT_EMBED_LOAD_LOADING; - ephy_base_embed_set_load_percent (EPHY_BASE_EMBED (embed), progress); + ephy_web_view_set_load_percent (EPHY_WEB_VIEW (web_view), progress); } static void @@ -288,7 +292,7 @@ hovering_over_link_cb (WebKitWebView *web_view, char *location, EphyEmbed *embed) { - ephy_base_embed_set_link_message (EPHY_BASE_EMBED (embed), location); + ephy_web_view_set_link_message (EPHY_WEB_VIEW (web_view), location); } static void @@ -307,7 +311,7 @@ zoom_changed_cb (WebKitWebView *web_view, return; } - address = ephy_embed_get_location (embed, TRUE); + address = ephy_web_view_get_location (EPHY_WEB_VIEW (web_view), TRUE); if (ephy_embed_utils_address_has_web_scheme (address)) { EphyHistory *history; EphyNode *host; @@ -371,18 +375,18 @@ mime_type_policy_decision_requested_cb (WebKitWebView *web_view, WebKitWebPolicyDecision *decision, WebKitEmbed *embed) { - EphyEmbedDocumentType type; + EphyWebViewDocumentType type; g_return_val_if_fail (mime_type, FALSE); - type = EPHY_EMBED_DOCUMENT_OTHER; + type = EPHY_WEB_VIEW_DOCUMENT_OTHER; if (!strcmp (mime_type, "text/html")) - type = EPHY_EMBED_DOCUMENT_HTML; + type = EPHY_WEB_VIEW_DOCUMENT_HTML; else if (!strcmp (mime_type, "application/xhtml+xml")) - type = EPHY_EMBED_DOCUMENT_XML; + type = EPHY_WEB_VIEW_DOCUMENT_XML; else if (!strncmp (mime_type, "image/", 6)) - type = EPHY_EMBED_DOCUMENT_IMAGE; + type = EPHY_WEB_VIEW_DOCUMENT_IMAGE; /* FIXME: maybe it makes more sense to have an API to query the mime * type when the load of a page starts than doing this here. @@ -390,7 +394,7 @@ mime_type_policy_decision_requested_cb (WebKitWebView *web_view, /* FIXME: rename ge-document-type (and all ge- signals...) to * something else */ - g_signal_emit_by_name (embed, "ge-document-type", type); + g_signal_emit_by_name (EPHY_GET_EPHY_WEB_VIEW_FROM_EMBED (embed), "ge-document-type", type); /* If WebKit can't handle the mime type start the download process */ @@ -766,101 +770,3 @@ webkit_embed_init (WebKitEmbed *embed) embed->priv->history = EPHY_HISTORY (ephy_embed_shell_get_global_history (ephy_embed_shell_get_default ())); } -static void -impl_load_url (EphyEmbed *embed, - const char *url) -{ -} - -static gboolean -impl_can_go_up (EphyEmbed *embed) -{ - return FALSE; -} - -static GSList * -impl_get_go_up_list (EphyEmbed *embed) -{ - return NULL; -} - -static void -impl_go_up (EphyEmbed *embed) -{ -} - -static char * -impl_get_js_status (EphyEmbed *embed) -{ - return NULL; -} - -static char * -impl_get_location (EphyEmbed *embed, - gboolean toplevel) -{ - WebKitWebFrame *web_frame = webkit_web_view_get_main_frame (WEBKIT_EMBED (embed)->priv->web_view); - return g_strdup (webkit_web_frame_get_uri (web_frame)); -} - -static void -impl_get_security_level (EphyEmbed *embed, - EphyEmbedSecurityLevel *level, - char **description) -{ - if (level) { - const gchar *uri = ephy_embed_get_address (embed); - - /* FIXME: as a temporary workaround, determine security level - based on the existence of a 'https' prefix for the URI */ - if (uri && g_str_has_prefix(uri, "https")) - *level = EPHY_EMBED_STATE_IS_SECURE_HIGH; - else - *level = EPHY_EMBED_STATE_IS_UNKNOWN; - } -} - -static void -impl_show_page_certificate (EphyEmbed *embed) -{ -} - -static void -impl_set_print_preview_mode (EphyEmbed *embed, gboolean preview_mode) -{ -} - -static int -impl_print_preview_n_pages (EphyEmbed *embed) -{ - return 0; -} - -static void -impl_print_preview_navigate (EphyEmbed *embed, - EphyEmbedPrintPreviewNavType type, - int page) -{ -} - -static gboolean -impl_has_modified_forms (EphyEmbed *embed) -{ - return FALSE; -} - -static void -ephy_embed_iface_init (EphyEmbedIface *iface) -{ - iface->can_go_up = impl_can_go_up; - iface->get_go_up_list = impl_get_go_up_list; - iface->go_up = impl_go_up; - iface->get_location = impl_get_location; - iface->get_js_status = impl_get_js_status; - iface->show_page_certificate = impl_show_page_certificate; - iface->set_print_preview_mode = impl_set_print_preview_mode; - 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_security_level = impl_get_security_level; -} -- cgit v1.2.3