LibWeb/WebVTT: Implement VTTCue idl interface

This commit is contained in:
Jamie Mansfield 2024-09-19 21:49:54 +01:00 committed by Tim Ledbetter
parent 1a012f279a
commit 973f774e56
Notes: github-actions[bot] 2024-09-24 22:49:51 +00:00
7 changed files with 267 additions and 0 deletions

View file

@ -363,6 +363,7 @@ Uint32Array
Uint8Array
Uint8ClampedArray
UserActivation
VTTCue
VTTRegion
ValidityState
VideoTrack

View file

@ -755,6 +755,7 @@ set(SOURCES
WebIDL/Promise.cpp
WebIDL/Tracing.cpp
WebSockets/WebSocket.cpp
WebVTT/VTTCue.cpp
WebVTT/VTTRegion.cpp
XHR/EventNames.cpp
XHR/FormData.cpp

View file

@ -791,6 +791,7 @@ class WebSocket;
}
namespace Web::WebVTT {
class VTTCue;
class VTTRegion;
}

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/WebVTT/VTTCue.h>
namespace Web::WebVTT {
JS_DEFINE_ALLOCATOR(VTTCue);
// https://w3c.github.io/webvtt/#dom-vttcue-vttcue
WebIDL::ExceptionOr<JS::NonnullGCPtr<VTTCue>> VTTCue::construct_impl(JS::Realm& realm, double start_time, double end_time, String const& text)
{
// 1. Create a new WebVTT cue. Let cue be that WebVTT cue.
auto cue = realm.heap().allocate<VTTCue>(realm, realm, nullptr);
// 2. Let cues text track cue start time be the value of the startTime argument.
cue->m_start_time = start_time;
// 3. If the value of the endTime argument is negative Infinity or a Not-a-Number (NaN) value, then throw a TypeError exception.
// Otherwise, let cues text track cue end time be the value of the endTime argument.
if (end_time == -AK::Infinity<double> || isnan(end_time))
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "End time is negative infinity or NaN"_string };
cue->m_end_time = end_time;
// 4. Let cues cue text be the value of the text argument, and let the rules for extracting the chapter title be the WebVTT rules
// for extracting the chapter title.
cue->m_text = text;
// FIXME: let the rules for extracting the chapter title be the WebVTT rules for extracting the chapter title.
// 5. Let cues text track cue identifier be the empty string.
cue->m_identifier = ""_string;
// 6. Let cues text track cue pause-on-exit flag be false.
cue->m_pause_on_exit = false;
// 7. Let cues WebVTT cue region be null.
cue->m_region = nullptr;
// 8. Let cues WebVTT cue writing direction be horizontal.
cue->m_writing_direction = WritingDirection::Horizontal;
// 9. Let cues WebVTT cue snap-to-lines flag be true.
cue->m_snap_to_lines = true;
// FIXME: 10. Let cues WebVTT cue line be auto.
// 11. Let cues WebVTT cue line alignment be start alignment.
cue->m_line_alignment = Bindings::LineAlignSetting::Start;
// FIXME: 12. Let cues WebVTT cue position be auto.
// 13. Let cues WebVTT cue position alignment be auto.
cue->m_position_alignment = Bindings::PositionAlignSetting::Auto;
// 14. Let cues WebVTT cue size be 100.
cue->m_size = 100;
// 15. Let cues WebVTT cue text alignment be center alignment.
cue->m_text_alignment = Bindings::AlignSetting::Center;
// 16. Return the VTTCue object representing cue.
return cue;
}
VTTCue::VTTCue(JS::Realm& realm, JS::GCPtr<HTML::TextTrack> track)
: HTML::TextTrackCue(realm, track)
{
}
void VTTCue::initialize(JS::Realm& realm)
{
Base::initialize(realm);
WEB_SET_PROTOTYPE_FOR_INTERFACE(VTTCue);
}
void VTTCue::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_region);
}
// https://w3c.github.io/webvtt/#dom-vttcue-vertical
Bindings::DirectionSetting VTTCue::vertical() const
{
switch (m_writing_direction) {
case WritingDirection::Horizontal:
return Bindings::DirectionSetting::Empty;
case WritingDirection::VerticalGrowingLeft:
return Bindings::DirectionSetting::Rl;
case WritingDirection::VerticalGrowingRight:
return Bindings::DirectionSetting::Lr;
}
VERIFY_NOT_REACHED();
}
// https://w3c.github.io/webvtt/#dom-vttcue-vertical
void VTTCue::set_vertical(Bindings::DirectionSetting vertical)
{
switch (vertical) {
case Bindings::DirectionSetting::Empty:
m_writing_direction = WritingDirection::Horizontal;
break;
case Bindings::DirectionSetting::Rl:
m_writing_direction = WritingDirection::VerticalGrowingLeft;
break;
case Bindings::DirectionSetting::Lr:
m_writing_direction = WritingDirection::VerticalGrowingRight;
break;
}
}
// https://w3c.github.io/webvtt/#cue-computed-position-alignment
Bindings::PositionAlignSetting VTTCue::computed_position_alignment()
{
// 1. If the WebVTT cue position alignment is not auto, then return the value of the WebVTT cue position alignment and abort these
// steps.
if (m_position_alignment != Bindings::PositionAlignSetting::Auto)
return m_position_alignment;
// 2. If the WebVTT cue text alignment is left, return line-left and abort these steps.
if (m_text_alignment == Bindings::AlignSetting::Left)
return Bindings::PositionAlignSetting::LineLeft;
// 3. If the WebVTT cue text alignment is right, return line-right and abort these steps.
if (m_text_alignment == Bindings::AlignSetting::Right)
return Bindings::PositionAlignSetting::LineRight;
// FIXME: 4. If the WebVTT cue text alignment is start, return line-left if the base direction of the cue text is left-to-right, line-right
// otherwise.
// FIXME: 5. If the WebVTT cue text alignment is end, return line-right if the base direction of the cue text is left-to-right, line-left
// otherwise.
// 6. Otherwise, return center.
return Bindings::PositionAlignSetting::Center;
}
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/Bindings/VTTCuePrototype.h>
#include <LibWeb/HTML/TextTrackCue.h>
#include <LibWeb/WebIDL/Types.h>
#include <LibWeb/WebVTT/VTTRegion.h>
namespace Web::WebVTT {
// https://w3c.github.io/webvtt/#vttcue
class VTTCue final : public HTML::TextTrackCue {
WEB_PLATFORM_OBJECT(VTTCue, HTML::TextTrackCue);
JS_DECLARE_ALLOCATOR(VTTCue);
public:
enum class WritingDirection : u8 {
// https://w3c.github.io/webvtt/#webvtt-cue-horizontal-writing-direction
Horizontal,
// https://w3c.github.io/webvtt/#webvtt-cue-vertical-growing-left-writing-direction
VerticalGrowingLeft,
// https://w3c.github.io/webvtt/#webvtt-cue-vertical-growing-right-writing-direction
VerticalGrowingRight,
};
static WebIDL::ExceptionOr<JS::NonnullGCPtr<VTTCue>> construct_impl(JS::Realm&, double start_time, double end_time, String const& text);
virtual ~VTTCue() override = default;
JS::GCPtr<VTTRegion> region() const { return m_region; }
void set_region(JS::GCPtr<VTTRegion> region) { m_region = region; }
Bindings::DirectionSetting vertical() const;
void set_vertical(Bindings::DirectionSetting);
bool snap_to_lines() const { return m_snap_to_lines; }
void set_snap_to_lines(bool snap_to_lines) { m_snap_to_lines = snap_to_lines; }
Bindings::LineAlignSetting line_align() const { return m_line_alignment; }
void set_line_align(Bindings::LineAlignSetting line_align) { m_line_alignment = line_align; }
Bindings::PositionAlignSetting position_align() const { return m_position_alignment; }
void set_position_align(Bindings::PositionAlignSetting position_align) { m_position_alignment = position_align; }
double size() const { return m_size; }
void set_size(double size) { m_size = size; }
Bindings::AlignSetting align() const { return m_text_alignment; }
void set_align(Bindings::AlignSetting align) { m_text_alignment = align; }
String const& text() const { return m_text; }
void set_text(String const& text) { m_text = text; }
protected:
Bindings::PositionAlignSetting computed_position_alignment();
private:
VTTCue(JS::Realm&, JS::GCPtr<HTML::TextTrack>);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Visitor&) override;
// https://w3c.github.io/webvtt/#cue-text
String m_text;
// https://w3c.github.io/webvtt/#webvtt-cue-writing-direction
WritingDirection m_writing_direction { WritingDirection::Horizontal };
// https://w3c.github.io/webvtt/#webvtt-cue-snap-to-lines-flag
bool m_snap_to_lines { true };
// https://w3c.github.io/webvtt/#webvtt-cue-line-alignment
Bindings::LineAlignSetting m_line_alignment { Bindings::LineAlignSetting::Start };
// https://w3c.github.io/webvtt/#webvtt-cue-position-alignment
Bindings::PositionAlignSetting m_position_alignment { Bindings::PositionAlignSetting::Auto };
// https://w3c.github.io/webvtt/#webvtt-cue-size
double m_size { 100 };
// https://w3c.github.io/webvtt/#webvtt-cue-text-alignment
Bindings::AlignSetting m_text_alignment { Bindings::AlignSetting::Center };
// https://w3c.github.io/webvtt/#webvtt-cue-region
JS::GCPtr<VTTRegion> m_region;
};
}

