diff options
Diffstat (limited to 'embed')
-rw-r--r-- | embed/ephy-embed-find.c | 15 | ||||
-rw-r--r-- | embed/ephy-embed-find.h | 6 | ||||
-rw-r--r-- | embed/mozilla/EphyFind.cpp | 86 | ||||
-rw-r--r-- | embed/mozilla/EphyFind.h | 5 | ||||
-rw-r--r-- | embed/mozilla/mozilla-embed-find.cpp | 11 |
5 files changed, 118 insertions, 5 deletions
diff --git a/embed/ephy-embed-find.c b/embed/ephy-embed-find.c index 596c0b8bc..f5ddb664e 100644 --- a/embed/ephy-embed-find.c +++ b/embed/ephy-embed-find.c @@ -70,6 +70,21 @@ ephy_embed_find_find_again (EphyEmbedFind *find, return iface->find_again (find, forward); } +/** + * ephy_embed_find_activate_link: + * @embed: an #EphyEmbedFind + * @mask: + * + * Activates the currently focused link, if there is any. + **/ +gboolean +ephy_embed_find_activate_link (EphyEmbedFind *find, + GdkModifierType mask) +{ + EphyEmbedFindIface *iface = EPHY_EMBED_FIND_GET_IFACE (find); + return iface->activate_link (find, mask); +} + GType ephy_embed_find_get_type (void) { diff --git a/embed/ephy-embed-find.h b/embed/ephy-embed-find.h index 6dbabe7db..a601c9a4e 100644 --- a/embed/ephy-embed-find.h +++ b/embed/ephy-embed-find.h @@ -25,6 +25,7 @@ #include <glib.h> #include "ephy-embed.h" +#include <gdk/gdktypes.h> G_BEGIN_DECLS @@ -54,6 +55,8 @@ struct _EphyEmbedFindIface gboolean links_only); gboolean (* find_again) (EphyEmbedFind *find, gboolean forward); + gboolean (* activate_link) (EphyEmbedFind *find, + GdkModifierType mask); }; GType ephy_embed_find_get_type (void); @@ -72,6 +75,9 @@ gboolean ephy_embed_find_find (EphyEmbedFind *find, gboolean ephy_embed_find_find_again (EphyEmbedFind *find, gboolean forward); +gboolean ephy_embed_find_activate_link (EphyEmbedFind *find, + GdkModifierType mask); + G_END_DECLS #endif diff --git a/embed/mozilla/EphyFind.cpp b/embed/mozilla/EphyFind.cpp index ace176b23..224e85081 100644 --- a/embed/mozilla/EphyFind.cpp +++ b/embed/mozilla/EphyFind.cpp @@ -37,6 +37,17 @@ #include <nsIInterfaceRequestorUtils.h> #include <nsIDOMWindow.h> #include <nsIWebBrowser.h> +#include <nsIWebBrowserFocus.h> +#include <nsIDOMNode.h> +#include <nsIDOMElement.h> +#include <nsIDOMDocument.h> +#include <nsIDOMDocumentView.h> +#include <nsIDOMAbstractView.h> +#include <nsIDOMDocumentEvent.h> +#include <nsIDOMEvent.h> +#include <nsIDOMKeyEvent.h> +#include <nsIDOMEventTarget.h> +#include <nsIDOMHTMLAnchorElement.h> #ifdef HAVE_TYPEAHEADFIND #include <nsIDocShell.h> @@ -52,6 +63,9 @@ #define NS_TYPEAHEADFIND_CONTRACTID "@mozilla.org/typeaheadfind;1" #endif /* HAVE_TYPEAHEADFIND */ +static const PRUnichar kKeyEvents[] = { 'K', 'e', 'y', 'E', 'v', 'e', 'n', 't', 's', '\0' }; +static const PRUnichar kKeyPress[] = { 'k', 'e', 'y', 'p', 'r', 'e', 's', 's', '\0' }; + EphyFind::EphyFind () : mCurrentEmbed(nsnull) { @@ -70,15 +84,15 @@ EphyFind::SetEmbed (EphyEmbed *aEmbed) if (aEmbed == mCurrentEmbed) return rv; mCurrentEmbed = nsnull; + mWebBrowser = nsnull; rv = NS_ERROR_FAILURE; - nsCOMPtr<nsIWebBrowser> webBrowser; gtk_moz_embed_get_nsIWebBrowser (GTK_MOZ_EMBED (aEmbed), - getter_AddRefs (webBrowser)); - NS_ENSURE_TRUE (webBrowser, rv); + getter_AddRefs (mWebBrowser)); + NS_ENSURE_TRUE (mWebBrowser, rv); #ifdef HAVE_TYPEAHEADFIND - nsCOMPtr<nsIDocShell> docShell (do_GetInterface (webBrowser, &rv)); + nsCOMPtr<nsIDocShell> docShell (do_GetInterface (mWebBrowser, &rv)); NS_ENSURE_SUCCESS (rv, rv); if (!mFinder) { @@ -97,7 +111,7 @@ EphyFind::SetEmbed (EphyEmbed *aEmbed) mFinder->GetSearchString (&string); } - mFinder = do_GetInterface (webBrowser, &rv); + mFinder = do_GetInterface (mWebBrowser, &rv); NS_ENSURE_SUCCESS (rv, rv); mFinder->SetWrapFind (PR_TRUE); @@ -186,3 +200,65 @@ EphyFind::FindAgain (PRBool aForward) return NS_SUCCEEDED (rv) && didFind; #endif /* HAVE_TYPEAHEADFIND */ } + +PRBool +EphyFind::ActivateLink (GdkModifierType aMask) +{ + nsresult rv; + nsCOMPtr<nsIDOMElement> link; +#if defined(HAVE_TYPEAHEADFIND) && defined(HAVE_GECKO_1_8) + rv = mFinder->GetFoundLink (getter_AddRefs (link)); + NS_ENSURE_TRUE (NS_SUCCEEDED (rv) && link, FALSE); +#else + nsCOMPtr<nsIWebBrowserFocus> focus (do_QueryInterface (mWebBrowser)); + NS_ENSURE_TRUE (focus, FALSE); + + rv = focus->GetFocusedElement (getter_AddRefs (link)); + NS_ENSURE_TRUE (NS_SUCCEEDED (rv) && link, FALSE); + + /* ensure this is really a link so we don't accidentally submit if we're on a button or so! */ + nsCOMPtr<nsIDOMHTMLAnchorElement> anchor (do_QueryInterface (link)); + if (!anchor) return FALSE; +#endif /* HAVE_TYPEAHEADFIND && HAVE_GECKO_1_8 */ + + nsCOMPtr<nsIDOMDocument> doc; + rv = link->GetOwnerDocument (getter_AddRefs (doc)); + NS_ENSURE_TRUE (doc, FALSE); + + nsCOMPtr<nsIDOMDocumentView> docView (do_QueryInterface (doc)); + NS_ENSURE_TRUE (docView, FALSE); + + nsCOMPtr<nsIDOMAbstractView> abstractView; + docView->GetDefaultView (getter_AddRefs (abstractView)); + NS_ENSURE_TRUE (abstractView, FALSE); + + nsCOMPtr<nsIDOMDocumentEvent> docEvent (do_QueryInterface (doc)); + NS_ENSURE_TRUE (docEvent, FALSE); + + nsCOMPtr<nsIDOMEvent> event; + rv = docEvent->CreateEvent (nsEmbedString(kKeyEvents), getter_AddRefs (event)); + NS_ENSURE_SUCCESS (rv, FALSE); + + nsCOMPtr<nsIDOMKeyEvent> keyEvent (do_QueryInterface (event)); + NS_ENSURE_TRUE (keyEvent, FALSE); + + rv = keyEvent->InitKeyEvent (nsEmbedString (kKeyPress), + PR_TRUE /* bubble */, + PR_TRUE /* cancelable */, + abstractView, + (aMask & GDK_CONTROL_MASK) != 0, + (aMask & GDK_MOD1_MASK) != 0 /* Alt */, + (aMask & GDK_SHIFT_MASK) != 0, + PR_FALSE /* Meta */, + nsIDOMKeyEvent::DOM_VK_RETURN, + 0); + NS_ENSURE_SUCCESS (rv, FALSE); + + nsCOMPtr<nsIDOMEventTarget> target (do_QueryInterface (link)); + NS_ENSURE_TRUE (target, FALSE); + + PRBool defaultPrevented = PR_FALSE; + rv = target->DispatchEvent (event, &defaultPrevented); + + return NS_SUCCEEDED (rv); +} diff --git a/embed/mozilla/EphyFind.h b/embed/mozilla/EphyFind.h index 7188ffb74..8e85356cb 100644 --- a/embed/mozilla/EphyFind.h +++ b/embed/mozilla/EphyFind.h @@ -24,8 +24,10 @@ #include "ephy-embed.h" #include <nsCOMPtr.h> +#include <gdk/gdktypes.h> class nsITypeAheadFind; +class nsIWebBrowser; class nsIWebBrowserFind; class EphyFind @@ -41,10 +43,13 @@ class EphyFind PRBool Find (const char *aSearchString, PRBool aLinksOnly); PRBool FindAgain (PRBool aForward); + PRBool ActivateLink (GdkModifierType aMask); private: EphyEmbed *mCurrentEmbed; + nsCOMPtr<nsIWebBrowser> mWebBrowser; + #ifdef HAVE_TYPEAHEADFIND nsCOMPtr<nsITypeAheadFind> mFinder; #else diff --git a/embed/mozilla/mozilla-embed-find.cpp b/embed/mozilla/mozilla-embed-find.cpp index d039b4d69..f8f4e6c60 100644 --- a/embed/mozilla/mozilla-embed-find.cpp +++ b/embed/mozilla/mozilla-embed-find.cpp @@ -83,6 +83,16 @@ impl_find_again (EphyEmbedFind *efind, return priv->find->FindAgain (forward); } +static gboolean +impl_activate_link (EphyEmbedFind *efind, + GdkModifierType mask) +{ + MozillaEmbedFind *find = MOZILLA_EMBED_FIND (efind); + MozillaEmbedFindPrivate *priv = find->priv; + + return priv->find->ActivateLink (mask); +} + static void ephy_find_iface_init (EphyEmbedFindIface *iface) { @@ -90,6 +100,7 @@ ephy_find_iface_init (EphyEmbedFindIface *iface) iface->set_properties = impl_set_properties; iface->find = impl_find; iface->find_again = impl_find_again; + iface->activate_link = impl_activate_link; } static void |