MediaQuery.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/FlyString.h>
  8. #include <AK/NonnullOwnPtrVector.h>
  9. #include <AK/NonnullRefPtr.h>
  10. #include <AK/Optional.h>
  11. #include <AK/OwnPtr.h>
  12. #include <AK/RefCounted.h>
  13. #include <LibWeb/CSS/GeneralEnclosed.h>
  14. #include <LibWeb/CSS/StyleValue.h>
  15. namespace Web::CSS {
  16. // https://www.w3.org/TR/mediaqueries-4/#typedef-mf-value
  17. class MediaFeatureValue {
  18. public:
  19. explicit MediaFeatureValue(String ident)
  20. : m_value(move(ident))
  21. {
  22. }
  23. explicit MediaFeatureValue(Length length)
  24. : m_value(move(length))
  25. {
  26. }
  27. explicit MediaFeatureValue(double number)
  28. : m_value(number)
  29. {
  30. }
  31. String to_string() const;
  32. bool is_ident() const { return m_value.has<String>(); }
  33. bool is_length() const { return m_value.has<Length>(); }
  34. bool is_number() const { return m_value.has<double>(); }
  35. bool is_same_type(MediaFeatureValue const& other) const;
  36. String const& ident() const
  37. {
  38. VERIFY(is_ident());
  39. return m_value.get<String>();
  40. }
  41. Length const& length() const
  42. {
  43. VERIFY(is_length());
  44. return m_value.get<Length>();
  45. }
  46. double number() const
  47. {
  48. VERIFY(is_number());
  49. return m_value.get<double>();
  50. }
  51. bool operator==(MediaFeatureValue const& other) const { return equals(other); }
  52. bool operator!=(MediaFeatureValue const& other) const { return !(*this == other); }
  53. bool equals(MediaFeatureValue const& other) const;
  54. private:
  55. // TODO: Support <ratio> once we have that.
  56. Variant<String, Length, double> m_value;
  57. };
  58. class MediaQuery : public RefCounted<MediaQuery> {
  59. friend class Parser;
  60. public:
  61. ~MediaQuery() = default;
  62. // https://www.w3.org/TR/mediaqueries-4/#media-types
  63. enum class MediaType {
  64. All,
  65. Print,
  66. Screen,
  67. // Deprecated, must never match:
  68. TTY,
  69. TV,
  70. Projection,
  71. Handheld,
  72. Braille,
  73. Embossed,
  74. Aural,
  75. Speech,
  76. };
  77. // https://www.w3.org/TR/mediaqueries-4/#mq-features
  78. struct MediaFeature {
  79. // FIXME: Implement range syntax: https://www.w3.org/TR/mediaqueries-4/#mq-ranges
  80. enum class Type {
  81. IsTrue,
  82. ExactValue,
  83. MinValue,
  84. MaxValue,
  85. };
  86. Type type;
  87. FlyString name;
  88. Optional<MediaFeatureValue> value {};
  89. bool evaluate(DOM::Window const&) const;
  90. String to_string() const;
  91. };
  92. // https://www.w3.org/TR/mediaqueries-4/#media-conditions
  93. struct MediaCondition {
  94. enum class Type {
  95. Single,
  96. And,
  97. Or,
  98. Not,
  99. GeneralEnclosed,
  100. };
  101. Type type;
  102. MediaFeature feature;
  103. NonnullOwnPtrVector<MediaCondition> conditions;
  104. Optional<GeneralEnclosed> general_enclosed;
  105. MatchResult evaluate(DOM::Window const&) const;
  106. String to_string() const;
  107. };
  108. static NonnullRefPtr<MediaQuery> create_not_all();
  109. static NonnullRefPtr<MediaQuery> create() { return adopt_ref(*new MediaQuery); }
  110. bool matches() const { return m_matches; }
  111. bool evaluate(DOM::Window const&);
  112. String to_string() const;
  113. private:
  114. MediaQuery() = default;
  115. // https://www.w3.org/TR/mediaqueries-4/#mq-not
  116. bool m_negated { false };
  117. MediaType m_media_type { MediaType::All };
  118. OwnPtr<MediaCondition> m_media_condition { nullptr };
  119. // Cached value, updated by evaluate()
  120. bool m_matches { false };
  121. };
  122. String serialize_a_media_query_list(NonnullRefPtrVector<MediaQuery> const&);
  123. }
  124. namespace AK {
  125. template<>
  126. struct Formatter<Web::CSS::MediaQuery::MediaFeature> : Formatter<StringView> {
  127. ErrorOr<void> format(FormatBuilder& builder, Web::CSS::MediaQuery::MediaFeature const& media_feature)
  128. {
  129. return Formatter<StringView>::format(builder, media_feature.to_string());
  130. }
  131. };
  132. template<>
  133. struct Formatter<Web::CSS::MediaQuery::MediaCondition> : Formatter<StringView> {
  134. ErrorOr<void> format(FormatBuilder& builder, Web::CSS::MediaQuery::MediaCondition const& media_condition)
  135. {
  136. return Formatter<StringView>::format(builder, media_condition.to_string());
  137. }
  138. };
  139. template<>
  140. struct Formatter<Web::CSS::MediaQuery> : Formatter<StringView> {
  141. ErrorOr<void> format(FormatBuilder& builder, Web::CSS::MediaQuery const& media_query)
  142. {
  143. return Formatter<StringView>::format(builder, media_query.to_string());
  144. }
  145. };
  146. }