summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2018-04-21 16:33:32 +0100
committerMichael Drake <michael.drake@codethink.co.uk>2019-03-10 13:42:03 +0000
commit0311677f5676e2f6213a774938dbdc893897cebb (patch)
treea76705b43280013838e8e3b80a7d37dd19148f90
parent52131876ea0a87f94963d7d00d04582ce379cdcb (diff)
downloadlibcss-0311677f5676e2f6213a774938dbdc893897cebb.tar.gz
Media Queries: Implement parsing <general-enclosed>.
-rw-r--r--src/parse/mq.c99
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;
}