diff options
-rw-r--r-- | AUTHORS | 2 | ||||
-rw-r--r-- | docs/INSTALL | 1 | ||||
-rw-r--r-- | examples/config/config | 15 | ||||
-rw-r--r-- | src/callbacks.c | 116 | ||||
-rw-r--r-- | src/callbacks.h | 9 | ||||
-rw-r--r-- | src/uzbl-core.c | 124 | ||||
-rw-r--r-- | src/uzbl-core.h | 8 |
7 files changed, 185 insertions, 90 deletions
@@ -41,7 +41,7 @@ In alphabetical order: Helmut Grohne (helmut) - move void **ptr to union, various fixes Henri Kemppainen (DuClare) <email is akarinotengoku AT THE DOMAIN OF gmail.com> - many contributions, mostly old handler code Igor Bogomazov - mouse ptr events - Jake Probst <jake.probst@gmail.com> - uzbl_tabbed: multiline tablist + Jake Probst <jake.probst@gmail.com> - uzbl_tabbed: multiline tablist, new window opening patches James S Wheaton (uranther) - zoom level, test framework Jan Kolkmeier (jouz) - scrolling, link following Jason Woofenden (JasonWoof) - geometry=maximized, link following diff --git a/docs/INSTALL b/docs/INSTALL index 61a40e3..76ddccc 100644 --- a/docs/INSTALL +++ b/docs/INSTALL @@ -38,7 +38,6 @@ Dependencies which are optional for uzbl-core are marked with an asterisk. (i.e. * zenity [*] * bash [*] * python [*] -* perl (formfiller.pl) [*] * xclip [*] * pango [*] * pygtk [*] diff --git a/examples/config/config b/examples/config/config index a3e1db2..de01cf3 100644 --- a/examples/config/config +++ b/examples/config/config @@ -45,13 +45,15 @@ set cookie_handler = talk_to_socket $XDG_CACHE_HOME/uzbl/cookie_daemon_sock set scheme_handler = sync_spawn @scripts_dir/scheme.py set authentication_handler = sync_spawn @scripts_dir/auth.py -# Open in the same window. -#set new_window = sh 'echo uri "$8" > $4' -# Open a link in a new window. equivalent to default behavior -set new_window = sh 'uzbl-browser -u "$8"' - # --- Optional dynamic event handlers ---------------------------------------- +# Open link in new window +@on_event NEW_WINDOW sh 'uzbl-browser -u "$8"' %r +# Open in current window +#@on_event NEW_WINDOW uri %s +# Open in new tab +#@on_event NEW_WINDOW event NEW_TAB %s + # Download handler @on_event DOWNLOAD_REQUEST spawn @scripts_dir/download.sh %s \@proxy_url @@ -134,6 +136,7 @@ set socket_dir = /tmp #modkey_addition <Key1> <Key2> <Result> @modkey_addition <Shift> <Ctrl> <Meta> @modkey_addition <Shift> <Tab> <Shift-Tab> +@modkey_addition <Shift> <Insert> <Shift-Insert> #ignore_key <glob> @ignore_key <ISO_*> @@ -303,6 +306,8 @@ set toggle_cmd_ins = @toggle_modes command insert @cbind P = sh 'echo "uri `xclip -selection clipboard -o | sed s/\\\@/%40/g`" > $4' # Start a new uzbl instance from the page in primary selection @cbind 'p = sh 'exec uzbl-browser --uri $(xclip -o)' +# paste primary selection into keycmd at the cursor position +@bind <Shift-Insert> = sh 'echo "event INJECT_KEYCMD `xclip -o | sed s/\\\@/%40/g`" > $4' # --- Bookmark inserting binds --- @cbind <Ctrl>b<tags:>_ = sh 'echo -e "$6 %s" >> $XDG_DATA_HOME/uzbl/bookmarks' diff --git a/src/callbacks.c b/src/callbacks.c index ac6c75d..5c8a386 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -290,6 +290,12 @@ cmd_useragent() { } void +cmd_javascript_windows() { + g_object_set (G_OBJECT(view_settings()), "javascript-can-open-windows-automatically", + uzbl.behave.javascript_windows, NULL); +} + +void cmd_scrollbars_visibility() { if(uzbl.gui.scrollbars_visible) { uzbl.gui.bar_h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win)); @@ -629,17 +635,27 @@ navigation_decision_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNe } gboolean -new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *navigation_action, WebKitWebPolicyDecision *policy_decision, gpointer user_data) { +new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, + WebKitNetworkRequest *request, WebKitWebNavigationAction *navigation_action, + WebKitWebPolicyDecision *policy_decision, gpointer user_data) { (void) web_view; (void) frame; (void) navigation_action; (void) policy_decision; (void) user_data; - const gchar* uri = webkit_network_request_get_uri (request); + if (uzbl.state.verbose) - printf("New window requested -> %s \n", uri); - webkit_web_policy_decision_use(policy_decision); - send_event(NEW_WINDOW, uri, NULL); + printf("New window requested -> %s \n", webkit_network_request_get_uri (request)); + + /* This seems to cause trouble and not to be needed anyways + * as create_web_view_cb will also be called whenever this + * callback is triggered thus resulting in doubled events + + send_event(NEW_WINDOW, webkit_network_request_get_uri (request), NULL); + + */ + + webkit_web_policy_decision_ignore(policy_decision); return TRUE; } @@ -672,6 +688,34 @@ request_starting_cb(WebKitWebView *web_view, WebKitWebFrame *frame, WebKitWebRes send_event(REQUEST_STARTING, webkit_network_request_get_uri(request), NULL); } +void +create_web_view_js2_cb (WebKitWebView* web_view, GParamSpec param_spec) { + (void) web_view; + (void) param_spec; + + const gchar* uri = webkit_web_view_get_uri(web_view); + + if (strncmp(uri, "javascript:", strlen("javascript:")) == 0) { + eval_js(uzbl.gui.web_view, (gchar*) uri + strlen("javascript:"), NULL, "javascript:"); + } + else + send_event(NEW_WINDOW, uri, NULL); + + gtk_widget_destroy(GTK_WIDGET(web_view)); +} + + +gboolean +create_web_view_js_cb (WebKitWebView* web_view, gpointer user_data) { + (void) web_view; + (void) user_data; + + g_object_connect (web_view, "signal::notify::uri", + G_CALLBACK(create_web_view_js2_cb), NULL); + return TRUE; +} + + /*@null@*/ WebKitWebView* create_web_view_cb (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data) { (void) web_view; @@ -679,13 +723,30 @@ create_web_view_cb (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer us (void) user_data; if (uzbl.state.selected_url != NULL) { if (uzbl.state.verbose) - printf("\nNew web view -> %s\n",uzbl.state.selected_url); - new_window_load_uri(uzbl.state.selected_url); + printf("\nNew web view -> %s\n", uzbl.state.selected_url); + + if (strncmp(uzbl.state.selected_url, "javascript:", strlen("javascript:")) == 0) { + WebKitWebView* new_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + + g_signal_connect (new_view, "web-view-ready", + G_CALLBACK(create_web_view_js_cb), NULL); + + return new_view; + } + else + send_event(NEW_WINDOW, uzbl.state.selected_url, NULL); + } else { if (uzbl.state.verbose) - printf("New web view -> %s\n","Nothing to open, exiting"); + printf("New web view -> javascript link...\n"); + + WebKitWebView* new_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + + g_signal_connect (new_view, "web-view-ready", + G_CALLBACK(create_web_view_js_cb), NULL); + return new_view; } - return (NULL); + return NULL; } gboolean @@ -762,3 +823,40 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { } } } + +void +save_cookies_js(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie, gpointer user_data) { + (void) jar; + (void) user_data; + (void) old_cookie; + char *scheme; + GString *s; + + if(new_cookie != NULL) { + scheme = (new_cookie->secure == TRUE) ? "https" : "http"; + + s = g_string_new(""); + g_string_printf(s, "PUT '%s' '%s' '%s' '%s=%s'", scheme, new_cookie->domain, new_cookie->path, new_cookie->name, new_cookie->value); + run_handler(uzbl.behave.cookie_handler, s->str); + g_string_free(s, TRUE); + } +} + +void +save_cookies_http(SoupMessage *msg, gpointer user_data) { + (void) user_data; + GSList *ck; + char *cookie; + + for(ck = soup_cookies_from_response(msg); ck; ck = ck->next){ + cookie = soup_cookie_to_set_cookie_header(ck->data); + SoupURI *soup_uri = soup_message_get_uri(msg); + GString *s = g_string_new(""); + g_string_printf(s, "PUT '%s' '%s' '%s' '%s'", soup_uri->scheme, soup_uri->host, soup_uri->path, cookie); + run_handler(uzbl.behave.cookie_handler, s->str); + g_free (cookie); + g_string_free(s, TRUE); + } + + g_slist_free(ck); +} diff --git a/src/callbacks.h b/src/callbacks.h index 278a31a..fdd08e4 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -110,6 +110,9 @@ void cmd_caret_browsing(); void +cmd_javascript_windows(); + +void cmd_set_geometry(); void @@ -207,3 +210,9 @@ button_release_cb (GtkWidget* window, GdkEventButton* event); gboolean focus_cb(GtkWidget* window, GdkEventFocus* event, void *ud); + +void +save_cookies_js(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie, gpointer user_data); + +void +save_cookies_http(SoupMessage *msg, gpointer user_data); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 4d60bd3..227e8c6 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -100,7 +100,6 @@ const struct var_name_to_ptr_t { { "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)}, { "cookie_handler", PTR_V_STR(uzbl.behave.cookie_handler, 1, NULL)}, { "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)}, - { "new_window", PTR_V_STR(uzbl.behave.new_window, 1, NULL)}, { "scheme_handler", PTR_V_STR(uzbl.behave.scheme_handler, 1, NULL)}, { "fifo_dir", PTR_V_STR(uzbl.behave.fifo_dir, 1, cmd_fifo_dir)}, { "socket_dir", PTR_V_STR(uzbl.behave.socket_dir, 1, cmd_socket_dir)}, @@ -110,6 +109,7 @@ const struct var_name_to_ptr_t { { "max_conns", PTR_V_INT(uzbl.net.max_conns, 1, cmd_max_conns)}, { "max_conns_host", PTR_V_INT(uzbl.net.max_conns_host, 1, cmd_max_conns_host)}, { "useragent", PTR_V_STR(uzbl.net.useragent, 1, cmd_useragent)}, + { "javascript_windows", PTR_V_INT(uzbl.behave.javascript_windows, 1, cmd_javascript_windows)}, /* requires webkit >=1.1.14 */ { "view_source", PTR_V_INT(uzbl.behave.view_source, 0, cmd_view_source)}, @@ -195,7 +195,7 @@ gchar * expand(const char *s, guint recurse) { uzbl_cmdprop *c; enum exp_type etype; - char *end_simple_var = "\t^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½"; + char *end_simple_var = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; char *ret = NULL; char *vend = NULL; GError *err = NULL; @@ -493,25 +493,40 @@ parseenv (gchar* string) { return out; } - void clean_up(void) { - send_event(INSTANCE_EXIT, uzbl.info.pid_str, NULL); - g_free(uzbl.info.pid_str); + if(uzbl.info.pid_str) { + send_event(INSTANCE_EXIT, uzbl.info.pid_str, NULL); + g_free(uzbl.info.pid_str); + uzbl.info.pid_str = NULL; + } + + if(uzbl.state.executable_path) { + g_free(uzbl.state.executable_path); + uzbl.state.executable_path = NULL; + } - g_free(uzbl.state.executable_path); if (uzbl.behave.commands) { g_hash_table_destroy(uzbl.behave.commands); uzbl.behave.commands = NULL; } - if(uzbl.state.event_buffer) + if(uzbl.state.event_buffer) { g_ptr_array_free(uzbl.state.event_buffer, TRUE); + uzbl.state.event_buffer = NULL; + } - if (uzbl.behave.fifo_dir) + if (uzbl.behave.fifo_dir) { unlink (uzbl.comm.fifo_path); - if (uzbl.behave.socket_dir) + g_free(uzbl.comm.fifo_path); + uzbl.comm.fifo_path = NULL; + } + + if (uzbl.behave.socket_dir) { unlink (uzbl.comm.socket_path); + g_free(uzbl.comm.socket_path); + uzbl.comm.socket_path = NULL; + } } gint @@ -1220,42 +1235,6 @@ dehilight (WebKitWebView *page, GArray *argv, GString *result) { webkit_web_view_set_highlight_text_matches (page, FALSE); } - -void -new_window_load_uri (const gchar * uri) { - if (uzbl.behave.new_window) { - GString *s = g_string_new (""); - g_string_printf(s, "'%s'", uri); - run_handler(uzbl.behave.new_window, s->str); - send_event(NEW_WINDOW, s->str, NULL); - return; - } - GString* to_execute = g_string_new (""); - g_string_append_printf (to_execute, "%s --uri '%s'", uzbl.state.executable_path, uri); - int i; - for (i = 0; entries[i].long_name != NULL; i++) { - if ((entries[i].arg == G_OPTION_ARG_STRING) && - !strcmp(entries[i].long_name,"uri") && - !strcmp(entries[i].long_name,"name")) { - gchar** str = (gchar**)entries[i].arg_data; - if (*str!=NULL) - g_string_append_printf (to_execute, " --%s '%s'", entries[i].long_name, *str); - } - else if(entries[i].arg == G_OPTION_ARG_STRING_ARRAY) { - int j; - gchar **str = *((gchar ***)entries[i].arg_data); - for(j=0; str[j]; j++) - g_string_append_printf(to_execute, " --%s '%s'", entries[i].long_name, str[j]); - } - } - if (uzbl.state.verbose) - printf("\n%s\n", to_execute->str); - g_spawn_command_line_async (to_execute->str, NULL); - /* TODO: should we just report the uri as event detail? */ - send_event(NEW_WINDOW, to_execute->str, NULL); - g_string_free (to_execute, TRUE); -} - void chain (WebKitWebView *page, GArray *argv, GString *result) { (void) page; (void) result; @@ -1641,7 +1620,7 @@ set_var_value(const gchar *name, gchar *val) { uzbl_cmdprop *c = NULL; char *endp = NULL; char *buf = NULL; - char *invalid_chars = "\t^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½"; + char *invalid_chars = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; GString *msg; if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) { @@ -1674,7 +1653,7 @@ set_var_value(const gchar *name, gchar *val) { /* check wether name violates our naming scheme */ if(strpbrk(name, invalid_chars)) { if (uzbl.state.verbose) - printf("Invalid variable name\n"); + printf("Invalid variable name: %s\n", name); return FALSE; } @@ -2394,16 +2373,15 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au } } -void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data){ +void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data) { (void) session; (void) user_data; - //if (!uzbl.behave.cookie_handler) - // return; - soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies), NULL); + soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies_http), NULL); GString *s = g_string_new (""); SoupURI * soup_uri = soup_message_get_uri(msg); g_string_printf(s, "GET '%s' '%s' '%s'", soup_uri->scheme, soup_uri->host, soup_uri->path); + if(uzbl.behave.cookie_handler) run_handler(uzbl.behave.cookie_handler, s->str); @@ -2413,7 +2391,30 @@ void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data) if ( p != NULL ) *p = '\0'; soup_message_headers_replace (msg->request_headers, "Cookie", (const char *) uzbl.comm.sync_stdout); + int len = strlen(uzbl.comm.sync_stdout); + + if(len > 0) { + SoupCookie *soup_cookie; + char *cookies = (char *) g_malloc(len+1); + strncpy(cookies, uzbl.comm.sync_stdout, len+1); + + /* Disconnect to avoid recusion */ + g_object_disconnect(G_OBJECT(uzbl.net.soup_cookie_jar), "any_signal", G_CALLBACK(save_cookies_js), NULL, NULL); + + p = cookies - 1; + while(p != NULL) { + p = p + 1; + soup_cookie = soup_cookie_parse((const char *) p, soup_uri); + if(soup_cookie->domain == NULL) soup_cookie->domain = soup_uri->host; + soup_cookie_jar_add_cookie(uzbl.net.soup_cookie_jar, soup_cookie); + p = strchr(p, ';'); + } + + g_object_connect(G_OBJECT(uzbl.net.soup_cookie_jar), "signal::changed", G_CALLBACK(save_cookies_js), NULL, NULL); + g_free(cookies); + } } + if (uzbl.comm.sync_stdout) uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); @@ -2421,23 +2422,6 @@ void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data) } void -save_cookies (SoupMessage *msg, gpointer user_data){ - (void) user_data; - GSList *ck; - char *cookie; - for (ck = soup_cookies_from_response(msg); ck; ck = ck->next){ - cookie = soup_cookie_to_set_cookie_header(ck->data); - SoupURI * soup_uri = soup_message_get_uri(msg); - GString *s = g_string_new (""); - g_string_printf(s, "PUT '%s' '%s' '%s' '%s'", soup_uri->scheme, soup_uri->host, soup_uri->path, cookie); - run_handler(uzbl.behave.cookie_handler, s->str); - g_free (cookie); - g_string_free(s, TRUE); - } - g_slist_free(ck); -} - -void dump_var_hash(gpointer k, gpointer v, gpointer ud) { (void) ud; uzbl_cmdprop *c = v; @@ -2535,6 +2519,10 @@ initialize(int argc, char *argv[]) { uzbl.net.soup_session = webkit_get_default_session(); + uzbl.net.soup_cookie_jar = soup_cookie_jar_new(); + soup_session_add_feature(uzbl.net.soup_session, SOUP_SESSION_FEATURE(uzbl.net.soup_cookie_jar)); + g_object_connect(G_OBJECT(uzbl.net.soup_cookie_jar), "signal::changed", G_CALLBACK(save_cookies_js), NULL, NULL); + for(i=0; sigs[i]; i++) { if(setup_signal(sigs[i], catch_signal) == SIG_ERR) fprintf(stderr, "uzbl: error hooking %d: %s\n", sigs[i], strerror(errno)); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 73ec7c1..5760423 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -105,6 +105,7 @@ typedef struct { /* networking */ typedef struct { SoupSession *soup_session; + SoupCookieJar *soup_cookie_jar; SoupLogger *soup_logger; char *proxy_url; char *useragent; @@ -123,7 +124,6 @@ typedef struct { gchar* socket_dir; gchar* cookie_handler; gchar* authentication_handler; - gchar* new_window; gchar* default_font_family; gchar* monospace_font_family; gchar* sans_serif_font_family; @@ -157,6 +157,7 @@ typedef struct { guint enforce_96dpi; gchar *inject_html; guint caret_browsing; + guint javascript_windows; guint mode; gchar* base_url; gboolean print_version; @@ -267,9 +268,6 @@ void load_uri (WebKitWebView * web_view, GArray *argv, GString *result); void -new_window_load_uri (const gchar * uri); - -void chain (WebKitWebView *page, GArray *argv, GString *result); void @@ -394,8 +392,6 @@ handle_authentication (SoupSession *session, void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data); -void -save_cookies (SoupMessage *msg, gpointer user_data); void set_var(WebKitWebView *page, GArray *argv, GString *result); |