Merge branch 'experimental' of git://github.com/Dieterbe/uzbl
authorRobert Manea <gotmor@gmail.com>
Tue, 26 May 2009 21:13:39 +0000 (23:13 +0200)
committerRobert Manea <gotmor@gmail.com>
Tue, 26 May 2009 21:13:39 +0000 (23:13 +0200)
AUTHORS
README
config.h
docs/FAQ
examples/configs/sampleconfig-dev
examples/scripts/formfiller.pl [new file with mode: 0755]
examples/scripts/linkfollow.js [new file with mode: 0644]
examples/scripts/uzblcat [new file with mode: 0755]
uzbl.c
uzbl.h

diff --git a/AUTHORS b/AUTHORS
index ca9e102..2212a87 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,7 +15,8 @@ Contributors:
     Damien Leon - misc
     Peter Suschlik - backwards searching
     (salinasv) - move some variables to heap
-    Sylvester Johansson (scj) - original form filler script
+    Sylvester Johansson (scj) - form filler script & different take on link follower 
+    (mxf) - uzblcat
 
 Originaly based on http://trac.webkit.org/browser/trunk/WebKitTools/GtkLauncher/main.c
 Which is  copyrighted:
diff --git a/README b/README
index 893ef1a..71cdcfa 100644 (file)
--- a/README
+++ b/README
@@ -55,6 +55,7 @@ Time to change that!
 ### CONFIGURATION / CONTROL:
 The general idea is that uzbl by default is very bare bones.  you can send it commands to update settings and perform actions, through various interfaces.
 There is a limited default configuration.  Please see config.h to see what it contains.
+By default, there are *no* keybinds defined at all.  (Default keybinds would work counterproductive when you try to customize)
 For examples of the possibilities what you can do, please see the sample config(s).
 There are several interfaces to interact with uzbl:
 
