From df6ddbad9e73a8dc53b67de52a7d899e81814f21 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Wed, 19 Dec 2012 15:04:20 +0100 Subject: [PATCH] Allow to active form fields via hinting. --- src/dom.c | 53 +++++++++++++++++++++++++++-------------------------- src/dom.h | 1 + src/hints.c | 35 ++++++++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/dom.c b/src/dom.c index 71ad4a6..b4e2a84 100644 --- a/src/dom.c +++ b/src/dom.c @@ -22,8 +22,7 @@ static gboolean dom_auto_insert(Element* element); static gboolean dom_editable_focus_cb(Element* element, Event* event); -static gboolean dom_is_editable(Element* element); -static WebKitDOMElement* dom_get_active_element(Document* doc); +static Element* dom_get_active_element(Document* doc); void dom_check_auto_insert(void) @@ -102,7 +101,7 @@ void dom_dispatch_mouse_event(Document* doc, Element* element, gchar* type, gush TRUE, TRUE, webkit_dom_document_get_default_view(doc), - 1, 0, 0, 0, 0, + 1, 1, 1, 0, 0, FALSE, FALSE, FALSE, FALSE, button, WEBKIT_DOM_EVENT_TARGET(element) @@ -111,6 +110,31 @@ void dom_dispatch_mouse_event(Document* doc, Element* element, gchar* type, gush webkit_dom_node_dispatch_event(WEBKIT_DOM_NODE(element), event, NULL); } +/** + * Indicates if the given dom element is an editable element like text input, + * password or textarea. + */ +gboolean dom_is_editable(Element* element) +{ + if (!element) { + return FALSE; + } + + gchar* tagname = webkit_dom_element_get_tag_name(element); + if (!g_ascii_strcasecmp(tagname, "textarea")) { + return TRUE; + } + gchar *type = webkit_dom_element_get_attribute(element, "type"); + if (!g_ascii_strcasecmp(tagname, "input") + || !g_ascii_strcasecmp(type, "text") + || !g_ascii_strcasecmp(type, "password") + ) { + return TRUE; + } + return FALSE; +} + + static gboolean dom_auto_insert(Element* element) { if (dom_is_editable(element)) { @@ -132,29 +156,6 @@ static gboolean dom_editable_focus_cb(Element* element, Event* event) return FALSE; } -/** - * Indicates if the given dom element is an editable element like text input, - * password or textarea. - */ -static gboolean dom_is_editable(WebKitDOMElement* element) -{ - if (!element) { - return FALSE; - } - - gchar* tagname = webkit_dom_node_get_node_name(WEBKIT_DOM_NODE(element)); - if (!g_strcmp0(tagname, "TEXTAREA")) { - return TRUE; - } - if (!g_strcmp0(tagname, "INPUT")) { - gchar *type = webkit_dom_element_get_attribute((void*)element, "type"); - if (!g_strcmp0(type, "text") || !g_strcmp0(type, "password")) { - return TRUE; - } - } - return FALSE; -} - static Element* dom_get_active_element(Document* doc) { Document* d = NULL; diff --git a/src/dom.h b/src/dom.h index ce41bc0..74a5571 100644 --- a/src/dom.h +++ b/src/dom.h @@ -52,5 +52,6 @@ void dom_element_style_set_property(Element* element, const gchar* property, con gboolean dom_element_is_visible(Window* win, Element* element); DomBoundingRect dom_elemen_get_bounding_rect(Element* element); void dom_dispatch_mouse_event(Document* doc, Element* element, gchar* type, gushort button); +gboolean dom_is_editable(Element* element); #endif /* end of include guard: DOM_H */ diff --git a/src/hints.c b/src/hints.c index 9789141..db65d9e 100644 --- a/src/hints.c +++ b/src/hints.c @@ -307,7 +307,6 @@ static void hints_focus(const gulong num) dom_element_style_set_property(hint->elem, "background-color", ELEM_BACKGROUND_FOCUS); dom_dispatch_mouse_event(doc, hint->elem, "mouseover", 0); - webkit_dom_element_focus(hint->elem); } currentFocusNum = num; @@ -321,10 +320,22 @@ static void hints_fire(const gulong num) * if the elemt has a target attribute - remove it temporary * fire mousedown and click events on the element * if it is an form element focus it and return */ - Document* doc = webkit_web_view_get_dom_document(vp.gui.webview); - dom_dispatch_mouse_event(doc, hint->elem, "click", 0); + + if (dom_is_editable(hint->elem)) { + webkit_dom_element_focus(hint->elem); + vp_set_mode(VP_MODE_INSERT, FALSE); + } else { + /* remove possible target attribute */ + gchar* type = webkit_dom_element_get_attribute(hint->elem, "target"); + if (g_strcmp0(type, "_blank") == 0) { + webkit_dom_element_remove_attribute(hint->elem, "target"); + } + Document* doc = webkit_web_view_get_dom_document(vp.gui.webview); + dom_dispatch_mouse_event(doc, hint->elem, "click", 0); + /* remove the hint filter input */ + vp_clean_input(); + } hints_clear(); - vp_clean_input(); } } @@ -368,13 +379,23 @@ static gchar* hints_get_xpath(const gchar* input) if (input == NULL) { xpath = g_strdup( "//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @ role='link'] | " - "//a[@href]" + "//a[@href] | " + "//input[not(@type='hidden')] | " + "//textarea | " + "//button | " + "//select | " + "//area" ); } else { xpath = g_strdup_printf( "//*[(@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link') and contains(., '%s')] | " - "//a[@href and contains(., '%s')]", - input, input + "//a[@href and contains(., '%s')] | " + "//input[not(@type='hidden') and contains(., '%s')] | " + "//textarea[contains(., '%s')] | " + "//button[contains(@value, '%s')] | " + "//select[contains(., '%s')] | " + "//area[contains(., '%s')]", + input, input, input, input, input, input, input ); } break; -- 2.20.1