aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--Makefile55
-rw-r--r--README30
-rw-r--r--docs/INSTALL1
-rw-r--r--examples/config/config45
-rwxr-xr-xexamples/data/scripts/cookies.sh154
-rwxr-xr-xexamples/data/scripts/download.sh2
-rw-r--r--examples/data/scripts/extedit.js102
-rw-r--r--examples/data/scripts/follower.js420
-rwxr-xr-xexamples/data/scripts/formfiller.pl99
-rwxr-xr-xexamples/data/scripts/formfiller.sh169
-rw-r--r--examples/data/scripts/hint.js26
-rwxr-xr-xexamples/data/scripts/instance-select-wmii.sh2
-rw-r--r--examples/data/scripts/linkfollow.js269
-rw-r--r--examples/data/scripts/scroll-percentage.js68
-rwxr-xr-xexamples/data/scripts/uzbl-tabbed154
-rwxr-xr-xexamples/data/scripts/uzblcat1
-rw-r--r--src/callbacks.c19
-rw-r--r--src/callbacks.h3
-rw-r--r--src/events.c7
-rw-r--r--src/events.h2
-rw-r--r--src/uzbl-core.c12
-rw-r--r--src/uzbl-core.h8
-rw-r--r--tests/test-expand.c7
24 files changed, 269 insertions, 1387 deletions
diff --git a/AUTHORS b/AUTHORS
index e5fc05b..80e69e5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
diff --git a/Makefile b/Makefile
index 79a7297..7a1fa36 100644
--- a/Makefile
+++ b/Makefile
@@ -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:
diff --git a/README b/README
index 11146ef..e26673c 100644
--- a/README
+++ b/README
@@ -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);