1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-21 00:25:37 +00:00

[iframe] Small progress.

This commit is contained in:
Witold Filipczyk 2021-07-26 21:28:19 +02:00
parent 06d50a9ccc
commit 734028277c
12 changed files with 253 additions and 14 deletions

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -13,6 +13,7 @@ enum connection_priority {
PRI_MAIN = 0,
PRI_DOWNLOAD = 0,
PRI_FRAME,
PRI_IFRAME,
PRI_CSS,
PRI_NEED_IMG,
PRI_IMG,

View File

@ -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) {

View File

@ -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);

View File

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

View File

@ -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);

View File

@ -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
View 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>