MediaQueryList.cpp 2.9 KB

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