diff --git a/src/document/html/parser.c b/src/document/html/parser.c
index 546b60c6..49211fb0 100644
--- a/src/document/html/parser.c
+++ b/src/document/html/parser.c
@@ -1,5 +1,9 @@
/* Generic HTML parser routines */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* XXX: we _WANT_ strcasestr() ! */
+#endif
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
diff --git a/src/document/refresh.c b/src/document/refresh.c
index cb8cc9fb..1580e1ef 100644
--- a/src/document/refresh.c
+++ b/src/document/refresh.c
@@ -66,8 +66,8 @@ done_document_refresh(struct document_refresh *refresh)
static void
do_document_refresh(void *data)
{
- struct session *ses = data;
- struct document_refresh *refresh = ses->doc_view->document->refresh;
+ struct document_view *doc_view = data;
+ struct document_refresh *refresh = doc_view->document->refresh;
struct type_query *type_query;
assert(refresh);
@@ -78,26 +78,28 @@ do_document_refresh(void *data)
/* When refreshing documents that will trigger a download (like
* sourceforge's download pages) make sure that we do not endlessly
* trigger the download (bug 289). */
- foreach (type_query, ses->type_queries)
+ foreach (type_query, doc_view->session->type_queries)
if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
return;
- if (compare_uri(refresh->uri, ses->doc_view->document->uri, 0)) {
+ if (compare_uri(refresh->uri, doc_view->document->uri, 0)) {
/* If the refreshing is for the current URI, force a reload. */
- reload(ses, CACHE_MODE_FORCE_RELOAD);
+ reload_frame(doc_view->session, doc_view->name,
+ CACHE_MODE_FORCE_RELOAD);
} else {
/* This makes sure that we send referer. */
- goto_uri_frame(ses, refresh->uri, NULL, CACHE_MODE_NORMAL);
+ goto_uri_frame(doc_view->session, refresh->uri, doc_view->name, CACHE_MODE_NORMAL);
/* XXX: A possible very wrong work-around for refreshing used when
* downloading files. */
refresh->restart = 0;
}
}
-void
-start_document_refresh(struct document_refresh *refresh, struct session *ses)
+static void
+start_document_refresh(struct document_refresh *refresh,
+ struct document_view *doc_view)
{
- milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time", ses);
+ milliseconds_T minimum = (milliseconds_T) get_opt_int("document.browse.minimum_refresh_time", doc_view->session);
milliseconds_T refresh_delay = sec_to_ms(refresh->seconds);
milliseconds_T time = ms_max(refresh_delay, minimum);
struct type_query *type_query;
@@ -114,9 +116,39 @@ start_document_refresh(struct document_refresh *refresh, struct session *ses)
/* Like bug 289 another sourceforge download thingy this time with
* number 434. It should take care when refreshing to the same URI or
* what ever the cause is. */
- foreach (type_query, ses->type_queries)
+ foreach (type_query, doc_view->session->type_queries)
if (compare_uri(refresh->uri, type_query->uri, URI_BASE))
return;
- install_timer(&refresh->timer, time, do_document_refresh, ses);
+ install_timer(&refresh->timer, time, do_document_refresh, doc_view);
+}
+
+void
+start_document_refreshes(struct session *ses)
+{
+
+ assert(ses);
+
+ if (!ses->doc_view
+ || !ses->doc_view->document
+ || !get_opt_bool("document.browse.refresh", ses))
+ return;
+
+ if (document_has_frames(ses->doc_view->document)) {
+ struct document_view *doc_view;
+
+ foreach (doc_view, ses->scrn_frames) {
+ if (!doc_view->document
+ || !doc_view->document->refresh)
+ continue;
+
+ start_document_refresh(doc_view->document->refresh,
+ doc_view);
+ }
+ }
+
+ if (!ses->doc_view->document->refresh)
+ return;
+
+ start_document_refresh(ses->doc_view->document->refresh, ses->doc_view);
}
diff --git a/src/document/refresh.h b/src/document/refresh.h
index f9b4c9c5..2d8732cd 100644
--- a/src/document/refresh.h
+++ b/src/document/refresh.h
@@ -16,6 +16,6 @@ struct document_refresh {
struct document_refresh *init_document_refresh(unsigned char *url, unsigned long seconds);
void done_document_refresh(struct document_refresh *refresh);
void kill_document_refresh(struct document_refresh *refresh);
-void start_document_refresh(struct document_refresh *refresh, struct session *ses);
+void start_document_refreshes(struct session *ses);
#endif
diff --git a/src/dom/test/dom-select.c b/src/dom/test/dom-select.c
index e4cc6f23..52b4a6a3 100644
--- a/src/dom/test/dom-select.c
+++ b/src/dom/test/dom-select.c
@@ -15,21 +15,7 @@
#include "dom/select.h"
#include "dom/sgml/parser.h"
#include "dom/stack.h"
-
-
-void die(const char *msg, ...)
-{
- va_list args;
-
- if (msg) {
- va_start(args, msg);
- vfprintf(stderr, msg, args);
- fputs("\n", stderr);
- va_end(args);
- }
-
- exit(!!NULL);
-}
+#include "util/test.h"
int
main(int argc, char *argv[])
@@ -51,41 +37,14 @@ main(int argc, char *argv[])
arg += 2;
- if (!strncmp(arg, "uri", 3)) {
- arg += 3;
- if (*arg == '=') {
- arg++;
- set_dom_string(&uri, arg, strlen(arg));
- } else {
- i++;
- if (i >= argc)
- die("--uri expects a URI");
- set_dom_string(&uri, argv[i], strlen(argv[i]));
- }
+ if (get_test_opt(&arg, "uri", &i, argc, argv, "a URI")) {
+ set_dom_string(&uri, arg, strlen(arg));
- } else if (!strncmp(arg, "src", 3)) {
- arg += 3;
- if (*arg == '=') {
- arg++;
- set_dom_string(&source, arg, strlen(arg));
- } else {
- i++;
- if (i >= argc)
- die("--src expects a string");
- set_dom_string(&source, argv[i], strlen(argv[i]));
- }
+ } else if (get_test_opt(&arg, "src", &i, argc, argv, "a string")) {
+ set_dom_string(&source, arg, strlen(arg));
- } else if (!strncmp(arg, "selector", 3)) {
- arg += 8;
- if (*arg == '=') {
- arg++;
- set_dom_string(&selector, arg, strlen(arg));
- } else {
- i++;
- if (i >= argc)
- die("--selector expects a string");
- set_dom_string(&selector, argv[i], strlen(argv[i]));
- }
+ } else if (get_test_opt(&arg, "selector", &i, argc, argv, "a string")) {
+ set_dom_string(&selector, arg, strlen(arg));
} else if (!strcmp(arg, "help")) {
die(NULL);
diff --git a/src/dom/test/sgml-parser.c b/src/dom/test/sgml-parser.c
index 5446ccd7..eee862ae 100644
--- a/src/dom/test/sgml-parser.c
+++ b/src/dom/test/sgml-parser.c
@@ -16,6 +16,7 @@
#include "dom/sgml/dump.h"
#include "dom/sgml/parser.h"
#include "dom/stack.h"
+#include "util/test.h"
unsigned int number_of_lines = 0;
@@ -242,44 +243,6 @@ sgml_error_function(struct sgml_parser *parser, struct dom_string *string,
return DOM_CODE_OK;
}
-static void
-die(const char *msg, ...)
-{
- va_list args;
-
- if (msg) {
- va_start(args, msg);
- vfprintf(stderr, msg, args);
- fputs("\n", stderr);
- va_end(args);
- }
-
- exit(!!NULL);
-}
-
-static int
-get_opt(char **argref, const char *name, int *argi, int argc, char *argv[],
- const char *expect_msg)
-{
- char *arg = *argref;
- int namelen = strlen(name);
-
- if (strncmp(arg, name, namelen))
- return 0;
-
- arg += namelen;
- if (*arg == '=') {
- (*argref) = arg + 1;
- } else {
- (*argi)++;
- if ((*argi) >= argc)
- die("--%s expects %s", name, expect_msg);
- (*argref) = argv[(*argi)];
- }
-
- return 1;
-}
-
int
main(int argc, char *argv[])
{
@@ -305,17 +268,17 @@ main(int argc, char *argv[])
arg += 2;
- if (get_opt(&arg, "uri", &i, argc, argv, "a URI")) {
+ if (get_test_opt(&arg, "uri", &i, argc, argv, "a URI")) {
set_dom_string(&uri, arg, strlen(arg));
- } else if (get_opt(&arg, "src", &i, argc, argv, "a string")) {
+ } else if (get_test_opt(&arg, "src", &i, argc, argv, "a string")) {
set_dom_string(&source, arg, strlen(arg));
- } else if (get_opt(&arg, "stdin", &i, argc, argv, "a number")) {
+ } else if (get_test_opt(&arg, "stdin", &i, argc, argv, "a number")) {
read_stdin = atoi(arg);
flags |= SGML_PARSER_INCREMENTAL;
- } else if (get_opt(&arg, "normalize", &i, argc, argv, "a string")) {
+ } else if (get_test_opt(&arg, "normalize", &i, argc, argv, "a string")) {
normalize = 1;
normalize_flags = parse_dom_config(arg, ',');
type = SGML_PARSER_TREE;
diff --git a/src/main/event.c b/src/main/event.c
index 91e1c0c9..9b3bc5dc 100644
--- a/src/main/event.c
+++ b/src/main/event.c
@@ -177,6 +177,7 @@ trigger_event(int id, ...)
va_start(ap, id);
trigger_event_va(id, ap);
+ va_end(ap);
}
void
@@ -187,6 +188,7 @@ trigger_event_name(unsigned char *name, ...)
va_start(ap, name);
trigger_event_va(id, ap);
+ va_end(ap);
}
static inline void
diff --git a/src/mime/backend/mailcap.c b/src/mime/backend/mailcap.c
index 1ca637a6..752c626c 100644
--- a/src/mime/backend/mailcap.c
+++ b/src/mime/backend/mailcap.c
@@ -678,6 +678,9 @@ struct module mailcap_mime_module = struct_module(
);
#ifdef TEST_MAILCAP
+
+#include "util/test.h"
+
/* Some ugly shortcuts for getting defined symbols to work. */
int default_mime_backend,
install_signal_handler,
@@ -685,20 +688,6 @@ int default_mime_backend,
program;
LIST_OF(struct terminal) terminals;
-void die(const char *msg, ...)
-{
- va_list args;
-
- if (msg) {
- va_start(args, msg);
- vfprintf(stderr, msg, args);
- fputs("\n", stderr);
- va_end(args);
- }
-
- exit(1);
-}
-
int
main(int argc, char *argv[])
{
@@ -714,44 +703,16 @@ main(int argc, char *argv[])
arg += 2;
- if (!strncmp(arg, "path", 4)) {
- arg += 4;
- if (*arg == '=') {
- arg++;
- get_mailcap_path() = arg;
- } else {
- i++;
- if (i >= argc)
- die("--path expects a parameter");
- get_mailcap_path() = argv[i];
- }
+ if (get_test_opt(&arg, "path", &i, argc, argv, "a string")) {
+ get_mailcap_path() = arg;
done_mailcap(NULL);
- } else if (!strncmp(arg, "format", 6)) {
- arg += 6;
- if (*arg == '=') {
- arg++;
- format = arg;
- } else {
- i++;
- if (i >= argc)
- die("--format expects a parameter");
- format = argv[i];
- }
+ } else if (get_test_opt(&arg, "format", &i, argc, argv, "a string")) {
+ format = arg;
- } else if (!strncmp(arg, "get", 3)) {
+ } else if (get_test_opt(&arg, "get", &i, argc, argv, "a string")) {
struct mime_handler *handler;
- arg += 3;
- if (*arg == '=') {
- arg++;
- } else {
- i++;
- if (i >= argc)
- die("--get expects a parameter");
- arg = argv[i];
- }
-
if (has_gotten)
printf("\n");
has_gotten = 1;
diff --git a/src/protocol/ftp/ftp-parser.c b/src/protocol/ftp/ftp-parser.c
index 197466a5..b2b7fbf9 100644
--- a/src/protocol/ftp/ftp-parser.c
+++ b/src/protocol/ftp/ftp-parser.c
@@ -13,21 +13,7 @@
#include "osdep/stat.h"
#include "protocol/ftp/parse.h"
-
-
-void die(const char *msg, ...)
-{
- va_list args;
-
- if (msg) {
- va_start(args, msg);
- vfprintf(stderr, msg, args);
- fputs("\n", stderr);
- va_end(args);
- }
-
- exit(!!NULL);
-}
+#include "util/test.h"
int
main(int argc, char *argv[])
@@ -45,17 +31,8 @@ main(int argc, char *argv[])
arg += 2;
- if (!strncmp(arg, "response", 8)) {
- arg += 8;
- if (*arg == '=') {
- arg++;
- response = arg;
- } else {
- i++;
- if (i >= argc)
- die("--response expects a string");
- response = argv[i];
- }
+ if (get_test_opt(&arg, "response", &i, argc, argv, "a string")) {
+ response = arg;
responselen = strlen(response);
} else {
diff --git a/src/protocol/test/.gitignore b/src/protocol/test/.gitignore
index 6656e2d0..6b153e58 100644
--- a/src/protocol/test/.gitignore
+++ b/src/protocol/test/.gitignore
@@ -1 +1 @@
-uri-parser
+uri-test
diff --git a/src/protocol/test/stub.c b/src/protocol/test/stub.c
index 4ed9b672..8b66e34a 100644
--- a/src/protocol/test/stub.c
+++ b/src/protocol/test/stub.c
@@ -13,6 +13,7 @@
#include "main/module.h"
#include "protocol/user.h"
#include "session/session.h"
+#include "util/test.h"
#define STUB_MODULE(name) \
struct module name = struct_module( \
@@ -38,21 +39,6 @@ STUB_MODULE(smb_protocol_module);
STUB_MODULE(uri_rewrite_module);
STUB_MODULE(user_protocol_module);
-static void
-die(const char *msg, ...)
-{
- va_list args;
-
- if (msg) {
- va_start(args, msg);
- vfprintf(stderr, msg, args);
- fputs("\n", stderr);
- va_end(args);
- }
-
- exit(!!NULL);
-}
-
static void
stub_called(const unsigned char *fun)
{
diff --git a/src/protocol/uri.c b/src/protocol/uri.c
index 8a64aede..5ea4fa85 100644
--- a/src/protocol/uri.c
+++ b/src/protocol/uri.c
@@ -785,6 +785,11 @@ normalize_uri(struct uri *uri, unsigned char *uristring)
continue;
}
+ } else if (is_uri_dir_sep(uri, src[1]) &&
+ uri->protocol == PROTOCOL_FILE) {
+ /* // - ignore first '/'. */
+ src += 1;
+ continue;
}
/* We don't want to access memory past the NUL char. */
diff --git a/src/session/session.c b/src/session/session.c
index 70980963..96317100 100644
--- a/src/session/session.c
+++ b/src/session/session.c
@@ -588,13 +588,7 @@ doc_loading_callback(struct download *download, struct session *ses)
load_ecmascript_imports(ses, ses->doc_view);
process_file_requests(ses);
- if (ses->doc_view
- && ses->doc_view->document
- && ses->doc_view->document->refresh
- && get_opt_bool("document.browse.refresh", ses)) {
- start_document_refresh(ses->doc_view->document->refresh,
- ses);
- }
+ start_document_refreshes(ses);
if (download->state != S_OK) {
print_error_dialog(ses, download->state,
@@ -1185,6 +1179,13 @@ destroy_session(struct session *ses)
void
reload(struct session *ses, enum cache_mode cache_mode)
+{
+ reload_frame(ses, NULL, cache_mode);
+}
+
+void
+reload_frame(struct session *ses, unsigned char *name,
+ enum cache_mode cache_mode)
{
abort_loading(ses, 0);
@@ -1212,6 +1213,8 @@ reload(struct session *ses, enum cache_mode cache_mode)
loc->download.data = ses;
loc->download.callback = (download_callback_T *) doc_loading_callback;
+ ses->task.target.frame = name;
+
load_uri(loc->vs.uri, ses->referrer, &loc->download, PRI_MAIN, cache_mode, -1);
foreach (ftl, ses->more_files) {
diff --git a/src/session/session.h b/src/session/session.h
index 0473d1d2..d23c00fe 100644
--- a/src/session/session.h
+++ b/src/session/session.h
@@ -255,6 +255,7 @@ struct session *init_session(struct session *ses, struct terminal *term,
void doc_loading_callback(struct download *, struct session *);
void abort_loading(struct session *, int);
+void reload_frame(struct session *, unsigned char *, enum cache_mode);
void reload(struct session *, enum cache_mode);
void load_frames(struct session *, struct document_view *);
diff --git a/src/terminal/screen.c b/src/terminal/screen.c
index 3cbc7d27..4ac6dc69 100644
--- a/src/terminal/screen.c
+++ b/src/terminal/screen.c
@@ -27,7 +27,8 @@
#include "util/string.h"
-/* TODO: We must use termcap/terminfo if available! --pasky */
+/* TODO: We must use termcap/terminfo if available! --pasky
+ * Please mention ELinks bug 96 in commit logs. --KON */
/** Mapping from (enum ::border_char - 0xB0) to ASCII characters. */
const unsigned char frame_dumb[48] = " ||||++||++++++--|-+||++--|-+----++++++++ ";
@@ -74,11 +75,11 @@ static const unsigned char frame_vt100_u[48] = {
* 0x8D U+250C 'l' ACS_ULCORNER
* 0x8E U+2514 'm' ACS_LLCORNER
* 0x8F U+253C 'n' ACS_PLUS
- * 0x90 - 'o' ACS_S1
- * 0x91 - 'p' ACS_S3
+ * 0x90 U+23BA 'o' ACS_S1
+ * 0x91 U+23BB 'p' ACS_S3
* 0x92 U+2500 'q' ACS_HLINE
- * 0x93 - 'r' ACS_S7
- * 0x94 - 's' ACS_S9
+ * 0x93 U+23BC 'r' ACS_S7
+ * 0x94 U+23BD 's' ACS_S9
* 0x95 U+251C 't' ACS_LTEE
* 0x96 U+2524 'u' ACS_RTEE
* 0x97 U+2534 'v' ACS_BTEE
diff --git a/src/terminal/window.h b/src/terminal/window.h
index 1d47d270..e94da64b 100644
--- a/src/terminal/window.h
+++ b/src/terminal/window.h
@@ -47,8 +47,20 @@ struct window {
/** The terminal (and screen) that hosts the window */
struct terminal *term;
- /** Used for tabs focus detection. */
+ /** For ::WINDOW_TAB, the position and size in the tab bar.
+ * Updated while the tab bar is being drawn, and read if the
+ * user clicks there with the mouse. */
int xpos, width;
+
+ /** The position of something that has focus in the window.
+ * Any popup menus are drawn near this position.
+ * In tab windows, during ::NAVIGATE_CURSOR_ROUTING, this is
+ * also the position of the cursor that the user can move;
+ * there is no separate cursor position for each frame.
+ * In dialog boxes, this is typically the top left corner of
+ * the focused widget, while the cursor is somewhere within
+ * the widget.
+ * @see set_window_ptr, get_parent_ptr, set_cursor */
int x, y;
/** For delayed tab resizing */
diff --git a/src/util/string.c b/src/util/string.c
index c3c953fa..076c491b 100644
--- a/src/util/string.c
+++ b/src/util/string.c
@@ -445,7 +445,6 @@ add_format_to_string(struct string *string, const unsigned char *format, ...)
int newlength;
int width;
va_list ap;
- va_list ap2;
assertm(string && format, "[add_format_to_string]");
if_assert_failed { return NULL; }
@@ -453,17 +452,16 @@ add_format_to_string(struct string *string, const unsigned char *format, ...)
check_string_magic(string);
va_start(ap, format);
- VA_COPY(ap2, ap);
-
- width = vsnprintf(NULL, 0, format, ap2);
+ width = vsnprintf(NULL, 0, format, ap);
+ va_end(ap);
if (width <= 0) return NULL;
newlength = string->length + width;
if (!realloc_string(string, newlength))
return NULL;
+ va_start(ap, format);
vsnprintf(&string->source[string->length], width + 1, format, ap);
-
va_end(ap);
string->length = newlength;
diff --git a/src/util/test.h b/src/util/test.h
new file mode 100644
index 00000000..152a943e
--- /dev/null
+++ b/src/util/test.h
@@ -0,0 +1,50 @@
+/* Test library */
+
+#ifndef EL__UTIL_TEST_H
+#define EL__UTIL_TEST_H
+
+#include
+
+static inline void
+die(const char *msg, ...)
+{
+ va_list args;
+
+ if (msg) {
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ fputs("\n", stderr);
+ va_end(args);
+ }
+
+ exit(EXIT_FAILURE);
+}
+
+static inline int
+get_test_opt(char **argref, const char *name, int *argi, int argc, char *argv[],
+ const char *expect_msg)
+{
+ char *arg = *argref;
+ int namelen = strlen(name);
+
+ if (strncmp(arg, name, namelen))
+ return 0;
+
+ arg += namelen;
+ if (*arg == '=') {
+ (*argref) = arg + 1;
+
+ } else if (!*arg) {
+ (*argi)++;
+ if ((*argi) >= argc)
+ die("--%s expects %s", name, expect_msg);
+ (*argref) = argv[(*argi)];
+
+ } else {
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif
diff --git a/src/viewer/text/draw.c b/src/viewer/text/draw.c
index 07df0f7f..e0676ded 100644
--- a/src/viewer/text/draw.c
+++ b/src/viewer/text/draw.c
@@ -351,13 +351,7 @@ draw_formatted(struct session *ses, int rerender)
render_document_frames(ses, rerender);
/* Rerendering kills the document refreshing so restart it. */
- if (ses->doc_view
- && ses->doc_view->document
- && ses->doc_view->document->refresh
- && get_opt_bool("document.browse.refresh", ses)) {
- start_document_refresh(ses->doc_view->document->refresh,
- ses);
- }
+ start_document_refreshes(ses);
}
if (ses->tab != get_current_tab(ses->tab->term))
diff --git a/src/viewer/text/link.c b/src/viewer/text/link.c
index ffc3819e..b5169773 100644
--- a/src/viewer/text/link.c
+++ b/src/viewer/text/link.c
@@ -1078,6 +1078,11 @@ enter(struct session *ses, struct document_view *doc_view, int do_reload)
return activate_link(ses, doc_view, link, do_reload);
}
+/** Get the link at the coordinates @a x and @a y, or NULL if none.
+ * The coordinates are relative to the document view; not to the
+ * terminal, nor to the document. So (0, 0) means whatever part of
+ * the document has been scrolled to the top left corner of the
+ * document view. */
struct link *
get_link_at_coordinates(struct document_view *doc_view, int x, int y)
{
diff --git a/src/viewer/text/vs.h b/src/viewer/text/vs.h
index 87343411..1de9e583 100644
--- a/src/viewer/text/vs.h
+++ b/src/viewer/text/vs.h
@@ -28,6 +28,8 @@ struct view_state {
* should never be negative. */
int y;
+ /** The index of the focused link in the document.links array,
+ * or -1 of none. */
int current_link;
int old_current_link;
diff --git a/test/refresh2.html b/test/refresh2.html
new file mode 100644
index 00000000..bae21659
--- /dev/null
+++ b/test/refresh2.html
@@ -0,0 +1,6 @@
+
+
+
+ Redirect to /somewhere after 3 seconds.
+
+