diff options
Diffstat (limited to 'src/hints.c')
-rw-r--r-- | src/hints.c | 398 |
1 files changed, 0 insertions, 398 deletions
diff --git a/src/hints.c b/src/hints.c deleted file mode 100644 index 91bb869..0000000 --- a/src/hints.c +++ /dev/null @@ -1,398 +0,0 @@ -/** - * vimb - a webkit based vim like browser. - * - * Copyright (C) 2012-2015 Daniel Carl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -#include "config.h" -#include <gdk/gdkkeysyms.h> -#include <gdk/gdkkeysyms-compat.h> -#include "hints.h" -#include "main.h" -#include "ascii.h" -#include "dom.h" -#include "command.h" -#include "hints.js.h" -#include "input.h" -#include "map.h" -#include "js.h" - -#define HINT_FILE "hints.js" - -static struct { - JSObjectRef obj; /* the js object */ - char mode; /* mode identifying char - that last char of the hint prompt */ - int promptlen; /* length of the hint prompt chars 2 or 3 */ - gboolean gmode; /* indicate if the hints 'g' mode is used */ - JSContextRef ctx; -#if WEBKIT_CHECK_VERSION(2, 0, 0) - /* holds the setting if JavaScript can open windows automatically that we - * have to change to open windows via hinting */ - gboolean allow_open_win; -#endif - guint timeout_id; -} hints; - -extern VbCore vb; - -static gboolean call_hints_function(const char *func, int count, JSValueRef params[]); -static void fire_timeout(gboolean on); -static gboolean fire_cb(gpointer data); - - -void hints_init(WebKitWebFrame *frame) -{ - if (hints.obj) { - JSValueUnprotect(hints.ctx, hints.obj); - hints.obj = NULL; - } - if (!hints.obj) { - hints.ctx = webkit_web_frame_get_global_context(frame); - hints.obj = js_create_object(hints.ctx, HINTS_JS); - } -} - -VbResult hints_keypress(int key) -{ - JSValueRef arguments[1]; - - if (key == KEY_CR) { - hints_fire(); - - return RESULT_COMPLETE; - } else if (key == CTRL('H')) { - fire_timeout(false); - arguments[0] = JSValueMakeNull(hints.ctx); - if (call_hints_function("update", 1, arguments)) { - return RESULT_COMPLETE; - } - } else if (key == KEY_TAB) { - fire_timeout(false); - hints_focus_next(false); - - return RESULT_COMPLETE; - } else if (key == KEY_SHIFT_TAB) { - fire_timeout(false); - hints_focus_next(true); - - return RESULT_COMPLETE; - } else { - fire_timeout(true); - /* try to handle the key by the javascript */ - arguments[0] = js_string_to_ref(hints.ctx, (char[]){key, '\0'}); - if (call_hints_function("update", 1, arguments)) { - return RESULT_COMPLETE; - } - } - - fire_timeout(false); - return RESULT_ERROR; -} - -void hints_clear(void) -{ - if (vb.mode->flags & FLAG_HINTING) { - vb.mode->flags &= ~FLAG_HINTING; - vb_set_input_text(""); - - call_hints_function("clear", 0, NULL); - - g_signal_emit_by_name(vb.gui.webview, "hovering-over-link", NULL, NULL); - -#if WEBKIT_CHECK_VERSION(2, 0, 0) - /* if open window was not allowed for JavaScript, restore this */ - if (!hints.allow_open_win) { - WebKitWebSettings *setting = webkit_web_view_get_settings(vb.gui.webview); - g_object_set(G_OBJECT(setting), "javascript-can-open-windows-automatically", hints.allow_open_win, NULL); - } -#endif - } -} - -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 received */ - 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_enter('n'); - } - return; - } - - if (!(vb.mode->flags & FLAG_HINTING)) { - vb.mode->flags |= FLAG_HINTING; - -#if WEBKIT_CHECK_VERSION(2, 0, 0) - WebKitWebSettings *setting = webkit_web_view_get_settings(vb.gui.webview); - - /* before we enable JavaScript to open new windows, we save the actual - * value to be able restore it after hints where fired */ - g_object_get(G_OBJECT(setting), "javascript-can-open-windows-automatically", &(hints.allow_open_win), NULL); - - /* if window open is already allowed there's no need to allow it again */ - if (!hints.allow_open_win) { - g_object_set(G_OBJECT(setting), "javascript-can-open-windows-automatically", true, NULL); - } -#endif - - 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), - js_string_to_ref(hints.ctx, GET_CHAR("hintkeys")), - JSValueMakeBoolean(hints.ctx, GET_BOOL("hint-follow-last")), - JSValueMakeBoolean(hints.ctx, GET_BOOL("hint-number-same-length")) - }; - call_hints_function("init", 6, arguments); - - /* if hinting is started there won't be any additional filter given and - * we can go out of this function */ - return; - } - - JSValueRef arguments[] = {js_string_to_ref(hints.ctx, *(input + hints.promptlen) ? input + hints.promptlen : "")}; - call_hints_function("filter", 1, arguments); -} - -void hints_focus_next(const gboolean back) -{ - JSValueRef arguments[] = { - JSValueMakeNumber(hints.ctx, back) - }; - call_hints_function("focus", 1, arguments); -} - -void hints_fire(void) -{ - call_hints_function("fire", 0, NULL); -} - -void hints_follow_link(const gboolean back, int count) -{ - char *json = g_strdup_printf( - "[%s]", - back ? vb.config.prevpattern : vb.config.nextpattern - ); - - JSValueRef arguments[] = { - js_string_to_ref(hints.ctx, back ? "prev" : "next"), - js_object_to_ref(hints.ctx, json), - JSValueMakeNumber(hints.ctx, count) - }; - g_free(json); - - call_hints_function("followLink", 3, arguments); -} - -void hints_increment_uri(int count) -{ - JSValueRef arguments[] = { - JSValueMakeNumber(hints.ctx, count) - }; - - call_hints_function("incrementUri", 1, arguments); -} - -/** - * Checks if the given hint prompt belong to a known and valid hints mode and - * parses the mode and is_gmode into given pointers. - * - * The given prompt sting may also contain additional chars after the prompt. - * - * @prompt: String to be parsed as prompt. The Prompt can be followed by - * additional characters. - * @mode: Pointer to char that will be filled with mode char if prompt was - * valid and given pointer is not NULL. - * @is_gmode: Pointer to gboolean to be filled with the flag to indicate gmode - * hinting. - */ -gboolean hints_parse_prompt(const char *prompt, char *mode, gboolean *is_gmode) -{ - gboolean res; - char pmode = '\0'; -#ifdef FEATURE_QUEUE - static char *modes = "eiIoOpPstTxyY"; - static char *g_modes = "IpPstyY"; -#else - static char *modes = "eiIoOstTxyY"; - static char *g_modes = "IstyY"; -#endif - - if (!prompt) { - return false; - } - - /* get the mode identifying char from prompt */ - if (*prompt == ';') { - pmode = prompt[1]; - } else if (*prompt == 'g' && strlen(prompt) >= 3) { - /* get mode for g;X hint modes */ - pmode = prompt[2]; - } - - /* no mode found in prompt */ - if (!pmode) { - return false; - } - - res = *prompt == 'g' - ? strchr(g_modes, pmode) != NULL - : strchr(modes, pmode) != NULL; - - /* fill pointer only if the prompt was valid */ - if (res) { - if (mode != NULL) { - *mode = pmode; - } - if (is_gmode != NULL) { - *is_gmode = *prompt == 'g'; - } - } - - return res; -} - -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); - - g_return_val_if_fail(value != NULL, 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) - ); - g_free(value); - - return true; - } - - /* following return values mark fired hints */ - if (!strncmp(value, "DONE:", 5)) { - fire_timeout(false); - /* Change to normal mode only if we are currently in command mode and - * we are not in g-mode hinting. This is required to not switch to - * normal mode when the hinting triggered a click that set focus on - * editable element that lead vimb to switch to input mode. */ - if (!hints.gmode && vb.mode->id == 'c') { - vb_enter('n'); - } - } else if (!strncmp(value, "INSERT:", 7)) { - fire_timeout(false); - vb_enter('i'); - if (hints.mode == 'e') { - input_open_editor(); - } - } else if (!strncmp(value, "DATA:", 5)) { - fire_timeout(false); - /* 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) { - vb_enter('n'); - } - - char *v = (value + 5); - Arg a = {0}; - /* put the hinted value into register "; */ - vb_register_add(';', v); - switch (hints.mode) { - /* used if images should be opened */ - case 'i': - case 'I': - a.s = v; - a.i = (hints.mode == 'I') ? VB_TARGET_NEW : VB_TARGET_CURRENT; - vb_load_uri(&a); - break; - - case 'O': - case 'T': - vb_echo(VB_MSG_NORMAL, false, "%s %s", (hints.mode == 'T') ? ":tabopen" : ":open", v); - if (!hints.gmode) { - vb_enter('c'); - } - break; - - case 's': - a.s = v; - a.i = COMMAND_SAVE_URI; - command_save(&a); - break; - - case 'x': - map_handle_string(GET_CHAR("x-hint-command"), true); - break; - - case 'y': - case 'Y': - a.i = COMMAND_YANK_ARG; - a.s = v; - command_yank(&a, vb.state.current_register); - break; - -#ifdef FEATURE_QUEUE - case 'p': - case 'P': - a.s = v; - a.i = (hints.mode == 'P') ? COMMAND_QUEUE_UNSHIFT : COMMAND_QUEUE_PUSH; - command_queue(&a); - break; -#endif - } - } - g_free(value); - return true; -} - -static void fire_timeout(gboolean on) -{ - int millis; - /* remove possible timeout function */ - if (hints.timeout_id) { - g_source_remove(hints.timeout_id); - hints.timeout_id = 0; - } - - if (on) { - millis = GET_INT("hint-timeout"); - if (millis) { - hints.timeout_id = g_timeout_add(millis, (GSourceFunc)fire_cb, NULL); - } - } -} - -static gboolean fire_cb(gpointer data) -{ - hints_fire(); - - /* remove timeout id for the timeout that is removed by return value of - * false automatic */ - hints.timeout_id = 0; - return false; -} |