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