diff options
Diffstat (limited to 'content/handlers/html/box_normalise.c')
-rw-r--r-- | content/handlers/html/box_normalise.c | 204 |
1 files changed, 200 insertions, 4 deletions
diff --git a/content/handlers/html/box_normalise.c b/content/handlers/html/box_normalise.c index 7155cb722..6bb107d64 100644 --- a/content/handlers/html/box_normalise.c +++ b/content/handlers/html/box_normalise.c @@ -93,6 +93,180 @@ static bool box_normalise_inline_container( const struct box *root, html_content *c); +static bool box_normalise_flex( + struct box *flex_container, + const struct box *root, + html_content *c) +{ + struct box *child; + struct box *next_child; + struct box *implied_flex_item; + css_computed_style *style; + nscss_select_ctx ctx; + + assert(flex_container != NULL); + assert(root != NULL); + + ctx.root_style = root->style; + +#ifdef BOX_NORMALISE_DEBUG + NSLOG(netsurf, INFO, "flex_container %p, flex_container->type %u", + flex_container, flex_container->type); +#endif + + assert(flex_container->type == BOX_FLEX || + flex_container->type == BOX_INLINE_FLEX); + + for (child = flex_container->children; child != NULL; child = next_child) { +#ifdef BOX_NORMALISE_DEBUG + NSLOG(netsurf, INFO, "child %p, child->type = %d", + child, child->type); +#endif + + next_child = child->next; /* child may be destroyed */ + + switch (child->type) { + case BOX_FLEX: + /* ok */ + if (box_normalise_flex(child, root, c) == false) + return false; + break; + case BOX_BLOCK: + /* ok */ + if (box_normalise_block(child, root, c) == false) + return false; + break; + case BOX_INLINE_CONTAINER: + /* insert implied flex item */ + assert(flex_container->style != NULL); + + ctx.ctx = c->select_ctx; + ctx.quirks = (c->quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL); + ctx.base_url = c->base_url; + ctx.universal = c->universal; + + style = nscss_get_blank_style(&ctx, flex_container->style); + if (style == NULL) + return false; + + implied_flex_item = box_create(NULL, style, true, + flex_container->href, + flex_container->target, + NULL, NULL, c->bctx); + if (implied_flex_item == NULL) { + css_computed_style_destroy(style); + return false; + } + implied_flex_item->type = BOX_BLOCK; + + if (child->prev == NULL) + flex_container->children = implied_flex_item; + else + child->prev->next = implied_flex_item; + + implied_flex_item->prev = child->prev; + + while (child != NULL && + child->type == BOX_INLINE_CONTAINER) { + box_add_child(implied_flex_item, child); + + next_child = child->next; + child->next = NULL; + child = next_child; + } + + implied_flex_item->last->next = NULL; + implied_flex_item->next = next_child = child; + if (implied_flex_item->next != NULL) + implied_flex_item->next->prev = implied_flex_item; + else + flex_container->last = implied_flex_item; + implied_flex_item->parent = flex_container; + + if (box_normalise_block(implied_flex_item, + root, c) == false) + return false; + break; + + case BOX_TABLE: + if (box_normalise_table(child, root, c) == false) + return false; + break; + case BOX_INLINE: + case BOX_INLINE_END: + case BOX_INLINE_FLEX: + case BOX_INLINE_BLOCK: + case BOX_FLOAT_LEFT: + case BOX_FLOAT_RIGHT: + case BOX_BR: + case BOX_TEXT: + /* should have been wrapped in inline + container by convert_xml_to_box() */ + assert(0); + break; + case BOX_TABLE_ROW_GROUP: + case BOX_TABLE_ROW: + case BOX_TABLE_CELL: + /* insert implied table */ + assert(flex_container->style != NULL); + + ctx.ctx = c->select_ctx; + ctx.quirks = (c->quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL); + ctx.base_url = c->base_url; + ctx.universal = c->universal; + + style = nscss_get_blank_style(&ctx, flex_container->style); + if (style == NULL) + return false; + + implied_flex_item = box_create(NULL, style, true, + flex_container->href, + flex_container->target, + NULL, NULL, c->bctx); + if (implied_flex_item == NULL) { + css_computed_style_destroy(style); + return false; + } + implied_flex_item->type = BOX_TABLE; + + if (child->prev == NULL) + flex_container->children = implied_flex_item; + else + child->prev->next = implied_flex_item; + + implied_flex_item->prev = child->prev; + + while (child != NULL && ( + child->type == BOX_TABLE_ROW_GROUP || + child->type == BOX_TABLE_ROW || + child->type == BOX_TABLE_CELL)) { + box_add_child(implied_flex_item, child); + + next_child = child->next; + child->next = NULL; + child = next_child; + } + + implied_flex_item->last->next = NULL; + implied_flex_item->next = next_child = child; + if (implied_flex_item->next != NULL) + implied_flex_item->next->prev = implied_flex_item; + else + flex_container->last = implied_flex_item; + implied_flex_item->parent = flex_container; + + if (box_normalise_table(implied_flex_item, + root, c) == false) + return false; + break; + default: + assert(0); + } + } + + return true; +} + /** * Ensure the box tree is correctly nested by adding and removing nodes. * @@ -104,14 +278,15 @@ static bool box_normalise_inline_container( * The tree is modified to satisfy the following: * \code * parent permitted child nodes - * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE - * INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR, TEXT + * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE, FLEX + * FLEX, INLINE_FLEX BLOCK, INLINE_CONTAINER, TABLE, FLEX + * INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR, TEXT, INLINE_FLEX * INLINE, TEXT none * TABLE at least 1 TABLE_ROW_GROUP * TABLE_ROW_GROUP at least 1 TABLE_ROW * TABLE_ROW at least 1 TABLE_CELL - * TABLE_CELL BLOCK, INLINE_CONTAINER, TABLE (same as BLOCK) - * FLOAT_(LEFT|RIGHT) exactly 1 BLOCK or TABLE + * TABLE_CELL BLOCK, INLINE_CONTAINER, TABLE, FLEX (same as BLOCK) + * FLOAT_(LEFT|RIGHT) exactly 1 BLOCK, TABLE or FLEX * \endcode */ @@ -147,6 +322,11 @@ bool box_normalise_block( next_child = child->next; /* child may be destroyed */ switch (child->type) { + case BOX_FLEX: + /* ok */ + if (box_normalise_flex(child, root, c) == false) + return false; + break; case BOX_BLOCK: /* ok */ if (box_normalise_block(child, root, c) == false) @@ -162,6 +342,7 @@ bool box_normalise_block( break; case BOX_INLINE: case BOX_INLINE_END: + case BOX_INLINE_FLEX: case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: @@ -275,6 +456,7 @@ bool box_normalise_table( return false; } break; + case BOX_FLEX: case BOX_BLOCK: case BOX_INLINE_CONTAINER: case BOX_TABLE: @@ -312,6 +494,7 @@ bool box_normalise_table( row_group->prev = child->prev; while (child != NULL && ( + child->type == BOX_FLEX || child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || @@ -342,6 +525,7 @@ bool box_normalise_table( break; case BOX_INLINE: case BOX_INLINE_END: + case BOX_INLINE_FLEX: case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: @@ -634,6 +818,7 @@ bool box_normalise_table_row_group( c) == false) return false; break; + case BOX_FLEX: case BOX_BLOCK: case BOX_INLINE_CONTAINER: case BOX_TABLE: @@ -667,6 +852,7 @@ bool box_normalise_table_row_group( row->prev = child->prev; while (child != NULL && ( + child->type == BOX_FLEX || child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || @@ -696,6 +882,7 @@ bool box_normalise_table_row_group( break; case BOX_INLINE: case BOX_INLINE_END: + case BOX_INLINE_FLEX: case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: @@ -787,6 +974,7 @@ bool box_normalise_table_row( return false; cell = child; break; + case BOX_FLEX: case BOX_BLOCK: case BOX_INLINE_CONTAINER: case BOX_TABLE: @@ -820,6 +1008,7 @@ bool box_normalise_table_row( cell->prev = child->prev; while (child != NULL && ( + child->type == BOX_FLEX || child->type == BOX_BLOCK || child->type == BOX_INLINE_CONTAINER || child->type == BOX_TABLE || @@ -847,6 +1036,7 @@ bool box_normalise_table_row( break; case BOX_INLINE: case BOX_INLINE_END: + case BOX_INLINE_FLEX: case BOX_INLINE_BLOCK: case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: @@ -994,6 +1184,11 @@ bool box_normalise_inline_container( if (box_normalise_block(child, root, c) == false) return false; break; + case BOX_INLINE_FLEX: + /* ok */ + if (box_normalise_flex(child, root, c) == false) + return false; + break; case BOX_FLOAT_LEFT: case BOX_FLOAT_RIGHT: /* ok */ @@ -1028,6 +1223,7 @@ bool box_normalise_inline_container( box_free(child); } break; + case BOX_FLEX: case BOX_BLOCK: case BOX_INLINE_CONTAINER: case BOX_TABLE: |