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