pull in latest stuff from experimental
authorDieter Plaetinck <dieter@plaetinck.be>
Sat, 6 Jun 2009 21:30:43 +0000 (23:30 +0200)
committerDieter Plaetinck <dieter@plaetinck.be>
Sat, 6 Jun 2009 21:30:43 +0000 (23:30 +0200)
22 files changed:
AUTHORS
Makefile
Makefile-new-test [new file with mode: 0644]
README
docs/FAQ
docs/INSTALL
examples/configs/sampleconfig
examples/configs/sampleconfig-dev
examples/data/style.css [new file with mode: 0644]
examples/scripts/clipboard.sh
examples/scripts/cookies.sh
examples/scripts/download.sh
examples/scripts/formfiller.pl
examples/scripts/formfiller.sh
examples/scripts/linkfollow.js
examples/scripts/load_url_from_bookmarks.sh
examples/scripts/load_url_from_history.sh
examples/scripts/session.sh
examples/scripts/yank.sh
uzbl.c
uzbl.h
uzblctrl.c

diff --git a/AUTHORS b/AUTHORS
index 2212a87..e5e3806 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,11 +3,11 @@ Developers:
     Dieter Plaetinck (Dieter@be) <email is dieter AT plaetinck.be>
     Dusan Popovic (dusanx)
     Michael Walker (Barrucadu) <email is mike AT barrucadu.co.uk>
-    Přemysl Hrubý, (anydot) <email is dfenze AT gmail.com>
+    Přemysl Hrubý (anydot) <email is dfenze AT gmail.com>
     Robert Manea (robm) <email is rob DOT manea AT gmail DOT com>
+    Henri Kemppainen (DuClare) <email is akarinotengoku AT THE DOMAIN OF gmail.com> 
 
 Contributors:
-    (DuClare) - Various improvements
     Zane Ashby (HashBox) - Rewrote FIFO interface. Fixed various bugs.
     (sentientswitch) - Cleaned up code. Added some commands.
     Jan Kolkmeier (jouz) - scrolling, link following
@@ -17,6 +17,14 @@ Contributors:
     (salinasv) - move some variables to heap
     Sylvester Johansson (scj) - form filler script & different take on link follower 
     (mxf) - uzblcat
+    Mark Nevill - misc patches
+    Uli Schlachter (psychon) - basic mime_policy_cb & Makefile patch
+    (uranther) - zoom level
+    (bobpaul) - session script patches
+    Tom Adams (holizz) - few patches
+    neutralinsomniac - load_progress = 0 fix
+    Maximilian Gaß (mxey) - small patches
+    Abel Camarillo (00z) - make it compile on OpenBSD
 
 Originaly based on http://trac.webkit.org/browser/trunk/WebKitTools/GtkLauncher/main.c
 Which is  copyrighted:
index d158a9b..04012ed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
-CPPFLAGS=$(shell pkg-config --cflags gtk+-2.0 webkit-1.0) -ggdb -Wall -W -DARCH="\"$(shell uname -m)\"" -DG_ERRORCHECK_MUTEXES -DCOMMIT="\"$(shell git log | head -n1 | sed "s/.* //")\""
-LDFLAGS=$(shell pkg-config --libs gtk+-2.0 webkit-1.0)
+CFLAGS:=-std=c99 $(shell pkg-config --cflags gtk+-2.0 webkit-1.0 libsoup-2.4) -ggdb -Wall -W -DARCH="\"$(shell uname -m)\"" -DG_ERRORCHECK_MUTEXES -DCOMMIT="\"$(shell git log | head -n1 | sed "s/.* //")\"" $(CPPFLAGS)
+LDFLAGS:=$(shell pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4) -pthread $(LDFLAGS)
 all: uzbl uzblctrl
 
+PREFIX?=$(DESTDIR)/usr
+
 test: uzbl
        ./uzbl --uri http://www.uzbl.org
 
@@ -16,18 +18,19 @@ clean:
        rm -f uzblctrl
 
 install:
-       install -d $(DESTDIR)/usr/bin
-       install -d $(DESTDIR)/usr/share/uzbl/docs
-       install -d $(DESTDIR)/usr/share/uzbl/examples
-       install -D -m755 uzbl $(DESTDIR)/usr/bin/uzbl
-       install -D -m755 uzblctrl $(DESTDIR)/usr/bin/uzblctrl
-       cp -ax docs     $(DESTDIR)/usr/share/uzbl/
-       cp -ax config.h $(DESTDIR)/usr/share/uzbl/docs/
-       cp -ax examples $(DESTDIR)/usr/share/uzbl/
-       install -D -m644 AUTHORS $(DESTDIR)/usr/share/uzbl/docs
-       install -D -m644 README  $(DESTDIR)/usr/share/uzbl/docs
+       install -d $(PREFIX)/bin
+       install -d $(PREFIX)/share/uzbl/docs
+       install -d $(PREFIX)/share/uzbl/examples
+       install -D -m755 uzbl $(PREFIX)/bin/uzbl
+       install -D -m755 uzblctrl $(PREFIX)/bin/uzblctrl
+       cp -ax docs     $(PREFIX)/share/uzbl/
+       cp -ax config.h $(PREFIX)/share/uzbl/docs/
+       cp -ax examples $(PREFIX)/share/uzbl/
+       install -D -m644 AUTHORS $(PREFIX)/share/uzbl/docs
+       install -D -m644 README  $(PREFIX)/share/uzbl/docs
+
 
 uninstall:
