blob: 8d06cf0e1d41089036c65a6052c4d2dc68b00c58 [file] [log] [blame]
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* 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.
*
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_VIEW_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_VIEW_H_
#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"
#include "third_party/blink/renderer/platform/pod_free_list_arena.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).
// http://www.w3.org/TR/CSS2/visudet.html#containing-block-details
//
// 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
// https://www.chromium.org/developers/design-documents/blink-coordinate-spaces
// 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 {
public:
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,
HitTestResult&);
// 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,
LayoutRect&,
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,
TransformState&,
MapCoordinatesFlags,
VisualRectFlags) const;
bool MapToVisualRectInAncestorSpaceInternal(
const LayoutBoxModelObject* ancestor,
TransformState&,
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 DispatchFakeMouseMoveEventSoon(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() {
layout_counter_count_++;
SetNeedsCounterUpdate();
}
void RemoveLayoutCounter() {
DCHECK_GT(layout_counter_count_, 0u);
layout_counter_count_--;
}
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() {
DCHECK(layout_state_);
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();
void SetShouldDoFullPaintInvalidationOnResizeIfNeeded(bool width_changed,
bool height_changed);
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 RecalcOverflowAfterStyleChange() override;
private:
void MapLocalToAncestor(
const LayoutBoxModelObject* ancestor,
TransformState&,
MapCoordinatesFlags = kApplyContainerFlip) const override;
const LayoutObject* PushMappingToContainer(
const LayoutBoxModelObject* ancestor_to_stop_at,
LayoutGeometryMap&) const override;
void MapAncestorToLocal(const LayoutBoxModelObject*,
TransformState&,
MapCoordinatesFlags) const override;
void ComputeSelfHitTestRects(Vector<LayoutRect>&,
const LayoutPoint& layer_offset) const override;
bool CanHaveChildren() const override;
void UpdateBlockLayout(bool relayout_children) override;
#if DCHECK_IS_ON()
void CheckLayoutState();
#endif
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_;
};
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutView, IsLayoutView());
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_VIEW_H_