commit 7130deb8ac0a357609b72bc02fbede362f592aae
parent 21a3c8ad30ed1e8af33fe0015abadeceadfc7238
Author: Marcin Szamotulski <mszamot@gmail.com>
Date:   Wed,  3 Jul 2013 15:17:53 +0100
add chromebar patch to surf
Diffstat:
2 files changed, 354 insertions(+), 0 deletions(-)
diff --git a/surf.suckless.org/patches/chromebar.md b/surf.suckless.org/patches/chromebar.md
@@ -0,0 +1,33 @@
+Chrome Bar
+==========
+
+Description
+-----------
+
+This patch is an extension of the [searchengines
+patch](http://surf.suckless.org/patches/searchengines).  It parses what you
+type in the dmenu window when you input new address or a query.  If what
+you wrote is not an internet address, it will use default search engine to
+query for that phrase: like the google bar.
+
+
+Configuration
+-------------
+
+Add something like this to your `config.h`:
+
+    static const char * defaultsearchengine = "http://www.google.co.uk/search?q=%s";
+    static SearchEngine searchengines[] = {
+	    { "g",   "http://www.google.de/search?q=%s"   },
+	    { "leo", "http://dict.leo.org/ende?search=%s" },
+    };
+
+Download
+--------
+
+* [surf-0.1-googlebar.diff](surf-0.1-googlebar.diff) (20130703)
+
+Author
+------
+
+* Marcin Szamotulski (coot) <[mszamot@gmail.com](mailto:mszamot@gmail.com)>
diff --git a/surf.suckless.org/patches/surf-0.1-chromebar.diff b/surf.suckless.org/patches/surf-0.1-chromebar.diff
@@ -0,0 +1,321 @@
+diff --git a/surf.c b/surf.c
+index 53dda18..38c15a4 100644
+--- a/surf.c
++++ b/surf.c
+@@ -17,6 +17,7 @@
+ #include <limits.h>
+ #include <stdlib.h>
+ #include <stdio.h>
++#include <ctype.h>
+ #include <webkit/webkit.h>
+ #include <glib/gstdio.h>
+ #include <JavaScriptCore/JavaScript.h>
+@@ -71,6 +72,12 @@ typedef struct {
+ 
+ G_DEFINE_TYPE(CookieJar, cookiejar, SOUP_TYPE_COOKIE_JAR_TEXT)
+ 
++typedef struct {
++	char *token;
++	char *uri;
++	int nr;
++} SearchEngine;
++
+ static Display *dpy;
+ static Atom atoms[AtomLast];
+ static Client *clients = NULL;
+@@ -141,6 +148,9 @@ static void loaduri(Client *c, const Arg *arg);
+ static void navigate(Client *c, const Arg *arg);
+ static Client *newclient(void);
+ static void newwindow(Client *c, const Arg *arg, gboolean noembed);
++static const gchar *parseuri(const gchar *uri, char **parsed_uri);
++static char **parse_address(const char *url);
++static char **parse_url(char *str);
+ static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
+ static void populatepopup(WebKitWebView *web, GtkMenu *menu, Client *c);
+ static void popupactivate(GtkMenuItem *menu, Client *);
+@@ -166,6 +176,7 @@ static void togglescrollbars(Client *c, const Arg *arg);
+ static void togglestyle(Client *c, const Arg *arg);
+ static void updatetitle(Client *c);
+ static void updatewinid(Client *c);
++static int url_has_domain(char *url, char **parsed_uri); 
+ static void usage(void);
+ static void windowobjectcleared(GtkWidget *w, WebKitWebFrame *frame,
+ 		JSContextRef js, JSObjectRef win, Client *c);
+@@ -616,32 +627,63 @@ loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c) {
+ 
+ static void
+ loaduri(Client *c, const Arg *arg) {
+-	char *u, *rp;
+-	const char *uri = (char *)arg->v;
++	const gchar *u;
++	char *rp, *pt;
++	const gchar *uri = arg->v;
++	char **parsed_uri;
++	char *home;
++	char *path;
++	int i;
++	FILE *f;
+ 	Arg a = { .b = FALSE };
+-	struct stat st;
+ 
+-	if(strcmp(uri, "") == 0)
++	if (*uri == '\0')
+ 		return;
+ 
++	pt=malloc(strlen(uri)+1);
++	pt=strdup((char *)uri);
++	parsed_uri = parse_url(pt);
++
+ 	/* In case it's a file path. */
+-	if(stat(uri, &st) == 0) {
+-		rp = realpath(uri, NULL);
++	if(strncmp(parsed_uri[0], "file://", 6) == 0 ||
++		( strlen(parsed_uri[0]) == 0 && strlen(parsed_uri[1]) == 0)) {
++		path=malloc(strlen(parsed_uri[1])+strlen(parsed_uri[2])+strlen(parsed_uri[3])+1);
++		path=strcpy(path, parsed_uri[1]);
++		path=strcat(path, parsed_uri[2]);
++		path=strcat(path, parsed_uri[3]);
++
++		if (path[0] == '~')
++		{
++		    home = getenv("HOME");
++		    home = realloc(home, strlen(path)+strlen(home));
++		    home = strcat(home, path+1);
++		    free(path);
++		    path = home;
++		}
++		rp = realpath(path, NULL);
+ 		u = g_strdup_printf("file://%s", rp);
++		free(path);
+ 		free(rp);
+ 	} else {
+-		u = g_strrstr(uri, "://") ? g_strdup(uri)
+-			: g_strdup_printf("http://%s", uri);
++		u = parseuri(pt,parsed_uri);
+ 	}
+ 
++	free(pt);
++	for (i=0;i<4;i++)
++	    free(parsed_uri[i]);
++	free(parsed_uri);
++
+ 	/* prevents endless loop */
+ 	if(c->uri && strcmp(u, c->uri) == 0) {
+ 		reload(c, &a);
+ 	} else {
+ 		webkit_web_view_load_uri(c->view, u);
++		f = fopen(historyfile, "a+");
++		fprintf(f, "%s", u);
++		fclose(f);
+ 		c->progress = 0;
+ 		c->title = copystr(&c->title, u);
+-		g_free(u);
++		g_free((gpointer )u);
+ 		updatetitle(c);
+ 	}
+ }
+@@ -912,6 +954,196 @@ popupactivate(GtkMenuItem *menu, Client *c) {
+ 	}
+ }
+ 
++#define SCHEME_CHAR(ch) (isalnum (ch) || (ch) == '-' || (ch) == '+')
++
++/*
++ * This function takes an url and chop it into three part: sheme, domain, the
++ * rest, e.g. http://www.google.co.uk/search?q=hello will produce a triple
++ * ('http://', 'www.google.co.uk', '/search?q=hello')
++ */
++static char **
++parse_url(char *str) {
++    /* Return the position of ':' - last element of a scheme, or 0 if there
++     * is no scheme. */
++    char *sch="";
++    char *pt;
++    char **ret;
++    char **dret;
++    int k,i = 0;
++
++    pt=malloc(strlen(str)+1);
++    pt=strcpy(pt, str);
++
++    while (*pt == ' ')
++	pt+=1;
++    ret=malloc(4*sizeof(char *));
++
++    /* The first char must be a scheme char. */
++    if (!*pt || !SCHEME_CHAR (*pt))
++    {
++	ret[0]=malloc(1);
++	ret[0][0]='\0';
++	dret=parse_address(pt);
++	for (k=0;k<3;k++)
++	    ret[k+1]=dret[k];
++	return ret;
++    }
++    ++i;
++    /* Followed by 0 or more scheme chars. */
++    while (*(pt+i) && SCHEME_CHAR (*(pt+i)))
++    {
++	++i;
++    }
++    sch=malloc(i+4);
++    sch=strncpy(sch, pt, i); 
++    sch[i]='\0';
++    if (strlen(sch)) {
++	sch=strcat(sch, "://");
++    }
++
++    /* Terminated by "://". */
++    if (strncmp(sch, pt, strlen(sch)) == 0) {
++	    ret[0]=sch;
++	    /* dret=malloc(strlen(str)); */
++	    dret=parse_address(pt+i+3);
++	    for (k=0;k<3;k++)
++		ret[k+1]=dret[k];
++	    return ret;
++    }
++    ret[0]=malloc(1);
++    ret[0][0]='\0';
++    dret=parse_address(str);
++    for (k=0;k<3;k++)
++	ret[k+1]=dret[k];
++    return ret;
++}
++
++#define DOMAIN_CHAR(ch) (isalnum (ch) || (ch) == '-' || (ch) == '.')
++
++/*
++ * This function takes an url without a scheme and outputs a pair: domain and
++ * the rest.
++ */
++static char **
++parse_address(const char *url)
++{
++    int n;
++    size_t i=0;
++    size_t u=strlen(url);
++    char *domain;
++    char *port;
++    char **res=malloc(3*sizeof (char *));
++
++    if (isalnum(*url)) {
++	++i;
++	while (*(url+i) && DOMAIN_CHAR (*(url+i)))
++	    ++i;
++    }
++    domain=malloc(i+1);
++    domain=strncpy(domain, url, i);
++    domain[i]='\0';
++
++    // check for a port number
++    if ( (u > i) && *(url+i) == ':' )
++    {
++	n=i+1;
++	while ( (n<=u) && (n<i+1+5) && isdigit(*(url+n)) )
++	    n++;
++	if (n>i+1)
++	{
++	    port=malloc(n-i+1);
++	    port=strncpy(port, (url+i), n-i);
++	    port[n-i+1]='\0';
++	}
++	else
++	{
++	    port=malloc(1);
++	    port[0]='\0';
++	}
++    }
++    else
++    {
++	n=i;
++	port=malloc(1);
++	port[0] = '\0';
++    }
++
++
++    res[0]=domain;
++    res[1]=port;
++    res[2]=malloc(strlen(url+n)+1);
++    res[2]=strcpy(res[2], (url+n));
++    return res;
++}
++
++/*
++ * This function tests if the url has a qualified domain name.
++ */
++static int
++url_has_domain(char *url, char **parsed_uri) {
++    char *domain=parsed_uri[1];
++    char *rest=parsed_uri[3];
++
++    if (strstr(domain, " ") != NULL)
++	return false;
++
++    if (! *domain ||
++	    (*rest && rest[0] != '/'))
++	return false;
++
++    // the domain name should contain at least one '.',
++    // unless it is "localhost"
++    if (strcmp(domain, "localhost") == 0) 
++	return true;
++
++    if (strstr(domain, ".") != NULL)
++	return true;
++
++    return false;
++}
++
++static const gchar *
++parseuri(const gchar *uri, char **parsed_uri) {
++	guint i;
++	gchar *pt = g_strdup(uri);
++
++	while (*pt == ' ')
++	    pt+=1;
++
++	bool hdm = url_has_domain((char *) pt, parsed_uri);
++
++	if (hdm)
++	    return g_strrstr(pt, "://") ? g_strdup(pt) : g_strdup_printf("http://%s", pt);
++
++	for (i = 0; i < LENGTH(searchengines); i++) {
++		if (searchengines[i].token == NULL
++			|| searchengines[i].uri == NULL)
++			continue;
++
++		if ((*(pt + strlen(searchengines[i].token)) == ' ' && g_str_has_prefix(pt, searchengines[i].token)))
++		{
++		    switch (searchengines[i].nr)
++		    {
++			case 0:
++			return g_strdup_printf("%s", searchengines[i].uri);
++			break;
++			case 2:
++			return g_strdup_printf(searchengines[i].uri, pt + strlen(searchengines[i].token) + 1, pt + strlen(searchengines[i].token) + 1);
++			break;
++			default:
++			return g_strdup_printf(searchengines[i].uri, pt + strlen(searchengines[i].token) + 1);
++			break;
++		    }
++		}
++
++		if (strcmp(pt, searchengines[i].token) == 0 && strstr(searchengines[i].token, "%s") == NULL)
++		{
++		    return g_strdup_printf(searchengines[i].uri, "");
++		}
++	}
++	return g_strdup_printf(defaultsearchengine, pt);
++}
++
+ static void
+ pasteuri(GtkClipboard *clipboard, const char *text, gpointer d) {
+ 	Arg arg = {.v = text };
+@@ -1028,6 +1260,7 @@ setup(void) {
+ 
+ 	/* dirs and files */
+ 	cookiefile = buildpath(cookiefile);
++ 	historyfile = buildpath(historyfile);
+ 	scriptfile = buildpath(scriptfile);
+ 	stylefile = buildpath(stylefile);
+