diff --git a/src/document/css/apply.c b/src/document/css/apply.c index c9a6101d..5c17d1e8 100644 --- a/src/document/css/apply.c +++ b/src/document/css/apply.c @@ -61,6 +61,28 @@ css_apply_background_color(struct html_context *html_context, element->attr.style.bg = prop->value.color; } +static void +css_apply_display(struct html_context *html_context, struct html_element *element, + struct css_property *prop) +{ + assert(prop->value_type == CSS_VT_DISPLAY); + + switch (prop->value.display) { + case CSS_DISP_INLINE: + element->linebreak = 0; + break; + case CSS_DISP_BLOCK: + /* 1 or 2, that is the question. I went for 2 since it + * gives a more "blocky" feel and it's more common. + * YMMV. */ + element->linebreak = 2; + break; + default: + INTERNAL("Bad prop->value.display %d", prop->value.display); + break; + } +} + static void css_apply_font_attribute(struct html_context *html_context, struct html_element *element, struct css_property *prop) @@ -86,6 +108,7 @@ static css_applier_T css_appliers[CSS_PT_LAST] = { /* CSS_PT_BACKGROUND */ css_apply_background_color, /* CSS_PT_BACKGROUND_COLOR */ css_apply_background_color, /* CSS_PT_COLOR */ css_apply_color, + /* CSS_PT_DISPLAY */ css_apply_display, /* CSS_PT_FONT_STYLE */ css_apply_font_attribute, /* CSS_PT_FONT_WEIGHT */ css_apply_font_attribute, /* CSS_PT_TEXT_ALIGN */ css_apply_text_align, diff --git a/src/document/css/property.c b/src/document/css/property.c index f42fd590..878191da 100644 --- a/src/document/css/property.c +++ b/src/document/css/property.c @@ -19,6 +19,7 @@ struct css_property_info css_property_info[CSS_PT_LAST] = { { "background", CSS_PT_BACKGROUND, CSS_VT_COLOR, css_parse_background_value }, { "background-color", CSS_PT_BACKGROUND_COLOR, CSS_VT_COLOR, css_parse_color_value }, { "color", CSS_PT_COLOR, CSS_VT_COLOR, css_parse_color_value }, + { "display", CSS_PT_DISPLAY, CSS_VT_DISPLAY, css_parse_display_value }, { "font-style", CSS_PT_FONT_STYLE, CSS_VT_FONT_ATTRIBUTE, css_parse_font_style_value }, { "font-weight", CSS_PT_FONT_WEIGHT, CSS_VT_FONT_ATTRIBUTE, css_parse_font_weight_value }, { "text-align", CSS_PT_TEXT_ALIGN, CSS_VT_TEXT_ALIGN, css_parse_text_align_value }, diff --git a/src/document/css/property.h b/src/document/css/property.h index 8f7e5b71..1cda9e72 100644 --- a/src/document/css/property.h +++ b/src/document/css/property.h @@ -22,6 +22,7 @@ struct css_property { CSS_PT_BACKGROUND, CSS_PT_BACKGROUND_COLOR, CSS_PT_COLOR, + CSS_PT_DISPLAY, CSS_PT_FONT_STYLE, CSS_PT_FONT_WEIGHT, CSS_PT_TEXT_ALIGN, @@ -36,6 +37,7 @@ struct css_property { enum css_property_value_type { CSS_VT_NONE, CSS_VT_COLOR, + CSS_VT_DISPLAY, CSS_VT_FONT_ATTRIBUTE, CSS_VT_TEXT_ALIGN, CSS_VT_LAST, @@ -43,6 +45,10 @@ struct css_property { union css_property_value { void *none; color_T color; + enum css_display { + CSS_DISP_INLINE, + CSS_DISP_BLOCK, + } display; struct { enum format_attr add, rem; } font_attribute; diff --git a/src/document/css/value.c b/src/document/css/value.c index 3a6141c3..bd186eda 100644 --- a/src/document/css/value.c +++ b/src/document/css/value.c @@ -283,6 +283,32 @@ css_parse_white_space_value(struct css_property_info *propinfo, return 1; } +int +css_parse_display_value(struct css_property_info *propinfo, + union css_property_value *value, + struct scanner *scanner) +{ + struct scanner_token *token = get_scanner_token(scanner); + + assert(propinfo->value_type == CSS_VT_DISPLAY); + + if (token->type != CSS_TOKEN_IDENT) return 0; + + /* FIXME: This is _very_ simplistic */ + if (scanner_token_contains(token, "inline")) { + value->display = CSS_DISP_INLINE; + } else if (scanner_token_contains(token, "inline-block")) { + value->display = CSS_DISP_INLINE; /* XXX */ + } else if (scanner_token_contains(token, "block")) { + value->display = CSS_DISP_BLOCK; + } else { + return 0; + } + + skip_css_tokens(scanner, CSS_TOKEN_IDENT); + return 1; +} + int css_parse_value(struct css_property_info *propinfo, diff --git a/src/document/css/value.h b/src/document/css/value.h index b4677522..1bdc29c0 100644 --- a/src/document/css/value.h +++ b/src/document/css/value.h @@ -30,6 +30,11 @@ int css_parse_color_value(struct css_property_info *propinfo, union css_property_value *value, struct scanner *scanner); +/* Takes no parser_data. */ +int css_parse_display_value(struct css_property_info *propinfo, + union css_property_value *value, + struct scanner *scanner); + /* Takes no parser_data. */ int css_parse_text_decoration_value(struct css_property_info *propinfo, union css_property_value *value, diff --git a/src/document/html/parser/parse.c b/src/document/html/parser/parse.c index 8f1ef7e0..5cf28e31 100644 --- a/src/document/html/parser/parse.c +++ b/src/document/html/parser/parse.c @@ -753,6 +753,14 @@ start_element(struct element_info *ei, unsigned char *eof, unsigned char *attr, struct html_context *html_context) { +#define ELEMENT_RENDER_PROLOGUE \ + ln_break(html_context, ei->linebreak); \ + a = get_attr_val(attr, "id", html_context->options); \ + if (a) { \ + html_context->special_f(html_context, SP_TAG, a); \ + mem_free(a); \ + } + unsigned char *a; struct par_attrib old_format; int restore_format; @@ -760,15 +768,6 @@ start_element(struct element_info *ei, struct css_selector *selector = NULL; #endif - - ln_break(html_context, ei->linebreak); - - a = get_attr_val(attr, "id", html_context->options); - if (a) { - html_context->special_f(html_context, SP_TAG, a); - mem_free(a); - } - if (html_top.type == ELEMENT_WEAK) { kill_html_stack_item(html_context, &html_top); } @@ -777,6 +776,7 @@ start_element(struct element_info *ei, * one. */ if (html_top.invisible && (ei->func != html_script || html_top.invisible < 2)) { + ELEMENT_RENDER_PROLOGUE return html; } @@ -785,15 +785,18 @@ start_element(struct element_info *ei, if (ei->func == html_table && html_context->options->tables && html_context->table_level < HTML_MAX_TABLE_LEVEL) { + ELEMENT_RENDER_PROLOGUE format_table(attr, html, eof, &html, html_context); ln_break(html_context, 2); return html; } if (ei->func == html_select) { + ELEMENT_RENDER_PROLOGUE if (!do_html_select(attr, html, eof, &html, html_context)) return html; } if (ei->func == html_textarea) { + ELEMENT_RENDER_PROLOGUE do_html_textarea(attr, html, eof, &html, html_context); return html; } @@ -860,6 +863,7 @@ start_element(struct element_info *ei, /* We need to have own element in the stack, that's why we waited for * so long. */ if (ei->func == html_script) { + ELEMENT_RENDER_PROLOGUE if (!do_html_script(html_context, attr, html, eof, &html)) return html; } @@ -887,7 +891,11 @@ start_element(struct element_info *ei, done_css_selector(selector); } } + /* Now this was the reason for this whole funny ELEMENT_RENDER_PROLOGUE + * bussiness. Only now we have the definitive linebreak value, since + * that's what the display: property plays with. */ #endif + ELEMENT_RENDER_PROLOGUE if (ei->func) ei->func(html_context, attr); #ifdef CONFIG_CSS if (selector && html_top.options) { @@ -908,6 +916,7 @@ start_element(struct element_info *ei, if (restore_format) par_format = old_format; return html; +#undef ELEMENT_RENDER_PROLOGUE } static unsigned char *