sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

surf-0.1-chromebar.diff (8020B)


      1 diff --git a/surf.c b/surf.c
      2 index 53dda18..38c15a4 100644
      3 --- a/surf.c
      4 +++ b/surf.c
      5 @@ -17,6 +17,7 @@
      6  #include <limits.h>
      7  #include <stdlib.h>
      8  #include <stdio.h>
      9 +#include <ctype.h>
     10  #include <webkit/webkit.h>
     11  #include <glib/gstdio.h>
     12  #include <JavaScriptCore/JavaScript.h>
     13 @@ -71,6 +72,12 @@ typedef struct {
     14  
     15  G_DEFINE_TYPE(CookieJar, cookiejar, SOUP_TYPE_COOKIE_JAR_TEXT)
     16  
     17 +typedef struct {
     18 +	char *token;
     19 +	char *uri;
     20 +	int nr;
     21 +} SearchEngine;
     22 +
     23  static Display *dpy;
     24  static Atom atoms[AtomLast];
     25  static Client *clients = NULL;
     26 @@ -141,6 +148,9 @@ static void loaduri(Client *c, const Arg *arg);
     27  static void navigate(Client *c, const Arg *arg);
     28  static Client *newclient(void);
     29  static void newwindow(Client *c, const Arg *arg, gboolean noembed);
     30 +static const gchar *parseuri(const gchar *uri, char **parsed_uri);
     31 +static char **parse_address(const char *url);
     32 +static char **parse_url(char *str);
     33  static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
     34  static void populatepopup(WebKitWebView *web, GtkMenu *menu, Client *c);
     35  static void popupactivate(GtkMenuItem *menu, Client *);
     36 @@ -166,6 +176,7 @@ static void togglescrollbars(Client *c, const Arg *arg);
     37  static void togglestyle(Client *c, const Arg *arg);
     38  static void updatetitle(Client *c);
     39  static void updatewinid(Client *c);
     40 +static int url_has_domain(char *url, char **parsed_uri); 
     41  static void usage(void);
     42  static void windowobjectcleared(GtkWidget *w, WebKitWebFrame *frame,
     43  		JSContextRef js, JSObjectRef win, Client *c);
     44 @@ -616,32 +627,63 @@ loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c) {
     45  
     46  static void
     47  loaduri(Client *c, const Arg *arg) {
     48 -	char *u, *rp;
     49 -	const char *uri = (char *)arg->v;
     50 +	const gchar *u;
     51 +	char *rp, *pt;
     52 +	const gchar *uri = arg->v;
     53 +	char **parsed_uri;
     54 +	char *home;
     55 +	char *path;
     56 +	int i;
     57 +	FILE *f;
     58  	Arg a = { .b = FALSE };
     59 -	struct stat st;
     60  
     61 -	if(strcmp(uri, "") == 0)
     62 +	if (*uri == '\0')
     63  		return;
     64  
     65 +	pt=malloc(strlen(uri)+1);
     66 +	pt=strdup((char *)uri);
     67 +	parsed_uri = parse_url(pt);
     68 +
     69  	/* In case it's a file path. */
     70 -	if(stat(uri, &st) == 0) {
     71 -		rp = realpath(uri, NULL);
     72 +	if(strncmp(parsed_uri[0], "file://", 6) == 0 ||
     73 +		( strlen(parsed_uri[0]) == 0 && strlen(parsed_uri[1]) == 0)) {
     74 +		path=malloc(strlen(parsed_uri[1])+strlen(parsed_uri[2])+strlen(parsed_uri[3])+1);
     75 +		path=strcpy(path, parsed_uri[1]);
     76 +		path=strcat(path, parsed_uri[2]);
     77 +		path=strcat(path, parsed_uri[3]);
     78 +
     79 +		if (path[0] == '~')
     80 +		{
     81 +		    home = getenv("HOME");
     82 +		    home = realloc(home, strlen(path)+strlen(home));
     83 +		    home = strcat(home, path+1);
     84 +		    free(path);
     85 +		    path = home;
     86 +		}
     87 +		rp = realpath(path, NULL);
     88  		u = g_strdup_printf("file://%s", rp);
     89 +		free(path);
     90  		free(rp);
     91  	} else {
     92 -		u = g_strrstr(uri, "://") ? g_strdup(uri)
     93 -			: g_strdup_printf("http://%s", uri);
     94 +		u = parseuri(pt,parsed_uri);
     95  	}
     96  
     97 +	free(pt);
     98 +	for (i=0;i<4;i++)
     99 +	    free(parsed_uri[i]);
    100 +	free(parsed_uri);
    101 +
    102  	/* prevents endless loop */
    103  	if(c->uri && strcmp(u, c->uri) == 0) {
    104  		reload(c, &a);
    105  	} else {
    106  		webkit_web_view_load_uri(c->view, u);
    107 +		f = fopen(historyfile, "a+");
    108 +		fprintf(f, "%s", u);
    109 +		fclose(f);
    110  		c->progress = 0;
    111  		c->title = copystr(&c->title, u);
    112 -		g_free(u);
    113 +		g_free((gpointer )u);
    114  		updatetitle(c);
    115  	}
    116  }
    117 @@ -912,6 +954,196 @@ popupactivate(GtkMenuItem *menu, Client *c) {
    118  	}
    119  }
    120  
    121 +#define SCHEME_CHAR(ch) (isalnum (ch) || (ch) == '-' || (ch) == '+')
    122 +
    123 +/*
    124 + * This function takes an url and chop it into three part: sheme, domain, the
    125 + * rest, e.g. http://www.google.co.uk/search?q=hello will produce a triple
    126 + * ('http://', 'www.google.co.uk', '/search?q=hello')
    127 + */
    128 +static char **
    129 +parse_url(char *str) {
    130 +    /* Return the position of ':' - last element of a scheme, or 0 if there
    131 +     * is no scheme. */
    132 +    char *sch="";
    133 +    char *pt;
    134 +    char **ret;
    135 +    char **dret;
    136 +    int k,i = 0;
    137 +
    138 +    pt=malloc(strlen(str)+1);
    139 +    pt=strcpy(pt, str);
    140 +
    141 +    while (*pt == ' ')
    142 +	pt+=1;
    143 +    ret=malloc(4*sizeof(char *));
    144 +
    145 +    /* The first char must be a scheme char. */
    146 +    if (!*pt || !SCHEME_CHAR (*pt))
    147 +    {
    148 +	ret[0]=malloc(1);
    149 +	ret[0][0]='\0';
    150 +	dret=parse_address(pt);
    151 +	for (k=0;k<3;k++)
    152 +	    ret[k+1]=dret[k];
    153 +	return ret;
    154 +    }
    155 +    ++i;
    156 +    /* Followed by 0 or more scheme chars. */
    157 +    while (*(pt+i) && SCHEME_CHAR (*(pt+i)))
    158 +    {
    159 +	++i;
    160 +    }
    161 +    sch=malloc(i+4);
    162 +    sch=strncpy(sch, pt, i); 
    163 +    sch[i]='\0';
    164 +    if (strlen(sch)) {
    165 +	sch=strcat(sch, "://");
    166 +    }
    167 +
    168 +    /* Terminated by "://". */
    169 +    if (strncmp(sch, pt, strlen(sch)) == 0) {
    170 +	    ret[0]=sch;
    171 +	    /* dret=malloc(strlen(str)); */
    172 +	    dret=parse_address(pt+i+3);
    173 +	    for (k=0;k<3;k++)
    174 +		ret[k+1]=dret[k];
    175 +	    return ret;
    176 +    }
    177 +    ret[0]=malloc(1);
    178 +    ret[0][0]='\0';
    179 +    dret=parse_address(str);
    180 +    for (k=0;k<3;k++)
    181 +	ret[k+1]=dret[k];
    182 +    return ret;
    183 +}
    184 +
    185 +#define DOMAIN_CHAR(ch) (isalnum (ch) || (ch) == '-' || (ch) == '.')
    186 +
    187 +/*
    188 + * This function takes an url without a scheme and outputs a pair: domain and
    189 + * the rest.
    190 + */
    191 +static char **
    192 +parse_address(const char *url)
    193 +{
    194 +    int n;
    195 +    size_t i=0;
    196 +    size_t u=strlen(url);
    197 +    char *domain;
    198 +    char *port;
    199 +    char **res=malloc(3*sizeof (char *));
    200 +
    201 +    if (isalnum(*url)) {
    202 +	++i;
    203 +	while (*(url+i) && DOMAIN_CHAR (*(url+i)))
    204 +	    ++i;
    205 +    }
    206 +    domain=malloc(i+1);
    207 +    domain=strncpy(domain, url, i);
    208 +    domain[i]='\0';
    209 +
    210 +    // check for a port number
    211 +    if ( (u > i) && *(url+i) == ':' )
    212 +    {
    213 +	n=i+1;
    214 +	while ( (n<=u) && (n<i+1+5) && isdigit(*(url+n)) )
    215 +	    n++;
    216 +	if (n>i+1)
    217 +	{
    218 +	    port=malloc(n-i+1);
    219 +	    port=strncpy(port, (url+i), n-i);
    220 +	    port[n-i+1]='\0';
    221 +	}
    222 +	else
    223 +	{
    224 +	    port=malloc(1);
    225 +	    port[0]='\0';
    226 +	}
    227 +    }
    228 +    else
    229 +    {
    230 +	n=i;
    231 +	port=malloc(1);
    232 +	port[0] = '\0';
    233 +    }
    234 +
    235 +
    236 +    res[0]=domain;
    237 +    res[1]=port;
    238 +    res[2]=malloc(strlen(url+n)+1);
    239 +    res[2]=strcpy(res[2], (url+n));
    240 +    return res;
    241 +}
    242 +
    243 +/*
    244 + * This function tests if the url has a qualified domain name.
    245 + */
    246 +static int
    247 +url_has_domain(char *url, char **parsed_uri) {
    248 +    char *domain=parsed_uri[1];
    249 +    char *rest=parsed_uri[3];
    250 +
    251 +    if (strstr(domain, " ") != NULL)
    252 +	return false;
    253 +
    254 +    if (! *domain ||
    255 +	    (*rest && rest[0] != '/'))
    256 +	return false;
    257 +
    258 +    // the domain name should contain at least one '.',
    259 +    // unless it is "localhost"
    260 +    if (strcmp(domain, "localhost") == 0) 
    261 +	return true;
    262 +
    263 +    if (strstr(domain, ".") != NULL)
    264 +	return true;
    265 +
    266 +    return false;
    267 +}
    268 +
    269 +static const gchar *
    270 +parseuri(const gchar *uri, char **parsed_uri) {
    271 +	guint i;
    272 +	gchar *pt = g_strdup(uri);
    273 +
    274 +	while (*pt == ' ')
    275 +	    pt+=1;
    276 +
    277 +	bool hdm = url_has_domain((char *) pt, parsed_uri);
    278 +
    279 +	if (hdm)
    280 +	    return g_strrstr(pt, "://") ? g_strdup(pt) : g_strdup_printf("http://%s", pt);
    281 +
    282 +	for (i = 0; i < LENGTH(searchengines); i++) {
    283 +		if (searchengines[i].token == NULL
    284 +			|| searchengines[i].uri == NULL)
    285 +			continue;
    286 +
    287 +		if ((*(pt + strlen(searchengines[i].token)) == ' ' && g_str_has_prefix(pt, searchengines[i].token)))
    288 +		{
    289 +		    switch (searchengines[i].nr)
    290 +		    {
    291 +			case 0:
    292 +			return g_strdup_printf("%s", searchengines[i].uri);
    293 +			break;
    294 +			case 2:
    295 +			return g_strdup_printf(searchengines[i].uri, pt + strlen(searchengines[i].token) + 1, pt + strlen(searchengines[i].token) + 1);
    296 +			break;
    297 +			default:
    298 +			return g_strdup_printf(searchengines[i].uri, pt + strlen(searchengines[i].token) + 1);
    299 +			break;
    300 +		    }
    301 +		}
    302 +
    303 +		if (strcmp(pt, searchengines[i].token) == 0 && strstr(searchengines[i].token, "%s") == NULL)
    304 +		{
    305 +		    return g_strdup_printf(searchengines[i].uri, "");
    306 +		}
    307 +	}
    308 +	return g_strdup_printf(defaultsearchengine, pt);
    309 +}
    310 +
    311  static void
    312  pasteuri(GtkClipboard *clipboard, const char *text, gpointer d) {
    313  	Arg arg = {.v = text };
    314 @@ -1028,6 +1260,7 @@ setup(void) {
    315  
    316  	/* dirs and files */
    317  	cookiefile = buildpath(cookiefile);
    318 + 	historyfile = buildpath(historyfile);
    319  	scriptfile = buildpath(scriptfile);
    320  	stylefile = buildpath(stylefile);
    321