diff options
author | portix <none@none> | 2012-06-13 11:29:05 +0200 |
---|---|---|
committer | portix <none@none> | 2012-06-13 11:29:05 +0200 |
commit | 03b7926b7cb5dc1903103c20b53b455cd41b8837 (patch) | |
tree | 3a3de12e4140c11718994e4dc3e9733454d00d63 /src | |
parent | 8d425fedae986a184d77d4afe8a28098568530d7 (diff) | |
download | dwb-03b7926b7cb5dc1903103c20b53b455cd41b8837.zip |
New function tabComplete
Diffstat (limited to 'src')
-rw-r--r-- | src/completion.c | 12 | ||||
-rw-r--r-- | src/dwb.c | 2 | ||||
-rw-r--r-- | src/dwb.h | 4 | ||||
-rw-r--r-- | src/js.c | 13 | ||||
-rw-r--r-- | src/js.h | 10 | ||||
-rw-r--r-- | src/scripts.c | 68 | ||||
-rw-r--r-- | src/scripts.h | 1 |
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) { @@ -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(); @@ -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; @@ -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); +} @@ -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 \ |