-       rm -rf $(DESTDIR)/usr/bin/uzbl
-       rm -rf $(DESTDIR)/usr/bin/uzblctrl
-       rm -rf $(DESTDIR)/usr/share/uzbl
+       rm -rf $(PREFIX)/bin/uzbl
+       rm -rf $(PREFIX)/bin/uzblctrl
+       rm -rf $(PREFIX)/share/uzbl
diff --git a/Makefile-new-test b/Makefile-new-test
new file mode 100644 (file)
index 0000000..5985c90
--- /dev/null
@@ -0,0 +1,51 @@
+LIBS      := gtk+-2.0 webkit-1.0
+ARCH      := $(shell uname -m)
+COMMIT    := $(shell git log | head -n1 | sed "s/.* //")
+DEBUG     := -ggdb -Wall -W -DG_ERRORCHECK_MUTEXES
+
+CFLAGS    := $(shell --cflags $(LIBS)) $(DEBUG) -DARCH="$(ARCH)" -DCOMMIT="\"$(COMMIT)\""
+LDFLAGS   := $(shell --libs $(LIBS)) $(LDFLAGS)
+
+PREFIX    ?= $(DESTDIR)/usr
+BINDIR    ?= $(PREFIX)/bin
+UZBLDATA  ?= $(PREFIX)/share/uzbl
+DOCSDIR   ?= $(PREFIX)/share/uzbl/docs
+EXMPLSDIR ?= $(PREFIX)/share/uzbl/examples
+
+all: uzbl uzblctrl
+
+uzbl: uzbl.c uzbl.h config.h
+
+%: %.c
+       $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBS) -o $@ $<
+
+test: uzbl
+       ./uzbl --uri http://www.uzbl.org
+
+test-config: uzbl
+       ./uzbl --uri http://www.uzbl.org < examples/configs/sampleconfig-dev
+
+test-config-real: uzbl
+       ./uzbl --uri http://www.uzbl.org < $(EXMPLSDIR)/configs/sampleconfig
+       
+clean:
+       rm -f uzbl
+       rm -f uzblctrl
+
+install:
+       install -d $(BINDIR)
+       install -d $(DOCSDIR)
+       install -d $(EXMPLSDIR)
+       install -D -m755 uzbl $(BINDIR)/uzbl
+       install -D -m755 uzblctrl $(BINDIR)/uzblctrl
+       cp -ax docs/*   $(DOCSDIR)
+       cp -ax config.h $(DOCSDIR)
+       cp -ax examples/* $(EXMPLSDIR)
+       install -D -m644 AUTHORS $(DOCSDIR)
+       install -D -m644 README $(DOCSDIR)
+
+
+uninstall:
+       rm -rf $(BINDIR)/uzbl
+       rm -rf $(BINDIR)/uzblctrl
+       rm -rf $(UZBLDATA)
diff --git a/README b/README
index 71cdcfa..4f394bd 100644 (file)
--- a/README
+++ b/README
@@ -83,62 +83,35 @@ When uzbl forks a new instance (eg "open in new window") it will use the same co
 If you made changes to the configuration at runtime, these are not pased on to the child.
 
 ### COMMAND SYNTAX
-Commands are used for:
-
-* creating keybindings
-* altering variables
-* getting the values of variables
-* running actions
-* setting the input buffer
-
 Uzbl will read commands via standard input, named fifo pipe (if `fifo_dir` is set) and IPC socket (when `socket_dir` is set).
 For convenience, uzbl can also be instructed to read commands from a file on startup by using the `-c` option.  Indeed, the config file is nothing more than a list of commands.
 
 Each command starts with the name of the command, which must be the first thing on a line; preceding whitespace is not allowed.
-A command is terminated by a newline.  Empty lines and lines that start with the hash sign are ignored by the parser.  Command names are not case sensitive.
+A command is terminated by a newline.  Empty lines and lines that start with the hash sign are ignored by the parser.  Command names are always written in lowercase.
 
 The following commands are recognized:
 
-    SET <key> = <value>
-Set is used for changing variables.  Every variable can be changed on the fly and for some variables, some additional logic is performed.
-For example, setting the variable `uri` will make uzbl start loading it, and changing the format of the statusbar/windowtitle/user agent/.. will be effective immediately.
-If you want to unset a string, use SET with one space after the equals sign.
-
-    GET <key>
-Use this to print the value of a key. (and TODO, get the value through the socket)
-
-    BIND <string> = <action>
-Makes the character sequence `<string>` invoke `<action>` when typed interactively in uzbl.
-There are a few tricks you can do:
-
-* `<string>` ends with an underscore: the action will only be invoked after pressing return/enter. If the user enters text where `<string>` has the underscore, `%s` in the `<action>` string will be replaced by this text. (optional)
-* `<string>` ends with an asterisk: similar behavior as with an underscore, but also makes the binding incremental (i.e. the action will be invoked on every keystroke).
-* `<string>` ends on a different character: you need to type the full string, which will trigger the action immediately, without pressing enter/return.
-
-Examples:
-
-    # uzbl will load the url when you type: 'o <url><enter>'
-    bind o _ = uri %s
-    # a search action which is called on every character typed after the slash, letting you see the search narrow down while typing.
-    #  Hitting return, enter or esc will terminate the search.
-    bind /*  = search %s
-    # when you type `ZZ` and nothing else, the exit action will be triggered immediately.
-    bind ZZ  = exit
-
-    ACT <action>
-This tells uzbl to execute an action immediately.  The simplest example of this would be `act exit`; you know what that'll do.
-
-    KEYCMD <string>
-This sets the interactive command buffer to `<string>`.  Keycmd is primarily useful for scripts that help you type a command while still letting you edit it before execution.
-For example, if you have a binding like "o _" that opens an URL, then you could create a binding `O` that spawns a script which will set the command buffer to "o current-uri-here", letting you enter relative URLs easily.
-
-    KEYCMDN <string>
-Like KEYCMD, but also emulates a press of return which causes binds with an asterisk or underscore to execute.
-(See sample config)
-
-### ACTIONS
-Actions are invoked via bindings and by the ACT command.  Most actions are self-explanatory, though a few need to be clarified.  A list of
-actions follows:
+* `set <key> = <value>`
+   - used for changing variables on the fly
+   - the changes are effective immediately; for example, setting the variable `uri` will make uzbl start loading, and changing `status_format` will make the status bar react immediately
+   - if you want to unset a string, use `set` with one space after the equals sign
+* `get <key>`
+   - use this to print the value of a variable. (and TODO, get the value through the socket)
+* `bind <string> = <command>`
+   - sets the character sequence `<string>` to invoke `<command>` when typed interactively in uzbl
+   - there are a few tricks you can do:
+       * `<string>` ends with an underscore: the command will only be invoked after pressing return/enter. If the user enters text where `<string>` has the underscore, `%s` in the `<command>` string will be replaced by this text. (optional)
+       * `<string>` ends with an asterisk: similar behavior as with an underscore, but also makes the binding incremental (i.e. the command will be invoked on every keystroke).
+       * `<string>` ends on a different character: you need to type the full string, which will trigger the command immediately, without pressing enter/return.
+   - examples:
+
+        # uzbl will load the url when you type: 'o <url><enter>'
+        bind o _ = uri %s
+        # a search command which is called on every character typed after the slash, letting you see the search narrow down while typing.
+        #  Hitting return, enter or esc will terminate the search.
+        bind /*  = search %s
+        # when you type `ZZ` and nothing else, the exit command will be triggered immediately.
+        bind ZZ  = exit
 
 * `back`
 * `forward`
@@ -156,7 +129,7 @@ actions follows:
 * `uri <address>`
 * `js <body>`
    - execute the javascript in `<body>`
-   - remember that the commands, and thus actions, must not contain line breaks
+   - remember that the commands must not contain line breaks
 * `script <file>`
    - execute the javascript in `<file>`
 * `toggle_status`
@@ -167,14 +140,25 @@ actions follows:
 * `sh <command>`
    - runs a shell command by expanding `%s` in the `shell_cmd` variable with the specified command; primarily useful as a shortcut for `spawn sh -c <body>`
    - note that the arguments as specified in "EXTERNAL SCRIPTS" are appended at the end, so the argument numbers will be higher.
+* `sync_spawn <executable> <additional args>`
+* `sync_sh <command>`
+   - these are synchronous variants of `spawn` and `sh`, which means uzbl will wait for them to return
+   - you should only need to use these manually if you want to use a chain command in a handler that wants output from the command it runs
 * `exit`
 * `search <string>`
 * `search_reverse <string>`
    - search with no string will search for the next/previous occurrence of the string previously searched for
 * `toggle_insert_mode <optional state>`
    - if the optional state is 0, disable insert mode. If 1, enable insert mode.
-* `runcmd`
-   - can be used for running a command such as SET or BIND
+* `keycmd <string>`
+* `keycmd_nl <string>`
+   - keycmd sets the interactive command buffer to `<string>`.  If the given string is a valid binding, it will execute.  `Keycmd_nl` is like `keycmd`, but it also emulates a press of return, causing bindings with a parameter to execute.  For example, `keycmd_nl o google.com` would load the said url if you have a binding like `bind o _ = uri %s`.
+* `keycmd_bs`
+   - erase (backspace) one character from the command buffer
+* `chain <command> <command> ..`
+   - use for chaining multiple commands
+   - remember to quote the commands; one command must come as one parameter
+   - if you use `chain` with a handler script which must return some output (such as a cookie handler -- uzbl will wait for and use its output), use sync_spawn or sync_sh instead of spawn or sh in the command that should give the output
 
 
 ### VARIABLE REPLACEMENT
index b5a6323..79e1364 100644 (file)
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -37,6 +37,10 @@ You have to look at the bigger picture.  In fact, we do support all these things
 These ideas are something we want to consistently apply throughout the entire application.  (Even more, throughout our entire desktop environment)
 In fact, we actually ship various sample scripts and some sample configs that make it easy for you to implement your workflow.
 
+### Okay, what can I actually do?  What commands are there?  How do I get more information?
+  * Commands and other features are documented in README.  Read it.
+  * You should also peek into the sampleconfigs to see how commands are used in practice.
+
 ### Why can't I type anything in forms?  How does the keybinding work?
 You are in command mode, not in insert mode.
 
@@ -64,12 +68,19 @@ Note that we do *not* depend on any Gnome libraries such as gconf.  _That_ would
 ### Do you support flash? javascript? Ajax?  Recent html/css/.. standards?
 Yes, Webkit takes care of all of that.  Not that we like all of these, but you can use them if you want.
 
+### What's the difference between the socket file and the fifo?
+They both have advantages and disadvantages:
+
+ * fifo's are _very_ easy to work with. You can write just plaintext commands into them, but they are unidirectional (you can only communicate in one direction)
+ * Sockets are bidirectional but more complex.  You cannot just write a plaintext string into them.  In shellscripts you can use uzblctrl or netcat to work with sockets, when programming you need to use library functions.
+
+So, when writing scripts, using fifo's is usually the fastest method (because you do not need to fork another process), so fifo is preferred unless you need a response.
+
 ### Does the world really need another browser?
 We did try a lot of browsers, and we do not suffer [NIH](http://en.wikipedia.org/wiki/Not_Invented_Here).
 We believe that the approach taken by way too many browsers is wrong.  We do not want browsers that try to do everything,
 instead we prefer a system where different applications work together, which gives plenty of advantages.
 We also like open source.  We take a lot of things from other projects and we also try to contribute to other projects.
 
-
 ### What? You call all of this user-friendly?
 Yes.  If you don't agree, don't use it :)
index 3453e03..1c0d007 100644 (file)
@@ -1,11 +1,13 @@
-Arch Linux
-----------
+Packages
+--------
 [Arch Linux](http://www.archlinux.org) is our distro of choice, and the distro we use for testing.
 
 You can find a [PKGBUILD](http://aur.archlinux.org/packages.php?ID=25972) on the AUR, which installs the latest
 from the master branch. You can edit the PKGBUILD to change to any other
 branch you want.
 
+For other distros, see [uzbl.org/wiki/howtos](http://www.uzbl.org/wiki/howtos)
+
 From source
 -----------
 You can pull the code from git or get a tagged tarball.
index a541854..e853836 100644 (file)
@@ -2,16 +2,16 @@
 # example uzbl config. in a real config, we should obey the xdg spec
 # all settings are optional.  you can use uzbl without any config at all (but it won't do much)
 
-# keyboard behavior is vimstyle by default (all actions -> 1 key). set
+# keyboard behavior is vimstyle by default (all commands -> 1 key). set
 # always_insert_mode to always be in insert mode and disable going out of it.
-# if you do this, make sure you've set a modkey so you can reach the actions
+# if you do this, make sure you've set a modkey so you can reach the commands
 # from insert mode by combining them with the modkey
 
 # TODO: ability to attach misc things (spawn <foo>, script <bar>,.. to internal events)
-# You can use any action in place of spawn
+# You can use any command in place of spawn
 set history_handler  = spawn /usr/share/uzbl/examples/scripts/history.sh
 set download_handler = spawn /usr/share/uzbl/examples/scripts/download.sh
-#set cookie_handler   = spawn /usr/share/uzbl/examples/scripts/cookies.sh
+set cookie_handler   = spawn /usr/share/uzbl/examples/scripts/cookies.sh
 
 set minimum_font_size = 6
 set font_size = 11
@@ -69,6 +69,8 @@ bind    r         = reload
 bind    R         = reload_ign_cache
 bind    +         = zoom_in
 bind    -         = zoom_out
+bind    1         = sh "echo set zoom_level = 1.0 > $4"
+bind    2         = sh "echo set zoom_level = 2.0 > $4"
 bind    t         = toggle_status
 # Hilight matches. Notice the * after the slash - it makes the command incremental, i.e. gets called
 # on every character you type.  You can do `bind /_ = search %s' if you want it less interactive.
@@ -89,14 +91,14 @@ bind    B         = spawn /usr/share/uzbl/examples/scripts/insert_bookmark.sh
 bind    U         = spawn /usr/share/uzbl/examples/scripts/load_url_from_history.sh
 bind    u         = spawn /usr/share/uzbl/examples/scripts/load_url_from_bookmarks.sh
 # with the sample yank script, you can yank one of the arguments into clipboard/selection
-bind    yurl      = spawn /usr/share/uzbl/examples/scripts/yank.sh 8 primary
-bind    ytitle    = spawn /usr/share/uzbl/examples/scripts/yank.sh 9 clipboard
+bind    yurl      = spawn /usr/share/uzbl/examples/scripts/yank.sh 6 primary
+bind    ytitle    = spawn /usr/share/uzbl/examples/scripts/yank.sh 7 clipboard
 # does the same as yurl but without needing a script
 bind    y2url     = sh "echo -n $6 | xclip"
 # go the page from primary selection
-bind    p         = sh "echo act uri `xclip -selection primary -o` > $4"
+bind    p         = sh "echo uri `xclip -selection primary -o` > $4"
 # go to the page in clipboard
-bind    P         = sh "echo act uri `xclip -selection clipboard -o` > $4"
+bind    P         = sh "echo uri `xclip -selection clipboard -o` > $4"
 bind    ZZ        = exit
 bind    S         = js alert("hi");
 # example showing how to use sh
@@ -104,7 +106,7 @@ bind    S         = js alert("hi");
 # if fifo_dir is not set, it'll echo to a file named (null) somewhere >:) remember to delete it
 # Parameters are separated by spaces and the script body must be one parameter, so enclose it in
 # quotes and escape any inner quotes using backslashes
-bind    XS        = sh 'echo "act script alert (\'This is sent by the shell via a fifo\')" > "$4"'
+bind    XS        = sh 'echo "js alert (\'This is sent by the shell via a fifo\')" > "$4"'
 
 
 # we ship some javascripts to do keyboard based link hinting/following.  (webkit does not have C DOM bindings yet)
index 3b1c069..ad6de24 100644 (file)
@@ -2,16 +2,16 @@
 # example uzbl config. in a real config, we should obey the xdg spec
 # all settings are optional.  you can use uzbl without any config at all (but it won't do much)
 
-# keyboard behavior is vimstyle by default (all actions -> 1 key). set
+# keyboard behavior is vimstyle by default (all commands -> 1 key). set
 # always_insert_mode to always be in insert mode and disable going out of it.
-# if you do this, make sure you've set a modkey so you can reach the actions
+# if you do this, make sure you've set a modkey so you can reach the commands
 # from insert mode by combining them with the modkey
 
 # TODO: ability to attach misc things (spawn <foo>, script <bar>,.. to internal events)
-# Usually you want to spawn a script to handle things, but any action (such as sh) can be used
+# Usually you want to spawn a script to handle things, but any command (such as sh) can be used
 set history_handler  = spawn ./examples/scripts/history.sh
 set download_handler = spawn ./examples/scripts/download.sh
-#set cookie_handler   = spawn ./examples/scripts/cookies.sh
+set cookie_handler   = spawn ./examples/scripts/cookies.sh
 
 set minimum_font_size = 6
 set font_size = 11
@@ -60,7 +60,7 @@ set shell_cmd         = sh -c
 set show_status       = 1
 # you can optionally use this setting to override the background color of the statusbar from your GTK theme.
 set status_background = #303030
-set status_format     = <span font_family="monospace"><span background="khaki" foreground="black">MODE</span> [<span weight="bold" foreground="red">KEYCMD</span>] <span foreground="#606060"> LOAD_PROGRESSBAR </span><span foreground="#99FF66">URI</span> <span foreground="khaki">NAME</span> <span foreground="orange">MSG</span><span foreground="#606060">SELECTED_URI</span></span>
+set status_format     = <span font_family="monospace"><span background="khaki" foreground="black">[MODE]</span> [<span weight="bold" foreground="red">KEYCMD</span>] <span foreground="#606060"> LOAD_PROGRESSBAR </span><span foreground="#99FF66">URI</span> <span foreground="khaki">NAME</span> <span foreground="orange">MSG</span><span foreground="#606060">SELECTED_URI</span></span>
 set status_top = 0
 # define how your titlebar should look like. (short = statusbar is also shown, long = show everything you must see if statusbar is off)
 set title_format_short = TITLE - Uzbl browser <NAME>
@@ -69,7 +69,8 @@ set title_format_long = KEYCMD MODE TITLE - Uzbl browser <NAME> > SELECTED_URI
 set status_pbar_done  = *
 set status_pbar_pending = -
 set status_pbar_width = 12
-
+set insert_indicator = I
+set command_indicator = C
 set modkey = Mod1
 # reset to command mode when new page is loaded
 set reset_command_mode = 1
@@ -103,6 +104,8 @@ bind    r         = reload
 bind    R         = reload_ign_cache
 bind    +         = zoom_in
 bind    -         = zoom_out
+bind    1         = sh "echo set zoom_level = 1.0 > $4"
+bind    2         = sh "echo set zoom_level = 2.0 > $4"
 bind    t         = toggle_status
 # Hilight matches. Notice the * after the slash - it makes the command incremental, i.e. gets called
 # on every character you type.  You can do `bind /_ = search %s' if you want it less interactive.
@@ -125,14 +128,14 @@ bind    B         = spawn ./examples/scripts/insert_bookmark.sh
 bind    U         = spawn ./examples/scripts/load_url_from_history.sh
 bind    u         = spawn ./examples/scripts/load_url_from_bookmarks.sh
 # with the sample yank script, you can yank one of the arguments into clipboard/selection
-bind    yurl      = spawn ./examples/scripts/yank.sh 8 primary
-bind    ytitle    = spawn ./examples/scripts/yank.sh 9 clipboard
+bind    yurl      = spawn ./examples/scripts/yank.sh 6 primary
+bind    ytitle    = spawn ./examples/scripts/yank.sh 7 clipboard
 # does the same as yurl but without needing a script
 bind    y2url     = sh 'echo -n $6 | xclip'
 # go the page from primary selection
-bind    p         = sh "echo act uri `xclip -selection primary -o` > $4"
+bind    p         = sh "echo uri `xclip -selection primary -o` > $4"
 # go to the page in clipboard
-bind    P         = sh "echo act uri `xclip -selection clipboard -o` > $4"
+bind    P         = sh "echo uri `xclip -selection clipboard -o` > $4"
 bind    ZZ        = exit
 bind    S         = js alert("hi");
 # example showing how to use sh
@@ -142,8 +145,7 @@ bind    S         = js alert("hi");
 # you must enclose it in quotes.  Remember to escape (and double-escape) quotes and backslashes
 # in the body.  Any additional parameters you use will appear AFTER the default parameters (cfg file
 # path, fifo & socket dirs, etc.)
-bind    XS        = sh 'echo "act script alert (\\"This is sent by the shell via a fifo\\")" > "$4"'
-
+bind    XS        = sh 'echo "js alert (\\"This is sent by the shell via a fifo\\")" > "$4"'
 
 # this script allows you to configure (per domain) values to fill in form fields (eg login information) and to fill in these values automatically
 bind za = spawn ./examples/scripts/formfiller.sh
diff --git a/examples/data/style.css b/examples/data/style.css
new file mode 100644 (file)
index 0000000..de0a38b
--- /dev/null
@@ -0,0 +1,26 @@
+.uzbl_highlight { background-color: yellow;}
+.uzbl_h_first   { background-color: lightgreen;}
+
+.uzbl_follow    { border-style:     dotted;
+                  border-width:     thin;
+}
+
+#uzbl_hint > div    { 
+       display:                        inline;
+       border:                         2px solid #4a6600;
+       background-color:               #b9ff00;
+       color:                          black;
+       font-size:                      9px;
+       font-weight:                    bold;
+       line-height:                    9px;
+       margin:                         0px;
+       padding:                        0px;
+       position:                       absolute;
+       z-index:                        1000;
+       -webkit-border-radius:          6px;
+       text-decoration:                none;
+       -wekit-transform:               scale(1) rotate(0deg) translate(-6px,-5px);
+}
+
+/* vim:set et ts=4: */
+
index e13f053..c64b65c 100755 (executable)
@@ -9,7 +9,7 @@ selection=$(xclip -o)
 
 case $action in
   "yank" ) echo -n "$url" | xclip;;
