[Nautilus-list] [PATCH] context menus for the mozilla component



Hi,

I added some stuff to the mozilla component to make context menus
possible. At the moment only open link and open link in new window work.
But before other items are added or implemented, I would like to know
what items should be in the menu, and, for example, how downloading
should be handled (gtm? own dialog? no dialog but something else?).

I'm aware the patch needs some cleaning up (function names, etc), I will
do that when I know the functionality is ok.

Remco de Jong
Index: components/mozilla/nautilus-mozilla-content-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/components/mozilla/nautilus-mozilla-content-view.c,v
retrieving revision 1.98
diff -u -r1.98 nautilus-mozilla-content-view.c
--- components/mozilla/nautilus-mozilla-content-view.c	2001/05/11 01:30:27	1.98
+++ components/mozilla/nautilus-mozilla-content-view.c	2001/05/20 14:49:01
@@ -19,6 +19,7 @@
  *
  *  Authors: Ramiro Estrugo <ramiro eazel com>
  *  	     Mike Fleming <mfleming eazel com>
+ * 			Remco de Jong <rdj rdj cg nu>
  *
  */
 
@@ -45,6 +46,7 @@
 #include <eel/eel-gtk-macros.h>
 #include <eel/eel-stock-dialogs.h>
 #include <gtk/gtksignal.h>
+#include <gnome.h>
 #include <libgnome/gnome-i18n.h>
 #include <libgnomeui/gnome-dialog-util.h>
 #include <libgnomeui/gnome-dialog.h>
@@ -91,6 +93,7 @@
 	GtkMozEmbed 	*mozilla;		/* If this is NULL, the mozilla widget has not yet been initialized */ 
 	NautilusView 	*nautilus_view;
 	GdkCursor 	*busy_cursor;
+	ContextInfo *moz_info;
 	char		*vfs_read_buffer;
 	GnomeVFSAsyncHandle *vfs_handle;
 						/* set to TRUE during the DOM callbacks
@@ -107,7 +110,6 @@
 static void     nautilus_mozilla_content_view_initialize       (NautilusMozillaContentView      *view);
 static void     nautilus_mozilla_content_view_destroy          (GtkObject                       *object);
 
-
 /* Gnome VFS callback functions */
 static void	vfs_open_callback				(GnomeVFSAsyncHandle 		*handle,
 								 GnomeVFSResult			result,
@@ -184,6 +186,13 @@
 								 const char			*nautilus_uri);
 
 static void	cancel_pending_vfs_operation			(NautilusMozillaContentView	*view);
+void context_menu_show (NautilusMozillaContentView *view);
+void get_context_menu (GnomeUIInfo *menu_data, ContextInfo *info);
+void fill_context_menu_item (GnomeUIInfo *menu_data, gchar *title, gchar *hint, gpointer user_function, gpointer user_data);
+void open_link_new_callback (GtkWidget *widget, gpointer user_data);
+void open_link_callback (GtkWidget *widget, gpointer user_data);
+void open_window_callback (GtkWidget *widget, gpointer user_data);
+gint handle_url (NautilusMozillaContentView *view, gchar *href);
 
 /* Utility functions */
 
@@ -1051,20 +1060,268 @@
  * form submissions can't be used to navigate to a nautilus-specific URI scheme
  */
 
