aboutsummaryrefslogtreecommitdiffstats
path: root/embed
diff options
context:
space:
mode:
Diffstat (limited to 'embed')
-rw-r--r--embed/ephy-embed-find.c15
-rw-r--r--embed/ephy-embed-find.h6
-rw-r--r--embed/mozilla/EphyFind.cpp86
-rw-r--r--embed/mozilla/EphyFind.h5
-rw-r--r--embed/mozilla/mozilla-embed-find.cpp11
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