tAdding web inspector support to surf. - surf - customized build of surf, the suckless webkit browser
 (HTM) git clone git://src.adamsgaard.dk/surf
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit e784d925dfab0405cb4bf2ac7466045d8089a189
 (DIR) parent 13b04d8b61b3e0f334b57749cf9b8755135ef4f4
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Sat, 26 Jan 2013 15:53:33 +0100
       
       Adding web inspector support to surf.
       
       Thanks Gregor Best <gbe@ring0.de>!
       
       Diffstat:
         M config.def.h                        |       9 +++++++--
         M surf.1                              |      12 +++++++-----
         M surf.c                              |     105 +++++++++++++++++++++++++------
       
       3 files changed, 101 insertions(+), 25 deletions(-)
       ---
 (DIR) diff --git a/config.def.h b/config.def.h
       t@@ -16,8 +16,12 @@ static char *cafile         = "/etc/ssl/certs/ca-certificates.crt";
        static char *strictssl      = FALSE; /* Refuse untrusted SSL connections */
        static int   indicator_thickness = 2;
        
       -/* Webkit features */
       -static Bool spatialbrowsing = TRUE;
       +/* Webkit default features */
       +static Bool enablespatialbrowsing = TRUE;
       +static Bool enableplugins = TRUE;
       +static Bool enablescripts = TRUE;
       +static Bool enableinspector = TRUE;
       +static Bool loadimages = TRUE;
        static Bool hidebackground  = FALSE;
        
        #define SETPROP(p, q) { \
       t@@ -69,6 +73,7 @@ static Key keys[] = {
            { 0,                    GDK_F11,    fullscreen, { 0 } },
            { 0,                    GDK_Escape, stop,       { 0 } },
            { MODKEY,               GDK_o,      source,     { 0 } },
       +    { MODKEY|GDK_SHIFT_MASK,GDK_o,      inspector,  { 0 } },
        
            { MODKEY,               GDK_g,      spawn,      SETPROP("_SURF_URI", "_SURF_GO") },
            { MODKEY,               GDK_f,      spawn,      SETPROP("_SURF_FIND", "_SURF_FIND") },
 (DIR) diff --git a/surf.1 b/surf.1
       t@@ -3,16 +3,12 @@
        surf \- simple webkit-based browser
        .SH SYNOPSIS
        .B surf
       +.RB [-ipnsvx]
        .RB [-c\ cookiefile]
        .RB [-e\ xid]
       -.RB [-i]
       -.RB [-p]
        .RB [-r\ scriptfile]
       -.RB [-s]
        .RB [-t\ stylefile]
        .RB [-u\ useragent]
       -.RB [-v]
       -.RB [-x]
        .RB "URI"
        .SH DESCRIPTION
        surf is a simple Web browser based on WebKit/GTK+. It is able
       t@@ -30,6 +26,9 @@ Reparents to window specified by xid.
        .B \-i
        Disable Images
        .TP
       +.B \-n
       +Disable the Web Inspector (Developer Tools).
       +.TP
        .B \-p
        Disable Plugins
        .TP
       t@@ -127,6 +126,9 @@ Copies current URI to primary selection.
        .B Ctrl\-o
        Show the sourcecode of the current page.
        .TP
       +.B Ctrl\-Shift\-o
       +Open the Web Inspector (Developer Tools) window for the current page.
       +.TP
        .B Ctrl\-Shift\-c
        Toggle caret browsing.
        .TP
 (DIR) diff --git a/surf.c b/surf.c
       t@@ -20,6 +20,8 @@
        #include <glib/gstdio.h>
        #include <JavaScriptCore/JavaScript.h>
        #include <sys/file.h>
       +#include <libgen.h>
       +#include <stdarg.h>
        
        #include "arg.h"
        
       t@@ -41,12 +43,12 @@ union Arg {
        typedef struct Client {
                GtkWidget *win, *scroll, *vbox, *indicator;
                WebKitWebView *view;
       +        WebKitWebInspector *inspector;
                char *title, *linkhover;
                const char *uri, *needle;
                gint progress;
       -        gboolean sslfailed;
                struct Client *next;
       -        gboolean zoomed, fullscreen;
       +        gboolean zoomed, fullscreen, isinspector, sslfailed;
        } Client;
        
        typedef struct {
       t@@ -79,8 +81,7 @@ static Client *clients = NULL;
        static GdkNativeWindow embed = 0;
        static gboolean showxid = FALSE;
        static char winid[64];
       -static gboolean loadimages = 1, enableplugins = 1, enablescripts = 1,
       -                usingproxy = 0;
       +static gboolean usingproxy = 0;
        static char togglestat[5];
        
        static void beforerequest(WebKitWebView *w, WebKitWebFrame *f,
       t@@ -91,12 +92,14 @@ static gboolean buttonrelease(WebKitWebView *web, GdkEventButton *e,
                        GList *gl);
        static void cleanup(void);
        static void clipboard(Client *c, const Arg *arg);
       +
        static void cookiejar_changed(SoupCookieJar *self, SoupCookie *old_cookie,
                        SoupCookie *new_cookie);
        static void cookiejar_finalize(GObject *self);
        static SoupCookieJar *cookiejar_new(const char *filename, gboolean read_only);
        static void cookiejar_set_property(GObject *self, guint prop_id,
                        const GValue *value, GParamSpec *pspec);
       +
        static char *copystr(char **str, const char *src);
        static WebKitWebView *createwindow(WebKitWebView *v, WebKitWebFrame *f,
                        Client *c);
       t@@ -108,14 +111,24 @@ static gboolean decidewindow(WebKitWebView *v, WebKitWebFrame *f,
                        WebKitWebPolicyDecision *p, Client *c);
        static void destroyclient(Client *c);
        static void destroywin(GtkWidget* w, Client *c);
       -static void die(char *str);
       +static void die(const char *errstr, ...);
        static void drawindicator(Client *c);
       +static void eval(Client *c, const Arg *arg);
        static gboolean exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c);
        static void find(Client *c, const Arg *arg);
        static void fullscreen(Client *c, const Arg *arg);
        static const char *getatom(Client *c, int a);
       +static void gettogglestat(Client *c);
        static char *geturi(Client *c);
        static gboolean initdownload(WebKitWebView *v, WebKitDownload *o, Client *c);
       +
       +static void inspector(Client *c, const Arg *arg);
       +static WebKitWebView *inspector_new(WebKitWebInspector *i, WebKitWebView *v,
       +                Client *c);
       +static gboolean inspector_show(WebKitWebInspector *i, Client *c);
       +static gboolean inspector_close(WebKitWebInspector *i, Client *c);
       +static void inspector_finished(WebKitWebInspector *i, Client *c);
       +
        static gboolean keypress(GtkWidget *w, GdkEventKey *ev, Client *c);
        static void linkhover(WebKitWebView *v, const char* t, const char* l,
                        Client *c);
       t@@ -141,12 +154,10 @@ static void setup(void);
        static void sigchld(int unused);
        static void source(Client *c, const Arg *arg);
        static void spawn(Client *c, const Arg *arg);
       -static void eval(Client *c, const Arg *arg);
        static void stop(Client *c, const Arg *arg);
        static void titlechange(WebKitWebView *v, WebKitWebFrame *frame,
                        const char *title, Client *c);
        static void toggle(Client *c, const Arg *arg);
       -static void gettogglestat(Client *c);
        static void update(Client *c);
        static void updatewinid(Client *c);
        static void usage(void);
       t@@ -381,8 +392,12 @@ destroywin(GtkWidget* w, Client *c) {
        }
        
        static void
       -die(char *str) {
       -        fputs(str, stderr);
       +die(const char *errstr, ...) {
       +        va_list ap;
       +
       +        va_start(ap, errstr);
       +        vfprintf(stderr, errstr, ap);
       +        va_end(ap);
                exit(EXIT_FAILURE);
        }
        
       t@@ -488,6 +503,38 @@ initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
                return FALSE;
        }
        
       +static void
       +inspector(Client *c, const Arg *arg) {
       +        if(c->isinspector)
       +                return;
       +        webkit_web_inspector_show(c->inspector);
       +}
       +
       +static WebKitWebView *
       +inspector_new(WebKitWebInspector *i, WebKitWebView *v, Client *c) {
       +        Client *n = newclient();
       +        n->isinspector = true;
       +
       +        return n->view;
       +}
       +
       +static gboolean
       +inspector_show(WebKitWebInspector *i, Client *c) {
       +        gtk_widget_show(GTK_WIDGET(webkit_web_inspector_get_web_view(i)));
       +        return true;
       +}
       +
       +static gboolean
       +inspector_close(WebKitWebInspector *i, Client *c) {
       +        gtk_widget_hide(GTK_WIDGET(webkit_web_inspector_get_web_view(i)));
       +        return true;
       +}
       +
       +static void
       +inspector_finished(WebKitWebInspector *i, Client *c) {
       +        g_free(c->inspector);
       +}
       +
        static gboolean
        keypress(GtkWidget* w, GdkEventKey *ev, Client *c) {
                guint i;
       t@@ -706,11 +753,30 @@ newclient(void) {
                g_object_set(G_OBJECT(settings), "user-agent", ua, NULL);
                uri = g_strconcat("file://", stylefile, NULL);
                g_object_set(G_OBJECT(settings), "user-stylesheet-uri", uri, NULL);
       -        g_object_set(G_OBJECT(settings), "auto-load-images", loadimages, NULL);
       -        g_object_set(G_OBJECT(settings), "enable-plugins", enableplugins, NULL);
       -        g_object_set(G_OBJECT(settings), "enable-scripts", enablescripts, NULL);
       +        g_object_set(G_OBJECT(settings), "auto-load-images", loadimages,
       +                        NULL);
       +        g_object_set(G_OBJECT(settings), "enable-plugins", enableplugins,
       +                        NULL);
       +        g_object_set(G_OBJECT(settings), "enable-scripts", enablescripts,
       +                        NULL);
                g_object_set(G_OBJECT(settings), "enable-spatial-navigation",
       -                        spatialbrowsing, NULL);
       +                        enablespatialbrowsing, NULL);
       +        g_object_set(G_OBJECT(settings), "enable-developer-extras",
       +                        enableinspector, NULL);
       +
       +        if(enableinspector) {
       +                c->inspector = WEBKIT_WEB_INSPECTOR(
       +                                webkit_web_view_get_inspector(c->view));
       +                g_signal_connect(G_OBJECT(c->inspector), "inspect-web-view",
       +                                G_CALLBACK(inspector_new), c);
       +                g_signal_connect(G_OBJECT(c->inspector), "show-window",
       +                                G_CALLBACK(inspector_show), c);
       +                g_signal_connect(G_OBJECT(c->inspector), "close-window",
       +                                G_CALLBACK(inspector_close), c);
       +                g_signal_connect(G_OBJECT(c->inspector), "finished",
       +                                G_CALLBACK(inspector_finished), c);
       +                c->isinspector = false;
       +        }
        
                g_free(uri);
        
       t@@ -1059,9 +1125,8 @@ updatewinid(Client *c) {
        
        static void
        usage(void) {
       -        fputs("surf - simple browser\n", stderr);
       -        die("usage: surf [-c cookiefile] [-e xid] [-i] [-p] [-r scriptfile]"
       -                " [-s] [-t stylefile] [-u useragent] [-v] [-x] [uri]\n");
       +        die("usage: %s [-inpsvx] [-c cookiefile] [-e xid] [-r scriptfile]"
       +                " [-t stylefile] [-u useragent] [uri]\n", basename(argv0));
        }
        
        static void
       t@@ -1103,6 +1168,9 @@ main(int argc, char *argv[]) {
                case 'i':
                        loadimages = 0;
                        break;
       +        case 'n':
       +                enableinspector = 0;
       +                break;
                case 'p':
                        enableplugins = 0;
                        break;
       t@@ -1118,11 +1186,12 @@ main(int argc, char *argv[]) {
                case 'u':
                        useragent = EARGF(usage());
                        break;
       +        case 'v':
       +                die("surf-"VERSION", ©2009-2012 surf engineers, "
       +                                "see LICENSE for details\n");
                case 'x':
                        showxid = TRUE;
                        break;
       -        case 'v':
       -                die("surf-"VERSION", ©2009-2012 surf engineers, see LICENSE for details\n");
                default:
                        usage();
                } ARGEND;