summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-04-17 07:24:50 -0400
committerAndreas Kling <kling@serenityos.org>2023-04-18 16:30:02 +0200
commit229cc67feef244c6117171b09bb2d75edb3aac44 (patch)
treec31893c50ed39521d07e7766d489685c69da4bbc
parent1ffd533ea27f43807d12a44605ea0a0de9436174 (diff)
downloadserenity-229cc67feef244c6117171b09bb2d75edb3aac44.zip
LibWeb: Implement HTMLMediaElement's autoplay attribute
-rw-r--r--Base/res/html/misc/video-webm.html2
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp56
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h4
3 files changed, 52 insertions, 10 deletions
diff --git a/Base/res/html/misc/video-webm.html b/Base/res/html/misc/video-webm.html
index 5ef64606d9..d48e9ee88e 100644
--- a/Base/res/html/misc/video-webm.html
+++ b/Base/res/html/misc/video-webm.html
@@ -77,7 +77,7 @@
<br />
- <video id=video controls src="file:///home/anon/Videos/test-webm.webm"></video>
+ <video id=video autoplay controls src="file:///home/anon/Videos/test-webm.webm"></video>
<script type="text/javascript">
let video = document.getElementById('video');
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp
index 2b6d25d481..54a7f9d15c 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp
@@ -335,7 +335,10 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::load_element()
}
// FIXME: 7. Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.
- // FIXME: 8. Set the error attribute to null and the can autoplay flag to true.
+
+ // 8. Set the error attribute to null and the can autoplay flag to true.
+ // FIXME: Handle the error attribute.
+ m_can_autoplay = true;
// 9. Invoke the media element's resource selection algorithm.
TRY(select_resource());
@@ -934,13 +937,25 @@ void HTMLMediaElement::set_ready_state(ReadyState ready_state)
dispatch_event(DOM::Event::create(this->realm(), HTML::EventNames::canplaythrough).release_value_but_fixme_should_propagate_errors());
});
- // FIXME: If the element is not eligible for autoplay, then the user agent must abort these substeps.
+ // If the element is not eligible for autoplay, then the user agent must abort these substeps.
+ if (!is_eligible_for_autoplay())
+ return;
+
+ // The user agent may run the following substeps:
+ {
+ // Set the paused attribute to false.
+ set_paused(false);
+
+ // FIXME: If the element's show poster flag is true, set it to false and run the time marches on steps.
- // FIXME: The user agent may run the following substeps:
- // Set the paused attribute to false.
- // If the element's show poster flag is true, set it to false and run the time marches on steps.
- // Queue a media element task given the element to fire an event named play at the element.
- // Notify about playing for the element.
+ // Queue a media element task given the element to fire an event named play at the element.
+ queue_a_media_element_task([this]() {
+ dispatch_event(DOM::Event::create(realm(), HTML::EventNames::play).release_value_but_fixme_should_propagate_errors());
+ });
+
+ // Notify about playing for the element.
+ notify_about_playing();
+ }
// FIXME: Alternatively, if the element is a video element, the user agent may start observing whether the element intersects the viewport. When the
// element starts intersecting the viewport, if the element is still eligible for autoplay, run the substeps above. Optionally, when the element
@@ -1003,7 +1018,8 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::play_element()
});
}
- // FIXME: 5. Set the media element's can autoplay flag to false.
+ // 5. Set the media element's can autoplay flag to false.
+ m_can_autoplay = false;
return {};
}
@@ -1011,7 +1027,8 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::play_element()
// https://html.spec.whatwg.org/multipage/media.html#internal-pause-steps
WebIDL::ExceptionOr<void> HTMLMediaElement::pause_element()
{
- // FIXME: 1. Set the media element's can autoplay flag to false.
+ // 1. Set the media element's can autoplay flag to false.
+ m_can_autoplay = false;
// 2. If the media element's paused attribute is false, run the following steps:
if (!paused()) {
@@ -1146,6 +1163,27 @@ void HTMLMediaElement::set_paused(bool paused)
on_paused();
}
+// https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay
+bool HTMLMediaElement::is_eligible_for_autoplay() const
+{
+ // A media element is said to be eligible for autoplay when all of the following conditions are met:
+ return (
+ // Its can autoplay flag is true.
+ m_can_autoplay &&
+
+ // Its paused attribute is true.
+ paused() &&
+
+ // It has an autoplay attribute specified.
+ has_attribute(HTML::AttributeNames::autoplay) &&
+
+ // Its node document's active sandboxing flag set does not have the sandboxed automatic features browsing context flag set.
+ (document().active_sandboxing_flag_set().flags & SandboxingFlagSet::SandboxedAutomaticFeatures) == 0 &&
+
+ // Its node document is allowed to use the "autoplay" feature.
+ document().is_allowed_to_use_feature(DOM::PolicyControlledFeature::Autoplay));
+}
+
// https://html.spec.whatwg.org/multipage/media.html#ended-playback
bool HTMLMediaElement::has_ended_playback() const
{
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h
index 0e03438239..d7c62fe867 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h
@@ -106,6 +106,7 @@ private:
void set_paused(bool);
void set_duration(double);
+ bool is_eligible_for_autoplay() const;
bool has_ended_playback() const;
WebIDL::ExceptionOr<void> reached_end_of_media_playback();
@@ -168,6 +169,9 @@ private:
// https://html.spec.whatwg.org/multipage/media.html#media-data
ByteBuffer m_media_data;
+ // https://html.spec.whatwg.org/multipage/media.html#can-autoplay-flag
+ bool m_can_autoplay { true };
+
bool m_running_time_update_event_handler { false };
Optional<Time> m_last_time_update_event_time;