Added logic to process hinted elements.
authorDaniel Carl <danielcarl@gmx.de>
Fri, 21 Dec 2012 14:09:14 +0000 (15:09 +0100)
committerDaniel Carl <danielcarl@gmx.de>
Fri, 21 Dec 2012 23:05:31 +0000 (00:05 +0100)
Added commend to write hinted link url to the inputbar.

doc/config
src/command.c
src/dom.c
src/dom.h
src/hints.c
src/hints.h

index 27fe492..cc4e2b3 100644 (file)
@@ -25,6 +25,8 @@ nmap k scrollup
 nmap j scrolldown
 nmap f hint-link
 nmap F hint-link-new
+nmap go hint-input-open
+nmap gt hint-input-tabopen
 cmap <tab> complete
 cmap <shift-tab> complete-back
 hmap <tab> hint-focus-next
index 6242fe8..e1b6342 100644 (file)
 #include "hints.h"
 
 static CommandInfo cmd_list[] = {
-    /* command              function             arg                                                                           mode */
-    {"open",                command_open,        {VP_TARGET_CURRENT, ""},                                                      VP_MODE_NORMAL},
-    {"tabopen",             command_open,        {VP_TARGET_NEW, ""},                                                          VP_MODE_NORMAL},
-    {"input",               command_input,       {0, ":"},                                                                     VP_MODE_COMMAND},
-    {"inputopen",           command_input,       {0, ":open "},                                                                VP_MODE_COMMAND},
-    {"inputtabopen",        command_input,       {0, ":tabopen "},                                                             VP_MODE_COMMAND},
-    {"inputopencurrent",    command_input,       {VP_INPUT_CURRENT_URI, ":open "},                                             VP_MODE_COMMAND},
-    {"inputtabopencurrent", command_input,       {VP_INPUT_CURRENT_URI, ":tabopen "},                                          VP_MODE_COMMAND},
-    {"quit",                command_close,       {0},                                                                          VP_MODE_NORMAL},
-    {"source",              command_view_source, {0},                                                                          VP_MODE_NORMAL},
-    {"back",                command_navigate,    {VP_NAVIG_BACK},                                                              VP_MODE_NORMAL},
-    {"forward",             command_navigate,    {VP_NAVIG_FORWARD},                                                           VP_MODE_NORMAL},
-    {"reload",              command_navigate,    {VP_NAVIG_RELOAD},                                                            VP_MODE_NORMAL},
-    {"reload!",             command_navigate,    {VP_NAVIG_RELOAD_FORCE},                                                      VP_MODE_NORMAL},
-    {"stop",                command_navigate,    {VP_NAVIG_STOP_LOADING},                                                      VP_MODE_NORMAL},
-    {"jumpleft",            command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_LEFT},                             VP_MODE_NORMAL},
-    {"jumpright",           command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_RIGHT},                            VP_MODE_NORMAL},
-    {"jumptop",             command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_TOP},                              VP_MODE_NORMAL},
-    {"jumpbottom",          command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_DOWN},                             VP_MODE_NORMAL},
-    {"pageup",              command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_TOP | VP_SCROLL_UNIT_PAGE},      VP_MODE_NORMAL},
-    {"pagedown",            command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_DOWN | VP_SCROLL_UNIT_PAGE},     VP_MODE_NORMAL},
-    {"halfpageup",          command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_TOP | VP_SCROLL_UNIT_HALFPAGE},  VP_MODE_NORMAL},
-    {"halfpagedown",        command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_DOWN | VP_SCROLL_UNIT_HALFPAGE}, VP_MODE_NORMAL},
-    {"scrollleft",          command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_LEFT | VP_SCROLL_UNIT_LINE},     VP_MODE_NORMAL},
-    {"scrollright",         command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_RIGHT | VP_SCROLL_UNIT_LINE},    VP_MODE_NORMAL},
-    {"scrollup",            command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_TOP | VP_SCROLL_UNIT_LINE},      VP_MODE_NORMAL},
-    {"scrolldown",          command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_DOWN | VP_SCROLL_UNIT_LINE},     VP_MODE_NORMAL},
-    {"nmap",                command_map,         {VP_MODE_NORMAL},                                                             VP_MODE_NORMAL},
-    {"imap",                command_map,         {VP_MODE_INSERT},                                                             VP_MODE_NORMAL},
-    {"cmap",                command_map,         {VP_MODE_COMMAND},                                                            VP_MODE_NORMAL},
-    {"hmap",                command_map,         {VP_MODE_HINTING},                                                            VP_MODE_NORMAL},
-    {"nunmap",              command_unmap,       {VP_MODE_NORMAL},                                                             VP_MODE_NORMAL},
-    {"iunmap",              command_unmap,       {VP_MODE_INSERT},                                                             VP_MODE_NORMAL},
-    {"cunmap",              command_unmap,       {VP_MODE_COMMAND},                                                            VP_MODE_NORMAL},
-    {"hunmap",              command_unmap,       {VP_MODE_HINTING},                                                            VP_MODE_NORMAL},
-    {"set",                 command_set,         {0},                                                                          VP_MODE_NORMAL},
-    {"complete",            command_complete,    {0},                                                                          VP_MODE_COMMAND | VP_MODE_COMPLETE},
-    {"complete-back",       command_complete,    {1},                                                                          VP_MODE_COMMAND | VP_MODE_COMPLETE},
-    {"inspect",             command_inspect,     {0},                                                                          VP_MODE_NORMAL},
-    {"hint-link",           command_hints,       {HINTS_TYPE_LINK, "."},                                                       VP_MODE_HINTING},
-    {"hint-link-new",       command_hints,       {HINTS_TYPE_LINK | HINTS_CLICK_BLANK, ","},                                   VP_MODE_HINTING},
-    {"hint-focus-next",     command_hints_focus, {0},                                                                          VP_MODE_HINTING},
-    {"hint-focus-prev",     command_hints_focus, {1},                                                                          VP_MODE_HINTING},
+    /* command              function             arg                                                                                 mode */
+    {"open",                command_open,        {VP_TARGET_CURRENT, ""},                                                            VP_MODE_NORMAL},
+    {"tabopen",             command_open,        {VP_TARGET_NEW, ""},                                                                VP_MODE_NORMAL},
+    {"input",               command_input,       {0, ":"},                                                                           VP_MODE_COMMAND},
+    {"inputopen",           command_input,       {0, ":open "},                                                                      VP_MODE_COMMAND},
+    {"inputtabopen",        command_input,       {0, ":tabopen "},                                                                   VP_MODE_COMMAND},
+    {"inputopencurrent",    command_input,       {VP_INPUT_CURRENT_URI, ":open "},                                                   VP_MODE_COMMAND},
+    {"inputtabopencurrent", command_input,       {VP_INPUT_CURRENT_URI, ":tabopen "},                                                VP_MODE_COMMAND},
+    {"quit",                command_close,       {0},                                                                                VP_MODE_NORMAL},
+    {"source",              command_view_source, {0},                                                                                VP_MODE_NORMAL},
+    {"back",                command_navigate,    {VP_NAVIG_BACK},                                                                    VP_MODE_NORMAL},
+    {"forward",             command_navigate,    {VP_NAVIG_FORWARD},                                                                 VP_MODE_NORMAL},
+    {"reload",              command_navigate,    {VP_NAVIG_RELOAD},                                                                  VP_MODE_NORMAL},
+    {"reload!",             command_navigate,    {VP_NAVIG_RELOAD_FORCE},                                                            VP_MODE_NORMAL},
+    {"stop",                command_navigate,    {VP_NAVIG_STOP_LOADING},                                                            VP_MODE_NORMAL},
+    {"jumpleft",            command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_LEFT},                                   VP_MODE_NORMAL},
+    {"jumpright",           command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_RIGHT},                                  VP_MODE_NORMAL},
+    {"jumptop",             command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_TOP},                                    VP_MODE_NORMAL},
+    {"jumpbottom",          command_scroll,      {VP_SCROLL_TYPE_JUMP | VP_SCROLL_DIRECTION_DOWN},                                   VP_MODE_NORMAL},
+    {"pageup",              command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_TOP | VP_SCROLL_UNIT_PAGE},            VP_MODE_NORMAL},
+    {"pagedown",            command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_DOWN | VP_SCROLL_UNIT_PAGE},           VP_MODE_NORMAL},
+    {"halfpageup",          command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_TOP | VP_SCROLL_UNIT_HALFPAGE},        VP_MODE_NORMAL},
+    {"halfpagedown",        command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_DOWN | VP_SCROLL_UNIT_HALFPAGE},       VP_MODE_NORMAL},
+    {"scrollleft",          command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_LEFT | VP_SCROLL_UNIT_LINE},           VP_MODE_NORMAL},
+    {"scrollright",         command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_RIGHT | VP_SCROLL_UNIT_LINE},          VP_MODE_NORMAL},
+    {"scrollup",            command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_TOP | VP_SCROLL_UNIT_LINE},            VP_MODE_NORMAL},
+    {"scrolldown",          command_scroll,      {VP_SCROLL_TYPE_SCROLL | VP_SCROLL_DIRECTION_DOWN | VP_SCROLL_UNIT_LINE},           VP_MODE_NORMAL},
+    {"nmap",                command_map,         {VP_MODE_NORMAL},                                                                   VP_MODE_NORMAL},
+    {"imap",                command_map,         {VP_MODE_INSERT},                                                                   VP_MODE_NORMAL},
+    {"cmap",                command_map,         {VP_MODE_COMMAND},                                                                  VP_MODE_NORMAL},
+    {"hmap",                command_map,         {VP_MODE_HINTING},                                                                  VP_MODE_NORMAL},
+    {"nunmap",              command_unmap,       {VP_MODE_NORMAL},                                                                   VP_MODE_NORMAL},
+    {"iunmap",              command_unmap,       {VP_MODE_INSERT},                                                                   VP_MODE_NORMAL},
+    {"cunmap",              command_unmap,       {VP_MODE_COMMAND},                                                                  VP_MODE_NORMAL},
+    {"hunmap",              command_unmap,       {VP_MODE_HINTING},                                                                  VP_MODE_NORMAL},
+    {"set",                 command_set,         {0},                                                                                VP_MODE_NORMAL},
+    {"complete",            command_complete,    {0},                                                                                VP_MODE_COMMAND | VP_MODE_COMPLETE},
+    {"complete-back",       command_complete,    {1},                                                                                VP_MODE_COMMAND | VP_MODE_COMPLETE},
+    {"inspect",             command_inspect,     {0},                                                                                VP_MODE_NORMAL},
+    {"hint-link",           command_hints,       {HINTS_TYPE_LINK, "."},                                                             VP_MODE_HINTING},
+    {"hint-link-new",       command_hints,       {HINTS_TYPE_LINK | HINTS_TARGET_BLANK, ","},                                        VP_MODE_HINTING},
+    {"hint-input-open",     command_hints,       {HINTS_TYPE_LINK | HINTS_PROCESS | HINTS_PROCESS_INPUT, ";o"},                      VP_MODE_HINTING},
+    {"hint-input-tabopen",  command_hints,       {HINTS_TYPE_LINK | HINTS_TARGET_BLANK | HINTS_PROCESS | HINTS_PROCESS_INPUT, ";t"}, VP_MODE_HINTING},
+    {"hint-focus-next",     command_hints_focus, {0},                                                                                VP_MODE_HINTING},
+    {"hint-focus-prev",     command_hints_focus, {1},                                                                                VP_MODE_HINTING},
 };
 
 static void command_write_input(const gchar* str);
