From 3b660a7e3355364f6426e0c4bb061057554cc1cc Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sun, 1 Aug 2004 14:13:47 +0000 Subject: [project @ 2004-08-01 14:13:47 by jmb] Internal representation and parsing of most CSS2 properties. svn path=/import/netsurf/; revision=1172 --- css/css.c | 772 ++++++++++++++++++++++++++++++++++++++++++++---- css/css.h | 236 ++++++++++++++- css/css_enums | 20 +- css/ruleset.c | 926 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1884 insertions(+), 70 deletions(-) (limited to 'css') diff --git a/css/css.c b/css/css.c index 6ff243b18..4cde93f1d 100644 --- a/css/css.c +++ b/css/css.c @@ -103,8 +103,8 @@ static void css_dump_selector(const struct css_selector *r); /** Default style for a document. These are the 'Initial values' from the * spec. */ const struct css_style css_base_style = { - 0xffffff, CSS_BACKGROUND_ATTACHMENT_SCROLL, + 0xffffff, { CSS_BACKGROUND_IMAGE_NONE, 0 }, { { CSS_BACKGROUND_POSITION_PERCENT, { 0.0 } }, { CSS_BACKGROUND_POSITION_PERCENT, { 0.0 } } }, @@ -117,40 +117,76 @@ const struct css_style css_base_style = { { 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE }, { 0x000000, { CSS_BORDER_WIDTH_LENGTH, { 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE } }, + CSS_BORDER_COLLAPSE_SEPARATE, + { CSS_BORDER_SPACING_LENGTH, + { 0, CSS_UNIT_PX }, { 0, CSS_UNIT_PX } }, + { CSS_BOTTOM_AUTO, { { 0, CSS_UNIT_PX } } }, + CSS_CAPTION_SIDE_TOP, CSS_CLEAR_NONE, + { CSS_CLIP_AUTO, { { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } } } }, 0x000000, CSS_CURSOR_AUTO, + CSS_DIRECTION_LTR, CSS_DISPLAY_BLOCK, + CSS_EMPTY_CELLS_SHOW, CSS_FLOAT_NONE, - { CSS_FONT_SIZE_LENGTH, { { 10, CSS_UNIT_PT } } }, CSS_FONT_FAMILY_SANS_SERIF, - CSS_FONT_WEIGHT_NORMAL, + { CSS_FONT_SIZE_LENGTH, { { 10, CSS_UNIT_PT } } }, CSS_FONT_STYLE_NORMAL, CSS_FONT_VARIANT_NORMAL, + CSS_FONT_WEIGHT_NORMAL, { CSS_HEIGHT_AUTO, { 1, CSS_UNIT_EM } }, + { CSS_LEFT_AUTO, { { 0, CSS_UNIT_PX } } }, + { CSS_LETTER_SPACING_NORMAL, { 0, CSS_UNIT_PX } }, { CSS_LINE_HEIGHT_ABSOLUTE, { 1.3 } }, + { CSS_LIST_STYLE_IMAGE_NONE, 0 }, + CSS_LIST_STYLE_POSITION_OUTSIDE, + CSS_LIST_STYLE_TYPE_DISC, { { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } } }, + { CSS_MAX_HEIGHT_NONE, { { 0, CSS_UNIT_PX } } }, + { CSS_MAX_WIDTH_NONE, { { 0, CSS_UNIT_PX } } }, + { CSS_MIN_HEIGHT_LENGTH, { { 0, CSS_UNIT_PX } } }, + { CSS_MIN_WIDTH_LENGTH, { { 0, CSS_UNIT_PX } } }, + { CSS_ORPHANS_INTEGER, 2 }, + { { CSS_OUTLINE_COLOR_INVERT, 0x000000 }, + { CSS_BORDER_WIDTH_LENGTH, { 2, CSS_UNIT_PX } }, + CSS_BORDER_STYLE_NONE }, CSS_OVERFLOW_VISIBLE, { { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } } }, + CSS_PAGE_BREAK_AFTER_AUTO, + CSS_PAGE_BREAK_BEFORE_AUTO, + CSS_PAGE_BREAK_INSIDE_AUTO, + CSS_POSITION_STATIC, + { CSS_RIGHT_AUTO, { { 0, CSS_UNIT_PX } } }, + CSS_TABLE_LAYOUT_AUTO, CSS_TEXT_ALIGN_LEFT, CSS_TEXT_DECORATION_NONE, { CSS_TEXT_INDENT_LENGTH, { { 0, CSS_UNIT_EM } } }, CSS_TEXT_TRANSFORM_NONE, + { CSS_TOP_AUTO, { { 0, CSS_UNIT_PX } } }, + CSS_UNICODE_BIDI_NORMAL, + { CSS_VERTICAL_ALIGN_BASELINE, { { 0, CSS_UNIT_PX } } }, CSS_VISIBILITY_VISIBLE, + CSS_WHITE_SPACE_NORMAL, + { CSS_WIDOWS_INTEGER, 2 }, { CSS_WIDTH_AUTO, { { 1, CSS_UNIT_EM } } }, - CSS_WHITE_SPACE_NORMAL + { CSS_WORD_SPACING_NORMAL, { 0, CSS_UNIT_PX } }, + { CSS_Z_INDEX_AUTO, 0 } }; /** Style with no values set. */ const struct css_style css_empty_style = { - CSS_COLOR_INHERIT, CSS_BACKGROUND_ATTACHMENT_INHERIT, + CSS_COLOR_INHERIT, { CSS_BACKGROUND_IMAGE_INHERIT, 0 }, { { CSS_BACKGROUND_POSITION_INHERIT, { 0.0 } }, { CSS_BACKGROUND_POSITION_INHERIT, { 0.0 } } }, @@ -163,81 +199,153 @@ const struct css_style css_empty_style = { { 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_INHERIT }, { CSS_COLOR_INHERIT, { CSS_BORDER_WIDTH_INHERIT, { 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_INHERIT } }, + CSS_BORDER_COLLAPSE_INHERIT, + { CSS_BORDER_SPACING_INHERIT, + { 0, CSS_UNIT_PX }, { 0, CSS_UNIT_PX } }, + { CSS_BOTTOM_INHERIT, { { 0, CSS_UNIT_PX } } }, + CSS_CAPTION_SIDE_INHERIT, CSS_CLEAR_INHERIT, + { CSS_CLIP_INHERIT, { { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } } } }, CSS_COLOR_INHERIT, CSS_CURSOR_INHERIT, + CSS_DIRECTION_INHERIT, CSS_DISPLAY_INHERIT, + CSS_EMPTY_CELLS_INHERIT, CSS_FLOAT_INHERIT, - { CSS_FONT_SIZE_INHERIT, { { 1, CSS_UNIT_EM } } }, CSS_FONT_FAMILY_INHERIT, - CSS_FONT_WEIGHT_INHERIT, + { CSS_FONT_SIZE_INHERIT, { { 1, CSS_UNIT_PT } } }, CSS_FONT_STYLE_INHERIT, CSS_FONT_VARIANT_INHERIT, + CSS_FONT_WEIGHT_INHERIT, { CSS_HEIGHT_INHERIT, { 1, CSS_UNIT_EM } }, + { CSS_LEFT_INHERIT, { { 0, CSS_UNIT_PX } } }, + { CSS_LETTER_SPACING_INHERIT, { 0, CSS_UNIT_PX } }, { CSS_LINE_HEIGHT_INHERIT, { 1.3 } }, + { CSS_LIST_STYLE_IMAGE_INHERIT, 0 }, + CSS_LIST_STYLE_POSITION_INHERIT, + CSS_LIST_STYLE_TYPE_INHERIT, { { CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_INHERIT, { { 0, CSS_UNIT_PX } } } }, + { CSS_MAX_HEIGHT_INHERIT, { { 0, CSS_UNIT_PX } } }, + { CSS_MAX_WIDTH_INHERIT, { { 0, CSS_UNIT_PX } } }, + { CSS_MIN_HEIGHT_INHERIT, { { 0, CSS_UNIT_PX } } }, + { CSS_MIN_WIDTH_INHERIT, { { 0, CSS_UNIT_PX } } }, + { CSS_ORPHANS_INHERIT, 0 }, + { { CSS_OUTLINE_COLOR_INHERIT, CSS_COLOR_INHERIT }, + { CSS_BORDER_WIDTH_INHERIT, { 0, CSS_UNIT_PX } }, + CSS_BORDER_STYLE_INHERIT }, CSS_OVERFLOW_INHERIT, { { CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_INHERIT, { { 0, CSS_UNIT_PX } } } }, + CSS_PAGE_BREAK_AFTER_INHERIT, + CSS_PAGE_BREAK_BEFORE_INHERIT, + CSS_PAGE_BREAK_INSIDE_INHERIT, + CSS_POSITION_INHERIT, + { CSS_RIGHT_INHERIT, { { 0, CSS_UNIT_PX } } }, + CSS_TABLE_LAYOUT_INHERIT, CSS_TEXT_ALIGN_INHERIT, CSS_TEXT_DECORATION_INHERIT, { CSS_TEXT_INDENT_INHERIT, { { 0, CSS_UNIT_EM } } }, CSS_TEXT_TRANSFORM_INHERIT, + { CSS_TOP_INHERIT, { { 0, CSS_UNIT_PX } } }, + CSS_UNICODE_BIDI_INHERIT, + { CSS_VERTICAL_ALIGN_INHERIT, { { 0, CSS_UNIT_PX } } }, CSS_VISIBILITY_INHERIT, + CSS_WHITE_SPACE_INHERIT, + { CSS_WIDOWS_INHERIT, 0 }, { CSS_WIDTH_INHERIT, { { 1, CSS_UNIT_EM } } }, - CSS_WHITE_SPACE_INHERIT + { CSS_WORD_SPACING_INHERIT, { 0, CSS_UNIT_PX } }, + { CSS_Z_INDEX_INHERIT, 0 } }; /** Default style for an element. These should be INHERIT if 'Inherited' is yes, * and the 'Initial value' otherwise. */ const struct css_style css_blank_style = { - TRANSPARENT, CSS_BACKGROUND_ATTACHMENT_SCROLL, + TRANSPARENT, { CSS_BACKGROUND_IMAGE_NONE, 0 }, { { CSS_BACKGROUND_POSITION_PERCENT, { 0.0 } }, { CSS_BACKGROUND_POSITION_PERCENT, { 0.0 } } }, CSS_BACKGROUND_REPEAT_REPEAT, { { 0x000000, { CSS_BORDER_WIDTH_LENGTH, - { 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE }, + { 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE }, { 0x000000, { CSS_BORDER_WIDTH_LENGTH, - { 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE }, + { 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE }, { 0x000000, { CSS_BORDER_WIDTH_LENGTH, - { 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE }, + { 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE }, { 0x000000, { CSS_BORDER_WIDTH_LENGTH, - { 2, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE } }, + { 0, CSS_UNIT_PX } }, CSS_BORDER_STYLE_NONE } }, + CSS_BORDER_COLLAPSE_INHERIT, + { CSS_BORDER_SPACING_INHERIT, + { 0, CSS_UNIT_PX }, { 0, CSS_UNIT_PX } }, + { CSS_BOTTOM_AUTO, { { 0, CSS_UNIT_PX } } }, + CSS_CAPTION_SIDE_INHERIT, CSS_CLEAR_NONE, + { CSS_CLIP_AUTO, { { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } }, + { CSS_CLIP_RECT_AUTO, { 0, CSS_UNIT_PX } } } }, CSS_COLOR_INHERIT, CSS_CURSOR_INHERIT, + CSS_DIRECTION_INHERIT, CSS_DISPLAY_INLINE, + CSS_EMPTY_CELLS_INHERIT, CSS_FLOAT_NONE, - { CSS_FONT_SIZE_INHERIT, { { 1, CSS_UNIT_EM } } }, CSS_FONT_FAMILY_INHERIT, - CSS_FONT_WEIGHT_INHERIT, + { CSS_FONT_SIZE_INHERIT, { { 1, CSS_UNIT_EM } } }, CSS_FONT_STYLE_INHERIT, CSS_FONT_VARIANT_INHERIT, + CSS_FONT_WEIGHT_INHERIT, { CSS_HEIGHT_AUTO, { 1, CSS_UNIT_EM } }, + { CSS_LEFT_AUTO, { { 0, CSS_UNIT_PX } } }, + { CSS_LETTER_SPACING_INHERIT, { 0, CSS_UNIT_PX } }, { CSS_LINE_HEIGHT_INHERIT, { 1.3 } }, + { CSS_LIST_STYLE_IMAGE_INHERIT, 0 }, + CSS_LIST_STYLE_POSITION_INHERIT, + CSS_LIST_STYLE_TYPE_INHERIT, { { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_MARGIN_LENGTH, { { 0, CSS_UNIT_PX } } } }, + { CSS_MAX_HEIGHT_NONE, { { 0, CSS_UNIT_PX } } }, + { CSS_MAX_WIDTH_NONE, { { 0, CSS_UNIT_PX } } }, + { CSS_MIN_HEIGHT_LENGTH, { { 0, CSS_UNIT_PX } } }, + { CSS_MIN_WIDTH_LENGTH, { { 0, CSS_UNIT_PX } } }, + { CSS_ORPHANS_INHERIT, 0 }, + { { CSS_OUTLINE_COLOR_INVERT, 0x000000 }, + { CSS_BORDER_WIDTH_LENGTH, { 2, CSS_UNIT_PX } }, + CSS_BORDER_STYLE_NONE }, CSS_OVERFLOW_VISIBLE, { { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } }, { CSS_PADDING_LENGTH, { { 0, CSS_UNIT_PX } } } }, + CSS_PAGE_BREAK_AFTER_AUTO, + CSS_PAGE_BREAK_BEFORE_AUTO, + CSS_PAGE_BREAK_INSIDE_INHERIT, + CSS_POSITION_STATIC, + { CSS_RIGHT_AUTO, { { 0, CSS_UNIT_PX } } }, + CSS_TABLE_LAYOUT_AUTO, CSS_TEXT_ALIGN_INHERIT, CSS_TEXT_DECORATION_INHERIT, { CSS_TEXT_INDENT_INHERIT, { { 0, CSS_UNIT_EM } } }, CSS_TEXT_TRANSFORM_INHERIT, + { CSS_TOP_AUTO, { { 0, CSS_UNIT_PX } } }, + CSS_UNICODE_BIDI_NORMAL, + { CSS_VERTICAL_ALIGN_BASELINE, { { 0, CSS_UNIT_PX } } }, CSS_VISIBILITY_INHERIT, + CSS_WHITE_SPACE_INHERIT, + { CSS_WIDOWS_INHERIT, 0 }, { CSS_WIDTH_AUTO, { { 1, CSS_UNIT_EM } } }, - CSS_WHITE_SPACE_INHERIT + { CSS_WORD_SPACING_INHERIT, { 0, CSS_UNIT_PX } }, + { CSS_Z_INDEX_AUTO, 0 } }; @@ -1113,10 +1221,111 @@ void css_dump_style(const struct css_style * const style) } fprintf(stderr, "; "); } + for (i = 0; i != 4; i++) { + if (style->border[i].color != css_empty_style.border[i].color || + style->border[i].width.width != css_empty_style.border[i].width.width || + style->border[i].style != css_empty_style.border[i].style) { + fprintf(stderr, "border-"); + switch (i) { + case TOP: + fprintf(stderr, "top: "); + break; + case RIGHT: + fprintf(stderr, "right: "); + break; + case BOTTOM: + fprintf(stderr, "bottom: "); + break; + case LEFT: + fprintf(stderr, "left: "); + break; + } + switch (style->border[i].width.width) { + case CSS_BORDER_WIDTH_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_BORDER_WIDTH_LENGTH: + css_dump_length(&style->border[i].width.value); + break; + default: + fprintf(stderr, "UNKNOWN"); + break; + } + fprintf(stderr, " %s", + css_border_style_name[style->border[i].style]); + + if (style->border[i].color == TRANSPARENT) + fprintf(stderr, " transparent; "); + else if (style->border[i].color == CSS_COLOR_NONE) + fprintf(stderr, " none; "); + else if (style->border[i].color == CSS_COLOR_INHERIT) + fprintf(stderr, " inherit; "); + else + fprintf(stderr, " #%.6lx; ", style->border[i].color); + } + } + DUMP_KEYWORD(border_collapse, "border-collapse", css_border_collapse_name); + if (style->border_spacing.border_spacing != css_empty_style.border_spacing.border_spacing) { + fprintf(stderr, "border-spacing: "); + css_dump_length(&style->border_spacing.horz); + css_dump_length(&style->border_spacing.vert); + fprintf(stderr, "; "); + } + if (style->bottom.bottom != css_empty_style.bottom.bottom) { + fprintf(stderr, "bottom: "); + switch (style->bottom.bottom) { + case CSS_BOTTOM_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_BOTTOM_AUTO: + fprintf(stderr, "auto"); + break; + case CSS_BOTTOM_PERCENT: + fprintf(stderr, "%g%%", + style->bottom.value.percent); + break; + case CSS_BOTTOM_LENGTH: + css_dump_length(&style->bottom.value.length); + break; + } + fprintf(stderr, "; "); + } + DUMP_KEYWORD(caption_side, "caption-side", css_caption_side_name); DUMP_KEYWORD(clear, "clear", css_clear_name); + + if (style->clip.clip != css_empty_style.clip.clip) { + fprintf(stderr, "clip: "); + switch (style->clip.clip) { + case CSS_CLIP_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_CLIP_AUTO: + fprintf(stderr, "auto"); + break; + case CSS_CLIP_RECT: + fprintf(stderr, "rect("); + for (i = 0; i != 4; i++) { + switch (style->clip.rect[i].rect) { + case CSS_CLIP_RECT_AUTO: + fprintf(stderr, "auto"); + break; + case CSS_CLIP_RECT_LENGTH: + css_dump_length(&style->clip.rect[i].value); + break; + } + if (i != 3) + fprintf(stderr, ", "); + } + fprintf(stderr, ")"); + break; + } + fprintf(stderr, "; "); + } DUMP_COLOR(color, "color"); DUMP_KEYWORD(cursor, "cursor", css_cursor_name); + DUMP_KEYWORD(direction, "direction", css_direction_name); DUMP_KEYWORD(display, "display", css_display_name); + DUMP_KEYWORD(empty_cells, "empty-cells", css_empty_cells_name); DUMP_KEYWORD(float_, "float", css_float_name); if (style->font_style != css_empty_style.font_style || @@ -1189,6 +1398,63 @@ void css_dump_style(const struct css_style * const style) fprintf(stderr, "; "); } + if (style->left.left != css_empty_style.left.left) { + fprintf(stderr, "left: "); + switch (style->left.left) { + case CSS_LEFT_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_LEFT_AUTO: + fprintf(stderr, "auto"); + break; + case CSS_LEFT_PERCENT: + fprintf(stderr, "%g%%", + style->left.value.percent); + break; + case CSS_LEFT_LENGTH: + css_dump_length(&style->left.value.length); + break; + } + fprintf(stderr, "; "); + } + + if (style->letter_spacing.letter_spacing != css_empty_style.letter_spacing.letter_spacing) { + fprintf(stderr, "letter-spacing: "); + switch (style->letter_spacing.letter_spacing) { + case CSS_LETTER_SPACING_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_LETTER_SPACING_NORMAL: + fprintf(stderr, "normal"); + break; + case CSS_LETTER_SPACING_LENGTH: + css_dump_length(&style->letter_spacing.length); + break; + } + fprintf(stderr, "; "); + } + + if (style->list_style_type != css_empty_style.list_style_type || + style->list_style_position != css_empty_style.list_style_position || + style->list_style_image.type != css_empty_style.list_style_image.type) { + fprintf(stderr, "list-style: %s %s", + css_list_style_type_name[style->list_style_type], + css_list_style_position_name[style->list_style_position]); + switch (style->list_style_image.type) { + case CSS_LIST_STYLE_IMAGE_INHERIT: + fprintf(stderr, " inherit"); + break; + case CSS_LIST_STYLE_IMAGE_NONE: + fprintf(stderr, " none"); + break; + case CSS_LIST_STYLE_IMAGE_URI: + fprintf(stderr, " url('%s')", + style->list_style_image.uri); + break; + } + fprintf(stderr, "; "); + } + if (style->margin[0].margin != css_empty_style.margin[0].margin || style->margin[1].margin != css_empty_style.margin[1].margin || style->margin[2].margin != css_empty_style.margin[2].margin || @@ -1218,6 +1484,130 @@ void css_dump_style(const struct css_style * const style) fprintf(stderr, "; "); } + if (style->max_height.max_height != css_empty_style.max_height.max_height) { + fprintf(stderr, "max-height: "); + switch (style->max_height.max_height) { + case CSS_MAX_HEIGHT_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_MAX_HEIGHT_NONE: + fprintf(stderr, "none"); + case CSS_MAX_HEIGHT_LENGTH: + css_dump_length(&style->max_height.value.length); + break; + case CSS_MAX_HEIGHT_PERCENT: + fprintf(stderr, "%g%%", + style->max_height.value.percent); + break; + } + fprintf(stderr, "; "); + } + + if (style->max_width.max_width != css_empty_style.max_width.max_width) { + fprintf(stderr, "max-width: "); + switch (style->max_width.max_width) { + case CSS_MAX_WIDTH_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_MAX_WIDTH_NONE: + fprintf(stderr, "none"); + case CSS_MAX_WIDTH_LENGTH: + css_dump_length(&style->max_width.value.length); + break; + case CSS_MAX_WIDTH_PERCENT: + fprintf(stderr, "%g%%", + style->max_width.value.percent); + break; + } + fprintf(stderr, "; "); + } + + if (style->min_height.min_height != css_empty_style.min_height.min_height) { + fprintf(stderr, "min-height: "); + switch (style->min_height.min_height) { + case CSS_MIN_HEIGHT_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_MIN_HEIGHT_LENGTH: + css_dump_length(&style->min_height.value.length); + break; + case CSS_MIN_HEIGHT_PERCENT: + fprintf(stderr, "%g%%", + style->min_height.value.percent); + break; + } + fprintf(stderr, "; "); + } + + if (style->min_width.min_width != css_empty_style.min_width.min_width) { + fprintf(stderr, "min-width: "); + switch (style->min_width.min_width) { + case CSS_MIN_WIDTH_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_MIN_WIDTH_LENGTH: + css_dump_length(&style->min_width.value.length); + break; + case CSS_MIN_WIDTH_PERCENT: + fprintf(stderr, "%g%%", + style->min_width.value.percent); + break; + } + fprintf(stderr, "; "); + } + + if (style->orphans.orphans != css_empty_style.orphans.orphans) { + fprintf(stderr, "orphans: "); + switch (style->orphans.orphans) { + case CSS_ORPHANS_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_ORPHANS_INTEGER: + fprintf(stderr, "%d", + style->orphans.value); + break; + } + fprintf(stderr, "; "); + } + + if (style->outline.color.color != css_empty_style.outline.color.color || + style->outline.width.width != css_empty_style.outline.width.width || + style->outline.style != css_empty_style.outline.style) { + fprintf(stderr, "outline: "); + switch (style->outline.color.color) { + case CSS_OUTLINE_COLOR_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_OUTLINE_COLOR_INVERT: + fprintf(stderr, "invert"); + break; + case CSS_OUTLINE_COLOR_COLOR: + if (style->outline.color.value == TRANSPARENT) + fprintf(stderr, "transparent"); + else if (style->outline.color.value == CSS_COLOR_NONE) + fprintf(stderr, "none"); + else if (style->outline.color.value == CSS_COLOR_INHERIT) + fprintf(stderr, "inherit"); + else + fprintf(stderr, "#%.6lx", style->outline.color.value); + break; + } + fprintf(stderr, " %s ", + css_border_style_name[style->outline.style]); + switch (style->outline.width.width) { + case CSS_BORDER_WIDTH_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_BORDER_WIDTH_LENGTH: + css_dump_length(&style->outline.width.value); + break; + default: + fprintf(stderr, "UNKNOWN"); + break; + } + fprintf(stderr, "; "); + } + DUMP_KEYWORD(overflow, "overflow", css_overflow_name); if (style->padding[0].padding != css_empty_style.padding[0].padding || @@ -1246,6 +1636,32 @@ void css_dump_style(const struct css_style * const style) fprintf(stderr, "; "); } + DUMP_KEYWORD(page_break_after, "page-break-after", css_page_break_after_name); + DUMP_KEYWORD(page_break_before, "page-break-before", css_page_break_before_name); + DUMP_KEYWORD(page_break_inside, "page-break-inside", css_page_break_inside_name); + DUMP_KEYWORD(position, "position", css_position_name); + + if (style->right.right != css_empty_style.right.right) { + fprintf(stderr, "right: "); + switch (style->right.right) { + case CSS_RIGHT_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_RIGHT_AUTO: + fprintf(stderr, "auto"); + break; + case CSS_RIGHT_PERCENT: + fprintf(stderr, "%g%%", + style->right.value.percent); + break; + case CSS_RIGHT_LENGTH: + css_dump_length(&style->right.value.length); + break; + } + fprintf(stderr, "; "); + } + + DUMP_KEYWORD(table_layout, "table-layout", css_table_layout_name); DUMP_KEYWORD(text_align, "text-align", css_text_align_name); if (style->text_decoration != css_empty_style.text_decoration) { @@ -1286,7 +1702,86 @@ void css_dump_style(const struct css_style * const style) } DUMP_KEYWORD(text_transform, "text-transform", css_text_transform_name); + + if (style->top.top != css_empty_style.top.top) { + fprintf(stderr, "top: "); + switch (style->top.top) { + case CSS_TOP_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_TOP_AUTO: + fprintf(stderr, "auto"); + break; + case CSS_TOP_PERCENT: + fprintf(stderr, "%g%%", + style->top.value.percent); + break; + case CSS_TOP_LENGTH: + css_dump_length(&style->top.value.length); + break; + } + fprintf(stderr, "; "); + } + + DUMP_KEYWORD(unicode_bidi, "unicode-bidi", css_unicode_bidi_name); + + if (style->vertical_align.type != css_empty_style.vertical_align.type) { + fprintf(stderr, "vertical-align: "); + switch (style->vertical_align.type) { + case CSS_VERTICAL_ALIGN_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_VERTICAL_ALIGN_BASELINE: + fprintf(stderr, "baseline"); + break; + case CSS_VERTICAL_ALIGN_SUB: + fprintf(stderr, "sub"); + break; + case CSS_VERTICAL_ALIGN_SUPER: + fprintf(stderr, "super"); + break; + case CSS_VERTICAL_ALIGN_TOP: + fprintf(stderr, "top"); + break; + case CSS_VERTICAL_ALIGN_TEXT_TOP: + fprintf(stderr, "text-top"); + break; + case CSS_VERTICAL_ALIGN_MIDDLE: + fprintf(stderr, "middle"); + break; + case CSS_VERTICAL_ALIGN_BOTTOM: + fprintf(stderr, "bottom"); + break; + case CSS_VERTICAL_ALIGN_TEXT_BOTTOM: + fprintf(stderr, "text-bottom"); + break; + case CSS_VERTICAL_ALIGN_LENGTH: + css_dump_length(&style->vertical_align.value.length); + break; + case CSS_VERTICAL_ALIGN_PERCENT: + fprintf(stderr, "%g%%", + style->vertical_align.value.percent); + break; + } + fprintf(stderr, "; "); + } + DUMP_KEYWORD(visibility, "visibility", css_visibility_name); + DUMP_KEYWORD(white_space, "white-space", css_white_space_name); + + if (style->widows.widows != css_empty_style.widows.widows) { + fprintf(stderr, "widows: "); + switch (style->widows.widows) { + case CSS_WIDOWS_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_WIDOWS_INTEGER: + fprintf(stderr, "%d", + style->widows.value); + break; + } + fprintf(stderr, "; "); + } if (style->width.width != css_empty_style.width.width) { fprintf(stderr, "width: "); @@ -1311,7 +1806,38 @@ void css_dump_style(const struct css_style * const style) fprintf(stderr, "; "); } - DUMP_KEYWORD(white_space, "white-space", css_white_space_name); + if (style->word_spacing.word_spacing != css_empty_style.word_spacing.word_spacing) { + fprintf(stderr, "word-spacing: "); + switch (style->word_spacing.word_spacing) { + case CSS_WORD_SPACING_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_WORD_SPACING_NORMAL: + fprintf(stderr, "normal"); + break; + case CSS_WORD_SPACING_LENGTH: + css_dump_length(&style->word_spacing.length); + break; + } + fprintf(stderr, "; "); + } + + if (style->z_index.z_index != css_empty_style.z_index.z_index) { + fprintf(stderr, "z-index: "); + switch (style->z_index.z_index) { + case CSS_Z_INDEX_INHERIT: + fprintf(stderr, "inherit"); + break; + case CSS_Z_INDEX_AUTO: + fprintf(stderr, "auto"); + break; + case CSS_Z_INDEX_INTEGER: + fprintf(stderr, "%d", + style->z_index.value); + break; + } + fprintf(stderr, "; "); + } fprintf(stderr, "}"); } @@ -1442,63 +1968,126 @@ void css_cascade(struct css_style * const style, unsigned int i; float f; - /* text-decoration: approximate CSS 2.1 by inheriting into inline elements */ - if (apply->text_decoration != CSS_TEXT_DECORATION_INHERIT) - style->text_decoration = apply->text_decoration; -/* if (style->display == CSS_DISPLAY_INLINE && apply->display != CSS_DISPLAY_INLINE) - style->text_decoration = CSS_TEXT_DECORATION_NONE;*/ - if (apply->background_attachment != CSS_BACKGROUND_ATTACHMENT_INHERIT) - style->background_attachment = apply->background_attachment; + if (apply->background_attachment != CSS_BACKGROUND_ATTACHMENT_INHERIT) + style->background_attachment = apply->background_attachment; if (apply->background_color != CSS_COLOR_INHERIT) style->background_color = apply->background_color; if (apply->background_image.type != CSS_BACKGROUND_IMAGE_INHERIT) style->background_image = apply->background_image; if (apply->background_repeat != CSS_BACKGROUND_REPEAT_INHERIT) style->background_repeat = apply->background_repeat; + if (apply->border_collapse != CSS_BORDER_COLLAPSE_INHERIT) + style->border_collapse = apply->border_collapse; + if (apply->border_spacing.border_spacing != CSS_BORDER_SPACING_INHERIT) + style->border_spacing = apply->border_spacing; + if (apply->bottom.bottom != CSS_BOTTOM_INHERIT) + style->bottom = apply->bottom; + if (apply->caption_side != CSS_CAPTION_SIDE_INHERIT) + style->caption_side = apply->caption_side; if (apply->clear != CSS_CLEAR_INHERIT) style->clear = apply->clear; if (apply->color != CSS_COLOR_INHERIT) style->color = apply->color; if (apply->cursor != CSS_CURSOR_INHERIT) style->cursor = apply->cursor; + if (apply->direction != CSS_DIRECTION_INHERIT) + style->direction = apply->direction; if (apply->display != CSS_DISPLAY_INHERIT) style->display = apply->display; + if (apply->empty_cells != CSS_EMPTY_CELLS_INHERIT) + style->empty_cells = apply->empty_cells; if (apply->float_ != CSS_FLOAT_INHERIT) style->float_ = apply->float_; if (apply->font_family != CSS_FONT_FAMILY_INHERIT) - style->font_family = apply->font_family; + style->font_family = apply->font_family; if (apply->font_style != CSS_FONT_STYLE_INHERIT) style->font_style = apply->font_style; + if (apply->font_variant != CSS_FONT_VARIANT_INHERIT) + style->font_variant = apply->font_variant; if (apply->font_weight != CSS_FONT_WEIGHT_INHERIT) style->font_weight = apply->font_weight; - if (apply->font_variant != CSS_FONT_VARIANT_INHERIT) - style->font_variant = apply->font_variant; if (apply->height.height != CSS_HEIGHT_INHERIT) style->height = apply->height; + if (apply->left.left != CSS_LEFT_INHERIT) + style->left = apply->left; + if (apply->letter_spacing.letter_spacing != CSS_LETTER_SPACING_INHERIT) + style->letter_spacing = apply->letter_spacing; if (apply->line_height.size != CSS_LINE_HEIGHT_INHERIT) style->line_height = apply->line_height; + if (apply->list_style_image.type != CSS_LIST_STYLE_IMAGE_INHERIT) + style->list_style_image = apply->list_style_image; + if (apply->list_style_position != CSS_LIST_STYLE_POSITION_INHERIT) + style->list_style_position = apply->list_style_position; + if (apply->list_style_type != CSS_LIST_STYLE_TYPE_INHERIT) + style->list_style_type = apply->list_style_type; + if (apply->max_height.max_height != CSS_MAX_HEIGHT_INHERIT) + style->max_height = apply->max_height; + if (apply->max_width.max_width != CSS_MAX_WIDTH_INHERIT) + style->max_width = apply->max_width; + if (apply->min_height.min_height != CSS_MIN_HEIGHT_INHERIT) + style->min_height = apply->min_height; + if (apply->min_width.min_width != CSS_MIN_WIDTH_INHERIT) + style->min_width = apply->min_width; + if (apply->orphans.orphans != CSS_ORPHANS_INHERIT) + style->orphans = apply->orphans; if (apply->overflow != CSS_OVERFLOW_INHERIT) style->overflow = apply->overflow; + if (apply->page_break_after != CSS_PAGE_BREAK_AFTER_INHERIT) + style->page_break_after = apply->page_break_after; + if (apply->page_break_before != CSS_PAGE_BREAK_BEFORE_INHERIT) + style->page_break_before = apply->page_break_before; + if (apply->page_break_inside != CSS_PAGE_BREAK_INSIDE_INHERIT) + style->page_break_inside = apply->page_break_inside; + if (apply->position != CSS_POSITION_INHERIT) + style->position = apply->position; + if (apply->right.right != CSS_RIGHT_INHERIT) + style->right = apply->right; + if (apply->table_layout != CSS_TABLE_LAYOUT_INHERIT) + style->table_layout = apply->table_layout; if (apply->text_align != CSS_TEXT_ALIGN_INHERIT) style->text_align = apply->text_align; + /* text-decoration: approximate CSS 2.1 by inheriting into inline elements */ + if (apply->text_decoration != CSS_TEXT_DECORATION_INHERIT) + style->text_decoration = apply->text_decoration; if (apply->text_indent.size != CSS_TEXT_INDENT_INHERIT) - style->text_indent = apply->text_indent; + style->text_indent = apply->text_indent; if (apply->text_transform != CSS_TEXT_TRANSFORM_INHERIT) style->text_transform = apply->text_transform; + if (apply->top.top != CSS_TOP_INHERIT) + style->top = apply->top; + if (apply->unicode_bidi != CSS_UNICODE_BIDI_INHERIT) + style->unicode_bidi = apply->unicode_bidi; + if (apply->vertical_align.type != CSS_VERTICAL_ALIGN_INHERIT) + style->vertical_align = apply->vertical_align; if (apply->visibility != CSS_VISIBILITY_INHERIT) style->visibility = apply->visibility; - if (apply->width.width != CSS_WIDTH_INHERIT) - style->width = apply->width; if (apply->white_space != CSS_WHITE_SPACE_INHERIT) style->white_space = apply->white_space; + if (apply->widows.widows != CSS_WIDOWS_INHERIT) + style->widows = apply->widows; + if (apply->width.width != CSS_WIDTH_INHERIT) + style->width = apply->width; + if (apply->word_spacing.word_spacing != CSS_WORD_SPACING_INHERIT) + style->word_spacing = apply->word_spacing; + if (apply->z_index.z_index != CSS_Z_INDEX_INHERIT) + style->z_index = apply->z_index; + + + /* clip */ + if (apply->clip.clip != CSS_CLIP_INHERIT) { + for (i = 0; i != 4; i++) { + style->clip.rect[i] = apply->clip.rect[i]; + } + } + /* background-position */ - if (apply->background_position.horz.pos != CSS_BACKGROUND_POSITION_INHERIT) { - style->background_position.horz = apply->background_position.horz; - } - if (apply->background_position.vert.pos != CSS_BACKGROUND_POSITION_INHERIT) { - style->background_position.vert = apply->background_position.vert; - } + if (apply->background_position.horz.pos != CSS_BACKGROUND_POSITION_INHERIT) { + style->background_position.horz = apply->background_position.horz; + } + if (apply->background_position.vert.pos != CSS_BACKGROUND_POSITION_INHERIT) { + style->background_position.vert = apply->background_position.vert; + } /* font-size */ f = apply->font_size.value.percent / 100; @@ -1538,6 +2127,15 @@ void css_cascade(struct css_style * const style, break; } + /* outline */ + if (apply->outline.color.color != CSS_OUTLINE_COLOR_INHERIT) + style->outline.color = apply->outline.color; + if (apply->outline.width.width != CSS_BORDER_WIDTH_INHERIT) + style->outline.width = apply->outline.width; + if (apply->outline.style != CSS_BORDER_STYLE_INHERIT) + style->outline.style = apply->outline.style; + + /* borders, margins and padding */ for (i = 0; i != 4; i++) { if (apply->border[i].color != CSS_COLOR_INHERIT) style->border[i].color = apply->border[i].color; @@ -1570,63 +2168,137 @@ void css_merge(struct css_style * const style, { unsigned int i; - if (apply->background_attachment != CSS_BACKGROUND_ATTACHMENT_INHERIT) - style->background_attachment = apply->background_attachment; + if (apply->background_attachment != CSS_BACKGROUND_ATTACHMENT_INHERIT) + style->background_attachment = apply->background_attachment; if (apply->background_color != CSS_COLOR_INHERIT) style->background_color = apply->background_color; if (apply->background_image.type != CSS_BACKGROUND_IMAGE_INHERIT) style->background_image = apply->background_image; if (apply->background_repeat != CSS_BACKGROUND_REPEAT_INHERIT) style->background_repeat = apply->background_repeat; + if (apply->border_collapse != CSS_BORDER_COLLAPSE_INHERIT) + style->border_collapse = apply->border_collapse; + if (apply->border_spacing.border_spacing != CSS_BORDER_SPACING_INHERIT) + style->border_spacing = apply->border_spacing; + if (apply->bottom.bottom != CSS_BOTTOM_INHERIT) + style->bottom = apply->bottom; + if (apply->caption_side != CSS_CAPTION_SIDE_INHERIT) + style->caption_side = apply->caption_side; if (apply->clear != CSS_CLEAR_INHERIT) style->clear = apply->clear; if (apply->color != CSS_COLOR_INHERIT) style->color = apply->color; if (apply->cursor != CSS_CURSOR_INHERIT) style->cursor = apply->cursor; + if (apply->direction != CSS_DIRECTION_INHERIT) + style->direction = apply->direction; if (apply->display != CSS_DISPLAY_INHERIT) style->display = apply->display; + if (apply->empty_cells != CSS_EMPTY_CELLS_INHERIT) + style->empty_cells = apply->empty_cells; if (apply->float_ != CSS_FLOAT_INHERIT) style->float_ = apply->float_; if (apply->font_family != CSS_FONT_FAMILY_INHERIT) - style->font_family = apply->font_family; + style->font_family = apply->font_family; if (apply->font_size.size != CSS_FONT_SIZE_INHERIT) style->font_size = apply->font_size; if (apply->font_style != CSS_FONT_STYLE_INHERIT) style->font_style = apply->font_style; - if (apply->font_weight != CSS_FONT_WEIGHT_INHERIT) - style->font_weight = apply->font_weight; if (apply->font_variant != CSS_FONT_VARIANT_INHERIT) style->font_variant = apply->font_variant; + if (apply->font_weight != CSS_FONT_WEIGHT_INHERIT) + style->font_weight = apply->font_weight; if (apply->height.height != CSS_HEIGHT_INHERIT) style->height = apply->height; + if (apply->left.left != CSS_LEFT_INHERIT) + style->left = apply->left; + if (apply->letter_spacing.letter_spacing != CSS_LETTER_SPACING_INHERIT) + style->letter_spacing = apply->letter_spacing; if (apply->line_height.size != CSS_LINE_HEIGHT_INHERIT) style->line_height = apply->line_height; + if (apply->list_style_image.type != CSS_LIST_STYLE_IMAGE_INHERIT) + style->list_style_image = apply->list_style_image; + if (apply->list_style_position != CSS_LIST_STYLE_POSITION_INHERIT) + style->list_style_position = apply->list_style_position; + if (apply->list_style_type != CSS_LIST_STYLE_TYPE_INHERIT) + style->list_style_type = apply->list_style_type; + if (apply->max_height.max_height != CSS_MAX_HEIGHT_INHERIT) + style->max_height = apply->max_height; + if (apply->max_width.max_width != CSS_MAX_WIDTH_INHERIT) + style->max_width = apply->max_width; + if (apply->min_height.min_height != CSS_MIN_HEIGHT_INHERIT) + style->min_height = apply->min_height; + if (apply->min_width.min_width != CSS_MIN_WIDTH_INHERIT) + style->min_width = apply->min_width; + if (apply->orphans.orphans != CSS_ORPHANS_INHERIT) + style->orphans = apply->orphans; if (apply->overflow != CSS_OVERFLOW_INHERIT) style->overflow = apply->overflow; + if (apply->page_break_after != CSS_PAGE_BREAK_AFTER_INHERIT) + style->page_break_after = apply->page_break_after; + if (apply->page_break_before != CSS_PAGE_BREAK_BEFORE_INHERIT) + style->page_break_before = apply->page_break_before; + if (apply->page_break_inside != CSS_PAGE_BREAK_INSIDE_INHERIT) + style->page_break_inside = apply->page_break_inside; + if (apply->position != CSS_POSITION_INHERIT) + style->position = apply->position; + if (apply->right.right != CSS_RIGHT_INHERIT) + style->right = apply->right; + if (apply->table_layout != CSS_TABLE_LAYOUT_INHERIT) + style->table_layout = apply->table_layout; if (apply->text_align != CSS_TEXT_ALIGN_INHERIT) style->text_align = apply->text_align; + /* text-decoration: approximate CSS 2.1 by inheriting into inline elements */ if (apply->text_decoration != CSS_TEXT_DECORATION_INHERIT) style->text_decoration = apply->text_decoration; if (apply->text_indent.size != CSS_TEXT_INDENT_INHERIT) - style->text_indent = apply->text_indent; + style->text_indent = apply->text_indent; if (apply->text_transform != CSS_TEXT_TRANSFORM_INHERIT) style->text_transform = apply->text_transform; + if (apply->top.top != CSS_TOP_INHERIT) + style->top = apply->top; + if (apply->unicode_bidi != CSS_UNICODE_BIDI_INHERIT) + style->unicode_bidi = apply->unicode_bidi; + if (apply->vertical_align.type != CSS_VERTICAL_ALIGN_INHERIT) + style->vertical_align = apply->vertical_align; if (apply->visibility != CSS_VISIBILITY_INHERIT) style->visibility = apply->visibility; - if (apply->width.width != CSS_WIDTH_INHERIT) - style->width = apply->width; if (apply->white_space != CSS_WHITE_SPACE_INHERIT) style->white_space = apply->white_space; + if (apply->widows.widows != CSS_WIDOWS_INHERIT) + style->widows = apply->widows; + if (apply->width.width != CSS_WIDTH_INHERIT) + style->width = apply->width; + if (apply->word_spacing.word_spacing != CSS_WORD_SPACING_INHERIT) + style->word_spacing = apply->word_spacing; + if (apply->z_index.z_index != CSS_Z_INDEX_INHERIT) + style->z_index = apply->z_index; + + + /* clip */ + if (apply->clip.clip != CSS_CLIP_INHERIT) { + for (i = 0; i != 4; i++) { + style->clip.rect[i] = apply->clip.rect[i]; + } + } /* background-position */ - if (apply->background_position.horz.pos != CSS_BACKGROUND_POSITION_INHERIT) { - style->background_position.horz = apply->background_position.horz; - } - if (apply->background_position.vert.pos != CSS_BACKGROUND_POSITION_INHERIT) { - style->background_position.vert = apply->background_position.vert; - } + if (apply->background_position.horz.pos != CSS_BACKGROUND_POSITION_INHERIT) { + style->background_position.horz = apply->background_position.horz; + } + if (apply->background_position.vert.pos != CSS_BACKGROUND_POSITION_INHERIT) { + style->background_position.vert = apply->background_position.vert; + } + + /* outline */ + if (apply->outline.color.color != CSS_OUTLINE_COLOR_INHERIT) + style->outline.color = apply->outline.color; + if (apply->outline.width.width != CSS_BORDER_WIDTH_INHERIT) + style->outline.width = apply->outline.width; + if (apply->outline.style != CSS_BORDER_STYLE_INHERIT) + style->outline.style = apply->outline.style; + /* borders, margins and padding */ for (i = 0; i != 4; i++) { if (apply->border[i].color != CSS_COLOR_INHERIT) style->border[i].color = apply->border[i].color; diff --git a/css/css.h b/css/css.h index 5a8af7ca1..63c311a30 100644 --- a/css/css.h +++ b/css/css.h @@ -72,41 +72,105 @@ struct css_background_position { } value; }; +struct css_border_width { + enum { CSS_BORDER_WIDTH_INHERIT, + CSS_BORDER_WIDTH_LENGTH } width; + struct css_length value; +}; + +typedef enum { + CSS_LIST_STYLE_IMAGE_INHERIT, + CSS_LIST_STYLE_IMAGE_NONE, + CSS_LIST_STYLE_IMAGE_URI +} css_list_style_image_type; + +typedef enum { + CSS_OUTLINE_COLOR_INHERIT, + CSS_OUTLINE_COLOR_COLOR, + CSS_OUTLINE_COLOR_INVERT +} css_outline_color_type; + +typedef enum { + CSS_VERTICAL_ALIGN_INHERIT, + CSS_VERTICAL_ALIGN_BASELINE, + CSS_VERTICAL_ALIGN_SUB, + CSS_VERTICAL_ALIGN_SUPER, + CSS_VERTICAL_ALIGN_TOP, + CSS_VERTICAL_ALIGN_TEXT_TOP, + CSS_VERTICAL_ALIGN_MIDDLE, + CSS_VERTICAL_ALIGN_BOTTOM, + CSS_VERTICAL_ALIGN_TEXT_BOTTOM, + CSS_VERTICAL_ALIGN_LENGTH, + CSS_VERTICAL_ALIGN_PERCENT +} css_vertical_align_type; + /** Representation of a complete CSS 2 style. */ struct css_style { - colour background_color; - + /* background properties */ css_background_attachment background_attachment; - + colour background_color; struct { css_background_image_type type; char *uri; } background_image; - struct { struct css_background_position horz; struct css_background_position vert; } background_position; - css_background_repeat background_repeat; + /* borders */ struct { colour color; - struct { - enum { CSS_BORDER_WIDTH_INHERIT, - CSS_BORDER_WIDTH_LENGTH } width; - struct css_length value; - } width; + struct css_border_width width; css_border_style style; } border[4]; /**< top, right, bottom, left */ + css_border_collapse border_collapse; + struct { + enum { CSS_BORDER_SPACING_INHERIT, + CSS_BORDER_SPACING_LENGTH } border_spacing; + struct css_length horz; + struct css_length vert; + } border_spacing; + struct { + enum { CSS_BOTTOM_INHERIT, + CSS_BOTTOM_AUTO, + CSS_BOTTOM_PERCENT, + CSS_BOTTOM_LENGTH } bottom; + union { + struct css_length length; + float percent; + } value; + } bottom; + + css_caption_side caption_side; css_clear clear; + + struct { + enum { CSS_CLIP_INHERIT, + CSS_CLIP_AUTO, + CSS_CLIP_RECT } clip; + struct { + enum { CSS_CLIP_RECT_AUTO, + CSS_CLIP_RECT_LENGTH } rect; + struct css_length value; + } rect[4]; /**< top, right, bottom, left */ + } clip; + colour color; + + /** \todo content and counters */ + css_cursor cursor; + css_direction direction; css_display display; + css_empty_cells empty_cells; css_float float_; + /* font properties */ + css_font_family font_family; struct { enum { CSS_FONT_SIZE_INHERIT, CSS_FONT_SIZE_ABSOLUTE, @@ -118,11 +182,9 @@ struct css_style { float percent; } value; } font_size; - - css_font_family font_family; - css_font_weight font_weight; css_font_style font_style; css_font_variant font_variant; + css_font_weight font_weight; struct { enum { CSS_HEIGHT_INHERIT, @@ -131,6 +193,24 @@ struct css_style { struct css_length length; } height; + struct { + enum { CSS_LEFT_INHERIT, + CSS_LEFT_AUTO, + CSS_LEFT_PERCENT, + CSS_LEFT_LENGTH } left; + union { + struct css_length length; + float percent; + } value; + } left; + + struct { + enum { CSS_LETTER_SPACING_INHERIT, + CSS_LETTER_SPACING_NORMAL, + CSS_LETTER_SPACING_LENGTH } letter_spacing; + struct css_length length; + } letter_spacing; + struct { enum { CSS_LINE_HEIGHT_INHERIT, CSS_LINE_HEIGHT_ABSOLUTE, @@ -143,6 +223,15 @@ struct css_style { } value; } line_height; + /* list properties */ + struct { + css_list_style_image_type type; + char *uri; + } list_style_image; + css_list_style_position list_style_position; + css_list_style_type list_style_type; + + /* margins */ struct { enum { CSS_MARGIN_INHERIT, CSS_MARGIN_LENGTH, @@ -154,8 +243,64 @@ struct css_style { } value; } margin[4]; /**< top, right, bottom, left */ + /* min/max width/height */ + struct { + enum { CSS_MAX_HEIGHT_INHERIT, + CSS_MAX_HEIGHT_NONE, + CSS_MAX_HEIGHT_LENGTH, + CSS_MAX_HEIGHT_PERCENT } max_height; + union { + struct css_length length; + float percent; + } value; + } max_height; + struct { + enum { CSS_MAX_WIDTH_INHERIT, + CSS_MAX_WIDTH_NONE, + CSS_MAX_WIDTH_LENGTH, + CSS_MAX_WIDTH_PERCENT } max_width; + union { + struct css_length length; + float percent; + } value; + } max_width; + struct { + enum { CSS_MIN_HEIGHT_INHERIT, + CSS_MIN_HEIGHT_LENGTH, + CSS_MIN_HEIGHT_PERCENT } min_height; + union { + struct css_length length; + float percent; + } value; + } min_height; + struct { + enum { CSS_MIN_WIDTH_INHERIT, + CSS_MIN_WIDTH_LENGTH, + CSS_MIN_WIDTH_PERCENT } min_width; + union { + struct css_length length; + float percent; + } value; + } min_width; + + struct { + enum { CSS_ORPHANS_INHERIT, + CSS_ORPHANS_INTEGER } orphans; + int value; + } orphans; + + struct { + struct { + css_outline_color_type color; + colour value; + } color; + struct css_border_width width; + css_border_style style; + } outline; + css_overflow overflow; + /* padding */ struct { enum { CSS_PADDING_INHERIT, CSS_PADDING_LENGTH, @@ -166,6 +311,28 @@ struct css_style { } value; } padding[4]; /**< top, right, bottom, left */ + css_page_break_after page_break_after; + css_page_break_before page_break_before; + css_page_break_inside page_break_inside; + + css_position position; + + /** \todo quotes */ + + struct { + enum { CSS_RIGHT_INHERIT, + CSS_RIGHT_AUTO, + CSS_RIGHT_PERCENT, + CSS_RIGHT_LENGTH } right; + union { + struct css_length length; + float percent; + } value; + } right; + + css_table_layout table_layout; + + /* text properties */ css_text_align text_align; css_text_decoration text_decoration; struct { @@ -179,8 +346,37 @@ struct css_style { } text_indent; css_text_transform text_transform; + struct { + enum { CSS_TOP_INHERIT, + CSS_TOP_AUTO, + CSS_TOP_PERCENT, + CSS_TOP_LENGTH } top; + union { + struct css_length length; + float percent; + } value; + } top; + + css_unicode_bidi unicode_bidi; + + struct { + css_vertical_align_type type; + union { + struct css_length length; + float percent; + } value; + } vertical_align; + css_visibility visibility; + css_white_space white_space; + + struct { + enum { CSS_WIDOWS_INHERIT, + CSS_WIDOWS_INTEGER } widows; + int value; + } widows; + struct { enum { CSS_WIDTH_INHERIT, CSS_WIDTH_AUTO, @@ -192,7 +388,19 @@ struct css_style { } value; } width; - css_white_space white_space; + struct { + enum { CSS_WORD_SPACING_INHERIT, + CSS_WORD_SPACING_NORMAL, + CSS_WORD_SPACING_LENGTH } word_spacing; + struct css_length length; + } word_spacing; + + struct { + enum { CSS_Z_INDEX_INHERIT, + CSS_Z_INDEX_AUTO, + CSS_Z_INDEX_INTEGER } z_index; + int value; + } z_index; }; struct css_stylesheet; diff --git a/css/css_enums b/css/css_enums index fef16123c..757550b7c 100644 --- a/css/css_enums +++ b/css/css_enums @@ -1,21 +1,29 @@ css_unit em ex px in cm mm pt pc css_background_attachment inherit fixed scroll css_background_repeat inherit repeat repeat-x repeat-y no-repeat +css_border_collapse inherit collapse separate css_border_style inherit none hidden dotted dashed solid double groove ridge inset outset +css_caption_side inherit top bottom css_clear inherit none both left right css_cursor inherit auto crosshair default pointer move e-resize ne-resize nw-resize n-resize se-resize sw-resize s-resize w-resize text wait help +css_direction inherit ltr rtl css_display inherit inline block list-item run-in inline-block table inline-table table-row-group table-header-group table-footer-group table-row table-column-group table-column table-cell table-caption none +css_empty_cells inherit show hide css_float inherit none left right css_font_family inherit sans-serif serif monospace cursive fantasy css_font_style inherit normal italic oblique css_font_variant inherit normal small-caps css_font_weight inherit normal bold bolder lighter 100 200 300 400 500 600 700 800 900 -css_letter_spacing normal length -css_list_style_position outside inside -css_list_style_type disc circle square decimal lower-alpha lower-roman upper-alpha upper-roman none +css_list_style_position inherit outside inside +css_list_style_type inherit disc circle square decimal lower-alpha lower-roman upper-alpha upper-roman none css_overflow inherit visible hidden scroll auto +css_page_break_after inherit auto always avoid left right +css_page_break_before inherit auto always avoid left right +css_page_break_inside inherit avoid auto +css_position inherit static relative absolute fixed +css_table_layout inherit auto fixed css_text_align inherit left right center justify css_text_transform inherit none capitalize lowercase uppercase -css_vertical_align baseline bottom middle sub super text-bottom text-top top percent -css_visibility inherit visible hidden -css_white_space inherit normal nowrap pre +css_unicode_bidi inherit normal embed bidi-override +css_visibility inherit visible hidden collapse +css_white_space inherit normal nowrap pre pre-wrap pre-line diff --git a/css/ruleset.c b/css/ruleset.c index 6aa470b6d..af5268c2c 100644 --- a/css/ruleset.c +++ b/css/ruleset.c @@ -59,6 +59,7 @@ static void parse_border_bottom(struct css_style * const s, const struct css_nod static void parse_border_bottom_color(struct css_style * const s, const struct css_node * v); static void parse_border_bottom_style(struct css_style * const s, const struct css_node * v); static void parse_border_bottom_width(struct css_style * const s, const struct css_node * v); +static void parse_border_collapse(struct css_style * const s, const struct css_node * v); static void parse_border_color(struct css_style * const s, const struct css_node * v); static void parse_border_color_side(struct css_style * const s, const struct css_node * const v, unsigned int i); @@ -72,6 +73,7 @@ static void parse_border_right_style(struct css_style * const s, const struct cs static void parse_border_right_width(struct css_style * const s, const struct css_node * v); static void parse_border_side(struct css_style * const s, const struct css_node *v, unsigned int i); +static void parse_border_spacing(struct css_style * const s, const struct css_node * v); static void parse_border_style(struct css_style * const s, const struct css_node * v); static void parse_border_style_side(struct css_style * const s, const struct css_node * const v, unsigned int i); @@ -82,10 +84,15 @@ static void parse_border_top_width(struct css_style * const s, const struct css_ static void parse_border_width(struct css_style * const s, const struct css_node * v); static void parse_border_width_side(struct css_style * const s, const struct css_node * const v, unsigned int i); +static void parse_bottom(struct css_style * const s, const struct css_node * v); +static void parse_caption_side(struct css_style * const s, const struct css_node * v); static void parse_clear(struct css_style * const s, const struct css_node * const v); +static void parse_clip(struct css_style * const s, const struct css_node * v); static void parse_color(struct css_style * const s, const struct css_node * const v); static void parse_cursor(struct css_style * const s, const struct css_node * v); +static void parse_direction(struct css_style * const s, const struct css_node * v); static void parse_display(struct css_style * const s, const struct css_node * const v); +static void parse_empty_cells(struct css_style * const s, const struct css_node * v); static void parse_float(struct css_style * const s, const struct css_node * const v); static void parse_font(struct css_style * const s, const struct css_node * v); static void parse_font_family(struct css_style * const s, const struct css_node * v); @@ -94,7 +101,15 @@ static void parse_font_style(struct css_style * const s, const struct css_node * static void parse_font_variant(struct css_style * const s, const struct css_node * const v); static void parse_font_weight(struct css_style * const s, const struct css_node * const v); static void parse_height(struct css_style * const s, const struct css_node * const v); +static void parse_left(struct css_style * const s, const struct css_node * v); +static void parse_letter_spacing(struct css_style * const s, const struct css_node * v); static void parse_line_height(struct css_style * const s, const struct css_node * const v); +static void parse_list_style(struct css_style * const s, const struct css_node * v); +static void parse_list_style_image(struct css_style * const s, const struct css_node * v); +static bool css_list_style_image_parse(const struct css_node *v, + css_list_style_image_type *type, char **uri); +static void parse_list_style_position(struct css_style * const s, const struct css_node * v); +static void parse_list_style_type(struct css_style * const s, const struct css_node * v); static void parse_margin(struct css_style * const s, const struct css_node * const v); static void parse_margin_bottom(struct css_style * const s, const struct css_node * const v); static void parse_margin_left(struct css_style * const s, const struct css_node * const v); @@ -102,6 +117,16 @@ static void parse_margin_right(struct css_style * const s, const struct css_node static void parse_margin_top(struct css_style * const s, const struct css_node * const v); static void parse_margin_side(struct css_style * const s, const struct css_node * const v, unsigned int i); +static void parse_max_height(struct css_style *const s, const struct css_node * v); +static void parse_max_width(struct css_style *const s, const struct css_node * v); +static void parse_min_height(struct css_style *const s, const struct css_node * v); +static void parse_min_width(struct css_style *const s, const struct css_node * v); +static void parse_orphans(struct css_style * const s, const struct css_node * const v); +static void parse_outline(struct css_style * const s, const struct css_node * v); +static void parse_outline_color(struct css_style * const s, const struct css_node * const v); +static void parse_outline_style(struct css_style * const s, const struct css_node * const v); +static void parse_outline_width(struct css_style * const s, const struct css_node * const v); +static bool css_outline_width_parse(const struct css_node * v, struct css_border_width * w); static void parse_overflow(struct css_style * const s, const struct css_node * const v); static void parse_padding(struct css_style * const s, const struct css_node * const v); static void parse_padding_bottom(struct css_style * const s, const struct css_node * const v); @@ -110,13 +135,25 @@ static void parse_padding_right(struct css_style * const s, const struct css_nod static void parse_padding_top(struct css_style * const s, const struct css_node * const v); static void parse_padding_side(struct css_style * const s, const struct css_node * const v, unsigned int i); +static void parse_page_break_after(struct css_style * const s, const struct css_node * v); +static void parse_page_break_before(struct css_style * const s, const struct css_node * v); +static void parse_page_break_inside(struct css_style * const s, const struct css_node * v); +static void parse_position(struct css_style * const s, const struct css_node * v); +static void parse_right(struct css_style * const s, const struct css_node * v); +static void parse_table_layout(struct css_style * const s, const struct css_node * v); static void parse_text_align(struct css_style * const s, const struct css_node * const v); static void parse_text_decoration(struct css_style * const s, const struct css_node * const v); static void parse_text_indent(struct css_style * const s, const struct css_node * const v); static void parse_text_transform(struct css_style * const s, const struct css_node * const v); +static void parse_top(struct css_style * const s, const struct css_node * v); +static void parse_unicode_bidi(struct css_style * const s, const struct css_node * const v); +static void parse_vertical_align(struct css_style * const s, const struct css_node * v); static void parse_visibility(struct css_style * const s, const struct css_node * const v); +static void parse_widows(struct css_style * const s, const struct css_node * const v); static void parse_width(struct css_style * const s, const struct css_node * const v); static void parse_white_space(struct css_style * const s, const struct css_node * const v); +static void parse_word_spacing(struct css_style * const s, const struct css_node * v); +static void parse_z_index(struct css_style * const s, const struct css_node * const v); static css_text_decoration css_text_decoration_parse(const char * const s, int length); @@ -141,6 +178,7 @@ static const struct css_property_entry css_property_table[] = { { "border-bottom-color", parse_border_bottom_color }, { "border-bottom-style", parse_border_bottom_style }, { "border-bottom-width", parse_border_bottom_width }, + { "border-collapse", parse_border_collapse }, { "border-color", parse_border_color }, { "border-left", parse_border_left }, { "border-left-color", parse_border_left_color }, @@ -150,16 +188,22 @@ static const struct css_property_entry css_property_table[] = { { "border-right-color", parse_border_right_color }, { "border-right-style", parse_border_right_style }, { "border-right-width", parse_border_right_width }, + { "border-spacing", parse_border_spacing }, { "border-style", parse_border_style }, { "border-top", parse_border_top }, { "border-top-color", parse_border_top_color }, { "border-top-style", parse_border_top_style }, { "border-top-width", parse_border_top_width }, { "border-width", parse_border_width }, + { "bottom", parse_bottom }, + { "caption-side", parse_caption_side }, { "clear", parse_clear }, + { "clip", parse_clip }, { "color", parse_color }, { "cursor", parse_cursor }, + { "direction", parse_direction }, { "display", parse_display }, + { "empty-cells", parse_empty_cells }, { "float", parse_float }, { "font", parse_font }, { "font-family", parse_font_family }, @@ -168,25 +212,52 @@ static const struct css_property_entry css_property_table[] = { { "font-variant", parse_font_variant }, { "font-weight", parse_font_weight }, { "height", parse_height }, + { "left", parse_left }, + { "letter-spacing", parse_letter_spacing }, { "line-height", parse_line_height }, + { "list-style", parse_list_style }, + { "list-style-image", parse_list_style_image }, + { "list-style-position", parse_list_style_position }, + { "list-style-type", parse_list_style_type }, { "margin", parse_margin }, { "margin-bottom", parse_margin_bottom }, { "margin-left", parse_margin_left }, { "margin-right", parse_margin_right }, { "margin-top", parse_margin_top }, + { "max-height", parse_max_height }, + { "max-width", parse_max_width }, + { "min-height", parse_min_height }, + { "min-width", parse_min_width }, + { "orphans", parse_orphans }, + { "outline", parse_outline }, + { "outline-color", parse_outline_color }, + { "outline-style", parse_outline_style }, + { "outline-width", parse_outline_width }, { "overflow", parse_overflow }, { "padding", parse_padding }, { "padding-bottom", parse_padding_bottom }, { "padding-left", parse_padding_left }, { "padding-right", parse_padding_right }, { "padding-top", parse_padding_top }, + { "page-break-after", parse_page_break_after }, + { "page-break-before", parse_page_break_before }, + { "page-break-inside", parse_page_break_inside }, + { "position", parse_position }, + { "right", parse_right }, + { "table-layout", parse_table_layout }, { "text-align", parse_text_align }, { "text-decoration", parse_text_decoration }, { "text-indent", parse_text_indent }, { "text-transform", parse_text_transform }, + { "top", parse_top }, + { "unicode-bidi", parse_unicode_bidi }, + { "vertical-align", parse_vertical_align }, { "visibility", parse_visibility }, { "white-space", parse_white_space }, + { "widows", parse_widows }, { "width", parse_width }, + { "word-spacing", parse_word_spacing }, + { "z-index", parse_z_index } }; @@ -1245,6 +1316,83 @@ void parse_border_side(struct css_style * const s, } } +void parse_border_collapse(struct css_style * const s, const struct css_node * v) +{ + css_border_collapse z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_border_collapse_parse(v->data, v->data_length); + if (z != CSS_BORDER_COLLAPSE_UNKNOWN) + s->border_collapse = z; +} + +void parse_border_spacing(struct css_style * const s, const struct css_node * v) +{ + if (v->next && v->next->next) + /* more than two nodes */ + return; + + if (!v->next) { + /* one node */ + if (v->type == CSS_NODE_IDENT && v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->border_spacing.border_spacing = CSS_BORDER_SPACING_INHERIT; + else if (v->type == CSS_NODE_DIMENSION || + v->type == CSS_NODE_NUMBER) { + if (parse_length(&s->border_spacing.horz, v, true) == 0 && parse_length(&s->border_spacing.vert, v, true == 0)) + s->border_spacing.border_spacing = CSS_BORDER_SPACING_LENGTH; + } + } + else { + /* two nodes */ + if ((v->type == CSS_NODE_DIMENSION || + v->type == CSS_NODE_NUMBER) && + (v->next->type == CSS_NODE_DIMENSION || + v->next->type == CSS_NODE_NUMBER)) { + if (parse_length(&s->border_spacing.horz, v, true) == 0 && parse_length(&s->border_spacing.vert, v->next, true == 0)) + s->border_spacing.border_spacing = CSS_BORDER_SPACING_LENGTH; + } + } +} + +void parse_bottom(struct css_style * const s, const struct css_node * v) +{ + if (v->next != 0) + return; + + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->bottom.bottom = CSS_BOTTOM_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "auto", 4) == 0) + s->bottom.bottom = CSS_BOTTOM_AUTO; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->bottom.value.length, v, false) == 0) + s->bottom.bottom = CSS_BOTTOM_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->bottom.bottom = CSS_BOTTOM_PERCENT; + s->bottom.value.percent = atof(v->data); + break; + default: + break; + } +} + +void parse_caption_side(struct css_style * const s, const struct css_node * v) +{ + css_caption_side z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_caption_side_parse(v->data, v->data_length); + if (z != CSS_CAPTION_SIDE_UNKNOWN) + s->caption_side = z; +} + void parse_clear(struct css_style * const s, const struct css_node * const v) { css_clear z; @@ -1255,6 +1403,67 @@ void parse_clear(struct css_style * const s, const struct css_node * const v) s->clear = z; } +void parse_clip(struct css_style * const s, const struct css_node * v) +{ + int i; + struct css_node *t; + + if (v->next != 0) + return; + + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->clip.clip = CSS_CLIP_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "auto", 4) == 0) + s->clip.clip = CSS_CLIP_AUTO; + break; + case CSS_NODE_FUNCTION: + /* must be rect(X,X,X,X) */ + if (v->data_length == 5 && + strncasecmp(v->data, "rect", 4) == 0) { + t = v->value; + for (i = 0; i != 4; i++) { + switch (t->type) { + case CSS_NODE_IDENT: + if (t->data_length == 4 && strncasecmp(t->data, "auto", 4) == 0) { + s->clip.rect[i].rect = CSS_CLIP_AUTO; + } + else + return; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->clip.rect[i].value, t, false) != 0) + return; + s->clip.rect[i].rect = CSS_CLIP_RECT_LENGTH; + break; + default: + return; + } + t = t->next; + + if (i == 3) { + if (t) + return; + } + else { + if (!t || t->type != CSS_NODE_COMMA) + return; + } + + t = t->next; + } + s->clip.clip = CSS_CLIP_RECT; + } + break; + default: + break; + } +} + void parse_color(struct css_style * const s, const struct css_node * const v) { colour c; @@ -1283,6 +1492,16 @@ void parse_cursor(struct css_style * const s, const struct css_node * v) } } +void parse_direction(struct css_style * const s, const struct css_node * v) +{ + css_direction z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_direction_parse(v->data, v->data_length); + if (z != CSS_DIRECTION_UNKNOWN) + s->direction = z; +} + void parse_display(struct css_style * const s, const struct css_node * const v) { css_display z; @@ -1293,6 +1512,16 @@ void parse_display(struct css_style * const s, const struct css_node * const v) s->display = z; } +void parse_empty_cells(struct css_style * const s, const struct css_node * v) +{ + css_empty_cells z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_empty_cells_parse(v->data, v->data_length); + if (z != CSS_EMPTY_CELLS_UNKNOWN) + s->empty_cells = z; +} + void parse_float(struct css_style * const s, const struct css_node * const v) { css_float z; @@ -1466,6 +1695,58 @@ void parse_height(struct css_style * const s, const struct css_node * const v) s->height.height = CSS_HEIGHT_LENGTH; } +void parse_left(struct css_style * const s, const struct css_node * v) +{ + if (v->next != 0) + return; + + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->left.left = CSS_LEFT_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "auto", 4) == 0) + s->left.left = CSS_LEFT_AUTO; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->left.value.length, v, false) == 0) + s->left.left = CSS_LEFT_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->left.left = CSS_LEFT_PERCENT; + s->left.value.percent = atof(v->data); + break; + default: + break; + } +} + +void parse_letter_spacing(struct css_style * const s, const struct css_node * v) +{ + if (v->next != 0) + return; + + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->letter_spacing.letter_spacing = CSS_LETTER_SPACING_INHERIT; + else if (v->data_length == 6 && + strncasecmp(v->data, "normal", 6) == 0) + s->letter_spacing.letter_spacing = CSS_LETTER_SPACING_NORMAL; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->letter_spacing.length, v, false) == 0) + s->letter_spacing.letter_spacing = CSS_LETTER_SPACING_LENGTH; + break; + default: + break; + } +} + void parse_line_height(struct css_style * const s, const struct css_node * const v) { if (v->type == CSS_NODE_IDENT && v->data_length == 6 && @@ -1484,6 +1765,161 @@ void parse_line_height(struct css_style * const s, const struct css_node * const } } +void parse_list_style(struct css_style * const s, const struct css_node * v) +{ + css_list_style_type t = CSS_LIST_STYLE_TYPE_DISC, t2; + css_list_style_position p = CSS_LIST_STYLE_POSITION_OUTSIDE, p2; + css_list_style_image_type i = CSS_LIST_STYLE_IMAGE_NONE, i2; + char *lsi_uri = 0; + + while (v) { + switch (v->type) { + case CSS_NODE_IDENT: + t2 = css_list_style_type_parse(v->data, v->data_length); + if (t2 != CSS_LIST_STYLE_TYPE_UNKNOWN) { + t = t2; + v = v->next; + break; + } + + p2 = css_list_style_position_parse(v->data, v->data_length); + if (p2 != CSS_LIST_STYLE_POSITION_UNKNOWN) { + p = p2; + v = v->next; + break; + } + + /* drop through */ + case CSS_NODE_STRING: + case CSS_NODE_URI: + if (!css_list_style_image_parse(v, &i2, &lsi_uri)) + return; + i = i2; + v = v->next; + break; + default: + return; + } + } + + s->list_style_type = t; + s->list_style_position = p; + s->list_style_image.type = i; + s->list_style_image.uri = lsi_uri; +} + +void parse_list_style_image(struct css_style * const s, const struct css_node * v) +{ + css_list_style_image_type type; + char *uri; + + if (v->next != 0) + return; + if (!css_list_style_image_parse(v, &type, &uri)) + return; + + s->list_style_image.type = type; + s->list_style_image.uri = uri; +} + +/** + * Parse a list-style-image property. + * + * \param node node to parse + * \param type updated to list-style-image type + * \param uri updated to image uri, if type is + * CSS_LIST_STYLE_IMAGE_URI + * \return true on success, false on parse failure + */ + +bool css_list_style_image_parse(const struct css_node *v, + css_list_style_image_type *type, char **uri) +{ + bool string = false; + const char *u; + char *t, *url; + + switch (v->type) { + case CSS_NODE_URI: + for (u = v->data + 4; + *u == ' ' || *u == '\t' || *u == '\r' || + *u == '\n' || *u == '\f'; + u++) + ; + if (*u == '\'' || *u == '"') { + string = true; + u++; + } + url = strndup(u, v->data_length - (u - v->data)); + if (!url) + return false; + for (t = url + strlen(url) - 2; + *t == ' ' || *t == '\t' || *t == '\r' || + *t == '\n' || *t == '\f'; + t--) + ; + if (string) + *t = 0; + else + *(t + 1) = 0; + + /* for inline style attributes, the stylesheet + * content is the parent HTML content + */ + if (v->stylesheet->type == CONTENT_HTML) + *uri = url_join(url, v->stylesheet->data.html.base_url); + else + *uri = url_join(url, v->stylesheet->url); + free(url); + if (!*uri) + return false; + *type = CSS_LIST_STYLE_IMAGE_URI; + break; + case CSS_NODE_STRING: + url = strndup(v->data, v->data_length); + if (!url) + return false; + + *uri = url_join(url, v->stylesheet->url); + free(url); + if (!*uri) + return false; + *type = CSS_LIST_STYLE_IMAGE_URI; + break; + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + *type = CSS_LIST_STYLE_IMAGE_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "none", 4) == 0) + *type = CSS_LIST_STYLE_IMAGE_NONE; + break; + default: + return false; + } + return true; +} + +void parse_list_style_position(struct css_style * const s, const struct css_node * v) +{ + css_list_style_position z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_list_style_position_parse(v->data, v->data_length); + if (z != CSS_LIST_STYLE_POSITION_UNKNOWN) + s->list_style_position = z; +} + +void parse_list_style_type(struct css_style * const s, const struct css_node * v) +{ + css_list_style_type z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_list_style_type_parse(v->data, v->data_length); + if (z != CSS_LIST_STYLE_TYPE_UNKNOWN) + s->list_style_type = z; +} + void parse_margin(struct css_style * const s, const struct css_node * const v) { unsigned int count = 0; @@ -1567,6 +2003,267 @@ void parse_margin_side(struct css_style * const s, const struct css_node * const } } +void parse_max_height(struct css_style *const s, const struct css_node * v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->max_height.max_height = CSS_MAX_HEIGHT_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "none", 4) == 0) + s->max_height.max_height = CSS_MAX_HEIGHT_NONE; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (!parse_length(&s->max_height.value.length, v, true)) + s->max_height.max_height = CSS_MAX_HEIGHT_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->max_height.value.percent = atof(v->data); + s->max_height.max_height = CSS_MAX_HEIGHT_PERCENT; + break; + default: + break; + } +} + +void parse_max_width(struct css_style *const s, const struct css_node * v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->max_width.max_width = CSS_MAX_WIDTH_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "none", 4) == 0) + s->max_width.max_width = CSS_MAX_WIDTH_NONE; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (!parse_length(&s->max_width.value.length, v, true)) + s->max_width.max_width = CSS_MAX_WIDTH_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->max_width.value.percent = atof(v->data); + s->max_width.max_width = CSS_MAX_WIDTH_PERCENT; + break; + default: + break; + } +} + +void parse_min_height(struct css_style *const s, const struct css_node * v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->min_height.min_height = CSS_MIN_HEIGHT_INHERIT; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (!parse_length(&s->min_height.value.length, v, true)) + s->min_height.min_height = CSS_MIN_HEIGHT_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->min_height.value.percent = atof(v->data); + s->min_height.min_height = CSS_MIN_HEIGHT_PERCENT; + break; + default: + break; + } +} + +void parse_min_width(struct css_style *const s, const struct css_node * v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->min_width.min_width = CSS_MIN_WIDTH_INHERIT; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (!parse_length(&s->min_width.value.length, v, true)) + s->min_width.min_width = CSS_MIN_WIDTH_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->min_width.value.percent = atof(v->data); + s->min_width.min_width = CSS_MIN_WIDTH_PERCENT; + break; + default: + break; + } +} + +void parse_orphans(struct css_style * const s, const struct css_node * const v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->orphans.orphans = CSS_ORPHANS_INHERIT; + break; + case CSS_NODE_NUMBER: + s->orphans.value = atoi(v->data); + s->orphans.orphans = CSS_ORPHANS_INTEGER; + break; + default: + break; + } +} + +void parse_outline(struct css_style * const s, const struct css_node * v) +{ + css_outline_color_type c = CSS_OUTLINE_COLOR_INVERT; + colour col = 0, col2; + css_border_style b = CSS_BORDER_STYLE_NONE, b2; + struct css_border_width w = { CSS_BORDER_WIDTH_LENGTH, { 2, CSS_UNIT_PX } }; + struct css_border_width w2; + + while (v) { + switch (v->type) { + case CSS_NODE_HASH: + case CSS_NODE_FUNCTION: + case CSS_NODE_IDENT: + col2 = parse_colour(v); + if (col2 != CSS_COLOR_NONE) { + col = col2; + c = CSS_OUTLINE_COLOR_COLOR; + v = v->next; + break; + } + if (v->type == CSS_NODE_HASH || + v->type == CSS_NODE_FUNCTION) + return; + + /* could be inherit */ + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) { + c = CSS_OUTLINE_COLOR_INHERIT; + v = v->next; + break; + } + + b2 = css_border_style_parse(v->data, v->data_length); + if (b2 != CSS_BORDER_STYLE_UNKNOWN) { + b = b2; + v = v->next; + break; + } + + /* fall through */ + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (css_outline_width_parse(v, &w2)) { + w = w2; + v = v->next; + break; + } + + /* fall through */ + default: + return; + } + } + + s->outline.color.color = c; + s->outline.color.value = col; + s->outline.width = w; + s->outline.style = b; +} + +void parse_outline_color(struct css_style * const s, const struct css_node * const v) +{ + colour c; + + if (v->next != 0) + return; + + c = parse_colour(v); + if (c == CSS_COLOR_NONE && v->type == CSS_NODE_IDENT) { + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->outline.color.color = CSS_OUTLINE_COLOR_INHERIT; + else if (v->data_length == 6 && + strncasecmp(v->data, "invert", 6) == 0) + s->outline.color.color = CSS_OUTLINE_COLOR_INVERT; + } + else { + s->outline.color.value = c; + s->outline.color.color = CSS_OUTLINE_COLOR_COLOR; + } +} + +void parse_outline_style(struct css_style * const s, const struct css_node * const v) +{ + css_border_style z; + + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_border_style_parse(v->data, v->data_length); + if (z != CSS_BORDER_STYLE_UNKNOWN) + s->outline.style = z; +} + +void parse_outline_width(struct css_style * const s, const struct css_node * const v) +{ + struct css_border_width w; + if (v->next != 0) + return; + if (!css_outline_width_parse(v, &w)) + return; + s->outline.width = w; +} + + +bool css_outline_width_parse(const struct css_node * v, struct css_border_width * w) +{ + if (v->type == CSS_NODE_IDENT) { + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) { + w->width = CSS_BORDER_WIDTH_INHERIT; + return true; + } else if (v->data_length == 4 && + strncasecmp(v->data, "thin", 4) == 0) { + w->width = CSS_BORDER_WIDTH_LENGTH; + w->value.value = 1; + w->value.unit = CSS_UNIT_PX; + return true; + } else if (v->data_length == 6 && + strncasecmp(v->data, "medium", 6) == 0) { + w->width = CSS_BORDER_WIDTH_LENGTH; + w->value.value = 2; + w->value.unit = CSS_UNIT_PX; + return true; + } else if (v->data_length == 5 && + strncasecmp(v->data, "thick", 5) == 0) { + w->width = CSS_BORDER_WIDTH_LENGTH; + w->value.value = 4; + w->value.unit = CSS_UNIT_PX; + return true; + } + } else if ((v->type == CSS_NODE_DIMENSION || + v->type == CSS_NODE_NUMBER) && + parse_length(&w->value, v, true) == 0) { + w->width = CSS_BORDER_WIDTH_LENGTH; + return true; + } + + return false; +} + void parse_overflow(struct css_style * const s, const struct css_node * const v) { css_overflow z; @@ -1654,6 +2351,84 @@ void parse_padding_side(struct css_style * const s, const struct css_node * cons } } +void parse_page_break_after(struct css_style * const s, const struct css_node * v) +{ + css_page_break_after z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_page_break_after_parse(v->data, v->data_length); + if (z != CSS_PAGE_BREAK_AFTER_UNKNOWN) + s->page_break_after = z; +} + +void parse_page_break_before(struct css_style * const s, const struct css_node * v) +{ + css_page_break_before z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_page_break_before_parse(v->data, v->data_length); + if (z != CSS_PAGE_BREAK_BEFORE_UNKNOWN) + s->page_break_before = z; +} + +void parse_page_break_inside(struct css_style * const s, const struct css_node * v) +{ + css_page_break_inside z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_page_break_inside_parse(v->data, v->data_length); + if (z != CSS_PAGE_BREAK_INSIDE_UNKNOWN) + s->page_break_inside = z; +} + +void parse_position(struct css_style * const s, const struct css_node * v) +{ + css_position z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_position_parse(v->data, v->data_length); + if (z != CSS_POSITION_UNKNOWN) + s->position = z; +} + +void parse_right(struct css_style * const s, const struct css_node * v) +{ + if (v->next != 0) + return; + + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->right.right = CSS_RIGHT_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "auto", 4) == 0) + s->right.right = CSS_RIGHT_AUTO; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->right.value.length, v, false) == 0) + s->right.right = CSS_RIGHT_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->right.right = CSS_RIGHT_PERCENT; + s->right.value.percent = atof(v->data); + break; + default: + break; + } +} + +void parse_table_layout(struct css_style * const s, const struct css_node * v) +{ + css_table_layout z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_table_layout_parse(v->data, v->data_length); + if (z != CSS_TABLE_LAYOUT_UNKNOWN) + s->table_layout = z; +} + void parse_text_align(struct css_style * const s, const struct css_node * const v) { css_text_align z; @@ -1708,6 +2483,92 @@ void parse_text_transform(struct css_style * const s, const struct css_node * co s->text_transform = z; } +void parse_top(struct css_style * const s, const struct css_node * v) +{ + if (v->next != 0) + return; + + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->top.top = CSS_TOP_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "auto", 4) == 0) + s->top.top = CSS_TOP_AUTO; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->top.value.length, v, false) == 0) + s->top.top = CSS_TOP_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->top.top = CSS_TOP_PERCENT; + s->top.value.percent = atof(v->data); + break; + default: + break; + } +} + +void parse_unicode_bidi(struct css_style * const s, const struct css_node * const v) +{ + css_unicode_bidi z; + if (v->type != CSS_NODE_IDENT || v->next != 0) + return; + z = css_unicode_bidi_parse(v->data, v->data_length); + if (z != CSS_UNICODE_BIDI_UNKNOWN) + s->unicode_bidi = z; +} + +void parse_vertical_align(struct css_style * const s, const struct css_node * v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_INHERIT; + else if (v->data_length == 8 && + strncasecmp(v->data, "baseline", 8) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_BASELINE; + else if (v->data_length == 3 && + strncasecmp(v->data, "sub", 3) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_SUB; + else if (v->data_length == 5 && + strncasecmp(v->data, "super", 5) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_SUPER; + else if (v->data_length == 3 && + strncasecmp(v->data, "top", 3) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_TOP; + else if (v->data_length == 8 && + strncasecmp(v->data, "text-top", 8) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_TEXT_TOP; + else if (v->data_length == 6 && + strncasecmp(v->data, "middle", 6) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_MIDDLE; + else if (v->data_length == 6 && + strncasecmp(v->data, "bottom", 6) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_BOTTOM; + else if (v->data_length == 11 && + strncasecmp(v->data, "text-bottom", 11) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_TEXT_BOTTOM; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->vertical_align.value.length, v, false) == 0) + s->vertical_align.type = CSS_VERTICAL_ALIGN_LENGTH; + break; + case CSS_NODE_PERCENTAGE: + s->vertical_align.value.percent = atof(v->data); + s->vertical_align.type = CSS_VERTICAL_ALIGN_PERCENT; + break; + default: + break; + } +} + void parse_visibility(struct css_style * const s, const struct css_node * const v) { css_visibility z; @@ -1718,6 +2579,25 @@ void parse_visibility(struct css_style * const s, const struct css_node * const s->visibility = z; } +void parse_widows(struct css_style * const s, const struct css_node * const v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->widows.widows = CSS_WIDOWS_INHERIT; + break; + case CSS_NODE_NUMBER: + s->widows.value = atoi(v->data); + s->widows.widows = CSS_WIDOWS_INTEGER; + break; + default: + break; + } +} + void parse_width(struct css_style * const s, const struct css_node * const v) { if (v->type == CSS_NODE_IDENT && v->data_length == 4 && @@ -1741,6 +2621,52 @@ void parse_white_space(struct css_style * const s, const struct css_node * const s->white_space = z; } +void parse_word_spacing(struct css_style * const s, const struct css_node * v) +{ + if (v->next != 0) + return; + + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->word_spacing.word_spacing = CSS_WORD_SPACING_INHERIT; + else if (v->data_length == 6 && + strncasecmp(v->data, "normal", 6) == 0) + s->word_spacing.word_spacing = CSS_WORD_SPACING_NORMAL; + break; + case CSS_NODE_DIMENSION: + case CSS_NODE_NUMBER: + if (parse_length(&s->word_spacing.length, v, false) == 0) + s->word_spacing.word_spacing = CSS_WORD_SPACING_LENGTH; + break; + default: + break; + } +} + +void parse_z_index(struct css_style * const s, const struct css_node * const v) +{ + if (v->next != 0) + return; + switch (v->type) { + case CSS_NODE_IDENT: + if (v->data_length == 7 && + strncasecmp(v->data, "inherit", 7) == 0) + s->z_index.z_index = CSS_Z_INDEX_INHERIT; + else if (v->data_length == 4 && + strncasecmp(v->data, "auto", 4) == 0) + s->z_index.z_index = CSS_Z_INDEX_AUTO; + break; + case CSS_NODE_NUMBER: + s->z_index.value = atoi(v->data); + s->z_index.z_index = CSS_Z_INDEX_INTEGER; + break; + default: + break; + } +} + css_text_decoration css_text_decoration_parse(const char * const s, int length) { -- cgit v1.2.3