diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | Makefile | 55 | ||||
-rw-r--r-- | README | 30 | ||||
-rw-r--r-- | docs/INSTALL | 1 | ||||
-rw-r--r-- | examples/config/config | 45 | ||||
-rwxr-xr-x | examples/data/scripts/cookies.sh | 154 | ||||
-rwxr-xr-x | examples/data/scripts/download.sh | 2 | ||||
-rw-r--r-- | examples/data/scripts/extedit.js | 102 | ||||
-rw-r--r-- | examples/data/scripts/follower.js | 420 | ||||
-rwxr-xr-x | examples/data/scripts/formfiller.pl | 99 | ||||
-rwxr-xr-x | examples/data/scripts/formfiller.sh | 169 | ||||
-rw-r--r-- | examples/data/scripts/hint.js | 26 | ||||
-rwxr-xr-x | examples/data/scripts/instance-select-wmii.sh | 2 | ||||
-rw-r--r-- | examples/data/scripts/linkfollow.js | 269 | ||||
-rw-r--r-- | examples/data/scripts/scroll-percentage.js | 68 | ||||
-rwxr-xr-x | examples/data/scripts/uzbl-tabbed | 154 | ||||
-rwxr-xr-x | examples/data/scripts/uzblcat | 1 | ||||
-rw-r--r-- | src/callbacks.c | 19 | ||||
-rw-r--r-- | src/callbacks.h | 3 | ||||
-rw-r--r-- | src/events.c | 7 | ||||
-rw-r--r-- | src/events.h | 2 | ||||
-rw-r--r-- | src/uzbl-core.c | 12 | ||||
-rw-r--r-- | src/uzbl-core.h | 8 | ||||
-rw-r--r-- | tests/test-expand.c | 7 |
24 files changed, 269 insertions, 1387 deletions
@@ -53,6 +53,7 @@ In alphabetical order: Moritz Lenz - small doc fix Nicolas Pouillard - refactored scroll command Olivier Schwander - auto file:// prepend + Paul Tomak - eFormFiller Paweł Zuzelski (pawelz) - http auth handler, misc patches Peter Suschlik - backwards searching Přemysl Hrubý (anydot) <email is dfenze AT gmail.com> - several C contributions and cleanups @@ -8,33 +8,21 @@ LDFLAGS!=echo `pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0` -p SRC = $(wildcard src/*.c) HEAD = $(wildcard src/*.h) -TOBJ = $(SRC:.c=.o) -OBJ = $(foreach obj, $(TOBJ), $(notdir $(obj))) +OBJ = $(foreach obj, $(SRC:.c=.o), $(notdir $(obj))) -all: uzbl-browser options - -options: - @echo - @echo BUILD OPTIONS: - @echo "CFLAGS = ${CFLAGS}" - @echo "LDFLAGS = ${LDFLAGS}" - @echo - @echo See the README file for usage instructions. +all: uzbl-browser +VPATH:=src .c.o: - @echo COMPILING $< + @echo -e "${CC} -c ${CFLAGS} $<" @${CC} -c ${CFLAGS} $< - @echo ... done. ${OBJ}: ${HEAD} -uzbl-core: ${TOBJ} # why doesn't ${OBJ} work? - @echo - @echo LINKING object files +uzbl-core: ${OBJ} + @echo -e "\n${CC} -o $@ ${OBJ} ${LDFLAGS}" @${CC} -o $@ ${OBJ} ${LDFLAGS} - @echo ... done. - uzbl-browser: uzbl-core @@ -43,6 +31,7 @@ uzbl-browser: uzbl-core # RUN_PREFIX : what the prefix is when the software is run. usually the same as PREFIX PREFIX?=/usr/local INSTALLDIR?=$(DESTDIR)$(PREFIX) +DOCDIR?=$(INSTALLDIR)/share/uzbl/docs RUN_PREFIX?=$(PREFIX) # the 'tests' target can never be up to date @@ -50,7 +39,7 @@ RUN_PREFIX?=$(PREFIX) force: # When compiling unit tests, compile uzbl as a library first -tests: ${TOBJ} force +tests: ${OBJ} force $(CC) -shared -Wl ${OBJ} -o ./tests/libuzbl-core.so cd ./tests/; $(MAKE) @@ -99,28 +88,26 @@ strip: install: install-uzbl-core install-uzbl-browser install-uzbl-tabbed install-uzbl-core: all - install -d $(INSTALLDIR)/bin - install -d $(INSTALLDIR)/share/uzbl/docs - install -d $(INSTALLDIR)/share/uzbl/examples - cp -rp docs $(INSTALLDIR)/share/uzbl/ - cp -rp src/config.h $(INSTALLDIR)/share/uzbl/docs/ - cp -rp examples $(INSTALLDIR)/share/uzbl/ - install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core - install -m644 AUTHORS $(INSTALLDIR)/share/uzbl/docs - install -m644 README $(INSTALLDIR)/share/uzbl/docs + install -d $(INSTALLDIR)/share/uzbl/ + install -d $(DOCDIR) + install -m644 docs/* $(DOCDIR)/ + install -m644 src/config.h $(DOCDIR)/ + install -m644 README $(DOCDIR)/ + install -m644 AUTHORS $(DOCDIR)/ + cp -r examples $(INSTALLDIR)/share/uzbl/ + chmod 755 $(INSTALLDIR)/share/uzbl/examples/data/scripts/* sed -i 's#^set prefix.*=.*#set prefix = $(RUN_PREFIX)#' $(INSTALLDIR)/share/uzbl/examples/config/config + install -D -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core install-uzbl-browser: - install -d $(INSTALLDIR)/bin - install -m755 src/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser - install -m755 examples/data/scripts/uzbl-cookie-daemon $(INSTALLDIR)/bin/uzbl-cookie-daemon - install -m755 examples/data/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager + install -D -m755 src/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser + install -D -m755 examples/data/scripts/uzbl-cookie-daemon $(INSTALLDIR)/bin/uzbl-cookie-daemon + install -D -m755 examples/data/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager sed -i 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' $(INSTALLDIR)/bin/uzbl-browser sed -i "s#^PREFIX = .*#PREFIX = '$(RUN_PREFIX)'#" $(INSTALLDIR)/bin/uzbl-event-manager install-uzbl-tabbed: - install -d $(INSTALLDIR)/bin - install -m755 examples/data/scripts/uzbl-tabbed $(INSTALLDIR)/bin/uzbl-tabbed + install -D -m755 examples/data/scripts/uzbl-tabbed $(INSTALLDIR)/bin/uzbl-tabbed # you probably only want to do this manually when testing and/or to the sandbox. not meant for distributors install-example-data: @@ -523,6 +523,32 @@ The script specific arguments are: Custom, userdefined scripts (`spawn foo bar`) get first the arguments as specified in the config and then the above 7 are added at the end. +### eFormFiller + +Example config entries for eFormFiller scripts + + set eFormFiller = spawn @scripts_dir/eFormFiller.sh + @cbind za = @eFormFiller add + @cbind ze = @eFormFiller edit + @cbind zn = @eFormFiller new + @cbind zl = @eFormFiller load + @cbind zo = @eFormFiller once + +NEW action generates new file with formfields for current domain. Note that it +will overwrite existing file. + +EDIT action calls an external editor with curent domain profiles. + +ADD action adds another profile to current domain. Remember to name the +profiles, by default the have a name with random numbers. + +LOAD action loads form data. If there is more then one profile, it will call +dmenu first to choose the profile you want to fill in the form. + +ONCE action generates a temp file with formfields including the textareas and +after closing the editor, it will load the data into the formfields. The temp +file is removed + ### HTTP/BASIC AUTHENTICATION You can use the authentication_handler variable to denote how http @@ -689,8 +715,8 @@ Events/requests which the EM and its plugins listens for return/enter. If the user enters text where `<string>` has the underscore, `%s` in the `<command>` string will be replaced by this text (optional). - `<keycmd>` ends with a `*`: similar behavior as with an underscore, but also - makes the binding incremental (i.e. the command will be invoked on every - keystroke). + makes the binding incremental (i.e. the command will be invoked after + reaching the `*` point then on every subsequent keystroke). - `<keycmd>` ends with a `!`: the command will only be invoked after pressing return/enter, no replacement happens. this is useful for preventing `x` to match when you want to bind `xx` also. diff --git a/docs/INSTALL b/docs/INSTALL index c795502..61a40e3 100644 --- a/docs/INSTALL +++ b/docs/INSTALL @@ -43,7 +43,6 @@ Dependencies which are optional for uzbl-core are marked with an asterisk. (i.e. * pango [*] * pygtk [*] * pygobject [*] -* python-simplejson [*] Make dependencies ----------------- diff --git a/examples/config/config b/examples/config/config index e01611e..a3e1db2 100644 --- a/examples/config/config +++ b/examples/config/config @@ -48,7 +48,7 @@ set authentication_handler = sync_spawn @scripts_dir/auth.py # Open in the same window. #set new_window = sh 'echo uri "$8" > $4' # Open a link in a new window. equivalent to default behavior -set new_window = sh 'uzbl-browser -u $8' +set new_window = sh 'uzbl-browser -u "$8"' # --- Optional dynamic event handlers ---------------------------------------- @@ -62,7 +62,6 @@ set new_window = sh 'uzbl-browser -u $8' # Load commit handlers @on_event LOAD_COMMIT @set_status <span foreground="green">recv</span> -#@on_event LOAD_COMMIT script @scripts_dir/scroll-percentage.js # Load finish handlers @on_event LOAD_FINISH @set_status <span foreground="gold">done</span> @@ -120,7 +119,7 @@ set title_format_long = \@keycmd_prompt \@raw_modcmd \@raw_keycmd \@TITLE - Uzbl # === Core settings ========================================================== -set useragent = Uzbl (Webkit @WEBKIT_MAJOR.@WEBKIT_MINOR.@WEBKIT_MICRO) (@(+uname -o)@ @(+uname -m)@ [@ARCH_UZBL]) (Commit @COMMIT) +set useragent = Uzbl (Webkit @WEBKIT_MAJOR.@WEBKIT_MINOR.@WEBKIT_MICRO) (@(+uname -s)@ @(+uname -m)@ [@ARCH_UZBL]) (Commit @COMMIT) set fifo_dir = /tmp set socket_dir = /tmp @@ -159,11 +158,13 @@ set ebind = @mode_bind global,-insert # === Global & keycmd editing binds ========================================== # Resets keycmd and returns to default mode. -@bind <Escape> = @set_mode +@on_event ESCAPE @set_mode +@bind <Escape> = event ESCAPE +@bind <Ctrl>] = event ESCAPE # Commands for editing and traversing the keycmd. @ebind <Return> = event KEYCMD_EXEC_CURRENT -@ebind <Home> = event SET_CURSOR_POS +@ebind <Home> = event SET_CURSOR_POS 0 @ebind <End> = event SET_CURSOR_POS -1 @ebind <Left> = event SET_CURSOR_POS - @ebind <Right> = event SET_CURSOR_POS + @@ -267,8 +268,9 @@ set preset = event PRESET_TABS @cbind ZZ = exit # Dump config to stdout @cbind !dump = sh "echo dump_config > $4" -# Reload config -@cbind !reload = sh "sed '/^# === Post-load misc commands/,$d' $1 > $4" +# Reload all variables in the config +@cbind !reload = sh "sed '/^# === Post-load misc commands/,$d' $1 | grep '^set ' > $4" + # Use socat to directly inject commands into uzbl-core and view events # raised by uzbl-core: @cbind <Ctrl><Alt>t = sh 'xterm -e "socat unix-connect:$5 -"' @@ -320,26 +322,15 @@ set follow_hint_keys = 0123456789 @cbind fl* = script @scripts_dir/follow.js '@follow_hint_keys %s' # --- Form filler binds --- -# this script allows you to configure (per domain) values to fill in form -# fields (eg login information) and to fill in these values automatically -set formfiller = spawn @scripts_dir/formfiller -@cbind za = @{formfiller}.sh -@cbind ze = @{formfiller}.sh edit -@cbind zn = @{formfiller}.sh new -@cbind zl = @{formfiller}.sh load -# Or the more advanced implementation using perl: (could not get this to run - Dieter) -@cbind LL = @{formfiller}.pl load -@cbind LN = @{formfiller}.pl new -@cbind LE = @{formfiller}.pl edit - -# --- External edit script configuration & binds --- -# Edit form input fields in an external editor (gvim, emacs, urxvt -e vim, ..) -# disabled since Uzbl object is gone -set external_editor = gvim -#set external_editor = xterm -e vim -#@cbind E = script @scripts_dir/extedit.js -# And add menu option. -#menu_editable_add Open in @external_editor = script @scripts_dir/extedit.js +# This script allows you to configure (per domain) values to fill in form +# fields (eg login information) and to fill in these values automatically. +# This implementation allows you to save multiple profiles for each form +# (think about multiple accounts on some website). +set formfiller = spawn @scripts_dir/formfiller.sh +@cbind za = @formfiller add +@cbind ze = @formfiller edit +@cbind zn = @formfiller new +@cbind zl = @formfiller load # --- Examples --- # Example showing how to use uzbl's fifo to execute a command. diff --git a/examples/data/scripts/cookies.sh b/examples/data/scripts/cookies.sh deleted file mode 100755 index ee2ce51..0000000 --- a/examples/data/scripts/cookies.sh +++ /dev/null @@ -1,154 +0,0 @@ -#!/bin/sh - -set -n; - -# THIS IS EXPERIMENTAL AND COULD BE INSECURE !!!!!! - -# this is an example bash script of how you could manage your cookies. it is very raw and basic and not as good as uzbl-cookie-daemon -# we use the cookies.txt format (See http://kb.mozillazine.org/Cookies.txt) -# This is one textfile with entries like this: -# kb.mozillazine.org FALSE / FALSE 1146030396 wikiUserID 16993 -# domain alow-read-other-subdomains path http-required expiration name value -# you probably want your cookies config file in your $XDG_CONFIG_HOME ( eg $HOME/.config/uzbl/cookies) -# Note. in uzbl there is no strict definition on what a session is. it's YOUR job to clear cookies marked as end_session if you want to keep cookies only valid during a "session" -# MAYBE TODO: allow user to edit cookie before saving. this cannot be done with zenity :( -# TODO: different cookie paths per config (eg per group of uzbl instances) - -# TODO: correct implementation. -# see http://curl.haxx.se/rfc/cookie_spec.html -# http://en.wikipedia.org/wiki/HTTP_cookie - -# TODO : check expires= before sending. -# write sample script that cleans up cookies dir based on expires attribute. -# TODO: check uri against domain attribute. and path also. -# implement secure attribute. -# support blocking or not for 3rd parties -# http://kb.mozillazine.org/Cookies.txt -# don't always append cookies, sometimes we need to overwrite - -cookie_config=${XDG_CONFIG_HOME:-${HOME}/.config}/uzbl/cookies -[ "x$cookie_config" = x ] && exit 1 -[ -d "${XDG_DATA_HOME:-${HOME}/.local/share}/uzbl/" ] &&\ -cookie_data=${XDG_DATA_HOME:-${HOME}/.local/share}/uzbl/cookies.txt || exit 1 - -notifier= -#notifier=notify-send -#notify_wrapper () { -# echo "$@" >> $HOME/cookielog -#} -#notifier=notifier_wrapper - -# if this variable is set, we will use it to inform you when and which cookies we store, and when/which we send. -# it's primarily used for debugging -notifier= -which zenity &>/dev/null || exit 2 - -# Example cookie: -# test_cookie=CheckForPermission; expires=Thu, 07-May-2009 19:17:55 GMT; path=/; domain=.doubleclick.net - -# uri=$6 -# uri=${uri/http:\/\/} # strip 'http://' part -# host=${uri/\/*/} -action=$8 # GET/PUT -shift -host=$9 -shift -path=$9 -shift -cookie=$9 - -field_domain=$host -field_path=$path -field_name= -field_value= -field_exp='end_session' - -notify() { - [ -n "$notifier" ] && $notifier "$@" -} - - -# FOR NOW LETS KEEP IT SIMPLE AND JUST ALWAYS PUT AND ALWAYS GET -parse_cookie() { - IFS=$';' - first_pair=1 - for pair in $cookie - do - if [ "x$first_pair" = x1 ] - then - field_name=${pair%%=*} - field_value=${pair#*=} - first_pair=0 - else - echo "$pair" | read -r pair #strip leading/trailing wite space - key=${pair%%=*} - val=${pair#*=} - [ "$key" == expires ] && field_exp=`date -u -d "$val" +'%s'` - # TODO: domain - [ "$key" == path ] && field_path=$val - fi - done - unset IFS -} - -# match cookies in cookies.txt against hostname and path -get_cookie() { - path_esc=${path//\//\\/} - search="^[^\t]*$host\t[^\t]*\t$path_esc" - cookie=`awk "/$search/" $cookie_data 2>/dev/null | tail -n 1` - if [ -z "$cookie" ] - then - notify "Get_cookie: search: $search in $cookie_data -> no result" - false - else - notify "Get_cookie: search: $search in $cookie_data -> result: $cookie" - echo "$cookie" | \ - read domain alow_read_other_subdomains path http_required expiration name \ - value; - cookie="$name=$value" - true - fi -} - -save_cookie() { - if parse_cookie - then - data="$field_domain\tFALSE\t$field_path\tFALSE\t$field_exp\t$field_name\t$field_value" - notify "save_cookie: adding $data to $cookie_data" - echo -e "$data" >> $cookie_data - else - notify "not saving a cookie. since we don't have policies yet, parse_cookie must have returned false. this is a bug" - fi -} - -[ "x$action" = xPUT ] && save_cookie -[ "x$action" = xGET ] && get_cookie && echo "$cookie" - -exit - - -# TODO: implement this later. -# $1 = section (TRUSTED or DENY) -# $2 =url -match() { - sed -n "/$1/,/^\$/p" $cookie_config 2>/dev/null | grep -q "^$host" -} - -fetch_cookie() { - cookie=`cat $cookie_data` -} - -store_cookie() { - echo $cookie > $cookie_data -} - -if match TRUSTED $host -then - [ "x$action" = xPUT ] && store_cookie $host - [ "x$action" = xGET ] && fetch_cookie && echo "$cookie" -elif ! match DENY $host -then - [ "x$action" = xPUT ] && cookie=`zenity --entry --title 'Uzbl Cookie handler' --text "Accept this cookie from $host ?" --entry-text="$cookie"` && store_cookie $host - [ "x$action" = xGET ] && fetch_cookie && cookie=`zenity --entry --title 'Uzbl Cookie handler' --text "Submit this cookie to $host ?" --entry-text="$cookie"` && echo $cookie -fi -exit 0 diff --git a/examples/data/scripts/download.sh b/examples/data/scripts/download.sh index 1c7d039..f6d34e9 100755 --- a/examples/data/scripts/download.sh +++ b/examples/data/scripts/download.sh @@ -3,7 +3,7 @@ # try some pattern matching on the uri to determine what we should do # Some sites block the default wget --user-agent.. -GET="wget --user-agent=Firefox" +GET="wget --user-agent=Firefox --content-disposition --load-cookies=$XDG_DATA_HOME/uzbl/cookies.txt" dest="$HOME" url="$8" diff --git a/examples/data/scripts/extedit.js b/examples/data/scripts/extedit.js deleted file mode 100644 index 8ed346d..0000000 --- a/examples/data/scripts/extedit.js +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Edit forms in external editor - * - * (c) 2009, Robert Manea - * utf8 functions are (c) by Webtoolkit.info (http://www.webtoolkit.info/) - * - * - * Installation: - * - Copy this script to $HOME/.local/share/uzbl/scripts - * - Add the following to $HOME/.config/uzbl/config: - * @bind E = script @scripts_dir/extedit.js - * - Set your preferred editor - * set editor = gvim - * - non-GUI editors - * set editor = xterm -e vim - * - * Usage: - * Select (click) an editable form, go to command mode and hit E - * -*/ - - -function utf8_decode ( str_data ) { - var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0; - - str_data += ''; - - while ( i < str_data.length ) { - c1 = str_data.charCodeAt(i); - if (c1 < 128) { - tmp_arr[ac++] = String.fromCharCode(c1); - i++; - } else if ((c1 > 191) && (c1 < 224)) { - c2 = str_data.charCodeAt(i+1); - tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); - i += 2; - } else { - c2 = str_data.charCodeAt(i+1); - c3 = str_data.charCodeAt(i+2); - tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return tmp_arr.join(''); -} - - -function utf8_encode ( argString ) { - var string = (argString+''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n"); - - var utftext = ""; - var start, end; - var stringl = 0; - - start = end = 0; - stringl = string.length; - for (var n = 0; n < stringl; n++) { - var c1 = string.charCodeAt(n); - var enc = null; - - if (c1 < 128) { - end++; - } else if (c1 > 127 && c1 < 2048) { - enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128); - } else { - enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128); - } - if (enc !== null) { - if (end > start) { - utftext += string.substring(start, end); - } - utftext += enc; - start = end = n+1; - } - } - - if (end > start) { - utftext += string.substring(start, string.length); - } - - return utftext; -} - - -(function() { - var actelem = document.activeElement; - - if(actelem.type == 'text' || actelem.type == 'textarea') { - var editor = Uzbl.run("print @external_editor") || "gvim"; - var filename = Uzbl.run("print @(mktemp /tmp/uzbl_edit.XXXXXX)@"); - - if(actelem.value) - Uzbl.run("sh 'echo " + window.btoa(utf8_encode(actelem.value)) + " | base64 -d > " + filename + "'"); - - Uzbl.run("sync_sh '" + editor + " " + filename + "'"); - actelem.value = utf8_decode(window.atob(Uzbl.run("print @(base64 -w 0 " + filename + ")@"))); - - Uzbl.run("sh 'rm -f " + filename + "'"); - } - - })(); diff --git a/examples/data/scripts/follower.js b/examples/data/scripts/follower.js deleted file mode 100644 index 604b779..0000000 --- a/examples/data/scripts/follower.js +++ /dev/null @@ -1,420 +0,0 @@ -// A Link Follower for Uzbl. -// P.C. Shyamshankar <sykora@lucentbeing.com> -// -// WARNING: this script depends on the Uzbl object which is now disabled for -// WARNING security reasons. So the script currently doesn't work but it's -// WARNING interesting nonetheless -// -// Based extensively (like copy-paste) on the follow_numbers.js and -// linkfollow.js included with uzbl, but modified to be more customizable and -// extensible. -// -// Usage -// ----- -// -// First, you'll need to make sure the script is loaded on each page. This can -// be done with: -// -// @on_event LOAD_COMMIT script /path/to/follower.js -// -// Then you can bind it to a key: -// -// @bind f* = js follower.follow('%s', matchSpec, handler, hintStyler) -// -// where matchSpec, handler and hintStyler are parameters which control the -// operation of follower. If you don't want to customize any further, you can -// set these to follower.genericMatchSpec, follower.genericHandler and -// follower.genericHintStyler respectively. -// -// For example, -// -// @bind f* = js follower.follow('%s', follower.genericMatchSpec, follower.genericHandler, follower.genericHintStyler) -// @bind F* = js follower.follow('%s', follower.onlyLinksMatchSpec, follower.newPageHandler, follower.newPageHintStyler) -// -// In order to make hints disappear when pressing a key (the Escape key, for -// example), you can do this: -// -// @bind <Escape> = js follower.clearHints() -// -// If your Escape is already bound to something like command mode, chain it. -// -// Alternatively, you can tell your <Escape> key to emit an event, and handle -// that instead. -// -// @bind <Escape> = event ESCAPE -// @on_event ESCAPE js follower.clearHints() -// -// Customization -// ------------- -// -// If however you do want to customize, 3 Aspects of the link follower can be -// customized with minimal pain or alteration to the existing code base: -// -// * What elements are hinted. -// * The style of the hints displayed. -// * How the hints are handled. -// -// In order to customize behavior, write an alternative, and pass that in to -// follower.follow invocation. You _will_ have to modify this script, but only -// locally, it beats having to copy the entire script under a new name and -// modify. -// -// TODO: -// * Whatever all the other TODOs in the file say. -// * Find out how to do default arguments in Javascript. -// * Abstract out the hints into a Hint object, make hintables a list of hint -// objects instead of two lists. - -// Helpers -String.prototype.lpad = function(padding, length) { - var padded = this; - while (padded.length < length) { - padded = padding + padded; - } - - return padded; -} - -function Follower() { - - // Globals - var uzblID = 'uzbl-follow'; // ID to apply to each hint. - var uzblContainerID = 'uzbl-follow-container'; // ID to apply to the div containing hints. - - // Translation table, used to display something other than numbers as hint - // labels. Typically set to the ten keys of the home row. - // - // Must have exactly 10 elements. - // - // I haven't parameterized this, to make it customizable. Should I? Do - // people really use more than one set of keys at a time? - var translation = ["a", "r", "s", "t", "d", "h", "n", "e", "i", "o"]; - - // MatchSpecs - // These are XPath expressions which indicate which elements will be hinted. - // Use multiple expressions for different situations, like hinting only form - // elements, or only links, etc. - // - // TODO: Check that these XPath expressions are correct, and optimize/make - // them more elegant. Preferably by someone who actually knows XPath, unlike - // me. - - // Vimperator default (copy-pasted, I never used vimperator). - this.genericMatchSpec = " //*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href] | //input[not(@type='hidden')] | //a | //area | //iframe | //textarea | //button | //select"; - - // Matches only links, suitable for opening in a new instance (I think). - this.onlyLinksMatchSpec = " //*[@href] | //a | //area"; - - // Follow Handlers - // These decide how an element should be 'followed'. The handler is passed - // the element in question. - - // Generic Handler, opens links in the same instance, emits the FORM_ACTIVE - // event if a form element was chosen. Also clears the keycmd. - this.genericHandler = function(node) { - if (node) { - if (window.itemClicker != undefined) { - window.itemClicker(node); - } else { - var tag = node.tagName.toLowerCase(); - if (tag == 'a') { - node.click(); - window.location = node.href; - } else if (tag == 'input') { - var inputType = node.getAttribute('type'); - if (inputType == undefined) - inputType = 'text'; - - inputType = inputType.toLowerCase(); - - if (inputType == 'text' || inputType == 'file' || inputType == 'password') { - node.focus(); - node.select(); - } else { - node.click(); - } - Uzbl.run("event FORM_ACTIVE"); - } else if (tag == 'textarea'|| tag == 'select') { - node.focus(); - node.select(); - Uzbl.run("event FORM_ACTIVE"); - } else { - node.click(); - if ((node.href != undefined) && node.href) - window.location = node.href; - } - } - } - Uzbl.run("event SET_KEYCMD"); - } - - // Handler to open links in a new page. The rest is the same as before. - this.newPageHandler = function(node) { - if (node) { - if (window.itemClicker != undefined) { - window.itemClicker(node); - } else { - var tag = node.tagName.toLowerCase(); - if (tag == 'a') { - node.click(); - Uzbl.run("@new_window " + node.href); - } else if (tag == 'input') { - var inputType = node.getAttribute('type'); - if (inputType == undefined) - inputType = 'text'; - - inputType = inputType.toLowerCase(); - - if (inputType == 'text' || inputType == 'file' || inputType == 'password') { - node.focus(); - node.select(); - } else { - node.click(); - } - Uzbl.run("event FORM_ACTIVE"); - } else if (tag == 'textarea'|| tag == 'select') { - node.focus(); - node.select(); - Uzbl.run("event FORM_ACTIVE"); - } else { - node.click(); - if ((node.href != undefined) && node.href) - window.location = node.href; - } - } - } - Uzbl.run("event SET_KEYCMD"); - }; - - // Hint styling. - // Pretty much any attribute of the hint object can be modified here, but it - // was meant to change the styling. Useful to differentiate between hints - // with different handlers. - // - // Hint stylers are applied at the end of hint creation, so that they - // override the defaults. - - this.genericHintStyler = function(hint) { - hint.style.backgroundColor = '#AAAAAA'; - hint.style.border = '2px solid #4A6600'; - hint.style.color = 'black'; - hint.style.fontSize = '10px'; - hint.style.fontWeight = 'bold'; - hint.style.lineHeight = '12px'; - return hint; - }; - - this.newPageHintStyler = function(hint) { - hint.style.backgroundColor = '#FFCC00'; - hint.style.border = '2px solid #4A6600'; - hint.style.color = 'black'; - hint.style.fontSize = '10px'; - hint.style.fontWeight = 'bold'; - hint.style.lineHeight = '12px'; - return hint; - }; - - // Beyond lies a jungle of pasta and verbosity. - - // Translate a numeric label using the translation table. - function translate(digitLabel, translationTable) { - translatedLabel = ''; - for (var i = 0; i < digitLabel.length; i++) { - translatedLabel += translationTable[digitLabel.charAt(i)]; - } - - return translatedLabel; - } - - function computeElementPosition(element) { - var up = element.offsetTop; - var left = element.offsetLeft; - var width = element.offsetWidth; - var height = element.offsetHeight; - - while (element.offsetParent) { - element = element.offsetParent; - up += element.offsetTop; - left += element.offsetLeft; - } - - return {up: up, left: left, width: width, height: height}; - } - - // Pretty much copy-pasted from every other link following script. - function isInViewport(element) { - offset = computeElementPosition(element); - - var up = offset.up; - var left = offset.left; - var width = offset.width; - var height = offset.height; - - return up < window.pageYOffset + window.innerHeight && - left < window.pageXOffset + window.innerWidth && - (up + height) > window.pageYOffset && - (left + width) > window.pageXOffset; - } - - function isVisible(element) { - if (element == document) { - return true; - } - - if (!element){ - return false; - } - - if (element.style) { - if (element.style.display == 'none' || element.style.visibiilty == 'hidden') { - return false; - } - } - - return isVisible(element.parentNode); - } - - function generateHintContainer() { - var container = document.getElementById(uzblContainerID); - if (container) { - container.parentNode.removeChild(container); - } - - container = document.createElement('div'); - container.id = uzblContainerID; - - if (document.body) { - document.body.appendChild(container); - } - return container; - } - - // Generate everything that is to be hinted, as per the given matchSpec. - // hintables[0] refers to the items, hintables[1] to their labels. - function generateHintables(matchSpec) { - var hintables = [[], []]; - - var itemsFromXPath = document.evaluate(matchSpec, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - - for (var i = 0; i < itemsFromXPath.snapshotLength; ++i) { - var element = itemsFromXPath.snapshotItem(i); - if (element && isVisible(element) && isInViewport(element)) { - hintables[0].push(element); - } - } - - // Assign labels to each hintable. Can't be combined with the previous - // step, because we didn't know how many there were at that time. - var hintLength = hintables.length; - for (var i = 0; i < hintables[0].length; ++i) { - var code = translate(i.toString(), translation); - hintables[1].push(code.lpad(translation[0], hintLength)); - } - - return hintables; - } - - // Filter the hintables based on input from the user. Makes the screen less - // cluttered after the user has typed some prefix of hint labels. - function filterHintables(hintables, target) { - var filtered = [[], []]; - - var targetPattern = new RegExp("^" + target); - - for (var i = 0; i < hintables[0].length; i++) { - if (hintables[1][i].match(targetPattern)) { - filtered[0].push(hintables[0][i]); - filtered[1].push(hintables[1][i].substring(target.length)); - } - } - - return filtered; - } - - // TODO make this use the container variable from main, instead of searching - // for it? - function clearHints() { - var container = document.getElementById(uzblContainerID); - if (container) { - container.parentNode.removeChild(container); - } - } - - // So that we can offer this as a separate function. - this.clearHints = clearHints; - - function makeHint(node, code, styler) { - var position = computeElementPosition(node); - var hint = document.createElement('div'); - - hint.name = uzblID; - hint.innerText = code; - hint.style.display = 'inline'; - - hint.style.margin = '0px'; - hint.style.padding = '1px'; - hint.style.position = 'absolute'; - hint.style.zIndex = '10000'; - - hint.style.left = position.left + 'px'; - hint.style.top = position.up + 'px'; - - var img = node.getElementsByTagName('img'); - if (img.length > 0) { - hint.style.left = position.left + img[0].width / 2 + 'px'; - } - - hint.style.textDecoration = 'none'; - hint.style.webkitBorderRadius = '6px'; - hint.style.webkitTransform = 'scale(1) rotate(0deg) translate(-6px, -5px)'; - - hint = styler(hint); // So that custom hint stylers can override the above. - return hint; - } - - - function drawHints(container, hintables, styler) { - for (var i = 0; i < hintables[0].length; i++) { - hint = makeHint(hintables[0][i], hintables[1][i], styler); - container.appendChild(hint); - } - - if (document.body) { - document.body.appendChild(container); - } - } - - // The main hinting function. I don't know how to do default values to - // functions, so all arguments must be specified. Use generics if you must. - this.follow = function(target, matchSpec, handler, hintStyler) { - var container = generateHintContainer(); // Get a container to hold all hints. - var allHintables = generateHintables(matchSpec); // Get all items that can be hinted. - hintables = filterHintables(allHintables, target); // Filter them based on current input. - - clearHints(); // Clear existing hints, if any. - - if (hintables[0].length == 0) { - // Nothing was hinted, user pressed an unknown key, maybe? - // Do nothing. - } else if (hintables[0].length == 1) { - handler(hintables[0][0]); // Only one hint remains, handle it. - } else { - drawHints(container, hintables, hintStyler); // Draw whatever hints remain. - } - - return; - }; -} - -// Make on-click links clickable. -try { - HTMLElement.prototype.click = function() { - if (typeof this.onclick == 'function') { - this.onclick({ - type: 'click' - }); - } - }; -} catch(e) {} - -follower = new Follower(); diff --git a/examples/data/scripts/formfiller.pl b/examples/data/scripts/formfiller.pl deleted file mode 100755 index 74dcc80..0000000 --- a/examples/data/scripts/formfiller.pl +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/perl - -# a slightly more advanced form filler -# -# uses settings file like: $keydir/<domain> -#TODO: fallback to $HOME/.local/share -# user arg 1: -# edit: force editing of the file (fetches if file is missing) -# load: fill forms from file (fetches if file is missing) -# new: fetch new file - -# usage example: -# bind LL = spawn /usr/share/uzbl/examples/data/scripts/formfiller.pl load -# bind LN = spawn /usr/share/uzbl/examples/data/scripts/formfiller.pl new -# bind LE = spawn /usr/share/uzbl/examples/data/scripts/formfiller.pl edit - -use strict; -use warnings; - -my $keydir = $ENV{XDG_CONFIG_HOME} . "/uzbl/forms"; -my ($config,$pid,$xid,$fifoname,$socket,$url,$title,$cmd) = @ARGV; -if (!defined $fifoname || $fifoname eq "") { die "No fifo"; } - -sub domain { - my ($url) = @_; - $url =~ s#http(s)?://([A-Za-z0-9\.-]+)(/.*)?#$2#; - return $url; -}; - -my $editor = "xterm -e vim"; -#my $editor = "gvim"; - -# ideally, there would be some way to ask uzbl for the html content instead of having to redownload it with -# Also, you may need to fake the user-agent on some sites (like facebook) - my $downloader = "curl -A 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042810 GranParadiso/3.0.10' "; -#my $downloader = "curl -s"; - -my @fields = ("type","name","value"); - -my %command; - -$command{load} = sub { - my ($domain) = @_; - my $filename = "$keydir/$domain"; - if (-e $filename){ - open(my $file, $filename) or die "Failed to open $filename: $!"; - my (@lines) = <$file>; - close($file); - $|++; - open(my $fifo, ">>", $fifoname) or die "Failed to open $fifoname: $!"; - foreach my $line (@lines) { - next if ($line =~ m/^#/); - my ($type,$name,$value) = ($line =~ /^\s*(\w+)\s*\|\s*(.*?)\s*\|\s*(.*?)\s*$/); - if ($type eq "checkbox") - { - printf $fifo 'js document.getElementsByName("%s")[0].checked = %s;', $name, $value; - } elsif ($type eq "submit") - { - printf $fifo 'js function fs (n) {try{n.submit()} catch (e){fs(n.parentNode)}}; fs(document.getElementsByName("%s")[0]);', $name; - } elsif ($type ne "") - { - printf $fifo 'js document.getElementsByName("%s")[0].value = "%s";', $name, $value; - } - print $fifo "\n"; - } - $|--; - } else { - $command{new}->($domain); - $command{edit}->($domain); - } -}; -$command{edit} = sub { - my ($domain) = @_; - my $file = "$keydir/$domain"; - if(-e $file){ - system ($editor, $file); - } else { - $command{new}->($domain); - } -}; -$command{new} = sub { - my ($domain) = @_; - my $filename = "$keydir/$domain"; - open (my $file,">>", $filename) or die "Failed to open $filename: $!"; - $|++; - print $file "# Make sure that there are no extra submits, since it may trigger the wrong one.\n"; - printf $file "#%-10s | %-10s | %s\n", @fields; - print $file "#------------------------------\n"; - my @data = `$downloader $url`; - foreach my $line (@data){ - if($line =~ m/<input ([^>].*?)>/i){ - $line =~ s/.*(<input ([^>].*?)>).*/$1/; - printf $file " %-10s | %-10s | %s\n", map { my ($r) = $line =~ /.*$_=["'](.*?)["']/;$r } @fields; - }; - }; - $|--; -}; - -$command{$cmd}->(domain($url)); diff --git a/examples/data/scripts/formfiller.sh b/examples/data/scripts/formfiller.sh index 10afaba..1408006 100755 --- a/examples/data/scripts/formfiller.sh +++ b/examples/data/scripts/formfiller.sh @@ -1,62 +1,159 @@ -#!/bin/bash - -# simple html form (eg for logins) filler (and manager) for uzbl. +#!/bin/sh +# +# Enhanced html form (eg for logins) filler (and manager) for uzbl. +# # uses settings files like: $keydir/<domain> -# files contain lines like: <fieldname>: <value> - - +# files contain lines like: !profile=<profile_name> +# <fieldname>(fieldtype): <value> +# profile_name should be replaced with a name that will tell sth about that profile +# fieldtype can be text or password - only for information pupropse (auto-generated) - don't change that +# # user arg 1: # edit: force editing the file (falls back to new if not found) # new: start with a new file. # load: try to load from file into form - +# add: try to add another profile to an existing file +# # something else (or empty): if file not available: new, otherwise load. -keydir=${XDG_DATA_HOME:-$HOME/.local/share}/uzbl/forms +# config dmenu colors and prompt +NB="#0f0f0f" +NF="#4e7093" +SB="#003d7c" +SF="#3a9bff" + +if [ "`dmenu --help 2>&1| grep lines`x" != "x" ] +then + LINES=" -l 3 " +else + LINES="" +fi + +PROMPT="Choose profile" + +keydir=${XDG_DATA_HOME:-$HOME/.local/share}/uzbl/dforms + [ -d "`dirname $keydir`" ] || exit 1 [ -d "$keydir" ] || mkdir "$keydir" editor=${VISUAL} -if [[ -z ${editor} ]]; then - #editor='gvim' - editor='urxvt -e vim' +if [ -z ${editor} ]; then + if [ -z ${EDITOR} ]; then + editor='xterm -e vim' + else + editor="xterm -e ${EDITOR}" + fi fi -config=$1; shift -pid=$1; shift -xid=$1; shift -fifo=$1; shift -socket=$1; shift -url=$1; shift -title=$1; shift +config=$1; +shift +pid=$1; +shift +xid=$1; +shift +fifo=$1; +shift +socket=$1; +shift +url=$1; +shift +title=$1; +shift action=$1 [ -d $keydir ] || mkdir $keydir || exit 1 -if [ "$action" != 'edit' -a "$action" != 'new' -a "$action" != 'load' ] +domain=$(echo $url | sed 's/\(http\|https\):\/\/\([^\/]\+\)\/.*/\2/') + +if [ "$action" != 'edit' -a "$action" != 'new' -a "$action" != 'load' -a "$action" != 'add' -a "$action" != 'once' ] then - action=new - [[ -e $keydir/$domain ]] && action=load -elif [ "$action" == 'edit' ] && [[ ! -e $keydir/$domain ]] + action="new" + [ -e "$keydir/$domain" ] && action="load" +elif [ "$action" == 'edit' ] && [ ! -e "$keydir/$domain" ] then - action=new + action="new" fi -domain=$(echo $url | sed -re 's|(http\|https)+://([A-Za-z0-9\.]+)/.*|\2|') +if [ "$action" = 'load' ] +then + [ -e $keydir/$domain ] || exit 2 + if [ `cat $keydir/$domain|grep "!profile"|wc -l` -gt 1 ] + then + menu=`cat $keydir/$domain| \ + sed -n 's/^!profile=\([^[:blank:]]\+\)/\1/p'` + option=`echo -e -n "$menu"| dmenu ${LINES} -nb "${NB}" -nf "${NF}" -sb "${SB}" -sf "${SF}" -p "${PROMPT}"` + fi -#regex='s|.*<input.*?name="([[:graph:]]+)".*?/>.*|\1: |p' # sscj's first version, does not work on http://wiki.archlinux.org/index.php?title=Special:UserLogin&returnto=Main_Page - regex='s|.*<input.*?name="([^"]*)".*|\1: |p' #works on arch wiki, but not on http://lists.uzbl.org/listinfo.cgi/uzbl-dev-uzbl.org TODO: improve + cat $keydir/$domain | \ + sed -n -e "/^!profile=${option}/,/^!profile=/p" | \ + sed -n -e 's/\([^(]\+\)([^)]\+):[ ]*\(.\+\)$/js if(window.frames.length > 0) { for(i=0;i<window.frames.length;i=i+1) { try { var e = window.frames[i].document.getElementsByName("\1"); if(e.length > 0) { e[0].value="\2"; } } catch(err) { } } }; document.getElementsByName("\1")[0].value="\2"/p' | \ + sed -e 's/@/\\@/g' >> $fifo +elif [ "$action" = "once" ] +then + tmpfile=`mktemp` + html=`echo 'js if(window.frames.length > 0) { for(j=0;j<window.frames.length;j=j+1) { try { window.frames[j].document.documentElement.outerHTML; } catch(err) { } } }' | \ + socat - unix-connect:$socket` + html=${html}" "`echo 'js document.documentElement.outerHTML' | \ + socat - unix-connect:$socket` + html=`echo ${html} | \ + tr -d '\n' | \ + sed 's/>/>\n/g' | \ + sed 's/<input/<input type="text"/g' | \ + sed 's/type="text"\(.*\)type="\([^"]\+\)"/type="\2" \1 /g'` + echo "${html}" | \ + sed -n 's/.*\(<input[^>]\+>\).*/\1/;/type="\(password\|text\)"/Ip' | \ + sed 's/\(.*\)\(type="[^"]\+"\)\(.*\)\(name="[^"]\+"\)\(.*\)/\1\4\3\2\5/I' | \ + sed 's/.*name="\([^"]\+\)".*type="\([^"]\+\)".*/\1(\2):/I' >> $tmpfile + echo "${html}" | \ + sed -n 's/.*<textarea.*name="\([^"]\+\)".*/\1(textarea):/Ip' >> $tmpfile + ${editor} $tmpfile + [ -e $tmpfile ] || exit 2 -if [ "$action" = 'load' ] -then - [[ -e $keydir/$domain ]] || exit 2 - gawk -F': ' '{ print "js document.getElementsByName(\"" $1 "\")[0].value = \"" $2 "\";"}' $keydir/$domain >> $fifo + cat $tmpfile | \ + sed -n -e 's/\([^(]\+\)([^)]\+):[ ]*\(.\+\)/js if(window.frames.length > 0) { for(i=0;i<window.frames.length;i=i+1) { try { var e = window.frames[i].document.getElementsByName("\1"); if(e.length > 0) { e[0].value="\2" } } catch(err) { } } }; document.getElementsByName("\1")[0].value="\2"/p' | \ + sed -e 's/@/\\@/g' >> $fifo + rm -f $tmpfile else - if [ "$action" == 'new' ] - then - curl "$url" | grep '<input' | sed -nre "$regex" > $keydir/$domain - fi - [[ -e $keydir/$domain ]] || exit 3 #this should never happen, but you never know. - $editor $keydir/$domain #TODO: if user aborts save in editor, the file is already overwritten + if [ "$action" == 'new' -o "$action" == 'add' ] + then + if [ "$action" == 'new' ] + then + echo "!profile=NAME_THIS_PROFILE$RANDOM" > $keydir/$domain + else + echo "!profile=NAME_THIS_PROFILE$RANDOM" >> $keydir/$domain + fi + # + # 2. and 3. line (tr -d and sed) are because, on gmail login for example, + # <input > tag is splited into lines + # ex: + # <input name="Email" + # type="text" + # value=""> + # So, tr removes all new lines, and sed inserts new line after each > + # Next sed selects only <input> tags and only with type == "text" or == "password" + # If type is first and name is second, then another sed will change their order + # so the last sed will make output + # text_from_the_name_attr(text or password): + # + # login(text): + # passwd(password): + # + html=`echo 'js if(window.frames.length > 0) { for(i=0;i<window.frames.length;i=i+1) { try { window.frames[i].document.documentElement.outerHTML; } catch(err) { } } }' | \ + socat - unix-connect:$socket` + html=${html}" "`echo 'js document.documentElement.outerHTML' | \ + socat - unix-connect:$socket` + echo ${html} | \ + tr -d '\n' | \ + sed 's/>/>\n/g' | \ + sed 's/<input/<input type="text"/g' | \ + sed 's/type="text"\(.*\)type="\([^"]\+\)"/type="\2" \1 /g' | \ + sed -n 's/.*\(<input[^>]\+>\).*/\1/;/type="\(password\|text\)"/Ip' | \ + sed 's/\(.*\)\(type="[^"]\+"\)\(.*\)\(name="[^"]\+"\)\(.*\)/\1\4\3\2\5/I' | \ + sed 's/.*name="\([^"]\+\)".*type="\([^"]\+\)".*/\1(\2):/I' >> $keydir/$domain + fi + [ -e "$keydir/$domain" ] || exit 3 #this should never happen, but you never know. + $editor "$keydir/$domain" #TODO: if user aborts save in editor, the file is already overwritten fi + +# vim:fileencoding=utf-8:sw=4 diff --git a/examples/data/scripts/hint.js b/examples/data/scripts/hint.js deleted file mode 100644 index ec7f1e2..0000000 --- a/examples/data/scripts/hint.js +++ /dev/null @@ -1,26 +0,0 @@ -for (var i=0; i < document.links.length; i++) { - var uzblid = 'uzbl_link_hint_'; - var li = document.links[i]; - var pre = document.getElementById(uzblid+i); - - if (pre) { - li.removeChild(pre); - } else { - var hint = document.createElement('div'); - hint.setAttribute('id',uzblid+i); - hint.innerHTML = i; - hint.style.display='inline'; - hint.style.lineHeight='90%'; - hint.style.backgroundColor='red'; - hint.style.color='white'; - hint.style.fontSize='small-xx'; - hint.style.fontWeight='light'; - hint.style.margin='0px'; - hint.style.padding='2px'; - hint.style.position='absolute'; - hint.style.textDecoration='none'; - hint.style.left=li.style.left; - hint.style.top=li.style.top; - li.insertAdjacentElement('afterBegin',hint); - } -} diff --git a/examples/data/scripts/instance-select-wmii.sh b/examples/data/scripts/instance-select-wmii.sh index 2bf13ba..fdd27e6 100755 --- a/examples/data/scripts/instance-select-wmii.sh +++ b/examples/data/scripts/instance-select-wmii.sh @@ -6,7 +6,7 @@ # you can select one from a list, or go to the next/previous one # It does not change the layout (stacked/tiled/floating) nor does it # changes the size or viewing mode of a uzbl window -# When your current uzbl window is maximized, the one you change to +# When your current uzbl window is maximized, the one you change to # will be maximized as well. # See http://www.uzbl.org/wiki/wmii for more info # $1 must be one of 'list', 'next', 'prev' diff --git a/examples/data/scripts/linkfollow.js b/examples/data/scripts/linkfollow.js deleted file mode 100644 index 3109cda..0000000 --- a/examples/data/scripts/linkfollow.js +++ /dev/null @@ -1,269 +0,0 @@ -// link follower for uzbl -// requires http://github.com/DuClare/uzbl/commit/6c11777067bdb8aac09bba78d54caea04f85e059 -// -// first, it needs to be loaded before every time it is used. -// One way would be to use the load_commit_handler: -// set load_commit_handler = sh 'echo "script /usr/share/uzbl/examples/data/scripts/linkfollow.js" > "$4"' -// -// when script is loaded, it can be invoked with -// bind f* = js hints.set("%s", hints.open) -// bind f_ = js hints.follow("%s",hints.open) -// -// At the moment, it may be useful to have way of forcing uzbl to load the script -// bind :lf = script /usr/share/uzbl/examples/data/scripts/linkfollow.js -// -// The default style for the hints are pretty ugly, so it is recommended to add the following -// to config file -// set stylesheet_uri = /usr/share/uzbl/examples/data/style.css -// -// based on follow_Numbers.js -// -// TODO: fix styling for the first element -// TODO: emulate mouseover events when visiting some elements -// TODO: rewrite the element->action handling - - -function Hints(){ - - // Settings - //////////////////////////////////////////////////////////////////////////// - - // if set to true, you must explicitly call hints.follow(), otherwise it will - // follow the link if there is only one matching result - var requireReturn = true; - - // Case sensitivity flag - var matchCase = "i"; - - // For case sensitive matching, uncomment: - // var matchCase = ""; - - - var uzblid = 'uzbl_hint'; - var uzblclass = 'uzbl_highlight'; - var uzblclassfirst = 'uzbl_h_first'; - var doc = document; - var visible = []; - var hintdiv; - - this.set = hint; - this.follow = follow; - this.keyPressHandler = keyPressHandler; - - function elementPosition(el) { - var up = el.offsetTop; - var left = el.offsetLeft; var width = el.offsetWidth; - var height = el.offsetHeight; - - while (el.offsetParent) { - el = el.offsetParent; - up += el.offsetTop; - left += el.offsetLeft; - } - return {up: up, left: left, width: width, height: height}; - } - - function elementInViewport(p) { - return (p.up < window.pageYOffset + window.innerHeight && - p.left < window.pageXOffset + window.innerWidth && - (p.up + p.height) > window.pageYOffset && - (p.left + p.width) > window.pageXOffset); - } - - function isVisible(el) { - if (el == doc) { return true; } - if (!el) { return false; } - if (!el.parentNode) { return false; } - if (el.style) { - if (el.style.display == 'none') { - return false; - } - if (el.style.visibility == 'hidden') { - return false; - } - } - return isVisible(el.parentNode); - } - - // the vimperator defaults minus the xhtml elements, since it gave DOM errors - var hintable = " //*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @role='link' or @href] | //input[not(@type='hidden')] | //a | //area | //iframe | //textarea | //button | //select"; - - function Matcher(str){ - var numbers = str.replace(/[^\d]/g,""); - var words = str.replace(/\d/g,"").split(/\s+/).map(function (n) { return new RegExp(n,matchCase)}); - this.test = test; - this.toString = toString; - this.numbers = numbers; - function matchAgainst(element){ - if(element.node.nodeName == "INPUT"){ - return element.node.value; - } else { - return element.node.textContent; - } - } - function test(element) { - // test all the regexp - var item = matchAgainst(element); - return words.every(function (regex) { return item.match(regex)}); - } - } - - function HintElement(node,pos){ - - this.node = node; - this.isHinted = false; - this.position = pos; - this.num = 0; - - this.addHint = function (labelNum) { - // TODO: fix uzblclassfirst - if(!this.isHinted){ - this.node.className += " " + uzblclass; - } - this.isHinted = true; - - // create hint - var hintNode = doc.createElement('div'); - hintNode.name = uzblid; - hintNode.innerText = labelNum; - hintNode.style.left = this.position.left + 'px'; - hintNode.style.top = this.position.up + 'px'; - hintNode.style.position = "absolute"; - doc.body.firstChild.appendChild(hintNode); - - } - this.removeHint = function(){ - if(this.isHinted){ - var s = (this.num)?uzblclassfirst:uzblclass; - this.node.className = this.node.className.replace(new RegExp(" "+s,"g"),""); - this.isHinted = false; - } - } - } - - function createHintDiv(){ - var hintdiv = doc.getElementById(uzblid); - if(hintdiv){ - hintdiv.parentNode.removeChild(hintdiv); - } - hintdiv = doc.createElement("div"); - hintdiv.setAttribute('id',uzblid); - doc.body.insertBefore(hintdiv,doc.body.firstChild); - return hintdiv; - } - - function init(){ - // WHAT? - doc.body.setAttribute("onkeyup","hints.keyPressHandler(event)"); - hintdiv = createHintDiv(); - visible = []; - - var items = doc.evaluate(hintable,doc,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null); - for (var i = 0;i<items.snapshotLength;i++){ - var item = items.snapshotItem(i); - var pos = elementPosition(item); - if(isVisible && elementInViewport(elementPosition(item))){ - visible.push(new HintElement(item,pos)); - } - } - } - - function clear(){ - - visible.forEach(function (n) { n.removeHint(); } ); - hintdiv = doc.getElementById(uzblid); - while(hintdiv){ - hintdiv.parentNode.removeChild(hintdiv); - hintdiv = doc.getElementById(uzblid); - } - } - - function update(str,openFun) { - var match = new Matcher(str); - hintdiv = createHintDiv(); - var i = 1; - visible.forEach(function (n) { - if(match.test(n)) { - n.addHint(i); - i++; - } else { - n.removeHint(); - }}); - if(!requireReturn){ - if(i==2){ //only been incremented once - follow(str,openFun); - } - } - } - - function hint(str,openFun){ - if(str.length == 0) init(); - update(str,openFun); - } - - function keyPressHandler(e) { - var kC = window.event ? event.keyCode: e.keyCode; - var Esc = window.event ? 27 : e.DOM_VK_ESCAPE; - if (kC == Esc) { - clear(); - doc.body.removeAttribute("onkeyup"); - } - } - - this.openNewWindow = function(item){ - // TODO: this doesn't work yet - item.className += " uzbl_follow"; - window.open(item.href,"uzblnew",""); - } - this.open = function(item){ - simulateMouseOver(item); - item.className += " uzbl_follow"; - window.location = item.href; - } - - function simulateMouseOver(item){ - var evt = doc.createEvent("MouseEvents"); - evt.initMouseEvent("MouseOver",true,true, - doc.defaultView,1,0,0,0,0, - false,false,false,false,0,null); - return item.dispatchEvent(evt); - } - - - function follow(str,openFunction){ - var m = new Matcher(str); - var items = visible.filter(function (n) { return n.isHinted }); - clear(); - var num = parseInt(m.numbers,10); - if(num){ - var item = items[num-1].node; - } else { - var item = items[0].node; - } - if (item) { - var name = item.tagName; - if (name == 'A') { - if(item.click) {item.click()}; - openFunction(item); - } else if (name == 'INPUT') { - var type = item.getAttribute('type').toUpperCase(); - if (type == 'TEXT' || type == 'FILE' || type == 'PASSWORD') { - item.focus(); - item.select(); - } else { - item.click(); - } - } else if (name == 'TEXTAREA' || name == 'SELECT') { - item.focus(); - item.select(); - } else { - item.click(); - openFunction(item); - } - } - } -} - -var hints = new Hints(); - -// vim:set et sw=2: diff --git a/examples/data/scripts/scroll-percentage.js b/examples/data/scripts/scroll-percentage.js deleted file mode 100644 index c9a51aa..0000000 --- a/examples/data/scripts/scroll-percentage.js +++ /dev/null @@ -1,68 +0,0 @@ -// VIM ruler style scroll message -(function() { - var run = Uzbl.run; - var update_message = function() { - var innerHeight = window.innerHeight; - var scrollY = window.scrollY; - var height = document.height; - var message; - - if (UzblZoom.type === "full") { - var zoom_level = UzblZoom.level; - innerHeight = Math.ceil(innerHeight * zoom_level); - scrollY = Math.ceil(scrollY * zoom_level); - height -= 1; - } - - if (! height) { - message = ""; - } - else if (height <= innerHeight) { - message = run("print @scroll_all_indicator") || "All"; - } - else if (scrollY === 0) { - message = run("print @scroll_top_indicator") || "Top"; - } - else if (scrollY + innerHeight >= height) { - message = run("print @scroll_bottom_indicator") || "Bot"; - } - else { - var percentage = Math.round(scrollY / (height - innerHeight) * 100); - message = percentage + "%"; - } - run("set scroll_message=" + message); - }; - - self.UzblZoom = { - get level() { - return Number(run("print @zoom_level")) || 1; - }, - set level(level) { - if (typeof level === "number" && level > 0) { - run("set zoom_level = " + level); - update_message(); - } - }, - get type() { - return run("print @zoom_type") || "text"; - }, - set type(type) { - if ((type === "text" || type === "full") && this.type != type) { - run("toggle_zoom_type"); - run("set zoom_type = " + type); - update_message(); - } - }, - toggle_type: function() { - this.type = (this.type === "text" ? "full" : "text"); - } - }; - - window.addEventListener("DOMContentLoaded", update_message, false); - window.addEventListener("load", update_message, false); - window.addEventListener("resize", update_message, false); - window.addEventListener("scroll", update_message, false); - update_message(); -})(); - -// vim: set noet ff=unix diff --git a/examples/data/scripts/uzbl-tabbed b/examples/data/scripts/uzbl-tabbed index f07bae4..1597dd3 100755 --- a/examples/data/scripts/uzbl-tabbed +++ b/examples/data/scripts/uzbl-tabbed @@ -54,9 +54,6 @@ # pango - python bindings needed for text rendering & layout in gtk widgets. # pygobject - GLib's GObject bindings for python. # -# Optional dependencies: -# simplejson - save uzbl_tabbed.py sessions & presets in json. -# # Note: I haven't included version numbers with this dependency list because # I've only ever tested uzbl_tabbed.py on the latest stable versions of these # packages in Gentoo's portage. Package names may vary on different systems. @@ -161,8 +158,9 @@ import atexit import types from gobject import io_add_watch, source_remove, timeout_add, IO_IN, IO_HUP -from signal import signal, SIGTERM, SIGINT +from signal import signal, SIGTERM, SIGINT, SIGCHLD from optparse import OptionParser, OptionGroup +from traceback import print_exc pygtk.require('2.0') @@ -213,7 +211,6 @@ config = { # Session options 'save_session': True, # Save session in file when quit - 'json_session': False, # Use json to save session. 'saved_sessions_dir': os.path.join(DATA_DIR, 'sessions/'), 'session_file': os.path.join(DATA_DIR, 'session'), @@ -371,9 +368,8 @@ class SocketClient: class UzblInstance: '''Uzbl instance meta-data/meta-action object.''' - def __init__(self, parent, tab, name, uri, title, switch, process): + def __init__(self, parent, tab, name, uri, title, switch): - self.process = process self.parent = parent self.tab = tab self.name = name @@ -455,10 +451,11 @@ class UzblInstance: if type == "EVENT": type, args = args.split(" ", 1) if type == "TITLE_CHANGED": - self.title = args + self.title = args.strip() self.title_changed() elif type == "VARIABLE_SET": var, _, val = args.split(" ", 2) + try: val = int(val) except: @@ -485,7 +482,7 @@ class UzblInstance: config[var] = val if var == "uri": - self.uri = var + self.uri = val.strip() self.parent.update_tablist() elif type == "NEW_TAB": self.parent.new_tab(args) @@ -529,18 +526,6 @@ class UzblInstance: self._client.close() self._client = None - pid = self.process.pid - timeout = time.time() + 5 - - while self.process.poll() is None and time.time() < timeout: - # Sleep between polls. - time.sleep(0.1) - - if self.process.poll() is None: - # uzbl instance didn't exit in time. - error("quit timeout expired, sending SIGTERM to uzbl instance") - self.process.terminate() - class UzblTabbed: '''A tabbed version of uzbl using gtk.Notebook''' @@ -551,6 +536,7 @@ class UzblTabbed: self._timers = {} self._buffer = "" self._killed = False + self._processes = [] # A list of the recently closed tabs self._closed = [] @@ -571,6 +557,7 @@ class UzblTabbed: self.window.set_default_size(*window_size) except: + print_exc() error("Invalid value for default_size in config file.") self.window.set_title("Uzbl Browser") @@ -668,10 +655,14 @@ class UzblTabbed: # Catch keyboard interrupts signal(SIGINT, lambda signum, stack_frame: self.terminate(SIGINT)) + # Catch SIGCHLD + signal(SIGCHLD, lambda signum, stack_frame: self.join_children()) + try: gtk.main() except: + print_exc() error("encounted error %r" % sys.exc_info()[1]) # Unlink fifo socket @@ -687,6 +678,14 @@ class UzblTabbed: raise + def join_children(self): + '''Find and remove zombie children processes.''' + + for p in self._processes: + if p.poll() is not None: + self._processes.remove(p) + + def terminate(self, termsig=None): '''Handle termination signals and exit safely and cleanly.''' @@ -834,6 +833,7 @@ class UzblTabbed: self.parse_command(cmd) except: + print_exc() error("parse_command: invalid command %s" % ' '.join(cmd)) raise @@ -1007,9 +1007,9 @@ class UzblTabbed: cmd = ['uzbl-browser', '-n', name, '-s', str(sid), '--connect-socket', self.socket_path, '--uri', uri] - process = subprocess.Popen(cmd) # TODO: do i need close_fds=True ? + self._processes += [subprocess.Popen(cmd)] # TODO: do i need close_fds=True ? - uzbl = UzblInstance(self, tab, name, uri, title, switch, process) + uzbl = UzblInstance(self, tab, name, uri, title, switch) SocketClient.instances_queue[name] = uzbl self.tabs[tab] = uzbl @@ -1237,48 +1237,35 @@ class UzblTabbed: def save_session(self, session_file=None): '''Save the current session to file for restoration on next load.''' - strip = str.strip - if session_file is None: session_file = config['session_file'] tabs = self.tabs.keys() - state = [] + lines = "curtab = %d\n" % self.notebook.get_current_page() for tab in list(self.notebook): - if tab not in tabs: continue - uzbl = self.tabs[tab] - if not uzbl.uri: continue - state += [(uzbl.uri, uzbl.title),] - - session = {'curtab': self.notebook.get_current_page(), - 'tabs': state} - - if config['json_session']: - raw = json.dumps(session) + if tab not in tabs: + continue - else: - lines = ["curtab = %d" % session['curtab'],] - for (uri, title) in session['tabs']: - lines += ["%s\t%s" % (strip(uri), strip(title)),] + uzbl = self.tabs[tab] + if not uzbl.uri: + continue - raw = "\n".join(lines) + lines += "%s %s\n" % (uzbl.uri, uzbl.title) if not os.path.isfile(session_file): dirname = os.path.dirname(session_file) if not os.path.isdir(dirname): os.makedirs(dirname) - h = open(session_file, 'w') - h.write(raw) - h.close() + fh = open(session_file, 'w') + fh.write(lines) + fh.close() def load_session(self, session_file=None): '''Load a saved session from file.''' default_path = False - strip = str.strip - json_session = config['json_session'] delete_loaded = False if session_file is None: @@ -1289,50 +1276,34 @@ class UzblTabbed: if not os.path.isfile(session_file): return False - h = open(session_file, 'r') - raw = h.read() - h.close() - if json_session: - if sum([1 for s in raw.split("\n") if strip(s)]) != 1: - error("Warning: The session file %r does not look json. "\ - "Trying to load it as a non-json session file."\ - % session_file) - json_session = False - - if json_session: - try: - session = json.loads(raw) - curtab, tabs = session['curtab'], session['tabs'] + fh = open(session_file, 'r') + raw = fh.read() + fh.close() - except: - error("Failed to load jsonifed session from %r"\ - % session_file) - return None + tabs = [] + curtab = 0 - else: - tabs = [] - strip = str.strip - curtab, tabs = 0, [] - lines = [s for s in raw.split("\n") if strip(s)] - if len(lines) < 2: - error("Warning: The non-json session file %r looks invalid."\ - % session_file) - return None + lines = filter(None, map(str.strip, raw.split('\n'))) + if len(lines) < 2: + error("Error: The session file %r looks invalid." % session_file) + if delete_loaded and os.path.exists(session_file): + os.remove(session_file) - try: - for line in lines: - if line.startswith("curtab"): - curtab = int(line.split()[-1]) + return None - else: - uri, title = line.split("\t",1) - tabs += [(strip(uri), strip(title)),] + try: + for line in lines: + if line.startswith("curtab"): + curtab = int(line.split()[-1]) - except: - error("Warning: failed to load session file %r" % session_file) - return None + else: + uri, title = map(str.strip, line.split(" ", 1)) + tabs += [(uri, title),] - session = {'curtab': curtab, 'tabs': tabs} + except: + print_exc() + error("Warning: failed to load session file %r" % session_file) + return None # Now populate notebook with the loaded session. for (index, (uri, title)) in enumerate(tabs): @@ -1342,11 +1313,6 @@ class UzblTabbed: if delete_loaded and os.path.exists(session_file): os.remove(session_file) - # There may be other state information in the session dict of use to - # other functions. Of course however the non-json session object is - # just a dummy object of no use to no one. - return session - def quitrequest(self, *args): '''Attempt to close all uzbl instances nicely and exit.''' @@ -1412,16 +1378,6 @@ if __name__ == "__main__": if options.verbose: config['verbose'] = True - if config['json_session']: - try: - import simplejson as json - - except: - error("Warning: json_session set but cannot import the python "\ - "module simplejson. Fix: \"set json_session = 0\" or "\ - "install the simplejson python module to remove this warning.") - config['json_session'] = False - if config['verbose']: import pprint sys.stderr.write("%s\n" % pprint.pformat(config)) diff --git a/examples/data/scripts/uzblcat b/examples/data/scripts/uzblcat index e955608..4aa4b9e 100755 --- a/examples/data/scripts/uzblcat +++ b/examples/data/scripts/uzblcat @@ -9,4 +9,3 @@ for line in stdin: stdout.write(line[0:-1]) # vim: set noet ff=unix - diff --git a/src/callbacks.c b/src/callbacks.c index c95c0f1..ac6c75d 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -311,7 +311,7 @@ cmd_view_source() { void cmd_set_zoom_type () { - if(uzbl.behave.zoom_type) + if(uzbl.behave.zoom_type) webkit_web_view_set_full_content_zoom (uzbl.gui.web_view, TRUE); else webkit_web_view_set_full_content_zoom (uzbl.gui.web_view, FALSE); @@ -692,23 +692,7 @@ gboolean download_cb (WebKitWebView *web_view, GObject *download, gpointer user_data) { (void) web_view; (void) user_data; - if (uzbl.behave.download_handler) { - const gchar* uri = webkit_download_get_uri ((WebKitDownload*)download); - if (uzbl.state.verbose) - printf("Download -> %s\n",uri); - - /* if urls not escaped, we may have to escape and quote uri before this call */ - GString *args = g_string_new(uri); - - if (uzbl.net.proxy_url) { - g_string_append_c(args, ' '); - g_string_append(args, uzbl.net.proxy_url); - } - run_handler(uzbl.behave.download_handler, args->str); - - g_string_free(args, TRUE); - } send_event(DOWNLOAD_REQ, webkit_download_get_uri ((WebKitDownload*)download), NULL); return (FALSE); } @@ -778,4 +762,3 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { } } } - diff --git a/src/callbacks.h b/src/callbacks.h index 6ed8986..278a31a 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -1,4 +1,4 @@ -/* +/* ** Callbacks ** (c) 2009 by Robert Manea et al. */ @@ -207,4 +207,3 @@ button_release_cb (GtkWidget* window, GdkEventButton* event); gboolean focus_cb(GtkWidget* window, GdkEventFocus* event, void *ud); - diff --git a/src/events.c b/src/events.c index 1028c30..c209550 100644 --- a/src/events.c +++ b/src/events.c @@ -1,5 +1,5 @@ -/* - ** Uzbl event routines +/* + ** Uzbl event routines ** (c) 2009 by Robert Manea */ @@ -84,7 +84,7 @@ send_event_socket(GString *msg) { tmp->str, tmp->len, &len, &error); - if (ret == G_IO_STATUS_ERROR) + if (ret == G_IO_STATUS_ERROR) g_warning ("Error sending event to socket: %s", error->message); else g_io_channel_flush(gio, &error); @@ -205,4 +205,3 @@ key_to_event(guint keyval, gint mode) { } } - diff --git a/src/events.h b/src/events.h index fe3ff3b..1bd8804 100644 --- a/src/events.h +++ b/src/events.h @@ -1,4 +1,4 @@ -/* +/* ** Uzbl event routines ** (c) 2009 by Robert Manea */ diff --git a/src/uzbl-core.c b/src/uzbl-core.c index c288b5f..4d60bd3 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -90,7 +90,6 @@ const struct var_name_to_ptr_t { { "print_events", PTR_V_INT(uzbl.state.events_stdout, 1, NULL)}, { "inject_html", PTR_V_STR(uzbl.behave.inject_html, 0, cmd_inject_html)}, { "geometry", PTR_V_STR(uzbl.gui.geometry, 1, cmd_set_geometry)}, - { "keycmd", PTR_V_STR(uzbl.state.keycmd, 1, NULL)}, { "show_status", PTR_V_INT(uzbl.behave.show_status, 1, cmd_set_status)}, { "status_top", PTR_V_INT(uzbl.behave.status_top, 1, move_statusbar)}, { "status_format", PTR_V_STR(uzbl.behave.status_format, 1, NULL)}, @@ -99,7 +98,6 @@ const struct var_name_to_ptr_t { { "title_format_short", PTR_V_STR(uzbl.behave.title_format_short, 1, NULL)}, { "icon", PTR_V_STR(uzbl.gui.icon, 1, set_icon)}, { "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)}, - { "download_handler", PTR_V_STR(uzbl.behave.download_handler, 1, NULL)}, { "cookie_handler", PTR_V_STR(uzbl.behave.cookie_handler, 1, NULL)}, { "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)}, { "new_window", PTR_V_STR(uzbl.behave.new_window, 1, NULL)}, @@ -197,7 +195,7 @@ gchar * expand(const char *s, guint recurse) { uzbl_cmdprop *c; enum exp_type etype; - char *end_simple_var = "^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½"; + char *end_simple_var = "\t^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½"; char *ret = NULL; char *vend = NULL; GError *err = NULL; @@ -999,7 +997,7 @@ act_dump_config_as_events() { void load_uri (WebKitWebView *web_view, GArray *argv, GString *result) { (void) web_view; (void) result; - load_uri_imp (argv_idx (argv, 0)); + set_var_value("uri", argv_idx(argv, 0)); } /* Javascript*/ @@ -1643,7 +1641,7 @@ set_var_value(const gchar *name, gchar *val) { uzbl_cmdprop *c = NULL; char *endp = NULL; char *buf = NULL; - char *invalid_chars = "^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½"; + char *invalid_chars = "\t^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½"; GString *msg; if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) { @@ -2536,7 +2534,6 @@ initialize(int argc, char *argv[]) { } uzbl.net.soup_session = webkit_get_default_session(); - uzbl.state.keycmd = g_strdup(""); for(i=0; sigs[i]; i++) { if(setup_signal(sigs[i], catch_signal) == SIG_ERR) @@ -2658,7 +2655,8 @@ main (int argc, char* argv[]) { /* generate an event with a list of built in commands */ builtins(); - gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); + if (!uzbl.state.plug_mode) + gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); if (uzbl.state.verbose) { printf("Uzbl start location: %s\n", argv[0]); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 23072e4..73ec7c1 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -92,7 +92,6 @@ typedef struct { gchar *selected_url; gchar *last_selected_url; gchar *executable_path; - gchar* keycmd; gchar* searchtx; gboolean verbose; gboolean events_stdout; @@ -122,7 +121,6 @@ typedef struct { gchar* status_background; gchar* fifo_dir; gchar* socket_dir; - gchar* download_handler; gchar* cookie_handler; gchar* authentication_handler; gchar* new_window; @@ -266,9 +264,6 @@ bool file_exists (const char * filename); void -set_keycmd(); - -void load_uri (WebKitWebView * web_view, GArray *argv, GString *result); void @@ -339,9 +334,6 @@ gboolean key_release_cb (GtkWidget* window, GdkEventKey* event); void -run_keycmd(const gboolean key_ret); - -void initialize (int argc, char *argv[]); void diff --git a/tests/test-expand.c b/tests/test-expand.c index 7ea3d61..f64aba8 100644 --- a/tests/test-expand.c +++ b/tests/test-expand.c @@ -31,12 +31,6 @@ extern gchar* expand(char*, guint); extern void make_var_to_name_hash(void); void -test_keycmd (void) { - uzbl.state.keycmd = "gg winslow"; - g_assert_cmpstr(expand("@keycmd", 0), ==, "gg winslow"); -} - -void test_uri (void) { g_assert_cmpstr(expand("@uri", 0), ==, ""); @@ -184,7 +178,6 @@ main (int argc, char *argv[]) { g_type_init(); g_test_init(&argc, &argv, NULL); - g_test_add_func("/test-expand/@keycmd", test_keycmd); g_test_add_func("/test-expand/@useragent", test_useragent); g_test_add_func("/test-expand/@uri", test_uri); g_test_add_func("/test-expand/@TITLE", test_TITLE); |