diff options
Diffstat (limited to 'content/handlers/html/box_construct.c')
-rw-r--r-- | content/handlers/html/box_construct.c | 121 |
1 files changed, 79 insertions, 42 deletions
diff --git a/content/handlers/html/box_construct.c b/content/handlers/html/box_construct.c index 12d9df87c..8519c2b1d 100644 --- a/content/handlers/html/box_construct.c +++ b/content/handlers/html/box_construct.c @@ -86,28 +86,30 @@ struct box_construct_props { static const content_type image_types = CONTENT_IMAGE; -/** - * mapping from CSS display to box type this table must be in sync - * with libcss' css_display enum - */ +/* mapping from CSS display to box type + * this table must be in sync with libcss' css_display enum */ static const box_type box_map[] = { - 0, /* CSS_DISPLAY_INHERIT, */ - BOX_INLINE, /* CSS_DISPLAY_INLINE, */ - BOX_BLOCK, /* CSS_DISPLAY_BLOCK, */ - BOX_BLOCK, /* CSS_DISPLAY_LIST_ITEM, */ - BOX_INLINE, /* CSS_DISPLAY_RUN_IN, */ - BOX_INLINE_BLOCK, /* CSS_DISPLAY_INLINE_BLOCK, */ - BOX_TABLE, /* CSS_DISPLAY_TABLE, */ - BOX_TABLE, /* CSS_DISPLAY_INLINE_TABLE, */ - BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_ROW_GROUP, */ - BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_HEADER_GROUP, */ - BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_FOOTER_GROUP, */ - BOX_TABLE_ROW, /* CSS_DISPLAY_TABLE_ROW, */ - BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN_GROUP, */ - BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN, */ - BOX_TABLE_CELL, /* CSS_DISPLAY_TABLE_CELL, */ - BOX_INLINE, /* CSS_DISPLAY_TABLE_CAPTION, */ - BOX_NONE /* CSS_DISPLAY_NONE */ + BOX_BLOCK, /* CSS_DISPLAY_INHERIT */ + BOX_INLINE, /* CSS_DISPLAY_INLINE */ + BOX_BLOCK, /* CSS_DISPLAY_BLOCK */ + BOX_BLOCK, /* CSS_DISPLAY_LIST_ITEM */ + BOX_INLINE, /* CSS_DISPLAY_RUN_IN */ + BOX_INLINE_BLOCK, /* CSS_DISPLAY_INLINE_BLOCK */ + BOX_TABLE, /* CSS_DISPLAY_TABLE */ + BOX_TABLE, /* CSS_DISPLAY_INLINE_TABLE */ + BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_ROW_GROUP */ + BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_HEADER_GROUP */ + BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_FOOTER_GROUP */ + BOX_TABLE_ROW, /* CSS_DISPLAY_TABLE_ROW */ + BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN_GROUP */ + BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN */ + BOX_TABLE_CELL, /* CSS_DISPLAY_TABLE_CELL */ + BOX_INLINE, /* CSS_DISPLAY_TABLE_CAPTION */ + BOX_NONE, /* CSS_DISPLAY_NONE */ + BOX_FLEX, /* CSS_DISPLAY_FLEX */ + BOX_INLINE_FLEX, /* CSS_DISPLAY_INLINE_FLEX */ + BOX_BLOCK, /* CSS_DISPLAY_GRID */ + BOX_INLINE_BLOCK, /* CSS_DISPLAY_INLINE_GRID */ }; @@ -142,7 +144,6 @@ static inline bool box_is_root(dom_node *n) return true; } - /** * Extract transient construction properties * @@ -248,16 +249,19 @@ box_get_style(html_content *c, const css_computed_style *root_style, dom_node *n) { - dom_string *s; - dom_exception err; + dom_string *s = NULL; css_stylesheet *inline_style = NULL; css_select_results *styles; nscss_select_ctx ctx; /* Firstly, construct inline stylesheet, if any */ - err = dom_element_get_attribute(n, corestring_dom_style, &s); - if (err != DOM_NO_ERR) - return NULL; + if (nsoption_bool(author_level_css)) { + dom_exception err; + err = dom_element_get_attribute(n, corestring_dom_style, &s); + if (err != DOM_NO_ERR) { + return NULL; + } + } if (s != NULL) { inline_style = nscss_create_inline_style( @@ -438,6 +442,23 @@ box_construct_marker(struct box *box, return true; } +static inline bool box__style_is_float(const struct box *box) +{ + return css_computed_float(box->style) == CSS_FLOAT_LEFT || + css_computed_float(box->style) == CSS_FLOAT_RIGHT; +} + +static inline bool box__is_flex(const struct box *box) +{ + return box->type == BOX_FLEX || box->type == BOX_INLINE_FLEX; +} + +static inline bool box__containing_block_is_flex( + const struct box_construct_props *props) +{ + return props->containing_block != NULL && + box__is_flex(props->containing_block); +} /** * Construct the box tree for an XML element. @@ -451,6 +472,7 @@ box_construct_element(struct box_construct_ctx *ctx, bool *convert_children) { dom_string *title0, *s; lwc_string *id = NULL; + enum css_display_e css_display; struct box *box = NULL, *old_box; css_select_results *styles = NULL; lwc_string *bgimage_uri; @@ -549,16 +571,15 @@ box_construct_element(struct box_construct_ctx *ctx, bool *convert_children) dom_string_unref(s); } + css_display = ns_computed_display_static(box->style); + /* Set box type from computed display */ if ((css_computed_position(box->style) == CSS_POSITION_ABSOLUTE || - css_computed_position(box->style) == - CSS_POSITION_FIXED) && - (ns_computed_display_static(box->style) == - CSS_DISPLAY_INLINE || - ns_computed_display_static(box->style) == - CSS_DISPLAY_INLINE_BLOCK || - ns_computed_display_static(box->style) == - CSS_DISPLAY_INLINE_TABLE)) { + css_computed_position(box->style) == CSS_POSITION_FIXED) && + (css_display == CSS_DISPLAY_INLINE || + css_display == CSS_DISPLAY_INLINE_BLOCK || + css_display == CSS_DISPLAY_INLINE_TABLE || + css_display == CSS_DISPLAY_INLINE_FLEX)) { /* Special case for absolute positioning: make absolute inlines * into inline block so that the boxes are constructed in an * inline container as if they were not absolutely positioned. @@ -572,6 +593,21 @@ box_construct_element(struct box_construct_ctx *ctx, bool *convert_children) /* Normal mapping */ box->type = box_map[ns_computed_display(box->style, props.node_is_root)]; + + if (props.containing_block->type == BOX_FLEX || + props.containing_block->type == BOX_INLINE_FLEX) { + /* Blockification */ + switch (box->type) { + case BOX_INLINE_FLEX: + box->type = BOX_FLEX; + break; + case BOX_INLINE_BLOCK: + box->type = BOX_BLOCK; + break; + default: + break; + } + } } if (convert_special_elements(ctx->n, @@ -587,10 +623,9 @@ box_construct_element(struct box_construct_ctx *ctx, bool *convert_children) box->styles->styles[CSS_PSEUDO_ELEMENT_BEFORE]); } - if (box->type == BOX_NONE || - (ns_computed_display(box->style, - props.node_is_root) == CSS_DISPLAY_NONE && - props.node_is_root == false)) { + if (box->type == BOX_NONE || (ns_computed_display(box->style, + props.node_is_root) == CSS_DISPLAY_NONE && + props.node_is_root == false)) { css_select_results_destroy(styles); box->styles = NULL; box->style = NULL; @@ -625,8 +660,9 @@ box_construct_element(struct box_construct_ctx *ctx, bool *convert_children) (box->type == BOX_INLINE || box->type == BOX_BR || box->type == BOX_INLINE_BLOCK || - css_computed_float(box->style) == CSS_FLOAT_LEFT || - css_computed_float(box->style) == CSS_FLOAT_RIGHT) && + box->type == BOX_INLINE_FLEX || + (box__style_is_float(box) && + !box__containing_block_is_flex(&props))) && props.node_is_root == false) { /* Found an inline child of a block without a current container * (i.e. this box is the first child of its parent, or was @@ -674,6 +710,7 @@ box_construct_element(struct box_construct_ctx *ctx, bool *convert_children) box->flags |= CONVERT_CHILDREN; if (box->type == BOX_INLINE || box->type == BOX_BR || + box->type == BOX_INLINE_FLEX || box->type == BOX_INLINE_BLOCK) { /* Inline container must exist, as we'll have * created it above if it didn't */ @@ -690,6 +727,7 @@ box_construct_element(struct box_construct_ctx *ctx, bool *convert_children) } if (props.node_is_root == false && + box__containing_block_is_flex(&props) == false && (css_computed_float(box->style) == CSS_FLOAT_LEFT || css_computed_float(box->style) == @@ -1342,7 +1380,6 @@ struct box *box_for_node(dom_node *n) return box; } - /* exported function documented in html/box_construct.h */ bool box_extract_link(const html_content *content, |