From 71bee0c5de91ec6fcbef84dfcb0d96bdfb89dfb1 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Mon, 27 Apr 2015 23:39:11 +0200 Subject: [PATCH] Allow to focus editable element in iframes (#201). This allows to use gi normal mode command to focus also editable element within iframes in case the current document contains no editable element. --- src/dom.c | 35 +++++++++++++++++++++++++++-------- src/dom.h | 2 +- src/normal.c | 2 +- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/dom.c b/src/dom.c index f2c5cb5..0e9e3c6 100644 --- a/src/dom.c +++ b/src/dom.c @@ -80,27 +80,30 @@ void dom_clear_focus(WebKitWebView *view) /** * Find the first editable element and set the focus on it and enter input * mode. + * Returns true if there was an editable element focused. */ -void dom_focus_input(WebKitWebView *view) +gboolean dom_focus_input(Document *doc) { WebKitDOMNode *html, *node; - WebKitDOMDocument *doc; WebKitDOMDOMWindow *win; WebKitDOMNodeList *list; WebKitDOMXPathNSResolver *resolver; WebKitDOMXPathResult* result; + Document *frame_doc; + guint i, len; - doc = webkit_web_view_get_dom_document(view); win = webkit_dom_document_get_default_view(doc); list = webkit_dom_document_get_elements_by_tag_name(doc, "html"); if (!list) { - return; + return false; } - html = webkit_dom_node_list_item(list, 0); + html = webkit_dom_node_list_item(list, 0); + g_object_unref(list); + resolver = webkit_dom_document_create_ns_resolver(doc, html); if (!resolver) { - return; + return false; } /* Use translate to match xpath expression case insensitive so that also @@ -125,16 +128,32 @@ void dom_focus_input(WebKitWebView *view) html, resolver, 5, NULL, NULL ); if (!result) { - return; + return false; } while ((node = webkit_dom_xpath_result_iterate_next(result, NULL))) { if (element_is_visible(win, WEBKIT_DOM_ELEMENT(node))) { vb_enter('i'); webkit_dom_element_focus(WEBKIT_DOM_ELEMENT(node)); - break; + return true; + } + } + + /* Look for editable elements in frames too. */ + list = webkit_dom_document_get_elements_by_tag_name(doc, "iframe"); + len = webkit_dom_node_list_get_length(list); + + for (i = 0; i < len; i++) { + node = webkit_dom_node_list_item(list, i); + frame_doc = webkit_dom_html_iframe_element_get_content_document(WEBKIT_DOM_HTML_IFRAME_ELEMENT(node)); + /* Stop on first frame with focused element. */ + if (dom_focus_input(frame_doc)) { + g_object_unref(list); + return true; } } g_object_unref(list); + + return false; } /** diff --git a/src/dom.h b/src/dom.h index a78b362..d2bb3b9 100644 --- a/src/dom.h +++ b/src/dom.h @@ -34,7 +34,7 @@ void dom_check_auto_insert(Document *doc); void dom_clear_focus(WebKitWebView *view); -void dom_focus_input(WebKitWebView *view); +gboolean dom_focus_input(Document *doc); gboolean dom_is_editable(Element *element); Element *dom_get_active_element(WebKitWebView *view); const char *dom_editable_element_get_value(Element *element); diff --git a/src/normal.c b/src/normal.c index abbf20b..f1f1be8 100644 --- a/src/normal.c +++ b/src/normal.c @@ -413,7 +413,7 @@ static VbResult normal_ex(const NormalCmdInfo *info) static VbResult normal_focus_input(const NormalCmdInfo *info) { - dom_focus_input(vb.gui.webview); + dom_focus_input(webkit_web_view_get_dom_document(vb.gui.webview)); return RESULT_COMPLETE; } -- 2.20.1