-  "goto" ) echo "act uri $selection" > "$fifo";;
+  "goto" ) echo "uri $selection" > "$fifo";;
   * ) echo "clipboard.sh: invalid action";;
 esac
 
index cd449dc..c0c37db 100755 (executable)
@@ -1,4 +1,7 @@
 #!/bin/bash
+
+# THIS IS EXPERIMENTAL AND COULD BE INSECURE !!!!!!
+
 # this is an example script of how you could manage your cookies..
 # we use the cookies.txt format (See http://kb.mozillazine.org/Cookies.txt)
 # This is one textfile with entries like this:
 # http://kb.mozillazine.org/Cookies.txt
 # don't always append cookies, sometimes we need to overwrite
 
-if [ -f /usr/share/uzbl/examples/configs/cookies ]
-then
-       file=/usr/share/uzbl/examples/configs/cookies
-else
-       file=./examples/configs/cookies #useful when developing
-fi
+[ -f /usr/share/uzbl/examples/configs/cookies ] && cookie_config=/usr/share/uzbl/examples/configs/cookies
+[ -f $XDG_CONFIG_HOME/uzbl/cookies            ] && cookie_config=$XDG_CONFIG_HOME/uzbl/cookies
+[ -f ./examples/configs/cookies               ] && cookie_config=./examples/configs/cookies #useful when developing
+[ -z "$cookie_config" ] && exit 1
 
-#cookie_file=$XDG_DATA_HOME/uzbl/cookies.txt
-cookie_file=./examples/data/cookies.txt
+[ -d /usr/share/uzbl/examples/data ] && cookie_data=/usr/share/uzbl/examples/data/cookies.txt
+[ -d $XDG_DATA_HOME/uzbl/          ] && cookie_data=$XDG_DATA_HOME/uzbl/cookies.txt
+[ -d ./examples/data/              ] && cookie_data=./examples/data/cookies.txt #useful when developing
+[ -z "$cookie_data" ] && exit 1
+
+
+#notifier=
+#notifier=notify-send
+notify_wrapper () {
+       echo "$@" >> $HOME/cookielog
+}
 
+# if this variable is set, we will use it to inform you when and which cookies we store, and when/which we send.
+notifier=notify_wrapper
 which zenity &>/dev/null || exit 2
 
 # Example cookie:
@@ -52,6 +64,10 @@ field_name=
 field_value=
 field_exp='end_session'
 
