diff --git a/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp b/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp index 2253fcf535..8fbc3a143d 100644 --- a/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp +++ b/Userland/Libraries/LibWeb/CSS/MediaQuery.cpp @@ -60,18 +60,18 @@ String MediaFeature::to_string() const switch (m_type) { case Type::IsTrue: - return serialize_an_identifier(m_name); + return string_from_media_feature_id(m_id); case Type::ExactValue: - return String::formatted("{}:{}", serialize_an_identifier(m_name), m_value->to_string()); + return String::formatted("{}:{}", string_from_media_feature_id(m_id), m_value->to_string()); case Type::MinValue: - return String::formatted("min-{}:{}", serialize_an_identifier(m_name), m_value->to_string()); + return String::formatted("min-{}:{}", string_from_media_feature_id(m_id), m_value->to_string()); case Type::MaxValue: - return String::formatted("max-{}:{}", serialize_an_identifier(m_name), m_value->to_string()); + return String::formatted("max-{}:{}", string_from_media_feature_id(m_id), m_value->to_string()); case Type::Range: if (!m_range->right_comparison.has_value()) - return String::formatted("{} {} {}", m_range->left_value.to_string(), comparison_string(m_range->left_comparison), serialize_an_identifier(m_name)); + return String::formatted("{} {} {}", m_range->left_value.to_string(), comparison_string(m_range->left_comparison), string_from_media_feature_id(m_id)); - return String::formatted("{} {} {} {} {}", m_range->left_value.to_string(), comparison_string(m_range->left_comparison), serialize_an_identifier(m_name), comparison_string(*m_range->right_comparison), m_range->right_value->to_string()); + return String::formatted("{} {} {} {} {}", m_range->left_value.to_string(), comparison_string(m_range->left_comparison), string_from_media_feature_id(m_id), comparison_string(*m_range->right_comparison), m_range->right_value->to_string()); } VERIFY_NOT_REACHED(); @@ -79,7 +79,7 @@ String MediaFeature::to_string() const bool MediaFeature::evaluate(HTML::Window const& window) const { - auto maybe_queried_value = window.query_media_feature(m_name); + auto maybe_queried_value = window.query_media_feature(m_id); if (!maybe_queried_value.has_value()) return false; auto queried_value = maybe_queried_value.release_value(); diff --git a/Userland/Libraries/LibWeb/CSS/MediaQuery.h b/Userland/Libraries/LibWeb/CSS/MediaQuery.h index 9cf0357b67..2045a47d26 100644 --- a/Userland/Libraries/LibWeb/CSS/MediaQuery.h +++ b/Userland/Libraries/LibWeb/CSS/MediaQuery.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -101,25 +102,29 @@ public: }; // Corresponds to `` grammar - static MediaFeature boolean(String const& name) + static MediaFeature boolean(MediaFeatureID id) { - return MediaFeature(Type::IsTrue, name); + return MediaFeature(Type::IsTrue, id); } // Corresponds to `` grammar - static MediaFeature plain(String const& name, MediaFeatureValue value) + static MediaFeature plain(MediaFeatureID id, MediaFeatureValue value) { - if (name.starts_with("min-", CaseSensitivity::CaseInsensitive)) - return MediaFeature(Type::MinValue, name.substring_view(4), move(value)); - if (name.starts_with("max-", CaseSensitivity::CaseInsensitive)) - return MediaFeature(Type::MaxValue, name.substring_view(4), move(value)); - return MediaFeature(Type::ExactValue, move(name), move(value)); + return MediaFeature(Type::ExactValue, move(id), move(value)); + } + static MediaFeature min(MediaFeatureID id, MediaFeatureValue value) + { + return MediaFeature(Type::MinValue, id, move(value)); + } + static MediaFeature max(MediaFeatureID id, MediaFeatureValue value) + { + return MediaFeature(Type::MaxValue, id, move(value)); } // Corresponds to `` grammar, with a single comparison - static MediaFeature half_range(MediaFeatureValue value, Comparison comparison, String const& name) + static MediaFeature half_range(MediaFeatureValue value, Comparison comparison, MediaFeatureID id) { - MediaFeature feature { Type::Range, name }; + MediaFeature feature { Type::Range, id }; feature.m_range = Range { .left_value = value, .left_comparison = comparison, @@ -128,9 +133,9 @@ public: } // Corresponds to `` grammar, with two comparisons - static MediaFeature range(MediaFeatureValue left_value, Comparison left_comparison, String const& name, Comparison right_comparison, MediaFeatureValue right_value) + static MediaFeature range(MediaFeatureValue left_value, Comparison left_comparison, MediaFeatureID id, Comparison right_comparison, MediaFeatureValue right_value) { - MediaFeature feature { Type::Range, name }; + MediaFeature feature { Type::Range, id }; feature.m_range = Range { .left_value = left_value, .left_comparison = left_comparison, @@ -152,9 +157,9 @@ private: Range, }; - MediaFeature(Type type, FlyString name, Optional value = {}) + MediaFeature(Type type, MediaFeatureID id, Optional value = {}) : m_type(type) - , m_name(move(name)) + , m_id(move(id)) , m_value(move(value)) { } @@ -169,7 +174,7 @@ private: }; Type m_type; - FlyString m_name; + MediaFeatureID m_id; Optional m_value {}; Optional m_range {}; }; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 8fa6a84ecc..26bafb7251 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -877,20 +877,31 @@ Optional Parser::parse_media_feature(TokenStream = ` - auto parse_mf_name = [](auto& tokens, bool allow_min_max_prefix) -> Optional { + struct MediaFeatureName { + enum Type { + Normal, + Min, + Max + } type; + MediaFeatureID id; + }; + auto parse_mf_name = [](auto& tokens, bool allow_min_max_prefix) -> Optional { auto& token = tokens.peek_token(); if (token.is(Token::Type::Ident)) { auto name = token.token().ident(); - if (is_media_feature_name(name)) { + if (auto id = media_feature_id_from_string(name); id.has_value()) { tokens.next_token(); - return name; + return MediaFeatureName { MediaFeatureName::Type::Normal, id.value() }; } if (allow_min_max_prefix && (name.starts_with("min-", CaseSensitivity::CaseInsensitive) || name.starts_with("max-", CaseSensitivity::CaseInsensitive))) { auto adjusted_name = name.substring_view(4); - if (is_media_feature_name(adjusted_name)) { + if (auto id = media_feature_id_from_string(adjusted_name); id.has_value()) { tokens.next_token(); - return name; + return MediaFeatureName { + name.starts_with("min-", CaseSensitivity::CaseInsensitive) ? MediaFeatureName::Type::Min : MediaFeatureName::Type::Max, + id.value() + }; } } } @@ -902,11 +913,10 @@ Optional Parser::parse_media_feature(TokenStreamid); } tokens.rewind_to_position(position); @@ -924,8 +934,17 @@ Optional Parser::parse_media_feature(TokenStreamtype) { + case MediaFeatureName::Type::Normal: + return MediaFeature::plain(maybe_name->id, maybe_value.release_value()); + case MediaFeatureName::Type::Min: + return MediaFeature::min(maybe_name->id, maybe_value.release_value()); + case MediaFeatureName::Type::Max: + return MediaFeature::max(maybe_name->id, maybe_value.release_value()); + } + VERIFY_NOT_REACHED(); + } } } } @@ -1016,7 +1035,7 @@ Optional Parser::parse_media_feature(TokenStreamis_ident()) - return MediaFeature::half_range(maybe_value.release_value(), flip(maybe_comparison.release_value()), maybe_name.release_value()); + return MediaFeature::half_range(maybe_value.release_value(), flip(maybe_comparison.release_value()), maybe_name->id); } } } @@ -1032,7 +1051,7 @@ Optional Parser::parse_media_feature(TokenStreamid); if (auto maybe_right_comparison = parse_comparison(tokens); maybe_right_comparison.has_value()) { tokens.skip_whitespace(); @@ -1049,7 +1068,7 @@ Optional Parser::parse_media_feature(TokenStreamis_ident() && !maybe_right_value->is_ident()) { - return MediaFeature::range(maybe_left_value.release_value(), left_comparison, maybe_name.release_value(), right_comparison, maybe_right_value.release_value()); + return MediaFeature::range(maybe_left_value.release_value(), left_comparison, maybe_name->id, right_comparison, maybe_right_value.release_value()); } } } diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index d8437d1064..f712eff310 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -372,52 +372,53 @@ NonnullRefPtr Window::match_media(String media) return media_query_list; } -Optional Window::query_media_feature(FlyString const& name) const +Optional Window::query_media_feature(CSS::MediaFeatureID media_feature) const { // FIXME: Many of these should be dependent on the hardware // MEDIAQUERIES-4 properties - https://www.w3.org/TR/mediaqueries-4/#media-descriptor-table - if (name.equals_ignoring_case("any-hover"sv)) + switch (media_feature) { + case CSS::MediaFeatureID::AnyHover: return CSS::MediaFeatureValue("hover"); - if (name.equals_ignoring_case("any-pointer"sv)) + case CSS::MediaFeatureID::AnyPointer: return CSS::MediaFeatureValue("fine"); - if (name.equals_ignoring_case("aspect-ratio"sv)) + case CSS::MediaFeatureID::AspectRatio: return CSS::MediaFeatureValue(CSS::Ratio(inner_width(), inner_height())); - if (name.equals_ignoring_case("color"sv)) + case CSS::MediaFeatureID::Color: return CSS::MediaFeatureValue(8); - if (name.equals_ignoring_case("color-gamut"sv)) + case CSS::MediaFeatureID::ColorGamut: return CSS::MediaFeatureValue("srgb"); - if (name.equals_ignoring_case("color-index"sv)) + case CSS::MediaFeatureID::ColorIndex: return CSS::MediaFeatureValue(0); // FIXME: device-aspect-ratio // FIXME: device-height // FIXME: device-width - if (name.equals_ignoring_case("grid"sv)) + case CSS::MediaFeatureID::Grid: return CSS::MediaFeatureValue(0); - if (name.equals_ignoring_case("height"sv)) + case CSS::MediaFeatureID::Height: return CSS::MediaFeatureValue(CSS::Length::make_px(inner_height())); - if (name.equals_ignoring_case("hover"sv)) + case CSS::MediaFeatureID::Hover: return CSS::MediaFeatureValue("hover"); - if (name.equals_ignoring_case("monochrome"sv)) + case CSS::MediaFeatureID::Monochrome: return CSS::MediaFeatureValue(0); - if (name.equals_ignoring_case("orientation"sv)) + case CSS::MediaFeatureID::Orientation: return CSS::MediaFeatureValue(inner_height() >= inner_width() ? "portrait" : "landscape"); - if (name.equals_ignoring_case("overflow-block"sv)) + case CSS::MediaFeatureID::OverflowBlock: return CSS::MediaFeatureValue("scroll"); - if (name.equals_ignoring_case("overflow-inline"sv)) + case CSS::MediaFeatureID::OverflowInline: return CSS::MediaFeatureValue("scroll"); - if (name.equals_ignoring_case("pointer"sv)) + case CSS::MediaFeatureID::Pointer: return CSS::MediaFeatureValue("fine"); // FIXME: resolution - if (name.equals_ignoring_case("scan"sv)) + case CSS::MediaFeatureID::Scan: return CSS::MediaFeatureValue("progressive"); - if (name.equals_ignoring_case("update"sv)) + case CSS::MediaFeatureID::Update: return CSS::MediaFeatureValue("fast"); - if (name.equals_ignoring_case("width"sv)) + case CSS::MediaFeatureID::Width: return CSS::MediaFeatureValue(CSS::Length::make_px(inner_width())); // MEDIAQUERIES-5 properties - https://www.w3.org/TR/mediaqueries-5/#media-descriptor-table - if (name.equals_ignoring_case("prefers-color-scheme")) { + case CSS::MediaFeatureID::PrefersColorScheme: { if (auto* page = this->page()) { switch (page->preferred_color_scheme()) { case CSS::PreferredColorScheme::Light: @@ -429,6 +430,11 @@ Optional Window::query_media_feature(FlyString const& na return CSS::MediaFeatureValue(page->palette().is_dark() ? "dark" : "light"); } } + return CSS::MediaFeatureValue(CSS::ValueID::Light); + } + + default: + break; } return {}; diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index f9bca0fa15..cb6c7414f5 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -89,7 +89,7 @@ public: NonnullRefPtr get_computed_style(DOM::Element&) const; NonnullRefPtr match_media(String); - Optional query_media_feature(FlyString const&) const; + Optional query_media_feature(CSS::MediaFeatureID) const; float scroll_x() const; float scroll_y() const;