Commit graph

11 commits

Author SHA1 Message Date
Zaggy1024
f213ef455d LibWeb: Cancel the animation frame callback in MediaControls destructor
Otherwise, when hiding controls, we would get a UAF on MediaControls::
update_timeline() and crash.
2026-03-17 06:00:40 -05:00
Zaggy1024
73c27f3448 LibWeb: Use requestAnimationFrame to update media controls timeline
The media element's timeupdate event only fires every 250ms. To make
the timeline update more smoothly, poll currentTime to update the
timeline every frame.
2026-03-17 01:48:59 -05:00
Zaggy1024
6f73b537f7 LibWeb: Simplify getting the Window in MediaControls callbacks 2026-03-17 01:48:59 -05:00
Zaggy1024
6cc13dbfa2 LibWeb: Skip assigning an unchanged timeline style in media controls 2026-03-17 01:48:59 -05:00
Zaggy1024
fe702847f8 LibWeb: Simplify the HTMLMediaElement null check in ~MediaControls() 2026-03-17 01:48:59 -05:00
Zaggy1024
63113cf5c9 Meta+LibWeb: Use a code generator to create the media controls' DOM
Instead of manually writing code to instantiate DOM elements in
MediaControls.cpp, use a Python script to generate a separate C++
struct to create and store the DOM elements.

The generator reads an HTML file and the HTML/SVG tags/attributes
headers to create C++ source that instantiates the DOM elements.

To enable embedding of stylesheets in shadow DOM, the generator
replaces `<link rel="stylesheet">` elements with plain `<style>`
elements containing the source from the linked stylesheet.

Elements that should be stored in the resulting struct should be marked
have the `data-name` attribute, which will be converted to snake_case
and used as the public field's name.

Optional elements can be marked with a 'data-option' attribute. Each
unique option value will be converted to PascalCase and added to a
bitwise enum named `Options` nested within the struct. Optional
elements and all their children will not be instantiated unless their
option is set in the constructor argument.

The MediaControls class stores the generated MediaControlsDOM struct
and sets up event handlers to implement user interactions.
2026-03-05 02:28:47 -06:00
Timothy Flynn
bfef5c460f LibWeb: Display video controls while the placeholder icon is visible
This matches the behavior of Firefox.
2026-03-03 16:53:23 +01:00
Timothy Flynn
3a9ae0eb02 LibWeb: Toggle the built-in media player fullscreen state on doubleclick 2026-03-01 15:41:43 -06:00
Timothy Flynn
24aacfea48 LibWeb: Add a button to the built-in media player to toggle fullscreen 2026-03-01 15:41:43 -06:00
Timothy Flynn
e95db70d2d LibJS+LibWeb: Return GC::Ptr from Value::as_if 2026-02-27 17:19:33 +01:00
Zaggy1024
21019c2fa9 LibWeb: Use UA shadow DOM for media elements' controls
Instead of using a custom paintable to draw the controls for video and
audio elements, we build them out of plain old HTML elements within a
shadow root.

This required a few hacks in the previous commits in order to allow a
replaced element to host children within a shadow root, but it's
fairly self-contained.

A big benefit is that we can drive all the UI updates off of plain old
DOM events (except the play button overlay on videos, which uses the
video element representation), so we can test our media and input event
handling more thoroughly. :^)

The control bar visibility is now more similar to how other browsers
handle it. It will show upon hovering over the element, but if the
cursor is kept still for more than a second, it will hide again. While
dragging, the controls remain visible, and will then hide after the
mouse button is released.

The icons have been redesigned from scratch, and the mute icon now
visualizes the volume level along with indicating the mute state.
2026-02-23 07:27:31 +01:00