surf-0.1-chromebar.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) 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