index b4e2a84..e05e010 100644 (file)
--- a/src/dom.c
+++ b/src/dom.c
@@ -134,6 +134,20 @@ gboolean dom_is_editable(Element* element)
     return FALSE;
 }
 
+/**
+ * Retrieves the src or href attribute of the given element.
+ */
+gchar* dom_element_get_source(Element* elem)
+{
+    gchar* url = NULL;
+
+    url = webkit_dom_html_anchor_element_get_href(WEBKIT_DOM_HTML_ANCHOR_ELEMENT(elem));
+    if (!url) {
+        url = webkit_dom_html_image_element_get_src(WEBKIT_DOM_HTML_IMAGE_ELEMENT(elem));
+    }
+
+    return url;
+}
 
 static gboolean dom_auto_insert(Element* element)
 {
index 74a5571..1dfca61 100644 (file)
--- a/src/dom.h
+++ b/src/dom.h
@@ -53,5 +53,6 @@ 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);
+gchar* dom_element_get_source(Element* elem);
 
 #endif /* end of include guard: DOM_H */
index 382bdee..6cde84f 100644 (file)
@@ -21,7 +21,7 @@
 #include <gdk/gdkkeysyms-compat.h>
 #include "hints.h"
 #include "dom.h"
-#include "main.h"
+#include "command.h"
 
 #define MAX_HINTS 200
 #define HINT_CONTAINER_ID "__hint_container"
