mirror of
https://github.com/RGBCube/serenity
synced 2025-05-26 01:45:06 +00:00
LibWeb: Change viewport ownership from BrowsingContext
to Navigable
This commit is contained in:
parent
4356d37b2c
commit
dd7bba66ed
23 changed files with 196 additions and 129 deletions
|
@ -137,7 +137,7 @@ Length::ResolutionContext Length::ResolutionContext::for_layout_node(Layout::Nod
|
|||
VERIFY(root_element);
|
||||
VERIFY(root_element->layout_node());
|
||||
return Length::ResolutionContext {
|
||||
.viewport_rect = node.browsing_context().viewport_rect(),
|
||||
.viewport_rect = node.navigable()->viewport_rect(),
|
||||
.font_metrics = { node.computed_values().font_size(), node.font().pixel_metrics(), node.line_height() },
|
||||
.root_font_metrics = { root_element->layout_node()->computed_values().font_size(), root_element->layout_node()->font().pixel_metrics(), root_element->layout_node()->line_height() },
|
||||
};
|
||||
|
@ -182,7 +182,7 @@ CSSPixels Length::to_px(Layout::Node const& layout_node) const
|
|||
}
|
||||
|
||||
VERIFY(is_viewport_relative());
|
||||
auto const& viewport_rect = layout_node.document().browsing_context()->viewport_rect();
|
||||
auto const& viewport_rect = layout_node.document().viewport_rect();
|
||||
return viewport_relative_length_to_px(viewport_rect);
|
||||
}
|
||||
|
||||
|
|
|
@ -2617,8 +2617,8 @@ void StyleComputer::invalidate_rule_cache()
|
|||
|
||||
CSSPixelRect StyleComputer::viewport_rect() const
|
||||
{
|
||||
if (auto const* browsing_context = document().browsing_context())
|
||||
return browsing_context->viewport_rect();
|
||||
if (auto const navigable = document().navigable())
|
||||
return navigable->viewport_rect();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ void ImageStyleValue::load_any_resources(DOM::Document& document)
|
|||
return;
|
||||
|
||||
// FIXME: Do less than a full repaint if possible?
|
||||
if (auto* browsing_context = m_document->browsing_context())
|
||||
browsing_context->set_needs_display();
|
||||
if (auto navigable = m_document->navigable())
|
||||
navigable->set_needs_display();
|
||||
|
||||
auto image_data = m_image_request->image_data();
|
||||
if (image_data->is_animated() && image_data->frame_count() > 1) {
|
||||
|
|
|
@ -46,8 +46,8 @@ double VisualViewport::offset_left() const
|
|||
return 0;
|
||||
|
||||
// 2. Otherwise, return the offset of the left edge of the visual viewport from the left edge of the layout viewport.
|
||||
VERIFY(m_document->browsing_context());
|
||||
return m_document->browsing_context()->viewport_rect().left().to_double();
|
||||
VERIFY(m_document->navigable());
|
||||
return m_document->viewport_rect().left().to_double();
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-visualviewport-offsettop
|
||||
|
@ -58,8 +58,8 @@ double VisualViewport::offset_top() const
|
|||
return 0;
|
||||
|
||||
// 2. Otherwise, return the offset of the top edge of the visual viewport from the top edge of the layout viewport.
|
||||
VERIFY(m_document->browsing_context());
|
||||
return m_document->browsing_context()->viewport_rect().top().to_double();
|
||||
VERIFY(m_document->navigable());
|
||||
return m_document->viewport_rect().top().to_double();
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-visualviewport-pageleft
|
||||
|
@ -95,8 +95,8 @@ double VisualViewport::width() const
|
|||
|
||||
// 2. Otherwise, return the width of the visual viewport
|
||||
// FIXME: excluding the width of any rendered vertical classic scrollbar that is fixed to the visual viewport.
|
||||
VERIFY(m_document->browsing_context());
|
||||
return m_document->browsing_context()->viewport_rect().width().to_double();
|
||||
VERIFY(m_document->navigable());
|
||||
return m_document->viewport_rect().width().to_double();
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-visualviewport-height
|
||||
|
@ -108,8 +108,8 @@ double VisualViewport::height() const
|
|||
|
||||
// 2. Otherwise, return the height of the visual viewport
|
||||
// FIXME: excluding the height of any rendered vertical classic scrollbar that is fixed to the visual viewport.
|
||||
VERIFY(m_document->browsing_context());
|
||||
return m_document->browsing_context()->viewport_rect().height().to_double();
|
||||
VERIFY(m_document->navigable());
|
||||
return m_document->viewport_rect().height().to_double();
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-visualviewport-scale
|
||||
|
|
|
@ -962,7 +962,7 @@ void Document::update_layout()
|
|||
if (m_created_for_appropriate_template_contents)
|
||||
return;
|
||||
|
||||
if (!browsing_context())
|
||||
if (!navigable())
|
||||
return;
|
||||
|
||||
auto viewport_rect = this->viewport_rect();
|
||||
|
@ -1005,7 +1005,8 @@ void Document::update_layout()
|
|||
// Broadcast the current viewport rect to any new paintables, so they know whether they're visible or not.
|
||||
inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
|
||||
browsing_context()->set_needs_display();
|
||||
if (navigable())
|
||||
navigable()->set_needs_display();
|
||||
|
||||
if (navigable()->is_traversable()) {
|
||||
if (auto* page = this->page())
|
||||
|
@ -3034,8 +3035,8 @@ HTML::ListOfAvailableImages const& Document::list_of_available_images() const
|
|||
|
||||
CSSPixelRect Document::viewport_rect() const
|
||||
{
|
||||
if (auto* browsing_context = this->browsing_context())
|
||||
return browsing_context->viewport_rect();
|
||||
if (auto const navigable = this->navigable())
|
||||
return navigable->viewport_rect();
|
||||
return CSSPixelRect {};
|
||||
}
|
||||
|
||||
|
|
|
@ -833,8 +833,8 @@ JS::NonnullGCPtr<Geometry::DOMRect> Element::get_bounding_client_rect() const
|
|||
if (!paintable_box)
|
||||
return Geometry::DOMRect::construct_impl(realm(), 0, 0, 0, 0).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
VERIFY(document().browsing_context());
|
||||
auto viewport_offset = document().browsing_context()->viewport_scroll_offset();
|
||||
VERIFY(document().navigable());
|
||||
auto viewport_offset = document().navigable()->viewport_scroll_offset();
|
||||
|
||||
return Geometry::DOMRect::create(realm(), paintable_box->absolute_rect().translated(-viewport_offset.x(), -viewport_offset.y()).to_type<float>());
|
||||
}
|
||||
|
@ -907,7 +907,7 @@ int Element::client_width() const
|
|||
// return the viewport width excluding the size of a rendered scroll bar (if any).
|
||||
if ((is<HTML::HTMLHtmlElement>(*this) && !document().in_quirks_mode())
|
||||
|| (is<HTML::HTMLBodyElement>(*this) && document().in_quirks_mode())) {
|
||||
return document().browsing_context()->viewport_rect().width().to_int();
|
||||
return document().viewport_rect().width().to_int();
|
||||
}
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
|
@ -932,7 +932,7 @@ int Element::client_height() const
|
|||
// return the viewport height excluding the size of a rendered scroll bar (if any).
|
||||
if ((is<HTML::HTMLHtmlElement>(*this) && !document().in_quirks_mode())
|
||||
|| (is<HTML::HTMLBodyElement>(*this) && document().in_quirks_mode())) {
|
||||
return document().browsing_context()->viewport_rect().height().to_int();
|
||||
return document().viewport_rect().height().to_int();
|
||||
}
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
|
@ -1262,8 +1262,8 @@ int Element::scroll_width() const
|
|||
|
||||
// 3. Let viewport width be the width of the viewport excluding the width of the scroll bar, if any,
|
||||
// or zero if there is no viewport.
|
||||
auto viewport_width = document.browsing_context()->viewport_rect().width().to_int();
|
||||
auto viewport_scroll_width = document.browsing_context()->size().width().to_int();
|
||||
auto viewport_width = document.viewport_rect().width().to_int();
|
||||
auto viewport_scroll_width = document.navigable()->size().width().to_int();
|
||||
|
||||
// 4. If the element is the root element and document is not in quirks mode
|
||||
// return max(viewport scrolling area width, viewport width).
|
||||
|
@ -1295,8 +1295,8 @@ int Element::scroll_height() const
|
|||
|
||||
// 3. Let viewport height be the height of the viewport excluding the height of the scroll bar, if any,
|
||||
// or zero if there is no viewport.
|
||||
auto viewport_height = document.browsing_context()->viewport_rect().height().to_int();
|
||||
auto viewport_scroll_height = document.browsing_context()->size().height().to_int();
|
||||
auto viewport_height = document.viewport_rect().height().to_int();
|
||||
auto viewport_scroll_height = document.navigable()->size().height().to_int();
|
||||
|
||||
// 4. If the element is the root element and document is not in quirks mode
|
||||
// return max(viewport scrolling area height, viewport height).
|
||||
|
|
|
@ -540,73 +540,6 @@ void BrowsingContext::set_active_document(JS::NonnullGCPtr<DOM::Document> docume
|
|||
previously_active_document->did_stop_being_active_document_in_browsing_context({});
|
||||
}
|
||||
|
||||
void BrowsingContext::set_viewport_rect(CSSPixelRect const& rect)
|
||||
{
|
||||
bool did_change = false;
|
||||
|
||||
if (m_size != rect.size()) {
|
||||
m_size = rect.size();
|
||||
if (auto* document = active_document()) {
|
||||
// NOTE: Resizing the viewport changes the reference value for viewport-relative CSS lengths.
|
||||
document->invalidate_style();
|
||||
document->set_needs_layout();
|
||||
}
|
||||
did_change = true;
|
||||
}
|
||||
|
||||
if (m_viewport_scroll_offset != rect.location()) {
|
||||
m_viewport_scroll_offset = rect.location();
|
||||
scroll_offset_did_change();
|
||||
did_change = true;
|
||||
}
|
||||
|
||||
if (did_change && active_document()) {
|
||||
active_document()->inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
}
|
||||
|
||||
// Schedule the HTML event loop to ensure that a `resize` event gets fired.
|
||||
HTML::main_thread_event_loop().schedule();
|
||||
}
|
||||
|
||||
void BrowsingContext::set_size(CSSPixelSize size)
|
||||
{
|
||||
if (m_size == size)
|
||||
return;
|
||||
m_size = size;
|
||||
|
||||
if (auto* document = active_document()) {
|
||||
document->invalidate_style();
|
||||
document->set_needs_layout();
|
||||
}
|
||||
|
||||
if (auto* document = active_document()) {
|
||||
document->inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
}
|
||||
|
||||
// Schedule the HTML event loop to ensure that a `resize` event gets fired.
|
||||
HTML::main_thread_event_loop().schedule();
|
||||
}
|
||||
|
||||
void BrowsingContext::set_needs_display()
|
||||
{
|
||||
set_needs_display(viewport_rect());
|
||||
}
|
||||
|
||||
void BrowsingContext::set_needs_display(CSSPixelRect const& rect)
|
||||
{
|
||||
if (!viewport_rect().intersects(rect))
|
||||
return;
|
||||
|
||||
if (is_top_level()) {
|
||||
if (m_page)
|
||||
m_page->client().page_did_invalidate(to_top_level_rect(rect));
|
||||
return;
|
||||
}
|
||||
|
||||
if (container() && container()->layout_node())
|
||||
container()->layout_node()->set_needs_display();
|
||||
}
|
||||
|
||||
void BrowsingContext::scroll_to(CSSPixelPoint position)
|
||||
{
|
||||
// NOTE: Scrolling to a position requires up-to-date layout *unless* we're scrolling to (0, 0)
|
||||
|
@ -647,7 +580,8 @@ void BrowsingContext::scroll_to_anchor(DeprecatedString const& fragment)
|
|||
|
||||
auto& layout_node = *element->layout_node();
|
||||
|
||||
CSSPixelRect target_rect { layout_node.box_type_agnostic_position(), { viewport_rect().width(), viewport_rect().height() } };
|
||||
auto const viewport_rect = document->viewport_rect();
|
||||
CSSPixelRect target_rect { layout_node.box_type_agnostic_position(), { viewport_rect.width(), viewport_rect.height() } };
|
||||
if (is<Layout::Box>(layout_node)) {
|
||||
auto& layout_box = verify_cast<Layout::Box>(layout_node);
|
||||
auto padding_box = layout_box.box_model().padding_box();
|
||||
|
|
|
@ -138,16 +138,6 @@ public:
|
|||
Page* page() { return m_page; }
|
||||
Page const* page() const { return m_page; }
|
||||
|
||||
CSSPixelSize size() const { return m_size; }
|
||||
void set_size(CSSPixelSize);
|
||||
|
||||
void set_needs_display();
|
||||
void set_needs_display(CSSPixelRect const&);
|
||||
|
||||
CSSPixelPoint viewport_scroll_offset() const { return m_viewport_scroll_offset; }
|
||||
CSSPixelRect viewport_rect() const { return { m_viewport_scroll_offset, m_size }; }
|
||||
void set_viewport_rect(CSSPixelRect const&);
|
||||
|
||||
FrameLoader& loader() { return m_loader; }
|
||||
FrameLoader const& loader() const { return m_loader; }
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Infra/Strings.h>
|
||||
#include <LibWeb/Layout/Node.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
#include <LibWeb/XHR/FormData.h>
|
||||
|
||||
|
@ -1548,4 +1549,111 @@ void perform_url_and_history_update_steps(DOM::Document& document, AK::URL new_u
|
|||
});
|
||||
}
|
||||
|
||||
void Navigable::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);
|
||||
}
|
||||
|
||||
CSSPixelRect Navigable::to_top_level_rect(CSSPixelRect const& a_rect)
|
||||
{
|
||||
auto rect = a_rect;
|
||||
rect.set_location(to_top_level_position(a_rect.location()));
|
||||
return rect;
|
||||
}
|
||||
|
||||
CSSPixelPoint Navigable::to_top_level_position(CSSPixelPoint a_position)
|
||||
{
|
||||
auto position = a_position;
|
||||
for (auto ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (is<TraversableNavigable>(*ancestor))
|
||||
break;
|
||||
if (!ancestor->container())
|
||||
return {};
|
||||
if (!ancestor->container()->layout_node())
|
||||
return {};
|
||||
position.translate_by(ancestor->container()->layout_node()->box_type_agnostic_position());
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
void Navigable::set_viewport_rect(CSSPixelRect const& rect)
|
||||
{
|
||||
bool did_change = false;
|
||||
|
||||
if (m_size != rect.size()) {
|
||||
m_size = rect.size();
|
||||
if (auto document = active_document()) {
|
||||
// NOTE: Resizing the viewport changes the reference value for viewport-relative CSS lengths.
|
||||
document->invalidate_style();
|
||||
document->set_needs_layout();
|
||||
}
|
||||
did_change = true;
|
||||
}
|
||||
|
||||
if (m_viewport_scroll_offset != rect.location()) {
|
||||
m_viewport_scroll_offset = rect.location();
|
||||
scroll_offset_did_change();
|
||||
did_change = true;
|
||||
}
|
||||
|
||||
if (did_change && active_document()) {
|
||||
active_document()->inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
}
|
||||
|
||||
// Schedule the HTML event loop to ensure that a `resize` event gets fired.
|
||||
HTML::main_thread_event_loop().schedule();
|
||||
}
|
||||
|
||||
void Navigable::set_size(CSSPixelSize size)
|
||||
{
|
||||
if (m_size == size)
|
||||
return;
|
||||
m_size = size;
|
||||
|
||||
if (auto document = active_document()) {
|
||||
document->invalidate_style();
|
||||
document->set_needs_layout();
|
||||
}
|
||||
|
||||
if (auto document = active_document()) {
|
||||
document->inform_all_viewport_clients_about_the_current_viewport_rect();
|
||||
}
|
||||
|
||||
// Schedule the HTML event loop to ensure that a `resize` event gets fired.
|
||||
HTML::main_thread_event_loop().schedule();
|
||||
}
|
||||
|
||||
void Navigable::set_needs_display()
|
||||
{
|
||||
set_needs_display(viewport_rect());
|
||||
}
|
||||
|
||||
void Navigable::set_needs_display(CSSPixelRect const& rect)
|
||||
{
|
||||
if (!viewport_rect().intersects(rect))
|
||||
return;
|
||||
|
||||
if (is<TraversableNavigable>(*this)) {
|
||||
static_cast<TraversableNavigable*>(this)->page()->client().page_did_invalidate(to_top_level_rect(rect));
|
||||
return;
|
||||
}
|
||||
|
||||
if (container() && container()->layout_node())
|
||||
container()->layout_node()->set_needs_display();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashTable.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibWeb/Bindings/NavigationPrototype.h>
|
||||
|
@ -19,6 +20,7 @@
|
|||
#include <LibWeb/HTML/SourceSnapshotParams.h>
|
||||
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||
#include <LibWeb/HTML/TokenizedFeatures.h>
|
||||
#include <LibWeb/PixelUnits.h>
|
||||
#include <LibWeb/XHR/FormDataEntry.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
@ -134,6 +136,19 @@ public:
|
|||
[[nodiscard]] bool has_been_destroyed() const { return m_has_been_destroyed; }
|
||||
void set_has_been_destroyed() { m_has_been_destroyed = true; }
|
||||
|
||||
CSSPixelPoint to_top_level_position(CSSPixelPoint);
|
||||
CSSPixelRect to_top_level_rect(CSSPixelRect const&);
|
||||
|
||||
CSSPixelSize size() const { return m_size; }
|
||||
void set_size(CSSPixelSize);
|
||||
|
||||
CSSPixelPoint viewport_scroll_offset() const { return m_viewport_scroll_offset; }
|
||||
CSSPixelRect viewport_rect() const { return { m_viewport_scroll_offset, m_size }; }
|
||||
void set_viewport_rect(CSSPixelRect const&);
|
||||
|
||||
void set_needs_display();
|
||||
void set_needs_display(CSSPixelRect const&);
|
||||
|
||||
protected:
|
||||
Navigable();
|
||||
|
||||
|
@ -146,6 +161,8 @@ private:
|
|||
bool allowed_by_sandboxing_to_navigate(Navigable const& target, SourceSnapshotParams const&);
|
||||
TargetSnapshotParams snapshot_target_snapshot_params();
|
||||
|
||||
void scroll_offset_did_change();
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/document-sequences.html#nav-id
|
||||
String m_id;
|
||||
|
||||
|
@ -168,6 +185,9 @@ private:
|
|||
JS::GCPtr<NavigableContainer> m_container;
|
||||
|
||||
bool m_has_been_destroyed { false };
|
||||
|
||||
CSSPixelSize m_size;
|
||||
CSSPixelPoint m_viewport_scroll_offset;
|
||||
};
|
||||
|
||||
HashTable<Navigable*>& all_navigables();
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
||||
#include <LibWeb/HTML/Storage.h>
|
||||
#include <LibWeb/HTML/TokenizedFeatures.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/HTML/WindowProxy.h>
|
||||
#include <LibWeb/HighResolutionTime/Performance.h>
|
||||
|
@ -1101,8 +1102,8 @@ i32 Window::inner_width() const
|
|||
{
|
||||
// The innerWidth attribute must return the viewport width including the size of a rendered scroll bar (if any),
|
||||
// or zero if there is no viewport.
|
||||
if (auto const* browsing_context = associated_document().browsing_context())
|
||||
return browsing_context->viewport_rect().width().to_int();
|
||||
if (auto const navigable = associated_document().navigable())
|
||||
return navigable->viewport_rect().width().to_int();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1111,8 +1112,8 @@ i32 Window::inner_height() const
|
|||
{
|
||||
// The innerHeight attribute must return the viewport height including the size of a rendered scroll bar (if any),
|
||||
// or zero if there is no viewport.
|
||||
if (auto const* browsing_context = associated_document().browsing_context())
|
||||
return browsing_context->viewport_rect().height().to_int();
|
||||
if (auto const navigable = associated_document().navigable())
|
||||
return navigable->viewport_rect().height().to_int();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1122,7 +1123,7 @@ double Window::scroll_x() const
|
|||
// The scrollX attribute must return the x-coordinate, relative to the initial containing block origin,
|
||||
// of the left of the viewport, or zero if there is no viewport.
|
||||
if (auto* page = this->page())
|
||||
return page->top_level_browsing_context().viewport_scroll_offset().x().to_double();
|
||||
return page->top_level_traversable()->viewport_scroll_offset().x().to_double();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1132,7 +1133,7 @@ double Window::scroll_y() const
|
|||
// The scrollY attribute must return the y-coordinate, relative to the initial containing block origin,
|
||||
// of the top of the viewport, or zero if there is no viewport.
|
||||
if (auto* page = this->page())
|
||||
return page->top_level_browsing_context().viewport_scroll_offset().y().to_double();
|
||||
return page->top_level_traversable()->viewport_scroll_offset().y().to_double();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1158,12 +1159,12 @@ void Window::scroll(ScrollToOptions const& options)
|
|||
auto* page = this->page();
|
||||
if (!page)
|
||||
return;
|
||||
auto const& top_level_browsing_context = page->top_level_browsing_context();
|
||||
auto top_level_traversable = page->top_level_traversable();
|
||||
|
||||
// 1. If invoked with one argument, follow these substeps:
|
||||
|
||||
// 1. Let options be the argument.
|
||||
auto viewport_rect = top_level_browsing_context.viewport_rect().to_type<float>();
|
||||
auto viewport_rect = top_level_traversable->viewport_rect().to_type<float>();
|
||||
|
||||
// 2. Let x be the value of the left dictionary member of options, if present, or the viewport’s current scroll
|
||||
// position on the x axis otherwise.
|
||||
|
@ -1206,7 +1207,7 @@ void Window::scroll(ScrollToOptions const& options)
|
|||
// smooth scroll, abort these steps.
|
||||
|
||||
// 11. Let document be the viewport’s associated Document.
|
||||
auto const* document = top_level_browsing_context.active_document();
|
||||
auto const document = top_level_traversable->active_document();
|
||||
|
||||
// 12. Perform a scroll of the viewport to position, document’s root element as the associated element, if there is
|
||||
// one, or null otherwise, and the scroll behavior being the value of the behavior dictionary member of options.
|
||||
|
|
|
@ -173,12 +173,12 @@ CSSPixelRect IntersectionObserver::root_intersection_rectangle() const
|
|||
if (intersection_root.has<JS::Handle<DOM::Document>>()) {
|
||||
auto document = intersection_root.get<JS::Handle<DOM::Document>>();
|
||||
|
||||
// Since the spec says that this is only reach if the document is fully active, that means it must have a browsing context.
|
||||
VERIFY(document->browsing_context());
|
||||
// Since the spec says that this is only reach if the document is fully active, that means it must have a navigable.
|
||||
VERIFY(document->navigable());
|
||||
|
||||
// NOTE: This rect is the *size* of the viewport. The viewport *offset* is not relevant,
|
||||
// as intersections are computed using viewport-relative element rects.
|
||||
rect = CSSPixelRect { CSSPixelPoint { 0, 0 }, document->browsing_context()->viewport_rect().size() };
|
||||
rect = CSSPixelRect { CSSPixelPoint { 0, 0 }, document->viewport_rect().size() };
|
||||
} else {
|
||||
VERIFY(intersection_root.has<JS::Handle<DOM::Element>>());
|
||||
auto element = intersection_root.get<JS::Handle<DOM::Element>>();
|
||||
|
|
|
@ -63,8 +63,11 @@ bool Box::is_user_scrollable() const
|
|||
|
||||
void Box::set_needs_display()
|
||||
{
|
||||
if (!navigable())
|
||||
return;
|
||||
|
||||
if (paintable_box())
|
||||
browsing_context().set_needs_display(paintable_box()->absolute_rect());
|
||||
navigable()->set_needs_display(paintable_box()->absolute_rect());
|
||||
}
|
||||
|
||||
bool Box::is_body() const
|
||||
|
|
|
@ -32,8 +32,8 @@ void FrameBox::did_set_content_size()
|
|||
{
|
||||
ReplacedBox::did_set_content_size();
|
||||
|
||||
VERIFY(dom_node().nested_browsing_context());
|
||||
dom_node().nested_browsing_context()->set_size(paintable_box()->content_size());
|
||||
VERIFY(dom_node().content_navigable());
|
||||
dom_node().content_navigable()->set_size(paintable_box()->content_size());
|
||||
}
|
||||
|
||||
JS::GCPtr<Painting::Paintable> FrameBox::create_paintable() const
|
||||
|
|
|
@ -196,6 +196,11 @@ HTML::BrowsingContext& Node::browsing_context()
|
|||
return *m_browsing_context;
|
||||
}
|
||||
|
||||
JS::GCPtr<HTML::Navigable> Node::navigable() const
|
||||
{
|
||||
return document().navigable();
|
||||
}
|
||||
|
||||
Viewport const& Node::root() const
|
||||
{
|
||||
VERIFY(document().layout_node());
|
||||
|
@ -219,7 +224,8 @@ void Node::set_needs_display()
|
|||
return;
|
||||
static_cast<Painting::PaintableWithLines const&>(*containing_block->paintable_box()).for_each_fragment([&](auto& fragment) {
|
||||
if (&fragment.layout_node() == this || is_ancestor_of(fragment.layout_node())) {
|
||||
browsing_context().set_needs_display(fragment.absolute_rect());
|
||||
if (navigable())
|
||||
navigable()->set_needs_display(fragment.absolute_rect());
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
|
|
@ -77,6 +77,8 @@ public:
|
|||
HTML::BrowsingContext const& browsing_context() const;
|
||||
HTML::BrowsingContext& browsing_context();
|
||||
|
||||
JS::GCPtr<HTML::Navigable> navigable() const;
|
||||
|
||||
Viewport const& root() const;
|
||||
Viewport& root();
|
||||
|
||||
|
|
|
@ -517,7 +517,7 @@ bool EventHandler::handle_mousemove(CSSPixelPoint position, CSSPixelPoint screen
|
|||
else
|
||||
(void)selection->set_base_and_extent(*hit->paintable->dom_node(), hit->index_in_node, *hit->paintable->dom_node(), hit->index_in_node);
|
||||
}
|
||||
m_browsing_context->set_needs_display();
|
||||
document.navigable()->set_needs_display();
|
||||
}
|
||||
if (auto* page = m_browsing_context->page())
|
||||
page->client().page_did_change_selection();
|
||||
|
@ -822,7 +822,7 @@ CSSPixelPoint EventHandler::compute_mouse_event_client_offset(CSSPixelPoint even
|
|||
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-mouseevent-clientx
|
||||
// The clientX attribute must return the x-coordinate of the position where the event occurred relative to the origin of the viewport.
|
||||
|
||||
auto scroll_offset = m_browsing_context->viewport_scroll_offset();
|
||||
auto scroll_offset = m_browsing_context->active_document()->navigable()->viewport_scroll_offset();
|
||||
return event_page_position.translated(-scroll_offset);
|
||||
}
|
||||
|
||||
|
@ -832,7 +832,7 @@ CSSPixelPoint EventHandler::compute_mouse_event_page_offset(CSSPixelPoint event_
|
|||
// FIXME: 1. If the event’s dispatch flag is set, return the horizontal coordinate of the position where the event occurred relative to the origin of the initial containing block and terminate these steps.
|
||||
|
||||
// 2. Let offset be the value of the scrollX attribute of the event’s associated Window object, if there is one, or zero otherwise.
|
||||
auto scroll_offset = m_browsing_context->viewport_scroll_offset();
|
||||
auto scroll_offset = m_browsing_context->active_document()->navigable()->viewport_scroll_offset();
|
||||
|
||||
// 3. Return the sum of offset and the value of the event’s clientX attribute.
|
||||
return event_client_offset.translated(scroll_offset);
|
||||
|
|
|
@ -129,7 +129,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
// Attachment and Origin
|
||||
switch (layer.attachment) {
|
||||
case CSS::BackgroundAttachment::Fixed:
|
||||
background_positioning_area = layout_node.root().browsing_context().viewport_rect();
|
||||
background_positioning_area = layout_node.root().navigable()->viewport_rect();
|
||||
break;
|
||||
case CSS::BackgroundAttachment::Local:
|
||||
background_positioning_area = get_box(layer.origin).rect;
|
||||
|
|
|
@ -56,7 +56,7 @@ void NestedBrowsingContextPaintable::paint(PaintContext& context, PaintPhase pha
|
|||
auto absolute_device_rect = context.enclosing_device_rect(absolute_rect);
|
||||
context.painter().translate(absolute_device_rect.x().value(), absolute_device_rect.y().value());
|
||||
|
||||
context.set_device_viewport_rect({ {}, context.enclosing_device_size(layout_box().dom_node().nested_browsing_context()->size()) });
|
||||
context.set_device_viewport_rect({ {}, context.enclosing_device_size(layout_box().dom_node().content_navigable()->size()) });
|
||||
const_cast<ViewportPaintable*>(hosted_paint_tree)->paint_all_phases(context);
|
||||
|
||||
context.set_device_viewport_rect(old_viewport_rect);
|
||||
|
|
|
@ -542,7 +542,7 @@ Optional<HitTestResult> StackingContext::hit_test(CSSPixelPoint position, HitTes
|
|||
auto transformed_position = affine_transform_matrix().inverse().value_or({}).map(offset_position).to_type<CSSPixels>() + transform_origin;
|
||||
|
||||
if (paintable_box().is_fixed_position()) {
|
||||
auto scroll_offset = paintable_box().document().browsing_context()->viewport_scroll_offset();
|
||||
auto scroll_offset = paintable_box().document().navigable()->viewport_scroll_offset();
|
||||
transformed_position.translate_by(-scroll_offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||
#include <LibWeb/HTML/TagNames.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Namespace.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
@ -54,7 +55,7 @@ Response capture_element_screenshot(Painter const& painter, Page& page, DOM::Ele
|
|||
Optional<Response> encoded_string_or_error;
|
||||
|
||||
element.document().window().animation_frame_callback_driver().add([&](auto) {
|
||||
auto viewport_rect = page.top_level_browsing_context().viewport_rect();
|
||||
auto viewport_rect = page.top_level_traversable()->viewport_rect();
|
||||
rect.intersect(page.enclosing_device_rect(viewport_rect).to_type<int>());
|
||||
|
||||
auto canvas_element = DOM::create_element(element.document(), HTML::TagNames::canvas, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
|
||||
|
|
|
@ -441,7 +441,7 @@ void ConnectionFromClient::debug_request(DeprecatedString const& request, Deprec
|
|||
if (request == "set-line-box-borders") {
|
||||
bool state = argument == "on";
|
||||
m_page_host->set_should_show_line_box_borders(state);
|
||||
page().top_level_browsing_context().set_needs_display(page().top_level_browsing_context().viewport_rect());
|
||||
page().top_level_traversable()->set_needs_display(page().top_level_traversable()->viewport_rect());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <LibWeb/CSS/SystemColor.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
#include <LibWeb/Painting/ViewportPaintable.h>
|
||||
|
@ -146,7 +147,7 @@ void PageHost::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& targ
|
|||
|
||||
void PageHost::set_viewport_rect(Web::DevicePixelRect const& rect)
|
||||
{
|
||||
page().top_level_browsing_context().set_viewport_rect(page().device_to_css_rect(rect));
|
||||
page().top_level_traversable()->set_viewport_rect(page().device_to_css_rect(rect));
|
||||
}
|
||||
|
||||
void PageHost::page_did_invalidate(Web::CSSPixelRect const& content_rect)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue