Allow to active form fields via hinting.
authorDaniel Carl <danielcarl@gmx.de>
Wed, 19 Dec 2012 14:04:20 +0000 (15:04 +0100)
committerDaniel Carl <danielcarl@gmx.de>
Wed, 19 Dec 2012 14:04:20 +0000 (15:04 +0100)
src/dom.c
src/dom.h
src/hints.c

index 71ad4a6..b4e2a84 100644 (file)
--- 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;
index ce41bc0..74a5571 100644 (file)
--- 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 */
index 9789141..db65d9e 100644 (file)
@@ -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;