aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-04-18 16:16:18 -0400
committerJorge Arellano Cid <jcid@dillo.org>2009-04-18 16:16:18 -0400
commit777f1f5ea25d5ebaeb494f567e678e78c8066368 (patch)
tree529080162cd374d18f214934bef3a1798f645695 /src
parentd0225361f2bbce9c0fefc2174fbe8d4878a2789d (diff)
Implemented Instant client-side redirects (META refresh with delay=0)
http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/H76.html
Diffstat (limited to 'src')
-rw-r--r--src/bw.c4
-rw-r--r--src/bw.h4
-rw-r--r--src/html.cc47
-rw-r--r--src/html_common.hh4
-rw-r--r--src/nav.c51
-rw-r--r--src/nav.h1
-rw-r--r--src/timeout.cc2
-rw-r--r--src/uicmd.cc8
-rw-r--r--src/uicmd.hh1
-rw-r--r--src/url.h2
10 files changed, 93 insertions, 31 deletions
diff --git a/src/bw.c b/src/bw.c
index 92d24556..5e1c47af 100644
--- a/src/bw.c
+++ b/src/bw.c
@@ -59,6 +59,8 @@ BrowserWindow *a_Bw_new()
bw->nav_expect_url = NULL;
bw->redirect_level = 0;
+ bw->meta_refresh_status = 0;
+ bw->meta_refresh_url = NULL;
bw->RootClients = dList_new(8);
bw->ImageClients = dList_new(8);
@@ -101,6 +103,8 @@ void a_Bw_free(BrowserWindow *bw)
dFree(dList_nth_data(bw->nav_stack, j));
dList_free(bw->nav_stack);
+ a_Url_free(bw->meta_refresh_url);
+
dStr_free(bw->page_bugs, 1);
dFree(bw);
break;
diff --git a/src/bw.h b/src/bw.h
index 1c27b676..d005b987 100644
--- a/src/bw.h
+++ b/src/bw.h
@@ -59,6 +59,10 @@ struct _BrowserWindow
* redirection loops (accounts for WEB_RootUrl only) */
int redirect_level;
+ /* Url for zero-delay redirections in the META element */
+ int meta_refresh_status;
+ DilloUrl *meta_refresh_url;
+
/* HTML-bugs detected at parse time */
int num_page_bugs;
Dstr *page_bugs;
diff --git a/src/html.cc b/src/html.cc
index 70eb8981..db6f99d5 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -2763,12 +2763,12 @@ static int Html_tag_pre_excludes(int tag_idx)
/*
* Handle <META>
- * We do not support http-equiv=refresh because it's non standard,
- * (the HTML 4.01 SPEC recommends explicitly to avoid it), and it
- * can be easily abused!
- *
+ * We do not support http-equiv=refresh with delay>0 because it's
+ * non standard, (the HTML 4.01 SPEC recommends explicitly to avoid it).
* More info at:
* http://lists.w3.org/Archives/Public/www-html/2000Feb/thread.html#msg232
+ * Instant client-side redirects (delay=0) are supported:
+ * http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/H76.html
*
* TODO: Note that we're sending custom HTML while still IN_HEAD. This
* is a hackish way to put the message. A much cleaner approach is to
@@ -2786,7 +2786,6 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
const char *equiv, *content, *new_content;
char delay_str[64], *mr_url, *p;
- Dstr *ds_msg;
int delay;
/* only valid inside HEAD */
@@ -2797,7 +2796,7 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
if ((equiv = a_Html_get_attr(html, tag, tagsize, "http-equiv"))) {
if (!dStrcasecmp(equiv, "refresh") &&
- (content = a_Html_get_attr(html, tag, tagsize, "content"))) {
+ (content = a_Html_get_attr(html, tag, tagsize, "content"))) {
/* Get delay, if present, and make a message with it */
if ((delay = strtol(content, NULL, 0))) {
@@ -2818,21 +2817,29 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
mr_url = strdup(content);
}
- /* Send a custom HTML message.
- * TODO: This is a hairy hack,
- * It'd be much better to build a widget. */
- ds_msg = dStr_sized_new(256);
- dStr_sprintf(ds_msg, meta_template, mr_url, delay_str);
- {
- int o_InFlags = html->InFlags;
- int o_TagSoup = html->TagSoup;
- html->InFlags = IN_BODY;
- html->TagSoup = false;
- Html_write_raw(html, ds_msg->str, ds_msg->len, 0);
- html->TagSoup = o_TagSoup;
- html->InFlags = o_InFlags;
+ if (delay == 0) {
+ /* zero-delay redirection */
+ html->stop_parser = true;
+ DilloUrl *new_url = a_Url_new(mr_url, URL_STR(html->base_url));
+ a_UIcmd_redirection0((void*)html->bw, new_url);
+ a_Url_free(new_url);
+ } else {
+ /* Send a custom HTML message.
+ * TODO: This is a hairy hack,
+ * It'd be much better to build a widget. */
+ Dstr *ds_msg = dStr_sized_new(256);
+ dStr_sprintf(ds_msg, meta_template, mr_url, delay_str);
+ {
+ int o_InFlags = html->InFlags;
+ int o_TagSoup = html->TagSoup;
+ html->InFlags = IN_BODY;
+ html->TagSoup = false;
+ Html_write_raw(html, ds_msg->str, ds_msg->len, 0);
+ html->TagSoup = o_TagSoup;
+ html->InFlags = o_InFlags;
+ }
+ dStr_free(ds_msg, 1);
}
- dStr_free(ds_msg, 1);
dFree(mr_url);
} else if (!dStrcasecmp(equiv, "content-type") &&
diff --git a/src/html_common.hh b/src/html_common.hh
index 7a6fda8f..36c6a464 100644
--- a/src/html_common.hh
+++ b/src/html_common.hh
@@ -185,8 +185,8 @@ public: //BUG: for now everything is public
Dstr *attr_data; /* Buffer for attribute value */
- int32_t non_css_link_color; /* as provided by link attribute in <body> */
- int32_t non_css_visited_color; /* as provided by vlink attribute in <body> */
+ int32_t non_css_link_color; /* as provided by link attribute in BODY */
+ int32_t non_css_visited_color; /* as provided by vlink attribute in BODY */
int32_t visited_color; /* as computed according to CSS */
/* -------------------------------------------------------------------*/
diff --git a/src/nav.c b/src/nav.c
index 36bf6b46..69f3b686 100644
--- a/src/nav.c
+++ b/src/nav.c
@@ -194,7 +194,7 @@ static void Nav_stack_clean(BrowserWindow *bw)
static void Nav_open_url(BrowserWindow *bw, const DilloUrl *url, int offset)
{
DilloUrl *old_url;
- bool_t MustLoad, ForceReload, Repush;
+ bool_t MustLoad, ForceReload, Repush, IgnoreScroll;
int x, y, idx, ClientKey;
DilloWeb *Web;
@@ -202,13 +202,14 @@ static void Nav_open_url(BrowserWindow *bw, const DilloUrl *url, int offset)
Repush = (URL_FLAGS(url) & URL_ReloadFromCache) != 0;
ForceReload = (URL_FLAGS(url) & (URL_E2EQuery + URL_ReloadFromCache)) != 0;
+ IgnoreScroll = (URL_FLAGS(url) & URL_IgnoreScroll) != 0;
/* Get the url of the current page */
idx = a_Nav_stack_ptr(bw);
old_url = a_History_get_url(NAV_UIDX(bw, idx));
_MSG("Nav_open_url: old_url='%s' idx=%d\n", URL_STR(old_url), idx);
/* Record current scrolling position */
- if (old_url) {
+ if (old_url && !IgnoreScroll) {
a_UIcmd_get_scroll_xy(bw, &x, &y);
Nav_save_scroll_pos(bw, idx, x, y);
_MSG("Nav_open_url: saved scroll of '%s' at x=%d y=%d\n",
@@ -254,6 +255,8 @@ void a_Nav_cancel_expect(BrowserWindow *bw)
}
bw->nav_expecting = FALSE;
}
+ if (bw->meta_refresh_status > 0)
+ --bw->meta_refresh_status;
}
/*
@@ -264,7 +267,7 @@ void a_Nav_cancel_expect(BrowserWindow *bw)
*/
void a_Nav_expect_done(BrowserWindow *bw)
{
- int url_idx, posx, posy, reload, repush, e2equery, goto_old_scroll = TRUE;
+ int m, url_idx, posx, posy, reload, repush, e2equery, goto_old_scroll=TRUE;
DilloUrl *url;
char *fragment = NULL;
@@ -277,11 +280,10 @@ void a_Nav_expect_done(BrowserWindow *bw)
e2equery = (URL_FLAGS(url) & URL_E2EQuery);
fragment = a_Url_decode_hex_str(URL_FRAGMENT_(url));
- /* Unset E2EQuery, ReloadPage and ReloadFromCache
+ /* Unset E2EQuery, ReloadPage, ReloadFromCache and IgnoreScroll
* before adding this url to history */
- a_Url_set_flags(url, URL_FLAGS(url) & ~URL_E2EQuery);
- a_Url_set_flags(url, URL_FLAGS(url) & ~URL_ReloadPage);
- a_Url_set_flags(url, URL_FLAGS(url) & ~URL_ReloadFromCache);
+ m = URL_E2EQuery|URL_ReloadPage|URL_ReloadFromCache|URL_IgnoreScroll;
+ a_Url_set_flags(url, URL_FLAGS(url) & ~m);
url_idx = a_History_add_url(url);
if (repush) {
@@ -389,6 +391,41 @@ void a_Nav_repush(BrowserWindow *bw)
}
/*
+ * This one does a_Nav_redirection0's job.
+ */
+static void Nav_redirection0_callback(void *data)
+{
+ BrowserWindow *bw = (BrowserWindow *)data;
+ _MSG(">>>> Nav_redirection0_callback <<<<\n");
+
+ if (bw->meta_refresh_status == 2) {
+ Nav_stack_move_ptr(bw, -1);
+ a_Nav_push(bw, bw->meta_refresh_url);
+ }
+ a_Url_free(bw->meta_refresh_url);
+ bw->meta_refresh_url = NULL;
+ bw->meta_refresh_status = 0;
+ a_Timeout_remove();
+}
+
+/*
+ * Handle a zero-delay URL redirection given by META
+ */
+void a_Nav_redirection0(BrowserWindow *bw, const DilloUrl *new_url)
+{
+ dReturn_if_fail (bw != NULL);
+ _MSG(">>> a_Nav_redirection0 <<<<\n");
+
+ if (bw->meta_refresh_url)
+ a_Url_free(bw->meta_refresh_url);
+ bw->meta_refresh_url = a_Url_dup(new_url);
+ a_Url_set_flags(bw->meta_refresh_url,
+ URL_FLAGS(new_url)|URL_E2EQuery|URL_IgnoreScroll);
+ bw->meta_refresh_status = 2;
+ a_Timeout_add(0.0, Nav_redirection0_callback, (void*)bw);
+}
+
+/*
* Same as a_Nav_push() but in a new window.
*/
void a_Nav_push_nw(BrowserWindow *bw, const DilloUrl *url)
diff --git a/src/nav.h b/src/nav.h
index 4a03960a..a37d012c 100644
--- a/src/nav.h
+++ b/src/nav.h
@@ -13,6 +13,7 @@
extern "C" {
#endif /* __cplusplus */
+void a_Nav_redirection0(BrowserWindow *bw, const DilloUrl *new_url);
void a_Nav_push(BrowserWindow *bw, const DilloUrl *url);
void a_Nav_push_nw(BrowserWindow *bw, const DilloUrl *url);
void a_Nav_vpush(void *vbw, const DilloUrl *url);
diff --git a/src/timeout.cc b/src/timeout.cc
index 356134cc..80eb6425 100644
--- a/src/timeout.cc
+++ b/src/timeout.cc
@@ -29,7 +29,7 @@ void a_Timeout_add(float t, TimeoutCb_t cb, void *cbdata)
}
/*
- * To be called from iside the 'cb' function when it wants to keep running
+ * To be called from inside the 'cb' function when it wants to keep running
*/
void a_Timeout_repeat(float t, TimeoutCb_t cb, void *cbdata)
{
diff --git a/src/uicmd.cc b/src/uicmd.cc
index de52b779..ac743f62 100644
--- a/src/uicmd.cc
+++ b/src/uicmd.cc
@@ -671,6 +671,14 @@ void a_UIcmd_repush(void *vbw)
}
/*
+ * Zero-delay URL redirection.
+ */
+void a_UIcmd_redirection0(void *vbw, const DilloUrl *url)
+{
+ a_Nav_redirection0((BrowserWindow*)vbw, url);
+}
+
+/*
* Return a suitable filename for a given URL path.
*/
static char *UIcmd_make_save_filename(const char *pathstr)
diff --git a/src/uicmd.hh b/src/uicmd.hh
index 134ed5ec..f10d43ee 100644
--- a/src/uicmd.hh
+++ b/src/uicmd.hh
@@ -22,6 +22,7 @@ void a_UIcmd_forw_popup(void *vbw);
void a_UIcmd_home(void *vbw);
void a_UIcmd_reload(void *vbw);
void a_UIcmd_repush(void *vbw);
+void a_UIcmd_redirection0(void *vbw, const DilloUrl *url);
void a_UIcmd_save(void *vbw);
void a_UIcmd_stop(void *vbw);
void a_UIcmd_tools(void *vbw, void *v_wid);
diff --git a/src/url.h b/src/url.h
index 02e89539..c6f6e6a4 100644
--- a/src/url.h
+++ b/src/url.h
@@ -39,7 +39,7 @@
#define URL_ReloadPage (1 << 7)
#define URL_ReloadFromCache (1 << 8)
-#define URL_ReloadIncomplete (1 << 9)
+#define URL_IgnoreScroll (1 << 9)
#define URL_SpamSafe (1 << 10)
#define URL_MultipartEnc (1 << 11)