+function notify () {
+       [ -n "$notifier" ] && $notifier "$@"
+}
+
 
 # FOR NOW LETS KEEP IT SIMPLE AND JUST ALWAYS PUT AND ALWAYS GET
 function parse_cookie () {
@@ -76,22 +92,35 @@ function parse_cookie () {
        unset IFS
 }
 
-# match cookies in cookies.txt againsh hostname and path
+# match cookies in cookies.txt against hostname and path
 function get_cookie () {
        path_esc=${path//\//\\/}
-       cookie=`awk "/^[^\t]*$host\t[^\t]*\t$path_esc/" $cookie_file 2>/dev/null | tail -n 1`
+       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"
                read domain alow_read_other_subdomains path http_required expiration name value <<< "$cookie"
                cookie="$name=$value" 
-               #echo "COOKIE $cookie" >> $HOME/cookielog
                true
        fi
 }
 
-[ $action == PUT ] && parse_cookie && echo -e "$field_domain\tFALSE\t$field_path\tFALSE\t$field_exp\t$field_name\t$field_value" >> $cookie_file
+function 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
+}
+
+[ $action == PUT ] && save_cookie
 [ $action == GET ] && get_cookie && echo "$cookie"
 
 exit
@@ -101,15 +130,15 @@ exit
 # $1 = section (TRUSTED or DENY)
 # $2 =url
 function match () {
-       sed -n "/$1/,/^\$/p" $file 2>/dev/null | grep -q "^$host"
+       sed -n "/$1/,/^\$/p" $cookie_config 2>/dev/null | grep -q "^$host"
 }
 
 function fetch_cookie () {
-       cookie=`cat $cookie_file/$host.cookie`
+       cookie=`cat $cookie_data`
 }
 
 function store_cookie () {
-       echo $cookie > $cookie_file/$host.cookie
+       echo $cookie > $cookie_data
 }
 
 if match TRUSTED $host
index 0d38d3c..d87335f 100755 (executable)
@@ -7,10 +7,9 @@ WGET="wget --user-agent=Firefox"
 
 if [[ $8 =~ .*(.torrent) ]] 
 then
-    pushd $HOME
+    cd $HOME
     $WGET $8
 else
-    pushd $HOME
+    cd $HOME
     $WGET $8
 fi
-popd
index a6e07a0..c590836 100755 (executable)
 # bind LE = spawn /usr/share/uzbl/examples/scripts/formfiller.pl edit
 
 use strict;
-use Switch;
+use warnings;
 
 my $keydir = $ENV{XDG_CONFIG_HOME} . "/uzbl/forms";
-my ($config,$pid,$xid,$fifo,$socket,$url,$title,$cmd) = @ARGV;
-if($fifo eq "") { die "No fifo"; };
+my ($config,$pid,$xid,$fifoname,$socket,$url,$title,$cmd) = @ARGV;
+if (!defined $fifoname || $fifoname eq "") { die "No fifo"; }
 
 sub domain {
   my ($url) = @_;
@@ -41,29 +41,29 @@ my %command;
 
 $command{load} = sub {
   my ($domain) = @_;
-  my $file = "$keydir/$domain";
-  if( -e $file){
-    open(FH,$file);
-    my (@lines) = <FH>;
-    close(FH);
+  my $filename = "$keydir/$domain";
+  if (-e $filename){
+    open(my $file, $filename) or die "Failed to open $filename: $!";
+    my (@lines) = <$file>;
+    close($file);
     $|++;
-    open(FIFO,">>$fifo");
-    print "opened $fifo\n";
+    open(my $fifo, ">>", $fifoname) or die "Failed to open $fifoname: $!";
     foreach my $line (@lines) {
-        if($line !~ m/^#/){
-          my ($type,$name,$value) = ($line =~ /\s*(\w+)\s*\|\s*(.*?)\s*\|\s*(.*?)\s*$/);
-          switch ($type) {
-            case ""         {}
-            case "checkbox" { printf FIFO 'act js document.getElementsByName("%s")[0].checked = %s;',  $name, $value}
-            case "submit"   { printf FIFO 'act js function fs (n) {try{n.submit()} catch (e){fs(n.parentNode)}}; fs(document.getElementsByName("%s")[0]);', $name }
-            else            { printf FIFO 'act js document.getElementsByName("%s")[0].value = "%s";',  $name, $value}
-          }
-
-        print FIFO "\n";
+      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";
     }
     $|--;
-    close(FIFO);
   } else {
     $command{new}->($domain);
     $command{edit}->($domain);
@@ -76,24 +76,24 @@ $command{edit} = sub {
     system ($editor, $file);
   } else {
     $command{new}->($domain);
-}
+  }
 };
 $command{new} = sub {
   my ($domain) = @_;
-  my $file = "$keydir/$domain";
-  open(FILE,">>$file");
+  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";
+  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;
+      $line =~ s/.*(<input ([^>].*?)>).*/$1/;
+      printf $file " %-10s | %-10s | %s\n", map { my ($r) = $line =~ /.*$_=["'](.*?)["']/;$r } @fields;
     };
   };
-  close(FILE);
   $|--;
 };
+
 $command{$cmd}->(domain($url));
index 45cde69..5debcce 100755 (executable)
@@ -49,7 +49,7 @@ domain=$(echo $url | sed -re 's|(http\|https)+://([A-Za-z0-9\.]+)/.*|\2|')
 if [ "$action" = 'load' ]
 then
        [[ -e $keydir/$domain ]] || exit 2
-       gawk -F': ' '{ print "act js document.getElementsByName(\"" $1 "\")[0].value = \"" $2 "\";"}' $keydir/$domain >> $fifo
+       gawk -F': ' '{ print "js document.getElementsByName(\"" $1 "\")[0].value = \"" $2 "\";"}' $keydir/$domain >> $fifo
 else
        if [ "$action" == 'new' ]
        then
index 9b7d811..a348af9 100644 (file)
 // 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 something like load_start_handler to send
-// "act script link_follower.js"
+// One way would be to use the load_commit_handler:
+// set load_commit_handler = sh 'echo "script /usr/share/uzbl/examples/scripts/linkfollow.js" > "$4"'
 //
 // when script is loaded, it can be invoked with
-// bind f* = js setHints("%s")
-// bind f_ = js followLink("%s")
+// 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/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: add classes to hinted elements
+// 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";
 
-var uzblid = 'uzbl_hint';
-var uzblclass = 'uzbl_hint_class'
+  // For case sensitive matching, uncomment:
+  // var matchCase = "";
 
-var doc = document;
 
-function elementPosition(el) {
+  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;
+      el = el.offsetParent;
+      up += el.offsetTop;
+      left += el.offsetLeft;
     }
-    return [up, left, width, height];
-}
+    return {up: up, left: left, width: width, height: height};
+  }
 
-function generateHint(el, label) {
-    var hint = doc.createElement('div');
-    hint.setAttribute('class', uzblclass);
-    hint.innerText = label;
-    hint.style.display = 'inline';
-    hint.style.backgroundColor = '#B9FF00';
-    hint.style.border = '2px solid #4A6600';
-    hint.style.color = 'black';
-    hint.style.fontSize = '9px';
-    hint.style.fontWeight = 'bold';
-    hint.style.lineHeight = '9px';
-    hint.style.margin = '0px';
-    hint.style.padding = '1px';
-    hint.style.position = 'absolute';
-    hint.style.zIndex = '10000';
-    hint.style.textDecoration = 'none';
-    hint.style.webkitBorderRadius = '6px';
-    // Play around with this, pretty funny things to do :)
-    hint.style.webkitTransform = 'scale(1) rotate(0deg) translate(-6px,-5px)';
-    return hint;
-}
+  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 elementInViewport(el) {
-    offset = elementPosition(el);
-    var up = offset[0];
-    var left = offset[1];
-    var width = offset[2];
-    var height = offset[3];
-    return (up < window.pageYOffset + window.innerHeight && 
-                               left < window.pageXOffset + window.innerWidth 
-                               && (up + height) > window.pageYOffset 
-                               && (left + 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);
+  }
 
-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";
 
-var hintable = "//a[@href] | //img | //input";
-
-function Matcher(str){
-       var numbers = str.replace(/[^\d]/g,"");
-       var words = str.replace(/\d/g,"").split(/\s+/).map(function (n) { return new RegExp(n,"i")});
-       this.test = test;
-       this.toString = toString;
-       this.numbers = numbers;
-       function test(element) {
-               // test all the regexp
-               return words.every(function (regex) { return element.textContent.match(regex)});
-       }
-       function toString(){
-               return "{"+numbers+"},{"+words+"}";
-       }
-}
+  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){
 
-function setHints(r){
-       if(doc.body) doc.body.setAttribute("onkeyup","keyPressHandler(event)");
-       var re = new Matcher(r);
-       clearHints();
-       var c = 1;
-       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);
-               if(re.test(item) && isVisible(item) && elementInViewport(item)){
-                       var h = generateHint(item,c);
-                       item.appendChild(h);
-                       c++;
-               }
-       }
-}
+    this.node = node;
+    this.isHinted = false;
+    this.position = pos;
+    this.num = 0;
 
-function clearHints(){
-       var items = doc.evaluate("//div[@class='" + uzblclass + "']",doc,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
-       for (var i = 0; i < items.snapshotLength;i++){
-               var item = items.snapshotItem(i);
-               item.parentNode.removeChild(item);
-       }
-}
+    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 keyPressHandler(e) {
+  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) {
-        clearHints();
-                               doc.body.removeAttribute("onkeyup");
+        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;
     }
-}
-function followLink(follow){
-       var m = new Matcher(follow);
-       var elements = doc.evaluate("//*/div[@class='"+uzblclass+"']",doc,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
-       // filter
-       var matched = [];
-       for (var i = 0; i < elements.snapshotLength;i++){
-               var item = elements.snapshotItem(i);
-               if(m.test(item.parentNode)){
-                       matched.push(item.parentNode);
-               }
-       }
-       clearHints();
-       if(matched.length == 1) {
-               var item = matched[0];
-       } else {
-               var item = matched[parseInt(m.numbers,10)-1];
-       }
     if (item) {
-                       item.style.backgroundColor = "blue";
-
-        var name = item.tagName;
-        if (name == 'A') {
-            if(item.click) {item.click()};
-            window.location = item.href;
-        } 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') {
+      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();
-            window.location = item.href;
         }
+      } else if (name == 'TEXTAREA' || name == 'SELECT') {
+        item.focus();
+        item.select();
+      } else {
+        item.click();
+        openFunction(item);
+      }
     }
+  }
 }
+
+var hints = new Hints();
+
+// vim:set et sw=2:
+
+
index 21ea33d..1ae39ff 100755 (executable)
@@ -18,5 +18,5 @@ else
        goto=`awk '{print $1}' $file | $DMENU $COLORS`
 fi
 
-#[ -n "$goto" ] && echo "act uri $goto" > $4
-[ -n "$goto" ] && uzblctrl -s $5 -c "act uri $goto"
+#[ -n "$goto" ] && echo "uri $goto" > $4
+[ -n "$goto" ] && uzblctrl -s $5 -c "uri $goto"
index 649c6b7..37c2afc 100755 (executable)
@@ -17,5 +17,5 @@ else
        current=`tail -n 1 $history_file | awk '{print $3}'`; goto=`(echo $current; awk '{print $3}' $history_file | grep -v "^$current\$" | sort -u) | $DMENU $COLORS`
 fi 
 
-[ -n "$goto" ] && echo "act uri $goto" > $4
-#[ -n "$goto" ] && uzblctrl -s $5 -c "act uri $goto"
+[ -n "$goto" ] && echo "uri $goto" > $4
+#[ -n "$goto" ] && uzblctrl -s $5 -c "uri $goto"
index e9d8c3f..e2642c7 100755 (executable)
@@ -40,23 +40,23 @@ case $act in
     if [ "$url" != "(null)" ]; then
       echo "$url" >> $sessionfile;
     fi
-    echo "act exit" > "$thisfifo"
+    echo "exit" > "$thisfifo"
     ;;
 
   "endsession" )
     mv "$sessionfile" "$sessionfile~"
     for fifo in $fifodir/uzbl_fifo_*; do
       if [ "$fifo" != "$thisfifo" ]; then
-        echo "act spawn $scriptfile endinstance" > "$fifo"
+        echo "spawn $scriptfile endinstance" > "$fifo"
       fi
     done
-    echo "act spawn $scriptfile endinstance" > "$thisfifo"
+    echo "spawn $scriptfile endinstance" > "$thisfifo"
     ;;
 
   * ) echo "session manager: bad action"
       echo "Usage: $scriptfile [COMMAND] where commands are:"
       echo " launch    - Restore a saved session or start a new one"
       echo " endsession        - Quit the running session. Must be called from uzbl"
-    ;;
+      ;;
 esac
 
index d4926be..ee140c7 100755 (executable)
@@ -2,10 +2,11 @@
 # in your uzbl config, make the first argument the number of the (later) argument you want to use (see README for list of args)
 # make the 2nd argument one of : primary, secondary, clipboard.
 # examples:
-# bind    yurl      = spawn ./examples/scripts/yank.sh 8 primary
-# bind    ytitle    = spawn ./examples/scripts/yank.sh 9 clipboard
+# bind    yurl      = spawn ./examples/scripts/yank.sh 6 primary
+# bind    ytitle    = spawn ./examples/scripts/yank.sh 7 clipboard
 
 which xclip &>/dev/null || exit 1
-[ "$2" == primary -o "$2" == secondary -o "$2" == clipboard ] || exit 2
+[ "$9" == primary -o "$9" == secondary -o "$9" == clipboard ] || exit 2
 
-echo -n "${!1}" | xclip -selection $2
\ No newline at end of file
+echo echo -n "${!8}" '|' xclip -selection $9
+echo -n "${!8}" | xclip -selection $9
diff --git a/uzbl.c b/uzbl.c
index 60c9eaa..9abcaa1 100644 (file)
--- a/uzbl.c
+++ b/uzbl.c
@@ -32,6 +32,7 @@
 
 #define LENGTH(x) (sizeof x / sizeof x[0])
 #define MAX_BINDINGS 256
+#define _POSIX_SOURCE
 
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include <sys/utsname.h>
 #include <sys/time.h>
 #include <webkit/webkit.h>
+#include <libsoup/soup.h>
+
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <errno.h>
-#include <string.h>
 #include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <libsoup/soup.h>
 #include <signal.h>
 #include "uzbl.h"
 #include "config.h"
@@ -81,72 +80,77 @@ GOptionEntry entries[] =
 typedef const struct {
     void **ptr;
     int type;
+    int dump;
     void (*func)(void);
 } uzbl_cmdprop;
 
-enum {TYPE_INT, TYPE_STR};
+enum {TYPE_INT, TYPE_STR, TYPE_FLOAT};
 
 /* an abbreviation to help keep the table's width humane */
