Supports.cpp 2.9 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(NonnullOwnPtr<Condition>&& condition)
  11. : m_condition(move(condition))
  12. {
  13. m_matches = m_condition->evaluate();
  14. }
  15. bool Supports::Condition::evaluate() const
  16. {
  17. switch (type) {
  18. case Type::Not:
  19. return !children.first().evaluate();
  20. case Type::And:
  21. for (auto& child : children) {
  22. if (!child.evaluate())
  23. return false;
  24. }
  25. return true;
  26. case Type::Or:
  27. for (auto& child : children) {
  28. if (child.evaluate())
  29. return true;
  30. }
  31. return false;
  32. }
  33. VERIFY_NOT_REACHED();
  34. }
  35. bool Supports::InParens::evaluate() const
  36. {
  37. return value.visit(
  38. [&](NonnullOwnPtr<Condition> const& condition) {
  39. return condition->evaluate();
  40. },
  41. [&](Feature const& feature) {
  42. return feature.evaluate();
  43. },
  44. [&](GeneralEnclosed const&) {
  45. return false;
  46. });
  47. }
  48. bool Supports::Declaration::evaluate() 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() const
  54. {
  55. auto style_property = parse_selector(Parser::ParsingContext { *realm }, selector);
  56. return style_property.has_value();
  57. }
  58. bool Supports::Feature::evaluate() const
  59. {
  60. return value.visit(
  61. [&](Declaration const& declaration) {
  62. return declaration.evaluate();
  63. },
  64. [&](Selector const& selector) {
  65. return selector.evaluate();
  66. });
  67. }
  68. ErrorOr<String> Supports::Declaration::to_string() const
  69. {
  70. return String::formatted("({})", declaration);
  71. }
  72. ErrorOr<String> Supports::Selector::to_string() const
  73. {
  74. return String::formatted("selector({})", selector);
  75. }
  76. ErrorOr<String> Supports::Feature::to_string() const
  77. {
  78. return value.visit([](auto& it) { return it.to_string(); });
  79. }
  80. ErrorOr<String> Supports::InParens::to_string() const
  81. {
  82. return value.visit(
  83. [](NonnullOwnPtr<Condition> const& condition) -> ErrorOr<String> { return String::formatted("({})", TRY(condition->to_string())); },
  84. [](Supports::Feature const& it) -> ErrorOr<String> { return it.to_string(); },
  85. [](GeneralEnclosed const& it) -> ErrorOr<String> { return it.to_string(); });
  86. }
  87. ErrorOr<String> Supports::Condition::to_string() const
  88. {
  89. switch (type) {
  90. case Type::Not:
  91. return String::formatted("not {}", TRY(children.first().to_string()));
  92. case Type::And:
  93. return String::join(" and "sv, children);
  94. case Type::Or:
  95. return String::join(" or "sv, children);
  96. }
  97. VERIFY_NOT_REACHED();
  98. }
  99. ErrorOr<String> Supports::to_string() const
  100. {
  101. return m_condition->to_string();
  102. }
  103. }