From b182cc7617a739f4b42293ef8e43485ef48d7cab Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 25 May 2020 17:12:43 +0100 Subject: [PATCH] remove box handling from browser window --- content/handlers/html/box.h | 8 - content/handlers/html/box_construct.c | 6 - content/handlers/html/box_special.c | 8 +- desktop/browser_private.h | 7 + desktop/browser_window.c | 85 +++---- desktop/frames.c | 331 ++++++++++++++++---------- desktop/frames.h | 38 ++- 7 files changed, 271 insertions(+), 212 deletions(-) diff --git a/content/handlers/html/box.h b/content/handlers/html/box.h index b4da031f1..d0df73568 100644 --- a/content/handlers/html/box.h +++ b/content/handlers/html/box.h @@ -448,12 +448,4 @@ struct box { }; -/* Frame target names (constant pointers to save duplicating the strings many - * times). We convert _blank to _top for user-friendliness. */ -extern const char *TARGET_SELF; -extern const char *TARGET_PARENT; -extern const char *TARGET_TOP; -extern const char *TARGET_BLANK; - - #endif diff --git a/content/handlers/html/box_construct.c b/content/handlers/html/box_construct.c index 5ae755211..5edd88ed2 100644 --- a/content/handlers/html/box_construct.c +++ b/content/handlers/html/box_construct.c @@ -85,12 +85,6 @@ struct box_construct_props { static const content_type image_types = CONTENT_IMAGE; -/* the strings are not important, since we just compare the pointers */ -const char *TARGET_SELF = "_self"; -const char *TARGET_PARENT = "_parent"; -const char *TARGET_TOP = "_top"; -const char *TARGET_BLANK = "_blank"; - /** * mapping from CSS display to box type this table must be in sync * with libcss' css_display enum diff --git a/content/handlers/html/box_special.c b/content/handlers/html/box_special.c index 2332316ce..c6be9e626 100644 --- a/content/handlers/html/box_special.c +++ b/content/handlers/html/box_special.c @@ -716,18 +716,18 @@ box_a(dom_node *n, if (err == DOM_NO_ERR && s != NULL) { if (dom_string_caseless_lwc_isequal(s, corestring_lwc__blank)) - box->target = TARGET_BLANK; + box->target = "_blank"; else if (dom_string_caseless_lwc_isequal(s, corestring_lwc__top)) - box->target = TARGET_TOP; + box->target = "_top"; else if (dom_string_caseless_lwc_isequal(s, corestring_lwc__parent)) - box->target = TARGET_PARENT; + box->target = "_parent"; else if (dom_string_caseless_lwc_isequal(s, corestring_lwc__self)) /* the default may have been overridden by a * , so this is different to 0 */ - box->target = TARGET_SELF; + box->target = "_self"; else { /* 6.16 says that frame names must begin with [a-zA-Z] * This doesn't match reality, so just take anything */ diff --git a/desktop/browser_private.h b/desktop/browser_private.h index 8ed2ddef6..40c3b43ce 100644 --- a/desktop/browser_private.h +++ b/desktop/browser_private.h @@ -287,6 +287,13 @@ nserror browser_window_initialise_common(enum browser_window_create_flags flags, const struct browser_window *existing); +/** + * Release all memory associated with a browser window. + * + * \param bw browser window + */ +nserror browser_window_destroy_internal(struct browser_window *bw); + /** * Get the dimensions of the area a browser window occupies * diff --git a/desktop/browser_window.c b/desktop/browser_window.c index 7bc5cc572..423ff998b 100644 --- a/desktop/browser_window.c +++ b/desktop/browser_window.c @@ -56,7 +56,6 @@ #include "css/utils.h" #include "html/form_internal.h" #include "html/html.h" -#include "html/box.h" #include "javascript/js.h" #include "desktop/cookie_manager.h" @@ -88,9 +87,6 @@ */ #define FRAME_DEPTH 8 -/* Have to forward declare browser_window_destroy_internal */ -static void browser_window_destroy_internal(struct browser_window *bw); - /* Forward declare internal navigation function */ static nserror browser_window__navigate_internal( struct browser_window *bw, struct browser_fetch_parameters *params); @@ -114,14 +110,6 @@ static void browser_window_destroy_children(struct browser_window *bw) bw->rows = 0; bw->cols = 0; } - if (bw->iframes) { - for (i = 0; i < bw->iframe_count; i++) { - browser_window_destroy_internal(&bw->iframes[i]); - } - free(bw->iframes); - bw->iframes = NULL; - bw->iframe_count = 0; - } } @@ -798,7 +786,8 @@ static void browser_window_update(struct browser_window *bw, bool scroll_to_top) /** @todo don't do this if the user has scrolled */ frag_scroll(bw); - html_redraw_a_box(bw->parent->current_content, bw->box); + browser_window_invalidate_iframe(bw); + break; case BROWSER_WINDOW_FRAME: @@ -919,15 +908,10 @@ static nserror browser_window_content_ready(struct browser_window *bw) browser_window_set_status(bw, content_get_status_message(bw->current_content)); /* frames */ - if ((content_get_type(bw->current_content) == CONTENT_HTML) && - (html_get_frameset(bw->current_content) != NULL)) { - res = browser_window_create_frameset(bw, html_get_frameset(bw->current_content)); - } + res = browser_window_create_frameset(bw); - if (content_get_type(bw->current_content) == CONTENT_HTML && - html_get_iframe(bw->current_content) != NULL) { - browser_window_create_iframes(bw, html_get_iframe(bw->current_content)); - } + /* iframes */ + res = browser_window_create_iframes(bw); /* Indicate page status may have changed */ if (res == NSERROR_OK) { @@ -1004,6 +988,7 @@ browser_window__handle_ssl_query_response(bool proceed, void *pw) browser_window_stop(bw); browser_window_remove_caret(bw, false); browser_window_destroy_children(bw); + browser_window_destroy_iframes(bw); } if (!proceed) { @@ -1149,6 +1134,7 @@ browser_window__handle_userpass_response(nsurl *url, browser_window_stop(bw); browser_window_remove_caret(bw, false); browser_window_destroy_children(bw); + browser_window_destroy_iframes(bw); } bw->internal_nav = false; return browser_window__navigate_internal(bw, &bw->loading_parameters); @@ -1560,14 +1546,12 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw) break; case CONTENT_MSG_REFORMAT: - if (c == bw->current_content && - content_get_type(c) == CONTENT_HTML) { - /* reposition frames */ - if (html_get_frameset(c) != NULL) - browser_window_recalculate_frameset(bw); - /* reflow iframe positions */ - if (html_get_iframe(c) != NULL) - browser_window_recalculate_iframes(bw); + if (c == bw->current_content) { + /* recompute frameset */ + browser_window_recalculate_frameset(bw); + + /* recompute iframe positions, sizes and scrollbars */ + browser_window_recalculate_iframes(bw); } /* Hide any caret, but don't remove it */ @@ -1848,21 +1832,13 @@ static void scheduled_reformat(void *vbw) } } - -/** - * Release all memory associated with a browser window. - * - * \param bw browser window - */ -static void browser_window_destroy_internal(struct browser_window *bw) +/* exported interface documented in desktop/browser_private.h */ +nserror browser_window_destroy_internal(struct browser_window *bw) { assert(bw); - NSLOG(netsurf, INFO, "Destroying window"); - - if (bw->children != NULL || bw->iframes != NULL) { - browser_window_destroy_children(bw); - } + browser_window_destroy_children(bw); + browser_window_destroy_iframes(bw); /* Destroy scrollbars */ if (bw->scroll_x != NULL) { @@ -1926,11 +1902,6 @@ static void browser_window_destroy_internal(struct browser_window *bw) bw->favicon.current = NULL; } - if (bw->box != NULL) { - bw->box->iframe = NULL; - bw->box = NULL; - } - if (bw->jsheap != NULL) { js_destroyheap(bw->jsheap); bw->jsheap = NULL; @@ -1956,6 +1927,8 @@ static void browser_window_destroy_internal(struct browser_window *bw) browser_window__free_fetch_parameters(&bw->loading_parameters); NSLOG(netsurf, INFO, "Status text cache match:miss %d:%d", bw->status.match, bw->status.miss); + + return NSERROR_OK; } @@ -1991,7 +1964,7 @@ browser_window_set_scale_internal(struct browser_window *bw, float scale) res = browser_window_set_scale_internal(&bw->children[i], scale); } - /* sale iframes */ + /* scale iframes */ for (i = 0; i < bw->iframe_count; i++) { res = browser_window_set_scale_internal(&bw->iframes[i], scale); } @@ -3487,6 +3460,7 @@ browser_window_navigate(struct browser_window *bw, browser_window_stop(bw); browser_window_remove_caret(bw, false); browser_window_destroy_children(bw); + browser_window_destroy_iframes(bw); /* Set up the fetch parameters */ memset(¶ms, 0, sizeof(params)); @@ -4389,7 +4363,7 @@ browser_window_find_target(struct browser_window *bw, target = html_get_base_target(c); } if (target == NULL) { - target = TARGET_SELF; + target = "_self"; } /* allow the simple case of target="_blank" to be ignored if requested @@ -4401,7 +4375,7 @@ browser_window_find_target(struct browser_window *bw, /* not a mouse button 2 click * not a mouse button 1 click with ctrl pressed * configured to ignore target="_blank" */ - if ((target == TARGET_BLANK) || (!strcasecmp(target, "_blank"))) + if (!strcasecmp(target, "_blank")) return bw; } @@ -4412,8 +4386,7 @@ browser_window_find_target(struct browser_window *bw, ((mouse & BROWSER_MOUSE_CLICK_1) && (mouse & BROWSER_MOUSE_MOD_2))) || ((nsoption_bool(button_2_tab)) && - ((target == TARGET_BLANK) || - (!strcasecmp(target, "_blank"))))) { + (!strcasecmp(target, "_blank")))) { /* open in new tab if: * - button_2 opens in new tab and button_2 was pressed * OR @@ -4439,8 +4412,7 @@ browser_window_find_target(struct browser_window *bw, ((mouse & BROWSER_MOUSE_CLICK_1) && (mouse & BROWSER_MOUSE_MOD_2))) || ((!nsoption_bool(button_2_tab)) && - ((target == TARGET_BLANK) || - (!strcasecmp(target, "_blank"))))) { + (!strcasecmp(target, "_blank")))) { /* open in new window if: * - button_2 doesn't open in new tabs and button_2 was pressed * OR @@ -4460,14 +4432,13 @@ browser_window_find_target(struct browser_window *bw, return bw; } return bw_target; - } else if ((target == TARGET_SELF) || (!strcasecmp(target, "_self"))) { + } else if (!strcasecmp(target, "_self")) { return bw; - } else if ((target == TARGET_PARENT) || - (!strcasecmp(target, "_parent"))) { + } else if (!strcasecmp(target, "_parent")) { if (bw->parent) return bw->parent; return bw; - } else if ((target == TARGET_TOP) || (!strcasecmp(target, "_top"))) { + } else if (!strcasecmp(target, "_top")) { while (bw->parent) bw = bw->parent; return bw; diff --git a/desktop/frames.c b/desktop/frames.c index 0d70029e9..85f18793e 100644 --- a/desktop/frames.c +++ b/desktop/frames.c @@ -181,20 +181,35 @@ void browser_window_handle_scrollbars(struct browser_window *bw) scrollbar_make_pair(bw->scroll_x, bw->scroll_y); } +/* exported function documented in desktop/frames.h */ +nserror browser_window_invalidate_iframe(struct browser_window *bw) +{ + html_redraw_a_box(bw->parent->current_content, bw->box); + return NSERROR_OK; +} /* exported function documented in desktop/frames.h */ -nserror browser_window_create_iframes(struct browser_window *bw, - struct content_html_iframe *iframe) +nserror browser_window_create_iframes(struct browser_window *bw) { + nserror ret = NSERROR_OK; struct browser_window *window; struct content_html_iframe *cur; struct rect rect; int iframes = 0; int index; - nserror ret = NSERROR_OK; + struct content_html_iframe *iframe; + bw->iframe_count = 0; + + /* only html contents can have iframes */ + if (content_get_type(bw->current_content) != CONTENT_HTML) { + return NSERROR_OK; + } + + /* obtain the iframes for this content */ + iframe = html_get_iframe(bw->current_content); if (iframe == NULL) { - return NSERROR_BAD_PARAMETER; + return NSERROR_OK; } /* Count iframe list and allocate enough space within the @@ -272,12 +287,7 @@ nserror browser_window_create_iframes(struct browser_window *bw, } -/** - * Recalculate iframe positions following a resize. - * - * \param bw The browser window to reposition iframes for - */ - +/* exported function documented in desktop/frames.h */ void browser_window_recalculate_iframes(struct browser_window *bw) { struct browser_window *window; @@ -293,123 +303,23 @@ void browser_window_recalculate_iframes(struct browser_window *bw) } -/* exported interface documented in desktop/frames.h */ -nserror browser_window_create_frameset(struct browser_window *bw, - struct content_html_frames *frameset) +/* exported function documented in desktop/frames.h */ +nserror browser_window_destroy_iframes(struct browser_window *bw) { - int row, col, index; - struct content_html_frames *frame; - struct browser_window *window; - hlcache_handle *parent; + int i; - assert(bw && frameset); - - /* 1. Create children */ - assert(bw->children == NULL); - assert(frameset->cols + frameset->rows != 0); - - bw->children = calloc((frameset->cols * frameset->rows), sizeof(*bw)); - if (!bw->children) { - return NSERROR_NOMEM; - } - - bw->cols = frameset->cols; - bw->rows = frameset->rows; - for (row = 0; row < bw->rows; row++) { - for (col = 0; col < bw->cols; col++) { - index = (row * bw->cols) + col; - frame = &frameset->children[index]; - window = &bw->children[index]; - - /* Initialise common parts */ - browser_window_initialise_common(BW_CREATE_NONE, - window, NULL); - - /* window characteristics */ - if (frame->children) - window->browser_window_type = - BROWSER_WINDOW_FRAMESET; - else - window->browser_window_type = - BROWSER_WINDOW_FRAME; - window->scrolling = frame->scrolling; - window->border = frame->border; - window->border_colour = frame->border_colour; - window->no_resize = frame->no_resize; - window->frame_width = frame->width; - window->frame_height = frame->height; - window->margin_width = frame->margin_width; - window->margin_height = frame->margin_height; - if (frame->name) { - window->name = strdup(frame->name); - if (!window->name) { - free(bw->children); - bw->children = NULL; - return NSERROR_NOMEM; - } + if (bw->iframes != NULL) { + for (i = 0; i < bw->iframe_count; i++) { + if (bw->iframes[i].box != NULL) { + bw->iframes[i].box->iframe = NULL; + bw->iframes[i].box = NULL; } - - window->scale = bw->scale; - - /* linking */ - window->parent = bw; - - if (window->name) - NSLOG(netsurf, INFO, "Created frame '%s'", - window->name); - else - NSLOG(netsurf, INFO, - "Created frame (unnamed)"); + browser_window_destroy_internal(&bw->iframes[i]); } + free(bw->iframes); + bw->iframes = NULL; + bw->iframe_count = 0; } - - /* 2. Calculate dimensions */ - browser_window_update_extent(bw); - browser_window_recalculate_frameset(bw); - - /* 3. Recurse for grandchildren */ - for (row = 0; row < bw->rows; row++) { - for (col = 0; col < bw->cols; col++) { - index = (row * bw->cols) + col; - frame = &frameset->children[index]; - window = &bw->children[index]; - - if (frame->children) - browser_window_create_frameset(window, frame); - } - } - - /* Use the URL of the first ancestor window containing html content - * as the referer */ - for (window = bw; window->parent; window = window->parent) { - if (window->current_content && - content_get_type(window->current_content) == - CONTENT_HTML) - break; - } - - parent = window->current_content; - - /* 4. Launch content */ - for (row = 0; row < bw->rows; row++) { - for (col = 0; col < bw->cols; col++) { - index = (row * bw->cols) + col; - frame = &frameset->children[index]; - window = &bw->children[index]; - - if (frame->url) { - browser_window_navigate(window, - frame->url, - hlcache_handle_get_url(parent), - BW_NAVIGATE_HISTORY | - BW_NAVIGATE_UNVERIFIABLE, - NULL, - NULL, - parent); - } - } - } - return NSERROR_OK; } @@ -417,10 +327,9 @@ nserror browser_window_create_frameset(struct browser_window *bw, /** * Recalculate frameset positions following a resize. * - * \param bw The browser window to reposition framesets for + * \param bw The browser window to reposition framesets for */ - -void browser_window_recalculate_frameset(struct browser_window *bw) +static void browser_window_recalculate_frameset_internal(struct browser_window *bw) { int widths[bw->cols][bw->rows]; int heights[bw->cols][bw->rows]; @@ -646,12 +555,180 @@ void browser_window_recalculate_frameset(struct browser_window *bw) x += widths[col][row]; if (window->children) - browser_window_recalculate_frameset(window); + browser_window_recalculate_frameset_internal(window); } } } +/** + * Create and open a frameset for a browser window. + * + * \param[in,out] bw The browser window to create the frameset for + * \param[in] frameset The frameset to create + * \return NSERROR_OK or error code on faliure + */ +static nserror +browser_window_create_frameset_internal(struct browser_window *bw, + struct content_html_frames *frameset) +{ + int row, col, index; + struct content_html_frames *frame; + struct browser_window *window; + hlcache_handle *parent; + + assert(bw && frameset); + + /* 1. Create children */ + assert(bw->children == NULL); + assert(frameset->cols + frameset->rows != 0); + + bw->children = calloc((frameset->cols * frameset->rows), sizeof(*bw)); + if (!bw->children) { + return NSERROR_NOMEM; + } + + bw->cols = frameset->cols; + bw->rows = frameset->rows; + for (row = 0; row < bw->rows; row++) { + for (col = 0; col < bw->cols; col++) { + index = (row * bw->cols) + col; + frame = &frameset->children[index]; + window = &bw->children[index]; + + /* Initialise common parts */ + browser_window_initialise_common(BW_CREATE_NONE, + window, NULL); + + /* window characteristics */ + if (frame->children) + window->browser_window_type = + BROWSER_WINDOW_FRAMESET; + else + window->browser_window_type = + BROWSER_WINDOW_FRAME; + window->scrolling = frame->scrolling; + window->border = frame->border; + window->border_colour = frame->border_colour; + window->no_resize = frame->no_resize; + window->frame_width = frame->width; + window->frame_height = frame->height; + window->margin_width = frame->margin_width; + window->margin_height = frame->margin_height; + if (frame->name) { + window->name = strdup(frame->name); + if (!window->name) { + free(bw->children); + bw->children = NULL; + return NSERROR_NOMEM; + } + } + + window->scale = bw->scale; + + /* linking */ + window->parent = bw; + + if (window->name) + NSLOG(netsurf, INFO, "Created frame '%s'", + window->name); + else + NSLOG(netsurf, INFO, + "Created frame (unnamed)"); + } + } + + /* 2. Calculate dimensions */ + browser_window_update_extent(bw); + browser_window_recalculate_frameset_internal(bw); + + /* 3. Recurse for grandchildren */ + for (row = 0; row < bw->rows; row++) { + for (col = 0; col < bw->cols; col++) { + index = (row * bw->cols) + col; + frame = &frameset->children[index]; + window = &bw->children[index]; + + if (frame->children) + browser_window_create_frameset_internal(window, frame); + } + } + + /* Use the URL of the first ancestor window containing html content + * as the referer */ + for (window = bw; window->parent; window = window->parent) { + if (window->current_content && + content_get_type(window->current_content) == + CONTENT_HTML) + break; + } + + parent = window->current_content; + + /* 4. Launch content */ + for (row = 0; row < bw->rows; row++) { + for (col = 0; col < bw->cols; col++) { + index = (row * bw->cols) + col; + frame = &frameset->children[index]; + window = &bw->children[index]; + + if (frame->url) { + browser_window_navigate(window, + frame->url, + hlcache_handle_get_url(parent), + BW_NAVIGATE_HISTORY | + BW_NAVIGATE_UNVERIFIABLE, + NULL, + NULL, + parent); + } + } + } + + return NSERROR_OK; +} + + +/* exported interface documented in desktop/frames.h */ +nserror browser_window_create_frameset(struct browser_window *bw) +{ + struct content_html_frames *frameset; + + if (content_get_type(bw->current_content) != CONTENT_HTML) { + return NSERROR_OK; + } + + frameset = html_get_frameset(bw->current_content); + if (frameset == NULL) { + return NSERROR_OK; + } + + return browser_window_create_frameset_internal(bw, frameset); +} + + + + +/** + * Recalculate frameset positions following a resize. + * + * \param bw The browser window to reposition framesets for + */ + +void browser_window_recalculate_frameset(struct browser_window *bw) +{ + if (content_get_type(bw->current_content) != CONTENT_HTML) { + return; + } + + if (html_get_frameset(bw->current_content) == NULL) { + return; + } + + browser_window_recalculate_frameset_internal(bw); +} + + /** * Resize a browser window that is a frame. * @@ -703,7 +780,7 @@ void browser_window_resize_frame(struct browser_window *bw, int x, int y) } if (change) { - browser_window_recalculate_frameset(parent); + browser_window_recalculate_frameset_internal(parent); } } diff --git a/desktop/frames.h b/desktop/frames.h index 063e2c558..dda31824b 100644 --- a/desktop/frames.h +++ b/desktop/frames.h @@ -16,12 +16,13 @@ * along with this program. If not, see . */ -/** \file +/** + * \file * Frame and frameset creation and manipulation (interface). */ -#ifndef _NETSURF_DESKTOP_FRAMES_H_ -#define _NETSURF_DESKTOP_FRAMES_H_ +#ifndef NETSURF_DESKTOP_FRAMES_H_ +#define NETSURF_DESKTOP_FRAMES_H_ struct scrollbar_msg_data; struct content_html_iframe; @@ -30,23 +31,40 @@ struct content_html_frames; /** * Create and open iframes for a browser window. * - * \param bw The browser window to create iframes for. - * \param iframe The iframes to create from. + * \param bw The browser window to create iframes for. * \return NSERROR_OK or error code on faliure. */ -nserror browser_window_create_iframes(struct browser_window *bw, - struct content_html_iframe *iframe); +nserror browser_window_create_iframes(struct browser_window *bw); + +/** + * Recalculate iframe positions following a resize. + * + * \param bw The browser window to reposition iframes for + */ void browser_window_recalculate_iframes(struct browser_window *bw); +/** + * Invalidate an iframe causing a redraw. + * + * \param bw The browser window to invalidate + */ +nserror browser_window_invalidate_iframe(struct browser_window *bw); + +/** + * Destroy iframes opened in browser_window_create_iframes() + * + * \param bw The browser window to destroy iframes for. + * \return NSERROR_OK + */ +nserror browser_window_destroy_iframes(struct browser_window *bw); + /** * Create and open a frameset for a browser window. * * \param[in,out] bw The browser window to create the frameset for - * \param[in] frameset The frameset to create * \return NSERROR_OK or error code on faliure */ -nserror browser_window_create_frameset(struct browser_window *bw, - struct content_html_frames *frameset); +nserror browser_window_create_frameset(struct browser_window *bw); void browser_window_recalculate_frameset(struct browser_window *bw); bool browser_window_frame_resize_start(struct browser_window *bw,