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. + +