From a7830f2452116f57e7880a3f1802c1c3bf1209c9 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 6 May 2019 15:29:58 +0100 Subject: Media queries: Start implementing feature matching. Currently we just look at: - width - height TODO: - Unit conversion - Use interned string comparison --- src/select/mq.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/src/select/mq.h b/src/select/mq.h index e4c09af..1c07ecc 100644 --- a/src/select/mq.h +++ b/src/select/mq.h @@ -9,8 +9,71 @@ #ifndef css_select_mq_h_ #define css_select_mq_h_ +static inline bool mq_match_feature_range_length_op1( + css_mq_feature_op op, + const css_mq_value *value, + const css_media_length *client_len) +{ + if (value->type != CSS_MQ_VALUE_TYPE_DIM) { + return false; + } + /* TODO: convert to same units */ + if (value->data.dim.unit != client_len->unit) { + return false; + } + + switch (op) { + case CSS_MQ_FEATURE_OP_BOOL: + return false; + case CSS_MQ_FEATURE_OP_LT: + return value->data.dim.len < client_len->value; + case CSS_MQ_FEATURE_OP_LTE: + return value->data.dim.len <= client_len->value; + case CSS_MQ_FEATURE_OP_EQ: + return value->data.dim.len == client_len->value; + case CSS_MQ_FEATURE_OP_GTE: + return value->data.dim.len >= client_len->value; + case CSS_MQ_FEATURE_OP_GT: + return value->data.dim.len > client_len->value; + default: + return false; + } +} + +static inline bool mq_match_feature_range_length_op2( + css_mq_feature_op op, + const css_mq_value *value, + const css_media_length *client_len) +{ + if (op == CSS_MQ_FEATURE_OP_UNUSED) { + return true; + } + if (value->type != CSS_MQ_VALUE_TYPE_DIM) { + return false; + } + /* TODO: convert to same units */ + if (value->data.dim.unit != client_len->unit) { + return false; + } + + switch (op) { + case CSS_MQ_FEATURE_OP_LT: + return client_len->value < value->data.dim.len; + case CSS_MQ_FEATURE_OP_LTE: + return client_len->value <= value->data.dim.len; + case CSS_MQ_FEATURE_OP_EQ: + return client_len->value == value->data.dim.len; + case CSS_MQ_FEATURE_OP_GTE: + return client_len->value >= value->data.dim.len; + case CSS_MQ_FEATURE_OP_GT: + return client_len->value > value->data.dim.len; + default: + return false; + } +} + /** - * Match media query conditions. + * Match media query features. * * \param[in] feat Condition to match. * \param[in] media Current media spec, to check against feat. @@ -20,11 +83,28 @@ static inline bool mq_match_feature( const css_mq_feature *feat, const css_media *media) { - /* TODO: Implement this. */ - (void) feat; - (void) media; + /* TODO: Use interned string for comparison. */ + if (strcmp(lwc_string_data(feat->name), "width") == 0) { + if (!mq_match_feature_range_length_op1( + feat->op, &feat->value, &media->width)) { + return false; + } + return mq_match_feature_range_length_op2( + feat->op2, &feat->value2, &media->width); - return true; + } else if (strcmp(lwc_string_data(feat->name), "height") == 0) { + if (!mq_match_feature_range_length_op1( + feat->op, &feat->value, &media->height)) { + return false; + } + + return mq_match_feature_range_length_op2( + feat->op2, &feat->value2, &media->height); + } + + /* TODO: Look at other feature names. */ + + return false; } /** -- cgit v1.2.3