changeset 1037:a72e5506e280

Implemented Instant client-side redirects (META refresh with delay=0) http://www.w3.org/TR/2008/NOTE-WCAG20-TECHS-20081211/H76.html
author Jorge Arellano Cid <jcid@dillo.org>
date Sat, 18 Apr 2009 16:16:18 -0400
parents bfda92d18f03
children 4d38b02bc704
files src/bw.c src/bw.h src/html.cc src/html_common.hh src/nav.c src/nav.h src/timeout.cc src/uicmd.cc src/uicmd.hh src/url.h
diffstat 10 files changed, 93 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/bw.c	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/bw.c	Sat Apr 18 16:16:18 2009 -0400
@@ -59,6 +59,8 @@
    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 @@
             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;
--- a/src/bw.h	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/bw.h	Sat Apr 18 16:16:18 2009 -0400
@@ -59,6 +59,10 @@
     * 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;
--- a/src/html.cc	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/html.cc	Sat Apr 18 16:16:18 2009 -0400
@@ -2763,12 +2763,12 @@
 
 /*
  * 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 @@
 
    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 @@
 
    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 @@
             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") &&
--- a/src/html_common.hh	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/html_common.hh	Sat Apr 18 16:16:18 2009 -0400
@@ -185,8 +185,8 @@
 
    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 */
 
    /* -------------------------------------------------------------------*/
--- a/src/nav.c	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/nav.c	Sat Apr 18 16:16:18 2009 -0400
@@ -194,7 +194,7 @@
 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 @@
 
    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 @@
       }
       bw->nav_expecting = FALSE;
    }
+   if (bw->meta_refresh_status > 0)
+      --bw->meta_refresh_status;
 }
 
 /*
@@ -264,7 +267,7 @@
  */
 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 @@
       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 @@
 }
 
 /*
+ * 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)
--- a/src/nav.h	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/nav.h	Sat Apr 18 16:16:18 2009 -0400
@@ -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);
--- a/src/timeout.cc	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/timeout.cc	Sat Apr 18 16:16:18 2009 -0400
@@ -29,7 +29,7 @@
 }
 
 /*
- * 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)
 {
--- a/src/uicmd.cc	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/uicmd.cc	Sat Apr 18 16:16:18 2009 -0400
@@ -671,6 +671,14 @@
 }
 
 /*
+ * 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)
--- a/src/uicmd.hh	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/uicmd.hh	Sat Apr 18 16:16:18 2009 -0400
@@ -22,6 +22,7 @@
 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);
--- a/src/url.h	Wed Apr 08 21:37:48 2009 +0200
+++ b/src/url.h	Sat Apr 18 16:16:18 2009 -0400
@@ -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)