diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2018-04-21 16:33:32 +0100 |
---|---|---|
committer | Michael Drake <michael.drake@codethink.co.uk> | 2019-03-10 13:42:03 +0000 |
commit | 0311677f5676e2f6213a774938dbdc893897cebb (patch) | |
tree | a76705b43280013838e8e3b80a7d37dd19148f90 | |
parent | 52131876ea0a87f94963d7d00d04582ce379cdcb (diff) | |
download | libcss-0311677f5676e2f6213a774938dbdc893897cebb.tar.gz |
Media Queries: Implement parsing <general-enclosed>.
-rw-r--r-- | src/parse/mq.c | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/src/parse/mq.c b/src/parse/mq.c index 719e129..6692651 100644 --- a/src/parse/mq.c +++ b/src/parse/mq.c @@ -433,14 +433,111 @@ static css_error mq_parse_media_feature(css_language *c, return CSS_OK; } +/* + * Consume any value + * + * CSS Syntax Module Level 3: 8.2 + */ +static css_error mq_parse_consume_any_value(css_language *c, + const parserutils_vector *vector, int *ctx, + bool until, const char until_char) +{ + const css_token *token; + css_error error; + + while (true) { + consumeWhitespace(vector, ctx); + + token = parserutils_vector_iterate(vector, ctx); + if (token == NULL) { + return CSS_INVALID; + } + + switch (token->type) { + case CSS_TOKEN_INVALID_STRING: + return CSS_INVALID; + + case CSS_TOKEN_CHAR: + if (until && tokenIsChar(token, until_char)) { + /* Found matching close bracket */ + return CSS_OK; + + } else if (tokenIsChar(token, ')') || + tokenIsChar(token, ']') || + tokenIsChar(token, '}')) { + /* Non-matching close bracket */ + return CSS_INVALID; + } + if (tokenIsChar(token, '(')) { + /* Need to consume until matching bracket. */ + error = mq_parse_consume_any_value( + c, vector, ctx, true, ')'); + if (error != CSS_OK) { + return error; + } + } else if (tokenIsChar(token, '[')) { + /* Need to consume until matching bracket. */ + error = mq_parse_consume_any_value( + c, vector, ctx, true, ']'); + if (error != CSS_OK) { + return error; + } + } else if (tokenIsChar(token, '{')) { + /* Need to consume until matching bracket. */ + error = mq_parse_consume_any_value( + c, vector, ctx, true, '}'); + if (error != CSS_OK) { + return error; + } + } + break; + + default: + break; + } + } + + return CSS_OK; +} + static css_error mq_parse_general_enclosed(css_language *c, const parserutils_vector *vector, int *ctx) { + const css_token *token; + css_error error; + /* <general-enclosed> = [ <function-token> <any-value> ) ] * | ( <ident> <any-value> ) */ - /* TODO: implement */ + token = parserutils_vector_iterate(vector, ctx); + if (token == NULL) { + return CSS_INVALID; + } + + switch (token->type) { + case CSS_TOKEN_FUNCTION: + error = mq_parse_consume_any_value(c, vector, ctx, true, ')'); + if (error != CSS_OK) { + return error; + } + + token = parserutils_vector_peek(vector, *ctx); + if (!tokenIsChar(token, ')')) { + return CSS_INVALID; + } + break; + + case CSS_TOKEN_IDENT: + error = mq_parse_consume_any_value(c, vector, ctx, false, '\0'); + if (error != CSS_OK) { + return error; + } + break; + + default: + return CSS_INVALID; + } return CSS_OK; } |