surf-0.1-chromebar.diff - 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, gpointe… | |
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 *a… | |
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 *… | |
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]) =… | |
74 + path=malloc(strlen(parsed_uri[1])+strlen(parsed_uri[2])… | |
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, domai… | |
125 + * rest, e.g. http://www.google.co.uk/search?q=hello will produce a tri… | |
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 t… | |
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: doma… | |
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_print… | |
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… | |
288 + { | |
289 + switch (searchengines[i].nr) | |
290 + { | |
291 + case 0: | |
292 + return g_strdup_printf("%s", searchengines[i].u… | |
293 + break; | |
294 + case 2: | |
295 + return g_strdup_printf(searchengines[i].uri, pt… | |
296 + break; | |
297 + default: | |
298 + return g_strdup_printf(searchengines[i].uri, pt… | |
299 + break; | |
300 + } | |
301 + } | |
302 + | |
303 + if (strcmp(pt, searchengines[i].token) == 0 && strstr(s… | |
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 |