diff --git a/src/document/document.c b/src/document/document.c index ba5d466bb..91f2bc417 100644 --- a/src/document/document.c +++ b/src/document/document.c @@ -54,6 +54,7 @@ #include "document/document.h" #include "document/forms.h" #include "document/html/frames.h" +#include "document/html/iframes.h" #include "document/html/parser.h" #include "document/html/parser/parse.h" #include "document/html/renderer.h" @@ -182,6 +183,25 @@ free_frameset_desc(struct frameset_desc *frameset_desc) mem_free(frameset_desc); } +static void +free_iframeset_desc(struct iframeset_desc *iframeset_desc) +{ + int i; + + for (i = 0; i < iframeset_desc->n; i++) { + struct iframe_desc *iframe_desc = &iframeset_desc->iframe_desc[i]; + +// if (iframe_desc->subframe) +// free_iframeset_desc(frame_desc->subframe); + mem_free_if(iframe_desc->name); + if (iframe_desc->uri) + done_uri(iframe_desc->uri); + } + + mem_free(iframeset_desc); +} + + void done_link_members(struct link *link) { @@ -271,7 +291,6 @@ reset_document(struct document *document) /// kill_timer(&document->timeout); /// free_document(document->dom); #endif - free_uri_list(&document->iframes); free_list(document->tags); free_list(document->nodes); @@ -299,6 +318,7 @@ done_document(struct document *document) mem_free_if(document->ip); mem_free_if(document->title); if (document->frame_desc) free_frameset_desc(document->frame_desc); + if (document->iframe_desc) free_iframeset_desc(document->iframe_desc); if (document->refresh) done_document_refresh(document->refresh); if (document->links) { @@ -337,7 +357,6 @@ done_document(struct document *document) mem_free_if(document->text); free_document(document->dom); #endif - free_uri_list(&document->iframes); free_list(document->tags); free_list(document->nodes); diff --git a/src/document/document.h b/src/document/document.h index d08be4f69..3e3a164fc 100644 --- a/src/document/document.h +++ b/src/document/document.h @@ -223,7 +223,7 @@ struct document { * Used for checking rerendering for available CSS imports. */ unsigned long css_magic; #endif - struct uri_list iframes; + struct iframeset_desc *iframe_desc; struct uri *uri; @@ -285,6 +285,7 @@ struct document { }; #define document_has_frames(document_) ((document_) && (document_)->frame_desc) +#define document_has_iframes(document_) ((document_) && (document_)->iframe_desc) /** Initializes a document and its canvas. * @returns NULL on allocation failure. diff --git a/src/document/html/Makefile b/src/document/html/Makefile index 91e7e08cd..7d4f85276 100644 --- a/src/document/html/Makefile +++ b/src/document/html/Makefile @@ -2,6 +2,6 @@ top_builddir=../../.. include $(top_builddir)/Makefile.config SUBDIRS = parser test -OBJS = frames.o parse-meta-refresh.o parser.o renderer.o tables.o +OBJS = frames.o iframes.o parse-meta-refresh.o parser.o renderer.o tables.o include $(top_srcdir)/Makefile.lib diff --git a/src/document/html/iframes.c b/src/document/html/iframes.c new file mode 100644 index 000000000..c61540c83 --- /dev/null +++ b/src/document/html/iframes.c @@ -0,0 +1,55 @@ +/* HTML frames parser */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "elinks.h" + +#include "cache/cache.h" +#include "document/document.h" +#include "document/html/iframes.h" +#include "document/options.h" +#include "document/renderer.h" +#include "document/view.h" +#include "protocol/uri.h" +#include "session/session.h" +#include "terminal/draw.h" +#include "util/color.h" +#include "util/string.h" +#include "util/time.h" + +void add_iframeset_entry(struct iframeset_desc **parent, + char *url, int y, int height) +{ + struct iframeset_desc *iframeset_desc; + struct iframe_desc *iframe_desc; + int offset; + + assert(parent); + if_assert_failed return; + + if (!*parent) { + *parent = mem_calloc(1, sizeof(iframeset_desc)); + } else { + *parent = mem_realloc(*parent, sizeof(struct iframeset_desc) + ((*parent)->n + 1) * sizeof(struct iframe_desc)); + } + if (!*parent) return; + + iframeset_desc = *parent; + + offset = iframeset_desc->n; + iframe_desc = &iframeset_desc->iframe_desc[offset]; + iframe_desc->name = stracpy(""); + iframe_desc->uri = get_uri(url, 0); + iframe_desc->height = height; + if (!iframe_desc->uri) + iframe_desc->uri = get_uri("about:blank", 0); + + iframeset_desc->n++; +} diff --git a/src/document/html/iframes.h b/src/document/html/iframes.h index 519e292c7..34e3a8bba 100644 --- a/src/document/html/iframes.h +++ b/src/document/html/iframes.h @@ -7,9 +7,22 @@ extern "C" { #endif struct iframeset_desc; -struct iframe_desc; -void add_iframeset_entry(struct iframeset_desc *parent, struct iframe_desc *subframe); +struct iframe_desc { + char *name; + struct uri *uri; + + int width, height; +}; + +struct iframeset_desc { + int n; +// struct el_box box; + + struct iframe_desc iframe_desc[1]; /* must be last of struct. --Zas */ +}; + +void add_iframeset_entry(struct iframeset_desc **parent, char *url, int y, int height); #ifdef __cplusplus } diff --git a/src/document/html/meson.build b/src/document/html/meson.build index 530930129..064d72ddd 100644 --- a/src/document/html/meson.build +++ b/src/document/html/meson.build @@ -1,3 +1,3 @@ subdir('parser') #test -srcs += files('frames.c', 'parse-meta-refresh.c', 'parser.c', 'renderer.c', 'tables.c') +srcs += files('frames.c', 'iframes.c', 'parse-meta-refresh.c', 'parser.c', 'renderer.c', 'tables.c') diff --git a/src/document/html/parser/link.c b/src/document/html/parser/link.c index 4f6c16d13..b46ec3966 100644 --- a/src/document/html/parser/link.c +++ b/src/document/html/parser/link.c @@ -509,12 +509,7 @@ html_iframe_do(char *a, char *object_src, url2 = join_urls(html_context->base_href, url); if (url2) { - struct uri *uri = get_uri(url2, URI_BASE); - - if (uri) { - html_context->special_f(html_context, SP_IFRAME, uri, y, height); - done_uri(uri); - } + html_context->special_f(html_context, SP_IFRAME, url2, y, height); mem_free(url2); } } diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c index 9c1c83f06..5df8f0188 100644 --- a/src/document/html/renderer.c +++ b/src/document/html/renderer.c @@ -26,6 +26,7 @@ #include "document/docdata.h" #include "document/document.h" #include "document/html/frames.h" +#include "document/html/iframes.h" #include "document/html/parser.h" #include "document/html/parser/parse.h" #include "document/html/renderer.h" @@ -2359,11 +2360,11 @@ html_special(struct html_context *html_context, enum html_special_type c, ...) case SP_IFRAME: { if (document) { - struct uri *uri = va_arg(l, struct uri *); + char *url = va_arg(l, char *); int y = va_arg(l, int); int height = va_arg(l, int); - add_to_uri_list(&document->iframes, uri); + add_iframeset_entry(&document->iframe_desc, url, y, height); } break; } diff --git a/src/session/location.c b/src/session/location.c index 302b4dc5b..e48dca40d 100644 --- a/src/session/location.c +++ b/src/session/location.c @@ -20,6 +20,7 @@ void copy_location(struct location *dst, struct location *src) { struct frame *frame, *new_frame; + struct frame *iframe, *new_iframe; init_list(dst->frames); foreachback (frame, src->frames) { @@ -35,6 +36,22 @@ copy_location(struct location *dst, struct location *src) add_to_list(dst->frames, new_frame); } } + + init_list(dst->iframes); + foreachback (iframe, src->iframes) { + new_iframe = mem_calloc(1, sizeof(*new_iframe)); + if (new_iframe) { + new_iframe->name = stracpy(iframe->name); + if (!new_iframe->name) { + mem_free(new_iframe); + return; + } + new_iframe->redirect_cnt = 0; + copy_vs(&new_iframe->vs, &iframe->vs); + add_to_list(dst->iframes, new_iframe); + } + } + copy_vs(&dst->vs, &src->vs); } @@ -42,12 +59,20 @@ void destroy_location(struct location *loc) { struct frame *frame; + struct frame *iframe; foreach (frame, loc->frames) { destroy_vs(&frame->vs, 1); mem_free(frame->name); } + + foreach (iframe, loc->iframes) { + destroy_vs(&iframe->vs, 1); + mem_free(iframe->name); + } + free_list(loc->frames); + free_list(loc->iframes); destroy_vs(&loc->vs, 1); mem_free(loc); } diff --git a/src/session/location.h b/src/session/location.h index 52b365265..5e90c5e07 100644 --- a/src/session/location.h +++ b/src/session/location.h @@ -2,6 +2,7 @@ #define EL__SESSION_LOCATION_H #include "session/download.h" +#include "session/session.h" #include "util/lists.h" #include "viewer/text/vs.h" @@ -13,6 +14,7 @@ struct location { LIST_HEAD(struct location); LIST_OF(struct frame) frames; + LIST_OF(struct frame) iframes; struct download download; struct view_state vs; }; diff --git a/src/session/session.c b/src/session/session.c index 4bc5b445a..ac63db047 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -20,6 +20,7 @@ #include "dialogs/status.h" #include "document/document.h" #include "document/html/frames.h" +#include "document/html/iframes.h" #include "document/refresh.h" #include "document/renderer.h" #include "document/view.h" @@ -420,6 +421,42 @@ request_frame(struct session *ses, char *name, request_additional_file(ses, name, frame->vs.uri, PRI_FRAME); } +static void +request_iframe(struct session *ses, char *name, + struct uri *uri, int depth) +{ + struct location *loc = cur_loc(ses); + struct frame *iframe; + + assertm(have_location(ses), "request_frame: no location"); + if_assert_failed return; + + foreach (iframe, loc->iframes) { + struct document_view *doc_view; + + if (c_strcasecmp(iframe->name, name)) + continue; + + request_additional_file(ses, name, iframe->vs.uri, PRI_FRAME); + return; + } + + iframe = mem_calloc(1, sizeof(*iframe)); + if (!iframe) return; + + iframe->name = stracpy(name); + if (!iframe->name) { + mem_free(iframe); + return; + } + + init_vs(&iframe->vs, uri, -1); + + add_to_list(loc->iframes, iframe); + + request_additional_file(ses, name, iframe->vs.uri, PRI_FRAME); +} + static void request_frameset(struct session *ses, struct frameset_desc *frameset_desc, int depth) { @@ -441,6 +478,25 @@ request_frameset(struct session *ses, struct frameset_desc *frameset_desc, int d } } +static void +request_iframes(struct session *ses, struct iframeset_desc *iframeset_desc, int depth) +{ + int i; + + if (depth > HTML_MAX_FRAME_DEPTH) return; + + depth++; /* Inheritation counter (recursion brake ;) */ + + for (i = 0; i < iframeset_desc->n; i++) { + struct iframe_desc *iframe_desc = &iframeset_desc->iframe_desc[i]; + + if (iframe_desc->uri) { + request_iframe(ses, iframe_desc->name, + iframe_desc->uri, depth); + } + } +} + #ifdef CONFIG_CSS static inline void load_css_imports(struct session *ses, struct document_view *doc_view) @@ -484,11 +540,9 @@ load_iframes(struct session *ses, struct document_view *doc_view) struct uri *uri; int index; - if (!document) return; + if (!document || !document->iframe_desc) return; - foreach_uri (uri, index, &document->iframes) { - request_additional_file(ses, "", uri, PRI_CSS); - } + request_iframes(ses, document->iframe_desc, 0); } NONSTATIC_INLINE void diff --git a/src/session/session.h b/src/session/session.h index bf74b9417..639b8b5b8 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -61,6 +61,16 @@ struct frame { struct view_state vs; }; +struct iframe { + LIST_HEAD(struct frame); + + char *name; + int redirect_cnt; + + struct view_state vs; +}; + + enum kp_mark { KP_MARK_NOTHING, KP_MARK_SET, KP_MARK_GOTO }; /** Use for keyboard prefixes. */