1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
/**
* 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 "js.h"
static gboolean evaluate_string(JSContextRef ctx, const char *script,
const char *file, JSValueRef *result);
/**
* Run scripts out of given file in the given frame.
*/
gboolean js_eval_file(JSContextRef ctx, const char *file)
{
char *js = NULL, *value = NULL;
if (g_file_test(file, G_FILE_TEST_IS_REGULAR)
&& g_file_get_contents(file, &js, NULL, NULL)
) {
gboolean success = js_eval(ctx, js, file, &value);
if (!success) {
g_warning("JavaScript error in %s: %s", file, value);
}
g_free(value);
g_free(js);
return success;
}
return false;
}
/**
* Evaluates given string as script and return if this call succeed or not.
* On success the given **value pointer is filled with the returned string,
* else with the exception message. In both cases this must be freed by the
* caller if no longer used.
*/
gboolean js_eval(JSContextRef ctx, const char *script, const char *file,
char **value)
{
gboolean success;
JSValueRef result = NULL;
success = evaluate_string(ctx, script, file, &result);
*value = js_ref_to_string(ctx, result);
return success;
}
/**
* Creates a JavaScript object in context of given frame.
*/
JSObjectRef js_create_object(JSContextRef ctx, const char *script)
{
JSValueRef result = NULL, exc = NULL;
JSObjectRef object;
if (!evaluate_string(ctx, script, NULL, &result)) {
return NULL;
}
object = JSValueToObject(ctx, result, &exc);
if (exc) {
return NULL;
}
JSValueProtect(ctx, result);
return object;
}
/**
* Calls a function on object and returns the result as newly allocates
* string.
* Returned string must be freed after use.
*/
char* js_object_call_function(JSContextRef ctx, JSObjectRef obj,
const char *func, int count, JSValueRef params[])
{
JSValueRef js_ret, function;
JSObjectRef function_object;
JSStringRef js_func = NULL;
char *value;
g_return_val_if_fail(obj != NULL, NULL);
js_func = JSStringCreateWithUTF8CString(func);
if (!JSObjectHasProperty(ctx, obj, js_func)) {
JSStringRelease(js_func);
return NULL;
}
function = JSObjectGetProperty(ctx, obj, js_func, NULL);
function_object = JSValueToObject(ctx, function, NULL);
js_ret = JSObjectCallAsFunction(ctx, function_object, NULL, count, params, NULL);
JSStringRelease(js_func);
value = js_ref_to_string(ctx, js_ret);
return value;
}
/**
* Returns a new allocates string for given value reference.
* String must be freed if not used anymore.
*/
char* js_ref_to_string(JSContextRef ctx, JSValueRef ref)
{
char *string;
size_t len;
JSStringRef str_ref;
g_return_val_if_fail(ref != NULL, NULL);
str_ref = JSValueToStringCopy(ctx, ref, NULL);
len = JSStringGetMaximumUTF8CStringSize(str_ref);
string = g_new0(char, len);
JSStringGetUTF8CString(str_ref, string, len);
JSStringRelease(str_ref);
return string;
}
/**
* Retrieves a values reference for given string.
*/
JSValueRef js_string_to_ref(JSContextRef ctx, const char *string)
{
JSStringRef js = JSStringCreateWithUTF8CString(string);
JSValueRef ref = JSValueMakeString(ctx, js);
JSStringRelease(js);
return ref;
}
/**
* Retrieves a values reference for given json or array string string.
*/
JSValueRef js_object_to_ref(JSContextRef ctx, const char *json)
{
JSValueRef ref = NULL;
if (evaluate_string(ctx, json, NULL, &ref)) {
return ref;
}
g_warning("Could not parse %s", json);
return NULL;
}
/**
* Runs a string as JavaScript and returns if the call succeed.
* In case the call succeed, the given *result is filled with the result
* value, else with the value reference of the exception.
*/
static gboolean evaluate_string(JSContextRef ctx, const char *script,
const char *file, JSValueRef *result)
{
JSStringRef js_str, js_file;
JSValueRef exc = NULL, res = NULL;
js_str = JSStringCreateWithUTF8CString(script);
js_file = JSStringCreateWithUTF8CString(file);
res = JSEvaluateScript(ctx, js_str, JSContextGetGlobalObject(ctx), js_file, 0, &exc);
JSStringRelease(js_file);
JSStringRelease(js_str);
if (exc) {
*result = exc;
return false;
}
*result = res;
return true;
}
|