diff options
-rw-r--r-- | README | 13 | ||||
-rw-r--r-- | examples/config/config | 6 | ||||
-rw-r--r-- | examples/data/scripts/formfiller.js | 9 | ||||
-rwxr-xr-x | examples/data/scripts/formfiller.sh | 20 | ||||
-rw-r--r-- | extras/vim/syntax/uzbl.vim | 4 | ||||
-rw-r--r-- | src/commands.c | 121 | ||||
-rw-r--r-- | src/commands.h | 3 | ||||
-rw-r--r-- | src/uzbl-core.c | 4 | ||||
-rw-r--r-- | src/variables.c | 100 | ||||
-rw-r--r-- | src/variables.h | 8 | ||||
-rw-r--r-- | tests/test-command.c | 49 |
11 files changed, 256 insertions, 81 deletions
@@ -141,6 +141,7 @@ The following commands are recognized: - argument can be `begin`, `end`, or an amount given in pixels(?) or as a percentage of the size of the view - set the amount to 100% to scroll a whole page + - argument can be appended with a `!` to scroll absolutely * `reload` - Reload the current page. * `reload_ign_cache` @@ -151,11 +152,6 @@ The following commands are recognized: - Increase the zoom level. * `zoom_out` - Decrease the zoom level. -* `toggle_zoom_type` - - Toggles the variable `zoom_type` between "full-content" and "text-only" - zoom. In "text-only" zoom, only the text of the page is zoomed, while in - "full-content" zoom, images and other page elements are zoomed along with - the text. * `uri <address>` - Attempt to load `<address>`. This is equivalent to `set uri = <address>`. * `js <body>` @@ -163,8 +159,6 @@ The following commands are recognized: - Remember that the commands must not contain line breaks. * `script <file>` - Execute the JavaScript in `<file>`. -* `toggle_status` - - Toggle the display of the status bar. * `spawn <executable> <additional args>` TODO explain path-alike expansion - Runs a command; see EXTERNAL SCRIPTS for details. - `$PATH` is searched, so giving the full path to commands is not necessary. @@ -201,6 +195,11 @@ The following commands are recognized: the status bar react immediately. - If you want to unset a string, use `set` with one space after the equals sign. +* `toggle <var> [possibilities]` + - Cycles the variable `var` through the list of options given in + `possibilities`. + - If `possibilities` are not given and the variable is an int or a float, + toggles between 0 and 1. * `dump_config` - Dumps the current config (which may have been changed at runtime) to stdout. - Uses a format which can be piped into `uzbl` again or saved as a config diff --git a/examples/config/config b/examples/config/config index e061e12..d295347 100644 --- a/examples/config/config +++ b/examples/config/config @@ -238,6 +238,8 @@ set ebind = @mode_bind global,-insert @cbind ^ = scroll horizontal begin @cbind $ = scroll horizontal end @cbind <Space> = scroll vertical end +@cbind G<Go To:>_ = scroll vertical %r! +@cbind _G<Go To:>_ = scroll horizontal %r! # Navigation binds @cbind b = back @@ -249,12 +251,12 @@ set ebind = @mode_bind global,-insert # Zoom binds @cbind + = zoom_in @cbind - = zoom_out -@cbind T = toggle_zoom_type +@cbind T = toggle zoom_type @cbind 1 = set zoom_level = 1.0 @cbind 2 = set zoom_level = 2.0 # Appearance binds -@cbind t = toggle_status +@cbind t = toggle show_status # Page searching binds @cbind /* = search %s diff --git a/examples/data/scripts/formfiller.js b/examples/data/scripts/formfiller.js index 1b10db4..06db648 100644 --- a/examples/data/scripts/formfiller.js +++ b/examples/data/scripts/formfiller.js @@ -29,6 +29,9 @@ uzbl.formfiller = { for( var k = 0; k < inputs.length; ++k ) { var input = inputs[k]; + if ( ! input.name ) { + continue + } if ( uzbl.formfiller.inputTypeIsText(input.type) ) { rv += '%' + escape(input.name) + '(' + input.type + '):' + input.value + '\n'; } else if ( input.type == 'checkbox' || input.type == 'radio' ) { @@ -39,8 +42,10 @@ uzbl.formfiller = { var textareas = allFrames[j].document.getElementsByTagName("textarea"); for( var k = 0; k < textareas.length; ++k ) { var textarea = textareas[k]; - rv += '%' + escape(textarea.name) + '(textarea):\n' + textarea.value.replace(/\n%/g,"\n\\%") + '\n%\n'; - rv += '%' + escape(textarea.name) + '(textarea):\n' + textarea.value.replace(/\n\\/g,"\n\\\\").replace(/\n%/g,"\n\\%") + '%\n'; + if ( ! textarea.name ) { + continue + } + rv += '%' + escape(textarea.name) + '(textarea):\n' + textarea.value.replace(/(^|\n)\\/g,"$1\\\\").replace(/(^|\n)%/g,"$1\\%") + '\n%\n'; } } catch (err) { } diff --git a/examples/data/scripts/formfiller.sh b/examples/data/scripts/formfiller.sh index 394bfbd..52d6ec6 100755 --- a/examples/data/scripts/formfiller.sh +++ b/examples/data/scripts/formfiller.sh @@ -63,6 +63,9 @@ ParseFields () awk '/^%/ { sub ( /%/, "" ) + gsub ( /\\/, "\\\\\\\\" ) + gsub ( /@/, "\\@" ) + gsub ( /"/, "\\\"" ) split( $0, parts, /\(|\)|\{|\}/ ) @@ -73,15 +76,24 @@ ParseFields () printf( "js uzbl.formfiller.insert(\"%s\",\"%s\",\"%s\",%s);\n", parts[1], parts[2], parts[3], field ) - else if ( parts[2] ~ /^textarea$/ ) { + else if ( parts[2] == "textarea" ) { field = "" while (getline) { if ( /^%/ ) break sub ( /^\\/, "" ) + # JavaScript escape + gsub ( /\\/, "\\\\\\\\" ) gsub ( /"/, "\\\"" ) - gsub ( /\\/, "\\\\" ) - field = field $0 "\\\\n" + # To support the possibility of the last line of the textarea + # not being terminated by a newline, we add the newline here. + # The "if (field)" is so that this does not happen in the first + # iteration. + if (field) field = field "\\n" + field = field $0 } + # Uzbl escape + gsub ( /\\/, "\\\\\\\\", field ) + gsub ( /@/, "\\@", field ) printf( "js uzbl.formfiller.insert(\"%s\",\"%s\",\"%s\",0);\n", parts[1], parts[2], field ) } @@ -120,7 +132,6 @@ Load () ParseProfile $option < "$file" \ | ParseFields \ - | sed 's/@/\\@/g' \ > "$UZBL_FIFO" } @@ -136,7 +147,6 @@ Once () test -e "$tmpfile" && ParseFields < "$tmpfile" \ - | sed 's/@/\\@/g' \ > "$UZBL_FIFO" } diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim index 1a4172b..2cb4006 100644 --- a/extras/vim/syntax/uzbl.vim +++ b/extras/vim/syntax/uzbl.vim @@ -26,8 +26,8 @@ elseif exists("b:current_syntax") endif syn keyword uzblKeyword back forward scroll reload reload_ign_cache stop -syn keyword uzblKeyword zoom_in zoom_out toggle_zoom_type uri script -syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh sync_spawn_exec +syn keyword uzblKeyword zoom_in zoom_out toggle uri script +syn keyword uzblKeyword spawn sync_spawn sync_sh sync_spawn_exec syn keyword uzblKeyword exit search search_reverse search_clear dehilight set syn keyword uzblKeyword dump_config dump_config_as_events chain print event syn keyword uzblKeyword request menu_add menu_link_add menu_image_add diff --git a/src/commands.c b/src/commands.c index ff3b15f..032bb4a 100644 --- a/src/commands.c +++ b/src/commands.c @@ -18,11 +18,9 @@ CommandInfo cmdlist[] = { "stop", view_stop_loading, 0 }, { "zoom_in", view_zoom_in, 0 }, //Can crash (when max zoom reached?). { "zoom_out", view_zoom_out, 0 }, - { "toggle_zoom_type", toggle_zoom_type, 0 }, { "uri", load_uri, TRUE }, { "js", run_js, TRUE }, { "script", run_external_js, 0 }, - { "toggle_status", toggle_status, 0 }, { "spawn", spawn_async, 0 }, { "sync_spawn", spawn_sync, 0 }, { "sync_spawn_exec", spawn_sync_exec, 0 }, // needed for load_cookies.sh :( @@ -34,6 +32,7 @@ CommandInfo cmdlist[] = { "search_clear", search_clear, TRUE }, { "dehilight", dehilight, 0 }, { "set", set_var, TRUE }, + { "toggle", toggle_var, 0 }, { "dump_config", act_dump_config, 0 }, { "dump_config_as_events", act_dump_config_as_events, 0 }, { "chain", chain, 0 }, @@ -96,26 +95,11 @@ VIEWFUNC(go_back) VIEWFUNC(go_forward) #undef VIEWFUNC -void -toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result) { - (void)page; (void)argv; (void)result; - - int current_type = get_zoom_type(); - set_zoom_type(!current_type); -} - -void -toggle_status (WebKitWebView* page, GArray *argv, GString *result) { - (void)page; (void)argv; (void)result; - - int current_status = get_show_status(); - set_show_status(!current_status); -} - /* * scroll vertical 20 * scroll vertical 20% * scroll vertical -40 + * scroll vertical 20! * scroll vertical begin * scroll vertical end * scroll horizontal 10 @@ -164,6 +148,107 @@ set_var(WebKitWebView *page, GArray *argv, GString *result) { g_strfreev(split); } +void +toggle_var(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + + if(!argv_idx(argv, 0)) + return; + + const gchar *var_name = argv_idx(argv, 0); + + uzbl_cmdprop *c = get_var_c(var_name); + + switch(c->type) { + case TYPE_STR: + { + const gchar *next; + + if(argv->len >= 3) { + gchar *current = get_var_value_string_c(c); + + guint i = 2; + const gchar *first = argv_idx(argv, 1); + const gchar *this = first; + next = argv_idx(argv, 2); + + while(next && strcmp(current, this)) { + this = next; + next = argv_idx(argv, ++i); + } + + if(!next) + next = first; + + g_free(current); + } else + next = ""; + + set_var_value_string_c(c, next); + break; + } + case TYPE_INT: + { + int current = get_var_value_int_c(c); + int next; + + if(argv->len >= 3) { + guint i = 2; + + int first = strtoul(argv_idx(argv, 1), NULL, 10); + int this = first; + + const gchar *next_s = argv_idx(argv, 2); + + while(next_s && this != current) { + this = strtoul(next_s, NULL, 10); + next_s = argv_idx(argv, ++i); + } + + if(next_s) + next = strtoul(next_s, NULL, 10); + else + next = first; + } else + next = !current; + + set_var_value_int_c(c, next); + break; + } + case TYPE_FLOAT: + { + float current = get_var_value_float_c(c); + float next; + + if(argv->len >= 3) { + guint i = 2; + + float first = strtod(argv_idx(argv, 1), NULL); + float this = first; + + const gchar *next_s = argv_idx(argv, 2); + + while(next_s && this != current) { + this = strtod(next_s, NULL); + next_s = argv_idx(argv, ++i); + } + + if(next_s) + next = strtod(next_s, NULL); + else + next = first; + } else + next = !current; + + set_var_value_float_c(c, next); + break; + } + default: + g_assert_not_reached(); + } + + send_set_var_event(var_name, c); +} void event(WebKitWebView *page, GArray *argv, GString *result) { diff --git a/src/commands.h b/src/commands.h index b8cf095..c39b541 100644 --- a/src/commands.h +++ b/src/commands.h @@ -58,10 +58,9 @@ void delete_cookie(WebKitWebView *page, GArray *argv, GString *result); void clear_cookies(WebKitWebView *pag, GArray *argv, GString *result); void download(WebKitWebView *pag, GArray *argv, GString *result); void set_var(WebKitWebView *page, GArray *argv, GString *result); +void toggle_var(WebKitWebView *page, GArray *argv, GString *result); void run_js (WebKitWebView * web_view, GArray *argv, GString *result); void run_external_js (WebKitWebView * web_view, GArray *argv, GString *result); -void toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result); -void toggle_status (WebKitWebView* page, GArray *argv, GString *result); void act_dump_config(WebKitWebView* page, GArray *argv, GString *result); void act_dump_config_as_events(WebKitWebView* page, GArray *argv, GString *result); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index c3bc2dd..e70b5e7 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -331,11 +331,15 @@ scroll(GtkAdjustment* bar, gchar *amount_str) { if (*end == '%') value += page_size * amount * 0.01; + else if (*end == '!') + value = amount; else value += amount; max_value = gtk_adjustment_get_upper(bar) - page_size; + if (value < 0) + value = 0; /* don't scroll past the beginning of the page */ if (value > max_value) value = max_value; /* don't scroll past the end of the page */ diff --git a/src/variables.c b/src/variables.c index 3bd941b..ed76f95 100644 --- a/src/variables.c +++ b/src/variables.c @@ -5,6 +5,11 @@ #include "io.h" #include "util.h" +uzbl_cmdprop * +get_var_c(const gchar *name) { + return g_hash_table_lookup(uzbl.behave.proto_var, name); +} + void send_set_var_event(const char *name, const uzbl_cmdprop *c) { /* check for the variable type */ @@ -41,8 +46,8 @@ send_set_var_event(const char *name, const uzbl_cmdprop *c) { void expand_variable(GString *buf, const gchar *name) { - uzbl_cmdprop* c; - if((c = g_hash_table_lookup(uzbl.behave.proto_var, name))) { + uzbl_cmdprop* c = get_var_c(name); + if(c) { if(c->type == TYPE_STR) { gchar *v = get_var_value_string_c(c); g_string_append(buf, v); @@ -54,50 +59,59 @@ expand_variable(GString *buf, const gchar *name) { } } +void +set_var_value_string_c(uzbl_cmdprop *c, const gchar *val) { + if(c->setter) + ((void (*)(const gchar *))c->setter)(val); + else { + g_free(*(c->ptr.s)); + *(c->ptr.s) = g_strdup(val); + } +} + +void +set_var_value_int_c(uzbl_cmdprop *c, int i) { + if(c->setter) + ((void (*)(int))c->setter)(i); + else + *(c->ptr.i) = i; +} + +void +set_var_value_float_c(uzbl_cmdprop *c, float f) { + if(c->setter) + ((void (*)(float))c->setter)(f); + else + *(c->ptr.f) = f; +} + gboolean set_var_value(const gchar *name, gchar *val) { - uzbl_cmdprop *c = NULL; - g_assert(val != NULL); - if( (c = g_hash_table_lookup(uzbl.behave.proto_var, name)) ) { + uzbl_cmdprop *c = get_var_c(name); + + if(c) { if(!c->writeable) return FALSE; - if(c->setter) { - switch(c->type) { - case TYPE_STR: - ((void (*)(const gchar *))c->setter)(val); - break; - case TYPE_INT: - { - int i = (int)strtoul(val, NULL, 10); - ((void (*)(int))c->setter)(i); - break; - } - case TYPE_FLOAT: - { - float f = strtod(val, NULL); - ((void (*)(float))c->setter)(f); - break; - } - default: - g_assert_not_reached(); - } - } else { - switch(c->type) { - case TYPE_STR: - g_free(*(c->ptr.s)); - *(c->ptr.s) = g_strdup(val); - break; - case TYPE_INT: - *(c->ptr.i) = (int)strtoul(val, NULL, 10); - break; - case TYPE_FLOAT: - *(c->ptr.f) = strtod(val, NULL); - break; - default: - g_assert_not_reached(); - } + switch(c->type) { + case TYPE_STR: + set_var_value_string_c(c, val); + break; + case TYPE_INT: + { + int i = (int)strtoul(val, NULL, 10); + set_var_value_int_c(c, i); + break; + } + case TYPE_FLOAT: + { + float f = strtod(val, NULL); + set_var_value_float_c(c, f); + break; + } + default: + g_assert_not_reached(); } send_set_var_event(name, c); @@ -148,7 +162,7 @@ get_var_value_string_c(const uzbl_cmdprop *c) { gchar* get_var_value_string(const gchar *name) { - uzbl_cmdprop *c = g_hash_table_lookup(uzbl.behave.proto_var, name); + uzbl_cmdprop *c = get_var_c(name); return get_var_value_string_c(c); } @@ -166,7 +180,7 @@ get_var_value_int_c(const uzbl_cmdprop *c) { int get_var_value_int(const gchar *name) { - uzbl_cmdprop *c = g_hash_table_lookup(uzbl.behave.proto_var, name); + uzbl_cmdprop *c = get_var_c(name); return get_var_value_int_c(c); } @@ -184,7 +198,7 @@ get_var_value_float_c(const uzbl_cmdprop *c) { float get_var_value_float(const gchar *name) { - uzbl_cmdprop *c = g_hash_table_lookup(uzbl.behave.proto_var, name); + uzbl_cmdprop *c = get_var_c(name); return get_var_value_float_c(c); } diff --git a/src/variables.h b/src/variables.h index 4f85474..dade652 100644 --- a/src/variables.h +++ b/src/variables.h @@ -10,6 +10,8 @@ #include "type.h" +uzbl_cmdprop *get_var_c(const gchar *name); + gboolean set_var_value(const gchar *name, gchar *val); void expand_variable(GString *buf, const gchar *name); void variables_hash(); @@ -21,6 +23,12 @@ int get_var_value_int(const char *name); float get_var_value_float_c(const uzbl_cmdprop *c); float get_var_value_float(const char *name); +void set_var_value_string_c(uzbl_cmdprop *c, const gchar *val); +void set_var_value_int_c(uzbl_cmdprop *c, int f); +void set_var_value_float_c(uzbl_cmdprop *c, float f); + +void send_set_var_event(const char *name, const uzbl_cmdprop *c); + void dump_config(); void dump_config_as_events(); diff --git a/tests/test-command.c b/tests/test-command.c index b6a1063..b3c3d0c 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -308,6 +308,51 @@ test_no_such_command (void) { /* if we didn't crash then we're ok! */ } +// TODO: test toggling emits an event +void +test_toggle_int (void) { + g_assert_cmpint(0, ==, uzbl.behave.forward_keys); + + parse_cmd_line("toggle forward_keys", NULL); + g_assert_cmpint(1, ==, uzbl.behave.forward_keys); + + parse_cmd_line("toggle forward_keys", NULL); + g_assert_cmpint(0, ==, uzbl.behave.forward_keys); + + // if cycle values are specified it should use those + parse_cmd_line("toggle forward_keys 1 2", NULL); + g_assert_cmpint(1, ==, uzbl.behave.forward_keys); + + parse_cmd_line("toggle forward_keys 1 2", NULL); + g_assert_cmpint(2, ==, uzbl.behave.forward_keys); + + // and wrap to the first value when it reaches the end. + parse_cmd_line("toggle forward_keys 1 2", NULL); + g_assert_cmpint(1, ==, uzbl.behave.forward_keys); +} + +void +test_toggle_string (void) { + parse_cmd_line("set useragent = something interesting", NULL); + g_assert_cmpstr("something interesting", ==, uzbl.net.useragent); + + // when something was set, it gets reset + parse_cmd_line("toggle useragent", NULL); + g_assert_cmpstr("", ==, uzbl.net.useragent); + + // if cycle values are specified it should use those + parse_cmd_line("set useragent = something interesting", NULL); + parse_cmd_line("toggle useragent 'x' 'y'", NULL); + g_assert_cmpstr("x", ==, uzbl.net.useragent); + + parse_cmd_line("toggle useragent 'x' 'y'", NULL); + g_assert_cmpstr("y", ==, uzbl.net.useragent); + + // and wrap to the first value when it reaches the end. + parse_cmd_line("toggle useragent 'x' 'y'", NULL); + g_assert_cmpstr("x", ==, uzbl.net.useragent); +} + int main (int argc, char *argv[]) { /* set up tests */ @@ -329,6 +374,10 @@ main (int argc, char *argv[]) { g_test_add_func("/test-command/no-such-command", test_no_such_command); + g_test_add_func("/test-command/toggle-int", test_toggle_int); + // we should probably test toggle float, but meh. + g_test_add_func("/test-command/toggle-string", test_toggle_string); + /* set up uzbl */ initialize(argc, argv); |