summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorportix <none@none>2012-06-13 11:29:05 +0200
committerportix <none@none>2012-06-13 11:29:05 +0200
commit03b7926b7cb5dc1903103c20b53b455cd41b8837 (patch)
tree3a3de12e4140c11718994e4dc3e9733454d00d63 /src
parent8d425fedae986a184d77d4afe8a28098568530d7 (diff)
downloaddwb-03b7926b7cb5dc1903103c20b53b455cd41b8837.zip
New function tabComplete
Diffstat (limited to 'src')
-rw-r--r--src/completion.c12
-rw-r--r--src/dwb.c2
-rw-r--r--src/dwb.h4
-rw-r--r--src/js.c13
-rw-r--r--src/js.h10
-rw-r--r--src/scripts.c68
-rw-r--r--src/scripts.h1
7 files changed, 110 insertions, 0 deletions
diff --git a/src/completion.c b/src/completion.c
index 7f3d65a5..a9201eed 100644
--- a/src/completion.c
+++ b/src/completion.c
@@ -349,6 +349,17 @@ completion_create_key_completion(GList *l, const char *first, KeyMap *m) {
return l;
}/*}}}*/
+static GList *
+completion_complete_scripts() {
+ GList *list = NULL;
+ for (GList *l = dwb.state.script_completion; l; l=l->next) {
+ Completion *c = completion_get_completion_item(((Navigation*)l->data)->first, ((Navigation*)l->data)->second, NULL, NULL);
+ gtk_box_pack_start(GTK_BOX(dwb.gui.compbox), c->event, false, false, 0);
+ list = g_list_append(list, c);
+ }
+ dwb.state.mode = COMPLETE_SCRIPTS;
+ return list;
+}
/*dwb_completion_get_keys() return GList *Completions{{{*/
static GList *
completion_get_key_completion(gboolean entry) {
@@ -563,6 +574,7 @@ completion_complete(CompletionType type, int back) {
case COMP_QUICKMARK: dwb.comps.completions = completion_get_quickmarks(back); break;
case COMP_PATH: completion_path(); return STATUS_OK;
case COMP_BUFFER: dwb.comps.completions = completion_complete_buffer(); break;
+ case COMP_SCRIPT: dwb.comps.completions = completion_complete_scripts(); break;
default: dwb.comps.completions = completion_get_normal_completion(); break;
}
if (!dwb.comps.completions) {
diff --git a/src/dwb.c b/src/dwb.c
index ec59f00f..eee064f7 100644
--- a/src/dwb.c
+++ b/src/dwb.c
@@ -2215,6 +2215,8 @@ dwb_entry_activate(GdkEventKey *e) {
return true;
case COMPLETE_PATH: completion_clean_path_completion();
break;
+ case COMPLETE_SCRIPTS: scripts_completion_activate();
+ return true;
default : break;
}
CLEAR_COMMAND_TEXT();
diff --git a/src/dwb.h b/src/dwb.h
index f8bd0253..d869a353 100644
--- a/src/dwb.h
+++ b/src/dwb.h
@@ -227,6 +227,7 @@ typedef enum {
COMP_CUR_HISTORY,
COMP_BUFFER,
COMP_QUICKMARK,
+ COMP_SCRIPT,
} CompletionType;
typedef enum {
@@ -334,6 +335,7 @@ typedef enum {
COMPLETE_COMMAND_MODE = 1<<19,
CONFIRM = 1<<21,
SETTINGS_MODE_LOCAL = 1<<22,
+ COMPLETE_SCRIPTS = 1<<23,
} Mode;
@@ -583,6 +585,7 @@ struct _State {
gboolean fullscreen;
unsigned int bar_visible;
gboolean auto_insert_mode;
+ GList *script_completion;
};
typedef enum _SettingsApply {
@@ -742,6 +745,7 @@ struct _Misc {
TabPosition tab_position;
char *hint_style;
int script_signals;
+
};
struct _Files {
const char *bookmarks;
diff --git a/src/js.c b/src/js.c
index ce90cd51..412f66f2 100644
--- a/src/js.c
+++ b/src/js.c
@@ -265,4 +265,17 @@ js_execute(JSContextRef ctx, const char *script, JSValueRef *exc) {
}
return NULL;
}
+void
+js_array_iterator_init(JSContextRef ctx, js_array_iterator *iter, JSObjectRef object) {
+ iter->ctx = ctx;
+ iter->array = object;
+ iter->current_index = 0;
+ iter->length = js_get_double_property(ctx, object, "length");
+}
+JSValueRef
+js_array_iterator_next(js_array_iterator *iter, JSValueRef *exc) {
+ if (iter->current_index == iter->length)
+ return NULL;
+ return JSObjectGetPropertyAtIndex(iter->ctx, iter->array, iter->current_index++, exc);
+}
diff --git a/src/js.h b/src/js.h
index cf7d83f5..a51cb911 100644
--- a/src/js.h
+++ b/src/js.h
@@ -35,6 +35,16 @@ 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);
+
+typedef struct _js_array_iterator {
+ JSContextRef ctx;
+ JSObjectRef array;
+ int current_index;
+ int length;
+} js_array_iterator;
+void js_array_iterator_init(JSContextRef ctx, js_array_iterator *iter, JSObjectRef object);
+JSValueRef js_array_iterator_next(js_array_iterator *iter, JSValueRef *exc);
+
#define JS_STRING_MAX 1024
#endif
diff --git a/src/scripts.c b/src/scripts.c
index f5ade2af..e40a13a5 100644
--- a/src/scripts.c
+++ b/src/scripts.c
@@ -29,6 +29,8 @@
#include "soup.h"
#include "domain.h"
#include "application.h"
+#include "completion.h"
+#include "entry.h"
//#define kJSDefaultFunction (kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete )
#define kJSDefaultProperty (kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly )
#define kJSDefaultAttributes (kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly )
@@ -147,6 +149,8 @@ static JSGlobalContextRef _global_context;
static GSList *_script_list;
static JSClassRef _webview_class, _frame_class, _download_class, _default_class, _download_class;
static gboolean _commandline = false;
+static JSObjectRef _arrayConstructor;
+static JSObjectRef _completion_callback;
/* MISC {{{*/
/* uncamelize {{{*/
@@ -720,7 +724,65 @@ global_send_request_sync(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject
JSStringRelease(js_key);
return o;
}
+void
+scripts_completion_activate(void) {
+ const char *text = GET_TEXT();
+ JSValueRef val[] = { js_char_to_value(_global_context, text) };
+ JSObjectCallAsFunction(_global_context, _completion_callback, NULL, 1, val, NULL);
+ completion_clean_completion(false);
+ dwb_change_mode(NORMAL_MODE, true);
+}
+static JSValueRef
+global_tab_complete(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exc) {
+ if (argc < 3 || !JSValueIsInstanceOfConstructor(ctx, argv[1], _arrayConstructor, exc)) {
+ js_make_exception(ctx, exc, EXCEPTION("tabComplete: invalid argument."));
+ return JSValueMakeUndefined(ctx);
+ }
+ _completion_callback = JSValueToObject(ctx, argv[2], exc);
+ if (_completion_callback == NULL)
+ return JSValueMakeUndefined(ctx);
+ if (!JSObjectIsFunction(ctx, _completion_callback)) {
+ js_make_exception(ctx, exc, EXCEPTION("tabComplete: arguments[2] is not a function."));
+ return JSValueMakeUndefined(ctx);
+ }
+
+ char *left, *right, *label;
+ js_array_iterator iter;
+ JSValueRef val;
+ JSObjectRef cur = NULL;
+ Navigation *n;
+ label = js_value_to_char(ctx, argv[0], JS_STRING_MAX, exc);
+ JSObjectRef o = JSValueToObject(ctx, argv[1], exc);
+ js_array_iterator_init(ctx, &iter, o);
+ while((val = js_array_iterator_next(&iter, exc))) {
+ cur = JSValueToObject(ctx, val, exc);
+ if (cur == NULL)
+ goto error_out;
+ left = js_get_string_property(ctx, cur, "left");
+ right = js_get_string_property(ctx, cur, "right");
+ n = g_malloc(sizeof(Navigation));
+ n->first = left;
+ n->second = right;
+ dwb.state.script_completion = g_list_prepend(dwb.state.script_completion, n);
+ }
+ dwb.state.script_completion = g_list_reverse(dwb.state.script_completion);
+ dwb_set_status_bar_text(dwb.gui.lstatus, label, NULL, NULL, true);
+
+ completion_complete(COMP_SCRIPT, false);
+ entry_focus();
+error_out:
+ for (GList *l = dwb.state.script_completion; l; l=l->next) {
+ n = l->data;
+ g_free(n->first);
+ g_free(n->second);
+ g_free(n);
+ }
+ g_free(label);
+ g_list_free(dwb.state.script_completion);
+ dwb.state.script_completion = NULL;
+ return JSValueMakeUndefined(ctx);
+}
/* timeout_callback {{{*/
static gboolean
timeout_callback(JSObjectRef obj) {
@@ -1452,6 +1514,7 @@ create_global_object() {
{ "domainFromHost", global_domain_from_host, kJSDefaultAttributes },
{ "sendRequest", global_send_request, kJSDefaultAttributes },
{ "sendRequestSync", global_send_request_sync, kJSDefaultAttributes },
+ { "tabComplete", global_tab_complete, kJSDefaultAttributes },
{ 0, 0, 0 },
};
@@ -1659,6 +1722,7 @@ scripts_init(gboolean force) {
else
return;
}
+ dwb.state.script_completion = NULL;
char *dir = util_get_data_dir(LIBJS_DIR);
if (dir != NULL) {
@@ -1672,6 +1736,9 @@ scripts_init(gboolean force) {
g_string_free(content, true);
g_free(dir);
}
+ JSObjectRef o = JSObjectMakeArray(_global_context, 0, NULL, NULL);
+ _arrayConstructor = js_get_object_property(_global_context, o, "constructor");
+ JSValueProtect(_global_context, _arrayConstructor);
}/*}}}*/
void
@@ -1708,6 +1775,7 @@ scripts_unbind(JSObjectRef obj) {
void
scripts_end() {
if (_global_context != NULL) {
+ JSValueUnprotect(_global_context, _arrayConstructor);
JSClassRelease(_default_class);
JSClassRelease(_webview_class);
JSClassRelease(_frame_class);
diff --git a/src/scripts.h b/src/scripts.h
index 3871fe7b..4a096ba7 100644
--- a/src/scripts.h
+++ b/src/scripts.h
@@ -67,6 +67,7 @@ void scripts_unbind(JSObjectRef);
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);
#define EMIT_SCRIPT(sig) ((dwb.misc.script_signals & (1<<SCRIPTS_SIG_##sig)))
#define SCRIPTS_EMIT_RETURN(signal, json) G_STMT_START \