summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Carl <danielcarl@gmx.de>2014-01-11 23:16:25 +0100
committerDaniel Carl <danielcarl@gmx.de>2014-01-11 23:23:12 +0100
commit0cf646a648a964e3373d8de97d5ccb4cb487e338 (patch)
tree929da160e71e23a3f17e081b5f8da9f3b8eff30b /src
parentad45d75a322c83163a73c2bb6a4fefa3a1c11de3 (diff)
Run hint script as anonymous object.
This avoids clashes between scripts on pages that defined a variable VbHint.
Diffstat (limited to 'src')
-rw-r--r--src/hints.c163
-rw-r--r--src/hints.js13
2 files changed, 115 insertions, 61 deletions
diff --git a/src/hints.c b/src/hints.c
index 69da66d..07e4ffd 100644
--- a/src/hints.c
+++ b/src/hints.c
@@ -30,26 +30,36 @@
#include "input.h"
#include "map.h"
-#define HINT_VAR "VbHint"
#define HINT_FILE "hints.js"
static struct {
- 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 */
+ 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 */
+ JSContextRef ctx;
} hints;
+
extern VbCore vb;
-static void run_script(char *js);
+static JSObjectRef create_hints_object(WebKitWebFrame *frame, const char *script);
+static void call_hints_function(const char *func, int count, JSValueRef params[]);
+static char *js_ref_to_string(JSContextRef context, JSValueRef ref);
+static JSValueRef js_string_to_ref(JSContextRef ctx, const char *string);
void hints_init(WebKitWebFrame *frame)
{
- char *value = NULL;
- vb_eval_script(frame, HINTS_JS, HINT_FILE, &value);
- g_free(value);
+ if (hints.obj) {
+ JSValueUnprotect(hints.ctx, hints.obj);
+ hints.obj = NULL;
+ }
+ if (!hints.obj) {
+ hints.obj = create_hints_object(frame, HINTS_JS);
+ hints.ctx = webkit_web_frame_get_global_context(frame);
+ }
}
VbResult hints_keypress(int key)
@@ -100,15 +110,11 @@ VbResult hints_keypress(int key)
void hints_clear(void)
{
- char *js, *value = NULL;
-
if (vb.mode->flags & FLAG_HINTING) {
vb.mode->flags &= ~FLAG_HINTING;
vb_set_input_text("");
- js = g_strconcat(HINT_VAR, ".clear();", NULL);
- vb_eval_script(webkit_web_view_get_main_frame(vb.gui.webview), js, HINT_FILE, &value);
- g_free(value);
- g_free(js);
+
+ call_hints_function("clear", 0, NULL);
g_signal_emit_by_name(vb.gui.webview, "hovering-over-link", NULL, NULL);
}
@@ -116,8 +122,6 @@ void hints_clear(void)
void hints_create(const char *input)
{
- char *js = NULL;
-
/* 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 */
@@ -135,53 +139,52 @@ void hints_create(const char *input)
hints.num = 0;
hints.promptlen = hints.gmode ? 3 : 2;
- js = g_strdup_printf("%s.init('%c', %d);", HINT_VAR, hints.mode, MAXIMUM_HINTS);
-
- run_script(js);
- g_free(js);
+ JSValueRef arguments[] = {
+ js_string_to_ref(hints.ctx, (char[]){hints.mode, '\0'}),
+ JSValueMakeNumber(hints.ctx, MAXIMUM_HINTS)
+ };
+ call_hints_function("init", 2, arguments);
/* if hinting is started there won't be any aditional filter given and
* we can go out of this function */
return;
}
- js = g_strdup_printf("%s.filter('%s');", HINT_VAR, *(input + hints.promptlen) ? input + hints.promptlen : "");
- run_script(js);
- g_free(js);
+ JSValueRef arguments[] = {js_string_to_ref(hints.ctx, *(input + hints.promptlen) ? input + hints.promptlen : "")};
+ call_hints_function("filter", 1, arguments);
}
void hints_update(int num)
{
- char *js = g_strdup_printf("%s.update(%d);", HINT_VAR, hints.num);
- run_script(js);
- g_free(js);
+ JSValueRef arguments[] = {
+ JSValueMakeNumber(hints.ctx, num)
+ };
+ call_hints_function("update", 1, arguments);
}
void hints_focus_next(const gboolean back)
{
- char *js = g_strdup_printf("%s.focus(%d);", HINT_VAR, back);
- run_script(js);
- g_free(js);
+ JSValueRef arguments[] = {
+ JSValueMakeNumber(hints.ctx, back)
+ };
+ call_hints_function("focus", 1, arguments);
}
void hints_fire(void)
{
- char *js = g_strconcat(HINT_VAR, ".fire();", NULL);
- run_script(js);
- g_free(js);
+ call_hints_function("fire", 0, NULL);
}
void hints_follow_link(const gboolean back, int count)
{
char *pattern = back ? vb.config.prevpattern : vb.config.nextpattern;
- char *js = g_strdup_printf(
- "%s.followLink('%s', [%s], %d);", HINT_VAR,
- back ? "prev" : "next",
- pattern,
- count
- );
- run_script(js);
- g_free(js);
+
+ JSValueRef arguments[] = {
+ js_string_to_ref(hints.ctx, back ? "prev" : "next"),
+ js_string_to_ref(hints.ctx, pattern),
+ JSValueMakeNumber(hints.ctx, count)
+ };
+ call_hints_function("followLink", 3, arguments);
}
/**
@@ -243,22 +246,60 @@ gboolean hints_parse_prompt(const char *prompt, char *mode, gboolean *is_gmode)
return res;
}
-static void run_script(char *js)
+static JSObjectRef create_hints_object(WebKitWebFrame *frame, const char *script)
+{
+ if (!script) {
+ return NULL;
+ }
+
+ JSStringRef str, file;
+ JSValueRef result, exc = NULL;
+ JSObjectRef object;
+
+ JSContextRef ctx = webkit_web_frame_get_global_context(frame);
+ str = JSStringCreateWithUTF8CString(script);
+ file = JSStringCreateWithUTF8CString(HINT_FILE);
+ result = JSEvaluateScript(ctx, str, NULL, file, 0, &exc);
+ JSStringRelease(str);
+ JSStringRelease(file);
+ if (exc) {
+ return NULL;
+ }
+
+ object = JSValueToObject(ctx, result, &exc);
+ if (exc) {
+ return NULL;
+ }
+ JSValueProtect(ctx, result);
+
+ return object;
+}
+
+static void call_hints_function(const char *func, int count, JSValueRef params[])
{
- char *value = NULL;
+ JSValueRef js_ret, function;
+ JSObjectRef function_object;
+ JSStringRef js_func = NULL;
+ char *value;
- gboolean success = vb_eval_script(
- webkit_web_view_get_main_frame(vb.gui.webview), js, HINT_FILE, &value
- );
- if (!success) {
- fprintf(stderr, "%s\n", value);
- g_free(value);
+ if (!hints.obj) {
+ return;
+ }
- mode_enter('n');
+ js_func = JSStringCreateWithUTF8CString(func);
+ if (!JSObjectHasProperty(hints.ctx, hints.obj, js_func)) {
+ JSStringRelease(js_func);
return;
}
+ function = JSObjectGetProperty(hints.ctx, hints.obj, js_func, NULL);
+ function_object = JSValueToObject(hints.ctx, function, NULL);
+ js_ret = JSObjectCallAsFunction(hints.ctx, function_object, NULL, count, params, NULL);
+ JSStringRelease(js_func);
+
+ value = js_ref_to_string(hints.ctx, js_ret);
+
if (!strncmp(value, "OVER:", 5)) {
g_signal_emit_by_name(
vb.gui.webview, "hovering-over-link", NULL, *(value + 5) == '\0' ? NULL : (value + 5)
@@ -330,3 +371,25 @@ static void run_script(char *js)
}
g_free(value);
}
+
+/* FIXME duplicate to main.c */
+static char *js_ref_to_string(JSContextRef ctx, JSValueRef ref)
+{
+ char *string;
+ JSStringRef str_ref = JSValueToStringCopy(ctx, ref, NULL);
+ size_t len = JSStringGetMaximumUTF8CStringSize(str_ref);
+
+ string = g_new0(char, len);
+ JSStringGetUTF8CString(str_ref, string, len);
+ JSStringRelease(str_ref);
+
+ return string;
+}
+
+static JSValueRef js_string_to_ref(JSContextRef ctx, const char *string)
+{
+ JSStringRef js = JSStringCreateWithUTF8CString(string);
+ JSValueRef ret = JSValueMakeString(ctx, js);
+ JSStringRelease(js);
+ return ret;
+}
diff --git a/src/hints.js b/src/hints.js
index f0cb659..cb1cf25 100644
--- a/src/hints.js
+++ b/src/hints.js
@@ -1,4 +1,4 @@
-function VimbHint() {
+Object.freeze((function(){
'use strict';
var hints = [], /* holds all hint data (hinted element, label, number) in view port */
@@ -531,13 +531,4 @@ function VimbHint() {
/* not really hintings but uses similar logic */
followLink: followLink
};
-}
-
-/* don't overwrite an already existing instance of VbHint, else we loose the */
-/* hinted elements after a hint was fired and we call VbHint.clear() from */
-/* hints.c */
-/* TODO implement the VimbHint as singleton */
-if (typeof VbHint == "undefined") {
- var VbHint = new VimbHint();
- Object.freeze(VbHint);
-}
+})());