MediaQueryList.cpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibWeb/CSS/MediaQueryList.h>
  8. #include <LibWeb/DOM/Document.h>
  9. #include <LibWeb/DOM/EventDispatcher.h>
  10. #include <LibWeb/DOM/IDLEventListener.h>
  11. #include <LibWeb/HTML/EventHandler.h>
  12. namespace Web::CSS {
  13. JS::NonnullGCPtr<MediaQueryList> MediaQueryList::create(DOM::Document& document, NonnullRefPtrVector<MediaQuery>&& media)
  14. {
  15. return *document.heap().allocate<MediaQueryList>(document.realm(), document, move(media));
  16. }
  17. MediaQueryList::MediaQueryList(DOM::Document& document, NonnullRefPtrVector<MediaQuery>&& media)
  18. : DOM::EventTarget(document.realm())
  19. , m_document(document)
  20. , m_media(move(media))
  21. {
  22. set_prototype(&document.window().cached_web_prototype("MediaQueryList"));
  23. evaluate();
  24. }
  25. void MediaQueryList::visit_edges(Cell::Visitor& visitor)
  26. {
  27. Base::visit_edges(visitor);
  28. visitor.visit(m_document.ptr());
  29. }
  30. // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-media
  31. String MediaQueryList::media() const
  32. {
  33. return serialize_a_media_query_list(m_media);
  34. }
  35. // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-matches
  36. bool MediaQueryList::matches() const
  37. {
  38. for (auto& media : m_media) {
  39. if (media.matches())
  40. return true;
  41. }
  42. return false;
  43. }
  44. bool MediaQueryList::evaluate()
  45. {
  46. bool now_matches = false;
  47. for (auto& media : m_media) {
  48. now_matches = now_matches || media.evaluate(m_document->window());
  49. }
  50. return now_matches;
  51. }
  52. // https://www.w3.org/TR/cssom-view/#dom-mediaquerylist-addlistener
  53. void MediaQueryList::add_listener(DOM::IDLEventListener* listener)
  54. {
  55. // 1. If listener is null, terminate these steps.
  56. if (!listener)
  57. return;
  58. // 2. Append an event listener to the associated list of event listeners with type set to change,
  59. // callback set to listener, and capture set to false, unless there already is an event listener
  60. // in that list with the same type, callback, and capture.
  61. // (NOTE: capture is set to false by default)
  62. add_event_listener_without_options(HTML::EventNames::change, *listener);
  63. }
  64. // https://www.w3.org/TR/cssom-view/#dom-mediaquerylist-removelistener
  65. void MediaQueryList::remove_listener(DOM::IDLEventListener* listener)
  66. {
  67. // 1. Remove an event listener from the associated list of event listeners, whose type is change, callback is listener, and capture is false.
  68. // NOTE: While the spec doesn't technically use remove_event_listener and instead manipulates the list directly, every major engine uses remove_event_listener.
  69. // This means if an event listener removes another event listener that comes after it, the removed event listener will not be invoked.
  70. remove_event_listener_without_options(HTML::EventNames::change, *listener);
  71. }
  72. void MediaQueryList::set_onchange(Bindings::CallbackType* event_handler)
  73. {
  74. set_event_handler_attribute(HTML::EventNames::change, event_handler);
  75. }
  76. Bindings::CallbackType* MediaQueryList::onchange()
  77. {
  78. return event_handler_attribute(HTML::EventNames::change);
  79. }
  80. }