diff options
author | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2010-04-02 23:42:55 +0200 |
---|---|---|
committer | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2010-04-02 23:42:55 +0200 |
commit | 6afddbd7a6a41c9a2c27a88749a3ed6dc082bbfd (patch) | |
tree | 3ea3728964fd92330751a8fcd4feee930ee0fd96 | |
parent | e69c87143a4bd364a197d6a86c97680a4e356537 (diff) |
add CSS_TYPE_LENGTH_PERCENTAGE_NUMBER
* Add an additional CssValueType CSS_TYPE_LENGTH_PERCENTAGE_NUMBER
which can be a length, a percentage, or a number without unit.
* Numbers without units are represented as CssLength of type
CSS_LENGTH_TYPE_NONE.
* Properly detect numbers without unit in cases where they are not
allowed (see testcase below). For lengths only '0' can be
specified without unit.
Testcase:
<html>
<head>
<style tyoe="text/css">
div {border: solid black 2px}
</style>
</head>
<body>
<!-- correct - border-width should be set to 0 -> no border -->
<div style="border-width: 0">foo bar</div>
<!-- false - border-width should be left untouched -> 2px border -->
<div style="border-width: 40">foo bar</div>
<!-- false - border-width should be left untouched -> 2px border -->
<div style="border-width: 40 px">foo bar</div>
</body>
</html>
-rw-r--r-- | src/css.hh | 4 | ||||
-rw-r--r-- | src/cssparser.cc | 33 |
2 files changed, 30 insertions, 7 deletions
@@ -36,6 +36,7 @@ typedef enum { in this particular case (e.g. 'margin-*-width'). */ CSS_TYPE_SIGNED_LENGTH, /* As CSS_TYPE_LENGTH but may be negative. */ + CSS_TYPE_LENGTH_PERCENTAGE_NUMBER, /* <length> or <percentage>, or <number> */ CSS_TYPE_COLOR, /* Represented as integer. */ CSS_TYPE_FONT_WEIGHT, /* this very special and only used by 'font-weight' */ @@ -70,6 +71,7 @@ typedef enum { typedef int CssLength; typedef enum { + CSS_LENGTH_TYPE_NONE, CSS_LENGTH_TYPE_PX, CSS_LENGTH_TYPE_MM, /* "cm", "in", "pt" and "pc" are converted into millimeters. */ @@ -94,6 +96,7 @@ inline CssLength CSS_CREATE_LENGTH (float v, CssLengthType t) { else if (iv < -CSS_LENGTH_INT_MAX) iv = -CSS_LENGTH_INT_MAX; return iv << 3 | t; + case CSS_LENGTH_TYPE_NONE: case CSS_LENGTH_TYPE_MM: case CSS_LENGTH_TYPE_EM: case CSS_LENGTH_TYPE_EX: @@ -120,6 +123,7 @@ inline float CSS_LENGTH_VALUE (CssLength l) { switch (CSS_LENGTH_TYPE(l)) { case CSS_LENGTH_TYPE_PX: return (float) (l >> 3); + case CSS_LENGTH_TYPE_NONE: case CSS_LENGTH_TYPE_MM: case CSS_LENGTH_TYPE_EM: case CSS_LENGTH_TYPE_EX: diff --git a/src/cssparser.cc b/src/cssparser.cc index 332a989a..f73c257b 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -89,6 +89,10 @@ static const char *const Css_list_style_position_enum_vals[] = { "inside", "outside", NULL }; +static const char *const Css_line_height_enum_vals[] = { + "normal", NULL +}; + static const char *const Css_list_style_type_enum_vals[] = { "disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-greek", "lower-alpha", @@ -168,7 +172,9 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = { {"left", {CSS_TYPE_UNUSED}, NULL}, {"letter-spacing", {CSS_TYPE_ENUM, CSS_TYPE_SIGNED_LENGTH, CSS_TYPE_UNUSED}, Css_letter_spacing_enum_vals}, - {"line-height", {CSS_TYPE_UNUSED}, NULL}, + {"line-height", + {CSS_TYPE_ENUM, CSS_TYPE_LENGTH_PERCENTAGE_NUMBER, CSS_TYPE_UNUSED}, + Css_line_height_enum_vals}, {"list-style-image", {CSS_TYPE_UNUSED}, NULL}, {"list-style-position", {CSS_TYPE_ENUM, CSS_TYPE_UNUSED}, Css_list_style_position_enum_vals}, @@ -661,6 +667,7 @@ bool CssParser::tokenMatchesProperty(CssPropertyName prop, CssValueType *type) break; case CSS_TYPE_LENGTH_PERCENTAGE: + case CSS_TYPE_LENGTH_PERCENTAGE_NUMBER: case CSS_TYPE_LENGTH: if (tval[0] == '-') return false; @@ -831,17 +838,17 @@ bool CssParser::parseValue(CssPropertyName prop, break; case CSS_TYPE_LENGTH_PERCENTAGE: + case CSS_TYPE_LENGTH_PERCENTAGE_NUMBER: case CSS_TYPE_LENGTH: case CSS_TYPE_SIGNED_LENGTH: if (ttype == CSS_TK_DECINT || ttype == CSS_TK_FLOAT) { fval = atof(tval); - lentype = CSS_LENGTH_TYPE_PX; /* Actually, there must be a unit, - * except for num == 0. */ - - ret = true; + lentype = CSS_LENGTH_TYPE_NONE; nextToken(); - if (ttype == CSS_TK_SYMBOL) { + if (!spaceSeparated && ttype == CSS_TK_SYMBOL) { + ret = true; + if (dStrcasecmp(tval, "px") == 0) { lentype = CSS_LENGTH_TYPE_PX; nextToken(); @@ -870,15 +877,27 @@ bool CssParser::parseValue(CssPropertyName prop, } else if (dStrcasecmp(tval, "ex") == 0) { lentype = CSS_LENGTH_TYPE_EX; nextToken(); + } else { + ret = false; } - } else if (type == CSS_TYPE_LENGTH_PERCENTAGE && + } else if (!spaceSeparated && + (type == CSS_TYPE_LENGTH_PERCENTAGE || + type == CSS_TYPE_LENGTH_PERCENTAGE_NUMBER) && ttype == CSS_TK_CHAR && tval[0] == '%') { fval /= 100; lentype = CSS_LENGTH_TYPE_PERCENTAGE; + ret = true; nextToken(); } + /* Allow numbers without unit only for 0 or + * CSS_TYPE_LENGTH_PERCENTAGE_NUMBER + */ + if (lentype == CSS_LENGTH_TYPE_NONE && + (type == CSS_TYPE_LENGTH_PERCENTAGE_NUMBER || fval == 0.0)) + ret = true; + val->intVal = CSS_CREATE_LENGTH(fval, lentype); } else if (ttype == CSS_TK_SYMBOL && dStrcasecmp(tval, "auto") == 0) { ret = true; |