View file

@ -0,0 +1,26 @@
#import <HTML/TextTrackCue.idl>
#import <WebVTT/VTTRegion.idl>
enum AutoKeyword { "auto" };
typedef (double or AutoKeyword) LineAndPositionSetting;
enum DirectionSetting { "", "rl", "lr" };
enum LineAlignSetting { "start", "center", "end" };
enum PositionAlignSetting { "line-left", "center", "line-right", "auto" };
enum AlignSetting { "start", "center", "end", "left", "right" };
// https://w3c.github.io/webvtt/#vttcue
[Exposed=Window]
interface VTTCue : TextTrackCue {
constructor(double startTime, unrestricted double endTime, DOMString text);
attribute VTTRegion? region;
attribute DirectionSetting vertical;
attribute boolean snapToLines;
[FIXME] attribute LineAndPositionSetting line;
attribute LineAlignSetting lineAlign;
[FIXME] attribute LineAndPositionSetting position;
attribute PositionAlignSetting positionAlign;
attribute double size;
attribute AlignSetting align;
attribute DOMString text;
[FIXME] DocumentFragment getCueAsHTML();
};

View file

@ -345,6 +345,7 @@ libweb_js_bindings(WebGL/WebGLContextEvent)
libweb_js_bindings(WebGL/WebGLRenderingContext)
libweb_js_bindings(WebIDL/DOMException)
libweb_js_bindings(WebSockets/WebSocket)
libweb_js_bindings(WebVTT/VTTCue)
libweb_js_bindings(WebVTT/VTTRegion)
libweb_js_bindings(XHR/FormData ITERABLE)
libweb_js_bindings(XHR/ProgressEvent)