From 8ee81a7d8e00c70739ece2bafee04c9dce5429c8 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Mon, 26 Jun 2006 04:52:34 +0000 Subject: Implement absolute positioning. svn path=/trunk/netsurf/; revision=2648 --- render/box_construct.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'render/box_construct.c') diff --git a/render/box_construct.c b/render/box_construct.c index 1cb0ffb19..a5f654926 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -82,10 +82,12 @@ const char *TARGET_TOP = "_top"; static bool convert_xml_to_box(xmlNode *n, struct content *content, struct css_style *parent_style, struct box *parent, struct box **inline_container, + struct box *containing_block, char *href, const char *target, char *title); bool box_construct_element(xmlNode *n, struct content *content, struct css_style *parent_style, struct box *parent, struct box **inline_container, + struct box *containing_block, char *href, const char *target, char *title); bool box_construct_text(xmlNode *n, struct content *content, struct css_style *parent_style, @@ -173,6 +175,7 @@ bool xml_to_box(xmlNode *n, struct content *c) root.parent = NULL; root.float_children = NULL; root.next_float = NULL; + root.absolute_children = NULL; c->data.html.style = talloc_memdup(c, &css_base_style, sizeof css_base_style); @@ -187,7 +190,7 @@ bool xml_to_box(xmlNode *n, struct content *c) c->data.html.object = 0; if (!convert_xml_to_box(n, c, c->data.html.style, &root, - &inline_container, 0, 0, 0)) + &inline_container, 0, 0, 0, 0)) return false; if (!box_normalise_block(&root, c)) @@ -231,6 +234,8 @@ static const box_type box_map[] = { * \param parent parent in box tree * \param inline_container current inline container box, or 0, updated to * new current inline container on exit + * \param containing_block current containing block for absolutes, as defined + * by CSS 2.1 10.1 4 * \param href current link URL, or 0 if not in a link * \param target current link target, or 0 if none * \param title current title, or 0 if none @@ -240,12 +245,14 @@ static const box_type box_map[] = { bool convert_xml_to_box(xmlNode *n, struct content *content, struct css_style *parent_style, struct box *parent, struct box **inline_container, + struct box *containing_block, char *href, const char *target, char *title) { switch (n->type) { case XML_ELEMENT_NODE: return box_construct_element(n, content, parent_style, parent, - inline_container, href, target, title); + inline_container, containing_block, + href, target, title); case XML_TEXT_NODE: return box_construct_text(n, content, parent_style, parent, inline_container, href, target, title); @@ -265,6 +272,8 @@ bool convert_xml_to_box(xmlNode *n, struct content *content, * \param parent parent in box tree * \param inline_container current inline container box, or 0, updated to * new current inline container on exit + * \param containing_block current containing block for absolutes, as defined + * by CSS 2.1 10.1 4 * \param href current link URL, or 0 if not in a link * \param target current link target, or 0 if none * \param title current title, or 0 if none @@ -274,6 +283,7 @@ bool convert_xml_to_box(xmlNode *n, struct content *content, bool box_construct_element(xmlNode *n, struct content *content, struct css_style *parent_style, struct box *parent, struct box **inline_container, + struct box *containing_block, char *href, const char *target, char *title) { bool convert_children = true; @@ -281,6 +291,7 @@ bool box_construct_element(xmlNode *n, struct content *content, char *s; struct box *box = 0; struct box *inline_container_c; + struct box *containing_block_c; struct box *inline_end; struct css_style *style = 0; struct element_entry *element; @@ -350,6 +361,15 @@ bool box_construct_element(xmlNode *n, struct content *content, return true; } + /* determine if this is a new containing block */ + if (style->position == CSS_POSITION_ABSOLUTE || + style->position == CSS_POSITION_RELATIVE || + style->position == CSS_POSITION_FIXED || + !containing_block) + containing_block_c = box; + else + containing_block_c = containing_block; + if (!*inline_container && (box->type == BOX_INLINE || box->type == BOX_BR || @@ -371,6 +391,7 @@ bool box_construct_element(xmlNode *n, struct content *content, for (c = n->children; c; c = c->next) if (!convert_xml_to_box(c, content, style, parent, inline_container, + containing_block_c, href, target, title)) return false; inline_end = box_create(style, href, target, title, id, @@ -392,6 +413,19 @@ bool box_construct_element(xmlNode *n, struct content *content, for (c = n->children; convert_children && c; c = c->next) if (!convert_xml_to_box(c, content, style, box, &inline_container_c, + containing_block_c, + href, target, title)) + return false; + } else if ((style->position == CSS_POSITION_ABSOLUTE || + style->position == CSS_POSITION_FIXED) && + containing_block) { + /* absolutely positioned */ + box_add_absolute_child(containing_block, box); + inline_container_c = 0; + for (c = n->children; convert_children && c; c = c->next) + if (!convert_xml_to_box(c, content, style, box, + &inline_container_c, + containing_block_c, href, target, title)) return false; } else { @@ -399,8 +433,6 @@ bool box_construct_element(xmlNode *n, struct content *content, style->float_ == CSS_FLOAT_RIGHT) { /* float: insert a float box between the parent and * current node */ - assert(style->float_ == CSS_FLOAT_LEFT || - style->float_ == CSS_FLOAT_RIGHT); parent = box_create(0, href, target, title, 0, content); if (!parent) return false; @@ -409,9 +441,6 @@ bool box_construct_element(xmlNode *n, struct content *content, else parent->type = BOX_FLOAT_RIGHT; box_add_child(*inline_container, parent); - if (box->type == BOX_INLINE || - box->type == BOX_INLINE_BLOCK) - box->type = BOX_BLOCK; } /* non-inline box: add to tree and recurse */ @@ -420,6 +449,7 @@ bool box_construct_element(xmlNode *n, struct content *content, for (c = n->children; convert_children && c; c = c->next) if (!convert_xml_to_box(c, content, style, box, &inline_container_c, + containing_block_c, href, target, title)) return false; if (style->float_ == CSS_FLOAT_NONE) @@ -1382,7 +1412,7 @@ bool box_object(BOX_SPECIAL_PARAMS) /* convert children and place into fallback */ for (c = n->children; c; c = c->next) { if (!convert_xml_to_box(c, content, box->style, box, - &inline_container, 0, 0, 0)) + &inline_container, 0, 0, 0, 0)) return false; } box->fallback = box->children; -- cgit v1.2.3