From a58e134dcb9e820476a6ce0924002447ca0f8cc2 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sun, 26 Apr 2015 23:30:36 +0200 Subject: [PATCH] Check for dom focus/blur event on window object cleared (#201). This allows us to track also focus changes within frames and iframes also if they are loaded dynamically. The previous logic added the event listeners to the document on WEBKIT_LOAD_FINISHED, but if there where later created iframes in the dom, these where not observers for focus events. This is only a first attempt to fix the focus issue and does break the logic behind `set strict-focus=on`. --- src/dom.c | 45 ++++++++++--------- src/dom.h | 2 +- src/main.c | 11 ++++- .../manual/201-editable-focus-in-iframes.html | 9 ++++ 4 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 tests/manual/201-editable-focus-in-iframes.html diff --git a/src/dom.c b/src/dom.c index a151d6b..75457d5 100644 --- a/src/dom.c +++ b/src/dom.c @@ -30,37 +30,40 @@ static gboolean editable_focus_cb(Element *element, Event *event); static Element *get_active_element(Document *doc); -void dom_check_auto_insert(WebKitWebView *view) +void dom_check_auto_insert(Document *doc) { Element *active; HtmlElement *element; - Document *doc = webkit_web_view_get_dom_document(view); - /* FIrst check for current active element that bocomes focused before we + /* First check for current active element that becomes focused before we * could add the evnet observers. */ - active = get_active_element(doc); - if (!vb.config.strict_focus) { - auto_insert(active); - } else if (vb.mode->id != 'i') { - /* If strict-focus is enabled and the editable element becomes focus, - * we explicitely remove the focus. But only if vim isn't in input - * mode at the time. This prevents from leaving input mode that was - * started by user interaction like click to editable element, or the - * gi normal mode command. */ - webkit_dom_element_blur(active); + active = webkit_dom_html_document_get_active_element(WEBKIT_DOM_HTML_DOCUMENT(doc)); + if (active) { + if (!vb.config.strict_focus) { + auto_insert(active); + } else if (vb.mode->id != 'i') { + /* If strict-focus is enabled and the editable element becomes + * focus, we explicitely remove the focus. But only if vim isn't + * in input mode at the time. This prevents from leaving input + * mode that was started by user interaction like click to + * editable element, or the gi normal mode command. */ + webkit_dom_element_blur(active); + } } element = webkit_dom_document_get_body(doc); if (!element) { element = WEBKIT_DOM_HTML_ELEMENT(webkit_dom_document_get_document_element(doc)); } - /* add event listener to track focus and blur events on the document */ - webkit_dom_event_target_add_event_listener( - WEBKIT_DOM_EVENT_TARGET(element), "blur", G_CALLBACK(editable_blur_cb), true, NULL - ); - webkit_dom_event_target_add_event_listener( - WEBKIT_DOM_EVENT_TARGET(element), "focus", G_CALLBACK(editable_focus_cb), true, NULL - ); + if (element) { + /* add event listener to track focus and blur events on the document */ + webkit_dom_event_target_add_event_listener( + WEBKIT_DOM_EVENT_TARGET(element), "blur", G_CALLBACK(editable_blur_cb), true, NULL + ); + webkit_dom_event_target_add_event_listener( + WEBKIT_DOM_EVENT_TARGET(element), "focus", G_CALLBACK(editable_focus_cb), true, NULL + ); + } } /** @@ -251,6 +254,7 @@ static gboolean auto_insert(Element *element) static gboolean editable_blur_cb(Element *element, Event *event) { + g_message("blur"); if (vb.mode->id == 'i') { vb_enter('n'); } @@ -259,6 +263,7 @@ static gboolean editable_blur_cb(Element *element, Event *event) static gboolean editable_focus_cb(Element *element, Event *event) { + g_message("focus"); auto_insert((Element*)webkit_dom_event_get_target(event)); return false; diff --git a/src/dom.h b/src/dom.h index 2c82281..a78b362 100644 --- a/src/dom.h +++ b/src/dom.h @@ -32,7 +32,7 @@ #define HtmlInputElement WebKitDOMHTMLInputElement #define HtmlTextareaElement WebKitDOMHTMLTextAreaElement -void dom_check_auto_insert(WebKitWebView *view); +void dom_check_auto_insert(Document *doc); void dom_clear_focus(WebKitWebView *view); void dom_focus_input(WebKitWebView *view); gboolean dom_is_editable(Element *element); diff --git a/src/main.c b/src/main.c index 5b2d701..ba14735 100644 --- a/src/main.c +++ b/src/main.c @@ -87,6 +87,8 @@ static gboolean navigation_decision_requested_cb(WebKitWebView *view, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *action, WebKitWebPolicyDecision *policy, gpointer data); +static void window_object_cleared_cb(GtkWidget *widget, WebKitWebFrame *frame, + JSContextRef js, JSObjectRef win, gpointer user_data); static void hover_link_cb(WebKitWebView *webview, const char *title, const char *link); static void title_changed_cb(WebKitWebView *webview, WebKitWebFrame *frame, const char *title); static gboolean mimetype_decision_cb(WebKitWebView *webview, @@ -776,7 +778,6 @@ static void webview_load_status_cb(WebKitWebView *view, GParamSpec *pspec) update_title(); if (strncmp(uri, "about:", 6)) { - dom_check_auto_insert(view); history_add(HISTORY_URL, uri, webkit_web_view_get_title(view)); } break; @@ -1131,6 +1132,7 @@ static void setup_signals() "signal::should-show-delete-interface-for-element", G_CALLBACK(gtk_false), NULL, "signal::resource-request-starting", G_CALLBACK(webview_request_starting_cb), NULL, "signal::navigation-policy-decision-requested", G_CALLBACK(navigation_decision_requested_cb), NULL, + "signal::window-object-cleared", G_CALLBACK(window_object_cleared_cb), NULL, NULL ); @@ -1408,6 +1410,13 @@ static gboolean navigation_decision_requested_cb(WebKitWebView *view, return false; } +static void window_object_cleared_cb(GtkWidget *widget, WebKitWebFrame *frame, + JSContextRef js, JSObjectRef win, gpointer user_data) +{ + Document *doc = webkit_web_frame_get_dom_document(frame); + dom_check_auto_insert(doc); +} + static void hover_link_cb(WebKitWebView *webview, const char *title, const char *link) { char *message; diff --git a/tests/manual/201-editable-focus-in-iframes.html b/tests/manual/201-editable-focus-in-iframes.html new file mode 100644 index 0000000..d02c0fb --- /dev/null +++ b/tests/manual/201-editable-focus-in-iframes.html @@ -0,0 +1,9 @@ + + +Track Focu/Blur also within iFrames + + + + + + -- 2.20.1