index f954736..ab6e195 100644 (file)
--- a/config.h
+++ b/config.h
@@ -1,27 +1,6 @@
 const struct {
     char *command;
 } default_config[] = {
-{ "bind    j         = scroll_vert 20"},
-{ "bind    k         = scroll_vert -20"},
-{ "bind    h         = scroll_horz -20"},
-{ "bind    l         = scroll_horz 20"},
-{ "bind    <<        = scroll_begin"},
-{ "bind    >>        = scroll_end"},
-{ "bind    b         = back"},
-{ "bind    m         = forward"},
-{ "bind    s         = stop "},
-{ "bind    r         = reload"},
-{ "bind    R         = reload_ign_cache"},
-{ "bind    +         = zoom_in"},
-{ "bind    -         = zoom_out"},
-{ "bind    t         = toggle_status"},
-{ "bind    /*        = search %s"},
-{ "bind    ?*        = search_reverse %s"},
-{ "bind    n         = search"},
-{ "bind    N         = search_reverse"},
-{ "bind    o _       = uri %s"},
-{ "bind    i         = toggle_insert_mode"},
-{ "bind    ZZ        = exit"},
 { "set reset_command_mode = 1"},
 { "set status_format = <span background=\"darkblue\" foreground=\"white\"> MODE </span> <span background=\"red\" foreground=\"white\">KEYCMD</span> (LOAD_PROGRESS%)  <b>TITLE</b>  - Uzbl browser"},
 { "set title_format_long = KEYCMD MODE TITLE - Uzbl browser <NAME> > SELECTED_URI"},
index 431675e..b5a6323 100644 (file)
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -2,11 +2,12 @@ FAQ
 ---
 
 ### I just installed uzbl but it doesn't do much.  What now?
-Uzbl does not create a default config file on startup like some other programs do.
+Uzbl includes very limited default settings (statusbar settings, but no keybinds, history/download handlers etc.)
+Look at /usr/share/uzbl/docs/config.h to see the default settings.
+Neither does uzbl create a default config file on startup like some other programs do.
 Because we want to give you the freedom to place your config where you want, and to use a config or not.
-Uzbl includes *some* default settings hardcoded, but these are rather limited (some navigation keybinds, statusbar settings, but no history/download handlers etc.)
-Look at config.h to see the default settings.
-Have a look in /usr/share/uzbl/examples/configs to see what you can do. You will probably want to create your own config based on an example config.
+Have a look in /usr/share/uzbl/examples/configs to see what you can do. You will probably want to create your own config based on an example config
+so you can add keybinds and to use scripts.
 Use the --config parameter or save your config as $XDG\_CONFIG\_HOME/uzbl/config to have it auto-loaded.
 
 ### Where is the location bar? How do I change the URL ?
index 8652cc1..3deeac1 100644 (file)
@@ -151,6 +151,11 @@ bind ze = spawn ./examples/scripts/formfiller.sh edit
 bind zn = spawn ./examples/scripts/formfiller.sh new
 bind zl = spawn ./examples/scripts/formfiller.sh load
 
+# other - more advanced - implementation using perl: (could not get this to run - Dieter )
+bind LL = spawn ./examples/scripts/formfiller.pl load
+bind LN = spawn ./examples/scripts/formfiller.pl new
+bind LE = spawn ./examples/scripts/formfiller.pl edit
+
 # we ship some javascripts to do keyboard based link hinting/following.  (webkit does not have C DOM bindings yet)
 # this is similar to how it works in vimperator (and konqueror)
 # TODO: did we resolve: "no click() event for hyperlinks so no referrer set" ?
diff --git a/examples/scripts/formfiller.pl b/examples/scripts/formfiller.pl
new file mode 100755 (executable)
index 0000000..a6e07a0
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/perl
+
+# a slightly more advanced form filler
+#
+# uses settings file like: $keydir/<domain>
+
+# user arg 1:
+# edit: force editing of the file (fetches if file is missing)
+# load: fill forms from file (fetches if file is missing)
+# new:  fetch new file 
+
+# usage example:
+# bind LL = spawn /usr/share/uzbl/examples/scripts/formfiller.pl load
+# bind LN = spawn /usr/share/uzbl/examples/scripts/formfiller.pl new
+# bind LE = spawn /usr/share/uzbl/examples/scripts/formfiller.pl edit
+
+use strict;
+use Switch;
+
+my $keydir = $ENV{XDG_CONFIG_HOME} . "/uzbl/forms";
+my ($config,$pid,$xid,$fifo,$socket,$url,$title,$cmd) = @ARGV;
+if($fifo eq "") { die "No fifo"; };
+
+sub domain {
+  my ($url) = @_;
+  $url =~ s#http(s)?://([A-Za-z0-9\.-]+)(/.*)?#$2#;
+  return $url;
+};
+
+my $editor = "xterm -e vim";
+#my $editor = "gvim";
+
+# ideally, there would be some way to ask uzbl for the html content instead of having to redownload it with
+#      Also, you may need to fake the user-agent on some sites (like facebook)
+ my $downloader = "curl -A 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042810 GranParadiso/3.0.10' ";
+#my $downloader = "curl -s";
+
+my @fields = ("type","name","value");
+
+my %command;
+
+$command{load} = sub {
+  my ($domain) = @_;
+  my $file = "$keydir/$domain";
+  if( -e $file){
+    open(FH,$file);
+    my (@lines) = <FH>;
+    close(FH);
+    $|++;
+    open(FIFO,">>$fifo");
+    print "opened $fifo\n";
+    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";
+      }
+    }
+    $|--;
+    close(FIFO);
+  } else {
+    $command{new}->($domain);
+    $command{edit}->($domain);
+  }
+};
+$command{edit} = sub {
+  my ($domain) = @_;
+  my $file = "$keydir/$domain";
+  if(-e $file){
+    system ($editor, $file);
+  } else {
+    $command{new}->($domain);
+}
+};
+$command{new} = sub {
+  my ($domain) = @_;
+  my $file = "$keydir/$domain";
+  open(FILE,">>$file");
+  $|++;
+  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;
+    };
+  };
+  close(FILE);
+  $|--;
+};
+$command{$cmd}->(domain($url));
diff --git a/examples/scripts/linkfollow.js b/examples/scripts/linkfollow.js
new file mode 100644 (file)
index 0000000..9b7d811
--- /dev/null
@@ -0,0 +1,175 @@
+// link follower for uzbl
+// requires http://github.com/DuClare/uzbl/commit/6c11777067bdb8aac09bba78d54caea04f85e059
+//
+// first, it needs to be loaded before every time it is used.
+// One way would be to use something like load_start_handler to send
+// "act script link_follower.js"
+//
+// when script is loaded, it can be invoked with
+// bind f* = js setHints("%s")
+// bind f_ = js followLink("%s")
+//
+// based on follow_Numbers.js
+//
+// TODO: add classes to hinted elements
+
+
+var uzblid = 'uzbl_hint';
+var uzblclass = 'uzbl_hint_class'
+
+var doc = document;
+
+function elementPosition(el) {
+    var up = el.offsetTop;
+    var left = el.offsetLeft; var width = el.offsetWidth;
+    var height = el.offsetHeight;
+
+    while (el.offsetParent) {
+        el = el.offsetParent;
+        up += el.offsetTop;
+        left += el.offsetLeft;
+    }
+    return [up, left, width, 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(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);
+}
+
+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 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++;
+               }
+       }
+}
+
+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);
+       }
+}
+
+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");
+    }
+}
+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') {
+            item.focus();
+            item.select();
+        } else {
+            item.click();
+            window.location = item.href;
+        }
+    }
+}
diff --git a/examples/scripts/uzblcat b/examples/scripts/uzblcat
new file mode 100755 (executable)
index 0000000..82341c7
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env perl
+# uzblcat - safely push html to uzbl
+# See http://www.uzbl.org/wiki/html-mode
+use strict; use warnings;
+my $html;
+local $/;      # slurp files
+# automagically choose to read from stdin/files/...
+$html .= $_ for <>;
+my $endmarker = rand;
+$endmarker .= rand() while $html =~ /^\Q$endmarker\E$/m;
+print "set base_url = $ENV{BASE_URL}\n" if $ENV{BASE_URL};
+print << "EOS";
+set html_endmarker = $endmarker
+set mode = 1
+$html
+$endmarker
+EOS
diff --git a/uzbl.c b/uzbl.c
index ae00462..5748a2b 100644 (file)
--- a/uzbl.c
+++ b/uzbl.c
@@ -556,6 +556,7 @@ static struct {char *name; Command command[2];} cmdlist[] =
     { "exit",               {close_uzbl, 0}                },
     { "search",             {search_forward_text, NOSPLIT} },
     { "search_reverse",     {search_reverse_text, NOSPLIT} },
