From 5cd8a2a7b7c1aff763c805a8459a15a3aba6f6e4 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sun, 5 May 2019 18:07:21 +0100 Subject: Media queries: Selection: Start implementing mq matching. --- src/select/mq.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/select/mq.h b/src/select/mq.h index 290505c..436eb90 100644 --- a/src/select/mq.h +++ b/src/select/mq.h @@ -12,32 +12,84 @@ /** * Match media query conditions. * - * \param[in] cond Condition to match. + * \param[in] feat Condition to match. + * \param[in] media Current media spec, to check against feat. * \return true if condition matches, otherwise false. */ -static inline bool mq_match_condition(css_mq_cond *cond) +static inline bool mq_match_feature( + const css_mq_feature *feat, + const css_media *media) { /* TODO: Implement this. */ - (void) cond; + (void) feat; + (void) media; + return true; } +/** + * Match media query conditions. + * + * \param[in] cond Condition to match. + * \param[in] media Current media spec, to check against cond. + * \return true if condition matches, otherwise false. + */ +static inline bool mq_match_condition( + const css_mq_cond *cond, + const css_media *media) +{ + bool matched = !cond->op; + + for (uint32_t i = 0; i < cond->parts->nparts; i++) { + bool part_matched; + if (cond->parts->parts[i]->type == CSS_MQ_FEATURE) { + part_matched = mq_match_feature( + cond->parts->parts[i]->data.feat, + media); + } else { + assert(cond->parts->parts[i]->type == SS_MQ_COND); + part_matched = mq_match_condition( + cond->parts->parts[i]->data.cond, + media); + } + + if (cond->op) { + /* OR */ + matched |= part_matched; + if (matched) { + break; /* Short-circuit */ + } + } else { + /* AND */ + matched &= part_matched; + if (!matched) { + break; /* Short-circuit */ + } + } + } + + return matched != cond->negate; +} + /** * Test whether media query list matches current media. * * If anything in the list matches, the list matches. If none match * it doesn't match. * - * \param m Media query list. - * \meaid media Current media spec, to check against m. + * \param[in] m Media query list. + * \param[in] media Current media spec, to check against m. * \return true if media query list matches media */ -static inline bool mq__list_match(const css_mq_query *m, const css_media *media) +static inline bool mq__list_match( + const css_mq_query *m, + const css_media *media) { for (; m != NULL; m = m->next) { /* Check type */ if (!!(m->type & media->type) != m->negate_type) { - if (mq_match_condition(m->cond)) { + if (m->cond == NULL || + mq_match_condition(m->cond, media)) { /* We have a match, no need to look further. */ return true; } @@ -51,7 +103,7 @@ static inline bool mq__list_match(const css_mq_query *m, const css_media *media) * Test whether the rule applies for current media. * * \param rule Rule to test - * \param media Current media type(s) + * \param media Current media spec * \return true iff chain's rule applies for media */ static inline bool mq_rule_good_for_media(const css_rule *rule, const css_media *media) -- cgit v1.2.3