mirror of
https://github.com/rkd77/elinks.git
synced 2024-09-28 03:06:20 -04:00
[iframe] Small progress.
This commit is contained in:
parent
06d50a9ccc
commit
734028277c
@ -18,6 +18,7 @@
|
||||
#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"
|
||||
@ -25,7 +26,7 @@
|
||||
#include "util/time.h"
|
||||
|
||||
void add_iframeset_entry(struct iframeset_desc **parent,
|
||||
char *url, int y, int height)
|
||||
char *url, char *name, int y, int width, int height)
|
||||
{
|
||||
struct iframeset_desc *iframeset_desc;
|
||||
struct iframe_desc *iframe_desc;
|
||||
@ -35,7 +36,7 @@ void add_iframeset_entry(struct iframeset_desc **parent,
|
||||
if_assert_failed return;
|
||||
|
||||
if (!*parent) {
|
||||
*parent = mem_calloc(1, sizeof(iframeset_desc));
|
||||
*parent = mem_calloc(1, sizeof(struct iframeset_desc));
|
||||
} else {
|
||||
*parent = mem_realloc(*parent, sizeof(struct iframeset_desc) + ((*parent)->n + 1) * sizeof(struct iframe_desc));
|
||||
}
|
||||
@ -45,11 +46,178 @@ void add_iframeset_entry(struct iframeset_desc **parent,
|
||||
|
||||
offset = iframeset_desc->n;
|
||||
iframe_desc = &iframeset_desc->iframe_desc[offset];
|
||||
iframe_desc->name = stracpy("");
|
||||
iframe_desc->name = stracpy(name);
|
||||
iframe_desc->uri = get_uri(url, 0);
|
||||
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;
|
||||
int i;
|
||||
|
||||
assert(ses && iframe_desc && o);
|
||||
if_assert_failed return NULL;
|
||||
|
||||
struct location *loc = cur_loc(ses);
|
||||
|
||||
if (!loc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (iframe, loc->iframes) {
|
||||
if (i == j) break;
|
||||
i++;
|
||||
}
|
||||
|
||||
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];
|
||||
struct document_view *doc_view;
|
||||
|
||||
o.box.x = op->box.x;
|
||||
|
||||
o.box.width = iframe_desc->width;
|
||||
o.box.height = iframe_desc->height;
|
||||
o.framename = iframe_desc->name;
|
||||
|
||||
doc_view = 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);
|
||||
do_not_optimize_here(doc_view);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct document_options;
|
||||
struct iframeset_desc;
|
||||
|
||||
struct iframe_desc {
|
||||
@ -22,7 +23,8 @@ struct iframeset_desc {
|
||||
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);
|
||||
void add_iframeset_entry(struct iframeset_desc **parent, char *url, char *name, int y, int width, int height);
|
||||
void format_iframes(struct session *ses, struct iframeset_desc *ifsd, struct document_options *op, int depth);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -468,8 +468,9 @@ html_iframe_do(char *a, char *object_src,
|
||||
struct html_context *html_context)
|
||||
{
|
||||
char *name, *url = NULL;
|
||||
char *hstr;
|
||||
char *hstr, *wstr;
|
||||
int height;
|
||||
int width;
|
||||
|
||||
url = null_or_stracpy(object_src);
|
||||
if (!url) url = get_url_val(a, "src", html_context->doc_cp);
|
||||
@ -483,6 +484,7 @@ html_iframe_do(char *a, char *object_src,
|
||||
return;
|
||||
}
|
||||
hstr = get_attr_val(a, "height", html_context->doc_cp);
|
||||
wstr = get_attr_val(a, "width", html_context->doc_cp);
|
||||
|
||||
html_focusable(html_context, a);
|
||||
|
||||
@ -501,6 +503,13 @@ html_iframe_do(char *a, char *object_src,
|
||||
mem_free(hstr);
|
||||
}
|
||||
|
||||
if (!wstr) {
|
||||
width = (300 + HTML_CHAR_WIDTH - 1) / HTML_CHAR_WIDTH;
|
||||
} else {
|
||||
width = (atoi(wstr) + HTML_CHAR_WIDTH - 1) / HTML_CHAR_WIDTH;
|
||||
mem_free(wstr);
|
||||
}
|
||||
|
||||
if (height > 0) {
|
||||
int y = html_context->part->cy;
|
||||
char *url2;
|
||||
@ -509,7 +518,7 @@ html_iframe_do(char *a, char *object_src,
|
||||
url2 = join_urls(html_context->base_href, url);
|
||||
|
||||
if (url2) {
|
||||
html_context->special_f(html_context, SP_IFRAME, url2, y, height);
|
||||
html_context->special_f(html_context, SP_IFRAME, url2, name, y, width, height);
|
||||
mem_free(url2);
|
||||
}
|
||||
}
|
||||
|
@ -2361,10 +2361,12 @@ html_special(struct html_context *html_context, enum html_special_type c, ...)
|
||||
{
|
||||
if (document) {
|
||||
char *url = va_arg(l, char *);
|
||||
char *name = va_arg(l, char *);
|
||||
int y = va_arg(l, int);
|
||||
int width = va_arg(l, int);
|
||||
int height = va_arg(l, int);
|
||||
|
||||
add_iframeset_entry(&document->iframe_desc, url, y, height);
|
||||
add_iframeset_entry(&document->iframe_desc, url, name, y, width, height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -515,6 +515,10 @@ render_document_frames(struct session *ses, int no_cache)
|
||||
format_frames(ses, ses->doc_view->document->frame_desc, &doc_opts, 0);
|
||||
}
|
||||
|
||||
if (document_has_iframes(ses->doc_view->document)) {
|
||||
format_iframes(ses, ses->doc_view->document->iframe_desc, &doc_opts, 0);
|
||||
}
|
||||
|
||||
foreach (doc_view, ses->scrn_frames) {
|
||||
struct document_view *prev_doc_view = doc_view->prev;
|
||||
|
||||
|
@ -13,6 +13,7 @@ enum connection_priority {
|
||||
PRI_MAIN = 0,
|
||||
PRI_DOWNLOAD = 0,
|
||||
PRI_FRAME,
|
||||
PRI_IFRAME,
|
||||
PRI_CSS,
|
||||
PRI_NEED_IMG,
|
||||
PRI_IMG,
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "util/memory.h"
|
||||
#include "util/string.h"
|
||||
|
||||
|
||||
/** @relates location */
|
||||
void
|
||||
copy_location(struct location *dst, struct location *src)
|
||||
@ -23,6 +22,7 @@ copy_location(struct location *dst, struct location *src)
|
||||
struct frame *iframe, *new_iframe;
|
||||
|
||||
init_list(dst->frames);
|
||||
init_list(dst->iframes);
|
||||
foreachback (frame, src->frames) {
|
||||
new_frame = mem_calloc(1, sizeof(*new_frame));
|
||||
if (new_frame) {
|
||||
@ -37,7 +37,6 @@ copy_location(struct location *dst, struct location *src)
|
||||
}
|
||||
}
|
||||
|
||||
init_list(dst->iframes);
|
||||
foreachback (iframe, src->iframes) {
|
||||
new_iframe = mem_calloc(1, sizeof(*new_iframe));
|
||||
if (new_iframe) {
|
||||
|
@ -437,7 +437,7 @@ request_iframe(struct session *ses, char *name,
|
||||
if (c_strcasecmp(iframe->name, name))
|
||||
continue;
|
||||
|
||||
request_additional_file(ses, name, iframe->vs.uri, PRI_FRAME);
|
||||
request_additional_file(ses, name, iframe->vs.uri, PRI_IFRAME);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ request_iframe(struct session *ses, char *name,
|
||||
|
||||
add_to_list(loc->iframes, iframe);
|
||||
|
||||
request_additional_file(ses, name, iframe->vs.uri, PRI_FRAME);
|
||||
request_additional_file(ses, name, iframe->vs.uri, PRI_IFRAME);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -818,7 +818,7 @@ file_loading_callback(struct download *download, struct file_to_load *ftl)
|
||||
|
||||
ses->loading_uri = ftl->uri;
|
||||
mem_free_set(&ses->task.target.frame, null_or_stracpy(ftl->target_frame));
|
||||
setup_download_handler(ses, &ftl->download, ftl->cached, 1);
|
||||
setup_download_handler(ses, &ftl->download, ftl->cached, 1 + (download->pri == PRI_IFRAME));
|
||||
ses->loading_uri = loading_uri;
|
||||
mem_free_set(&ses->task.target.frame, target_frame);
|
||||
}
|
||||
@ -1048,6 +1048,7 @@ init_session(struct session *base_session, struct terminal *term,
|
||||
CO_SHALLOW | CO_NO_LISTBOX_ITEM);
|
||||
create_history(&ses->history);
|
||||
init_list(ses->scrn_frames);
|
||||
init_list(ses->scrn_iframes);
|
||||
init_list(ses->more_files);
|
||||
init_list(ses->type_queries);
|
||||
ses->task.type = TASK_NONE;
|
||||
@ -1369,6 +1370,11 @@ destroy_session(struct session *ses)
|
||||
|
||||
free_list(ses->scrn_frames);
|
||||
|
||||
foreach (doc_view, ses->scrn_iframes)
|
||||
detach_formatted(doc_view);
|
||||
|
||||
free_list(ses->scrn_iframes);
|
||||
|
||||
destroy_history(&ses->history);
|
||||
set_session_referrer(ses, NULL);
|
||||
|
||||
|
@ -196,6 +196,7 @@ struct session {
|
||||
|
||||
struct document_view *doc_view;
|
||||
LIST_OF(struct document_view) scrn_frames;
|
||||
LIST_OF(struct document_view) scrn_iframes;
|
||||
|
||||
/** The URI from which the next start_download() or resume_download()
|
||||
* call should download, or NULL if no such call is pending.
|
||||
|
@ -324,7 +324,35 @@ x:
|
||||
copy_struct(&loc->download, &ses->loading);
|
||||
}
|
||||
|
||||
if (ses->task.target.frame && *ses->task.target.frame) {
|
||||
if (loaded_in_frame == 2) {
|
||||
struct frame *iframe;
|
||||
|
||||
assertm(have_location(ses), "no location yet");
|
||||
if_assert_failed return NULL;
|
||||
|
||||
struct location *loc = cur_loc(ses);
|
||||
|
||||
iframe = loc->iframes.next;
|
||||
|
||||
if (!iframe) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vs = &iframe->vs;
|
||||
|
||||
done_uri(vs->uri);
|
||||
vs->uri = get_uri_reference(ses->loading_uri);
|
||||
if (vs->doc_view) {
|
||||
/* vs->doc_view itself will get detached in
|
||||
* render_document_frames(), but that's too
|
||||
* late for us. */
|
||||
vs->doc_view->vs = NULL;
|
||||
vs->doc_view = NULL;
|
||||
}
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
vs->ecmascript_fragile = 1;
|
||||
#endif
|
||||
} else if (ses->task.target.frame && *ses->task.target.frame) {
|
||||
struct frame *frame;
|
||||
|
||||
assertm(have_location(ses), "no location yet");
|
||||
@ -369,6 +397,7 @@ x:
|
||||
if_assert_failed return NULL;
|
||||
|
||||
init_list(loc->frames);
|
||||
init_list(loc->iframes);
|
||||
vs = &loc->vs;
|
||||
init_vs(vs, ses->loading_uri, vs->plain);
|
||||
add_to_history(&ses->history, loc);
|
||||
|
@ -374,13 +374,19 @@ draw_frames(struct session *ses)
|
||||
assert(ses && ses->doc_view && ses->doc_view->document);
|
||||
if_assert_failed return;
|
||||
|
||||
if (!document_has_frames(ses->doc_view->document)) return;
|
||||
if (!document_has_frames(ses->doc_view->document)
|
||||
&& !document_has_iframes(ses->doc_view->document)) return;
|
||||
|
||||
n = 0;
|
||||
foreach (doc_view, ses->scrn_frames) {
|
||||
doc_view->last_x = doc_view->last_y = -1;
|
||||
n++;
|
||||
}
|
||||
foreach (doc_view, ses->scrn_iframes) {
|
||||
doc_view->last_x = doc_view->last_y = -1;
|
||||
n++;
|
||||
}
|
||||
|
||||
l = &cur_loc(ses)->vs.current_link;
|
||||
*l = int_max(*l, 0) % int_max(n, 1);
|
||||
|
||||
@ -395,6 +401,9 @@ draw_frames(struct session *ses)
|
||||
else if (doc_view->depth > d)
|
||||
more = 1;
|
||||
}
|
||||
if (d == 0) foreach (doc_view, ses->scrn_iframes) {
|
||||
draw_doc(ses, doc_view, 0);
|
||||
}
|
||||
|
||||
if (!more) break;
|
||||
d++;
|
||||
|
9
test/iframe.html
Normal file
9
test/iframe.html
Normal file
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<body>
|
||||
TESTY1
|
||||
<iframe src="file:///" height="200" width="800" name="t1"></iframe><hr>
|
||||
TESTY2
|
||||
<iframe src="file:///usr/share/doc" height="400" width="800" name="t2"></iframe><hr>
|
||||
TESTY3
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user