aboutsummaryrefslogtreecommitdiffstats
path: root/src/xwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xwidget.c')
-rw-r--r--src/xwidget.c219
1 files changed, 92 insertions, 127 deletions
diff --git a/src/xwidget.c b/src/xwidget.c
index 121510ebac0..ecb37936293 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -31,14 +31,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
31#include <webkit2/webkit2.h> 31#include <webkit2/webkit2.h>
32#include <JavaScriptCore/JavaScript.h> 32#include <JavaScriptCore/JavaScript.h>
33 33
34/* Suppress GCC deprecation warnings starting in WebKitGTK+ 2.21.1 for
35 webkit_javascript_result_get_global_context and
36 webkit_javascript_result_get_value (Bug#33679).
37 FIXME: Use the JavaScriptCore GLib API instead, and remove this hack. */
38#if WEBKIT_CHECK_VERSION (2, 21, 1) && GNUC_PREREQ (4, 2, 0)
39# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
40#endif
41
42static struct xwidget * 34static struct xwidget *
43allocate_xwidget (void) 35allocate_xwidget (void)
44{ 36{
@@ -284,95 +276,70 @@ webkit_view_load_changed_cb (WebKitWebView *webkitwebview,
284 276
285/* Recursively convert a JavaScript value to a Lisp value. */ 277/* Recursively convert a JavaScript value to a Lisp value. */
286static Lisp_Object 278static Lisp_Object
287webkit_js_to_lisp (JSContextRef context, JSValueRef value) 279webkit_js_to_lisp (JSCValue *value)
288{ 280{
289 switch (JSValueGetType (context, value)) 281 if (jsc_value_is_string (value))
290 { 282 {
291 case kJSTypeString: 283 gchar *str_value = jsc_value_to_string (value);
292 { 284 Lisp_Object ret = build_string (str_value);
293 JSStringRef js_str_value; 285 g_free (str_value);
294 gchar *str_value; 286
295 gsize str_length; 287 return ret;
296 288 }
297 js_str_value = JSValueToStringCopy (context, value, NULL); 289 else if (jsc_value_is_boolean (value))
298 str_length = JSStringGetMaximumUTF8CStringSize (js_str_value); 290 {
299 str_value = (gchar *)g_malloc (str_length); 291 return (jsc_value_to_boolean (value)) ? Qt : Qnil;
300 JSStringGetUTF8CString (js_str_value, str_value, str_length); 292 }
301 JSStringRelease (js_str_value); 293 else if (jsc_value_is_number (value))
302 return build_string (str_value); 294 {
303 } 295 return make_fixnum (jsc_value_to_int32 (value));
304 case kJSTypeBoolean: 296 }
305 return (JSValueToBoolean (context, value)) ? Qt : Qnil; 297 else if (jsc_value_is_array (value))
306 case kJSTypeNumber: 298 {
307 return make_fixnum (JSValueToNumber (context, value, NULL)); 299 JSCValue *len = jsc_value_object_get_property (value, "length");
308 case kJSTypeObject: 300 const gint32 dlen = jsc_value_to_int32 (len);
309 { 301
310 if (JSValueIsArray (context, value)) 302 Lisp_Object obj;
311 { 303 if (! (0 <= dlen && dlen < PTRDIFF_MAX + 1.0))
312 JSStringRef pname = JSStringCreateWithUTF8CString("length"); 304 memory_full (SIZE_MAX);
313 JSValueRef len = JSObjectGetProperty (context, (JSObjectRef) value, 305
314 pname, NULL); 306 ptrdiff_t n = dlen;
315 double dlen = JSValueToNumber (context, len, NULL); 307 struct Lisp_Vector *p = allocate_vector (n);
316 JSStringRelease(pname); 308
317 309 for (ptrdiff_t i = 0; i < n; ++i)
318 Lisp_Object obj; 310 {
319 if (! (0 <= dlen && dlen < PTRDIFF_MAX + 1.0)) 311 p->contents[i] =
320 memory_full (SIZE_MAX); 312 webkit_js_to_lisp (jsc_value_object_get_property_at_index (value, i));
321 ptrdiff_t n = dlen; 313 }
322 struct Lisp_Vector *p = allocate_vector (n); 314 XSETVECTOR (obj, p);
323 315 return obj;
324 for (ptrdiff_t i = 0; i < n; ++i) 316 }
325 { 317 else if (jsc_value_is_object (value))
326 p->contents[i] = 318 {
327 webkit_js_to_lisp (context, 319 char **properties_names = jsc_value_object_enumerate_properties (value);
328 JSObjectGetPropertyAtIndex (context, 320 guint n = g_strv_length (properties_names);
329 (JSObjectRef) value, 321
330 i, NULL)); 322 Lisp_Object obj;
331 } 323 if (PTRDIFF_MAX < n)
332 XSETVECTOR (obj, p); 324 memory_full (n);
333 return obj; 325 struct Lisp_Vector *p = allocate_vector (n);
334 } 326
335 else 327 for (ptrdiff_t i = 0; i < n; ++i)
336 { 328 {
337 JSPropertyNameArrayRef properties = 329 const char *name = properties_names[i];
338 JSObjectCopyPropertyNames (context, (JSObjectRef) value); 330 JSCValue *property = jsc_value_object_get_property (value, name);
339 331
340 size_t n = JSPropertyNameArrayGetCount (properties); 332 p->contents[i] =
341 Lisp_Object obj; 333 Fcons (build_string (name), webkit_js_to_lisp (property));
342 334 }
343 /* TODO: can we use a regular list here? */ 335
344 if (PTRDIFF_MAX < n) 336 g_strfreev (properties_names);
345 memory_full (n); 337
346 struct Lisp_Vector *p = allocate_vector (n); 338 XSETVECTOR (obj, p);
347 339 return obj;
348 for (ptrdiff_t i = 0; i < n; ++i)
349 {
350 JSStringRef name = JSPropertyNameArrayGetNameAtIndex (properties, i);
351 JSValueRef property = JSObjectGetProperty (context,
352 (JSObjectRef) value,
353 name, NULL);
354 gchar *str_name;
355 gsize str_length;
356 str_length = JSStringGetMaximumUTF8CStringSize (name);
357 str_name = (gchar *)g_malloc (str_length);
358 JSStringGetUTF8CString (name, str_name, str_length);
359 JSStringRelease (name);
360
361 p->contents[i] =
362 Fcons (build_string (str_name),
363 webkit_js_to_lisp (context, property));
364 }
365
366 JSPropertyNameArrayRelease (properties);
367 XSETVECTOR (obj, p);
368 return obj;
369 }
370 }
371 case kJSTypeUndefined:
372 case kJSTypeNull:
373 default:
374 return Qnil;
375 } 340 }
341
342 return Qnil;
376} 343}
377 344
378static void 345static void
@@ -380,41 +347,39 @@ webkit_javascript_finished_cb (GObject *webview,
380 GAsyncResult *result, 347 GAsyncResult *result,
381 gpointer arg) 348 gpointer arg)
382{ 349{
383 WebKitJavascriptResult *js_result; 350 GError *error = NULL;
384 JSValueRef value; 351 struct xwidget *xw = g_object_get_data (G_OBJECT (webview), XG_XWIDGET);
385 JSGlobalContextRef context;
386 GError *error = NULL;
387 struct xwidget *xw = g_object_get_data (G_OBJECT (webview),
388 XG_XWIDGET);
389 ptrdiff_t script_idx = (intptr_t) arg;
390 Lisp_Object script_callback = AREF (xw->script_callbacks, script_idx);
391 ASET (xw->script_callbacks, script_idx, Qnil);
392 if (!NILP (script_callback))
393 xfree (xmint_pointer (XCAR (script_callback)));
394
395 js_result = webkit_web_view_run_javascript_finish
396 (WEBKIT_WEB_VIEW (webview), result, &error);
397
398 if (!js_result)
399 {
400 g_warning ("Error running javascript: %s", error->message);
401 g_error_free (error);
402 return;
403 }
404 352
405 if (!NILP (script_callback) && !NILP (XCDR (script_callback))) 353 ptrdiff_t script_idx = (intptr_t) arg;
406 { 354 Lisp_Object script_callback = AREF (xw->script_callbacks, script_idx);
407 context = webkit_javascript_result_get_global_context (js_result); 355 ASET (xw->script_callbacks, script_idx, Qnil);
408 value = webkit_javascript_result_get_value (js_result); 356 if (!NILP (script_callback))
409 Lisp_Object lisp_value = webkit_js_to_lisp (context, value); 357 xfree (xmint_pointer (XCAR (script_callback)));
410 358
411 /* Register an xwidget event here, which then runs the callback. 359 WebKitJavascriptResult *js_result =
412 This ensures that the callback runs in sync with the Emacs 360 webkit_web_view_run_javascript_finish
413 event loop. */ 361 (WEBKIT_WEB_VIEW (webview), result, &error);
414 store_xwidget_js_callback_event (xw, XCDR (script_callback), lisp_value); 362
415 } 363 if (!js_result)
364 {
365 g_warning ("Error running javascript: %s", error->message);
366 g_error_free (error);
367 return;
368 }
369
370 if (!NILP (script_callback) && !NILP (XCDR (script_callback)))
371 {
372 JSCValue *value = webkit_javascript_result_get_js_value (js_result);
373
374 Lisp_Object lisp_value = webkit_js_to_lisp (value);
375
376 /* Register an xwidget event here, which then runs the callback.
377 This ensures that the callback runs in sync with the Emacs
378 event loop. */
379 store_xwidget_js_callback_event (xw, XCDR (script_callback), lisp_value);
380 }
416 381
417 webkit_javascript_result_unref (js_result); 382 webkit_javascript_result_unref (js_result);
418} 383}
419 384
420 385