blob: 6353404482483dbf5f8f767c745cb1877e44e623 [file] [log] [blame]
* Copyright (C) 1999 Lars Knoll (
* Copyright (C) 2006 Apple Computer, Inc.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* Library General Public License for more details.
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
#include <memory>
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/hit_test_cache.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_state.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class LayoutQuote;
class LocalFrameView;
class PaintLayerCompositor;
class ViewFragmentationContext;
// LayoutView is the root of the layout tree and the Document's LayoutObject.
// It corresponds to the CSS concept of 'initial containing block' (or ICB).
// Its dimensions match that of the layout viewport. This viewport is used to
// size elements, in particular fixed positioned elements.
// LayoutView is always at position (0,0) relative to the document (and so isn't
// necessarily in view).
// See
// about the different viewports.
// Because there is one LayoutView per rooted layout tree (or Frame), this class
// is used to add members shared by this tree (e.g. m_layoutState or
// m_layoutQuoteHead).
class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
explicit LayoutView(Document*);
~LayoutView() override;
void WillBeDestroyed() override;
// hitTest() will update layout, style and compositing first while
// hitTestNoLifecycleUpdate() does not.
bool HitTest(const HitTestLocation& location, HitTestResult&);
bool HitTestNoLifecycleUpdate(const HitTestLocation& location,
// Returns the total count of calls to HitTest, for testing.
unsigned HitTestCount() const { return hit_test_count_; }
unsigned HitTestCacheHits() const { return hit_test_cache_hits_; }
void ClearHitTestCache();
const char* GetName() const override { return "LayoutView"; }
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectLayoutView || LayoutBlockFlow::IsOfType(type);
PaintLayerType LayerTypeRequired() const override {
return kNormalPaintLayer;
bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
void UpdateLayout() override;
void UpdateLogicalWidth() override;
void ComputeLogicalHeight(LayoutUnit logical_height,
LayoutUnit logical_top,
LogicalExtentComputedValues&) const override;
// Based on LocalFrameView::LayoutSize, but:
// - checks for null LocalFrameView
// - returns 0x0 if using printing layout
// - scrollbar exclusion is compatible with root layer scrolling
IntSize GetLayoutSize(IncludeScrollbarsInRect = kExcludeScrollbars) const;
int ViewHeight(
IncludeScrollbarsInRect scrollbar_inclusion = kExcludeScrollbars) const {
return GetLayoutSize(scrollbar_inclusion).Height();
int ViewWidth(
IncludeScrollbarsInRect scrollbar_inclusion = kExcludeScrollbars) const {
return GetLayoutSize(scrollbar_inclusion).Width();
int ViewLogicalWidth(IncludeScrollbarsInRect = kExcludeScrollbars) const;
int ViewLogicalHeight(IncludeScrollbarsInRect = kExcludeScrollbars) const;
LayoutUnit ViewLogicalHeightForPercentages() const;
float ZoomFactor() const;
LocalFrameView* GetFrameView() const { return frame_view_; }
const LayoutBox& RootBox() const;
void UpdateAfterLayout() override;
// See comments for the equivalent method on LayoutObject.
bool MapToVisualRectInAncestorSpace(const LayoutBoxModelObject* ancestor,
MapCoordinatesFlags mode,
VisualRectFlags) const;
// |ancestor| can be nullptr, which will map the rect to the main frame's
// space, even if the main frame is remote (or has intermediate remote
// frames in the chain).
bool MapToVisualRectInAncestorSpaceInternal(
const LayoutBoxModelObject* ancestor,
VisualRectFlags) const;
bool MapToVisualRectInAncestorSpaceInternal(
const LayoutBoxModelObject* ancestor,
VisualRectFlags = kDefaultVisualRectFlags) const override;
LayoutSize OffsetForFixedPosition() const;
void InvalidatePaintForViewAndCompositedLayers();
void Paint(const PaintInfo&) const override;
void PaintBoxDecorationBackground(
const PaintInfo&,
const LayoutPoint& paint_offset) const override;
void CommitPendingSelection();
void AbsoluteRects(Vector<IntRect>&,
const LayoutPoint& accumulated_offset) const override;
void AbsoluteQuads(Vector<FloatQuad>&,
MapCoordinatesFlags mode = 0) const override;
LayoutRect ViewRect() const override;
LayoutRect OverflowClipRect(
const LayoutPoint& location,
OverlayScrollbarClipBehavior =
kIgnorePlatformOverlayScrollbarSize) const override;
// If either direction has a non-auto mode, the other must as well.
void SetAutosizeScrollbarModes(ScrollbarMode h_mode, ScrollbarMode v_mode);
ScrollbarMode AutosizeHorizontalScrollbarMode() const {
return autosize_h_scrollbar_mode_;
ScrollbarMode AutosizeVerticalScrollbarMode() const {
return autosize_v_scrollbar_mode_;
void CalculateScrollbarModes(ScrollbarMode& h_mode,
ScrollbarMode& v_mode) const;
void MayUpdateHoverWhenContentUnderMouseChanged(EventHandler&) override;
LayoutState* GetLayoutState() const { return layout_state_; }
void UpdateHitTestResult(HitTestResult&, const LayoutPoint&) const override;
ViewFragmentationContext* FragmentationContext() const {
return fragmentation_context_.get();
LayoutUnit PageLogicalHeight() const { return page_logical_height_; }
void SetPageLogicalHeight(LayoutUnit height) {
page_logical_height_ = height;
// Notification that this view moved into or out of a native window.
void SetIsInWindow(bool);
PaintLayerCompositor* Compositor();
bool UsesCompositing() const;
IntRect DocumentRect() const;
IntervalArena* GetIntervalArena();
void SetLayoutQuoteHead(LayoutQuote* head) { layout_quote_head_ = head; }
LayoutQuote* LayoutQuoteHead() const { return layout_quote_head_; }
// FIXME: This is a work around because the current implementation of counters
// requires walking the entire tree repeatedly and most pages don't actually
// use either feature so we shouldn't take the performance hit when not
// needed. Long term we should rewrite the counter and quotes code.
void AddLayoutCounter() {
void RemoveLayoutCounter() {
DCHECK_GT(layout_counter_count_, 0u);
bool HasLayoutCounters() { return layout_counter_count_; }
void SetNeedsCounterUpdate() { needs_counter_update_ = true; }
void UpdateCounters();
bool BackgroundIsKnownToBeOpaqueInRect(
const LayoutRect& local_rect) const override;
// Returns the viewport size in (CSS pixels) that vh and vw units are
// calculated from.
FloatSize ViewportSizeForViewportUnits() const;
void PushLayoutState(LayoutState& layout_state) {
layout_state_ = &layout_state;
void PopLayoutState() {
layout_state_ = layout_state_->Next();
LayoutRect LocalVisualRectIgnoringVisibility() const override;
// Invalidates paint for the entire view, including composited descendants,
// but not including child frames.
// It is very likely you do not want to call this method.
void SetShouldDoFullPaintInvalidationForViewAndAllDescendants();
bool ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const override;
LayoutRect DebugRect() const override;
// Returns the coordinates of find-in-page scrollbar tickmarks. These come
// from DocumentMarkerController, unless overridden by SetTickmarks.
Vector<IntRect> GetTickmarks() const;
// Sets the coordinates of find-in-page scrollbar tickmarks, bypassing
// DocumentMarkerController. This is used by the PDF plugin.
void OverrideTickmarks(const Vector<IntRect>&);
// Issues a paint invalidation on the layout viewport's vertical scrollbar
// (which is responsible for painting the tickmarks).
void InvalidatePaintForTickmarks();
bool RecalcOverflow() override;
// The visible background area, in the local coordinates. The view background
// will be painted in this rect. It's also the positioning area of fixed-
// attachment backgrounds.
LayoutRect BackgroundRect() const { return OverflowClipRect(LayoutPoint()); }
// The previous BackgroundRect after the previous paint invalidation.
LayoutRect PreviousBackgroundRect() const {
return previous_background_rect_;
void SetPreviousBackgroundRect(const LayoutRect& r) const {
previous_background_rect_ = r;
void MapLocalToAncestor(
const LayoutBoxModelObject* ancestor,
MapCoordinatesFlags = kApplyContainerFlip) const override;
const LayoutObject* PushMappingToContainer(
const LayoutBoxModelObject* ancestor_to_stop_at,
LayoutGeometryMap&) const override;
void MapAncestorToLocal(const LayoutBoxModelObject*,
MapCoordinatesFlags) const override;
void ComputeSelfHitTestRects(Vector<LayoutRect>&,
const LayoutPoint& layer_offset) const override;
bool CanHaveChildren() const override;
void UpdateBlockLayout(bool relayout_children) override;
void CheckLayoutState();
void UpdateFromStyle() override;
bool ShouldUsePrintingLayout() const;
int ViewLogicalWidthForBoxSizing() const {
return ViewLogicalWidth(kIncludeScrollbars);
int ViewLogicalHeightForBoxSizing() const {
return ViewLogicalHeight(kIncludeScrollbars);
bool UpdateLogicalWidthAndColumnWidth() override;
UntracedMember<LocalFrameView> frame_view_;
// The page logical height.
// This is only used during printing to split the content into pages.
// Outside of printing, this is 0.
LayoutUnit page_logical_height_;
// LayoutState is an optimization used during layout.
// |m_layoutState| will be nullptr outside of layout.
// See the class comment for more details.
LayoutState* layout_state_;
std::unique_ptr<ViewFragmentationContext> fragmentation_context_;
std::unique_ptr<PaintLayerCompositor> compositor_;
scoped_refptr<IntervalArena> interval_arena_;
LayoutQuote* layout_quote_head_;
unsigned layout_counter_count_;
bool needs_counter_update_ = false;
unsigned hit_test_count_;
unsigned hit_test_cache_hits_;
Persistent<HitTestCache> hit_test_cache_;
// FrameViewAutoSizeInfo controls scrollbar appearance manually rather than
// relying on layout. These members are used to override the ScrollbarModes
// calculated from style. kScrollbarAuto disables the override.
ScrollbarMode autosize_h_scrollbar_mode_;
ScrollbarMode autosize_v_scrollbar_mode_;
Vector<IntRect> tickmarks_override_;
mutable LayoutRect previous_background_rect_;
} // namespace blink