diff options
Diffstat (limited to 'render')
-rw-r--r-- | render/box.c | 4 | ||||
-rw-r--r-- | render/box.h | 6 | ||||
-rw-r--r-- | render/box_construct.c | 2 | ||||
-rw-r--r-- | render/html_interaction.c | 22 | ||||
-rw-r--r-- | render/html_redraw.c | 13 | ||||
-rw-r--r-- | render/layout.c | 73 | ||||
-rw-r--r-- | render/textplain.c | 2 |
7 files changed, 100 insertions, 22 deletions
diff --git a/render/box.c b/render/box.c index bd5f3daa1..60b5b9381 100644 --- a/render/box.c +++ b/render/box.c @@ -165,6 +165,7 @@ struct box * box_create(css_select_results *styles, css_computed_style *style, box->background = NULL; box->object = NULL; box->object_params = NULL; + box->iframe = NULL; return box; } @@ -932,6 +933,9 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth) fprintf(stream, "(object '%s') ", content_get_url(box->object)); } + if (box->iframe) { + fprintf(stream, "(iframe) "); + } if (box->gadget) fprintf(stream, "(gadget) "); if (box->style) diff --git a/render/box.h b/render/box.h index 936c57337..99f67ee1f 100644 --- a/render/box.h +++ b/render/box.h @@ -127,7 +127,8 @@ typedef enum { HAS_HEIGHT = 1 << 6, /* box has height (perhaps due to children) */ MAKE_HEIGHT = 1 << 7, /* box causes its own height */ NEED_MIN = 1 << 8, /* minimum width is required for layout */ - REPLACE_DIM = 1 << 9 /* replaced element has given dimensions */ + REPLACE_DIM = 1 << 9, /* replaced element has given dimensions */ + IFRAME = 1 << 10 /* box contains an iframe */ } box_flags; /* Sides of a box */ @@ -257,6 +258,9 @@ struct box { struct hlcache_handle* object; /** Parameters for the object, or 0. */ struct object_params *object_params; + + /** Iframe's browser_window, or NULL if none */ + struct browser_window *iframe; }; /** Table column data. */ diff --git a/render/box_construct.c b/render/box_construct.c index 34cd77b04..5fdb23b5a 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -1631,8 +1631,8 @@ bool box_iframe(BOX_SPECIAL_PARAMS) free(url); /* box */ - box->type = BOX_INLINE_BLOCK; assert(box->style); + box->flags |= IFRAME; /* Showing iframe, so don't show alternate content */ if (convert_children) diff --git a/render/html_interaction.c b/render/html_interaction.c index cd4caa488..91f8cb39c 100644 --- a/render/html_interaction.c +++ b/render/html_interaction.c @@ -135,6 +135,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw, hlcache_handle *gadget_content = h; struct form_control *gadget = 0; hlcache_handle *object = NULL; + struct browser_window *iframe = NULL; struct box *next_box; struct box *drag_candidate = NULL; struct scrollbar *scrollbar = NULL; @@ -214,6 +215,9 @@ void html_mouse_action(struct content *c, struct browser_window *bw, if (box->object) object = box->object; + if (box->iframe) + iframe = box->iframe; + if (box->href) { url = box->href; target = box->target; @@ -464,6 +468,18 @@ void html_mouse_action(struct content *c, struct browser_window *bw, /* \todo should have a drag-saving object msg */ status = content_get_status_message(h); + } else if (iframe) { + int pos_x, pos_y; + browser_window_get_position(iframe, false, &pos_x, &pos_y); + + if (mouse & BROWSER_MOUSE_CLICK_1 || + mouse & BROWSER_MOUSE_CLICK_2) { + browser_window_mouse_click(iframe, mouse, + x - pos_x, y - pos_y); + } else { + browser_window_mouse_track(iframe, mouse, + x - pos_x, y - pos_y); + } } else if (url) { if (title) { snprintf(status_buffer, sizeof status_buffer, "%s: %s", @@ -601,7 +617,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw, if (status != NULL) browser_window_set_status(bw, status); - browser_window_set_pointer(bw->window, pointer); + if (!iframe) + browser_window_set_pointer(bw, pointer); /* deferred actions that can cause this browser_window to be destroyed * and must therefore be done after set_status/pointer @@ -778,8 +795,7 @@ void html_overflow_scroll_callback(void *client_data, case SCROLLBAR_MSG_SCROLL_FINISHED: bw->scrollbar = NULL; - browser_window_set_pointer(bw->window, - GUI_POINTER_DEFAULT); + browser_window_set_pointer(bw, GUI_POINTER_DEFAULT); break; } } diff --git a/render/html_redraw.c b/render/html_redraw.c index cc80bde81..1bc32607f 100644 --- a/render/html_redraw.c +++ b/render/html_redraw.c @@ -430,7 +430,7 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent, bg_box->type != BOX_TEXT && bg_box->type != BOX_INLINE_END && (bg_box->type != BOX_INLINE || bg_box->object || - box->flags & REPLACE_DIM)) { + bg_box->flags & IFRAME || box->flags & REPLACE_DIM)) { /* find intersection of clip box and border edge */ struct rect p; p.x0 = x - border_left < r.x0 ? r.x0 : x - border_left; @@ -475,7 +475,7 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent, if (box->style && box->type != BOX_TEXT && box->type != BOX_INLINE_END && (box->type != BOX_INLINE || box->object || - box->flags & REPLACE_DIM) && + box->flags & IFRAME || box->flags & REPLACE_DIM) && (border_top || border_right || border_bottom || border_left)) { if (!html_redraw_borders(box, x_parent, y_parent, @@ -622,8 +622,9 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent, /* clip to the padding edge for objects, or boxes with overflow hidden * or scroll */ - if (box->object || (box->style && css_computed_overflow(box->style) != - CSS_OVERFLOW_VISIBLE)) { + if ((box->style && css_computed_overflow(box->style) != + CSS_OVERFLOW_VISIBLE) || box->object || + box->flags & IFRAME) { r.x0 = x; r.y0 = y; r.x1 = x + padding_width; @@ -660,6 +661,10 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent, false, false)) return false; + } else if (box->flags & IFRAME) { + browser_window_redraw(box->iframe, + x + padding_left, y + padding_top, &r); + } else if (box->gadget && box->gadget->type == GADGET_CHECKBOX) { if (!html_redraw_checkbox(x + padding_left, y + padding_top, width, height, diff --git a/render/layout.c b/render/layout.c index 60ad8baa9..711eb5c71 100644 --- a/render/layout.c +++ b/render/layout.c @@ -273,6 +273,12 @@ bool layout_block_context(struct box *block, int viewport_height, return true; } + /* special case if the block contains an iframe */ + if (block->iframe) { + browser_window_reformat(block->iframe, block->width, + block->height == AUTO ? 0 : block->height); + } + /* special case if the block contains an radio button or checkbox */ if (block->gadget && (block->gadget->type == GADGET_RADIO || block->gadget->type == GADGET_CHECKBOX)) { @@ -360,8 +366,10 @@ bool layout_block_context(struct box *block, int viewport_height, * left and right margins to avoid any floats. */ lm = rm = 0; - if (box->type == BOX_BLOCK || box->object) { - if (!box->object && !(box->flags & REPLACE_DIM) && + if (box->type == BOX_BLOCK || box->object || + box->flags & IFRAME) { + if (!box->object && !(box->flags & IFRAME) && + !(box->flags & REPLACE_DIM) && box->style && css_computed_overflow(box->style) != CSS_OVERFLOW_VISIBLE) { @@ -388,7 +396,7 @@ bool layout_block_context(struct box *block, int viewport_height, } layout_block_find_dimensions(box->parent->width, viewport_height, lm, rm, box); - if (box->type == BOX_BLOCK) { + if (box->type == BOX_BLOCK && !(box->flags & IFRAME)) { layout_block_add_scrollbar(box, RIGHT); layout_block_add_scrollbar(box, BOTTOM); } @@ -503,11 +511,18 @@ bool layout_block_context(struct box *block, int viewport_height, if (box->object) { if (!layout_block_object(box)) return false; + + } else if (box->iframe) { + browser_window_reformat(box->iframe, box->width, + box->height == AUTO ? + 0 : box->height); + } else if (box->type == BOX_INLINE_CONTAINER) { box->width = box->parent->width; if (!layout_inline_container(box, box->width, block, cx, cy, content)) return false; + } else if (box->type == BOX_TABLE) { /* Move down to avoid floats if necessary. */ int x0, x1; @@ -549,7 +564,8 @@ bool layout_block_context(struct box *block, int viewport_height, } /* Advance to next box. */ - if (box->type == BOX_BLOCK && !box->object && box->children) { + if (box->type == BOX_BLOCK && !box->object && !(box->iframe) && + box->children) { /* Down into children. */ if (box == margin_collapse) { @@ -563,7 +579,8 @@ bool layout_block_context(struct box *block, int viewport_height, box->y = y; cy += y; continue; - } else if (box->type == BOX_BLOCK || box->object) + } else if (box->type == BOX_BLOCK || box->object || + box->flags & IFRAME) cy += box->padding[TOP]; if (box->type == BOX_BLOCK && box->height == AUTO) { @@ -777,6 +794,10 @@ void layout_minmax_block(struct box *block, } block->flags |= HAS_HEIGHT; + } else if (block->flags & IFRAME) { + /** TODO: do we need to know the min/max width of the iframe's + * content? */ + block->flags |= HAS_HEIGHT; } else { /* recurse through children */ for (child = block->children; child; child = child->next) { @@ -2016,8 +2037,9 @@ bool layout_inline_container(struct box *inline_container, int width, whitespace == CSS_WHITE_SPACE_PRE_WRAP); } - if ((!c->object && !(c->flags & REPLACE_DIM) && c->text && - (c->length || is_pre)) || + if ((!c->object && !(c->flags & REPLACE_DIM) && + !(c->flags & IFRAME) && + c->text && (c->length || is_pre)) || c->type == BOX_BR) has_text_children = true; } @@ -2369,7 +2391,7 @@ bool layout_line(struct box *first, int *width, int *y, continue; } - if (!b->object && !b->gadget && + if (!b->object && !(b->flags & IFRAME) && !b->gadget && !(b->flags & REPLACE_DIM)) { /* inline non-replaced, 10.3.1 and 10.6.1 */ b->height = line_height(b->style ? b->style : @@ -2468,6 +2490,19 @@ bool layout_line(struct box *first, int *width, int *y, if (b->object && !(b->flags & REPLACE_DIM)) { layout_get_object_dimensions(b, &b->width, &b->height, true, true); + } else if (b->flags & IFRAME) { + /* TODO: should we look at the content dimensions? */ + if (b->width == AUTO) + b->width = 400; + if (b->height == AUTO) + b->height = 300; + + /* If the iframe's bw is in place, reformat it to the + * new box size */ + if (b->iframe) { + browser_window_reformat(b->iframe, + b->width, b->height); + } } else { /* form control with no object */ if (b->width == AUTO) @@ -2478,6 +2513,7 @@ bool layout_line(struct box *first, int *width, int *y, CSS_UNIT_EM, b->style)); } + /* Reformat object to new box size */ if (b->object && content_get_type(b->object) == CONTENT_HTML && b->width != content_get_available_width(b->object)) { @@ -2558,7 +2594,8 @@ bool layout_line(struct box *first, int *width, int *y, } space_before = space_after; - if (b->object || b->flags & REPLACE_DIM) + if (b->object || b->flags & REPLACE_DIM || + b->flags & IFRAME) space_after = 0; else if (b->text || b->type == BOX_INLINE_END) { if (b->space == UNKNOWN_WIDTH) { @@ -2713,6 +2750,7 @@ bool layout_line(struct box *first, int *width, int *y, split_box->type == BOX_TEXT) && !split_box->object && !(split_box->flags & REPLACE_DIM) && + !(split_box->flags & IFRAME) && !split_box->gadget && split_box->text) { /* skip leading spaces, otherwise code gets fooled into * thinking it's all one long word */ @@ -2867,6 +2905,7 @@ bool layout_line(struct box *first, int *width, int *y, continue; } else if ((d->type == BOX_INLINE && ((d->object || d->gadget) == false) && + !(d->flags & IFRAME) && !(d->flags & REPLACE_DIM)) || d->type == BOX_BR || d->type == BOX_TEXT || @@ -3022,7 +3061,8 @@ struct box *layout_minmax_line(struct box *first, font_plot_style_from_css(b->style, &fstyle); if (b->type == BOX_INLINE && !b->object && - !(b->flags & REPLACE_DIM)) { + !(b->flags & REPLACE_DIM) && + !(b->flags & IFRAME)) { fixed = frac = 0; calculate_mbp_width(b->style, LEFT, true, true, true, &fixed, &frac); @@ -3050,7 +3090,7 @@ struct box *layout_minmax_line(struct box *first, continue; } - if (!b->object && !b->gadget && + if (!b->object && !(b->flags & IFRAME) && !b->gadget && !(b->flags & REPLACE_DIM)) { /* inline non-replaced, 10.3.1 and 10.6.1 */ if (!b->text) @@ -3165,6 +3205,15 @@ struct box *layout_minmax_line(struct box *first, if (0 < width + fixed) width += fixed; + } else if (b->flags & IFRAME) { + fixed = frac = 0; + calculate_mbp_width(b->style, LEFT, true, true, true, + &fixed, &frac); + calculate_mbp_width(b->style, RIGHT, true, true, true, + &fixed, &frac); + + if (0 < width + fixed) + width += fixed; } else { /* form control with no object */ if (width == AUTO) @@ -4668,7 +4717,7 @@ bool layout_absolute(struct box *box, struct box *containing_block, box->height = height; if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || - box->object) { + box->object || box->flags & IFRAME) { if (!layout_block_context(box, -1, content)) return false; } else if (box->type == BOX_TABLE) { diff --git a/render/textplain.c b/render/textplain.c index f498869de..8a1bdc88a 100644 --- a/render/textplain.c +++ b/render/textplain.c @@ -661,7 +661,7 @@ void textplain_mouse_action(struct content *c, struct browser_window *bw, if (status != NULL) browser_window_set_status(bw, status); - browser_window_set_pointer(bw->window, pointer); + browser_window_set_pointer(bw, pointer); } |