瀏覽代碼

LibWeb: Move dispatching timeupdate events to a helper for tracking

For some media APIs, we will need to know whether we are currently in an
event handler for the timeupdate event, and the last time we fired the
event.
Timothy Flynn 2 年之前
父節點
當前提交
2ef4a51c39

+ 12 - 1
Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp

@@ -929,7 +929,7 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::pause_element()
             auto& realm = this->realm();
 
             // 1. Fire an event named timeupdate at the element.
-            dispatch_event(DOM::Event::create(realm, HTML::EventNames::timeupdate).release_value_but_fixme_should_propagate_errors());
+            dispatch_time_update_event().release_value_but_fixme_should_propagate_errors();
 
             // 2. Fire an event named pause at the element.
             dispatch_event(DOM::Event::create(realm, HTML::EventNames::pause).release_value_but_fixme_should_propagate_errors());
@@ -973,6 +973,17 @@ void HTMLMediaElement::set_paused(bool paused)
         on_paused();
 }
 
+WebIDL::ExceptionOr<void> HTMLMediaElement::dispatch_time_update_event()
+{
+    ScopeGuard guard { [this] { m_running_time_update_event_handler = false; } };
+    m_running_time_update_event_handler = true;
+
+    m_last_time_update_event_time = Time::now_monotonic();
+
+    dispatch_event(TRY(DOM::Event::create(realm(), HTML::EventNames::timeupdate)));
+    return {};
+}
+
 // https://html.spec.whatwg.org/multipage/media.html#take-pending-play-promises
 JS::MarkedVector<JS::NonnullGCPtr<WebIDL::Promise>> HTMLMediaElement::take_pending_play_promises()
 {

+ 6 - 0
Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h

@@ -8,6 +8,7 @@
 #pragma once
 
 #include <AK/ByteBuffer.h>
+#include <AK/Time.h>
 #include <AK/Variant.h>
 #include <LibJS/Heap/MarkedVector.h>
 #include <LibJS/SafeFunction.h>
@@ -87,6 +88,8 @@ private:
     void set_paused(bool);
     void set_duration(double);
 
+    WebIDL::ExceptionOr<void> dispatch_time_update_event();
+
     JS::MarkedVector<JS::NonnullGCPtr<WebIDL::Promise>> take_pending_play_promises();
     void resolve_pending_play_promises(ReadonlySpan<JS::NonnullGCPtr<WebIDL::Promise>> promises);
     void reject_pending_play_promises(ReadonlySpan<JS::NonnullGCPtr<WebIDL::Promise>> promises, JS::NonnullGCPtr<WebIDL::DOMException> error);
@@ -126,6 +129,9 @@ private:
     // https://html.spec.whatwg.org/multipage/media.html#media-data
     ByteBuffer m_media_data;
 
+    bool m_running_time_update_event_handler { false };
+    Optional<Time> m_last_time_update_event_time;
+
     JS::GCPtr<Fetch::Infrastructure::FetchController> m_fetch_controller;
 };