+void open_window_callback (GtkWidget *widget, gpointer user_data)
+{
+}
+
+void open_link_callback (GtkWidget *widget, gpointer user_data)
+{
+	gint ret;
+	NautilusMozillaContentView *view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data);
+
+	ret = handle_url (view, view->details->moz_info->link);
+	if (ret == NS_DOM_EVENT_IGNORED) {
+		/* feed it to mozilla */
+		nautilus_view_open_location_in_this_window (view->details->nautilus_view, view->details->moz_info->link);
+	}
+}
+
+void open_link_new_callback (GtkWidget *widget, gpointer user_data)
+{
+	NautilusMozillaContentView *view = NAUTILUS_MOZILLA_CONTENT_VIEW (user_data);
+	
+	nautilus_view_open_location_force_new_window (view->details->nautilus_view, view->details->moz_info->link, NULL);
+}
+
+void fill_context_menu_item (GnomeUIInfo *menu_data, gchar *title, gchar *hint, gpointer user_function, gpointer user_data)
+{
+		menu_data->type = GNOME_APP_UI_ITEM;
+		menu_data->label = title;
+		menu_data->hint = hint;
+		menu_data->moreinfo = user_function;
+		menu_data->user_data = user_data;
+		menu_data->unused_data = NULL;
+		menu_data->pixmap_type = GNOME_APP_PIXMAP_NONE;
+		menu_data->pixmap_info = NULL;
+		menu_data->accelerator_key = 0;
+		menu_data->ac_mods = 0;
+		menu_data->widget = NULL;
+}
+
+void 
+get_context_menu (GnomeUIInfo *menu_data, ContextInfo *info)
+{
+	int i = 0;
+	
+	if (info->context & CONTEXT_LINK) {
+		/* open in new window, open */
+		fill_context_menu_item (&menu_data[i++], 
+						_("Open Link"), 
+						_("Open link in the current window"), 
+						open_link_callback,
+						NULL);
+		fill_context_menu_item (&menu_data[i++], 
+						_("Open Link In New Window"), 
+						_("Open link in a new window"), 
+						open_link_new_callback,
+						NULL);
+	}
+
+	if (info->context & CONTEXT_IMAGE) {
+		/* save image as */
+		fill_context_menu_item (&menu_data[i++], 
+						_("Save Image"), 
+						_("Save the selected image to a file"), 
+						NULL, /* callback goes here instead of NULL */
+						NULL);
+	}
+
+	if ((info->context & CONTEXT_OTHER || info->context & CONTEXT_DOCUMENT) && !(info->context & CONTEXT_LINK) && !(info->context & CONTEXT_IMAGE)) {
+		/* new window */
+		fill_context_menu_item (&menu_data[i++], 
+						_("New Window"), 
+						_("Open a new window"), 
+						open_window_callback,
+						NULL);
+	}
+	
+	menu_data[i++].type = GNOME_APP_UI_SEPARATOR;
+
+	fill_context_menu_item (&menu_data[i++], 
+					_("Zoom In"), 
+					_("Zoom in on the current page"), 
+					NULL, /* callback goes here instead of NULL */
+					NULL);
+
+	fill_context_menu_item (&menu_data[i++], 
+					_("Zoom Out"), 
+					_("Zoom out on the current page"), 
+					NULL, /* callback goes here instead of NULL */
+					NULL);
+
+	fill_context_menu_item (&menu_data[i++], 
+					_("Normal Size"), 
+					_("Reset zoom for the current page"), 
+					NULL, /* callback goes here instead of NULL */
+					NULL);
+
+	/* close with an end item */
+	menu_data[i].type = GNOME_APP_UI_ENDOFINFO;
+}
+
+void 
+context_menu_show (NautilusMozillaContentView *view)
+{        
+	/*
+	 * context and a pointer to menu are added to each item
+	 * FIXME: create menu using gnome_popup
+	 */
+
+	GtkWidget *popup;
+	GnomeUIInfo *menu_data = g_new0 (GnomeUIInfo, 10); /* ugly, but will do for now */
+
+	get_context_menu (menu_data, view->details->moz_info);
+	popup = gnome_popup_menu_new (menu_data);
+	
+       	/* Wait for the menu to be destroyed if a menu item is selected */
+       	if (gnome_popup_menu_do_popup_modal (popup, NULL, NULL, NULL , view) != -1) {
+               	while (gtk_events_pending()) {
+                       	gtk_main_iteration();
+		}
+	}
+	
+	g_free (menu_data);
+       	gtk_widget_destroy (popup);
+	
+}
+
+gint
+handle_url (NautilusMozillaContentView *view, gchar *href)
+{
+	char 				*href_full;
+	char 				*href_mozilla;
+	gint					ret;
+
+	/*
+	 * What's up with these translations?
+	 * mozilla_to_nautilus translates http://localhost:160xx -> eazel-services:///
+	 * nautilus_to_mozilla translates eazel--services -> http://localhost:160xx
+	 * 
+	 * Case 0)
+	 *  "href" is a full normal HTTP uri
+	 *  href_full is identical to href
+	 *  Both the mozilla and nautilus versions of the href are identical
+	 *  We let the navigate continue w/o interrupting
+	 *
+	 * Case 1)
+	 *  "href" is a partial URI inside a normal HTTP page
+	 *  href_full is the full version of the uri
+	 *  Like in case 0,
+	 *  Both the mozilla and nautilus versions of the href are identical
+	 *  We let the navigate continue w/o interrupting
+	 *
+	 * Case 2)
+	 *   "href" is a relative link inside an eazel-services page
+	 *   href_full is "eazel-services:///<whatever>"
+	 *   href_mozilla is "http://localhost:160xx/<whatever>"
+	 *   We let the navigate continue w/o interrupting
+	 * 
+	 * Case 3)
+	 *   "href" is a full eazel-services: URI
+	 *   href_full is "eazel-services:///<whatever>"
+	 *   href_mozilla is "http://localhost:160xx/<whatever>"
+	 *   We need to interrupt the navigate to translate.  It's the
+	 *   same case as case (2) in the if statement below
+	 *
+	 * It's not actually feasible to get an http://localhost:160xx
+	 * as href_full here, so we don't handle the case where
+	 * href_full needs to be converted to a "nautilus" URI
+	 */
+
+	href_full = NULL;
+	href_mozilla = NULL;
+	ret = NS_DOM_EVENT_IGNORED;
+
+	href_full = make_full_uri_from_relative (view->details->uri, href);
+	href_mozilla = translate_uri_nautilus_to_mozilla (view, href_full);
+	DEBUG_MSG (("=%s href='%s' full='%s' xlate='%s'\n", __FUNCTION__, href, href_full, href_mozilla));
+
+	if (href_mozilla == NULL) {
+		/* An eazel-services URL when the user isn't logged in.
+	 	 * Right now, we report a load error.  But we
+	  	 * could tell ammonite to prompt for login
+	 	 */
+		DEBUG_MSG ((">nautilus_view_report_load_failed\n"));
+		nautilus_view_report_load_failed (view->details->nautilus_view);
+		ret = NS_DOM_EVENT_CONSUMED;
+	} else if (href[0] == '#') {
+		/* a navigation to an anchor within the same page */
+		view->details->user_initiated_navigation = TRUE;
+
+		/* bugzilla.mozilla.org 70311 -- anchor navigation
+	 	 * doesn't work on documents that have been streamed
+	 	 * into gtkmozembed.  So we do it outselves.
+	 	 */
+		if (should_mozilla_load_uri_directly (href_full)) {
+			DEBUG_MSG (("=%s : anchor navigation in normal uri, allowing navigate to continue\n", __FUNCTION__));
+			ret = NS_DOM_EVENT_IGNORED;
+		} else {
+			char *unescaped_anchor;
+
+			/* href+1 to skip the fragment identifier */
+			unescaped_anchor = gnome_vfs_unescape_string (href+1, NULL);
+
+			DEBUG_MSG (("=%s : anchor navigation in gnome-vfs uri, navigate by hand to anchor '%s'\n", __FUNCTION__, unescaped_anchor));
+
+			mozilla_navigate_to_anchor (view->details->mozilla, unescaped_anchor);
+			g_free (unescaped_anchor);
+			ret = NS_DOM_EVENT_CONSUMED;
+			}
+	} else if (0 == strncmp (href, "javascript:", strlen ("javascript:"))) {
+		/* This is a bullshit javascript uri, let it pass */
+		DEBUG_MSG (("=%s : javascript uri, allowing navigate to continue\n", __FUNCTION__));
+		ret = NS_DOM_EVENT_IGNORED;			
+	} else if (should_uri_navigate_bypass_nautilus (href_full)) {
+		view->details->user_initiated_navigation = TRUE;
+
+		if ((should_mozilla_load_uri_directly (href_full) 
+	     	&& 0 == strcmp (href_full, href_mozilla))
+	     	|| is_uri_relative (href)) {
+			/* If the URI doesn't need to be translated and we can load it directly,
+			 * then just keep going...report_location_change will happen in the
+			 * mozilla_location_callback.
+			 */
+			/* This is cases (0), (1), and (2) above */
+			DEBUG_MSG (("=%s : allowing navigate to continue\n", __FUNCTION__));
+			ret = NS_DOM_EVENT_IGNORED;
+		} else {
+			/* Otherwise, cancel the current navigation and do it ourselves */
+			/* This is case (3) above */
+			/* FIXME: form posting in this case does not work */
+			DEBUG_MSG (("=%s : handling navigate ourselves\n", __FUNCTION__));
+
+			navigate_mozilla_to_nautilus_uri (view, href_full);
+			update_nautilus_uri (view, href_full);
+
+			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__));
+		DEBUG_MSG ((">nautilus_view_open_location_in_this_window '%s'", href_full));
+		nautilus_view_open_location_in_this_window (view->details->nautilus_view, href_full);
+
+		ret = NS_DOM_EVENT_CONSUMED;
+	}
+
+	g_free (href_mozilla);
+	g_free (href_full);
+	
+	return ret;
+}
+
+
 static gint
 mozilla_dom_mouse_click_callback (GtkMozEmbed *mozilla,
 				  gpointer	dom_event,
 				  gpointer	user_data)
 {
  	NautilusMozillaContentView	*view;
-	char				*href;
-	char 				*href_full;
-	char 				*href_mozilla;
-	gint				ret;
+	char					*href;
+	gint					ret;
+	MouseEventInfo 		*info;
 
 	href = NULL;
-	href_full = NULL;
-	href_mozilla = NULL;
 	ret = NS_DOM_EVENT_IGNORED;
 
 	g_return_val_if_fail (GTK_IS_MOZ_EMBED (mozilla), NS_DOM_EVENT_IGNORED);
@@ -1081,128 +1338,55 @@
 	g_print ("%s (%p)\n", __FUNCTION__, dom_event);
 #endif
 
-	href = mozilla_events_get_href_for_event (dom_event);
-
-	if (href != NULL) {
+	/* 
+	 * first check which button was pressed
+	 * show a context menu on right click 
+	 * left clicks are handled the old way
+	 * see description below.
+	 * ps. this code was taken from galeon
+	 */
+	 
+        info = g_new0 (MouseEventInfo,1);
+        if (!mozilla_get_mouse_event_info (dom_event, info))
+	{
+         	mozilla_free_context_info_sub (&(info->ctx));
+		g_free (info);
+		
+		/* nothing happens, consume the event */
+		return NS_DOM_EVENT_CONSUMED;
+        }
 
-		/*
-		 * What's up with these translations?
-		 * mozilla_to_nautilus translates http://localhost:160xx -> eazel-services:///
-		 * nautilus_to_mozilla translates eazel--services -> http://localhost:160xx
-		 * 
-		 * Case 0)
-		 *  "href" is a full normal HTTP uri
-		 *  href_full is identical to href
-		 *  Both the mozilla and nautilus versions of the href are identical
-		 *  We let the navigate continue w/o interrupting
-		 *
-		 * Case 1)
-		 *  "href" is a partial URI inside a normal HTTP page
-		 *  href_full is the full version of the uri
-		 *  Like in case 0,
-		 *  Both the mozilla and nautilus versions of the href are identical
-		 *  We let the navigate continue w/o interrupting
-		 *
-		 * Case 2)
-		 *   "href" is a relative link inside an eazel-services page
-		 *   href_full is "eazel-services:///<whatever>"
-		 *   href_mozilla is "http://localhost:160xx/<whatever>"
-		 *   We let the navigate continue w/o interrupting
-		 * 
-		 * Case 3)
-		 *   "href" is a full eazel-services: URI
-		 *   href_full is "eazel-services:///<whatever>"
-		 *   href_mozilla is "http://localhost:160xx/<whatever>"
-		 *   We need to interrupt the navigate to translate.  It's the
-		 *   same case as case (2) in the if statement below
-		 *
-		 * It's not actually feasible to get an http://localhost:160xx
-		 * as href_full here, so we don't handle the case where
-		 * href_full needs to be converted to a "nautilus" URI
-		 */
+	if (info->button == 0) {
 	
-		href_full = make_full_uri_from_relative (view->details->uri, href);
-		href_mozilla = translate_uri_nautilus_to_mozilla (view, href_full);
-
-		DEBUG_MSG (("=%s href='%s' full='%s' xlate='%s'\n", __FUNCTION__, href, href_full, href_mozilla));
-
-		if (href_mozilla == NULL) {
-			/* An eazel-services URL when the user isn't logged in.
-			 * Right now, we report a load error.  But we
-			 * could tell ammonite to prompt for login
-			 */
-			DEBUG_MSG ((">nautilus_view_report_load_failed\n"));
-			nautilus_view_report_load_failed (view->details->nautilus_view);
-			ret = NS_DOM_EVENT_CONSUMED;
-		} else if (href[0] == '#') {
-			/* a navigation to an anchor within the same page */
-			view->details->user_initiated_navigation = TRUE;
-
-			/* bugzilla.mozilla.org 70311 -- anchor navigation
-			 * doesn't work on documents that have been streamed
-			 * into gtkmozembed.  So we do it outselves.
-			 */
-			if (should_mozilla_load_uri_directly (href_full)) {
-				DEBUG_MSG (("=%s : anchor navigation in normal uri, allowing navigate to continue\n", __FUNCTION__));
-				ret = NS_DOM_EVENT_IGNORED;
-			} else {
-				char *unescaped_anchor;
-
-				/* href+1 to skip the fragment identifier */
-				unescaped_anchor = gnome_vfs_unescape_string (href+1, NULL);
-
-				DEBUG_MSG (("=%s : anchor navigation in gnome-vfs uri, navigate by hand to anchor '%s'\n", __FUNCTION__, unescaped_anchor));
-
-				mozilla_navigate_to_anchor (view->details->mozilla, unescaped_anchor);
-				g_free (unescaped_anchor);
-				ret = NS_DOM_EVENT_CONSUMED;
-			}
-		} else if (0 == strncmp (href, "javascript:", strlen ("javascript:"))) {
-			/* This is a bullshit javascript uri, let it pass */
-			DEBUG_MSG (("=%s : javascript uri, allowing navigate to continue\n", __FUNCTION__));
-			ret = NS_DOM_EVENT_IGNORED;			
-		} else if (should_uri_navigate_bypass_nautilus (href_full)) {
-			view->details->user_initiated_navigation = TRUE;
-
-			if ((should_mozilla_load_uri_directly (href_full) 
-			     && 0 == strcmp (href_full, href_mozilla))
-			     || is_uri_relative (href)) {
-				/* If the URI doesn't need to be translated and we can load it directly,
-				 * then just keep going...report_location_change will happen in the
-				 * mozilla_location_callback.
-				 */
-				/* This is cases (0), (1), and (2) above */
-				DEBUG_MSG (("=%s : allowing navigate to continue\n", __FUNCTION__));
-				ret = NS_DOM_EVENT_IGNORED;
-			} else {
-				/* Otherwise, cancel the current navigation and do it ourselves */
-				/* This is case (3) above */
-				/* FIXME: form posting in this case does not work */
-				DEBUG_MSG (("=%s : handling navigate ourselves\n", __FUNCTION__));
-
-				navigate_mozilla_to_nautilus_uri (view, href_full);
-				update_nautilus_uri (view, href_full);
+		href = mozilla_events_get_href_for_event (dom_event);
 
-				ret = NS_DOM_EVENT_CONSUMED;
-			}
+		if (href != NULL) {
+			ret = handle_url (view, href);
 		} else {
-			/* With some schemes, navigation needs to be funneled through nautilus. */
-			DEBUG_MSG (("=%s : funnelling navigation through nautilus\n", __FUNCTION__));
-			DEBUG_MSG ((">nautilus_view_open_location_in_this_window '%s'", href_full));
-			nautilus_view_open_location_in_this_window (view->details->nautilus_view, href_full);
-
-			ret = NS_DOM_EVENT_CONSUMED;
+			DEBUG_MSG (("=%s no href, ignoring\n", __FUNCTION__));
 		}
-	} else {
-		DEBUG_MSG (("=%s no href, ignoring\n", __FUNCTION__));
-	}
 
-	g_free (href_mozilla);
-	g_free (href_full);
-	g_free (href);
+		g_free (href);
 
+	}
+	else if (info->button == 1) {
+		/* 
+		 * middle mouse button clicked
+		 * nothing for now 
+		 */
+	}
+
+	else if (info->button == 2) {
+		/* show context menu */
+		view->details->moz_info = &(info->ctx);
+		context_menu_show (view);
+		ret = NS_DOM_EVENT_CONSUMED;
+	}
+	
 	DEBUG_MSG (("-%s\n", __FUNCTION__));
 	
+	mozilla_free_context_info_sub (&(info->ctx));
+	g_free (info);
 	return ret;
 }
 
@@ -2006,3 +2190,4 @@
 }
 
 #endif /* HAVE_AMMONITE */
