+void
+decideresource(WebKitPolicyDecision *d, Client *c)
+{
+ int i, isascii = 1;
+ WebKitResponsePolicyDecision *r = WEBKIT_RESPONSE_POLICY_DECISION(d);
+ WebKitURIResponse *res =
+ webkit_response_policy_decision_get_response(r);
+ const gchar *uri = webkit_uri_response_get_uri(res);
+
+ if (g_str_has_suffix(uri, "/favicon.ico"))
+ webkit_uri_request_set_uri(
+ webkit_response_policy_decision_get_request(r),
+ "about:blank");
+
+ if (!g_str_has_prefix(uri, "http://")
+ && !g_str_has_prefix(uri, "https://")
+ && !g_str_has_prefix(uri, "about:")
+ && !g_str_has_prefix(uri, "file://")
+ && !g_str_has_prefix(uri, "data:")
+ && !g_str_has_prefix(uri, "blob:")
+ && strlen(uri) > 0) {
+ for (i = 0; i < strlen(uri); i++) {
+ if (!g_ascii_isprint(uri[i])) {
+ isascii = 0;
+ break;
+ }
+ }
+ if (isascii) {
+ handleplumb(c, uri);
+ webkit_policy_decision_ignore(d);
+ }
+ }
+
+ if (webkit_response_policy_decision_is_mime_type_supported(r)) {
+ webkit_policy_decision_use(d);
+ } else {
+ webkit_policy_decision_ignore(d);
+ download(c, res);
+ }
+}
+
+void
+downloadstarted(WebKitWebContext *wc, WebKitDownload *d, Client *c)
+{
+ g_signal_connect(G_OBJECT(d), "notify::response",
+ G_CALLBACK(responsereceived), c);
+}
+
+void
+responsereceived(WebKitDownload *d, GParamSpec *ps, Client *c)
+{
+ download(c, webkit_download_get_response(d));
+ webkit_download_cancel(d);
+}
+
+void
+download(Client *c, WebKitURIResponse *r)
+{
+ Arg a = (Arg)DOWNLOAD(webkit_uri_response_get_uri(r), geturi(c));
+ spawn(c, &a);
+}
+
+void
+closeview(WebKitWebView *v, Client *c)
+{
+ gtk_widget_destroy(c->win);
+}
+
+void
+destroywin(GtkWidget* w, Client *c)
+{
+ destroyclient(c);
+ if (!clients)
+ gtk_main_quit();
+}
+
+void
+pasteuri(GtkClipboard *clipboard, const char *text, gpointer d)
+{
+ Arg a = {.v = text };
+ if (!text)
+ loaduri((Client *) d, &a);
+}
+
+void
+reload(Client *c, const Arg *a)
+{
+ if (a->b)
+ webkit_web_view_reload_bypass_cache(c->view);
+ else
+ webkit_web_view_reload(c->view);
+}
+
+void
+print(Client *c, const Arg *a)
+{
+ webkit_print_operation_run_dialog(webkit_print_operation_new(c->view),
+ GTK_WINDOW(c->win));
+}
+
+void
+clipboard(Client *c, const Arg *a)
+{
+ if (a->b) { /* load clipboard uri */
+ gtk_clipboard_request_text(gtk_clipboard_get(
+ GDK_SELECTION_PRIMARY),
+ pasteuri, c);
+ } else { /* copy uri */
+ gtk_clipboard_set_text(gtk_clipboard_get(
+ GDK_SELECTION_PRIMARY), c->targeturi
+ ? c->targeturi : geturi(c), -1);
+ }
+}
+
+void
+zoom(Client *c, const Arg *a)
+{
+ if (a->i > 0)
+ webkit_web_view_set_zoom_level(c->view, zoomlevel + 0.1);
+ else if (a->i < 0)
+ webkit_web_view_set_zoom_level(c->view, zoomlevel - 0.1);
+ else
+ webkit_web_view_set_zoom_level(c->view, 1.0);
+
+ zoomlevel = webkit_web_view_get_zoom_level(c->view);
+}
+
+void
+scroll_v(Client *c, const Arg *a)
+{
+ evalscript(c, "window.scrollBy(0, %d * (window.innerHeight / 100))",
+ a->i);
+}
+
+void
+scroll_h(Client *c, const Arg *a)
+{
+ evalscript(c, "window.scrollBy(%d * (window.innerWidth / 100), 0)",
+ a->i);
+}
+
+void
+navigate(Client *c, const Arg *a)
+{
+ if (a->i < 0)
+ webkit_web_view_go_back(c->view);
+ else if (a->i > 0)
+ webkit_web_view_go_forward(c->view);
+}
+
+void
+stop(Client *c, const Arg *a)
+{
+ webkit_web_view_stop_loading(c->view);
+}
+
+void
+toggle(Client *c, const Arg *a)
+{
+ WebKitSettings *s = webkit_web_view_get_settings(c->view);
+
+ switch ((unsigned int)a->i) {
+ case CaretBrowsing:
+ enablecaretbrowsing = !enablecaretbrowsing;
+ webkit_settings_set_enable_caret_browsing(s,
+ enablecaretbrowsing);
+ updatetitle(c);
+ return; /* do not reload */
+ break;
+ case FrameFlattening:
+ enableframeflattening = !enableframeflattening;
+ webkit_settings_set_enable_frame_flattening(s,
+ enableframeflattening);
+ break;
+ case Geolocation:
+ allowgeolocation = !allowgeolocation;
+ break;
+ case JavaScript:
+ enablescripts = !enablescripts;
+ webkit_settings_set_enable_javascript(s, enablescripts);
+ break;
+ case LoadImages:
+ loadimages = !loadimages;
+ webkit_settings_set_auto_load_images(s, loadimages);
+ break;
+ case Plugins:
+ enableplugins = !enableplugins;
+ webkit_settings_set_enable_plugins(s, enableplugins);
+ break;
+ case ScrollBars:
+ /* Disabled until we write some WebKitWebExtension for
+ * manipulating the DOM directly.
+ enablescrollbars = !enablescrollbars;
+ evalscript(c, "document.documentElement.style.overflow = '%s'",
+ enablescrollbars ? "auto" : "hidden");
+ */
+ return; /* do not reload */
+ break;
+ default:
+ break;
+ }
+ reload(c, a);
+}
+
+void
+togglefullscreen(Client *c, const Arg *a)
+{
+ /* toggling value is handled in winevent() */
+ if (c->fullscreen)
+ gtk_window_unfullscreen(GTK_WINDOW(c->win));
+ else
+ gtk_window_fullscreen(GTK_WINDOW(c->win));
+}
+
+void
+togglecookiepolicy(Client *c, const Arg *a)
+{
+ ++cookiepolicy;
+ cookiepolicy %= strlen(cookiepolicies);
+
+ webkit_cookie_manager_set_accept_policy(
+ webkit_web_context_get_cookie_manager(
+ webkit_web_view_get_context(c->view)),
+ cookiepolicy_get());
+
+ updatetitle(c);
+ /* Do not reload. */
+}
+
+void
+togglestyle(Client *c, const Arg *a)
+{
+ enablestyle = !enablestyle;
+ setstyle(c, enablestyle ? getstyle(geturi(c)) : "");
+
+ updatetitle(c);
+}
+
+void
+toggleinspector(Client *c, const Arg *a)
+{
+ if (enableinspector) {
+ if (webkit_web_inspector_is_attached(c->inspector))
+ webkit_web_inspector_close(c->inspector);
+ else
+ webkit_web_inspector_show(c->inspector);
+ }
+}
+
+void
+find(Client *c, const Arg *a)
+{
+ const char *s, *f;
+
+ if (a && a->i) {
+ if (a->i > 0)
+ webkit_find_controller_search_next(c->finder);
+ else
+ webkit_find_controller_search_previous(c->finder);
+ } else {
+ s = getatom(c, AtomFind);
+ f = webkit_find_controller_get_search_text(c->finder);
+
+ if (g_strcmp0(f, s) == 0) /* reset search */
+ webkit_find_controller_search(c->finder, "", findopts,
+ G_MAXUINT);
+
+ webkit_find_controller_search(c->finder, s, findopts,
+ G_MAXUINT);
+
+ if (strcmp(s, "") == 0)
+ webkit_find_controller_search_finish(c->finder);
+ }
+}
+
+void
+clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h)
+{
+ navigate(c, a);
+}
+
+void
+clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h)
+{
+ Arg arg;
+
+ arg.v = webkit_hit_test_result_get_link_uri(h);
+ newwindow(c, &arg, a->b);
+}
+
+void
+clickexternplayer(Client *c, const Arg *a, WebKitHitTestResult *h)
+{
+ Arg arg;
+
+ if (webkit_hit_test_result_get_context(h) & OnMedia) {
+ arg = (Arg)VIDEOPLAY(webkit_hit_test_result_get_media_uri(h));
+ spawn(c, &arg);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ Arg arg;