diff options
author | Michael Fleming <mfleming@src.gnome.org> | 2001-02-08 22:32:15 +0000 |
---|---|---|
committer | Michael Fleming <mfleming@src.gnome.org> | 2001-02-08 22:32:15 +0000 |
commit | ac9ce10ab1ba5a40d272ebef15c16d9c38e7c0d7 (patch) | |
tree | c2c85d59f010aa947a07e6031a392bb8b77a1baa | |
parent | 13414e32b4a6d80a40f8b272cf510759151c89ed (diff) | |
download | nautilus-ac9ce10ab1ba5a40d272ebef15c16d9c38e7c0d7.tar.gz |
reviewed by: <ramiro@eazel.com>
Significant rework of nautilus-mozilla-content-view to use
report_location_change and to do general house-cleaning.
Fixes following bugs:
Bug 3547 POSTs in the mozilla component don't update the URI
Bug 4682, 6142 Frame sets have difficulty in Nautilus
Bug 5461 "http://localhost:xxxx" instead of "eazel-services:" on location bar
Will fix following bugs when I talk with Darin about problems
with report_location_change:
5592 nautilus / mozilla back button goes back 2 pages
Also removes all module-global and static variables, making gnome-vfs
and general state-tracking per-instance, thus eliminating latent
bugs related to using two browsers simultainously
Removes all special-casing for form POST's and for iframes
Removes usage of the mozilla "open_uri" signal, which was no longer really
being used for anything (interruption of eazel-specific schemes is done
at the DOM event level, notification to Nautilus of navigation is done
as a result of the "location" signal
Introduces/aggrevates these bugs:
6435 No history recorded when using report_location_change
6436 Throbber doesn't throb when using report_location_change
I'll wait until Darin returns to figure out solutions to this.
* components/mozilla/Makefile.am:
* components/mozilla/main.c: (main):
* components/mozilla/mozilla-events.cpp:
* components/mozilla/mozilla-events.h:
* components/mozilla/nautilus-mozilla-content-view.c:
* components/mozilla/nautilus-mozilla-content-view.h:
-rw-r--r-- | ChangeLog | 43 | ||||
-rw-r--r-- | components/mozilla/main.c | 20 | ||||
-rw-r--r-- | components/mozilla/mozilla-events.cpp | 6 | ||||
-rw-r--r-- | components/mozilla/mozilla-events.h | 2 | ||||
-rw-r--r-- | components/mozilla/nautilus-mozilla-content-view.c | 1697 | ||||
-rw-r--r-- | components/mozilla/nautilus-mozilla-content-view.h | 7 |
6 files changed, 962 insertions, 813 deletions
@@ -1,3 +1,46 @@ +2001-02-08 Michael K. Fleming <mfleming@eazel.com> + + reviewed by: <ramiro@eazel.com> + + Significant rework of nautilus-mozilla-content-view to use + report_location_change and to do general house-cleaning. + + Fixes following bugs: + + Bug 3547 POSTs in the mozilla component don't update the URI + Bug 4682, 6142 Frame sets have difficulty in Nautilus + Bug 5461 "http://localhost:xxxx" instead of "eazel-services:" on location bar + + Will fix following bugs when I talk with Darin about problems + with report_location_change: + + 5592 nautilus / mozilla back button goes back 2 pages + + Also removes all module-global and static variables, making gnome-vfs + and general state-tracking per-instance, thus eliminating latent + bugs related to using two browsers simultainously + + Removes all special-casing for form POST's and for iframes + + Removes usage of the mozilla "open_uri" signal, which was no longer really + being used for anything (interruption of eazel-specific schemes is done + at the DOM event level, notification to Nautilus of navigation is done + as a result of the "location" signal + + Introduces/aggrevates these bugs: + + 6435 No history recorded when using report_location_change + 6436 Throbber doesn't throb when using report_location_change + + I'll wait until Darin returns to figure out solutions to this. + + * components/mozilla/Makefile.am: + * components/mozilla/main.c: (main): + * components/mozilla/mozilla-events.cpp: + * components/mozilla/mozilla-events.h: + * components/mozilla/nautilus-mozilla-content-view.c: + * components/mozilla/nautilus-mozilla-content-view.h: + 2001-02-08 Andy Hertzfeld <andy@eazel.com> * libnautilus-extensions/nautilus-gnome-extensions.c: diff --git a/components/mozilla/main.c b/components/mozilla/main.c index 4dd593117..91abc947e 100644 --- a/components/mozilla/main.c +++ b/components/mozilla/main.c @@ -68,8 +68,7 @@ mozilla_make_object (BonoboGenericFactory *factory, const char *goad_id, void *closure) { - NautilusMozillaContentView *view; - NautilusView *nautilus_view; + BonoboObject *bonobo_object; if (strcmp (goad_id, "OAFIID:nautilus_mozilla_content_view:1ee70717-57bf-4079-aae5-922abdd576b1")) { return NULL; @@ -78,20 +77,18 @@ mozilla_make_object (BonoboGenericFactory *factory, #ifdef DEBUG_mfleming g_print ("+mozilla_make_object\n"); #endif - - view = NAUTILUS_MOZILLA_CONTENT_VIEW (gtk_object_new (NAUTILUS_TYPE_MOZILLA_CONTENT_VIEW, NULL)); object_count++; - nautilus_view = nautilus_mozilla_content_view_get_nautilus_view (view); + bonobo_object = nautilus_mozilla_content_view_new (); - gtk_signal_connect (GTK_OBJECT (nautilus_view), "destroy", mozilla_object_destroyed, NULL); + gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", mozilla_object_destroyed, NULL); #ifdef DEBUG_mfleming g_print ("-mozilla_make_object\n"); #endif - return BONOBO_OBJECT (nautilus_view); + return BONOBO_OBJECT (bonobo_object); } extern gboolean test_make_full_uri_from_relative (void); @@ -102,11 +99,6 @@ run_test_cases (void) return test_make_full_uri_from_relative (); } -#ifdef EAZEL_SERVICES -/*Defined in nautilus-mozilla-content-view.c*/ -extern EazelProxy_UserControl nautilus_mozilla_content_view_user_control; -#endif - int main (int argc, char *argv[]) { @@ -156,9 +148,7 @@ main (int argc, char *argv[]) gnome_vfs_init (); #ifdef EAZEL_SERVICES - if (ammonite_init ((PortableServer_POA) bonobo_poa)) { - nautilus_mozilla_content_view_user_control = ammonite_get_user_control (); - } + ammonite_init ((PortableServer_POA) bonobo_poa); #endif #ifdef DEBUG_mfleming diff --git a/components/mozilla/mozilla-events.cpp b/components/mozilla/mozilla-events.cpp index e5d6e6735..219f8658d 100644 --- a/components/mozilla/mozilla-events.cpp +++ b/components/mozilla/mozilla-events.cpp @@ -173,6 +173,8 @@ mozilla_events_get_href_for_event (gpointer dom_event) } +#if 0 + /* * returns TRUE if the given event occurs in a SUBMIT button to a form with method=POST */ @@ -236,6 +238,7 @@ mozilla_events_is_in_form_POST_submit (gpointer dom_event) return FALSE; } +#endif /* 0 */ /* defined in gtkmozembed_internal.h */ extern "C" void gtk_moz_embed_get_nsIWebBrowser (GtkMozEmbed *embed, nsIWebBrowser **retval); @@ -310,6 +313,7 @@ debug_dom_dump (nsIDOMElement *element, int depth) } #endif /* 0 */ +#if 0 /* Why can't I use GetElementsByTagName? I couldn't get it to work for me */ static gboolean find_node_named_with_src (nsIDOMNode *top_node, const nsAReadableString& aName, const nsAReadableString& uri) @@ -469,5 +473,5 @@ mozilla_events_is_url_in_iframe (GtkMozEmbed *embed, const char *uri) #endif } - +#endif /* 0 */ diff --git a/components/mozilla/mozilla-events.h b/components/mozilla/mozilla-events.h index 1872809ac..6a38ec2d8 100644 --- a/components/mozilla/mozilla-events.h +++ b/components/mozilla/mozilla-events.h @@ -39,9 +39,11 @@ gboolean mozilla_events_is_key_return (gpointer dom_event); char *mozilla_events_get_href_for_event (gpointer dom_event); +#if 0 gboolean mozilla_events_is_in_form_POST_submit (gpointer dom_event); gboolean mozilla_events_is_url_in_iframe (GtkMozEmbed *embed, const char *uri); +#endif #ifdef __cplusplus } diff --git a/components/mozilla/nautilus-mozilla-content-view.c b/components/mozilla/nautilus-mozilla-content-view.c index 2b4fa4987..5413cc6bc 100644 --- a/components/mozilla/nautilus-mozilla-content-view.c +++ b/components/mozilla/nautilus-mozilla-content-view.c @@ -32,6 +32,12 @@ #define nopeDEBUG_ramiro 1 #define nopeDEBUG_mfleming 1 +#ifdef DEBUG_mfleming +#define DEBUG_MSG(x) g_print x; +#else +#define DEBUG_MSG(x) ; +#endif + #include <config.h> #include "nautilus-mozilla-content-view.h" @@ -70,64 +76,126 @@ enum nsEventStatus { #define NS_DOM_EVENT_IGNORED ((enum nsEventStatus)nsEventStatus_eIgnore) #define NS_DOM_EVENT_CONSUMED ((enum nsEventStatus)nsEventStatus_eConsumeNoDefault) -#ifdef EAZEL_SERVICES -EazelProxy_UserControl nautilus_mozilla_content_view_user_control = CORBA_OBJECT_NIL; -#endif +/* Buffer for streaming contents from gnome-vfs into mozilla */ +#define VFS_READ_BUFFER_SIZE (40 * 1024) struct NautilusMozillaContentViewDetails { - char *uri; - GtkWidget *mozilla; - NautilusView *nautilus_view; - GdkCursor *busy_cursor; - gboolean got_called_by_nautilus; + char *uri; /* The URI stored here is nautilus's idea of the URI */ + GtkWidget *mozilla; /* If this is NULL, the mozilla widget has not yet been initialized */ + gboolean report_progress_to_view; /* If we notified the view via report_location_change, don't send report_load_xxx */ + NautilusView *nautilus_view; + GdkCursor *busy_cursor; + char *vfs_read_buffer; + GnomeVFSAsyncHandle *vfs_handle; + + /* For async NautilusView messages */ + char *pending_title; /*for set_title*/ + char *pending_report_uri; /*for report_location_change*/ + char *pending_open_uri; /*for location_change*/ + char *pending_link_message; /*for report_status*/ + double pending_load_progress; /*for load_progress*/ + + gboolean is_pending_set_title :1; + gboolean is_pending_report_load_failed :1; + gboolean is_pending_report_load_complete :1; + gboolean is_pending_report_location_change :1; + gboolean is_pending_report_status :1; + gboolean is_pending_report_load_progress :1; + gboolean is_pending_open_location :1; }; +/* GTK Type System */ static void nautilus_mozilla_content_view_initialize_class (NautilusMozillaContentViewClass *klass); static void nautilus_mozilla_content_view_initialize (NautilusMozillaContentView *view); static void nautilus_mozilla_content_view_destroy (GtkObject *object); -static void mozilla_load_location_callback (NautilusView *nautilus_view, - const char *location, - NautilusMozillaContentView *view); - -/* Mozilla embed widget callbacks */ -static void mozilla_title_changed_callback (GtkMozEmbed *mozilla, - gpointer user_data); -static void mozilla_location_changed_callback (GtkMozEmbed *mozilla, - gpointer user_data); -static void mozilla_net_state_callback (GtkMozEmbed *mozilla, - gint state, - guint status, - gpointer user_data); -static void mozilla_net_stop_callback (GtkMozEmbed *mozilla, - gpointer user_data); -static void mozilla_link_message_callback (GtkMozEmbed *mozilla, - gpointer user_data); -static void mozilla_progress_callback (GtkMozEmbed *mozilla, - gint max_progress, - gint current_progress, - gpointer user_data); -static gint mozilla_open_uri_callback (GtkMozEmbed *mozilla, - const char *uri, - gpointer user_data); -static gint mozilla_dom_key_press_callback (GtkMozEmbed *mozilla, - gpointer dom_event, - gpointer user_data); -static gint mozilla_dom_mouse_click_callback (GtkMozEmbed *mozilla, - gpointer dom_event, - gpointer user_data); - - -/* Other mozilla content view functions */ -static void mozilla_content_view_set_busy_cursor (NautilusMozillaContentView *view); -static void mozilla_content_view_clear_busy_cursor (NautilusMozillaContentView *view); -static gboolean mozilla_is_uri_handled_by_nautilus (const char *uri); -static gboolean mozilla_is_uri_handled_by_mozilla (const char *uri); -static char * mozilla_translate_uri_if_needed (NautilusMozillaContentView *view, - const char *uri); -static char * mozilla_untranslate_uri_if_needed (NautilusMozillaContentView *view, - const char *uri); -static void mozilla_content_view_one_time_happenings (void); -static void mozilla_content_view_setup_profile_directory (void); + + +/* Gnome VFS callback functions */ +static void vfs_open_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer data); + +static void vfs_read_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer data); + +/* NautilusView callback functions */ +static void view_load_location_callback (NautilusView *nautilus_view, + const char *location, + gpointer data); + +/* GtkEmbedMoz callback functions */ + +static void mozilla_title_changed_callback (GtkMozEmbed *mozilla, + gpointer user_data); + +static void mozilla_location_callback (GtkMozEmbed *mozilla, + gpointer user_data); + +static void mozilla_net_state_callback (GtkMozEmbed *mozilla, + gint state_flags, + guint status_flags, + gpointer user_data); + +static void mozilla_net_stop_callback (GtkMozEmbed *mozilla, + gpointer user_data); + +static void mozilla_link_message_callback (GtkMozEmbed *mozilla, + gpointer user_data); + +static void mozilla_progress_callback (GtkMozEmbed *mozilla, + gint current_progress, + gint max_progress, + gpointer user_data); + +static gint mozilla_dom_key_press_callback (GtkMozEmbed *mozilla, + gpointer dom_event, + gpointer user_data); + +static gint mozilla_dom_mouse_click_callback (GtkMozEmbed *mozilla, + gpointer dom_event, + gpointer user_data); + +/* Private NautilusMozillaContentView functions */ + +static char * translate_uri_nautilus_to_mozilla (NautilusMozillaContentView *view, + const char *uri); +static char * translate_uri_mozilla_to_nautilus (NautilusMozillaContentView *view, + const char *uri); + +static void set_busy_cursor (NautilusMozillaContentView *view); +static void clear_busy_cursor (NautilusMozillaContentView *view); + +static void navigate_mozilla_to_nautilus_uri (NautilusMozillaContentView *view, + const char *uri); + +static void update_nautilus_uri (NautilusMozillaContentView *view, + const char *nautilus_uri); + +static void cancel_pending_vfs_operation (NautilusMozillaContentView *view); + +/* Utility functions */ + +static char * make_full_uri_from_relative (const char *base_uri, + const char *uri); + +static gboolean uris_identical (const char *uri1, + const char *uri2); + +static gboolean should_uri_navigate_bypass_nautilus (const char *uri); + +static gboolean should_mozilla_load_uri_directly (const char *uri); + +#define STRING_LIST_NOT_FOUND -1 +static gint string_list_get_index_of_string (const char *string_list[], + guint num_strings, + const char *string); + +static void pre_widget_initialize (void); +static void post_widget_initialize (void); #ifdef EAZEL_SERVICES @@ -135,34 +203,64 @@ static void mozilla_content_view_setup_profile_directory (void); * URL scheme hack for the eazel-services: scheme */ -static char * -eazel_services_scheme_translate (NautilusMozillaContentView *view, - const char *uri, - gboolean is_retry); +static char * eazel_services_scheme_to_http (NautilusMozillaContentView *view, + const char *uri); -static char * -eazel_services_scheme_untranslate (NautilusMozillaContentView *view, - const char *uri); +static char * eazel_services_scheme_from_http (NautilusMozillaContentView *view, + const char *uri); +#endif /* EAZEL_SERVICES */ -#ifdef EAZEL_SERVICES_MOZILLA_MODAL_LOGIN -typedef struct { - NautilusMozillaContentView *view; - char *uri; -} LoginAsyncState; +/* + * Async NautilusView message dispatchers + */ -static void /* AmmonitePromptLoginCb */ -eazel_services_prompt_login_cb ( - gpointer user_data, - const EazelProxy_User *user, - const EazelProxy_AuthnFailInfo *fail_info -); -#endif /* EAZEL_SERVICES_MOZILLA_MODAL_LOGIN */ +static void async_set_title (NautilusMozillaContentView *view, + const char *title); +static void async_report_location_change (NautilusMozillaContentView *view, + const char *report_uri); +static void async_report_status (NautilusMozillaContentView *view, + const char *link_message); +static void async_open_location (NautilusMozillaContentView *view, + const char *open_uri); + +static void async_report_load_failed (NautilusMozillaContentView *view); + +static void async_report_load_complete (NautilusMozillaContentView *view); + +static void async_report_load_progress (NautilusMozillaContentView *view, + double load_progress); -#endif /* EAZEL_SERVICES */ +/***********************************************************************************/ +/***********************************************************************************/ static GtkVBoxClass *parent_class = NULL; +GtkType +nautilus_mozilla_content_view_get_type (void) +{ + static GtkType mozilla_content_view_type = 0; + + if (!mozilla_content_view_type) + { + static const GtkTypeInfo mozilla_content_view_info = + { + "NautilusMozillaContentView", + sizeof (NautilusMozillaContentView), + sizeof (NautilusMozillaContentViewClass), + (GtkClassInitFunc) nautilus_mozilla_content_view_initialize_class, + (GtkObjectInitFunc) nautilus_mozilla_content_view_initialize, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + mozilla_content_view_type = gtk_type_unique (GTK_TYPE_VBOX, &mozilla_content_view_info); + } + + return mozilla_content_view_type; +} + static void nautilus_mozilla_content_view_initialize_class (NautilusMozillaContentViewClass *klass) { @@ -174,7 +272,7 @@ nautilus_mozilla_content_view_initialize_class (NautilusMozillaContentViewClass object_class->destroy = nautilus_mozilla_content_view_destroy; - mozilla_content_view_setup_profile_directory (); + pre_widget_initialize (); } static void @@ -182,6 +280,8 @@ nautilus_mozilla_content_view_initialize (NautilusMozillaContentView *view) { view->details = g_new0 (NautilusMozillaContentViewDetails, 1); + DEBUG_MSG (("+%s\n", __FUNCTION__)); + /* Conjure up the beast. May God have mercy on our souls. */ view->details->mozilla = gtk_moz_embed_new (); @@ -190,7 +290,7 @@ nautilus_mozilla_content_view_initialize (NautilusMozillaContentView *view) * created, otherwise the mozilla runtime environment is not properly * setup. */ - mozilla_content_view_one_time_happenings (); + post_widget_initialize (); /* Add callbacks to the beast */ gtk_signal_connect_while_alive (GTK_OBJECT (view->details->mozilla), @@ -201,7 +301,7 @@ nautilus_mozilla_content_view_initialize (NautilusMozillaContentView *view) gtk_signal_connect_while_alive (GTK_OBJECT (view->details->mozilla), "location", - GTK_SIGNAL_FUNC (mozilla_location_changed_callback), + GTK_SIGNAL_FUNC (mozilla_location_callback), view, GTK_OBJECT (view->details->mozilla)); @@ -230,12 +330,6 @@ nautilus_mozilla_content_view_initialize (NautilusMozillaContentView *view) GTK_OBJECT (view->details->mozilla)); gtk_signal_connect_while_alive (GTK_OBJECT (view->details->mozilla), - "open_uri", - GTK_SIGNAL_FUNC (mozilla_open_uri_callback), - view, - GTK_OBJECT (view->details->mozilla)); - - gtk_signal_connect_while_alive (GTK_OBJECT (view->details->mozilla), "dom_key_press", GTK_SIGNAL_FUNC (mozilla_dom_key_press_callback), view, @@ -255,11 +349,13 @@ nautilus_mozilla_content_view_initialize (NautilusMozillaContentView *view) gtk_signal_connect_while_alive (GTK_OBJECT (view->details->nautilus_view), "load_location", - GTK_SIGNAL_FUNC (mozilla_load_location_callback), + GTK_SIGNAL_FUNC (view_load_location_callback), view, - GTK_OBJECT (view->details->mozilla)); + GTK_OBJECT (view)); gtk_widget_show_all (GTK_WIDGET (view)); + + DEBUG_MSG (("-%s\n", __FUNCTION__)); } static void @@ -267,377 +363,135 @@ nautilus_mozilla_content_view_destroy (GtkObject *object) { NautilusMozillaContentView *view; -#ifdef DEBUG_ramiro - g_print ("%s()\n", __FUNCTION__); -#endif + DEBUG_MSG (("+%s\n", __FUNCTION__)); view = NAUTILUS_MOZILLA_CONTENT_VIEW (object); g_free (view->details->uri); + view->details->uri = NULL; if (view->details->busy_cursor != NULL) { gdk_cursor_destroy (view->details->busy_cursor); + view->details->busy_cursor = NULL; } - g_free (view->details); + cancel_pending_vfs_operation (view); + g_free (view->details); + if (GTK_OBJECT_CLASS (parent_class)->destroy) { (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } + + DEBUG_MSG (("-%s\n", __FUNCTION__)); } /** - * nautilus_mozilla_content_view_get_nautilus_view: + * nautilus_mozilla_content_view_get_bonobo_object: * - * Return the NautilusView object associated with this view; this + * Return the BonoboObject associated with this view; this * is needed to export the view via CORBA/Bonobo. * @view: NautilusMozillaContentView to get the nautilus_view from.. * **/ -NautilusView * -nautilus_mozilla_content_view_get_nautilus_view (NautilusMozillaContentView *view) +BonoboObject * +nautilus_mozilla_content_view_new (void) { - return view->details->nautilus_view; -} - - -/** - * mozilla_vfs_read_callback: - * - * Read data from buffer and copy into mozilla stream. - **/ - -static char vfs_read_buf[40960]; - -static void -mozilla_vfs_read_callback (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer buffer, - GnomeVFSFileSize bytes_requested, - GnomeVFSFileSize bytes_read, - gpointer data) -{ - NautilusMozillaContentView *view = data; - -#ifdef DEBUG_ramiro - g_print ("mozilla_vfs_read_callback: %ld/%ld bytes\n", (long) bytes_read, (long) bytes_requested); -#endif - nautilus_view_report_load_underway (view->details->nautilus_view); - if (bytes_read != 0) { - gtk_moz_embed_append_data (GTK_MOZ_EMBED (view->details->mozilla), buffer, bytes_read); - } - - if (bytes_read == 0 || result != GNOME_VFS_OK) { - gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->details->mozilla)); - gnome_vfs_async_close (handle, (GnomeVFSAsyncCloseCallback) gtk_true, NULL); - nautilus_view_report_load_complete (view->details->nautilus_view); - return; - } - - gnome_vfs_async_read (handle, vfs_read_buf, sizeof (vfs_read_buf), mozilla_vfs_read_callback, view); -} - -/** - * mozilla_vfs_callback: - * - * Callback for gnome_vfs_async_open. Attempt to read data from handle - * and pass to mozilla streaming callback. - * - **/ -static void -mozilla_vfs_callback (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data) -{ - NautilusMozillaContentView *view = data; - -#ifdef DEBUG_ramiro - g_print ("mozilla_vfs_callback, result was %s\n", gnome_vfs_result_to_string (result)); -#endif - - if (result != GNOME_VFS_OK) - { - nautilus_view_report_load_failed (view->details->nautilus_view); - gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->details->mozilla)); - } else { - gtk_moz_embed_open_stream (GTK_MOZ_EMBED (view->details->mozilla), "file://", "text/html"); - gnome_vfs_async_read (handle, vfs_read_buf, sizeof (vfs_read_buf), mozilla_vfs_read_callback, view); - } -} - -#if 0 -/* Check whether two uris are "equal". Equal means: - * - * Same uri regardless of mozilla canonicalization - * - * What happens is that mozilla internall canonicalizes - * uris and appends trailing slashes to those that it - * knows to be directories. Unfortunately this is - * different from Nautilus. - */ -static gboolean -uris_are_equal (const char *uri_one, const char *uri_two) -{ - guint length_one; - guint length_two; - - if (uri_one == NULL && uri_two == NULL) { - return TRUE; - } - - if (uri_one == NULL || uri_two == NULL) { - return FALSE; - } - - length_one = strlen (uri_one); - length_two = strlen (uri_two); - - if (length_one == 0 && length_two == 0) { - return TRUE; - } - - if (length_one == 0 || length_two == 0) { - return FALSE; - } - - /* Drop the trailing slashes */ - if (uri_one[length_one - 1] == '/') { - length_one--; - } - - if (uri_two[length_two - 1] == '/') { - length_two--; - } - - if (length_one != length_two) { - return FALSE; - } + NautilusMozillaContentView *view; + view = NAUTILUS_MOZILLA_CONTENT_VIEW (gtk_object_new (NAUTILUS_TYPE_MOZILLA_CONTENT_VIEW, NULL)); - return strncmp (uri_one, uri_two, MIN (length_one, length_two)) == 0; + return BONOBO_OBJECT (view->details->nautilus_view); } -#endif - -/** - * nautilus_mozilla_content_view_load_uri: - * - * Load the resource pointed to by the specified URI. - * @view: NautilusMozillaContentView to get the nautilus_view from. - * - **/ -void -nautilus_mozilla_content_view_load_uri (NautilusMozillaContentView *view, - const char *uri) -{ - GnomeVFSAsyncHandle *async_handle; - gboolean same_uri = FALSE; - - g_assert (uri != NULL); - -#ifdef DEBUG_mfleming - g_print ("+%s uri='%s'\n", __FUNCTION__, uri); -#endif - - view->details->got_called_by_nautilus = TRUE; - - /* Check whether its the same uri. Ignore the mozilla - * added canonicalization. - */ - - /* FIXME bugzilla.eazel.com 2780: - * Reload is broken. - */ - /* same_uri = uris_are_equal (view->details->uri, uri); */ - same_uri = FALSE; - - if (view->details->uri) { - g_free (view->details->uri); - } - - view->details->uri = g_strdup (uri); -#ifdef DEBUG_ramiro - g_print ("nautilus_mozilla_content_view_load_uri (uri = %s, same = %d)\n", - view->details->uri, same_uri); -#endif - /* NOTE: (mfleming) I placed this here to fix bugzilla.eazel.com 5249 - * The belief is that calling load_underway here will cause - * the Bonobo::Control::realize call to be made while this call is - * pending, rather than later. It's somewhat safer for that to occur - * here. Anyway, no harm is done: this is a totally legit place - * to call load_underway - */ - nautilus_view_report_load_underway (view->details->nautilus_view); - - /* If the request can be handled by mozilla, pass the uri as is. Otherwise, - * use gnome-vfs to open the uri and later stream the data into the gtkmozembed - * widget. - */ - if (mozilla_is_uri_handled_by_mozilla (uri)) { - if (same_uri) { - gtk_moz_embed_reload (GTK_MOZ_EMBED (view->details->mozilla), - GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE); - } - else { - gtk_moz_embed_load_url (GTK_MOZ_EMBED (view->details->mozilla), - view->details->uri); - } - } else { - gnome_vfs_async_open (&async_handle, uri, GNOME_VFS_OPEN_READ, mozilla_vfs_callback, view); - } -} +/***********************************************************************************/ +/***********************************************************************************/ static void -mozilla_content_view_set_busy_cursor (NautilusMozillaContentView *view) +view_load_location_callback (NautilusView *nautilus_view, + const char *location, + gpointer data) { - g_return_if_fail (NAUTILUS_IS_MOZILLA_CONTENT_VIEW (view)); + NautilusMozillaContentView *view; - if (!view->details->busy_cursor) { - view->details->busy_cursor = gdk_cursor_new (GDK_WATCH); - } + view = NAUTILUS_MOZILLA_CONTENT_VIEW (data); - g_assert (view->details->busy_cursor != NULL); - g_assert (GTK_WIDGET_REALIZED (GTK_WIDGET (view->details->mozilla))); + DEBUG_MSG (("+%s\n", __FUNCTION__)); - gdk_window_set_cursor (GTK_WIDGET (view->details->mozilla)->window, - view->details->busy_cursor); + DEBUG_MSG ((">nautilus_view_report_load_underway\n")); - gdk_flush (); -} + nautilus_view_report_load_underway (nautilus_view); + view->details->report_progress_to_view = TRUE; -static void -mozilla_content_view_clear_busy_cursor (NautilusMozillaContentView *view) -{ - g_return_if_fail (NAUTILUS_IS_MOZILLA_CONTENT_VIEW (view)); + navigate_mozilla_to_nautilus_uri (view, location); - g_assert (GTK_WIDGET_REALIZED (GTK_WIDGET (view->details->mozilla))); - - gdk_window_set_cursor (GTK_WIDGET (view->details->mozilla)->window, NULL); + DEBUG_MSG (("-%s\n", __FUNCTION__)); } -static void -mozilla_load_location_callback (NautilusView *nautilus_view, - const char *location, - NautilusMozillaContentView *view) -{ - char *translated_location; - - g_assert (nautilus_view == view->details->nautilus_view); - -#ifdef DEBUG_mfleming - g_print ("+%s location='%s'\n", __FUNCTION__, location); -#endif - - translated_location = mozilla_translate_uri_if_needed (view, location); +/***********************************************************************************/ +/***********************************************************************************/ - if (translated_location) { -#ifdef DEBUG_ramiro - g_print ("%s(%s,%s)\n", __FUNCTION__, location, translated_location); -#endif - - nautilus_view_report_load_underway (nautilus_view); - nautilus_mozilla_content_view_load_uri (view, translated_location); - g_free (translated_location); - } else { - nautilus_view_report_load_failed ( nautilus_view); - } -} - -/* Mozilla embed widget callbacks */ static void mozilla_title_changed_callback (GtkMozEmbed *mozilla, gpointer user_data) { NautilusMozillaContentView *view; char *new_title; + DEBUG_MSG (("+%s\n", __FUNCTION__)); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data); g_assert (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla)); new_title = gtk_moz_embed_get_title (GTK_MOZ_EMBED (view->details->mozilla)); + DEBUG_MSG (("=%s : new title='%s'\n", __FUNCTION__, new_title)); + if (new_title != NULL && strcmp (new_title, "") != 0) { - nautilus_view_set_title (view->details->nautilus_view, - new_title); + async_set_title (view, new_title); } g_free (new_title); -} - -static gboolean -mozilla_uris_differ_only_by_fragment_identifier (const char *uri1, const char *uri2) -{ - char *uri1_hash; - char *uri2_hash; - gboolean ret = FALSE; - - uri1_hash = strchr (uri1, '#'); - uri2_hash = strchr (uri2, '#'); - - if (uri1_hash == NULL && uri2_hash == NULL) { - /* neither has a fragment identifier - return true - * only if they match exactly - */ - ret = (strcasecmp (uri1, uri2) == 0); - } else if (uri1_hash == NULL) { - /* only the second has an fragment identifier - return - * true only if the part before the fragment - * identifier matches the first URI - */ - ret = (strncasecmp (uri1, uri2, uri2_hash - uri2) == 0); - } else if (uri2_hash == NULL) { - /* only the first has a fragment identifier - return - * true only if the part before the fragment - * identifier matches the second URI - */ - ret = (strncasecmp (uri1, uri2, uri1_hash - uri1) == 0); - } else if (uri1_hash - uri1 == uri2_hash - uri2) { - /* both have a fragment identifier - return true only - * if the parts before the fragment identifier match - */ - ret = (strncasecmp (uri1, uri2, uri1_hash - uri1) == 0); - } -#ifdef DEBUG_ramiro - if (ret) { - g_print("%s: returning TRUE for URI's '%s' and '%s'\n", __FUNCTION__, uri1, uri2); - } -#endif - - return ret; + DEBUG_MSG (("-%s\n", __FUNCTION__)); } static void -mozilla_location_changed_callback (GtkMozEmbed *mozilla, gpointer user_data) +mozilla_location_callback (GtkMozEmbed *mozilla, gpointer user_data) { NautilusMozillaContentView *view; char *new_location; + char *new_location_translated; + DEBUG_MSG (("+%s\n", __FUNCTION__)); view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data); g_assert (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla)); - new_location = gtk_moz_embed_get_location (GTK_MOZ_EMBED (view->details->mozilla)); + /* If we were streaming in content, stop now */ + cancel_pending_vfs_operation (view); -#ifdef DEBUG_mfleming - g_print ("+%s current moz location='%s'\n", __FUNCTION__, new_location); -#endif + new_location = gtk_moz_embed_get_location (GTK_MOZ_EMBED (view->details->mozilla)); -#ifdef DEBUG_ramiro - g_print ("mozilla_location_changed_callback (%s)\n", new_location); -#endif + new_location_translated = translate_uri_mozilla_to_nautilus (view, new_location); - /* If we only changed anchors in the same page, we should - report some fake progress to Nautilus. */ + DEBUG_MSG (("=%s : current='%s' new='%s'\n", __FUNCTION__, view->details->uri, new_location_translated)); - if (mozilla_uris_differ_only_by_fragment_identifier (view->details->uri, - new_location)) { - nautilus_view_report_load_underway (view->details->nautilus_view); - nautilus_view_report_load_complete (view->details->nautilus_view); + if (view->details->uri == NULL || !uris_identical (new_location_translated, view->details->uri)) { + update_nautilus_uri (view, new_location_translated); + } else { + DEBUG_MSG (("=%s : URI's identical, ignoring request\n", __FUNCTION__)); } - if (view->details->uri) { - g_free (view->details->uri); - } - - view->details->uri = new_location; + g_free (new_location_translated); + new_location_translated = NULL; + + g_free (new_location); + new_location = NULL; + + + DEBUG_MSG (("-%s\n", __FUNCTION__)); } #if defined(DEBUG_ramiro) @@ -675,11 +529,8 @@ debug_print_status_flags (guint status_flags) PRINT_FLAG (status_flags, GTK_MOZ_EMBED_STATUS_FAILED_USERCANCELED, "failed_usercanceled"); g_print ("\n"); } - - #endif - static void mozilla_net_state_callback (GtkMozEmbed *mozilla, gint state_flags, @@ -688,13 +539,12 @@ mozilla_net_state_callback (GtkMozEmbed *mozilla, { NautilusMozillaContentView *view; + DEBUG_MSG (("+%s\n", __FUNCTION__)); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data); g_assert (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla)); -#if defined(DEBUG_mfleming) - g_print ("gtkembedmoz signal: 'net_state'\n"); -#endif #if defined(DEBUG_ramiro) g_print ("%s\n", __FUNCTION__); debug_print_state_flags (state_flags); @@ -704,15 +554,16 @@ mozilla_net_state_callback (GtkMozEmbed *mozilla, /* win_start */ if (state_flags & GTK_MOZ_EMBED_FLAG_START) { - mozilla_content_view_set_busy_cursor (view); + set_busy_cursor (view); } /* win_stop */ if (state_flags & GTK_MOZ_EMBED_FLAG_STOP) { - mozilla_content_view_clear_busy_cursor (view); + clear_busy_cursor (view); } -} + DEBUG_MSG (("-%s\n", __FUNCTION__)); +} static void mozilla_net_stop_callback (GtkMozEmbed *mozilla, @@ -720,17 +571,24 @@ mozilla_net_stop_callback (GtkMozEmbed *mozilla, { NautilusMozillaContentView *view; + DEBUG_MSG (("+%s\n", __FUNCTION__)); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data); g_assert (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla)); -#if defined(DEBUG_mfleming) - g_print ("gtkembedmoz signal: 'net_stop'\n"); -#endif + DEBUG_MSG (("gtkembedmoz signal: 'net_stop'\n")); + + if (view->details->report_progress_to_view) { + async_report_load_complete (view); + } else { + DEBUG_MSG (("=%s : report_progress_to_view is FALSE\n", __FUNCTION__)); + } - nautilus_view_report_load_complete (view->details->nautilus_view); + DEBUG_MSG (("-%s\n", __FUNCTION__)); } + static void mozilla_link_message_callback (GtkMozEmbed *mozilla, gpointer user_data) { @@ -740,17 +598,27 @@ mozilla_link_message_callback (GtkMozEmbed *mozilla, gpointer user_data) view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data); + DEBUG_MSG (("+%s\n", __FUNCTION__)); + g_assert (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla)); link_message = gtk_moz_embed_get_link_message (GTK_MOZ_EMBED (view->details->mozilla)); + /* You could actually use make_full_uri_from_relative here + * to translate things like fragment links to full URI's. + * I just didn't. + */ + /* This is actually not that efficient */ - translated_link_message = mozilla_untranslate_uri_if_needed (view, link_message); + translated_link_message = translate_uri_mozilla_to_nautilus (view, link_message); + + DEBUG_MSG (("=%s new link message '%s'\n", __FUNCTION__, translated_link_message)); - nautilus_view_report_status (view->details->nautilus_view, - translated_link_message); + async_report_status (view, translated_link_message); g_free (translated_link_message); g_free (link_message); + + DEBUG_MSG (("-%s\n", __FUNCTION__)) } static void @@ -773,89 +641,351 @@ mozilla_progress_callback (GtkMozEmbed *mozilla, * On occasion, it appears that current_progress may actuall exceed max_progress */ - if (max_progress == -1 || max_progress == 0) { - nautilus_view_report_load_progress (view->details->nautilus_view, - 0); - } else if (max_progress < current_progress) { - nautilus_view_report_load_progress (view->details->nautilus_view, - 1.0); + if (view->details->report_progress_to_view) { + if (max_progress == -1 || max_progress == 0) { + async_report_load_progress (view, 0); + } else if (max_progress < current_progress) { + async_report_load_progress (view, 1.0); + } else { + async_report_load_progress (view, current_progress / max_progress); + } + } +} + +static gint +mozilla_dom_key_press_callback (GtkMozEmbed *mozilla, + gpointer dom_event, + gpointer user_data) +{ + g_return_val_if_fail (dom_event != NULL, NS_DOM_EVENT_IGNORED); + + DEBUG_MSG (("+%s\n", __FUNCTION__)); + + /* If this keyboard event is going to trigger a URL navigation, we need + * to fake it out like the mouse event below + */ + + if (mozilla_events_is_key_return (dom_event)) { + return mozilla_dom_mouse_click_callback (mozilla, dom_event, user_data); } else { - nautilus_view_report_load_progress (view->details->nautilus_view, - current_progress / max_progress); + return NS_DOM_EVENT_IGNORED; } + + DEBUG_MSG (("-%s\n", __FUNCTION__)); } +/* + * The dom_mouse_click/key_press handler is here primarally to catch navigation + * events to wierd nautilus-only URI schemes such as "eazel:" + * + * It only catches navigations started from an anchor tag <A>, so in particular + * form submissions can't be used to navigate to a nautilus-specific URI scheme + */ static gint -mozilla_open_uri_callback (GtkMozEmbed *mozilla, - const char *uri, - gpointer user_data) +mozilla_dom_mouse_click_callback (GtkMozEmbed *mozilla, + gpointer dom_event, + gpointer user_data) { - gint abort_uri_open; - NautilusMozillaContentView *view; - /*FIXME this static is shared between multiple browser windows! */ - static gboolean do_nothing = FALSE; + NautilusMozillaContentView *view; + char *href; + char *href_full; + char *href_translated; + gint ret; + + href = NULL; + href_full = NULL; + href_translated = NULL; + ret = NS_DOM_EVENT_IGNORED; + g_return_val_if_fail (GTK_IS_MOZ_EMBED (mozilla), NS_DOM_EVENT_IGNORED); + g_return_val_if_fail (dom_event != NULL, NS_DOM_EVENT_IGNORED); + g_return_val_if_fail (NAUTILUS_IS_MOZILLA_CONTENT_VIEW (user_data), NS_DOM_EVENT_IGNORED); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data); - g_assert (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla)); + g_return_val_if_fail (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla), TRUE); - /* Determine whether we want to abort this uri load */ - abort_uri_open = mozilla_is_uri_handled_by_nautilus (uri); + DEBUG_MSG (("+%s\n", __FUNCTION__)); -#ifdef DEBUG_mfleming - g_print ("+%s do_nothing = %d, got_called_by_nautilus = %d\n", __FUNCTION__, do_nothing, view->details->got_called_by_nautilus); +#ifdef DEBUG_ramiro + g_print ("%s (%p)\n", __FUNCTION__, dom_event); #endif - /* FIXME: I believe that this will cause a navigation from - * a page containing a specific iframe URL to that same URL - * to fail. - * - * This check is here because we get an "open_uri" call from GtkEmbedMoz - * in M18 when mozilla opens locations that appear as IFRAME's - * within the current document. If we didn't do this check, we would - * cause Nautilus to navigate to these IFRAME url's - */ + href = mozilla_events_get_href_for_event (dom_event); - if ( mozilla_events_is_url_in_iframe (mozilla, uri)) { -#ifdef DEBUG_mfleming - g_print ("URI is in an iframe;ignoring '%s'\n", uri); -#endif - return FALSE; + if (href != NULL) { + + href_full = make_full_uri_from_relative (view->details->uri, href); + href_translated = translate_uri_mozilla_to_nautilus (view, href_full); + + DEBUG_MSG (("=%s href='%s' full='%s' xlate='%s'\n", __FUNCTION__, href, href_full, href_translated)); + + if (href[0] == '#') { + /* a navigation to an anchor within the same page, let it pass */ + ret = NS_DOM_EVENT_IGNORED; + } else if (0 == strncmp (href, "javascript:", strlen ("javascript:"))) { + /* This is a bullshit javascript uri, let it pass */ + ret = NS_DOM_EVENT_IGNORED; + } else if (should_uri_navigate_bypass_nautilus (href_translated)) { + if (should_mozilla_load_uri_directly (href_translated) + && 0 == strcmp (href_full, href_translated)) { + /* If the URI doesn't need to be translated and we can load it directly, + * then just keep going...report_location_changed will happen in the + * mozilla_location_callback. + */ + DEBUG_MSG (("=%s : allowing navigate to continue\n", __FUNCTION__)); + ret = NS_DOM_EVENT_IGNORED; + } else { + /* Otherwise, cancel the current navigation and do it ourselves */ + DEBUG_MSG (("=%s : handling navigate ourselves\n", __FUNCTION__)); + + update_nautilus_uri (view, href_translated); + navigate_mozilla_to_nautilus_uri (view, href_translated); + ret = NS_DOM_EVENT_CONSUMED; + } + } else { + /* With some schemes, navigation needs to be funneled through nautilus. */ + DEBUG_MSG (("=%s : funnelling navigation through nautilus\n", __FUNCTION__)); + async_open_location (view, href_translated); + + ret = NS_DOM_EVENT_CONSUMED; + } + } else { + DEBUG_MSG (("=%s no href, ignoring\n", __FUNCTION__)); } + + g_free (href_translated); + g_free (href_full); + g_free (href); + + DEBUG_MSG (("-%s\n", __FUNCTION__)); -#ifdef DEBUG_ramiro - g_print ("mozilla_open_uri_callback (uri = %s) abort = %s\n", - uri, - abort_uri_open ? "TRUE" : "FALSE"); -#endif + return ret; +} + + +/***********************************************************************************/ +/***********************************************************************************/ + +/** + * vfs_open_callback + * + * Callback for gnome_vfs_async_open. Attempt to read data from handle + * and pass to mozilla streaming callback. + * + **/ +static void +vfs_open_callback (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data) +{ + NautilusMozillaContentView *view = data; - if (do_nothing == TRUE) { - do_nothing = FALSE; - view->details->got_called_by_nautilus = FALSE; - } else if (view->details->got_called_by_nautilus == TRUE) { - view->details->got_called_by_nautilus = FALSE; + DEBUG_MSG (("+%s GnomeVFSResult: %u\n", __FUNCTION__, (unsigned)result)); + + if (result != GNOME_VFS_OK) + { + DEBUG_MSG ((">nautilus_view_report_load_failed\n")); + nautilus_view_report_load_failed (view->details->nautilus_view); + gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->details->mozilla)); } else { - char *untranslated_uri; + if (view->details->vfs_read_buffer == NULL) { + view->details->vfs_read_buffer = g_malloc (VFS_READ_BUFFER_SIZE); + } + gtk_moz_embed_open_stream (GTK_MOZ_EMBED (view->details->mozilla), "file://", "text/html"); + gnome_vfs_async_read (handle, view->details->vfs_read_buffer, VFS_READ_BUFFER_SIZE, vfs_read_callback, view); + } + DEBUG_MSG (("-%s\n", __FUNCTION__)); +} + +/** + * vfs_read_callback: + * + * Read data from buffer and copy into mozilla stream. + **/ + +static void +vfs_read_callback (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer buffer, + GnomeVFSFileSize bytes_requested, + GnomeVFSFileSize bytes_read, + gpointer data) +{ + NautilusMozillaContentView *view = data; + + DEBUG_MSG (("+%s %ld/%ld bytes\n", __FUNCTION__, (long)bytes_requested, (long) bytes_read)); + + if (bytes_read != 0) { + gtk_moz_embed_append_data (GTK_MOZ_EMBED (view->details->mozilla), buffer, bytes_read); + } + + if (bytes_read == 0 || result != GNOME_VFS_OK) { + gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->details->mozilla)); + view->details->vfs_handle = NULL; + g_free (view->details->vfs_read_buffer); + view->details->vfs_read_buffer = NULL; + + gnome_vfs_async_close (handle, (GnomeVFSAsyncCloseCallback) gtk_true, NULL); + + if (view->details->report_progress_to_view) { + DEBUG_MSG ((">nautilus_view_report_load_complete\n")); + nautilus_view_report_load_complete (view->details->nautilus_view); + } + DEBUG_MSG (("=%s load complete\n", __FUNCTION__)); + } else { + gnome_vfs_async_read (handle, view->details->vfs_read_buffer, VFS_READ_BUFFER_SIZE, vfs_read_callback, view); + } + + DEBUG_MSG (("-%s\n", __FUNCTION__)); +} + +/***********************************************************************************/ +/***********************************************************************************/ + +/* + * FIXME + * Both of these calls can make outbound CORBA calls which + * can allow incoming CORBA calls that can cause things to bust + */ + +/* + * FIXME + * Right now, if you're on a normal HTML page and you encounter a link + * to eazel-services:///<something>, you'll get a failure from Mozilla instead + * of a login prompt. Login prompting needs to be added to Mozilla like + * the eazel-install view + */ + +/* A NULL return from this function must trigger a nautilus load error */ +static char * +translate_uri_nautilus_to_mozilla (NautilusMozillaContentView *view, const char *uri) +{ + /* gint i; */ + char *ret; + + g_return_val_if_fail (uri != NULL, NULL); + + +#ifdef EAZEL_SERVICES + if (0 == strncmp (uri, "eazel-services:", strlen ("eazel-services:"))) { + ret = eazel_services_scheme_to_http (view, uri); + } else +#endif /* EAZEL_SERVICES */ + { + ret = g_strdup (uri); + } + + return ret; + +} + +static char * +translate_uri_mozilla_to_nautilus (NautilusMozillaContentView *view, const char *uri) +{ +#ifdef EAZEL_SERVICES + return eazel_services_scheme_from_http (view, uri); +#else + return g_strdup (uri); +#endif /* EAZEL_SERVICES */ +} + +static void +set_busy_cursor (NautilusMozillaContentView *view) +{ + g_return_if_fail (NAUTILUS_IS_MOZILLA_CONTENT_VIEW (view)); + + if (!view->details->busy_cursor) { + view->details->busy_cursor = gdk_cursor_new (GDK_WATCH); + } + + g_assert (view->details->busy_cursor != NULL); + g_assert (GTK_WIDGET_REALIZED (GTK_WIDGET (view->details->mozilla))); + + gdk_window_set_cursor (GTK_WIDGET (view->details->mozilla)->window, + view->details->busy_cursor); + + gdk_flush (); +} + +static void +clear_busy_cursor (NautilusMozillaContentView *view) +{ + g_return_if_fail (NAUTILUS_IS_MOZILLA_CONTENT_VIEW (view)); + + g_assert (GTK_WIDGET_REALIZED (GTK_WIDGET (view->details->mozilla))); + + gdk_window_set_cursor (GTK_WIDGET (view->details->mozilla)->window, NULL); +} + +static void +cancel_pending_vfs_operation (NautilusMozillaContentView *view) +{ + if (view->details->vfs_handle != NULL) { + gnome_vfs_async_cancel (view->details->vfs_handle); + gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->details->mozilla)); + } + + view->details->vfs_handle = NULL; + g_free (view->details->vfs_read_buffer); + view->details->vfs_read_buffer = NULL; +} - /* set it so that we load next time we are called. */ - do_nothing = TRUE; - abort_uri_open = TRUE; - bonobo_object_ref (BONOBO_OBJECT (view->details->nautilus_view)); +/* this takes a "nautilus" uri, not a "mozilla" uri */ +static void +navigate_mozilla_to_nautilus_uri (NautilusMozillaContentView *view, + const char *nautilus_uri) +{ + char *mozilla_uri; - /*do untranslate here*/ - untranslated_uri = mozilla_untranslate_uri_if_needed (view, uri); - nautilus_view_open_location_in_this_window - (view->details->nautilus_view, untranslated_uri); - g_free (untranslated_uri); + mozilla_uri = translate_uri_nautilus_to_mozilla (view, nautilus_uri); - bonobo_object_unref (BONOBO_OBJECT (view->details->nautilus_view)); + cancel_pending_vfs_operation (view); + + if (mozilla_uri == NULL) { + async_report_load_failed (view); + goto error; + } else if (should_mozilla_load_uri_directly (nautilus_uri)) { + if (view->details->uri != NULL && uris_identical (nautilus_uri, view->details->uri)) { + DEBUG_MSG (("=%s uri's identical, telling mozilla to reload\n", __FUNCTION__)); + gtk_moz_embed_reload (GTK_MOZ_EMBED (view->details->mozilla), + GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE); + + } else { + gtk_moz_embed_load_url (GTK_MOZ_EMBED (view->details->mozilla), + mozilla_uri); + } + } else { + DEBUG_MSG (("=%s loading URI via gnome-vfs\n", __FUNCTION__)); + gnome_vfs_async_open (&(view->details->vfs_handle), nautilus_uri, GNOME_VFS_OPEN_READ, vfs_open_callback, view); } - return abort_uri_open; + g_free (view->details->uri); + view->details->uri = g_strdup (nautilus_uri); + + DEBUG_MSG (("=%s current URI is now '%s'\n", __FUNCTION__, view->details->uri)); + +error: + g_free (mozilla_uri); + mozilla_uri = NULL; } +static void +update_nautilus_uri (NautilusMozillaContentView *view, const char *nautilus_uri) +{ + cancel_pending_vfs_operation (view); + + g_free (view->details->uri); + view->details->uri = g_strdup (nautilus_uri); + + DEBUG_MSG (("=%s current URI is now '%s'\n", __FUNCTION__, view->details->uri)); + + view->details->report_progress_to_view = FALSE; + + async_report_location_change (view, view->details->uri); +} + +/***********************************************************************************/ +/***********************************************************************************/ + static gboolean is_uri_partial (const char *uri) { @@ -953,7 +1083,6 @@ remove_internal_relative_components (char *uri_current) } - /* If I had known this relative uri code would have ended up this long, I would * have done it a different way */ @@ -962,6 +1091,9 @@ make_full_uri_from_relative (const char *base_uri, const char *uri) { char *result = NULL; + g_return_val_if_fail (base_uri != NULL, g_strdup (uri)); + g_return_val_if_fail (uri != NULL, NULL); + /* See section 5.2 in RFC 2396 */ /* FIXME bugzilla.eazel.com 4413: This function does not take @@ -1077,9 +1209,7 @@ make_full_uri_from_relative (const char *base_uri, const char *uri) g_free (mutable_base_uri); g_free (mutable_uri); -#ifdef DEBUG_mfleming - g_print ("Relative URI converted base '%s' uri '%s' to '%s'\n", base_uri, uri, result); -#endif + DEBUG_MSG (("Relative URI converted base '%s' uri '%s' to '%s'\n", base_uri, uri, result)); } else { result = g_strdup (uri); } @@ -1087,149 +1217,96 @@ make_full_uri_from_relative (const char *base_uri, const char *uri) return result; } -static gint -mozilla_dom_key_press_callback (GtkMozEmbed *mozilla, - gpointer dom_event, - gpointer user_data) -{ - g_return_val_if_fail (dom_event != NULL, NS_DOM_EVENT_IGNORED); - -#ifdef DEBUG_mfleming - g_print ("%s (%p)\n", __FUNCTION__, dom_event); -#endif - - /* If this keyboard event is going to trigger a URL navigation, we need - * to fake it out like the mouse event below - */ - - if (mozilla_events_is_key_return (dom_event)) { - return mozilla_dom_mouse_click_callback (mozilla, dom_event, user_data); - } else { - return NS_DOM_EVENT_IGNORED; +#define TEST_PARTIAL(partial, expected) \ + tmp = make_full_uri_from_relative (base_uri, partial); \ + if ( 0 != strcmp (tmp, expected) ) { \ + g_message ("Test failed: partial '%s' expected '%s' got '%s'", partial, expected, tmp); \ + success = FALSE; \ + g_free (tmp); \ } -} - -static gint -mozilla_dom_mouse_click_callback (GtkMozEmbed *mozilla, - gpointer dom_event, - gpointer user_data) -{ - NautilusMozillaContentView *view; - char *href; - g_return_val_if_fail (GTK_IS_MOZ_EMBED (mozilla), NS_DOM_EVENT_IGNORED); - g_return_val_if_fail (dom_event != NULL, NS_DOM_EVENT_IGNORED); - g_return_val_if_fail (NAUTILUS_IS_MOZILLA_CONTENT_VIEW (user_data), NS_DOM_EVENT_IGNORED); - - view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data); +gboolean test_make_full_uri_from_relative (void); - g_return_val_if_fail (GTK_MOZ_EMBED (mozilla) == GTK_MOZ_EMBED (view->details->mozilla), TRUE); +gboolean +test_make_full_uri_from_relative (void) +{ + const char * base_uri = "http://a/b/c/d;p?q"; + char *tmp; + gboolean success = TRUE; -#ifdef DEBUG_ramiro - g_print ("%s (%p)\n", __FUNCTION__, dom_event); -#endif + /* Commented out cases do no t work and should; they are marked above + * as fixmes + */ - if (mozilla_events_is_in_form_POST_submit (dom_event)) { -#ifdef DEBUG_mfleming - g_print ("%s: is a POST submit\n", __FUNCTION__); -#endif - - /* So that the post event can be properly submitted without - * the Nautilus shell history/navigation framework breaking - * its context, we use a hack. The hack is to lie Nautilus - * that the POST event was instigated by Nautilus. Nautilus - * will the call our load_location() away without having - * gnome-vfs try and do the post and thus spoiling it. - */ - view->details->got_called_by_nautilus = TRUE; - } else { - - href = mozilla_events_get_href_for_event (dom_event); + /* From the RFC */ - if (href) { - char * href_full = NULL; + TEST_PARTIAL ("g", "http://a/b/c/g"); + TEST_PARTIAL ("./g", "http://a/b/c/g"); + TEST_PARTIAL ("g/", "http://a/b/c/g/"); + TEST_PARTIAL ("/g", "http://a/g"); - href_full = make_full_uri_from_relative (view->details->uri, href); + TEST_PARTIAL ("//g", "http://g"); + + TEST_PARTIAL ("?y", "http://a/b/c/?y"); + TEST_PARTIAL ("g?y", "http://a/b/c/g?y"); + TEST_PARTIAL ("#s", "http://a/b/c/d;p#s"); + TEST_PARTIAL ("g#s", "http://a/b/c/g#s"); + TEST_PARTIAL ("g?y#s", "http://a/b/c/g?y#s"); + TEST_PARTIAL (";x", "http://a/b/c/;x"); + TEST_PARTIAL ("g;x", "http://a/b/c/g;x"); + TEST_PARTIAL ("g;x?y#s", "http://a/b/c/g;x?y#s"); - g_free (href); - href = href_full; - href_full = NULL; + TEST_PARTIAL (".", "http://a/b/c/"); + TEST_PARTIAL ("./", "http://a/b/c/"); -#if 0 -/* FIXME mfleming I think I should do this here, but I'm not sure */ - href_full = mozilla_untranslate_uri_if_needed (view, href); - g_free (href); - href = href_full; - href_full = NULL; -#endif + TEST_PARTIAL ("..", "http://a/b/"); + TEST_PARTIAL ("../g", "http://a/b/g"); + TEST_PARTIAL ("../..", "http://a/"); + TEST_PARTIAL ("../../", "http://a/"); + TEST_PARTIAL ("../../g", "http://a/g"); -#ifdef DEBUG_ramiro - g_print ("%s() href = %s\n", __FUNCTION__, href); -#endif - bonobo_object_ref (BONOBO_OBJECT (view->details->nautilus_view)); - nautilus_view_open_location_in_this_window - (view->details->nautilus_view, href); - bonobo_object_unref (BONOBO_OBJECT (view->details->nautilus_view)); - g_free (href); + /* Others */ + TEST_PARTIAL ("g/..", "http://a/b/c/"); + TEST_PARTIAL ("g/../", "http://a/b/c/"); + TEST_PARTIAL ("g/../g", "http://a/b/c/g"); - return NS_DOM_EVENT_CONSUMED; - } else { -#ifdef DEBUG_ramiro - g_print ("%s() no href;ignoring\n", __FUNCTION__); -#endif - } - } - - return NS_DOM_EVENT_IGNORED; + return success; } -#define STRING_LIST_NOT_FOUND -1 -static gint -string_list_get_index_of_string (const char *string_list[], guint num_strings, const char *string) + +gboolean +uris_identical (const char *uri1, const char *uri2) { - guint i; + /* + * FIXME: the dns portion of the authority is case-insensitive, + * but the rest of the URI is case-sensitive. We just + * treat the whole thing as case-sensitive, which is mostly + * OK, especially since false negatives here aren't the end + * of the world + */ - g_return_val_if_fail (string != NULL, STRING_LIST_NOT_FOUND); - g_return_val_if_fail (string_list != NULL, STRING_LIST_NOT_FOUND); - g_return_val_if_fail (num_strings > 0, STRING_LIST_NOT_FOUND); - - for (i = 0; i < num_strings; i++) { - g_assert (string_list[i] != NULL); - if (strlen (string) >= strlen (string_list[i]) - && (strncmp (string, string_list[i], strlen (string_list[i])) == 0)) { - return i; - } - } - - return STRING_LIST_NOT_FOUND; + return (strcmp (uri1, uri2) == 0); } - /* - * The issue here is that mozilla handles some protocols "natively" just as nautilus - * does thanks to gnome-vfs magic. - * - * The embedded mozilla beast provides a mechanism for aborting url loading (ie, the - * thing that happens when a user boinks on a hyperlink). - * - * We use this feature to abort uri loads for the following protocol(s): - * + * returns TRUE if a specified URI can be loaded by the mozilla-content-view + * If TRUE: Nautilus is informed via report_location_change and navigation proceeds immediately + * If FALSE: Nautilus is informed via open_location_in_this_window and we wait to be called back */ + static gboolean -mozilla_is_uri_handled_by_nautilus (const char *uri) +should_uri_navigate_bypass_nautilus (const char *uri) { static const char *handled_by_nautilus[] = { - "ftp", - "eazel", - "eazel-install", - "eazel-pw", - "eazel-services", "man", "info", "help", "gnome-help", - "ghelp" + "ghelp", + "http", + "file", + "eazel-services" }; g_return_val_if_fail (uri != NULL, FALSE); @@ -1239,105 +1316,137 @@ mozilla_is_uri_handled_by_nautilus (const char *uri) } /* - * Conversly, this a list of protocols handled by mozilla. The strategy is to check - * uris for these protocols and pass them through to mozilla as as. For other uris, - * we try to use gnome-vfs and later stream the information into the gtkmozembed - * widget. For example, this is how the man: protocol works. + * This a list of URI schemes that mozilla should load directly, rather than load through gnome-vfs */ static gboolean -mozilla_is_uri_handled_by_mozilla (const char *uri) +should_mozilla_load_uri_directly (const char *uri) { static const char *handled_by_mozilla[] = { "http", - "file" + "file", + "eazel-services" }; return string_list_get_index_of_string (handled_by_mozilla, NUM_ELEMENTS_IN_ARRAY (handled_by_mozilla), uri) != STRING_LIST_NOT_FOUND; } - -/* A NULL return from this function must trigger a nautilus load error */ -static char * -mozilla_translate_uri_if_needed (NautilusMozillaContentView *view, const char *uri) +static gint +string_list_get_index_of_string (const char *string_list[], guint num_strings, const char *string) { - /* gint i; */ - char *ret; + guint i; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (string != NULL, STRING_LIST_NOT_FOUND); + g_return_val_if_fail (string_list != NULL, STRING_LIST_NOT_FOUND); + g_return_val_if_fail (num_strings > 0, STRING_LIST_NOT_FOUND); + + for (i = 0; i < num_strings; i++) { + g_assert (string_list[i] != NULL); + if (strlen (string) >= strlen (string_list[i]) + && (strncmp (string, string_list[i], strlen (string_list[i])) == 0)) { + return i; + } + } + + return STRING_LIST_NOT_FOUND; +} -#ifdef EAZEL_SERVICES - if (0 == strncmp (uri, "eazel-services:", strlen ("eazel-services:"))) { - ret = eazel_services_scheme_translate (view, uri, FALSE); +/* + * one-time initialization that need to happen before the first GtkMozEmbed widget + * is created + */ -#ifdef DEBUG_mfleming - g_message ("Mozilla: translated uri '%s' to '%s'\n", uri, ret ? ret : "<no such page>"); -#endif +/* The "Mozilla Profile" directory is the place where mozilla stores + * things like cookies and cache. Here we tell the mozilla embedding + * widget to use ~/.nautilus/MozillaProfile for this purpose. + * + * We need mozilla M19 to support this feature. + */ - } else -#endif /* EAZEL_SERVICES */ - { - ret = g_strdup (uri); - } +static void +pre_widget_initialize (void) +{ + const char *profile_directory_name = "MozillaProfile"; + char *profile_base_path; + char *profile_path; + char *cache_path; + + profile_base_path = g_strdup_printf ("%s/.nautilus", g_get_home_dir ()); + profile_path = g_strdup_printf ("%s/.nautilus/%s", g_get_home_dir (), profile_directory_name); + cache_path = g_strdup_printf ("%s/.nautilus/%s/Cache", g_get_home_dir (), profile_directory_name); - return ret; + /* Create directories if they don't already exist */ + mkdir (profile_path, 0777); + mkdir (cache_path, 0777); -} +#if (MOZILLA_MILESTONE >= 19) + /* this will be in Mozilla 0.8 */ + /* Its a bug in mozilla embedding that we need to cast the const away */ + gtk_moz_embed_set_profile_path (profile_base_path, (char *) profile_name); +#endif -static char * -mozilla_untranslate_uri_if_needed (NautilusMozillaContentView *view, const char *uri) -{ -#ifdef EAZEL_SERVICES - return eazel_services_scheme_untranslate (view, uri); -#else - return g_strdup (uri); -#endif /* EAZEL_SERVICES */ + g_free (cache_path); + g_free (profile_path); + g_free (profile_base_path); } -GtkType -nautilus_mozilla_content_view_get_type (void) + +/* + * one-time initialization that need to happen after the first GtkMozEmbed widget + * is created + */ +static void +post_widget_initialize (void) { - static GtkType mozilla_content_view_type = 0; + static gboolean once = FALSE; + char *cache_dir; - if (!mozilla_content_view_type) - { - static const GtkTypeInfo mozilla_content_view_info = - { - "NautilusMozillaContentView", - sizeof (NautilusMozillaContentView), - sizeof (NautilusMozillaContentViewClass), - (GtkClassInitFunc) nautilus_mozilla_content_view_initialize_class, - (GtkObjectInitFunc) nautilus_mozilla_content_view_initialize, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - mozilla_content_view_type = gtk_type_unique (GTK_TYPE_VBOX, &mozilla_content_view_info); + if (once == TRUE) { + return; } - - return mozilla_content_view_type; + + once = TRUE; + + /* Tell the security manager to allow ftp:// and file:// content through. */ + mozilla_preference_set_boolean ("security.checkloaduri", FALSE); + + /* Change http protocol user agent to include the string 'Nautilus' */ + mozilla_preference_set ("general.useragent.misc", "Nautilus/1.0PR3"); + + /* We dont want to use the proxy for localhost */ + mozilla_preference_set ("network.proxy.no_proxies_on", "localhost"); + + /* Setup routing of proxy preferences from gconf to mozilla */ + mozilla_gconf_listen_for_proxy_changes (); + + cache_dir = g_strdup_printf ("%s/.nautilus/MozillaProfile/Cache", g_get_home_dir ()); + + mozilla_preference_set ("browser.cache.directory", cache_dir); + + g_free (cache_dir); + + cache_dir = NULL; } #ifdef EAZEL_SERVICES + +/* + * URL scheme hack for the eazel-services: scheme + */ + /* A NULL return from this function must trigger a nautilus load error */ static char * -eazel_services_scheme_translate (NautilusMozillaContentView *view, - const char *uri, - gboolean is_retry) +eazel_services_scheme_to_http (NautilusMozillaContentView *view, + const char *uri) { const char *uri_minus_scheme; char *new_uri = NULL; char *ret = NULL; AmmoniteError err; - if (CORBA_OBJECT_NIL == nautilus_mozilla_content_view_user_control) { - return NULL; - } - /* Chew off the the scheme, leave the colon */ uri_minus_scheme = strchr (uri, (unsigned char)':'); @@ -1351,48 +1460,17 @@ eazel_services_scheme_translate (NautilusMozillaContentView *view, g_free (new_uri); new_uri = NULL; break; - -#ifdef EAZEL_SERVICES_MOZILLA_MODAL_LOGIN - case ERR_UserNotLoggedIn: - if (is_retry) { - /* We already tried this once and it didn't work */ - ret = NULL; - } else { - AmmoniteParsedURL *parsed = NULL; - LoginAsyncState *p_state; - - p_state = g_new0 (LoginAsyncState, 1); - - p_state->uri = strdup (uri); - p_state->view = view; - - parsed = ammonite_url_parse (uri); - g_assert (parsed); - - /* FIXME bugzilla.eazel.com 4412: it's possible that "view" will be gone by the time the reponse comes back */ - if (! ammonite_do_prompt_login_async (parsed->user, NULL, NULL, p_state, prompt_login_cb) ) { - ret = NULL; - g_free (p_state->uri); - g_free (p_state); - } - - ammonite_url_free (parsed); - } - break; -#endif /* EAZEL_SERVICES_MOZILLA_MODAL_LOGIN */ - default: ret = NULL; break; - } return ret; } static char * -eazel_services_scheme_untranslate (NautilusMozillaContentView *view, - const char *uri) +eazel_services_scheme_from_http (NautilusMozillaContentView *view, + const char *uri) { AmmoniteError err; char *ret; @@ -1400,9 +1478,7 @@ eazel_services_scheme_untranslate (NautilusMozillaContentView *view, err = ammonite_eazel_url_for_http_url (uri, &ret); if (ERR_Success == err) { -#ifdef DEBUG_mfleming - g_message ("Mozilla: untranslated uri '%s' to '%s'\n", uri, ret ); -#endif + DEBUG_MSG (("%s untranslated uri '%s' to '%s'\n", __FUNCTION__, uri, ret)); } else { ret = g_strdup (uri); } @@ -1410,168 +1486,207 @@ eazel_services_scheme_untranslate (NautilusMozillaContentView *view, return ret; } -#ifdef EAZEL_SERVICES_MOZILLA_MODAL_LOGIN -static void /* AmmonitePromptLoginCb */ -eazel_services_prompt_login_cb ( - gpointer user_data, - const EazelProxy_User *user, - const EazelProxy_AuthnFailInfo *fail_info -) { - LoginAsyncState *p_state; +#endif /* EAZEL_SERVICES */ - p_state = (LoginAsyncState *) user_data; - /* Are we still at the same location? If not, forget about it */ - if ( 0 == strcmp (p_state->uri, p_state->view->details->uri)) { - goto error; - } +/***********************************************************************************/ +/***********************************************************************************/ - if (fail_info) { - /*fail_info is non-NULL on failure */ - nautilus_view_report_load_failed (p_state->view->details->nautilus_view); - goto error; - } else { - eazel_services_scheme_translate (p_state->view, p_state->uri, TRUE); +/* + * What's going on here? + * + * Below are wrapper functions that delay outbound NautilusViewFrame callbacks + * until we return to the GTK idle loop. The problem is this: + * + * o Any outbound ORBit call, including oneway calls, may result in a + * pending inbound call being dispatched + * o Some inbound calls, particularly Bonobo::Control::realize, cannot safely + * be handled away from the event loop. Indeed, if Bonobo::Control::realize + * gets called during a callback from Mozilla, the mozilla view will deadlock. + * + * By postponing all outbound ORBit calls invoked as a result of mozilla callback + * to the event loop, we eliminated the possibility that inbound calls can occur + * during callbacks from Mozilla + * + * Note: outbound ORBit calls that do not occur as a result of a mozilla callback + * do not need to be so wrapped + */ + +/* + * Note that the "unref" in the calls below matches the "ref" in the async_ + * calls below + */ + +#define DISPATCH_STRING_TMPL(FUNCNAME, REALFUNCNAME, ARGNAME) \ + static int /* GtkFunction */ \ + dispatch_##FUNCNAME (gpointer data) \ + { \ + NautilusMozillaContentView *view; \ + \ + view = NAUTILUS_MOZILLA_CONTENT_VIEW (data); \ + \ + view->details->is_pending_##FUNCNAME = FALSE; \ + \ + if (!GTK_OBJECT_DESTROYED (view)) { \ + DEBUG_MSG ((">>nautilus_view_" #REALFUNCNAME " '%s'\n", view->details->pending_##ARGNAME)); \ + nautilus_view_##REALFUNCNAME (view->details->nautilus_view, view->details->pending_##ARGNAME); \ + g_free (view->details->pending_##ARGNAME); \ + view->details->pending_##ARGNAME = NULL; \ + } \ + gtk_object_unref (GTK_OBJECT (view)); \ + \ + return 0; \ } -error: - g_free (p_state->uri); - g_free (p_state); -} +DISPATCH_STRING_TMPL (set_title, set_title, title) -#endif /* EAZEL_SERVICES_MOZILLA_MODAL_LOGIN */ +DISPATCH_STRING_TMPL (report_status, report_status, link_message) -#endif /* EAZEL_SERVICES */ +DISPATCH_STRING_TMPL (open_location, open_location_in_this_window, open_uri) -#define TEST_PARTIAL(partial, expected) \ - tmp = make_full_uri_from_relative (base_uri, partial); \ - if ( 0 != strcmp (tmp, expected) ) { \ - g_message ("Test failed: partial '%s' expected '%s' got '%s'", partial, expected, tmp); \ - success = FALSE; \ - g_free (tmp); \ - } +static int /* GtkFunction */ +dispatch_report_location_change (gpointer data) +{ + NautilusMozillaContentView *view; -gboolean test_make_full_uri_from_relative (void); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (data); -gboolean -test_make_full_uri_from_relative (void) -{ - const char * base_uri = "http://a/b/c/d;p?q"; - char *tmp; - gboolean success = TRUE; + view->details->is_pending_report_location_change = FALSE; - /* Commented out cases do no t work and should; they are marked above - * as fixmes - */ + if (!GTK_OBJECT_DESTROYED (view)) { + nautilus_view_report_location_change (view->details->nautilus_view, view->details->pending_report_uri, NULL, view->details->pending_report_uri); + g_free (view->details->pending_report_uri); + view->details->pending_report_uri = NULL; + } - /* From the RFC */ + gtk_object_unref (GTK_OBJECT (view)); - TEST_PARTIAL ("g", "http://a/b/c/g"); - TEST_PARTIAL ("./g", "http://a/b/c/g"); - TEST_PARTIAL ("g/", "http://a/b/c/g/"); - TEST_PARTIAL ("/g", "http://a/g"); + return 0; +} - TEST_PARTIAL ("//g", "http://g"); - - TEST_PARTIAL ("?y", "http://a/b/c/?y"); - TEST_PARTIAL ("g?y", "http://a/b/c/g?y"); - TEST_PARTIAL ("#s", "http://a/b/c/d;p#s"); - TEST_PARTIAL ("g#s", "http://a/b/c/g#s"); - TEST_PARTIAL ("g?y#s", "http://a/b/c/g?y#s"); - TEST_PARTIAL (";x", "http://a/b/c/;x"); - TEST_PARTIAL ("g;x", "http://a/b/c/g;x"); - TEST_PARTIAL ("g;x?y#s", "http://a/b/c/g;x?y#s"); +static int /* GtkFunction */ +dispatch_report_load_failed (gpointer data) +{ + NautilusMozillaContentView *view; - TEST_PARTIAL (".", "http://a/b/c/"); - TEST_PARTIAL ("./", "http://a/b/c/"); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (data); - TEST_PARTIAL ("..", "http://a/b/"); - TEST_PARTIAL ("../g", "http://a/b/g"); - TEST_PARTIAL ("../..", "http://a/"); - TEST_PARTIAL ("../../", "http://a/"); - TEST_PARTIAL ("../../g", "http://a/g"); + view->details->is_pending_report_load_failed = FALSE; - /* Others */ - TEST_PARTIAL ("g/..", "http://a/b/c/"); - TEST_PARTIAL ("g/../", "http://a/b/c/"); - TEST_PARTIAL ("g/../g", "http://a/b/c/g"); + if (!GTK_OBJECT_DESTROYED (view)) { + DEBUG_MSG ((">>nautilus_view_report_load_failed\n")); + nautilus_view_report_load_failed (view->details->nautilus_view); + } - return success; + gtk_object_unref (GTK_OBJECT (view)); + + return 0; } -static void -ensure_profile_dir (void) +static int /* GtkFunction */ +dispatch_report_load_complete (gpointer data) { - char *profile_dir; - - profile_dir = g_strdup_printf ("%s/.nautilus/MozillaProfile", g_get_home_dir ()); + NautilusMozillaContentView *view; - /* Make sure the profile directory exists */ - mkdir (profile_dir, 0777); - - g_free (profile_dir); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (data); + + view->details->is_pending_report_load_complete = FALSE; + + if (!GTK_OBJECT_DESTROYED (view)) { + DEBUG_MSG ((">>nautilus_view_report_load_failed\n")); + nautilus_view_report_load_complete (view->details->nautilus_view); + } + + gtk_object_unref (GTK_OBJECT (view)); + + return 0; } -static void -ensure_cache_dir (void) +static int /* GtkFunction */ +dispatch_report_load_progress (gpointer data) { - char *cache_dir; + NautilusMozillaContentView *view; - ensure_profile_dir (); - - cache_dir = g_strdup_printf ("%s/.nautilus/MozillaProfile/Cache", g_get_home_dir ()); + view = NAUTILUS_MOZILLA_CONTENT_VIEW (data); - /* Make sure the cache directory exists */ - mkdir (cache_dir, 0777); - - mozilla_preference_set ("browser.cache.directory", cache_dir); - - g_free (cache_dir); + view->details->is_pending_report_load_progress = FALSE; + + if (!GTK_OBJECT_DESTROYED (view)) { + DEBUG_MSG ((">>nautilus_view_report_load_progress %f\n", + view->details->pending_load_progress)); + nautilus_view_report_load_progress (view->details->nautilus_view, view->details->pending_load_progress); + } + + gtk_object_unref (GTK_OBJECT (view)); + + return 0; } -static void -mozilla_content_view_one_time_happenings (void) -{ - static gboolean once = FALSE; +/* + * These async_ functions delay CORBA calls by registering a gtk_timeout + * with the callbacks being the dispatch functions above. + * + * Note that a gtk reference is kept across the timeout callbacks + * to ensure the object is still valid + */ - if (once == TRUE) { - return; +#define ASYNC_STRING_WRAPPER_TMPL(FUNCNAME, ARGNAME) \ + static void \ + async_##FUNCNAME (NautilusMozillaContentView *view, const char *ARGNAME) \ + { \ + g_free (view->details->pending_##ARGNAME); \ + view->details->pending_##ARGNAME = g_strdup (ARGNAME); \ + \ + DEBUG_MSG (("~" #FUNCNAME " '%s'\n", view->details->pending_##ARGNAME)); \ + \ + if (!view->details->is_pending_##FUNCNAME) { \ + view->details->is_pending_##FUNCNAME = TRUE; \ + gtk_object_ref (GTK_OBJECT (view)); \ + gtk_timeout_add (0, dispatch_##FUNCNAME, view); \ + } \ } - once = TRUE; - /* Tell the security manager to allow ftp:// and file:// content through. */ - mozilla_preference_set_boolean ("security.checkloaduri", FALSE); +ASYNC_STRING_WRAPPER_TMPL (set_title, title) - /* Change http protocol user agent to include the string 'Nautilus' */ - mozilla_preference_set ("general.useragent.misc", "Nautilus/1.0PR3"); +ASYNC_STRING_WRAPPER_TMPL (report_location_change, report_uri) - /* We dont want to use the proxy for localhost */ - mozilla_preference_set ("network.proxy.no_proxies_on", "localhost"); +ASYNC_STRING_WRAPPER_TMPL (report_status, link_message) - /* Setup routing of proxy preferences from gconf to mozilla */ - mozilla_gconf_listen_for_proxy_changes (); +ASYNC_STRING_WRAPPER_TMPL (open_location, open_uri) - ensure_cache_dir (); +static void +async_report_load_failed (NautilusMozillaContentView *view) +{ + if (!view->details->is_pending_report_load_failed) { + DEBUG_MSG (("~report_load_failed\n")); + view->details->is_pending_report_load_failed = TRUE; + gtk_object_ref (GTK_OBJECT (view)); + gtk_timeout_add (0, dispatch_report_load_failed, view); + } } -/* The "Mozilla Profile" directory is the place where mozilla stores - * things like cookies and cache. Here we tell the mozilla embedding - * widget to use ~/.nautilus/MozillaProfile for this purpose. - * - * We need mozilla M19 to support this feature. - */ static void -mozilla_content_view_setup_profile_directory (void) +async_report_load_complete (NautilusMozillaContentView *view) { -#if (MOZILLA_MILESTONE >= 19) - const char *profile_name = "MozillaProfile"; - char *profile_dir; - - profile_dir = g_strdup_printf ("%s/.nautilus", g_get_home_dir ()); - - /* Its a bug in mozilla embedding that we need to cast the const away */ - gtk_moz_embed_set_profile_path (profile_dir, (char *) profile_name); -#endif + if (!view->details->is_pending_report_load_complete) { + DEBUG_MSG (("~report_load_complete\n")); + view->details->is_pending_report_load_complete = TRUE; + gtk_object_ref (GTK_OBJECT (view)); + gtk_timeout_add (0, dispatch_report_load_complete, view); + } } +static void +async_report_load_progress (NautilusMozillaContentView *view, double load_progress) +{ + view->details->pending_load_progress = load_progress; + + if (!view->details->is_pending_report_load_progress) { + DEBUG_MSG (("~report_load_progress %f\n", + view->details->pending_load_progress)); + view->details->is_pending_report_load_progress = TRUE; + gtk_object_ref (GTK_OBJECT (view)); + gtk_timeout_add (0, dispatch_report_load_progress, view); + } +} diff --git a/components/mozilla/nautilus-mozilla-content-view.h b/components/mozilla/nautilus-mozilla-content-view.h index 5f748627b..e829ebaa6 100644 --- a/components/mozilla/nautilus-mozilla-content-view.h +++ b/components/mozilla/nautilus-mozilla-content-view.h @@ -54,11 +54,6 @@ GtkType nautilus_mozilla_content_view_get_type (void); /* Component embedding support */ -NautilusView *nautilus_mozilla_content_view_get_nautilus_view (NautilusMozillaContentView *view); - - -/* URI handling */ -void nautilus_mozilla_content_view_load_uri (NautilusMozillaContentView *view, - const char *uri); +BonoboObject *nautilus_mozilla_content_view_new (void); #endif /* NAUTILUS_MOZILLA_CONTENT_VIEW_H */ |