+
Index: components/mozilla/nautilus-mozilla-embed-extensions.cpp
===================================================================
RCS file: /cvs/gnome/nautilus/components/mozilla/nautilus-mozilla-embed-extensions.cpp,v
retrieving revision 1.6
diff -u -r1.6 nautilus-mozilla-embed-extensions.cpp
--- components/mozilla/nautilus-mozilla-embed-extensions.cpp	2001/02/22 12:40:40	1.6
+++ components/mozilla/nautilus-mozilla-embed-extensions.cpp	2001/05/20 14:49:02
@@ -34,11 +34,21 @@
 #include <libgnome/gnome-defs.h>
 #include <libgnome/gnome-i18n.h>
 
+/* added for mouse event stuff */
+#include "nsIDOMHTMLDocument.h"
+#include "nsIDOMNamedNodeMap.h"
+#include "nsIDOMMouseEvent.h"
+#include "nsCOMPtr.h"
+#include "nsIDOMEventReceiver.h"
+#include "nsIDocument.h"
+#include "nsIDOMHTMLInputElement.h"
+
 #include "nsIServiceManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIMarkupDocumentViewer.h"
+#include "nsIDOMMouseEvent.h"
 #include "nsICharsetConverterManager.h"
 #include "nsICharsetConverterManager2.h"
 #include <vector>
