remove box handling from browser window

This commit is contained in:
Vincent Sanders 2020-05-25 17:12:43 +01:00
parent 6d62a06899
commit b182cc7617
7 changed files with 271 additions and 212 deletions

View File

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

View File

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

View File

@ -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
* <base target=...>, 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 */

View File

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

View File

@ -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,13 +1546,11 @@ 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)
if (c == bw->current_content) {
/* recompute frameset */
browser_window_recalculate_frameset(bw);
/* reflow iframe positions */
if (html_get_iframe(c) != NULL)
/* recompute iframe positions, sizes and scrollbars */
browser_window_recalculate_iframes(bw);
}
@ -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_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(&params, 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;

View File

@ -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;
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;
}
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;
browser_window_destroy_internal(&bw->iframes[i]);
}
free(bw->iframes);
bw->iframes = NULL;
bw->iframe_count = 0;
}
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(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;
}
@ -419,8 +329,7 @@ nserror browser_window_create_frameset(struct browser_window *bw,
*
* \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);
}
}

View File

@ -16,12 +16,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \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;
@ -31,22 +32,39 @@ 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.
* \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,