summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/content.h2
-rw-r--r--content/fetchcache.c59
-rw-r--r--css/css.c3
-rw-r--r--desktop/browser.c12
-rw-r--r--render/html.c4
-rw-r--r--riscos/plugin.c2
-rw-r--r--riscos/theme_install.c1
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 */
diff --git a/css/css.c b/css/css.c
index 381d9a5aa..e34169080 100644
--- a/css/css.c
+++ b/css/css.c
@@ -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);