/* 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/location.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, char *name, int y, int width, 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(struct 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(name);
iframe_desc->uri = get_uri(url, 0);
iframe_desc->x = 1;
iframe_desc->y = y;
iframe_desc->width = width;
iframe_desc->height = height;
if (!iframe_desc->uri)
iframe_desc->uri = get_uri("about:blank", 0);
iframeset_desc->n++;
}
static void
add_iframe_to_list(struct session *ses, struct document_view *doc_view)
{
struct document_view *ses_doc_view;
assert(ses && doc_view);
if_assert_failed return;
foreach (ses_doc_view, ses->scrn_iframes) {
int sx = ses_doc_view->box.x;
int sy = ses_doc_view->box.y;
int x = doc_view->box.x;
int y = doc_view->box.y;
if (sy > y || (sy == y && sx > x)) {
add_at_pos(ses_doc_view->prev, doc_view);
return;
}
}
add_to_list_end(ses->scrn_iframes, doc_view);
}
static struct document_view *
find_ifd(struct session *ses, char *name,
int depth, int x, int y)
{
struct document_view *doc_view;
assert(ses && name);
if_assert_failed return NULL;
foreachback (doc_view, ses->scrn_iframes) {
if (doc_view->used) continue;
if (c_strcasecmp(doc_view->name, name)) continue;
doc_view->used = 1;
doc_view->depth = 0;//depth;
return doc_view;
}
doc_view = mem_calloc(1, sizeof(*doc_view));
if (!doc_view) return NULL;
doc_view->used = 1;
doc_view->name = stracpy(name);
if (!doc_view->name) {
mem_free(doc_view);
return NULL;
}
doc_view->depth = 0;//depth;
doc_view->session = ses;
doc_view->search_word = &ses->search_word;
set_box(&doc_view->box, x, y, 0, 0);
add_iframe_to_list(ses, doc_view);
return doc_view;
}
static struct document_view *
format_iframe(struct session *ses, struct iframe_desc *iframe_desc,
struct document_options *o, int j)
{
struct view_state *vs;
struct document_view *doc_view;
struct frame *iframe = NULL;
struct cache_entry *cached;
int plain;
assert(ses && iframe_desc && o);
if_assert_failed return NULL;
struct location *loc = cur_loc(ses);
if (!loc) {
return NULL;
}
foreach (iframe, loc->iframes) {
if (!c_strcasecmp(iframe->name, iframe_desc->name)) break;
}
if (!iframe) {
return NULL;
}
vs = &iframe->vs;
cached = find_in_cache(vs->uri);
if (!cached) {
return NULL;
}
plain = o->plain;
if (vs->plain != -1) o->plain = vs->plain;
if (!cached->redirect || iframe->redirect_cnt >= MAX_REDIRECTS) {
goto redir;
}
iframe->redirect_cnt++;
done_uri(vs->uri);
vs->uri = get_uri_reference(cached->redirect);
#ifdef CONFIG_ECMASCRIPT
vs->ecmascript_fragile = 1;
#endif
o->plain = plain;
redir:
doc_view = find_ifd(ses, iframe_desc->name, j, o->box.x, o->box.y);
if (doc_view) {
render_document(vs, doc_view, o);
///assert(doc_view->document);
//doc_view->document->iframe = frame_desc;
}
o->plain = plain;
return doc_view;
}
void
format_iframes(struct session *ses, struct iframeset_desc *ifsd,
struct document_options *op, int depth)
{
struct document_options o;
int j;
assert(ses && ifsd && op);
if_assert_failed return;
if (depth > HTML_MAX_FRAME_DEPTH) {
return;
}
copy_struct(&o, op);
o.margin = !!o.margin;
for (j = 0; j < ifsd->n; j++) {
struct iframe_desc *iframe_desc = &ifsd->iframe_desc[j];
o.box.x = iframe_desc->x;
o.box.y = iframe_desc->y;
o.box.width = iframe_desc->width;
o.box.height = int_min(iframe_desc->height, ses->tab->term->height - iframe_desc->y - 1);
o.framename = iframe_desc->name;
format_iframe(ses, iframe_desc, &o, j);
o.box.x += o.box.width + 1;
o.box.y += o.box.height + 1;
#ifdef CONFIG_DEBUG
/* This makes this ugly loop actually at least remotely
* debuggable by gdb, otherwise the compiler happily */
do_not_optimize_here(&j);
do_not_optimize_here(&ifsd);
do_not_optimize_here(&iframe_desc);
#endif
}
}