summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/js.c17
-rw-r--r--src/js.h2
-rw-r--r--src/scratchpad.c35
-rw-r--r--src/scripts.c49
-rw-r--r--src/scripts.h2
5 files changed, 100 insertions, 5 deletions
diff --git a/src/js.c b/src/js.c
index d5b9e02b..789471a4 100644
--- a/src/js.c
+++ b/src/js.c
@@ -120,6 +120,23 @@ js_string_to_char(JSContextRef ctx, JSStringRef jsstring, size_t size) {
return ret;
}/*}}}*/
+JSValueRef
+js_context_change(JSContextRef source_ctx, JSContextRef dest_ctx, JSValueRef val, JSValueRef *exc) {
+ char *c_val = js_value_to_json(source_ctx, val, -1, exc);
+ if (c_val == NULL)
+ return JSValueMakeNull(dest_ctx);
+
+ JSStringRef json = JSStringCreateWithUTF8CString(c_val);
+ JSValueRef ret = JSValueMakeFromJSONString(dest_ctx, json);
+
+ g_free(c_val);
+ JSStringRelease(json);
+
+ if (ret == NULL)
+ return JSValueMakeNull(dest_ctx);
+ return ret;
+}
+
/* js_create_object(WebKitWebFrame *frame, const char *)
*
* Executes a script in a function scope, should return an object with
diff --git a/src/js.h b/src/js.h
index 2edf79a3..40dbdd2e 100644
--- a/src/js.h
+++ b/src/js.h
@@ -18,6 +18,7 @@
#ifndef JS_H
#define JS_H
+#include <JavaScriptCore/JavaScript.h>
void js_make_exception(JSContextRef ctx, JSValueRef *exception, const gchar *format, ...);
char * js_string_to_char(JSContextRef ctx, JSStringRef jsstring, size_t );
@@ -36,6 +37,7 @@ JSValueRef js_execute(JSContextRef ctx, const char *, JSValueRef *exc);
gboolean js_print_exception(JSContextRef ctx, JSValueRef exception);
JSObjectRef js_make_function(JSContextRef ctx, const char *script);
JSValueRef js_json_to_value(JSContextRef ctx, const char *text);
+JSValueRef js_context_change(JSContextRef, JSContextRef, JSValueRef, JSValueRef *);
typedef struct _js_array_iterator {
JSContextRef ctx;
diff --git a/src/scratchpad.c b/src/scratchpad.c
index 4ae25848..00fc0974 100644
--- a/src/scratchpad.c
+++ b/src/scratchpad.c
@@ -17,6 +17,9 @@
*/
#include "dwb.h"
+#include "js.h"
+#include "scripts.h"
+#include <JavaScriptCore/JavaScript.h>
GtkWidget *g_scratchpad;
static gboolean
@@ -30,6 +33,32 @@ navigation_cb(WebKitWebView *wv, WebKitWebFrame *frame, WebKitNetworkRequest *re
return false;
}
+
+static JSValueRef
+sp_send(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) {
+ if (argc > 0)
+ scripts_scratchpad_send(ctx, argv[0]);
+ return JSValueMakeUndefined(ctx);
+}
+
+static JSValueRef
+sp_get(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc) {
+ scripts_scratchpad_get(ctx, function, this, argc, argv, exc);
+ return JSValueMakeUndefined(ctx);
+}
+
+static void
+window_object_cb(WebKitWebView *wv, WebKitWebFrame *frame, JSContextRef ctx, JSObjectRef window) {
+ if (frame == webkit_web_view_get_main_frame(wv)) {
+ JSObjectRef func = JSObjectMakeFunctionWithCallback(ctx, NULL, sp_get);
+ js_set_property(ctx, window, "dwbGet", func,
+ kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, NULL);
+ func = JSObjectMakeFunctionWithCallback(ctx, NULL, sp_send);
+ js_set_property(ctx, window, "dwbSend", func,
+ kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, NULL);
+ }
+}
+
void
scratchpad_load(const char *text) {
if (g_str_has_prefix(text, "file://"))
@@ -43,22 +72,24 @@ scratchpad_show(void) {
gtk_widget_show(g_scratchpad);
gtk_widget_grab_focus(g_scratchpad);
}
+
void
scratchpad_hide(void) {
gtk_widget_hide(g_scratchpad);
dwb_focus_scroll(dwb.state.fview);
}
+
static void
scratchpad_init(void) {
g_scratchpad = webkit_web_view_new();
g_signal_connect(g_scratchpad, "navigation-policy-decision-requested", G_CALLBACK(navigation_cb), NULL);
+ g_signal_connect(g_scratchpad, "window-object-cleared", G_CALLBACK(window_object_cb), NULL);
gtk_widget_set_size_request(g_scratchpad, -1, 200);
}
+
GtkWidget *
scratchpad_get(void) {
if (g_scratchpad == NULL)
scratchpad_init();
return g_scratchpad;
}
-
-
diff --git a/src/scripts.c b/src/scripts.c
index 5fdeae85..669de66e 100644
--- a/src/scripts.c
+++ b/src/scripts.c
@@ -125,6 +125,8 @@ static JSStaticValue message_values[] = {
static JSValueRef sp_show(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSValueRef sp_hide(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSValueRef sp_load(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
+static JSValueRef sp_get(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
+static JSValueRef sp_send(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSValueRef frame_inject(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc);
static JSStaticFunction frame_functions[] = {
@@ -165,6 +167,8 @@ static JSClassRef m_webview_class, m_frame_class, m_download_class, m_default_cl
static gboolean m_commandline = false;
static JSObjectRef m_array_contructor;
static JSObjectRef m_completion_callback;
+static JSObjectRef m_sp_scripts_cb;
+static JSObjectRef m_sp_scratchpad_cb;
static GQuark ref_quark;
/* MISC {{{*/
@@ -491,10 +495,47 @@ sp_load(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, c
g_free(text);
}
return JSValueMakeUndefined(ctx);
-
}
-
-
+static JSObjectRef
+sp_callback_create(JSContextRef ctx, size_t argc, const JSValueRef argv[], JSValueRef *exc) {
+ JSObjectRef ret = NULL;
+ if (argc > 0) {
+ ret = JSValueToObject(ctx, argv[0], exc);
+ if (ret == NULL || !JSObjectIsFunction(ctx, ret))
+ ret = NULL;
+ }
+ return ret;
+}
+static JSValueRef
+sp_get(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc) {
+ m_sp_scripts_cb = sp_callback_create(ctx, argc, argv, exc);
+ return JSValueMakeUndefined(ctx);
+}
+void
+scripts_scratchpad_get(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc) {
+ m_sp_scratchpad_cb = sp_callback_create(ctx, argc, argv, exc);
+}
+void
+sp_context_change(JSContextRef src_ctx, JSContextRef dest_ctx, JSObjectRef func, JSValueRef val) {
+ if (func != NULL) {
+ JSValueRef val_changed = js_context_change(src_ctx, dest_ctx, val, NULL);
+ JSValueRef argv[] = { val_changed == 0 ? JSValueMakeNull(dest_ctx) : val_changed };
+ JSObjectCallAsFunction(dest_ctx, func, NULL, 1, argv, NULL);
+ }
+}
+// send from scripts context to scratchpad context
+static JSValueRef
+sp_send(JSContextRef ctx, JSObjectRef function, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc) {
+ if (argc > 0) {
+ sp_context_change(m_global_context, webkit_web_frame_get_global_context(webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(scratchpad_get()))), m_sp_scratchpad_cb, argv[0]);
+ }
+ return JSValueMakeUndefined(ctx);
+}
+// send from scratchpad context to script context
+void
+scripts_scratchpad_send(JSContextRef ctx, JSValueRef val) {
+ sp_context_change(ctx, m_global_context, m_sp_scripts_cb, val);
+}
/* SOUP_MESSAGE {{{*/
/* soup_uri_to_js_object {{{*/
@@ -1853,6 +1894,8 @@ create_global_object() {
{ "show", sp_show, kJSDefaultAttributes },
{ "hide", sp_hide, kJSDefaultAttributes },
{ "load", sp_load, kJSDefaultAttributes },
+ { "get", sp_get, kJSDefaultAttributes },
+ { "send", sp_send, kJSDefaultAttributes },
{ 0, 0, 0 },
};
cd.className = "Scratchpad";
diff --git a/src/scripts.h b/src/scripts.h
index f1beb70f..a6ab6244 100644
--- a/src/scripts.h
+++ b/src/scripts.h
@@ -69,6 +69,8 @@ void scripts_execute_scripts(char **scripts);
DwbStatus scripts_eval_key(KeyMap *m, Arg *arg);
gboolean scripts_execute_one(const char *script);
void scripts_completion_activate(void);
+void scripts_scratchpad_send(JSContextRef ctx, JSValueRef val);
+void scripts_scratchpad_get(JSContextRef, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef* );
#define EMIT_SCRIPT(sig) ((dwb.misc.script_signals & (1<<SCRIPTS_SIG_##sig)))
#define SCRIPTS_EMIT_RETURN(signal, json) G_STMT_START \