From f8c906e4c6ff36cefe0803cba6b2a083efe5bcb6 Mon Sep 17 00:00:00 2001 From: John-Mark Bell Date: Sun, 20 Nov 2016 13:10:02 +0000 Subject: Media Queries: datastructures and plumbing. No parse implementation as yet. Selection hasn't been updated, either. One item of note in that area is that a client currently provides the media for top-level sheets being added to a selection context. This probably needs to change to providing a lwc_string containing the verbatim media query from the containing document's import mechanism. That way, the internal representation of media queries can remain opaque to clients. --- src/parse/language.c | 115 +++++++++++---------------------------------------- 1 file changed, 23 insertions(+), 92 deletions(-) (limited to 'src/parse/language.c') diff --git a/src/parse/language.c b/src/parse/language.c index 9af2547..a5f57d3 100644 --- a/src/parse/language.c +++ b/src/parse/language.c @@ -15,6 +15,7 @@ #include "parse/font_face.h" #include "parse/important.h" #include "parse/language.h" +#include "parse/mq.h" #include "parse/parse.h" #include "parse/propstrings.h" #include "parse/properties/properties.h" @@ -53,9 +54,6 @@ static css_error handleDeclaration(css_language *c, const parserutils_vector *vector); /* At-rule parsing */ -static css_error parseMediaList(css_language *c, - const parserutils_vector *vector, int *ctx, - uint64_t *media); static css_error addNamespace(css_language *c, lwc_string *prefix, lwc_string *uri); static css_error lookupNamespace(css_language *c, @@ -416,10 +414,10 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector) match) { if (c->state <= IMPORT_PERMITTED) { lwc_string *url; - uint64_t media = 0; + css_mq_query *media = NULL; /* any0 = (STRING | URI) ws - * (IDENT ws (',' ws IDENT ws)* )? */ + * (media query)? */ const css_token *uri = parserutils_vector_iterate(vector, &ctx); if (uri == NULL || (uri->type != CSS_TOKEN_STRING && @@ -429,21 +427,24 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector) consumeWhitespace(vector, &ctx); /* Parse media list */ - error = parseMediaList(c, vector, &ctx, &media); + error = css__mq_parse_media_list(c, vector, &ctx, &media); if (error != CSS_OK) return error; /* Create rule */ error = css__stylesheet_rule_create(c->sheet, CSS_RULE_IMPORT, &rule); - if (error != CSS_OK) + if (error != CSS_OK) { + css__mq_query_unref(media); return error; + } /* Resolve import URI */ error = c->sheet->resolve(c->sheet->resolve_pw, c->sheet->url, uri->idata, &url); if (error != CSS_OK) { + css__mq_query_unref(media); css__stylesheet_rule_destroy(c->sheet, rule); return error; } @@ -453,6 +454,7 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector) rule, url, media); if (error != CSS_OK) { lwc_string_unref(url); + css__mq_query_unref(media); css__stylesheet_rule_destroy(c->sheet, rule); return error; } @@ -460,17 +462,19 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector) /* Inform client of need for import */ if (c->sheet->import != NULL) { error = c->sheet->import(c->sheet->import_pw, - c->sheet, url, media); + c->sheet, url); if (error != CSS_OK) { lwc_string_unref(url); + css__mq_query_unref(media); css__stylesheet_rule_destroy(c->sheet, rule); return error; } } - /* No longer care about url */ + /* No longer care about url or media */ lwc_string_unref(url); + css__mq_query_unref(media); /* Add rule to sheet */ error = css__stylesheet_add_rule(c->sheet, rule, NULL); @@ -527,31 +531,37 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector) } } else if (lwc_string_caseless_isequal(atkeyword->idata, c->strings[MEDIA], &match) == lwc_error_ok && match) { - uint64_t media = 0; + css_mq_query *media = NULL; - /* any0 = IDENT ws (',' ws IDENT ws)* */ + /* any0 = media query */ - error = parseMediaList(c, vector, &ctx, &media); + error = css__mq_parse_media_list(c, vector, &ctx, &media); if (error != CSS_OK) return error; error = css__stylesheet_rule_create(c->sheet, CSS_RULE_MEDIA, &rule); - if (error != CSS_OK) + if (error != CSS_OK) { + css__mq_query_unref(media); return error; + } error = css__stylesheet_rule_set_media(c->sheet, rule, media); if (error != CSS_OK) { css__stylesheet_rule_destroy(c->sheet, rule); + css__mq_query_unref(media); return error; } error = css__stylesheet_add_rule(c->sheet, rule, NULL); if (error != CSS_OK) { css__stylesheet_rule_destroy(c->sheet, rule); + css__mq_query_unref(media); return error; } + css__mq_query_unref(media); + /* Rule is now owned by the sheet, * so no need to destroy it */ @@ -795,85 +805,6 @@ css_error handleDeclaration(css_language *c, const parserutils_vector *vector) * At-rule parsing functions * ******************************************************************************/ -css_error parseMediaList(css_language *c, - const parserutils_vector *vector, int *ctx, - uint64_t *media) -{ - uint64_t ret = 0; - bool match = false; - const css_token *token; - - token = parserutils_vector_iterate(vector, ctx); - - while (token != NULL) { - if (token->type != CSS_TOKEN_IDENT) - return CSS_INVALID; - - if (lwc_string_caseless_isequal(token->idata, c->strings[AURAL], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_AURAL; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[BRAILLE], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_BRAILLE; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[EMBOSSED], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_EMBOSSED; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[HANDHELD], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_HANDHELD; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[PRINT], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_PRINT; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[PROJECTION], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_PROJECTION; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[SCREEN], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_SCREEN; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[SPEECH], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_SPEECH; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[TTY], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_TTY; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[TV], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_TV; - } else if (lwc_string_caseless_isequal( - token->idata, c->strings[ALL], - &match) == lwc_error_ok && match) { - ret |= CSS_MEDIA_ALL; - } else - return CSS_INVALID; - - consumeWhitespace(vector, ctx); - - token = parserutils_vector_iterate(vector, ctx); - if (token != NULL && tokenIsChar(token, ',') == false) - return CSS_INVALID; - - consumeWhitespace(vector, ctx); - } - - /* If, after parsing the media list, we still have no media, - * then it must be ALL. */ - if (ret == 0) - ret = CSS_MEDIA_ALL; - - *media = ret; - - return CSS_OK; -} - /** * Add a namespace mapping * -- cgit v1.2.3