-#define PTR(var, t, fun) { .ptr = (void*)&(var), .type = TYPE_##t, .func = fun }
+#define PTR(var, t, d, fun) { .ptr = (void*)&(var), .type = TYPE_##t, .dump = d, .func = fun }
 
 const struct {
     char *name;
     uzbl_cmdprop cp;
 } var_name_to_ptr[] = {
-/*    variable name         pointer to variable in code          type  callback function    */
+/*    variable name         pointer to variable in code          type  dump callback function    */
 /*  --------------------------------------------------------------------------------------- */
-    { "uri",                 PTR(uzbl.state.uri,                  STR, cmd_load_uri)},
-    { "mode",                PTR(uzbl.behave.mode,                INT, NULL)},
-    { "inject_html",         PTR(uzbl.behave.inject_html,         STR, cmd_inject_html)},
-    { "base_url",            PTR(uzbl.behave.base_url,            STR, NULL)},
-    { "html_endmarker",      PTR(uzbl.behave.html_endmarker,      STR, NULL)},
-    { "html_mode_timeout",   PTR(uzbl.behave.html_timeout,        INT, NULL)},
-    { "status_message",      PTR(uzbl.gui.sbar.msg,               STR, update_title)},
-    { "show_status",         PTR(uzbl.behave.show_status,         INT, cmd_set_status)},
-    { "status_top",          PTR(uzbl.behave.status_top,          INT, move_statusbar)},
-    { "status_format",       PTR(uzbl.behave.status_format,       STR, update_title)},
-    { "status_pbar_done",    PTR(uzbl.gui.sbar.progress_s,        STR, update_title)},
-    { "status_pbar_pending", PTR(uzbl.gui.sbar.progress_u,        STR, update_title)},
-    { "status_pbar_width",   PTR(uzbl.gui.sbar.progress_w,        INT, update_title)},
-    { "status_background",   PTR(uzbl.behave.status_background,   STR, update_title)},
-    { "title_format_long",   PTR(uzbl.behave.title_format_long,   STR, update_title)},
-    { "title_format_short",  PTR(uzbl.behave.title_format_short,  STR, update_title)},
-    { "insert_mode",         PTR(uzbl.behave.insert_mode,         INT, NULL)},
-    { "always_insert_mode",  PTR(uzbl.behave.always_insert_mode,  INT, cmd_always_insert_mode)},
-    { "reset_command_mode",  PTR(uzbl.behave.reset_command_mode,  INT, NULL)},
-    { "modkey",              PTR(uzbl.behave.modkey,              STR, cmd_modkey)},
-    { "load_finish_handler", PTR(uzbl.behave.load_finish_handler, STR, NULL)},
-    { "load_start_handler",  PTR(uzbl.behave.load_start_handler,  STR, NULL)},
-    { "load_commit_handler", PTR(uzbl.behave.load_commit_handler, STR, NULL)},
-    { "history_handler",     PTR(uzbl.behave.history_handler,     STR, NULL)},
-    { "download_handler",    PTR(uzbl.behave.download_handler,    STR, NULL)},
-    { "cookie_handler",      PTR(uzbl.behave.cookie_handler,      STR, cmd_cookie_handler)},
-    { "fifo_dir",            PTR(uzbl.behave.fifo_dir,            STR, cmd_fifo_dir)},
-    { "socket_dir",          PTR(uzbl.behave.socket_dir,          STR, cmd_socket_dir)},
-    { "http_debug",          PTR(uzbl.behave.http_debug,          INT, cmd_http_debug)},
-    { "shell_cmd",           PTR(uzbl.behave.shell_cmd,           STR, NULL)},
-    { "proxy_url",           PTR(uzbl.net.proxy_url,              STR, set_proxy_url)},
-    { "max_conns",           PTR(uzbl.net.max_conns,              INT, cmd_max_conns)},
-    { "max_conns_host",      PTR(uzbl.net.max_conns_host,         INT, cmd_max_conns_host)},
-    { "useragent",           PTR(uzbl.net.useragent,              STR, cmd_useragent)},
-    /* exported WebKitWebSettings properties*/
-    { "font_size",           PTR(uzbl.behave.font_size,           INT, cmd_font_size)},
-    { "monospace_size",      PTR(uzbl.behave.monospace_size,      INT, cmd_font_size)},
-    { "minimum_font_size",   PTR(uzbl.behave.minimum_font_size,   INT, cmd_minimum_font_size)},
-    { "disable_plugins",     PTR(uzbl.behave.disable_plugins,     INT, cmd_disable_plugins)},
-    { "disable_scripts",     PTR(uzbl.behave.disable_scripts,     INT, cmd_disable_scripts)},
-    { "autoload_images",     PTR(uzbl.behave.autoload_img,        INT, cmd_autoload_img)},
-    { "autoshrink_images",   PTR(uzbl.behave.autoshrink_img,      INT, cmd_autoshrink_img)},
-    { "enable_spellcheck",   PTR(uzbl.behave.enable_spellcheck,   INT, cmd_enable_spellcheck)},
-    { "enable_private",      PTR(uzbl.behave.enable_private,      INT, cmd_enable_private)},
-    { "print_backgrounds",   PTR(uzbl.behave.print_bg,            INT, cmd_print_bg)},
-    { "stylesheet_uri",      PTR(uzbl.behave.style_uri,           STR, cmd_style_uri)},
-    { "resizable_text_areas",PTR(uzbl.behave.resizable_txt,       INT, cmd_resizable_txt)},
-    { "default_encoding",    PTR(uzbl.behave.default_encoding,    STR, cmd_default_encoding)},
-    { "enforce_96_dpi",      PTR(uzbl.behave.enforce_96dpi,       INT, cmd_enforce_96dpi)},
-    { "caret_browsing",      PTR(uzbl.behave.caret_browsing,      INT, cmd_caret_browsing)},
-
-    { NULL,                  {.ptr = NULL, .type = TYPE_INT, .func = NULL}}
+    { "uri",                 PTR(uzbl.state.uri,                  STR,  1,   cmd_load_uri)},
+    { "verbose",             PTR(uzbl.state.verbose,              INT,  1,   NULL)},
+    { "mode",                PTR(uzbl.behave.mode,                INT,  0,   NULL)},
+    { "inject_html",         PTR(uzbl.behave.inject_html,         STR,  0,   cmd_inject_html)},
+    { "base_url",            PTR(uzbl.behave.base_url,            STR,  1,   NULL)},
+    { "html_endmarker",      PTR(uzbl.behave.html_endmarker,      STR,  1,   NULL)},
+    { "html_mode_timeout",   PTR(uzbl.behave.html_timeout,        INT,  1,   NULL)},
+    { "status_message",      PTR(uzbl.gui.sbar.msg,               STR,  1,   update_title)},
+    { "show_status",         PTR(uzbl.behave.show_status,         INT,  1,   cmd_set_status)},
+    { "status_top",          PTR(uzbl.behave.status_top,          INT,  1,   move_statusbar)},
+    { "status_format",       PTR(uzbl.behave.status_format,       STR,  1,   update_title)},
+    { "status_pbar_done",    PTR(uzbl.gui.sbar.progress_s,        STR,  1,   update_title)},
+    { "status_pbar_pending", PTR(uzbl.gui.sbar.progress_u,        STR,  1,   update_title)},
+    { "status_pbar_width",   PTR(uzbl.gui.sbar.progress_w,        INT,  1,   update_title)},
+    { "status_background",   PTR(uzbl.behave.status_background,   STR,  1,   update_title)},
+    { "insert_indicator",    PTR(uzbl.behave.insert_indicator,    STR,  1,   update_title)},
+    { "command_indicator",   PTR(uzbl.behave.cmd_indicator,       STR,  1,   update_title)},
+    { "title_format_long",   PTR(uzbl.behave.title_format_long,   STR,  1,   update_title)},
+    { "title_format_short",  PTR(uzbl.behave.title_format_short,  STR,  1,   update_title)},
+    { "insert_mode",         PTR(uzbl.behave.insert_mode,         INT,  1,   NULL)},
+    { "always_insert_mode",  PTR(uzbl.behave.always_insert_mode,  INT,  1,   cmd_always_insert_mode)},
+    { "reset_command_mode",  PTR(uzbl.behave.reset_command_mode,  INT,  1,   NULL)},
+    { "modkey",              PTR(uzbl.behave.modkey,              STR,  1,   cmd_modkey)},
+    { "load_finish_handler", PTR(uzbl.behave.load_finish_handler, STR,  1,   NULL)},
+    { "load_start_handler",  PTR(uzbl.behave.load_start_handler,  STR,  1,   NULL)},
+    { "load_commit_handler", PTR(uzbl.behave.load_commit_handler, STR,  1,   NULL)},
+    { "history_handler",     PTR(uzbl.behave.history_handler,     STR,  1,   NULL)},
+    { "download_handler",    PTR(uzbl.behave.download_handler,    STR,  1,   NULL)},
+    { "cookie_handler",      PTR(uzbl.behave.cookie_handler,      STR,  1,   cmd_cookie_handler)},
+    { "fifo_dir",            PTR(uzbl.behave.fifo_dir,            STR,  1,   cmd_fifo_dir)},
+    { "socket_dir",          PTR(uzbl.behave.socket_dir,          STR,  1,   cmd_socket_dir)},
+    { "http_debug",          PTR(uzbl.behave.http_debug,          INT,  1,   cmd_http_debug)},
+    { "shell_cmd",           PTR(uzbl.behave.shell_cmd,           STR,  1,   NULL)},
+    { "proxy_url",           PTR(uzbl.net.proxy_url,              STR,  1,   set_proxy_url)},
+    { "max_conns",           PTR(uzbl.net.max_conns,              INT,  1,   cmd_max_conns)},
+    { "max_conns_host",      PTR(uzbl.net.max_conns_host,         INT,  1,   cmd_max_conns_host)},
+    { "useragent",           PTR(uzbl.net.useragent,              STR,  1,   cmd_useragent)},
+    /* exported WebKitWebSettings properties */
+    { "zoom_level",          PTR(uzbl.behave.zoom_level,          FLOAT,1,   cmd_zoom_level)},
+    { "font_size",           PTR(uzbl.behave.font_size,           INT,  1,   cmd_font_size)},
+    { "monospace_size",      PTR(uzbl.behave.monospace_size,      INT,  1,   cmd_font_size)},
+    { "minimum_font_size",   PTR(uzbl.behave.minimum_font_size,   INT,  1,   cmd_minimum_font_size)},
+    { "disable_plugins",     PTR(uzbl.behave.disable_plugins,     INT,  1,   cmd_disable_plugins)},
+    { "disable_scripts",     PTR(uzbl.behave.disable_scripts,     INT,  1,   cmd_disable_scripts)},
+    { "autoload_images",     PTR(uzbl.behave.autoload_img,        INT,  1,   cmd_autoload_img)},
+    { "autoshrink_images",   PTR(uzbl.behave.autoshrink_img,      INT,  1,   cmd_autoshrink_img)},
+    { "enable_spellcheck",   PTR(uzbl.behave.enable_spellcheck,   INT,  1,   cmd_enable_spellcheck)},
+    { "enable_private",      PTR(uzbl.behave.enable_private,      INT,  1,   cmd_enable_private)},
+    { "print_backgrounds",   PTR(uzbl.behave.print_bg,            INT,  1,   cmd_print_bg)},
+    { "stylesheet_uri",      PTR(uzbl.behave.style_uri,           STR,  1,   cmd_style_uri)},
+    { "resizable_text_areas",PTR(uzbl.behave.resizable_txt,       INT,  1,   cmd_resizable_txt)},
+    { "default_encoding",    PTR(uzbl.behave.default_encoding,    STR,  1,   cmd_default_encoding)},
+    { "enforce_96_dpi",      PTR(uzbl.behave.enforce_96dpi,       INT,  1,   cmd_enforce_96dpi)},
+    { "caret_browsing",      PTR(uzbl.behave.caret_browsing,      INT,  1,   cmd_caret_browsing)},
+
+    { NULL,                  {.ptr = NULL, .type = TYPE_INT, .dump = 0, .func = NULL}}
 }, *n2v_p = var_name_to_ptr;
 
 const struct {
@@ -183,8 +187,51 @@ make_var_to_name_hash() {
     }
 }
 
-
 /* --- UTILITY FUNCTIONS --- */
+static gchar *
+expand_vars(char *s) {
+    uzbl_cmdprop *c;
+    char upto = ' ';
+    char ret[256],  *vend;
+    GString *buf = g_string_new("");
+
+    while(*s) {
+        switch(*s) {
+            case '\\':
+                g_string_append_c(buf, *++s);
+                s++;
+                break;
+            case '@':
+                if(*(s+1) == '{') {
+                    upto = '}'; s++;
+                }
+                s++;
+                if( (vend = strchr(s, upto)) ||
+                        (vend = strchr(s, '\0')) ) {
+                    strncpy(ret, s, vend-s);
+                    ret[vend-s] = '\0';
+                    if( (c = g_hash_table_lookup(uzbl.comm.proto_var, ret)) ) {
+                        if(c->type == TYPE_STR)
+                            g_string_append(buf, (gchar *)*c->ptr);
+                        else if(c->type == TYPE_INT) {
+                            char *b = itos((int)*c->ptr);
+                            g_string_append(buf, b);
+                            g_free(b);
+                        }
+                    }
+                    if(upto == ' ') s = vend;
+                    else s = vend+1;
+                    upto = ' ';
+                }
+                break;
+            default:
+                g_string_append_c(buf, *s);
+                s++;
+                break;
+        }
+    }
+    return g_string_free(buf, FALSE);
+}
 
 char *
 itos(int val) {
@@ -345,6 +392,23 @@ new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequ
     return (FALSE);
 }
 