@@ -324,4 +334,235 @@
 	nsMemory::Free (ns_c_string);
 
 	return c_string;
+}
+
+/* Code taken / adapted from galeon */
+
+nsresult GetDOMAttribute (nsIDOMNode *node, const char *tag, char **attribute)
+{
+        nsresult result;
+
+        nsCOMPtr<nsIDOMNamedNodeMap> attributes;
+        result = node->GetAttributes(getter_AddRefs (attributes));
+        if (!NS_SUCCEEDED (result) || !attributes) return NS_ERROR_FAILURE;
+
+        nsAutoString attr;
+
+        attr.AssignWithConversion (tag);
+
+        nsCOMPtr<nsIDOMNode> attrNode;
+        result = attributes->GetNamedItem (attr, getter_AddRefs (attrNode));
+	if (!NS_SUCCEEDED (result) || !attrNode) return NS_ERROR_FAILURE;
+
+        nsAutoString nodeValue;
+       	result = attrNode->GetNodeValue (nodeValue);
+        if (!NS_SUCCEEDED (result)) return NS_ERROR_FAILURE;
+
+        char *cstr = nodeValue.ToNewCString();
+        *attribute = g_strdup (cstr);
+
+        nsMemory::Free (cstr);
+}
+
+void
+mozilla_free_context_info_sub (ContextInfo *ctx)
+{
+ 	g_free(ctx->linktext);
+
+	/* created by mozilla: */
+        if (ctx->link) {
+		nsMemory::Free (ctx->link);
+	}
+	
+        if (ctx->img) {
+		nsMemory::Free (ctx->img);
+	}
+}
+
+gboolean 
+mozilla_get_mouse_event_info (gpointer event, MouseEventInfo *info)
+{
+	nsresult result;
+	nsIDOMMouseEvent *aMouseEvent = (nsIDOMMouseEvent*)event;
+	
+	aMouseEvent->GetButton ((PRUint16*)&info->button);
+
+        /* be sure we are not clicking on the scroolbars */
+
+        nsCOMPtr<nsIDOMEventTarget> OriginalTarget;
+        result = aMouseEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget));        
+	if (NS_FAILED(result) || !OriginalTarget) {
+		return FALSE;
+	}
+
+        nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget);
+        if (!OriginalNode) {
+		return FALSE;
+	}
+
+        nsString nodename;
+        OriginalNode->GetNodeName(nodename);
+        if (nodename.EqualsWithConversion ("xul:thumb") || nodename.EqualsWithConversion ("xul:slider")) {
+		return FALSE;
+	}
+
+        nsCOMPtr<nsIDOMEventTarget> EventTarget;
+        result = aMouseEvent->GetTarget(getter_AddRefs(EventTarget));
+        if (NS_FAILED(result) || !EventTarget) {
+		return FALSE;
+	}
+
+	/* Get the context */
+
+	ContextInfo *ctx;
+	ctx = &(info->ctx);
+	
+ 	ctx->img = ctx->link = NULL;
+
+	nsCOMPtr<nsIDOMNode> node = do_QueryInterface(EventTarget);
+	if (!node) return NS_ERROR_FAILURE;
+
+	nsCOMPtr<nsIDOMDocument> domDoc;
+	result = node->GetOwnerDocument(getter_AddRefs(domDoc));
+	if (!NS_SUCCEEDED (result) || !domDoc) return NS_ERROR_FAILURE;
+
+	nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+	if(!doc) return NS_ERROR_FAILURE;
+
+	nsIURI *baseURI;
+	result = doc->GetBaseURL(baseURI);
+	if (NS_FAILED(result) || !baseURI) return NS_ERROR_FAILURE;
+   
+	nsString mime;  
+	doc->GetContentType(mime);  
+	if (mime.EqualsWithConversion ("text/xul"))
+		return NS_ERROR_FAILURE;
+
+	ctx->context = CONTEXT_NONE;
+	nsCOMPtr<nsIDOMHTMLElement> element;
+
+	do 
+	{
+		PRUint16 type;
+		node->GetNodeType(&type);
+
+		element = do_QueryInterface(node);
+		if (element)
+		{
+			nsAutoString tag;
+			element->GetTagName(tag);
+
+			if (tag.EqualsWithConversion("input", PR_TRUE))
+			{
+				ctx->context |= CONTEXT_INPUT;
+			}
+			else if (tag.EqualsWithConversion("img", PR_TRUE))
+			{
+				ctx->context |= CONTEXT_IMAGE;
+
+				char *src;
+				result = GetDOMAttribute (node, "src", &src);
+				
+				if (NS_FAILED(result) || !src) {
+					return FALSE;
+				}
+			
+				result = baseURI->Resolve(src, &(ctx->img));
+				g_free(src);
+				if (NS_FAILED(result) || !(ctx->img)) {
+					return FALSE;
+				}
+
+			}
+			else
+			{
+				ctx->context |= CONTEXT_OTHER;
+			}
+
+			nsCOMPtr<nsIDOMNamedNodeMap> attributes;
+			node->GetAttributes(getter_AddRefs(attributes));
+			if (attributes)
+			{
+				nsCOMPtr<nsIDOMNode> hrefNode;
+				nsAutoString href; 
+				href.AssignWithConversion("href");
+				attributes->GetNamedItem(href,
+						       getter_AddRefs(hrefNode));
+				if (hrefNode)
+				{
+					ctx->context |= CONTEXT_LINK;
+					nsAutoString linkhtml;
+#if MOZILLA_MILESTONE == 91
+					nsCOMPtr<nsIDOMNSHTMLElement> nsElement;
+
+					nsElement = do_QueryInterface (element);
+					if (nsElement)
+					{
+
+						result = nsElement->GetInnerHTML (linkhtml);
+#else
+						result = element->GetInnerHTML (linkhtml);
+#endif
+						if (NS_SUCCEEDED(result)){
+							ctx->linktext = g_strdup(linkhtml.GetBuffer());
+						}
+#if MOZILLA_MILESTONE == 91
+					}
+#endif
+					char *href;
+					result = GetDOMAttribute (node, "href", &href);
+					
+					if (NS_FAILED(result) || !href) {
+						return FALSE;
+					}
+				
+					result = baseURI->Resolve(href, &(ctx->link));
+					g_free(href);
+					if (NS_FAILED(result) || !(ctx->link)) {
+						return FALSE;
+					}
+					
+					break;
+				}
+			}
+		}
+		nsCOMPtr<nsIDOMNode> parentNode;
+		node->GetParentNode(getter_AddRefs(parentNode));
+		
+		if (!parentNode)
+		{
+			node = nsnull;
+			ctx->context |= CONTEXT_DOCUMENT;
+			break;
+		}
+		node = parentNode;
+	} while (node);
+
+        /* Get the modifier */
+
+        PRBool mod_key;
+
+        info->modifier = 0;
+
+        aMouseEvent->GetAltKey(&mod_key);
+        if (mod_key) {
+		info->modifier |= ALT_KEY;
+	}
+
+        aMouseEvent->GetShiftKey(&mod_key);
+        if (mod_key) {
+		info->modifier |= SHIFT_KEY;
+	}
+
+        aMouseEvent->GetMetaKey(&mod_key);
+        if (mod_key) {
+		info->modifier |= META_KEY;
+	}
+
+        aMouseEvent->GetCtrlKey(&mod_key);
+        if (mod_key) {
+		info->modifier |= CTRL_KEY;
+	}
+
+	return TRUE;
 }