@@ -58,6 +58,8 @@ static void hints_create_for_window(
     gulong top_height, gulong offsetX, gulong offsetY);
 static void hints_focus(const gulong num);
 static void hints_fire(const gulong num);
+static void hints_click_fired_hint(guint mode, Element* elem);
+static void hints_process_fired_hint(guint mode, const gchar* uri);
 static Hint* hints_get_hint_by_number(const gulong num);
 static GList* hints_get_hint_list_by_number(const gulong num);
 static gchar* hints_get_xpath(const gchar* input);
@@ -110,7 +112,6 @@ void hints_create(const gchar* input, guint mode)
     gulong top_width, top_height, offsetX, offsetY;
 
     currentMode = mode;
-
     hints_clear();
 
     doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(vp.gui.webview));
@@ -307,6 +308,7 @@ 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_blur(hint->elem);
     }
 
     currentFocusNum = num;
@@ -322,39 +324,68 @@ static void hints_fire(const gulong num)
         webkit_dom_element_focus(hint->elem);
         vp_set_mode(VP_MODE_INSERT, FALSE);
     } else {
-        if (currentMode & HINTS_OPEN_USE) {
-            /* get the elements source or href attribute */
-
+        if (currentMode & HINTS_PROCESS) {
+            hints_process_fired_hint(currentMode, dom_element_get_source(hint->elem));
         } else {
-            /* TODO I don't get the mouse click event dispatched here to
-             * invoce the gtk events for button press wich might be the better
-             * way hanlding to open new windows that setting temporary target
-             * attribute here */
-            gchar* target = webkit_dom_element_get_attribute(hint->elem, "target");
-            if (currentMode & HINTS_CLICK_BLANK) {          /* open in new window */
-                webkit_dom_element_set_attribute(hint->elem, "target", "_blank", NULL);
-            } else if (g_strcmp0(target, "_blank") == 0) {  /* remove possible target attribute */
-                webkit_dom_element_remove_attribute(hint->elem, "target");
-            }
-
-            /* dispatch click event */
-            Document* doc = webkit_web_view_get_dom_document(vp.gui.webview);
-            dom_dispatch_mouse_event(doc, hint->elem, "click", 0);
+            hints_click_fired_hint(currentMode, hint->elem);
 
-            /* reset previous target attribute */
-            if (target && strlen(target)) {
-                webkit_dom_element_set_attribute(hint->elem, "target", target, NULL);
-            } else {
-                webkit_dom_element_remove_attribute(hint->elem, "target");
-            }
+            /* remove the hint filter input and witch to normal mode */
+            vp_set_mode(VP_MODE_NORMAL, TRUE);
         }
-
-        /* remove the hint filter input and witch to normal mode */
-        vp_set_mode(VP_MODE_NORMAL, TRUE);
     }
     hints_clear();
 }
 
