summaryrefslogtreecommitdiff
path: root/src/webextension
diff options
context:
space:
mode:
Diffstat (limited to 'src/webextension')
-rw-r--r--src/webextension/ext-main.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/src/webextension/ext-main.c b/src/webextension/ext-main.c
index 97e4261..3abf4bf 100644
--- a/src/webextension/ext-main.c
+++ b/src/webextension/ext-main.c
@@ -43,6 +43,8 @@ static void dbus_emit_signal(const char *name, WebKitWebExtension* extension,
static void dbus_handle_method_call(GDBusConnection *conn, const char *sender,
const char *object_path, const char *interface_name, const char *method,
GVariant *parameters, GDBusMethodInvocation *invocation, gpointer data);
+static void on_editable_change_focus(WebKitDOMEventTarget *target,
+ WebKitDOMEvent *event, WebKitWebExtension *extension);
static void on_page_created(WebKitWebExtension *ext, WebKitWebPage *webpage, gpointer data);
static void on_web_page_document_loaded(WebKitWebPage *webpage, gpointer extension);
static gboolean on_web_page_send_request(WebKitWebPage *webpage, WebKitURIRequest *request,
@@ -177,7 +179,6 @@ static void on_dbus_connection_created(GObject *source_object,
static void add_onload_event_observers(WebKitDOMDocument *doc,
WebKitWebExtension *extension)
{
-#if 0 /* might soon be use for some events */
WebKitDOMEventTarget *target;
/* Add the document to the table of known documents or if already exists
@@ -190,7 +191,15 @@ static void add_onload_event_observers(WebKitDOMDocument *doc,
* function is called with content document of an iframe. Else the event
* observing does not work. */
target = WEBKIT_DOM_EVENT_TARGET(webkit_dom_document_get_default_view(doc));
-#endif
+
+ webkit_dom_event_target_add_event_listener(target, "focus",
+ G_CALLBACK(on_editable_change_focus), TRUE, extension);
+ webkit_dom_event_target_add_event_listener(target, "blur",
+ G_CALLBACK(on_editable_change_focus), TRUE, extension);
+ /* Check for focused editable elements also if they where focused before
+ * the event observer where set up. */
+ /* TODO this is not needed for strict-focus=on */
+ on_editable_change_focus(target, NULL, extension);
}
/**
@@ -297,6 +306,63 @@ static void dbus_handle_method_call(GDBusConnection *conn, const char *sender,
}
/**
+ * Callback called if a editable element changes it focus state.
+ * Event target may be a WebKitDOMDocument (in case of iframe) or a
+ * WebKitDOMDOMWindow.
+ */
+static void on_editable_change_focus(WebKitDOMEventTarget *target,
+ WebKitDOMEvent *event, WebKitWebExtension *extension)
+{
+ gboolean input_focus;
+ WebKitDOMDocument *doc;
+ WebKitDOMDOMWindow *dom_window;
+ WebKitDOMElement *active;
+
+ if (WEBKIT_DOM_IS_DOM_WINDOW(target)) {
+ g_object_get(target, "document", &doc, NULL);
+ } else {
+ /* target is a doc document */
+ doc = WEBKIT_DOM_DOCUMENT(target);
+ }
+
+ dom_window = webkit_dom_document_get_default_view(doc);
+ if (!dom_window) {
+ return;
+ }
+
+ active = webkit_dom_document_get_active_element(doc);
+ /* Don't do anything if there is no active element or the active element
+ * is the same as before. */
+ if (!active || active == ext.active) {
+ return;
+ }
+ if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT(active)) {
+ WebKitDOMHTMLIFrameElement *iframe;
+ WebKitDOMDocument *subdoc;
+
+ iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT(active);
+ subdoc = webkit_dom_html_iframe_element_get_content_document(iframe);
+ add_onload_event_observers(subdoc, extension);
+ return;
+ }
+
+ ext.active = active;
+
+ /* Check if the active element is an editable element. */
+ input_focus = ext_dom_is_editable(active);
+ if (input_focus != ext.input_focus) {
+ ext.input_focus = input_focus;
+
+ webkit_dom_document_get_default_view(doc);
+ if (!webkit_dom_dom_window_webkit_message_handlers_post_message(dom_window, "focus", input_focus ? "1" : "0")) {
+ g_warning("Error sending focus message");
+ return;
+ }
+ }
+ g_object_unref(dom_window);
+}
+
+/**
* Callback for web extensions page-created signal.
*/
static void on_page_created(WebKitWebExtension *extension, WebKitWebPage *webpage, gpointer data)