Index: components/mozilla/nautilus-mozilla-embed-extensions.h
===================================================================
RCS file: /cvs/gnome/nautilus/components/mozilla/nautilus-mozilla-embed-extensions.h,v
retrieving revision 1.2
diff -u -r1.2 nautilus-mozilla-embed-extensions.h
--- components/mozilla/nautilus-mozilla-embed-extensions.h	2001/02/22 12:40:40	1.2
+++ components/mozilla/nautilus-mozilla-embed-extensions.h	2001/05/20 14:49:02
@@ -35,6 +35,48 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* Code copied from galeon */
+
+typedef struct
+{
+       	gchar *img;
+        gchar *link;
+       	gchar *linktext;
+       	gint context;
+} ContextInfo;
+
+typedef struct
+{
+        ContextInfo ctx;
+        gint button;
+        gint modifier;
+} MouseEventInfo;
+
+typedef enum
+{
+	ALT_KEY   = (1 << 0),
+	CTRL_KEY  = (1 << 1),
+	SHIFT_KEY = (1 << 2),
+	META_KEY  = (1 << 3),
+	KEY_CODE  = (1 << 4)
+} KeyModifier;
+
+typedef enum
+{
+	CONTEXT_NONE     = 0,
+	CONTEXT_DEFAULT  = (1 << 1),
+	CONTEXT_LINK     = (1 << 2),
+	CONTEXT_IMAGE    = (1 << 3),
+	CONTEXT_DOCUMENT = (1 << 4),
+	CONTEXT_INPUT    = (1 << 5),
+	CONTEXT_OTHER    = (1 << 6),
+	CONTEXT_XUL      = (1 << 7),
+} ContextMenuType;
+
+void mozilla_free_context_info_sub (ContextInfo *ctx);
+gboolean mozilla_get_mouse_event_info (gpointer event,
+                                              MouseEventInfo *info);
+
 gboolean mozilla_charset_set_encoding                      (GtkMozEmbed       *mozilla_embed,
 							    const char        *encoding);
 guint    mozilla_charset_get_num_encodings                 (const GtkMozEmbed *mozilla_embed);


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