MediaList.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  3. * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibWeb/Bindings/Intrinsics.h>
  8. #include <LibWeb/Bindings/MediaListPrototype.h>
  9. #include <LibWeb/CSS/MediaList.h>
  10. #include <LibWeb/CSS/Parser/Parser.h>
  11. namespace Web::CSS {
  12. MediaList* MediaList::create(JS::Realm& realm, NonnullRefPtrVector<MediaQuery>&& media)
  13. {
  14. return realm.heap().allocate<MediaList>(realm, realm, move(media)).release_allocated_value_but_fixme_should_propagate_errors();
  15. }
  16. MediaList::MediaList(JS::Realm& realm, NonnullRefPtrVector<MediaQuery>&& media)
  17. : Bindings::LegacyPlatformObject(realm)
  18. , m_media(move(media))
  19. {
  20. }
  21. JS::ThrowCompletionOr<void> MediaList::initialize(JS::Realm& realm)
  22. {
  23. MUST_OR_THROW_OOM(Base::initialize(realm));
  24. set_prototype(&Bindings::ensure_web_prototype<Bindings::MediaListPrototype>(realm, "MediaList"));
  25. return {};
  26. }
  27. // https://www.w3.org/TR/cssom-1/#dom-medialist-mediatext
  28. DeprecatedString MediaList::media_text() const
  29. {
  30. return serialize_a_media_query_list(m_media);
  31. }
  32. // https://www.w3.org/TR/cssom-1/#dom-medialist-mediatext
  33. void MediaList::set_media_text(DeprecatedString const& text)
  34. {
  35. m_media.clear();
  36. if (text.is_empty())
  37. return;
  38. m_media = parse_media_query_list({}, text);
  39. }
  40. bool MediaList::is_supported_property_index(u32 index) const
  41. {
  42. return index < length();
  43. }
  44. // https://www.w3.org/TR/cssom-1/#dom-medialist-item
  45. DeprecatedString MediaList::item(u32 index) const
  46. {
  47. if (!is_supported_property_index(index))
  48. return {};
  49. return m_media[index].to_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string();
  50. }
  51. // https://www.w3.org/TR/cssom-1/#dom-medialist-appendmedium
  52. void MediaList::append_medium(DeprecatedString medium)
  53. {
  54. auto m = parse_media_query({}, medium);
  55. if (!m)
  56. return;
  57. if (m_media.contains_slow(*m))
  58. return;
  59. m_media.append(m.release_nonnull());
  60. }
  61. // https://www.w3.org/TR/cssom-1/#dom-medialist-deletemedium
  62. void MediaList::delete_medium(DeprecatedString medium)
  63. {
  64. auto m = parse_media_query({}, medium);
  65. if (!m)
  66. return;
  67. m_media.remove_all_matching([&](auto& existing) -> bool {
  68. return m->to_string().release_value_but_fixme_should_propagate_errors() == existing->to_string().release_value_but_fixme_should_propagate_errors();
  69. });
  70. // FIXME: If nothing was removed, then throw a NotFoundError exception.
  71. }
  72. bool MediaList::evaluate(HTML::Window const& window)
  73. {
  74. for (auto& media : m_media)
  75. media.evaluate(window);
  76. return matches();
  77. }
  78. bool MediaList::matches() const
  79. {
  80. if (m_media.is_empty()) {
  81. return true;
  82. }
  83. for (auto& media : m_media) {
  84. if (media.matches())
  85. return true;
  86. }
  87. return false;
  88. }
  89. JS::Value MediaList::item_value(size_t index) const
  90. {
  91. if (index >= m_media.size())
  92. return JS::js_undefined();
  93. return JS::PrimitiveString::create(vm(), m_media[index].to_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string());
  94. }
  95. }