summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/box.c4
-rw-r--r--render/box.h6
-rw-r--r--render/box_construct.c2
-rw-r--r--render/html_interaction.c22
-rw-r--r--render/html_redraw.c13
-rw-r--r--render/layout.c73
-rw-r--r--render/textplain.c2
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);
}