From de285144f084b0d9f644fea3246cc409b51fc95b Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Sat, 10 Jun 2023 17:57:28 +0200 Subject: [PATCH] [iframes] Still not functional There are bugs. For example: - frames borders are drawn in wrong place - iframes are not "relative" to the document, they are drawn in the same position of the screen even when scrolling. - some elements of screen disappear when going back - crashes --- src/document/html/iframes.c | 16 +++---- src/document/html/iframes.h | 8 +--- src/document/renderer.cpp | 2 +- src/document/view.h | 2 + src/session/session.cpp | 16 ++++--- src/viewer/text/draw.c | 64 ++++++++++++++++++------- src/viewer/text/link.cpp | 93 +++++++++++++++++++++++++++++++++++++ src/viewer/text/view.cpp | 12 +++-- src/viewer/text/vs.cpp | 8 +--- test/iframe.html | 67 ++++++++++++++++++++++++-- 10 files changed, 237 insertions(+), 51 deletions(-) diff --git a/src/document/html/iframes.c b/src/document/html/iframes.c index 556cf0100..4d7b23376 100644 --- a/src/document/html/iframes.c +++ b/src/document/html/iframes.c @@ -48,10 +48,10 @@ void add_iframeset_entry(struct iframeset_desc **parent, iframe_desc = &iframeset_desc->iframe_desc[offset]; iframe_desc->name = stracpy(name); iframe_desc->uri = get_uri(url, URI_NONE); - iframe_desc->x = 1; - iframe_desc->y = y; - iframe_desc->width = width; - iframe_desc->height = height; + iframe_desc->box.x = 1; + iframe_desc->box.y = y; + iframe_desc->box.width = width; + iframe_desc->box.height = height; iframe_desc->nlink = nlink; if (!iframe_desc->uri) iframe_desc->uri = get_uri(about_blank, URI_NONE); @@ -201,11 +201,11 @@ format_iframes(struct session *ses, struct iframeset_desc *ifsd, 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.x = iframe_desc->box.x; + o.box.y = iframe_desc->box.y; - o.box.width = iframe_desc->width; - o.box.height = int_min(iframe_desc->height, ses->tab->term->height - iframe_desc->y - 1); + o.box.width = iframe_desc->box.width; + o.box.height = int_min(iframe_desc->box.height, ses->tab->term->height - iframe_desc->box.y - 1); o.framename = iframe_desc->name; format_iframe(ses, iframe_desc, &o, j); diff --git a/src/document/html/iframes.h b/src/document/html/iframes.h index 864508e95..37a225dc3 100644 --- a/src/document/html/iframes.h +++ b/src/document/html/iframes.h @@ -1,4 +1,3 @@ - #ifndef EL__DOCUMENT_HTML_IFRAMES_H #define EL__DOCUMENT_HTML_IFRAMES_H @@ -7,21 +6,18 @@ extern "C" { #endif struct document_options; +struct el_box; struct iframeset_desc; struct iframe_desc { char *name; struct uri *uri; - - int x; - int y; - int width, height; + struct el_box box; int nlink; }; struct iframeset_desc { int n; -// struct el_box box; struct iframe_desc iframe_desc[1]; /* must be last of struct. --Zas */ }; diff --git a/src/document/renderer.cpp b/src/document/renderer.cpp index cced837c8..29fa7d013 100644 --- a/src/document/renderer.cpp +++ b/src/document/renderer.cpp @@ -468,7 +468,6 @@ render_document(struct view_state *vs, struct document_view *doc_view, doc_view->box.height = options->box.height; } - void render_document_frames(struct session *ses, int no_cache) { @@ -479,6 +478,7 @@ render_document_frames(struct session *ses, int no_cache) if (!ses->doc_view) { ses->doc_view = (struct document_view *)mem_calloc(1, sizeof(*ses->doc_view)); + if (!ses->doc_view) return; ses->doc_view->session = ses; ses->doc_view->search_word = &ses->search_word; diff --git a/src/document/view.h b/src/document/view.h index b6f621144..06d4b8889 100644 --- a/src/document/view.h +++ b/src/document/view.h @@ -22,6 +22,8 @@ struct document_view { struct document *document; struct view_state *vs; + struct document_view *parent_doc_view; + struct el_box box; /**< pos and size of window */ int last_x, last_y; /**< last pos of window */ int depth; diff --git a/src/session/session.cpp b/src/session/session.cpp index 20cf5b04b..b47964e57 100644 --- a/src/session/session.cpp +++ b/src/session/session.cpp @@ -1367,21 +1367,25 @@ destroy_session(struct session *ses) destroy_downloads(ses); abort_loading(ses, 0); free_files(ses); - if (ses->doc_view) { - detach_formatted(ses->doc_view); - mem_free(ses->doc_view); - } foreach (doc_view, ses->scrn_frames) detach_formatted(doc_view); free_list(ses->scrn_frames); - foreach (doc_view, ses->scrn_iframes) + foreach (doc_view, ses->scrn_iframes) { detach_formatted(doc_view); - + if (doc_view->session->doc_view == doc_view) { + doc_view->session->doc_view = doc_view->parent_doc_view; + } + } free_list(ses->scrn_iframes); + if (ses->doc_view) { + detach_formatted(ses->doc_view); + mem_free(ses->doc_view); + } + destroy_history(&ses->history); set_session_referrer(ses, NULL); diff --git a/src/viewer/text/draw.c b/src/viewer/text/draw.c index cde1c8854..36f5bfaeb 100644 --- a/src/viewer/text/draw.c +++ b/src/viewer/text/draw.c @@ -182,11 +182,11 @@ draw_iframe_lines(struct terminal *term, struct iframeset_desc *iframe_desc, for (j = 0; j < iframe_desc->n; j++) { struct el_box box; - int y = iframe_desc->iframe_desc[j].y - 1; - int x = iframe_desc->iframe_desc[j].x - 1; + int y = yp + iframe_desc->iframe_desc[j].box.y - 1; + int x = xp + iframe_desc->iframe_desc[j].box.x - 1; - int height = iframe_desc->iframe_desc[j].height + 1; - int width = iframe_desc->iframe_desc[j].width + 1; + int height = iframe_desc->iframe_desc[j].box.height + 1; + int width = iframe_desc->iframe_desc[j].box.width + 1; set_box(&box, x, y + 1, 1, height - 1); draw_box(term, &box, BORDER_SVLINE, SCREEN_ATTR_FRAME, colors); @@ -329,6 +329,7 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active) : get_opt_color("document.colors.background", ses); vs = doc_view->vs; + if (!vs) { int bgchar = get_opt_int("ui.background_char", ses); #ifdef CONFIG_UTF8 @@ -349,6 +350,7 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active) draw_frame_lines(term, doc_view->document->frame_desc, box->x, box->y, &color); if (vs->current_link == -1) vs->current_link = 0; + return; } @@ -389,7 +391,8 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active) if (doc_view->last_x != -1 && doc_view->last_x == vx && doc_view->last_y == vy - && !has_search_word(doc_view)) { + && !has_search_word(doc_view) + && !document_has_iframes(doc_view->document)) { clear_link(term, doc_view); draw_view_status(ses, doc_view, active); return; @@ -403,7 +406,9 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active) #else draw_box(term, box, (unsigned char)bgchar, 0, get_bfu_color(term, "desktop")); #endif - if (!doc_view->document->height) return; + if (!doc_view->document->height) { + return; + } while (vs->y >= doc_view->document->height) vs->y -= box->height; int_lower_bound(&vs->y, 0); @@ -505,27 +510,25 @@ draw_frames(struct session *ses) int n, d; assert(ses && ses->doc_view && ses->doc_view->document); - if_assert_failed return; + if_assert_failed { + return; + } - if (!document_has_frames(ses->doc_view->document) - && !document_has_iframes(ses->doc_view->document)) return; + if (!document_has_frames(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++; - } if (n) { l = &cur_loc(ses)->vs.current_link; *l = int_max(*l, 0) % int_max(n, 1); } - current_doc_view = current_frame(ses); d = 0; while (1) { @@ -537,15 +540,34 @@ 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, doc_view == current_doc_view); - } if (!more) break; d++; }; } +static void +draw_iframes(struct session *ses) +{ + struct document_view *doc_view, *current_doc_view; + + assert(ses && ses->doc_view && ses->doc_view->document); + if_assert_failed { + return; + } + + foreach (doc_view, ses->scrn_iframes) { + doc_view->last_x = doc_view->last_y = -1; + } + + current_doc_view = current_frame(ses); + + foreach (doc_view, ses->scrn_iframes) { + draw_doc(ses, doc_view, doc_view == current_doc_view); + } +} + + /** @todo @a rerender is ridiciously wound-up. */ void draw_formatted(struct session *ses, int rerender) @@ -596,9 +618,15 @@ refresh_view(struct session *ses, struct document_view *doc_view, int frames) * form field has changed, @ses might not be in the current * tab: consider SELECT pop-ups behind which -remote loads * another tab, or setTimeout in ECMAScript. */ + if (ses->tab == get_current_tab(ses->tab->term)) { - draw_doc(ses, doc_view, 1); + if (doc_view->parent_doc_view) { + draw_doc(ses, doc_view->parent_doc_view, 0); + } else { + draw_doc(ses, doc_view, 1); + } if (frames) draw_frames(ses); + draw_iframes(ses); } print_screen_status(ses); } diff --git a/src/viewer/text/link.cpp b/src/viewer/text/link.cpp index b331b972d..918c09d86 100644 --- a/src/viewer/text/link.cpp +++ b/src/viewer/text/link.cpp @@ -22,6 +22,7 @@ #include "dialogs/status.h" #include "document/document.h" #include "document/forms.h" +#include "document/html/iframes.h" #include "document/html/renderer.h" #include "document/libdom/mapa.h" #include "document/options.h" @@ -555,6 +556,62 @@ next_link_in_view_(struct document_view *doc_view, int current, int direction, document = doc_view->document; vs = doc_view->vs; + if (document_has_iframes(document)) { + struct document_view *dw; + + if (direction > 0) { + int j = 0; + + foreach (dw, doc_view->session->scrn_iframes) { + if (vs->current_link != document->iframe_desc->iframe_desc[j].nlink - 1) { + goto next; + } + if (dw->document->nlinks > 0) { + vs = dw->vs; + current_link_blur(doc_view); + + if (fn(dw, &dw->document->links[0])) { + dw->parent_doc_view = dw->session->doc_view; + dw->session->doc_view = dw; + vs->current_link = 0; + + if (cntr) cntr(dw, &dw->document->links[0]); + current_link_hover(dw); + + return 1; + } + } +next: + j++; + } + } else { + int j = document->iframe_desc->n - 1; + + foreachback (dw, doc_view->session->scrn_iframes) { + if (vs->current_link != document->iframe_desc->iframe_desc[j].nlink) { + goto nextback; + } + if (dw->document->nlinks > 0) { + int last = dw->document->nlinks - 1; + vs = dw->vs; + current_link_blur(doc_view); + + if (fn(dw, &dw->document->links[last])) { + dw->parent_doc_view = dw->session->doc_view; + dw->session->doc_view = dw; + vs->current_link = last; + if (cntr) cntr(dw, &dw->document->links[last]); + current_link_hover(dw); + + return 1; + } + } +nextback: + j--; + } + } + } + get_visible_links_range(doc_view, &start, &end); current_link_blur(doc_view); @@ -564,6 +621,7 @@ next_link_in_view_(struct document_view *doc_view, int current, int direction, while (current >= start && current <= end) { if (fn(doc_view, &document->links[current])) { vs->current_link = current; + if (cntr) cntr(doc_view, &document->links[current]); current_link_hover(doc_view); return 1; @@ -571,7 +629,38 @@ next_link_in_view_(struct document_view *doc_view, int current, int direction, current += direction; } + if (doc_view->parent_doc_view && + ((current <= 0 && direction < 0) || (current == document->nlinks && direction > 0))) { + int j = 0; + struct document_view *dw = NULL; + struct session *ses = doc_view->parent_doc_view->session; + + foreach (dw, ses->scrn_iframes) { + if (dw == doc_view) { + break; + } + j++; + } + document = doc_view->parent_doc_view->document; + vs = doc_view->parent_doc_view->vs; + if (direction < 0) { + current = document->iframe_desc->iframe_desc[j].nlink - 1; + } else { + current = document->iframe_desc->iframe_desc[j].nlink; + } + + if (fn(doc_view->parent_doc_view, &document->links[current])) { + vs->current_link = current; + doc_view = doc_view->parent_doc_view; + doc_view->session->doc_view = doc_view; + + if (cntr) cntr(doc_view, &document->links[current]); + current_link_hover(doc_view); + return 1; + } + } vs->current_link = -1; + return 0; } @@ -768,6 +857,7 @@ next_link_in_dir(struct document_view *doc_view, int dir_x, int dir_y) current_link_blur(doc_view); vs->current_link = -1; + return 0; chose_link: @@ -776,6 +866,7 @@ chose_link: vs->current_link = get_link_index(document, link); set_pos_x(doc_view, link); current_link_hover(doc_view); + return 1; } @@ -887,6 +978,7 @@ find_link(struct document_view *doc_view, int direction, int page_mode) doc_view->vs->current_link = link_pos; set_pos_x(doc_view, link); current_link_hover(doc_view); + return; nolink: @@ -1221,6 +1313,7 @@ jump_to_link_number(struct session *ses, struct document_view *doc_view, int n) if (n < 0 || n >= doc_view->document->nlinks) return; current_link_blur(doc_view); doc_view->vs->current_link = n; + if (ses->navigate_mode == NAVIGATE_CURSOR_ROUTING) { struct link *link = get_current_link(doc_view); int offset = get_link_cursor_offset(doc_view, link); diff --git a/src/viewer/text/view.cpp b/src/viewer/text/view.cpp index a682a9074..efc6567c7 100644 --- a/src/viewer/text/view.cpp +++ b/src/viewer/text/view.cpp @@ -260,12 +260,17 @@ move_link(struct session *ses, struct document_view *doc_view, int direction, * page_down() and set_textarea() under some conditions * as well. --pasky */ continue; + } else { + if (next_link_in_view_y(doc_view, current_link + direction, + direction)) { + continue; + } } - } else { if (next_link_in_view_y(doc_view, current_link + direction, - direction)) + direction)) { continue; + } } /* This is a work around for the case where the index of @@ -616,6 +621,7 @@ move_cursor(struct session *ses, struct document_view *doc_view, int x, int y) ses->navigate_mode = NAVIGATE_CURSOR_ROUTING; link = get_link_at_coordinates(doc_view, x - box->x, y - box->y); + if (link) { doc_view->vs->current_link = link - doc_view->document->links; } else { @@ -913,7 +919,7 @@ move_link_next_line(struct session *ses, struct document_view *doc_view) link = get_current_link(doc_view); if (link) { - get_link_x_bounds(link, y1, &min_x, &max_x); + get_link_x_bounds(link, y1, &min_x, &max_x); } else { min_x = max_x = x1; } diff --git a/src/viewer/text/vs.cpp b/src/viewer/text/vs.cpp index 1818481e4..dd0c7694b 100644 --- a/src/viewer/text/vs.cpp +++ b/src/viewer/text/vs.cpp @@ -175,9 +175,9 @@ next_frame(struct session *ses, int p) int n; if (!have_location(ses) - || (ses->doc_view && !document_has_frames(ses->doc_view->document))) -// && !document_has_iframes(ses->doc_view->document))) + || (ses->doc_view && !document_has_frames(ses->doc_view->document))) { return; + } ses->navigate_mode = NAVIGATE_LINKWISE; @@ -188,10 +188,6 @@ next_frame(struct session *ses, int p) if (!document_has_frames(doc_view->document)) n++; } -// foreach (doc_view, ses->scrn_iframes) { -// if (!document_has_frames(doc_view->document)) -// n++; -// } vs->current_link += p; if (!n) n = 1; diff --git a/test/iframe.html b/test/iframe.html index e0aa3679a..656b1cf54 100644 --- a/test/iframe.html +++ b/test/iframe.html @@ -1,10 +1,71 @@ -TESTY1 +TESTY1TESTYaTTEST

TTTESTTESTY1TTEST
-
TTTESTTESTY2TTEST
-
+

TTTESTTESTY3TTEST
+
TEST4TEST4
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+TEST 5
\ No newline at end of file