diff options
-rw-r--r-- | content/content.h | 2 | ||||
-rw-r--r-- | content/fetchcache.c | 59 | ||||
-rw-r--r-- | css/css.c | 3 | ||||
-rw-r--r-- | desktop/browser.c | 12 | ||||
-rw-r--r-- | render/html.c | 4 | ||||
-rw-r--r-- | riscos/plugin.c | 2 | ||||
-rw-r--r-- | riscos/theme_install.c | 1 |
7 files changed, 61 insertions, 22 deletions
diff --git a/content/content.h b/content/content.h index 5e130e138..f2f3f4de2 100644 --- a/content/content.h +++ b/content/content.h @@ -89,6 +89,7 @@ typedef enum { CONTENT_MSG_REDRAW, /**< needs redraw (eg. new animation frame) */ CONTENT_MSG_NEWPTR, /**< structure has been replaced */ CONTENT_MSG_REFRESH, /**< wants refresh */ + CONTENT_MSG_LAUNCH, /**< needs url launching in external program */ #ifdef WITH_AUTH CONTENT_MSG_AUTH, /**< authentication required */ #endif @@ -117,6 +118,7 @@ union content_msg_data { } redraw; const char *auth_realm; /**< Realm, for CONTENT_MSG_AUTH. */ int delay; /**< Minimum delay, for CONTENT_MSG_REFRESH */ + const char *launch_url; /**< URL to launch, for CONTENT_MSG_LAUNCH */ struct { /** Certificate chain (certs[0] == server) */ const struct ssl_cert_info *certs; diff --git a/content/fetchcache.c b/content/fetchcache.c index 5d5753af7..d7e180b89 100644 --- a/content/fetchcache.c +++ b/content/fetchcache.c @@ -814,6 +814,7 @@ void fetchcache_redirect(struct content *c, const void *data, long http_code; const char *ref; const char *parent; + bool can_fetch; union content_msg_data msg_data; url_func_result result; @@ -933,6 +934,9 @@ void fetchcache_redirect(struct content *c, const void *data, /* No longer need url1 */ free(url1); + /* Determine if we've got a fetch handler for this url */ + can_fetch = fetch_can_fetch(url); + /* Process users of this content */ while (c->user_list->next) { intptr_t p1, p2; @@ -946,34 +950,45 @@ void fetchcache_redirect(struct content *c, const void *data, p2 = c->user_list->next->p2; callback = c->user_list->next->callback; + /* If we can't fetch this url, attempt to launch it */ + if (!can_fetch) { + msg_data.launch_url = url; + callback(CONTENT_MSG_LAUNCH, c, p1, p2, msg_data); + } + /* Remove user */ content_remove_user(c, callback, p1, p2); - /* Get replacement content -- HTTP GET request */ - replacement = fetchcache(url, callback, p1, p2, - c->width, c->height, c->no_error_pages, - NULL, NULL, false, c->download); - if (!replacement) { - msg_data.error = messages_get("BadRedirect"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - - free(url); - free(parent_url); - free(referer); - return; - } + if (can_fetch) { + /* Get replacement content -- HTTP GET request */ + replacement = fetchcache(url, callback, p1, p2, + c->width, c->height, c->no_error_pages, + NULL, NULL, false, c->download); + if (!replacement) { + msg_data.error = messages_get("BadRedirect"); + content_broadcast(c, CONTENT_MSG_ERROR, + msg_data); - /* Set replacement's redirect count to 1 greater than ours */ - replacement->redirect_count = c->redirect_count + 1; + free(url); + free(parent_url); + free(referer); + return; + } - /* Notify user that content has changed */ - msg_data.new_url = url; - callback(CONTENT_MSG_NEWPTR, replacement, p1, p2, msg_data); + /* Set replacement's redirect count to 1 greater + * than ours */ + replacement->redirect_count = c->redirect_count + 1; - /* Start fetching the replacement content */ - fetchcache_go(replacement, referer, callback, p1, p2, - c->width, c->height, NULL, NULL, - false, parent_url); + /* Notify user that content has changed */ + msg_data.new_url = url; + callback(CONTENT_MSG_NEWPTR, replacement, + p1, p2, msg_data); + + /* Start fetching the replacement content */ + fetchcache_go(replacement, referer, callback, p1, p2, + c->width, c->height, NULL, NULL, + false, parent_url); + } } /* Clean up */ @@ -946,6 +946,9 @@ void css_atimport_callback(content_msg msg, struct content *css, case CONTENT_MSG_SSL: #endif /* todo: handle AUTH and SSL */ + + case CONTENT_MSG_LAUNCH: + /* Fall through */ case CONTENT_MSG_ERROR: /* The stylesheet we were fetching may have been * redirected, in that case, the object pointers diff --git a/desktop/browser.c b/desktop/browser.c index 8d9ac6d8a..9e87f72e4 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -559,6 +559,18 @@ void browser_window_callback(content_msg msg, struct content *c, } break; + case CONTENT_MSG_LAUNCH: + assert(data.launch_url != NULL); + + bw->loading_content = NULL; + + gui_launch_url(data.launch_url); + + browser_window_stop_throbber(bw); + free(bw->referer); + bw->referer = 0; + break; + #ifdef WITH_AUTH case CONTENT_MSG_AUTH: gui_401login_open(bw, c, data.auth_realm); diff --git a/render/html.c b/render/html.c index e803f2ea6..2bd1437c9 100644 --- a/render/html.c +++ b/render/html.c @@ -1097,6 +1097,8 @@ void html_convert_css_callback(content_msg msg, struct content *css, c->active--; break; + case CONTENT_MSG_LAUNCH: + /* Fall through */ case CONTENT_MSG_ERROR: LOG(("stylesheet %s failed: %s", css->url, data.error)); /* The stylesheet we were fetching may have been @@ -1325,6 +1327,8 @@ void html_object_callback(content_msg msg, struct content *object, c->active--; break; + case CONTENT_MSG_LAUNCH: + /* Fall through */ case CONTENT_MSG_ERROR: /* The object we were fetching may have been * redirected, in that case, the object pointers diff --git a/riscos/plugin.c b/riscos/plugin.c index 19f0f106f..c08397de4 100644 --- a/riscos/plugin.c +++ b/riscos/plugin.c @@ -1693,6 +1693,8 @@ void plugin_stream_callback(content_msg msg, struct content *c, plugin_send_stream_new(p); break; + case CONTENT_MSG_LAUNCH: + /* Fall through */ case CONTENT_MSG_ERROR: /* The plugin we were fetching may have been * redirected, in that case, the object pointers diff --git a/riscos/theme_install.c b/riscos/theme_install.c index 4fa77a687..7f151fd94 100644 --- a/riscos/theme_install.c +++ b/riscos/theme_install.c @@ -128,6 +128,7 @@ void theme_install_callback(content_msg msg, struct content *c, case CONTENT_MSG_REFORMAT: case CONTENT_MSG_REDRAW: case CONTENT_MSG_NEWPTR: + case CONTENT_MSG_LAUNCH: case CONTENT_MSG_AUTH: default: assert(0); |