summaryrefslogtreecommitdiff
path: root/render/box_construct.c
diff options
context:
space:
mode:
Diffstat (limited to 'render/box_construct.c')
-rw-r--r--render/box_construct.c46
1 files changed, 38 insertions, 8 deletions
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;