diff options
Diffstat (limited to 'src/webextension')
-rw-r--r-- | src/webextension/ext-main.c | 70 |
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) |