diff options
Diffstat (limited to 'embed/ephy-base-embed.c')
-rw-r--r-- | embed/ephy-base-embed.c | 1402 |
1 files changed, 1 insertions, 1401 deletions
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, @@ -161,1341 +86,16 @@ ephy_base_embed_grab_focus (GtkWidget *widget) } 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"); - } } |