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);
+