mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-07 00:19:27 +00:00
LibWeb: Implement basic "scroll" events at the document level
This commit is contained in:
parent
07c4bf03b5
commit
da451467b1
|
@ -323,6 +323,11 @@ void Document::visit_edges(Cell::Visitor& visitor)
|
|||
|
||||
for (auto& node_iterator : m_node_iterators)
|
||||
visitor.visit(node_iterator);
|
||||
|
||||
for (auto& target : m_pending_scroll_event_targets)
|
||||
visitor.visit(target.ptr());
|
||||
for (auto& target : m_pending_scrollend_event_targets)
|
||||
visitor.visit(target.ptr());
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-document-write
|
||||
|
@ -1570,6 +1575,29 @@ void Document::run_the_resize_steps()
|
|||
update_layout();
|
||||
}
|
||||
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view-1/#document-run-the-scroll-steps
|
||||
void Document::run_the_scroll_steps()
|
||||
{
|
||||
// 1. For each item target in doc’s pending scroll event targets, in the order they were added to the list, run these substeps:
|
||||
for (auto& target : m_pending_scroll_event_targets) {
|
||||
// 1. If target is a Document, fire an event named scroll that bubbles at target and fire an event named scroll at the VisualViewport that is associated with target.
|
||||
if (is<Document>(*target)) {
|
||||
auto event = DOM::Event::create(window(), HTML::EventNames::scroll);
|
||||
event->set_bubbles(true);
|
||||
target->dispatch_event(*event);
|
||||
// FIXME: Fire at the associated VisualViewport
|
||||
}
|
||||
// 2. Otherwise, fire an event named scroll at target.
|
||||
else {
|
||||
auto event = DOM::Event::create(window(), HTML::EventNames::scroll);
|
||||
target->dispatch_event(*event);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Empty doc’s pending scroll event targets.
|
||||
m_pending_scroll_event_targets.clear();
|
||||
}
|
||||
|
||||
void Document::add_media_query_list(JS::NonnullGCPtr<CSS::MediaQueryList> media_query_list)
|
||||
{
|
||||
m_media_query_lists.append(*media_query_list);
|
||||
|
|
|
@ -317,6 +317,7 @@ public:
|
|||
String visibility_state() const;
|
||||
|
||||
void run_the_resize_steps();
|
||||
void run_the_scroll_steps();
|
||||
|
||||
void evaluate_media_queries_and_report_changes();
|
||||
void add_media_query_list(JS::NonnullGCPtr<CSS::MediaQueryList>);
|
||||
|
@ -360,6 +361,9 @@ public:
|
|||
String domain() const;
|
||||
void set_domain(String const& domain);
|
||||
|
||||
auto& pending_scroll_event_targets() { return m_pending_scroll_event_targets; }
|
||||
auto& pending_scrollend_event_targets() { return m_pending_scrollend_event_targets; }
|
||||
|
||||
protected:
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
|
@ -456,6 +460,12 @@ private:
|
|||
// Used by run_the_resize_steps().
|
||||
Gfx::IntSize m_last_viewport_size;
|
||||
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view-1/#document-pending-scroll-event-targets
|
||||
Vector<JS::NonnullGCPtr<EventTarget>> m_pending_scroll_event_targets;
|
||||
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view-1/#document-pending-scrollend-event-targets
|
||||
Vector<JS::NonnullGCPtr<EventTarget>> m_pending_scrollend_event_targets;
|
||||
|
||||
// Used by evaluate_media_queries_and_report_changes().
|
||||
Vector<WeakPtr<CSS::MediaQueryList>> m_media_query_lists;
|
||||
|
||||
|
|
|
@ -320,6 +320,7 @@ void BrowsingContext::set_viewport_rect(Gfx::IntRect const& rect)
|
|||
|
||||
if (m_viewport_scroll_offset != rect.location()) {
|
||||
m_viewport_scroll_offset = rect.location();
|
||||
scroll_offset_did_change();
|
||||
did_change = true;
|
||||
}
|
||||
|
||||
|
@ -785,4 +786,23 @@ DOM::Document* BrowsingContext::active_document()
|
|||
return m_active_document.cell();
|
||||
}
|
||||
|
||||
void BrowsingContext::scroll_offset_did_change()
|
||||
{
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view-1/#scrolling-events
|
||||
// Whenever a viewport gets scrolled (whether in response to user interaction or by an API), the user agent must run these steps:
|
||||
|
||||
// 1. Let doc be the viewport’s associated Document.
|
||||
auto* doc = active_document();
|
||||
VERIFY(doc);
|
||||
|
||||
// 2. If doc is already in doc’s pending scroll event targets, abort these steps.
|
||||
for (auto& target : doc->pending_scroll_event_targets()) {
|
||||
if (target.ptr() == doc)
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Append doc to doc’s pending scroll event targets.
|
||||
doc->pending_scroll_event_targets().append(*doc);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -129,6 +129,8 @@ private:
|
|||
|
||||
void reset_cursor_blink_cycle();
|
||||
|
||||
void scroll_offset_did_change();
|
||||
|
||||
WeakPtr<Page> m_page;
|
||||
|
||||
FrameLoader m_loader;
|
||||
|
|
|
@ -169,7 +169,10 @@ void EventLoop::process()
|
|||
document.run_the_resize_steps();
|
||||
});
|
||||
|
||||
// FIXME: 8. For each fully active Document in docs, run the scroll steps for that Document, passing in now as the timestamp. [CSSOMVIEW]
|
||||
// 8. For each fully active Document in docs, run the scroll steps for that Document, passing in now as the timestamp. [CSSOMVIEW]
|
||||
for_each_fully_active_document_in_docs([&](DOM::Document& document) {
|
||||
document.run_the_scroll_steps();
|
||||
});
|
||||
|
||||
// 9. For each fully active Document in docs, evaluate media queries and report changes for that Document, passing in now as the timestamp. [CSSOMVIEW]
|
||||
for_each_fully_active_document_in_docs([&](DOM::Document& document) {
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace Web::HTML::EventNames {
|
|||
__ENUMERATE_HTML_EVENT(readystatechange) \
|
||||
__ENUMERATE_HTML_EVENT(rejectionhandled) \
|
||||
__ENUMERATE_HTML_EVENT(reset) \
|
||||
__ENUMERATE_HTML_EVENT(scroll) \
|
||||
__ENUMERATE_HTML_EVENT(securitypolicyviolation) \
|
||||
__ENUMERATE_HTML_EVENT(select) \
|
||||
__ENUMERATE_HTML_EVENT(slotchange) \
|
||||
|
|
Loading…
Reference in a new issue