summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Carl <danielcarl@gmx.de>2014-01-12 20:25:15 +0100
committerDaniel Carl <danielcarl@gmx.de>2014-01-12 22:10:36 +0100
commitd8b406d2512c16accfa7b873e21041bbe33a1d7b (patch)
tree2049c9e27ed4b81ceca4443f581121689f4499c9
parent6e7e3a1266271041ca794252cf0396764c5638f1 (diff)
Changes responsibility for hinting (#61).
The JavaScript handles now the clearing of the hints, so that we do not run into trouble if the hinting object is overwritten by the next page call before we are able to run the clear() method on it. The JavaScript handles also the number filter processing now.
-rw-r--r--src/hints.c87
-rw-r--r--src/hints.h1
-rw-r--r--src/hints.js60
3 files changed, 77 insertions, 71 deletions
diff --git a/src/hints.c b/src/hints.c
index 7e50c1c..52fe9e0 100644
--- a/src/hints.c
+++ b/src/hints.c
@@ -35,7 +35,6 @@
static struct {
JSObjectRef obj; /* the js object */
- guint num; /* olds the numeric filter for hints typed by the user */
char mode; /* mode identifying char - that last char of the hint prompt */
int promptlen; /* lenfth of the hint prompt chars 2 or 3 */
gboolean gmode; /* indicate if the hints g mode is used */
@@ -45,7 +44,7 @@ static struct {
extern VbCore vb;
-static void call_hints_function(const char *func, int count, JSValueRef params[]);
+static gboolean call_hints_function(const char *func, int count, JSValueRef params[]);
void hints_init(WebKitWebFrame *frame)
@@ -55,13 +54,15 @@ void hints_init(WebKitWebFrame *frame)
hints.obj = NULL;
}
if (!hints.obj) {
- hints.obj = js_create_object(frame, HINTS_JS);
hints.ctx = webkit_web_frame_get_global_context(frame);
+ hints.obj = js_create_object(frame, HINTS_JS);
}
}
VbResult hints_keypress(int key)
{
+ JSValueRef arguments[1];
+
/* if we are not already in hint mode we expect to get a ; to start
* hinting */
if (!(vb.mode->flags & FLAG_HINTING) && key != ';') {
@@ -72,32 +73,21 @@ VbResult hints_keypress(int key)
hints_fire();
return RESULT_COMPLETE;
- }
-
- /* if there is an active filter by hint num backspace will remove the
- * number filter first */
- if (hints.num && key == CTRL('H')) {
- hints.num /= 10;
- hints_update(hints.num);
-
- return RESULT_COMPLETE;
- }
- if (isdigit(key)) {
- int num = key - '0';
- if ((num >= 1 && num <= 9) || (num == 0 && hints.num)) {
- /* allow a zero as non-first number */
- hints.num = (hints.num ? hints.num * 10 : 0) + num;
- hints_update(hints.num);
-
+ } else if (key == CTRL('H')) {
+ arguments[0] = JSValueMakeNull(hints.ctx);
+ if (call_hints_function("update", 1, arguments)) {
return RESULT_COMPLETE;
}
- }
- if (key == KEY_TAB) {
+ } else if (isdigit(key)) {
+ arguments[0] = JSValueMakeNumber(hints.ctx, key - '0');
+ if (call_hints_function("update", 1, arguments)) {
+ return RESULT_COMPLETE;
+ }
+ } else if (key == KEY_TAB) {
hints_focus_next(false);
return RESULT_COMPLETE;
- }
- if (key == KEY_SHIFT_TAB) {
+ } else if (key == KEY_SHIFT_TAB) {
hints_focus_next(true);
return RESULT_COMPLETE;
@@ -120,6 +110,12 @@ void hints_clear(void)
void hints_create(const char *input)
{
+ /* don't start hinting if the hinting object isn't created - for example
+ * if hinting is started before the first data of page are recieved */
+ if (!hints.obj) {
+ return;
+ }
+
/* check if the input contains a valid hinting prompt */
if (!hints_parse_prompt(input, &hints.mode, &hints.gmode)) {
/* if input is not valid, clear possible previous hint mode */
@@ -132,16 +128,14 @@ void hints_create(const char *input)
if (!(vb.mode->flags & FLAG_HINTING)) {
vb.mode->flags |= FLAG_HINTING;
- /* unset number filter - this is required to remove the last char from
- * inputbox on backspace also if there was used a number filter prior */
- hints.num = 0;
hints.promptlen = hints.gmode ? 3 : 2;
JSValueRef arguments[] = {
js_string_to_ref(hints.ctx, (char[]){hints.mode, '\0'}),
+ JSValueMakeBoolean(hints.ctx, hints.gmode),
JSValueMakeNumber(hints.ctx, MAXIMUM_HINTS)
};
- call_hints_function("init", 2, arguments);
+ call_hints_function("init", 3, arguments);
/* if hinting is started there won't be any aditional filter given and
* we can go out of this function */
@@ -152,14 +146,6 @@ void hints_create(const char *input)
call_hints_function("filter", 1, arguments);
}
-void hints_update(int num)
-{
- JSValueRef arguments[] = {
- JSValueMakeNumber(hints.ctx, num)
- };
- call_hints_function("update", 1, arguments);
-}
-
void hints_focus_next(const gboolean back)
{
JSValueRef arguments[] = {
@@ -244,20 +230,25 @@ gboolean hints_parse_prompt(const char *prompt, char *mode, gboolean *is_gmode)
return res;
}
-static void call_hints_function(const char *func, int count, JSValueRef params[])
+static gboolean call_hints_function(const char *func, int count, JSValueRef params[])
{
char *value = js_object_call_function(hints.ctx, hints.obj, func, count, params);
+ if (!value) {
+ return false;
+ }
+
+ if (!strncmp(value, "ERROR:", 6)) {
+ g_free(value);
+ return false;
+ }
+
if (!strncmp(value, "OVER:", 5)) {
g_signal_emit_by_name(
vb.gui.webview, "hovering-over-link", NULL, *(value + 5) == '\0' ? NULL : (value + 5)
);
} else if (!strncmp(value, "DONE:", 5)) {
- if (hints.gmode) {
- /* if g mode is used reset number filter and keep in hint mode */
- hints.num = 0;
- hints_update(hints.num);
- } else {
+ if (!hints.gmode) {
mode_enter('n');
}
} else if (!strncmp(value, "INSERT:", 7)) {
@@ -266,13 +257,9 @@ static void call_hints_function(const char *func, int count, JSValueRef params[]
input_open_editor();
}
} else if (!strncmp(value, "DATA:", 5)) {
- if (hints.gmode) {
- /* if g mode is used reset number filter and keep in hint mode */
- hints.num = 0;
- hints_update(hints.num);
- } else {
- /* switch first to normal mode - else we would clear the inputbox
- * on switching mode also if we want to show yanked data */
+ /* switch first to normal mode - else we would clear the inputbox
+ * on switching mode also if we want to show yanked data */
+ if (!hints.gmode) {
mode_enter('n');
}
@@ -318,4 +305,6 @@ static void call_hints_function(const char *func, int count, JSValueRef params[]
}
}
g_free(value);
+
+ return true;
}
diff --git a/src/hints.h b/src/hints.h
index 6503a9d..9a786cb 100644
--- a/src/hints.h
+++ b/src/hints.h
@@ -25,7 +25,6 @@
void hints_init(WebKitWebFrame *frame);
VbResult hints_keypress(int key);
void hints_create(const char *input);
-void hints_update(int num);
void hints_fire(void);
void hints_follow_link(const gboolean back, int count);
gboolean hints_parse_prompt(const char *prompt, char *mode, gboolean *is_gmode);
diff --git a/src/hints.js b/src/hints.js
index cb1cf25..86fa7a3 100644
--- a/src/hints.js
+++ b/src/hints.js
@@ -238,7 +238,7 @@ Object.freeze((function(){
helper(window);
}
- function show() {
+ function show(fireLast) {
var i, hint, newIdx,
num = 1,
matcher = getMatcher(filterText);
@@ -263,10 +263,8 @@ Object.freeze((function(){
num++;
}
}
-
- if (validHints.length <= 1) {
+ if (fireLast && validHints.length <= 1) {
focusHint(0);
-
return fire();
}
@@ -332,32 +330,40 @@ Object.freeze((function(){
function fire() {
if (!activeHint) {
- return "DONE:";
+ return "ERROR:";
}
var e = activeHint.e,
tag = e.nodeName.toLowerCase(),
- type = e.type || "";
+ type = e.type || "",
+ res = "";
if (tag === "input" || tag === "textarea" || tag === "select") {
if (type === "radio" || type === "checkbox") {
e.focus();
click(e);
- return "DONE:";
- }
- if (type === "submit" || type === "reset" || type === "button" || type === "image") {
+ res = "DONE:";
+ } else if (type === "submit" || type === "reset" || type === "button" || type === "image") {
click(e);
- return "DONE:";
+ res = "DONE:";
+ } else {
+ e.focus();
+ res = "INSERT:";
}
+ } else if (tag === "iframe" || tag === "frame") {
e.focus();
- return "INSERT:";
+ res = "DONE:";
}
- if (tag === "iframe" || tag === "frame") {
- e.focus();
- return "DONE:";
+
+ if (config.continue) {
+ /* reset the filter number */
+ filterNum = 0;
+ show(false);
+ } else {
+ clear();
}
- return config.action(e);
+ return res || config.action(e);
}
/* internal used methods */
@@ -481,7 +487,7 @@ Object.freeze((function(){
/* the api */
return {
- init: function init(mode, maxHints) {
+ init: function init(mode, keepOpen, maxHints) {
var prop,
/* holds the xpaths for the different modes */
xpathmap = {
@@ -497,7 +503,10 @@ Object.freeze((function(){
eiIOpPsTy: function(e) {return "DATA:" + getSrc(e);}
};
- config = {maxHints: maxHints};
+ config = {
+ maxHints: maxHints,
+ continue: keepOpen
+ };
for (prop in xpathmap) {
if (prop.indexOf(mode) >= 0) {
config["xpath"] = xpathmap[prop];
@@ -512,18 +521,27 @@ Object.freeze((function(){
}
create();
- return show();
+ return show(true);
},
filter: function filter(text) {
/* remove previously set number filters to make the filter */
/* easier to understand for the users */
filterNum = 0;
filterText = text || "";
- return show();
+ return show(true);
},
update: function update(n) {
- filterNum = n;
- return show();
+ /* delete last filter number digit */
+ if (null === n && filterNum) {
+ filterNum = Math.floor(filterNum / 10);
+ return show(false);
+ }
+ if ((n >= 1 && n <= 9) || (n === 0 && filterNum)) {
+ /* allow a zero as non-first number */
+ filterNum = (filterNum ? filterNum * 10 : 0) + n;
+ return show(true);
+ }
+ return "ERROR:";
},
clear: clear,
fire: fire,