Supports.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Runtime/Realm.h>
  7. #include <LibWeb/CSS/Parser/Parser.h>
  8. #include <LibWeb/CSS/Supports.h>
  9. namespace Web::CSS {
  10. Supports::Supports(JS::Realm& realm, NonnullOwnPtr<Condition>&& condition)
  11. : m_condition(move(condition))
  12. {
  13. m_matches = m_condition->evaluate(realm);
  14. }
  15. bool Supports::Condition::evaluate(JS::Realm& realm) const
  16. {
  17. switch (type) {
  18. case Type::Not:
  19. return !children.first().evaluate(realm);
  20. case Type::And:
  21. for (auto& child : children) {
  22. if (!child.evaluate(realm))
  23. return false;
  24. }
  25. return true;
  26. case Type::Or:
  27. for (auto& child : children) {
  28. if (child.evaluate(realm))
  29. return true;
  30. }
  31. return false;
  32. }
  33. VERIFY_NOT_REACHED();
  34. }
  35. bool Supports::InParens::evaluate(JS::Realm& realm) const
  36. {
  37. return value.visit(
  38. [&](NonnullOwnPtr<Condition> const& condition) {
  39. return condition->evaluate(realm);
  40. },
  41. [&](Feature const& feature) {
  42. return feature.evaluate(realm);
  43. },
  44. [&](GeneralEnclosed const&) {
  45. return false;
  46. });
  47. }
  48. bool Supports::Declaration::evaluate(JS::Realm& realm) const
  49. {
  50. auto style_property = parse_css_supports_condition(Parser::ParsingContext { realm }, declaration);
  51. return style_property.has_value();
  52. }
  53. bool Supports::Selector::evaluate(JS::Realm& realm) const
  54. {
  55. auto style_property = parse_selector(Parser::ParsingContext { realm }, selector);
  56. return style_property.has_value();
  57. }
  58. bool Supports::Feature::evaluate(JS::Realm& realm) const
  59. {
  60. return value.visit(
  61. [&](Declaration const& declaration) {
  62. return declaration.evaluate(realm);
  63. },
  64. [&](Selector const& selector) {
  65. return selector.evaluate(realm);
  66. });
  67. }
  68. String Supports::Declaration::to_string() const
  69. {
  70. return MUST(String::formatted("({})", declaration));
  71. }
  72. String Supports::Selector::to_string() const
  73. {
  74. return MUST(String::formatted("selector({})", selector));
  75. }
  76. String Supports::Feature::to_string() const
  77. {
  78. return value.visit([](auto& it) { return it.to_string(); });
  79. }
  80. String Supports::InParens::to_string() const
  81. {
  82. return value.visit(
  83. [](NonnullOwnPtr<Condition> const& condition) { return MUST(String::formatted("({})", condition->to_string())); },
  84. [](Supports::Feature const& it) { return it.to_string(); },
  85. [](GeneralEnclosed const& it) { return it.to_string(); });
  86. }
  87. String Supports::Condition::to_string() const
  88. {
  89. switch (type) {
  90. case Type::Not:
  91. return MUST(String::formatted("not {}", children.first().to_string()));
  92. case Type::And:
  93. return MUST(String::join(" and "sv, children));
  94. case Type::Or:
  95. return MUST(String::join(" or "sv, children));
  96. }
  97. VERIFY_NOT_REACHED();
  98. }
  99. String Supports::to_string() const
  100. {
  101. return m_condition->to_string();
  102. }
  103. }