summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2008-10-19 21:49:05 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2008-10-19 21:49:05 +0000
commit2c5846b5f8042c4269926d1dba2e29fafe4a5165 (patch)
tree77421f0f54af153dd62fcecb0eadfe0cb0cc345d /src
parent3b433639d83e6bf4ddb074f989c17502bc862fc0 (diff)
downloadlibcss-2c5846b5f8042c4269926d1dba2e29fafe4a5165.tar.gz
libcss-2c5846b5f8042c4269926d1dba2e29fafe4a5165.tar.bz2
Fix parsing of combinators: the CSS 2.1 spec grammar contains inaccuracies -- combinators may be preceded by whitespace.
Fix handling of whitespace after a selector list: again, the CSS 2.1 grammar isn't accurate here. svn path=/trunk/libcss/; revision=5603
Diffstat (limited to 'src')
-rw-r--r--src/parse/css21.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/src/parse/css21.c b/src/parse/css21.c
index 501b4b6..5455eb6 100644
--- a/src/parse/css21.c
+++ b/src/parse/css21.c
@@ -747,26 +747,38 @@ css_error parseCombinator(css_css21 *c, const parserutils_vector *vector,
int *ctx, css_combinator *result)
{
const css_token *token;
+ css_combinator comb = CSS_COMBINATOR_NONE;
- /* combinator -> '+' ws | '>' ws | ws1 */
+ /* combinator -> ws '+' ws | ws '>' ws | ws1 */
UNUSED(c);
- token = parserutils_vector_iterate(vector, ctx);
- if (token == NULL)
- return CSS_INVALID;
+ while ((token = parserutils_vector_peek(vector, *ctx)) != NULL) {
+ if (tokenIsChar(token, '+'))
+ comb = CSS_COMBINATOR_SIBLING;
+ else if (tokenIsChar(token, '>'))
+ comb = CSS_COMBINATOR_PARENT;
+ else if (token->type == CSS_TOKEN_S)
+ comb = CSS_COMBINATOR_ANCESTOR;
+ else
+ break;
+
+ parserutils_vector_iterate(vector, ctx);
+
+ /* If we've seen a '+' or '>', we're done. */
+ if (comb != CSS_COMBINATOR_ANCESTOR)
+ break;
+ }
- if (tokenIsChar(token, '+'))
- *result = CSS_COMBINATOR_SIBLING;
- else if (tokenIsChar(token, '>'))
- *result = CSS_COMBINATOR_PARENT;
- else if (token->type == CSS_TOKEN_S)
- *result = CSS_COMBINATOR_ANCESTOR;
- else
+ /* No valid combinator found */
+ if (comb == CSS_COMBINATOR_NONE)
return CSS_INVALID;
+ /* Consume any trailing whitespace */
consumeWhitespace(vector, ctx);
+ *result = comb;
+
return CSS_OK;
}
@@ -793,6 +805,18 @@ css_error parseSelector(css_css21 *c, const parserutils_vector *vector,
if (error != CSS_OK)
return error;
+ /* In the case of "html , body { ... }", the whitespace after
+ * "html" and "body" will be considered an ancestor combinator.
+ * This clearly is not the case, however. Therefore, as a
+ * special case, if we've got an ancestor combinator and there
+ * are no further tokens, or if the next token is a comma,
+ * we ignore the supposed combinator and continue. */
+ if (comb == CSS_COMBINATOR_ANCESTOR &&
+ ((token = parserutils_vector_peek(vector,
+ *ctx)) == NULL ||
+ tokenIsChar(token, ',')))
+ continue;
+
error = parseSimpleSelector(c, vector, ctx, &other);
if (error != CSS_OK)
return error;