+static gboolean
+mime_policy_cb(WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, gchar *mime_type,  WebKitWebPolicyDecision *policy_decision, gpointer user_data) {
+    (void) frame;
+    (void) request;
+    (void) user_data;
+
+    /* If we can display it, let's display it... */
+    if (webkit_web_view_can_show_mime_type (web_view, mime_type)) {
+        webkit_web_policy_decision_use (policy_decision);
+        return TRUE;
+    }
+
+    /* ...everything we can't displayed is downloaded */
+    webkit_web_policy_decision_download (policy_decision);
+    return TRUE;
+}
+
 WebKitWebView*
 create_web_view_cb (WebKitWebView  *web_view, WebKitWebFrame *frame, gpointer user_data) {
     (void) web_view;
@@ -386,23 +450,27 @@ scroll (GtkAdjustment* bar, GArray *argv) {
     gtk_adjustment_set_value (bar, gtk_adjustment_get_value(bar)+amount);
 }
 
-static void scroll_begin(WebKitWebView* page, GArray *argv) {
+static void
+scroll_begin(WebKitWebView* page, GArray *argv) {
     (void) page; (void) argv;
     gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_lower(uzbl.gui.bar_v));
 }
 
-static void scroll_end(WebKitWebView* page, GArray *argv) {
+static void
+scroll_end(WebKitWebView* page, GArray *argv) {
     (void) page; (void) argv;
     gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_upper(uzbl.gui.bar_v) -
                               gtk_adjustment_get_page_size(uzbl.gui.bar_v));
 }
 
-static void scroll_vert(WebKitWebView* page, GArray *argv) {
+static void
+scroll_vert(WebKitWebView* page, GArray *argv) {
     (void) page;
     scroll(uzbl.gui.bar_v, argv);
 }
 
-static void scroll_horz(WebKitWebView* page, GArray *argv) {
+static void
+scroll_horz(WebKitWebView* page, GArray *argv) {
     (void) page;
     scroll(uzbl.gui.bar_h, argv);
 }
@@ -478,6 +546,7 @@ load_start_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data) {
     (void) page;
     (void) frame;
     (void) data;
+    uzbl.gui.sbar.load_progress = 0;
     g_string_truncate(uzbl.state.keycmd, 0); // don't need old commands to remain on new page?
     if (uzbl.behave.load_start_handler)
         run_handler(uzbl.behave.load_start_handler, "");
@@ -531,7 +600,6 @@ VIEWFUNC(go_forward)
 #undef VIEWFUNC
 
 /* -- command to callback/function map for things we cannot attach to any signals */
-// TODO: reload
 static struct {char *name; Command command[2];} cmdlist[] =
 {   /* key                   function      no_split      */
     { "back",               {view_go_back, 0}              },
@@ -558,8 +626,15 @@ static struct {char *name; Command command[2];} cmdlist[] =
     { "search_reverse",     {search_reverse_text, NOSPLIT} },
     { "dehilight",          {dehilight, 0}                 },
     { "toggle_insert_mode", {toggle_insert_mode, 0}        },
-    { "runcmd",             {runcmd, NOSPLIT}              },
-    { "set",                {set_var, NOSPLIT}          }
+    { "set",                {set_var, NOSPLIT}             },
+    //{ "get",                {get_var, NOSPLIT}             },
+    { "bind",               {act_bind, NOSPLIT}            },
+    { "dump_config",        {act_dump_config, 0}           },
+    { "keycmd",             {keycmd, NOSPLIT}              },
+    { "keycmd_nl",          {keycmd_nl, NOSPLIT}           },
+    { "keycmd_bs",          {keycmd_bs, 0}                 },
+    { "chain",              {chain, 0}                     },
+    { "print",              {print, NOSPLIT}               }
 };
 
 static void
@@ -604,11 +679,37 @@ file_exists (const char * filename) {
 static void
 set_var(WebKitWebView *page, GArray *argv) {
     (void) page;
-    gchar *ctl_line;
+    gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2);
+    gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " "));
+    set_var_value(g_strstrip(split[0]), value);
+    g_free(value);
+    g_strfreev(split);
+}
 
-    ctl_line = g_strdup_printf("%s %s", "set", argv_idx(argv, 0));
-    parse_cmd_line(ctl_line);
-    g_free(ctl_line);
+static void
+print(WebKitWebView *page, GArray *argv) {
+    (void) page;
+    gchar* buf;
+
+    buf = expand_vars(argv_idx(argv, 0));
+    puts(buf);
+    g_free(buf);
+}
+
+static void
+act_bind(WebKitWebView *page, GArray *argv) {
+    (void) page;
+    gchar **split = g_strsplit(argv_idx(argv, 0), " = ", 2);
+    gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " "));
+    add_binding(g_strstrip(split[0]), value);
+    g_free(value);
+    g_strfreev(split);
+}
+
+
+static void
+act_dump_config() {
+    dump_config();
 }
 
 static void
