LibWeb: Add 'Run the fullscreen steps'

Run the fullscreen steps is an event-dispatching algorithm, which we
implement here. Future work will populate the pending list with events.
This commit is contained in:
Simon Farre 2025-03-20 15:38:20 +01:00
parent a901bf45dc
commit 65b23d9e43
4 changed files with 56 additions and 1 deletions

View file

@ -582,6 +582,10 @@ void Document::visit_edges(Cell::Visitor& visitor)
visitor.visit(event.target);
}
for (auto& event : m_pending_fullscreen_events) {
visitor.visit(event.element);
}
visitor.visit(m_adopted_style_sheets);
for (auto& shadow_root : m_shadow_roots)
@ -6209,6 +6213,39 @@ void Document::remove_render_blocking_element(GC::Ref<Element> element)
m_render_blocking_elements.remove(element);
}
// https://fullscreen.spec.whatwg.org/#run-the-fullscreen-steps
void Document::run_fullscreen_steps()
{
// 1. Let pendingEvents be documents list of pending fullscreen events.
// 2. Empty documents list of pending fullscreen events.
Vector<PendingFullscreenEvent> pending_events;
std::swap(m_pending_fullscreen_events, pending_events);
// 3. For each (type, element) in pendingEvents:
for (auto const& [type, element] : pending_events) {
// 1. Let target be element if element is connected and its node document is document, and otherwise let target be document.
EventTarget* target = nullptr;
if (element->is_connected() && &element->document() == this) {
target = element;
} else {
target = this;
}
// 2. Fire an event named type, with its bubbles and composed attributes set to true, at target.
switch (type) {
case PendingFullscreenEvent::Type::Change:
target->dispatch_event(Event::create(realm(), HTML::EventNames::fullscreenchange, EventInit { .bubbles = true, .composed = true }));
break;
case PendingFullscreenEvent::Type::Error:
target->dispatch_event(Event::create(realm(), HTML::EventNames::fullscreenerror, EventInit { .bubbles = true, .composed = true }));
break;
}
}
}
void Document::append_pending_fullscreen_change(PendingFullscreenEvent::Type type, GC::Ref<Element> element)
{
m_pending_fullscreen_events.append(PendingFullscreenEvent { type, element });
}
// https://dom.spec.whatwg.org/#document-allow-declarative-shadow-roots
void Document::set_allow_declarative_shadow_roots(bool allow)
{

View file

@ -156,6 +156,14 @@ enum class PolicyControlledFeature : u8 {
FocusWithoutUserActivation,
};
struct PendingFullscreenEvent {
enum class Type {
Change,
Error,
} type;
GC::Ref<Element> element;
};
class Document
: public ParentNode
, public HTML::GlobalEventHandlers {
@ -896,6 +904,9 @@ public:
}
ElementByIdMap& element_by_id() const;
// https://fullscreen.spec.whatwg.org/#run-the-fullscreen-steps
void run_fullscreen_steps();
void append_pending_fullscreen_change(PendingFullscreenEvent::Type type, GC::Ref<Element> element);
protected:
virtual void initialize(JS::Realm&) override;
@ -1249,6 +1260,8 @@ private:
HashTable<GC::Ref<Element>> m_render_blocking_elements;
HashTable<WeakPtr<Node>> m_pending_nodes_for_style_invalidation_due_to_presence_of_has;
// https://fullscreen.spec.whatwg.org/#list-of-pending-fullscreen-events
Vector<PendingFullscreenEvent> m_pending_fullscreen_events;
};
template<>

View file

@ -379,7 +379,10 @@ void EventLoop::update_the_rendering()
document->update_animations_and_send_events(HighResolutionTime::relative_high_resolution_time(frame_timestamp, relevant_global_object(*document)));
};
// FIXME: 12. For each doc of docs, run the fullscreen steps for doc. [FULLSCREEN]
// 12. For each doc of docs, run the fullscreen steps for doc. [FULLSCREEN]
for (auto& document : docs) {
document->run_fullscreen_steps();
}
// FIXME: 13. For each doc of docs, if the user agent detects that the backing storage associated with a CanvasRenderingContext2D or an OffscreenCanvasRenderingContext2D, context, has been lost, then it must run the context lost steps for each such context:

View file

@ -62,6 +62,8 @@ namespace Web::HTML::EventNames {
__ENUMERATE_HTML_EVENT(focusin) \
__ENUMERATE_HTML_EVENT(focusout) \
__ENUMERATE_HTML_EVENT(formdata) \
__ENUMERATE_HTML_EVENT(fullscreenchange) \
__ENUMERATE_HTML_EVENT(fullscreenerror) \
__ENUMERATE_HTML_EVENT(hashchange) \
__ENUMERATE_HTML_EVENT(input) \
__ENUMERATE_HTML_EVENT(invalid) \