HTMLVideoElement.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibGfx/Bitmap.h>
  8. #include <LibWeb/Bindings/Intrinsics.h>
  9. #include <LibWeb/DOM/Document.h>
  10. #include <LibWeb/HTML/HTMLVideoElement.h>
  11. #include <LibWeb/HTML/VideoTrack.h>
  12. #include <LibWeb/Layout/VideoBox.h>
  13. namespace Web::HTML {
  14. HTMLVideoElement::HTMLVideoElement(DOM::Document& document, DOM::QualifiedName qualified_name)
  15. : HTMLMediaElement(document, move(qualified_name))
  16. {
  17. }
  18. HTMLVideoElement::~HTMLVideoElement() = default;
  19. JS::ThrowCompletionOr<void> HTMLVideoElement::initialize(JS::Realm& realm)
  20. {
  21. MUST_OR_THROW_OOM(Base::initialize(realm));
  22. set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLVideoElementPrototype>(realm, "HTMLVideoElement"));
  23. return {};
  24. }
  25. void HTMLVideoElement::visit_edges(Cell::Visitor& visitor)
  26. {
  27. Base::visit_edges(visitor);
  28. visitor.visit(m_video_track);
  29. }
  30. JS::GCPtr<Layout::Node> HTMLVideoElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
  31. {
  32. return heap().allocate_without_realm<Layout::VideoBox>(document(), *this, move(style));
  33. }
  34. Layout::VideoBox* HTMLVideoElement::layout_node()
  35. {
  36. return static_cast<Layout::VideoBox*>(Node::layout_node());
  37. }
  38. Layout::VideoBox const* HTMLVideoElement::layout_node() const
  39. {
  40. return static_cast<Layout::VideoBox const*>(Node::layout_node());
  41. }
  42. // https://html.spec.whatwg.org/multipage/media.html#dom-video-videowidth
  43. u32 HTMLVideoElement::video_width() const
  44. {
  45. // The videoWidth IDL attribute must return the intrinsic width of the video in CSS pixels. The videoHeight IDL
  46. // attribute must return the intrinsic height of the video in CSS pixels. If the element's readyState attribute
  47. // is HAVE_NOTHING, then the attributes must return 0.
  48. if (ready_state() == ReadyState::HaveNothing)
  49. return 0;
  50. return m_video_width;
  51. }
  52. // https://html.spec.whatwg.org/multipage/media.html#dom-video-videoheight
  53. u32 HTMLVideoElement::video_height() const
  54. {
  55. // The videoWidth IDL attribute must return the intrinsic width of the video in CSS pixels. The videoHeight IDL
  56. // attribute must return the intrinsic height of the video in CSS pixels. If the element's readyState attribute
  57. // is HAVE_NOTHING, then the attributes must return 0.
  58. if (ready_state() == ReadyState::HaveNothing)
  59. return 0;
  60. return m_video_height;
  61. }
  62. void HTMLVideoElement::set_video_track(JS::GCPtr<HTML::VideoTrack> video_track)
  63. {
  64. set_needs_style_update(true);
  65. document().set_needs_layout();
  66. if (m_video_track)
  67. m_video_track->pause_video({});
  68. m_video_track = video_track;
  69. }
  70. void HTMLVideoElement::set_current_frame(Badge<VideoTrack>, RefPtr<Gfx::Bitmap> frame)
  71. {
  72. m_current_frame = move(frame);
  73. layout_node()->set_needs_display();
  74. }
  75. void HTMLVideoElement::on_playing()
  76. {
  77. if (m_video_track)
  78. m_video_track->play_video({});
  79. }
  80. void HTMLVideoElement::on_paused()
  81. {
  82. if (m_video_track)
  83. m_video_track->pause_video({});
  84. }
  85. void HTMLVideoElement::on_seek(double position, MediaSeekMode seek_mode)
  86. {
  87. if (m_video_track)
  88. m_video_track->seek(Time::from_milliseconds(position * 1000.0), seek_mode);
  89. }
  90. }