@@ -632,7 +733,11 @@ static void
 load_uri (WebKitWebView *web_view, GArray *argv) {
     if (argv_idx(argv, 0)) {
         GString* newuri = g_string_new (argv_idx(argv, 0));
-        if (g_strrstr (argv_idx(argv, 0), "://") == NULL)
+        if (g_strstr_len (argv_idx(argv, 0), 11, "javascript:") != NULL) {
+            run_js(web_view, argv);
+            return;
+        }
+        if (g_strrstr (argv_idx(argv, 0), "://") == NULL && g_strstr_len (argv_idx(argv, 0), 5, "data:") == NULL)
             g_string_prepend (newuri, "http://");
         /* if we do handle cookies, ask our handler for them */
         webkit_web_view_load_uri (web_view, newuri->str);
@@ -734,6 +839,45 @@ new_window_load_uri (const gchar * uri) {
 }
 
 static void
+chain (WebKitWebView *page, GArray *argv) {
+    (void)page;
+    gchar *a = NULL;
+    gchar **parts = NULL;
+    guint i = 0;    
+    while ((a = argv_idx(argv, i++))) {
+        parts = g_strsplit (a, " ", 2);
+        parse_command(parts[0], parts[1]);
+        g_strfreev (parts);
+    }
+}
+
+static void
+keycmd (WebKitWebView *page, GArray *argv) {
+    (void)page;
+    (void)argv;
+    g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0));
+    run_keycmd(FALSE);
+    update_title();
+}
+
+static void
+keycmd_nl (WebKitWebView *page, GArray *argv) {
+    (void)page;
+    (void)argv;
+    g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0));
+    run_keycmd(TRUE);
+    update_title();
+}
+
+static void
+keycmd_bs (WebKitWebView *page, GArray *argv) {
+    (void)page;
+    (void)argv;
+    g_string_truncate(uzbl.state.keycmd, uzbl.state.keycmd->len - 1);
+    update_title();
+}
+
+static void
 close_uzbl (WebKitWebView *page, GArray *argv) {
     (void)page;
     (void)argv;
@@ -829,7 +973,7 @@ expand_template(const char *template, gboolean escape_markup) {
          token = g_scanner_get_next_token(uzbl.scan);
 
          if(token == G_TOKEN_SYMBOL) {
-             sym = (int)g_scanner_cur_value(uzbl.scan).v_symbol;
+             sym = GPOINTER_TO_INT(g_scanner_cur_value(uzbl.scan).v_symbol);
              switch(sym) {
                  case SYM_URI:
                      if(escape_markup) {
@@ -893,7 +1037,8 @@ expand_template(const char *template, gboolean escape_markup) {
                      break;
                  case SYM_MODE:
                      g_string_append(ret,
-                             uzbl.behave.insert_mode?"[I]":"[C]");
+                             uzbl.behave.insert_mode?
+                             uzbl.behave.insert_indicator:uzbl.behave.cmd_indicator);
                      break;
                  case SYM_MSG:
                      g_string_append(ret,
@@ -971,7 +1116,7 @@ sharg_append(GArray *a, const gchar *str) {
 // make sure that the args string you pass can properly be interpreted (eg properly escaped against whitespace, quotes etc)
 static gboolean
 run_command (const gchar *command, const guint npre, const gchar **args,
-             const gboolean sync, char **stdout) {
+             const gboolean sync, char **output_stdout) {
    //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
     GError *err = NULL;
     
@@ -995,10 +1140,10 @@ run_command (const gchar *command, const guint npre, const gchar **args,
     
     gboolean result;
     if (sync) {
-        if (*stdout) *stdout = strfree(*stdout);
+        if (*output_stdout) *output_stdout = strfree(*output_stdout);
         
         result = g_spawn_sync(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
-                              NULL, NULL, stdout, NULL, NULL, &err);
+                              NULL, NULL, output_stdout, NULL, NULL, &err);
     } else result = g_spawn_async(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
                                   NULL, NULL, NULL, &err);
 
@@ -1012,6 +1157,9 @@ run_command (const gchar *command, const guint npre, const gchar **args,
         g_string_append_printf(s, " -- result: %s", (result ? "true" : "false"));
         printf("%s\n", s->str);
         g_string_free(s, TRUE);
+        if(output_stdout) {
+            printf("Stdout: %s\n", *output_stdout);
+        }
     }
     if (err) {
         g_printerr("error on run_command: %s\n", err->message);
@@ -1144,34 +1292,6 @@ parse_command(const char *cmd, const char *param) {
         g_printerr ("command \"%s\" not understood. ignoring.\n", cmd);
 }
 
-/* command parser */
-static void
-setup_regex() {
-    uzbl.comm.get_regex  = g_regex_new("^[Gg][a-zA-Z]*\\s+([^ \\n]+)$",
-            G_REGEX_OPTIMIZE, 0, NULL);
-    uzbl.comm.set_regex  = g_regex_new("^[Ss][a-zA-Z]*\\s+([^ ]+)\\s*=\\s*([^\\n].*)$",
-            G_REGEX_OPTIMIZE, 0, NULL);
-    uzbl.comm.bind_regex = g_regex_new("^[Bb][a-zA-Z]*\\s+?(.*[^ ])\\s*?=\\s*([a-z][^\\n].+)$",
-            G_REGEX_UNGREEDY|G_REGEX_OPTIMIZE, 0, NULL);
-    uzbl.comm.act_regex = g_regex_new("^[Aa][a-zA-Z]*\\s+([^ \\n]+)\\s*([^\\n]*)?$",
-            G_REGEX_OPTIMIZE, 0, NULL);
-    uzbl.comm.keycmd_regex = g_regex_new("^[Kk][a-zA-Z]*\\s+([^\\n]+)$",
-            G_REGEX_OPTIMIZE, 0, NULL);
-}
-
-static gboolean
-get_var_value(gchar *name) {
-    uzbl_cmdprop *c;
-
-    if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
-        if(c->type == TYPE_STR)
-            printf("VAR: %s VALUE: %s\n", name, (char *)*c->ptr);
-        else if(c->type == TYPE_INT)
-            printf("VAR: %s VALUE: %d\n", name, (int)*c->ptr);
-    }
-    return TRUE;
-}
-
 static void
 set_proxy_url() {
     SoupURI *suri;
@@ -1252,6 +1372,11 @@ cmd_font_size() {
 }
 
 static void
+cmd_zoom_level() {
+    webkit_web_view_set_zoom_level (uzbl.gui.web_view, uzbl.behave.zoom_level);
+}
+
+static void
 cmd_disable_plugins() {
     g_object_set (G_OBJECT(view_settings()), "enable-plugins", 
             !uzbl.behave.disable_plugins, NULL);
@@ -1260,7 +1385,7 @@ cmd_disable_plugins() {
 static void
 cmd_disable_scripts() {
     g_object_set (G_OBJECT(view_settings()), "enable-scripts",
-            !uzbl.behave.disable_plugins, NULL);
+            !uzbl.behave.disable_scripts, NULL);
 }
 
 static void
@@ -1333,6 +1458,7 @@ cmd_caret_browsing() {
 static void
 cmd_cookie_handler() {
     gchar **split = g_strsplit(uzbl.behave.cookie_handler, " ", 2);
+    /* pitfall: doesn't handle chain actions; must the sync_ action manually */
     if ((g_strcmp0(split[0], "sh") == 0) ||
         (g_strcmp0(split[0], "spawn") == 0)) {
         g_free (uzbl.behave.cookie_handler);
@@ -1417,15 +1543,24 @@ static gboolean
 set_var_value(gchar *name, gchar *val) {
     uzbl_cmdprop *c = NULL;
     char *endp = NULL;
+    char *buf = NULL;
 
     if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
         /* check for the variable type */
         if (c->type == TYPE_STR) {
+            buf = expand_vars(val);
             g_free(*c->ptr);
-            *c->ptr = g_strdup(val);
+            *c->ptr = buf;
         } else if(c->type == TYPE_INT) {
             int *ip = (int *)c->ptr;
-            *ip = (int)strtoul(val, &endp, 10);
+            buf = expand_vars(val);
+            *ip = (int)strtoul(buf, &endp, 10);
+            g_free(buf);
+        } else if (c->type == TYPE_FLOAT) {
+            float *fp = (float *)c->ptr;
+            buf = expand_vars(val);
+            *fp = strtod(buf, &endp);
+            g_free(buf);
         }
 
         /* invoke a command specific function */
@@ -1435,12 +1570,6 @@ set_var_value(gchar *name, gchar *val) {
 }
 
 static void
-runcmd(WebKitWebView* page, GArray *argv) {
-    (void) page;
-    parse_cmd_line(argv_idx(argv, 0));
-}
-
-static void
 render_html() {
     Behaviour *b = &uzbl.behave;
 
@@ -1455,90 +1584,42 @@ render_html() {
 enum {M_CMD, M_HTML};
 static void
 parse_cmd_line(const char *ctl_line) {
-    gchar **tokens = NULL;
     Behaviour *b = &uzbl.behave;
+    size_t len=0;
 
     if(b->mode == M_HTML) {
-
-        if(!strncmp(b->html_endmarker, ctl_line, strlen(b->html_endmarker))) {
+        len = strlen(b->html_endmarker);
+        /* ctl_line has trailing '\n' so we check for strlen(ctl_line)-1 */
+        if(len == strlen(ctl_line)-1 &&
+           !strncmp(b->html_endmarker, ctl_line, len)) {
             set_timeout(0);
             set_var_value("mode", "0");
             render_html();
             return;
         }
         else {
-            /* set an alarm to kill us after the timeout */
             set_timeout(b->html_timeout);
             g_string_append(b->html_buffer, ctl_line);
         }
     }
-    else {
-        /* SET command */
-        if(ctl_line[0] == 's' || ctl_line[0] == 'S') {
-            tokens = g_regex_split(uzbl.comm.set_regex, ctl_line, 0);
-            if(tokens[0][0] == 0) {
-                gchar* value = parseenv(g_strdup(tokens[2]));
-                set_var_value(tokens[1], value);
-                g_free(value);
-            }
-            else
-                printf("Error in command: %s\n", tokens[0]);
-        }
-        /* GET command */
-        else if(ctl_line[0] == 'g' || ctl_line[0] == 'G') {
-            tokens = g_regex_split(uzbl.comm.get_regex, ctl_line, 0);
-            if(tokens[0][0] == 0) {
-                get_var_value(tokens[1]);
-            }
-            else
-                printf("Error in command: %s\n", tokens[0]);
-        }
-        /* BIND command */
-        else if(ctl_line[0] == 'b' || ctl_line[0] == 'B') {
-            tokens = g_regex_split(uzbl.comm.bind_regex, ctl_line, 0);
-            if(tokens[0][0] == 0) {
-                gchar* value = parseenv(g_strdup(tokens[2]));
-                add_binding(tokens[1], value);
-                g_free(value);
-            }
-            else
-                printf("Error in command: %s\n", tokens[0]);
-        }
-        /* ACT command */
-        else if(ctl_line[0] == 'A' || ctl_line[0] == 'a') {
-            tokens = g_regex_split(uzbl.comm.act_regex, ctl_line, 0);
-            if(tokens[0][0] == 0) {
-                parse_command(tokens[1], tokens[2]);
-            }
-            else
-                printf("Error in command: %s\n", tokens[0]);
-        }
-        /* KEYCMD command */
-        else if(ctl_line[0] == 'K' || ctl_line[0] == 'k') {
-            tokens = g_regex_split(uzbl.comm.keycmd_regex, ctl_line, 0);
-            if(tokens[0][0] == 0) {
-                /* should incremental commands want each individual "keystroke"
-                   sent in a loop or the whole string in one go like now? */
-                g_string_assign(uzbl.state.keycmd, tokens[1]);
-                run_keycmd(FALSE);
-                if (g_strstr_len(ctl_line, 7, "n") || g_strstr_len(ctl_line, 7, "N"))
-                    run_keycmd(TRUE);
-                update_title();
-            }
-        }
-        /* Comments */
-        else if(   (ctl_line[0] == '#')
-                || (ctl_line[0] == ' ')
-                || (ctl_line[0] == '\n'))
-            ; /* ignore these lines */
-        else
-            printf("Command not understood (%s)\n", ctl_line);
-
-        if(tokens)
-            g_strfreev(tokens);
+    else if((ctl_line[0] == '#') /* Comments */
+            || (ctl_line[0] == ' ')
+            || (ctl_line[0] == '\n'))
+        ; /* ignore these lines */
+    else { /* parse a command */
+        gchar *ctlstrip;
+        gchar **tokens = NULL;
+        len = strlen(ctl_line);
+
+        if (ctl_line[len - 1] == '\n') /* strip trailing newline */
+            ctlstrip = g_strndup(ctl_line, len - 1);
+        else ctlstrip = g_strdup(ctl_line);
+
+        tokens = g_strsplit(ctlstrip, " ", 2);
+        parse_command(tokens[0], tokens[1]);
+        g_free(ctlstrip);
+        g_strfreev(tokens);
     }
-
-    return;
 }
 
 static gchar*
@@ -1840,10 +1921,8 @@ key_press_cb (GtkWidget* window, GdkEventKey* event)
         return TRUE;
     }
 
-    if ((event->keyval == GDK_BackSpace) && (uzbl.state.keycmd->len > 0)) {
-        g_string_truncate(uzbl.state.keycmd, uzbl.state.keycmd->len - 1);
-        update_title();
-    }
+    if (event->keyval == GDK_BackSpace)
+        keycmd_bs(NULL, NULL);
 
     gboolean key_ret = FALSE;
     if ((event->keyval == GDK_Return) || (event->keyval == GDK_KP_Enter))
@@ -1932,6 +2011,7 @@ create_browser () {
     g_signal_connect (G_OBJECT (g->web_view), "new-window-policy-decision-requested", G_CALLBACK (new_window_cb), g->web_view);
     g_signal_connect (G_OBJECT (g->web_view), "download-requested", G_CALLBACK (download_cb), g->web_view);
     g_signal_connect (G_OBJECT (g->web_view), "create-web-view", G_CALLBACK (create_web_view_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "mime-type-policy-decision-requested", G_CALLBACK (mime_policy_cb), g->web_view);
 
     return scrolled_window;
 }
@@ -1951,6 +2031,7 @@ create_mainbar () {
     gtk_misc_set_alignment (GTK_MISC(g->mainbar_label), 0, 0);
     gtk_misc_set_padding (GTK_MISC(g->mainbar_label), 2, 2);
     gtk_box_pack_start (GTK_BOX (g->mainbar), g->mainbar_label, TRUE, TRUE, 0);
+    g_signal_connect (G_OBJECT (g->mainbar), "key-press-event", G_CALLBACK (key_press_cb), NULL);
     return g->mainbar;
 }
 
@@ -1965,29 +2046,105 @@ GtkWidget* create_window () {
     return window;
 }
 
+static gchar**
+inject_handler_args(const gchar *actname, const gchar *origargs, const gchar *newargs) {
+    /*
+      If actname is one that calls an external command, this function will inject
+      newargs in front of the user-provided args in that command line.  They will
+      come become after the body of the script (in sh) or after the name of
+      the command to execute (in spawn).
+      i.e. sh <body> <userargs> becomes sh <body> <ARGS> <userargs> and
+      span <command> <userargs> becomes spawn <command> <ARGS> <userargs>.
+
+      The return value consist of two strings: the action (sh, ...) and its args.
+
+      If act is not one that calls an external command, then the given action merely
+      gets duplicated.
+    */
+    GArray *rets = g_array_new(TRUE, FALSE, sizeof(gchar*));
+    gchar *actdup = g_strdup(actname);
+    g_array_append_val(rets, actdup);
+
+    if ((g_strcmp0(actname, "spawn") == 0) ||
+        (g_strcmp0(actname, "sh") == 0) ||
+        (g_strcmp0(actname, "sync_spawn") == 0) ||
+        (g_strcmp0(actname, "sync_sh") == 0)) {
+        guint i;
+        GString *a = g_string_new("");
+        gchar **spawnparts = split_quoted(origargs, FALSE);
+        g_string_append_printf(a, "%s", spawnparts[0]); /* sh body or script name */
+        if (newargs) g_string_append_printf(a, " %s", newargs); /* handler args */
+
+        for (i = 1; i < g_strv_length(spawnparts); i++) /* user args */
+            if (spawnparts[i]) g_string_append_printf(a, " %s", spawnparts[i]);
+
+        g_array_append_val(rets, a->str);
+        g_string_free(a, FALSE);
+        g_strfreev(spawnparts);
+    } else {
+        gchar *origdup = g_strdup(origargs);
+        g_array_append_val(rets, origdup);
+    }
+    return (gchar**)g_array_free(rets, FALSE);
+}
+
 static void
 run_handler (const gchar *act, const gchar *args) {
+    /* Consider this code a temporary hack to make the handlers usable.
+       In practice, all this splicing, injection, and reconstruction is
+       inefficient, annoying and hard to manage.  Potential pitfalls arise
+       when the handler specific args 1) are not quoted  (the handler
+       callbacks should take care of this)  2) are quoted but interfere
+       with the users' own quotation.  A more ideal solution is
+       to refactor parse_command so that it doesn't just take a string
+       and execute it; rather than that, we should have a function which
+       returns the argument vector parsed from the string.  This vector
+       could be modified (e.g. insert additional args into it) before
+       passing it to the next function that actually executes it.  Though
+       it still isn't perfect for chain actions..  will reconsider & re-
+       factor when I have the time. -duc */
+
     char **parts = g_strsplit(act, " ", 2);
     if (!parts) return;
-    else if ((g_strcmp0(parts[0], "spawn") == 0)
-             || (g_strcmp0(parts[0], "sh") == 0)
-             || (g_strcmp0(parts[0], "sync_spawn") == 0)
-             || (g_strcmp0(parts[0], "sync_sh") == 0)) {
-        guint i;
-        GString *a = g_string_new ("");
-        char **spawnparts;
-        spawnparts = split_quoted(parts[1], FALSE);
-        g_string_append_printf(a, "%s", spawnparts[0]);
-        if (args) g_string_append_printf(a, " %s", args); /* append handler args before user args */
+    if (g_strcmp0(parts[0], "chain") == 0) {
+        GString *newargs = g_string_new("");
+        gchar **chainparts = split_quoted(parts[1], FALSE);
         
-        for (i = 1; i < g_strv_length(spawnparts); i++) /* user args */
-            g_string_append_printf(a, " %s", spawnparts[i]);
-        parse_command(parts[0], a->str);
-        g_string_free (a, TRUE);
-        g_strfreev (spawnparts);
-    } else
-        parse_command(parts[0], parts[1]);
-    g_strfreev (parts);
+        /* for every argument in the chain, inject the handler args
+           and make sure the new parts are wrapped in quotes */
+        gchar **cp = chainparts;
+        gchar quot = '\'';
+        gchar *quotless = NULL;
+        gchar **spliced_quotless = NULL; // sigh -_-;
+        gchar **inpart = NULL;
+        
+        while (*cp) {
+            if ((**cp == '\'') || (**cp == '\"')) { /* strip old quotes */
+                quot = **cp;
+                quotless = g_strndup(&(*cp)[1], strlen(*cp) - 2);
+            } else quotless = g_strdup(*cp);
+
+            spliced_quotless = g_strsplit(quotless, " ", 2);
+            inpart = inject_handler_args(spliced_quotless[0], spliced_quotless[1], args);
+            g_strfreev(spliced_quotless);
+            
+            g_string_append_printf(newargs, " %c%s %s%c", quot, inpart[0], inpart[1], quot);
+            g_free(quotless);
+            g_strfreev(inpart);
+            cp++;
+        }
+
+        parse_command(parts[0], &(newargs->str[1]));
+        g_string_free(newargs, TRUE);
+        g_strfreev(chainparts);
+        
+    } else {
+        gchar **inparts = inject_handler_args(parts[0], parts[1], args);
+        parse_command(inparts[0], inparts[1]);
+        g_free(inparts[0]);
+        g_free(inparts[1]);
+    }
+    g_strfreev(parts);
 }
 
 static void
@@ -2003,6 +2160,8 @@ add_binding (const gchar *key, const gchar *act) {
         printf ("Binding %-10s : %s\n", key, act);
     action = new_action(parts[0], parts[1]);
 
+    if (g_hash_table_remove (uzbl.bindings, key))
+        g_warning ("Overwriting existing binding for \"%s\"", key);
     g_hash_table_replace(uzbl.bindings, g_strdup(key), action);
     g_strfreev(parts);
 }
@@ -2086,13 +2245,14 @@ settings_init () {
             printf ("No configuration file loaded.\n");
     }
 
-    g_signal_connect(n->soup_session, "request-queued", G_CALLBACK(handle_cookies), NULL);
+    g_signal_connect_after(n->soup_session, "request-started", G_CALLBACK(handle_cookies), NULL);
 }
 
 static void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data){
     (void) session;
     (void) user_data;
-    if (!uzbl.behave.cookie_handler) return;
+    if (!uzbl.behave.cookie_handler)
+         return;
 
     soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies), NULL);
     GString *s = g_string_new ("");
@@ -2100,10 +2260,13 @@ static void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer use
     g_string_printf(s, "GET '%s' '%s'", soup_uri->host, soup_uri->path);
     run_handler(uzbl.behave.cookie_handler, s->str);
 
-    if(uzbl.comm.sync_stdout)
-        soup_message_headers_replace (msg->request_headers, "Cookie", uzbl.comm.sync_stdout);
-    //printf("stdout: %s\n", uzbl.comm.sync_stdout);   // debugging
-    if (uzbl.comm.sync_stdout) uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
+    if(uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) {
+        char *p = strchr(uzbl.comm.sync_stdout, '\n' );
+        if ( p != NULL ) *p = '\0';
+        soup_message_headers_replace (msg->request_headers, "Cookie", (const char *) uzbl.comm.sync_stdout);
+    }
+    if (uzbl.comm.sync_stdout)
+        uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
         
     g_string_free(s, TRUE);
 }
@@ -2217,7 +2380,34 @@ set_up_inspector() {
     g_signal_connect (G_OBJECT (g->inspector), "notify::inspected-uri", G_CALLBACK (inspector_uri_changed_cb), NULL);
 }
 
+static void
+dump_var_hash(gpointer k, gpointer v, gpointer ud) {
+    (void) ud;
+    uzbl_cmdprop *c = v;
 
+    if(!c->dump)
+        return;
+
+    if(c->type == TYPE_STR)
+        printf("set %s = %s\n", (char *)k, *c->ptr?(char *)*c->ptr:" ");
+    else if(c->type == TYPE_INT)
+        printf("set %s = %d\n", (char *)k, (int)*c->ptr);
+}
+
+static void
+dump_key_hash(gpointer k, gpointer v, gpointer ud) {
+    (void) ud;
+    Action *a = v;
+
+    printf("bind %s = %s %s\n", (char *)k ,
+            (char *)a->name, a->param?(char *)a->param:"");
+}
+
+static void
+dump_config() {
+    g_hash_table_foreach(uzbl.comm.proto_var, dump_var_hash, NULL);
+    g_hash_table_foreach(uzbl.bindings, dump_key_hash, NULL);
+}
 
 /** -- MAIN -- **/
 int
@@ -2234,6 +2424,10 @@ main (int argc, char* argv[]) {
     g_option_context_add_group (context, gtk_get_option_group (TRUE));
     g_option_context_parse (context, &argc, &argv, NULL);
     g_option_context_free(context);
+    
+    gchar *uri_override = (uzbl.state.uri ? g_strdup(uzbl.state.uri) : NULL);
+    gboolean verbose_override = uzbl.state.verbose;
+
     /* initialize hash table */
     uzbl.bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action);
 
@@ -2261,7 +2455,10 @@ main (int argc, char* argv[]) {
     uzbl.behave.html_timeout = 60;
     uzbl.behave.base_url = g_strdup("http://invalid");
 
-    setup_regex();
+    /* default mode indicators */
+    uzbl.behave.insert_indicator = g_strdup("I");
+    uzbl.behave.cmd_indicator    = g_strdup("C");
+
     setup_scanner();
     commands_hash ();
     make_var_to_name_hash();
@@ -2308,12 +2505,14 @@ main (int argc, char* argv[]) {
 
     create_stdin();
 
-    if(uzbl.state.uri) {
-        GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
-        g_array_append_val(a, uzbl.state.uri);
-        load_uri (uzbl.gui.web_view, a);
-        g_array_free (a, TRUE);
-    }
+    if (verbose_override > uzbl.state.verbose)
+        uzbl.state.verbose = verbose_override;
+    
+    if (uri_override) {
+        set_var_value("uri", uri_override);
+        g_free(uri_override);
+    } else if (uzbl.state.uri)
+        cmd_load_uri(uzbl.gui.web_view, NULL);
 
     gtk_main ();
     clean_up();
diff --git a/uzbl.h b/uzbl.h
index cd5e3ef..a6a3a6e 100644 (file)
--- a/uzbl.h
+++ b/uzbl.h
@@ -93,12 +93,6 @@ typedef struct {
     gchar          *socket_path;
     /* stores (key)"variable name" -> (value)"pointer to this var*/
     GHashTable     *proto_var;
-    /* command parsing regexes */
-    GRegex         *set_regex;
-    GRegex         *act_regex;
-    GRegex         *keycmd_regex;
-    GRegex         *get_regex;
-    GRegex         *bind_regex;
     gchar          *sync_stdout;
 } Communication;
 
@@ -155,6 +149,7 @@ typedef struct {
     guint    font_size;
     guint    monospace_size;
     guint    minimum_font_size;
+    gfloat   zoom_level;
     guint    disable_plugins;
     guint    disable_scripts;
     guint    autoload_img;    
@@ -171,6 +166,8 @@ typedef struct {
     guint    mode;  
     gchar*   base_url;
     gchar*   html_endmarker;
+    gchar*   insert_indicator;
+    gchar*   cmd_indicator;
     GString* html_buffer;
     guint    html_timeout;  
 
@@ -246,9 +243,15 @@ setup_signal(int signe, sigfunc *shandler);
 static gboolean
 set_var_value(gchar *name, gchar *val);
 
+static void
+print(WebKitWebView *page, GArray *argv);
+
 static gboolean
 new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *navigation_action, WebKitWebPolicyDecision *policy_decision, gpointer user_data);
 
+static gboolean
+mime_policy_cb(WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, gchar *mime_type,  WebKitWebPolicyDecision *policy_decision, gpointer user_data);
+
 WebKitWebView*
 create_web_view_cb (WebKitWebView  *web_view, WebKitWebFrame *frame, gpointer user_data);
 
@@ -304,11 +307,23 @@ static void
 new_window_load_uri (const gchar * uri);
 
 static void
+chain (WebKitWebView *page, GArray *argv);
+
+static void
+keycmd (WebKitWebView *page, GArray *argv);
+
+static void
+keycmd_nl (WebKitWebView *page, GArray *argv);
+
+static void
+keycmd_bs (WebKitWebView *page, GArray *argv);
+
+static void
 close_uzbl (WebKitWebView *page, GArray *argv);
 
 static gboolean
 run_command(const gchar *command, const guint npre,
-            const gchar **args, const gboolean sync, char **stdout);
+            const gchar **args, const gboolean sync, char **output_stdout);
 
 static void
 spawn(WebKitWebView *web_view, GArray *argv);
@@ -326,9 +341,6 @@ static void
 parse_command(const char *cmd, const char *param);
 
 static void
-runcmd(WebKitWebView *page, GArray *argv);
-
-static void
 parse_cmd_line(const char *ctl_line);
 
 static gchar*
@@ -417,11 +429,26 @@ static void
 set_var(WebKitWebView *page, GArray *argv);
 
 static void
+act_bind(WebKitWebView *page, GArray *argv);
+
+static void
+act_dump_config();
+
+static void
 render_html();
 
 static void
 set_timeout(int seconds);
 
+static void
+dump_var_hash(gpointer k, gpointer v, gpointer ud);
+
+static void
+dump_key_hash(gpointer k, gpointer v, gpointer ud);
+
+static void
+dump_config();
+
 
 /* Command callbacks */
 static void
@@ -451,10 +478,15 @@ cmd_max_conns();
 static void
 cmd_max_conns_host();
 
+/* exported WebKitWebSettings properties */
+
 static void
 cmd_font_size();
 
 static void
+cmd_zoom_level();
+
+static void
 cmd_disable_plugins();
 
 static void
index 55a3aac..f0fe732 100644 (file)
@@ -23,7 +23,7 @@ static gchar* command;
 
 static GOptionEntry entries[] =
 {
-    { "socket",  's', 0, G_OPTION_ARG_STRING, &sockpath, "Socket path of the client uzbl", NULL },
+    { "socket",  's', 0, G_OPTION_ARG_STRING, &sockpath, "Path to the uzbl socket",        NULL },
     { "command", 'c', 0, G_OPTION_ARG_STRING, &command,  "The uzbl command to execute",    NULL },
     { NULL,       0,  0, 0,                    NULL,      NULL,                            NULL }
 };
@@ -31,7 +31,7 @@ static GOptionEntry entries[] =
 int
 main(int argc, char* argv[]) {
     GError *error = NULL;
-    GOptionContext* context = g_option_context_new ("- some stuff here maybe someday");
+    GOptionContext* context = g_option_context_new ("- utility for controlling and interacting with uzbl through its socket file"); //TODO: get stuff back from uzbl
     g_option_context_add_main_entries (context, entries, NULL);
     g_option_context_add_group        (context, gtk_get_option_group (TRUE));
     g_option_context_parse            (context, &argc, &argv, &error);
@@ -64,8 +64,7 @@ main(int argc, char* argv[]) {
         
         return 0;
     } else {
-        printf ("You need to specify the -s and -c parameters for uzblctrl to do anything of use.\n");
-        printf ("Usage: uzblctrl -s /path/to/socket -c \"command\"\n");
+        puts ("Usage: uzblctrl -s /path/to/socket -c \"command\"");
         return 1;
     }
 }