+/**
+ * Perform a mouse click to given element.
+ */
+static void hints_click_fired_hint(guint mode, Element* elem)
+{
+    /* TODO I don't get the mouse click event dispatched here to
+     * invoke the gtk events for button press wich might be the better
+     * way hanlding to open new windows than setting temporary target
+     * attribute here */
+    gchar* target = webkit_dom_element_get_attribute(elem, "target");
+    if (mode & HINTS_TARGET_BLANK) {                /* open in new window */
+        webkit_dom_element_set_attribute(elem, "target", "_blank", NULL);
+    } else if (g_strcmp0(target, "_blank") == 0) {  /* remove possible target attribute */
+        webkit_dom_element_remove_attribute(elem, "target");
+    }
+
+    /* dispatch click event */
+    /* TODO use document of the hint an not the default one, but this is only
+     * required if we hint also into frames and iframes */
+    Document* doc = webkit_web_view_get_dom_document(vp.gui.webview);
+    dom_dispatch_mouse_event(doc, elem, "click", 0);
+
+    /* reset previous target attribute */
+    if (target && strlen(target)) {
+        webkit_dom_element_set_attribute(elem, "target", target, NULL);
+    } else {
+        webkit_dom_element_remove_attribute(elem, "target");
+    }
+}
+
+/**
+ * Handle fired hints that are not opened via simulated mouse click.
+ */
+static void hints_process_fired_hint(guint mode, const gchar* uri)
+{
+    HintsProcess type = HINTS_GET_PROCESSING(mode);
+    Arg a = {0};
+    switch (type) {
+        case HINTS_PROCESS_INPUT:
+            a.s = g_strconcat((mode & HINTS_TARGET_BLANK) ? ":tabopen " : ":open ", uri, NULL);
+            command_input(&a);
+            g_free(a.s);
+            break;
+
+        case HINTS_PROCESS_YANK:
+            /* TODO not implemented */
+            break;
+    }
+}
+
 static Hint* hints_get_hint_by_number(const gulong num)
 {
     GList* list = hints_get_hint_list_by_number(num);
@@ -390,7 +421,7 @@ static gchar* hints_get_xpath(const gchar* input)
 {
     gchar* xpath = NULL;
 
-    switch (CLEAN_HINTS_TYPE(currentMode)) {
+    switch (HINTS_GET_TYPE(currentMode)) {
         case HINTS_TYPE_LINK:
             if (input == NULL) {
                 xpath = g_strdup(
@@ -452,9 +483,8 @@ static gboolean hints_changed_callback(GtkEditable *entry, gpointer data)
 {
     const gchar* text = GET_TEXT();
 
-    if (text[0] == '.' || text[0] == ',') {
-        hints_create(text + 1, currentMode);
-    }
+    /* skip hinting prefixes like '. ', ', ', ';y' ... */
+    hints_create(text + 2, currentMode);
 
     return TRUE;
 }
index 2e7c4c9..8286697 100644 (file)
 
 #include "main.h"
 
-#define CLEAN_HINTS_TYPE(type) ((type) & ~(HINTS_OPEN_USE | HINTS_CLICK_BLANK))
-
-enum {
+#define HINTS_GET_TYPE(type)       ((type) & (HINTS_TYPE_LAST))
+#define HINTS_GET_PROCESSING(type) ((type) & ~(HINTS_TYPE_LAST | HINTS_PROCESS | HINTS_TARGET_BLANK))
+
+/*
+bits 1 and 2 form the hint type
+3:  0 = click hint       1 = process source
+4:  0 = open current     1 = open in new window
+all further bits are used for processing types
+*/
+typedef enum {
     HINTS_TYPE_LINK,
     HINTS_TYPE_IMAGE,
     HINTS_TYPE_DEFAULT,
-    HINTS_TYPE_FORM
+    HINTS_TYPE_FORM,
+    HINTS_TYPE_LAST = HINTS_TYPE_FORM,
 } HintsType;
 
 enum {
-    HINTS_OPEN_CLICK,
-    HINTS_OPEN_USE = (1 << 2)
+    HINTS_CLICK,
+    HINTS_PROCESS = (1 << 2)
 };
 
 enum {
-    HINTS_CLICK_CURRENT,
-    HINTS_CLICK_BLANK = (1 << 3)
+    HINTS_TARGET_CURRENT,
+    HINTS_TARGET_BLANK = (1 << 3)
 };
 
+typedef enum {
+    HINTS_PROCESS_INPUT = (1 << 4),
+    HINTS_PROCESS_YANK
+} HintsProcess;
+
 void hints_create(const gchar* input, guint mode);
 void hints_update(const gulong num);
 void hints_clear(void);