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 */
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)
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 != ';') {
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;
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 */
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 */
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[] = {
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)) {
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');
}
}
}
g_free(value);
+
+ return true;
}
helper(window);
}
- function show() {
+ function show(fireLast) {
var i, hint, newIdx,
num = 1,
matcher = getMatcher(filterText);
num++;
}
}
-
- if (validHints.length <= 1) {
+ if (fireLast && validHints.length <= 1) {
focusHint(0);
-
return fire();
}
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 */
/* the api */
return {
- init: function init(mode, maxHints) {
+ init: function init(mode, keepOpen, maxHints) {
var prop,
/* holds the xpaths for the different modes */
xpathmap = {
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];
}
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,