mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Add opt-in tracing of update_layout() calls with reason
This commit is contained in:
parent
c4b1d2382a
commit
c333042e63
Notes:
github-actions[bot]
2025-03-08 02:39:13 +00:00
Author: https://github.com/awesomekling
Commit: c333042e63
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3852
21 changed files with 137 additions and 52 deletions
|
@ -254,6 +254,10 @@
|
|||
# cmakedefine01 TOKENIZER_TRACE_DEBUG
|
||||
#endif
|
||||
|
||||
#ifndef UPDATE_LAYOUT_DEBUG
|
||||
# cmakedefine01 UPDATE_LAYOUT_DEBUG
|
||||
#endif
|
||||
|
||||
#ifndef URL_PARSER_DEBUG
|
||||
# cmakedefine01 URL_PARSER_DEBUG
|
||||
#endif
|
||||
|
|
|
@ -65,7 +65,7 @@ bool MediaQueryList::matches() const
|
|||
// NOTE: If our document is inside a frame, we need to update layout
|
||||
// since that may cause our frame (and thus viewport) to resize.
|
||||
if (auto container_document = m_document->container_document()) {
|
||||
container_document->update_layout();
|
||||
container_document->update_layout(DOM::UpdateLayoutReason::MediaQueryListMatches);
|
||||
const_cast<MediaQueryList*>(this)->evaluate();
|
||||
}
|
||||
|
||||
|
|
|
@ -513,7 +513,7 @@ Optional<StyleProperty> ResolvedCSSStyleDeclaration::property(PropertyID propert
|
|||
// We may legitimately have no layout node if we're not visible, but this protects against situations
|
||||
// where we're requesting the computed style before layout has happened.
|
||||
if (!layout_node || property_affects_layout(property_id)) {
|
||||
const_cast<DOM::Document&>(m_element->document()).update_layout();
|
||||
const_cast<DOM::Document&>(m_element->document()).update_layout(DOM::UpdateLayoutReason::ResolvedCSSStyleDeclarationProperty);
|
||||
layout_node = get_layout_node();
|
||||
} else {
|
||||
// FIXME: If we had a way to update style for a single element, this would be a good place to use it.
|
||||
|
|
|
@ -458,7 +458,7 @@ Document::Document(JS::Realm& realm, const URL::URL& url, TemporaryDocumentForFr
|
|||
if (!navigable || !navigable->is_focused())
|
||||
return;
|
||||
|
||||
node->document().update_layout();
|
||||
node->document().update_layout(UpdateLayoutReason::CursorBlinkTimer);
|
||||
|
||||
if (node->paintable()) {
|
||||
m_cursor_blink_state = !m_cursor_blink_state;
|
||||
|
@ -1278,7 +1278,7 @@ static void propagate_overflow_to_viewport(Element& root_element, Layout::Viewpo
|
|||
overflow_origin_computed_values.set_overflow_y(CSS::Overflow::Visible);
|
||||
}
|
||||
|
||||
void Document::update_layout()
|
||||
void Document::update_layout(UpdateLayoutReason reason)
|
||||
{
|
||||
auto navigable = this->navigable();
|
||||
if (!navigable || navigable->active_document() != this)
|
||||
|
@ -1287,7 +1287,7 @@ void Document::update_layout()
|
|||
// NOTE: If our parent document needs a relayout, we must do that *first*.
|
||||
// This is necessary as the parent layout may cause our viewport to change.
|
||||
if (navigable->container() && &navigable->container()->document() != this)
|
||||
navigable->container()->document().update_layout();
|
||||
navigable->container()->document().update_layout(reason);
|
||||
|
||||
update_style();
|
||||
|
||||
|
@ -1303,6 +1303,8 @@ void Document::update_layout()
|
|||
auto* document_element = this->document_element();
|
||||
auto viewport_rect = navigable->viewport_rect();
|
||||
|
||||
auto timer = Core::ElapsedTimer::start_new(Core::TimerType::Precise);
|
||||
|
||||
if (!m_layout_root || needs_layout_tree_update() || child_needs_layout_tree_update() || needs_full_layout_tree_update()) {
|
||||
Layout::TreeBuilder tree_builder;
|
||||
m_layout_root = as<Layout::Viewport>(*tree_builder.build(*this));
|
||||
|
@ -1313,6 +1315,10 @@ void Document::update_layout()
|
|||
}
|
||||
|
||||
set_needs_full_layout_tree_update(false);
|
||||
|
||||
if constexpr (UPDATE_LAYOUT_DEBUG) {
|
||||
dbgln("TREEBUILD {} µs", timer.elapsed_time().to_microseconds());
|
||||
}
|
||||
}
|
||||
|
||||
// Assign each box that establishes a formatting context a list of absolutely positioned children it should take care of during layout
|
||||
|
@ -1388,6 +1394,10 @@ void Document::update_layout()
|
|||
// after the viewport size change.
|
||||
if (auto window = this->window())
|
||||
window->scroll_by(0, 0);
|
||||
|
||||
if constexpr (UPDATE_LAYOUT_DEBUG) {
|
||||
dbgln("LAYOUT {} {} µs", to_string(reason), timer.elapsed_time().to_microseconds());
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] static CSS::RequiredInvalidationAfterStyleChange update_style_recursively(Node& node, CSS::StyleComputer& style_computer, bool needs_inherited_style_update)
|
||||
|
@ -5405,7 +5415,7 @@ WebIDL::ExceptionOr<void> Document::set_design_mode(String const& design_mode)
|
|||
if (auto active_range = selection->range(); active_range) {
|
||||
TRY(active_range->set_start(*this, 0));
|
||||
TRY(active_range->set_end(*this, 0));
|
||||
update_layout();
|
||||
update_layout(UpdateLayoutReason::DocumentSetDesignMode);
|
||||
}
|
||||
}
|
||||
// 3. Run the focusing steps for this's document element, if non-null.
|
||||
|
@ -5432,7 +5442,7 @@ Element const* Document::element_from_point(double x, double y)
|
|||
return nullptr;
|
||||
|
||||
// Ensure the layout tree exists prior to hit testing.
|
||||
update_layout();
|
||||
update_layout(UpdateLayoutReason::DocumentElementFromPoint);
|
||||
|
||||
// 2. If there is a box in the viewport that would be a target for hit testing at coordinates x,y, when applying the transforms
|
||||
// that apply to the descendants of the viewport, return the associated element and terminate these steps.
|
||||
|
@ -5474,7 +5484,7 @@ GC::RootVector<GC::Ref<Element>> Document::elements_from_point(double x, double
|
|||
return sequence;
|
||||
|
||||
// Ensure the layout tree exists prior to hit testing.
|
||||
update_layout();
|
||||
update_layout(UpdateLayoutReason::DocumentElementsFromPoint);
|
||||
|
||||
// 3. For each box in the viewport, in paint order, starting with the topmost box, that would be a target for
|
||||
// hit testing at coordinates x,y even if nothing would be overlapping it, when applying the transforms that
|
||||
|
@ -6002,7 +6012,7 @@ void Document::set_needs_to_refresh_scroll_state(bool b)
|
|||
Vector<GC::Root<DOM::Range>> Document::find_matching_text(String const& query, CaseSensitivity case_sensitivity)
|
||||
{
|
||||
// Ensure the layout tree exists before searching for text matches.
|
||||
update_layout();
|
||||
update_layout(UpdateLayoutReason::DocumentFindMatchingText);
|
||||
|
||||
if (!layout_node())
|
||||
return {};
|
||||
|
@ -6393,4 +6403,16 @@ void Document::set_onvisibilitychange(WebIDL::CallbackType* value)
|
|||
set_event_handler_attribute(HTML::EventNames::visibilitychange, value);
|
||||
}
|
||||
|
||||
StringView to_string(UpdateLayoutReason reason)
|
||||
{
|
||||
switch (reason) {
|
||||
#define ENUMERATE_UPDATE_LAYOUT_REASON(e) \
|
||||
case UpdateLayoutReason::e: \
|
||||
return #e##sv;
|
||||
ENUMERATE_UPDATE_LAYOUT_REASONS(ENUMERATE_UPDATE_LAYOUT_REASON)
|
||||
#undef ENUMERATE_UPDATE_LAYOUT_REASON
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,64 @@ enum class QuirksMode {
|
|||
Yes
|
||||
};
|
||||
|
||||
#define ENUMERATE_UPDATE_LAYOUT_REASONS(X) \
|
||||
X(CanvasRenderingContext2DSetFilter) \
|
||||
X(CursorBlinkTimer) \
|
||||
X(Debugging) \
|
||||
X(DocumentElementFromPoint) \
|
||||
X(DocumentElementsFromPoint) \
|
||||
X(DocumentFindMatchingText) \
|
||||
X(DocumentSetDesignMode) \
|
||||
X(ElementCheckVisibility) \
|
||||
X(ElementClientHeight) \
|
||||
X(ElementClientLeft) \
|
||||
X(ElementClientTop) \
|
||||
X(ElementClientWidth) \
|
||||
X(ElementGetClientRects) \
|
||||
X(ElementIsPotentiallyScrollable) \
|
||||
X(ElementScroll) \
|
||||
X(ElementScrollHeight) \
|
||||
X(ElementScrollIntoView) \
|
||||
X(ElementScrollLeft) \
|
||||
X(ElementScrollTop) \
|
||||
X(ElementScrollWidth) \
|
||||
X(ElementSetScrollLeft) \
|
||||
X(ElementSetScrollTop) \
|
||||
X(EventHandlerHandleDoubleClick) \
|
||||
X(EventHandlerHandleDragAndDrop) \
|
||||
X(EventHandlerHandleMouseDown) \
|
||||
X(EventHandlerHandleMouseMove) \
|
||||
X(EventHandlerHandleMouseUp) \
|
||||
X(EventHandlerHandleMouseWheel) \
|
||||
X(HTMLElementGetTheTextSteps) \
|
||||
X(HTMLElementOffsetHeight) \
|
||||
X(HTMLElementOffsetLeft) \
|
||||
X(HTMLElementOffsetParent) \
|
||||
X(HTMLElementOffsetTop) \
|
||||
X(HTMLElementOffsetWidth) \
|
||||
X(HTMLEventLoopRenderingUpdate) \
|
||||
X(HTMLImageElementHeight) \
|
||||
X(HTMLImageElementWidth) \
|
||||
X(HTMLInputElementHeight) \
|
||||
X(HTMLInputElementWidth) \
|
||||
X(InternalsHitTest) \
|
||||
X(MediaQueryListMatches) \
|
||||
X(NodeNameOrDescription) \
|
||||
X(RangeGetClientRects) \
|
||||
X(ResolvedCSSStyleDeclarationProperty) \
|
||||
X(SVGDecodedImageDataRender) \
|
||||
X(SVGGraphicsElementGetBBox) \
|
||||
X(SourceSetNormalizeSourceDensities) \
|
||||
X(WindowScroll)
|
||||
|
||||
enum class UpdateLayoutReason {
|
||||
#define ENUMERATE_UPDATE_LAYOUT_REASON(e) e,
|
||||
ENUMERATE_UPDATE_LAYOUT_REASONS(ENUMERATE_UPDATE_LAYOUT_REASON)
|
||||
#undef ENUMERATE_UPDATE_LAYOUT_REASON
|
||||
};
|
||||
|
||||
[[nodiscard]] StringView to_string(UpdateLayoutReason);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/dom.html#document-load-timing-info
|
||||
struct DocumentLoadTimingInfo {
|
||||
// https://html.spec.whatwg.org/multipage/dom.html#navigation-start-time
|
||||
|
@ -258,7 +316,7 @@ public:
|
|||
void obtain_theme_color();
|
||||
|
||||
void update_style();
|
||||
void update_layout();
|
||||
void update_layout(UpdateLayoutReason);
|
||||
void update_paint_and_hit_testing_properties_if_needed();
|
||||
void update_animated_style_if_needed();
|
||||
|
||||
|
|
|
@ -994,7 +994,7 @@ GC::Ref<Geometry::DOMRectList> Element::get_client_rects() const
|
|||
return Geometry::DOMRectList::create(realm(), {});
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
const_cast<Document&>(document()).update_layout(UpdateLayoutReason::ElementGetClientRects);
|
||||
|
||||
// 1. If the element on which it was invoked does not have an associated layout box return an empty DOMRectList
|
||||
// object and stop this algorithm.
|
||||
|
@ -1047,7 +1047,7 @@ GC::Ref<Geometry::DOMRectList> Element::get_client_rects() const
|
|||
int Element::client_top() const
|
||||
{
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
const_cast<Document&>(document()).update_layout(UpdateLayoutReason::ElementClientTop);
|
||||
|
||||
// 1. If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.
|
||||
if (!paintable_box())
|
||||
|
@ -1063,7 +1063,7 @@ int Element::client_top() const
|
|||
int Element::client_left() const
|
||||
{
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
const_cast<Document&>(document()).update_layout(UpdateLayoutReason::ElementClientLeft);
|
||||
|
||||
// 1. If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.
|
||||
if (!paintable_box())
|
||||
|
@ -1089,7 +1089,7 @@ int Element::client_width() const
|
|||
}
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
const_cast<Document&>(document()).update_layout(UpdateLayoutReason::ElementClientWidth);
|
||||
|
||||
// 1. If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.
|
||||
if (!paintable_box())
|
||||
|
@ -1114,7 +1114,7 @@ int Element::client_height() const
|
|||
}
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
const_cast<Document&>(document()).update_layout(UpdateLayoutReason::ElementClientHeight);
|
||||
|
||||
// 1. If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.
|
||||
if (!paintable_box())
|
||||
|
@ -1420,7 +1420,7 @@ void Element::set_tab_index(i32 tab_index)
|
|||
bool Element::is_potentially_scrollable() const
|
||||
{
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
const_cast<Document&>(document()).update_layout(UpdateLayoutReason::ElementIsPotentiallyScrollable);
|
||||
|
||||
// An element body (which will be the body element) is potentially scrollable if all of the following conditions are true:
|
||||
VERIFY(is<HTML::HTMLBodyElement>(this) || is<HTML::HTMLFrameSetElement>(this));
|
||||
|
@ -1466,7 +1466,7 @@ double Element::scroll_top() const
|
|||
return window->scroll_y();
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document).update_layout();
|
||||
const_cast<Document&>(document).update_layout(UpdateLayoutReason::ElementScrollTop);
|
||||
|
||||
// 7. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, return the value of scrollY on window.
|
||||
if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable())
|
||||
|
@ -1508,7 +1508,7 @@ double Element::scroll_left() const
|
|||
return window->scroll_x();
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document).update_layout();
|
||||
const_cast<Document&>(document).update_layout(UpdateLayoutReason::ElementScrollLeft);
|
||||
|
||||
// 7. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, return the value of scrollX on window.
|
||||
if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable())
|
||||
|
@ -1557,7 +1557,7 @@ void Element::set_scroll_left(double x)
|
|||
}
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics or scrolling the page.
|
||||
const_cast<Document&>(document).update_layout();
|
||||
const_cast<Document&>(document).update_layout(UpdateLayoutReason::ElementSetScrollLeft);
|
||||
|
||||
// 9. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, invoke scroll() on window with x as first argument and scrollY on window as second argument, and terminate these steps.
|
||||
if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable()) {
|
||||
|
@ -1614,7 +1614,7 @@ void Element::set_scroll_top(double y)
|
|||
}
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics or scrolling the page.
|
||||
const_cast<Document&>(document).update_layout();
|
||||
const_cast<Document&>(document).update_layout(UpdateLayoutReason::ElementSetScrollTop);
|
||||
|
||||
// 9. If the element is the body element, document is in quirks mode, and the element is not potentially scrollable, invoke scroll() on window with scrollX as first argument and y as second argument, and terminate these steps.
|
||||
if (document.body() == this && document.in_quirks_mode() && !is_potentially_scrollable()) {
|
||||
|
@ -1659,7 +1659,7 @@ int Element::scroll_width() const
|
|||
return max(viewport_scroll_width, viewport_width);
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document).update_layout();
|
||||
const_cast<Document&>(document).update_layout(UpdateLayoutReason::ElementScrollWidth);
|
||||
|
||||
// 5. If the element is the body element, document is in quirks mode and the element is not potentially scrollable,
|
||||
// return max(viewport scrolling area width, viewport width).
|
||||
|
@ -1698,7 +1698,7 @@ int Element::scroll_height() const
|
|||
return max(viewport_scroll_height, viewport_height);
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document).update_layout();
|
||||
const_cast<Document&>(document).update_layout(UpdateLayoutReason::ElementScrollHeight);
|
||||
|
||||
// 5. If the element is the body element, document is in quirks mode and the element is not potentially scrollable,
|
||||
// return max(viewport scrolling area height, viewport height).
|
||||
|
@ -2180,7 +2180,7 @@ ErrorOr<void> Element::scroll_into_view(Optional<Variant<bool, ScrollIntoViewOpt
|
|||
}
|
||||
|
||||
// 7. If the element does not have any associated box, or is not available to user-agent features, then return.
|
||||
document().update_layout();
|
||||
document().update_layout(UpdateLayoutReason::ElementScrollIntoView);
|
||||
if (!layout_node())
|
||||
return Error::from_string_literal("Element has no associated box");
|
||||
|
||||
|
@ -2761,7 +2761,7 @@ void Element::scroll(double x, double y)
|
|||
return;
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
document.update_layout();
|
||||
document.update_layout(UpdateLayoutReason::ElementScroll);
|
||||
|
||||
// 8. If the element is the root element invoke scroll() on window with scrollX on window as first argument and y as second argument, and terminate these steps.
|
||||
if (document.document_element() == this) {
|
||||
|
@ -2841,7 +2841,7 @@ void Element::scroll_by(HTML::ScrollToOptions options)
|
|||
bool Element::check_visibility(Optional<CheckVisibilityOptions> options)
|
||||
{
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
document().update_layout();
|
||||
document().update_layout(UpdateLayoutReason::ElementCheckVisibility);
|
||||
|
||||
// 1. If this does not have an associated box, return false.
|
||||
if (!paintable_box())
|
||||
|
|
|
@ -2745,7 +2745,7 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
if (!child_node->is_element() && !child_node->is_text())
|
||||
continue;
|
||||
bool should_add_space = true;
|
||||
const_cast<DOM::Document&>(document).update_layout();
|
||||
const_cast<DOM::Document&>(document).update_layout(DOM::UpdateLayoutReason::NodeNameOrDescription);
|
||||
auto const* layout_node = child_node->layout_node();
|
||||
if (layout_node) {
|
||||
auto display = layout_node->display();
|
||||
|
|
|
@ -1157,7 +1157,7 @@ GC::Ref<Geometry::DOMRectList> Range::get_client_rects()
|
|||
if (!start_container()->document().navigable())
|
||||
return Geometry::DOMRectList::create(realm(), {});
|
||||
|
||||
start_container()->document().update_layout();
|
||||
start_container()->document().update_layout(DOM::UpdateLayoutReason::RangeGetClientRects);
|
||||
update_associated_selection();
|
||||
Vector<GC::Root<Geometry::DOMRect>> rects;
|
||||
// FIXME: take Range collapsed into consideration
|
||||
|
|
|
@ -962,7 +962,7 @@ void CanvasRenderingContext2D::set_filter(String filter)
|
|||
drawing_state().filters.grow_capacity(filter_value_list.size());
|
||||
|
||||
// Note: The layout must be updated to make sure the canvas's layout node isn't null.
|
||||
canvas_element().document().update_layout();
|
||||
canvas_element().document().update_layout(DOM::UpdateLayoutReason::CanvasRenderingContext2DSetFilter);
|
||||
auto layout_node = canvas_element().layout_node();
|
||||
|
||||
// 4. Set this's current filter to the given value.
|
||||
|
|
|
@ -400,7 +400,7 @@ void EventLoop::update_the_rendering()
|
|||
while (true) {
|
||||
// 1. Recalculate styles and update layout for doc.
|
||||
// NOTE: Recalculation of styles is handled by update_layout()
|
||||
document->update_layout();
|
||||
document->update_layout(DOM::UpdateLayoutReason::HTMLEventLoopRenderingUpdate);
|
||||
|
||||
// 2. Let hadInitialVisibleContentVisibilityDetermination be false.
|
||||
bool had_initial_visible_content_visibility_determination = false;
|
||||
|
|
|
@ -368,7 +368,7 @@ static Vector<Variant<String, RequiredLineBreakCount>> rendered_text_collection_
|
|||
String HTMLElement::get_the_text_steps()
|
||||
{
|
||||
// 1. If element is not being rendered or if the user agent is a non-CSS user agent, then return element's descendant text content.
|
||||
document().update_layout();
|
||||
document().update_layout(DOM::UpdateLayoutReason::HTMLElementGetTheTextSteps);
|
||||
if (!layout_node())
|
||||
return descendant_text_content();
|
||||
|
||||
|
@ -444,7 +444,7 @@ String HTMLElement::outer_text()
|
|||
// https://www.w3.org/TR/cssom-view-1/#dom-htmlelement-offsetparent
|
||||
GC::Ptr<DOM::Element> HTMLElement::offset_parent() const
|
||||
{
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLElementOffsetParent);
|
||||
|
||||
// 1. If any of the following holds true return null and terminate this algorithm:
|
||||
// - The element does not have an associated CSS layout box.
|
||||
|
@ -491,7 +491,7 @@ int HTMLElement::offset_top() const
|
|||
return 0;
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLElementOffsetTop);
|
||||
|
||||
if (!paintable_box())
|
||||
return 0;
|
||||
|
@ -533,7 +533,7 @@ int HTMLElement::offset_left() const
|
|||
return 0;
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLElementOffsetLeft);
|
||||
|
||||
if (!paintable_box())
|
||||
return 0;
|
||||
|
@ -571,7 +571,7 @@ int HTMLElement::offset_left() const
|
|||
int HTMLElement::offset_width() const
|
||||
{
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLElementOffsetWidth);
|
||||
|
||||
// 1. If the element does not have any associated box return zero and terminate this algorithm.
|
||||
auto const* box = paintable_box();
|
||||
|
@ -590,7 +590,7 @@ int HTMLElement::offset_width() const
|
|||
int HTMLElement::offset_height() const
|
||||
{
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLElementOffsetHeight);
|
||||
|
||||
// 1. If the element does not have any associated box return zero and terminate this algorithm.
|
||||
auto const* box = paintable_box();
|
||||
|
|
|
@ -204,7 +204,7 @@ void HTMLImageElement::set_visible_in_viewport(bool)
|
|||
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-width
|
||||
WebIDL::UnsignedLong HTMLImageElement::width() const
|
||||
{
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLImageElementWidth);
|
||||
|
||||
// Return the rendered width of the image, in CSS pixels, if the image is being rendered.
|
||||
if (auto* paintable_box = this->paintable_box())
|
||||
|
@ -235,7 +235,7 @@ WebIDL::ExceptionOr<void> HTMLImageElement::set_width(WebIDL::UnsignedLong width
|
|||
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-height
|
||||
WebIDL::UnsignedLong HTMLImageElement::height() const
|
||||
{
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLImageElementHeight);
|
||||
|
||||
// Return the rendered height of the image, in CSS pixels, if the image is being rendered.
|
||||
if (auto* paintable_box = this->paintable_box())
|
||||
|
|
|
@ -2029,7 +2029,7 @@ WebIDL::ExceptionOr<void> HTMLInputElement::set_size(WebIDL::UnsignedLong value)
|
|||
// https://html.spec.whatwg.org/multipage/input.html#dom-input-height
|
||||
WebIDL::UnsignedLong HTMLInputElement::height() const
|
||||
{
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLInputElementHeight);
|
||||
|
||||
// When the input element's type attribute is not in the Image Button state, then no image is available.
|
||||
if (type_state() != TypeAttributeState::ImageButton)
|
||||
|
@ -2064,7 +2064,7 @@ WebIDL::ExceptionOr<void> HTMLInputElement::set_height(WebIDL::UnsignedLong valu
|
|||
// https://html.spec.whatwg.org/multipage/input.html#dom-input-width
|
||||
WebIDL::UnsignedLong HTMLInputElement::width() const
|
||||
{
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::HTMLInputElementWidth);
|
||||
|
||||
// When the input element's type attribute is not in the Image Button state, then no image is available.
|
||||
if (type_state() != TypeAttributeState::ImageButton)
|
||||
|
|
|
@ -402,7 +402,7 @@ void SourceSet::normalize_source_densities(DOM::Element const& element)
|
|||
|
||||
// HACK: Flush any pending layouts here so we get an up-to-date length resolution context.
|
||||
// FIXME: We should have a way to build a LengthResolutionContext for any DOM node without going through the layout tree.
|
||||
const_cast<DOM::Document&>(element.document()).update_layout();
|
||||
const_cast<DOM::Document&>(element.document()).update_layout(DOM::UpdateLayoutReason::SourceSetNormalizeSourceDensities);
|
||||
if (element.layout_node()) {
|
||||
CSS::CalculationResolutionContext context { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*element.layout_node()) };
|
||||
return m_source_size.resolved(context).value_or(CSS::Length::make_auto());
|
||||
|
|
|
@ -1422,7 +1422,7 @@ void Window::scroll(ScrollToOptions const& options)
|
|||
VERIFY(document);
|
||||
|
||||
// Make sure layout is up-to-date before looking at scrollable overflow metrics.
|
||||
document->update_layout();
|
||||
document->update_layout(DOM::UpdateLayoutReason::WindowScroll);
|
||||
|
||||
VERIFY(document->paintable_box());
|
||||
auto scrolling_area = document->paintable_box()->scrollable_overflow_rect()->to_type<float>();
|
||||
|
|
|
@ -69,7 +69,7 @@ JS::Object* Internals::hit_test(double x, double y)
|
|||
// NOTE: Force a layout update just before hit testing. This is because the current layout tree, which is required
|
||||
// for stacking context traversal, might not exist if this call occurs between the tear_down_layout_tree()
|
||||
// and update_layout() calls
|
||||
active_document.update_layout();
|
||||
active_document.update_layout(DOM::UpdateLayoutReason::InternalsHitTest);
|
||||
auto result = active_document.paintable_box()->hit_test({ x, y }, Painting::HitTestType::Exact);
|
||||
if (result.has_value()) {
|
||||
auto hit_tеsting_result = JS::Object::create(realm(), nullptr);
|
||||
|
|
|
@ -365,7 +365,7 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseWheel);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
@ -431,7 +431,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseUp);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
@ -575,7 +575,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseDown);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
@ -699,7 +699,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
m_navigable->active_document()->update_layout();
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseMove);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
@ -846,7 +846,7 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
|||
|
||||
auto& document = *m_navigable->active_document();
|
||||
|
||||
document.update_layout();
|
||||
document.update_layout(DOM::UpdateLayoutReason::EventHandlerHandleDoubleClick);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
@ -924,7 +924,7 @@ EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPi
|
|||
return EventResult::Dropped;
|
||||
|
||||
auto& document = *m_navigable->active_document();
|
||||
document.update_layout();
|
||||
document.update_layout(DOM::UpdateLayoutReason::EventHandlerHandleDragAndDrop);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
|
|
@ -94,7 +94,7 @@ RefPtr<Gfx::Bitmap> SVGDecodedImageData::render(Gfx::IntSize size) const
|
|||
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, Gfx::AlphaType::Premultiplied, size).release_value_but_fixme_should_propagate_errors();
|
||||
VERIFY(m_document->navigable());
|
||||
m_document->navigable()->set_viewport_size(size.to_type<CSSPixels>());
|
||||
m_document->update_layout();
|
||||
m_document->update_layout(DOM::UpdateLayoutReason::SVGDecodedImageDataRender);
|
||||
|
||||
auto display_list = m_document->record_display_list({});
|
||||
if (!display_list)
|
||||
|
|
|
@ -362,7 +362,7 @@ GC::Ref<Geometry::DOMRect> SVGGraphicsElement::get_b_box(Optional<SVGBoundingBox
|
|||
// SVG coordinate space (before any viewbox or other transformations), so it should be possible to
|
||||
// calculate this from SVG geometry without a full layout tree (at least for simple cases).
|
||||
// See: https://svgwg.org/svg2-draft/coords.html#BoundingBoxes
|
||||
const_cast<DOM::Document&>(document()).update_layout();
|
||||
const_cast<DOM::Document&>(document()).update_layout(DOM::UpdateLayoutReason::SVGGraphicsElementGetBBox);
|
||||
if (!layout_node())
|
||||
return Geometry::DOMRect::create(realm());
|
||||
// Invert the SVG -> screen space transform.
|
||||
|
|
|
@ -59,6 +59,7 @@ set(TIFF_DEBUG ON)
|
|||
set(TIME_ZONE_DEBUG ON)
|
||||
set(TLS_DEBUG ON)
|
||||
set(TOKENIZER_TRACE_DEBUG ON)
|
||||
set(UPDATE_LAYOUT_DEBUG ON)
|
||||
set(URL_PARSER_DEBUG ON)
|
||||
set(UTF8_DEBUG ON)
|
||||
set(VPX_DEBUG ON)
|
||||
|
|
|
@ -886,7 +886,7 @@ static void append_layout_tree(Web::Page& page, StringBuilder& builder)
|
|||
return;
|
||||
}
|
||||
|
||||
document->update_layout();
|
||||
document->update_layout(Web::DOM::UpdateLayoutReason::Debugging);
|
||||
|
||||
auto* layout_root = document->layout_node();
|
||||
if (!layout_root) {
|
||||
|
@ -905,7 +905,7 @@ static void append_paint_tree(Web::Page& page, StringBuilder& builder)
|
|||
return;
|
||||
}
|
||||
|
||||
document->update_layout();
|
||||
document->update_layout(Web::DOM::UpdateLayoutReason::Debugging);
|
||||
|
||||
auto* layout_root = document->layout_node();
|
||||
if (!layout_root) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue