+ g_free(cookiefile);
+ g_free(scriptfile);
+ g_free(stylefile);
+}
+
+static void
+cookiejar_changed(SoupCookieJar *self, SoupCookie *old_cookie,
+ SoupCookie *new_cookie) {
+ flock(COOKIEJAR(self)->lock, LOCK_EX);
+ if(new_cookie && !new_cookie->expires && sessiontime) {
+ soup_cookie_set_expires(new_cookie,
+ soup_date_new_from_now(sessiontime));
+ }
+ SOUP_COOKIE_JAR_CLASS(cookiejar_parent_class)->changed(self,
+ old_cookie, new_cookie);
+ flock(COOKIEJAR(self)->lock, LOCK_UN);
+}
+
+static void
+cookiejar_class_init(CookieJarClass *klass) {
+ SOUP_COOKIE_JAR_CLASS(klass)->changed = cookiejar_changed;
+ G_OBJECT_CLASS(klass)->get_property =
+ G_OBJECT_CLASS(cookiejar_parent_class)->get_property;
+ G_OBJECT_CLASS(klass)->set_property = cookiejar_set_property;
+ G_OBJECT_CLASS(klass)->finalize = cookiejar_finalize;
+ g_object_class_override_property(G_OBJECT_CLASS(klass), 1, "filename");
+}
+
+static void
+cookiejar_finalize(GObject *self) {
+ close(COOKIEJAR(self)->lock);
+ G_OBJECT_CLASS(cookiejar_parent_class)->finalize(self);
+}
+
+static void
+cookiejar_init(CookieJar *self) {
+ self->lock = open(cookiefile, 0);
+}
+
+static SoupCookieJar *
+cookiejar_new(const char *filename, gboolean read_only) {
+ return g_object_new(COOKIEJAR_TYPE,
+ SOUP_COOKIE_JAR_TEXT_FILENAME, filename,
+ SOUP_COOKIE_JAR_READ_ONLY, read_only, NULL);
+}
+
+static void
+cookiejar_set_property(GObject *self, guint prop_id, const GValue *value,
+ GParamSpec *pspec) {
+ flock(COOKIEJAR(self)->lock, LOCK_SH);
+ G_OBJECT_CLASS(cookiejar_parent_class)->set_property(self, prop_id,
+ value, pspec);
+ flock(COOKIEJAR(self)->lock, LOCK_UN);
+}
+
+static void
+evalscript(JSContextRef js, char *script, char* scriptname) {
+ JSStringRef jsscript, jsscriptname;
+ JSValueRef exception = NULL;
+
+ jsscript = JSStringCreateWithUTF8CString(script);
+ jsscriptname = JSStringCreateWithUTF8CString(scriptname);
+ JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), jsscriptname, 0, &exception);
+ JSStringRelease(jsscript);
+ JSStringRelease(jsscriptname);
+}
+
+static void
+runscript(WebKitWebFrame *frame) {
+ char *script;
+ GError *error;
+
+ if(g_file_get_contents(scriptfile, &script, NULL, &error)) {
+ evalscript(webkit_web_frame_get_global_context(frame), script, scriptfile);
+ }
+}
+
+static void
+clipboard(Client *c, const Arg *arg) {
+ gboolean paste = *(gboolean *)arg;
+
+ if(paste)
+ gtk_clipboard_request_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), pasteuri, c);
+ else
+ gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), c->linkhover ? c->linkhover : geturi(c), -1);
+}
+
+static char *
+copystr(char **str, const char *src) {
+ char *tmp;
+ tmp = g_strdup(src);
+
+ if(str && *str) {
+ g_free(*str);
+ *str = tmp;
+ }
+ return tmp;
+}
+
+static WebKitWebView *
+createwindow(WebKitWebView *v, WebKitWebFrame *f, Client *c) {
+ Client *n = newclient();
+ return n->view;
+}
+
+static gboolean
+decidedownload(WebKitWebView *v, WebKitWebFrame *f, WebKitNetworkRequest *r,
+ gchar *m, WebKitWebPolicyDecision *p, Client *c) {
+ if(!webkit_web_view_can_show_mime_type(v, m)) {
+ webkit_web_policy_decision_download(p);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+decidewindow(WebKitWebView *view, WebKitWebFrame *f, WebKitNetworkRequest *r,
+ WebKitWebNavigationAction *n, WebKitWebPolicyDecision *p,
+ Client *c) {
+ Arg arg;
+
+ if(webkit_web_navigation_action_get_reason(n) ==
+ WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED) {
+ webkit_web_policy_decision_ignore(p);
+ arg.v = (void *)webkit_network_request_get_uri(r);
+ newwindow(NULL, &arg, 0);
+ return TRUE;
+ }
+ return FALSE;