+    { "dehilight",          {dehilight, 0}                 },
     { "toggle_insert_mode", {toggle_insert_mode, 0}        },
     { "runcmd",             {runcmd, NOSPLIT}              },
     { "set",                {set_var, NOSPLIT}          }
@@ -707,6 +708,13 @@ search_reverse_text (WebKitWebView *page, GArray *argv) {
 }
 
 static void
+dehilight (WebKitWebView *page, GArray *argv) {
+    (void) argv;
+    webkit_web_view_set_highlight_text_matches (page, FALSE);
+}
+
+
+static void
 new_window_load_uri (const gchar * uri) {
     GString* to_execute = g_string_new ("");
     g_string_append_printf (to_execute, "%s --uri '%s'", uzbl.state.executable_path, uri);
@@ -1810,6 +1818,7 @@ key_press_cb (GtkWidget* window, GdkEventKey* event)
     if (event->keyval == GDK_Escape) {
         g_string_truncate(uzbl.state.keycmd, 0);
         update_title();
+        dehilight(uzbl.gui.web_view, NULL);
         return TRUE;
     }
 
@@ -2192,10 +2201,8 @@ inspector_inspector_destroyed_cb (WebKitWebInspector* inspector){
 static void
 set_up_inspector() {
     GUI *g = &uzbl.gui;
-    WebKitWebSettings *settings = webkit_web_settings_new();
+    WebKitWebSettings *settings = view_settings();
     g_object_set(G_OBJECT(settings), "enable-developer-extras", TRUE, NULL);
-    webkit_web_view_set_settings(WEBKIT_WEB_VIEW(uzbl.gui.web_view), settings);
-
 
     uzbl.gui.inspector = webkit_web_view_get_inspector(uzbl.gui.web_view);
     g_signal_connect (G_OBJECT (g->inspector), "inspect-web-view", G_CALLBACK (create_inspector_cb), NULL);
diff --git a/uzbl.h b/uzbl.h
index fd81614..cd5e3ef 100644 (file)
--- a/uzbl.h
+++ b/uzbl.h
@@ -398,6 +398,9 @@ static void
 search_reverse_text (WebKitWebView *page, GArray *argv);
 
 static void
+dehilight (WebKitWebView *page, GArray *argv);
+
+static void
 run_js (WebKitWebView * web_view, GArray *argv);
 
 static void