[ContentChangeObserver] Content observation should be limited to the current document.
[WebKit-https.git] / Source / WebCore / rendering / RenderFlexibleBox.h
index 624ef16..df67496 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef RenderFlexibleBox_h
-#define RenderFlexibleBox_h
+#pragma once
 
+#include "OrderIterator.h"
 #include "RenderBlock.h"
-#include <wtf/OwnPtr.h>
 
 namespace WebCore {
 
+class FlexItem;
+    
 class RenderFlexibleBox : public RenderBlock {
+    WTF_MAKE_ISO_ALLOCATED(RenderFlexibleBox);
 public:
-    RenderFlexibleBox(Node*);
+    RenderFlexibleBox(Element&, RenderStyle&&);
+    RenderFlexibleBox(Document&, RenderStyle&&);
     virtual ~RenderFlexibleBox();
 
-    virtual const char* renderName() const OVERRIDE;
+    bool isFlexibleBox() const override { return true; }
 
-    virtual bool isFlexibleBox() const OVERRIDE { return true; }
-    virtual bool avoidsFloats() const OVERRIDE { return true; }
-    virtual void computePreferredLogicalWidths() OVERRIDE;
-    virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
+    const char* renderName() const override;
 
-    virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) OVERRIDE;
+    bool avoidsFloats() const final { return true; }
+    bool canDropAnonymousBlockChild() const final { return false; }
+    void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0_lu) final;
+
+    int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
+    Optional<int> firstLineBaseline() const override;
+    Optional<int> inlineBlockBaseline(LineDirectionMode) const override;
+
+    void styleDidChange(StyleDifference, const RenderStyle*) override;
+    void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) override;
 
     bool isHorizontalFlow() const;
 
+    const OrderIterator& orderIterator() const { return m_orderIterator; }
+
+    bool isTopLayoutOverflowAllowed() const override;
+    bool isLeftLayoutOverflowAllowed() const override;
+
+    virtual bool isFlexibleBoxImpl() const { return false; };
+    
+    Optional<LayoutUnit> crossSizeForPercentageResolution(const RenderBox&);
+    Optional<LayoutUnit> mainSizeForPercentageResolution(const RenderBox&);
+    Optional<LayoutUnit> childLogicalHeightForPercentageResolution(const RenderBox&);
+    
+    void clearCachedMainSizeForChild(const RenderBox& child);
+    
+    LayoutUnit cachedChildIntrinsicContentLogicalHeight(const RenderBox& child) const;
+    void setCachedChildIntrinsicContentLogicalHeight(const RenderBox& child, LayoutUnit);
+    void clearCachedChildIntrinsicContentLogicalHeight(const RenderBox& child);
+
+    LayoutUnit staticMainAxisPositionForPositionedChild(const RenderBox&);
+    LayoutUnit staticCrossAxisPositionForPositionedChild(const RenderBox&);
+    
+    LayoutUnit staticInlinePositionForPositionedChild(const RenderBox&);
+    LayoutUnit staticBlockPositionForPositionedChild(const RenderBox&);
+    
+    // Returns true if the position changed. In that case, the child will have to
+    // be laid out again.
+    bool setStaticPositionForPositionedLayout(const RenderBox&);
+
+protected:
+    void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
+    void computePreferredLogicalWidths() override;
+
 private:
     enum FlexSign {
         PositiveFlexibility,
         NegativeFlexibility,
     };
-
-    enum PositionedLayoutMode {
-        FlipForRowReverse,
-        NoFlipForRowReverse,
-    };
-
-    struct OrderHashTraits;
-    typedef HashSet<int, DefaultHash<int>::Hash, OrderHashTraits> OrderHashSet;
-
-    class OrderIterator;
-    typedef WTF::HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize;
-    typedef WTF::Vector<RenderBox*> OrderedFlexItemList;
+    
+    enum ChildLayoutType { LayoutIfNeeded, ForceLayout, NeverLayout };
+    
+    enum class SizeDefiniteness { Definite, Indefinite, Unknown };
+    
+    // Use an inline capacity of 8, since flexbox containers usually have less than 8 children.
+    typedef Vector<LayoutRect, 8> ChildFrameRects;
 
     struct LineContext;
-    struct Violation;
-
-    bool hasOrthogonalFlow(RenderBox* child) const;
+    
+    bool hasOrthogonalFlow(const RenderBox& child) const;
     bool isColumnFlow() const;
     bool isLeftToRightFlow() const;
     bool isMultiline() const;
-    Length flexBasisForChild(RenderBox* child) const;
-    void setCrossAxisExtent(LayoutUnit);
-    LayoutUnit crossAxisExtentForChild(RenderBox* child);
-    LayoutUnit mainAxisExtentForChild(RenderBox* child);
+    Length flexBasisForChild(const RenderBox& child) const;
+    LayoutUnit crossAxisExtentForChild(const RenderBox& child) const;
+    LayoutUnit crossAxisIntrinsicExtentForChild(const RenderBox& child) const;
+    LayoutUnit childIntrinsicLogicalHeight(const RenderBox& child) const;
+    LayoutUnit childIntrinsicLogicalWidth(const RenderBox& child) const;
+    LayoutUnit mainAxisExtentForChild(const RenderBox& child) const;
+    LayoutUnit mainAxisContentExtentForChildIncludingScrollbar(const RenderBox& child) const;
     LayoutUnit crossAxisExtent() const;
     LayoutUnit mainAxisExtent() const;
     LayoutUnit crossAxisContentExtent() const;
-    LayoutUnit mainAxisContentExtent();
-    LayoutUnit computeLogicalClientHeight(SizeType, const Length& height);
+    LayoutUnit mainAxisContentExtent(LayoutUnit contentLogicalHeight);
+    Optional<LayoutUnit> computeMainAxisExtentForChild(const RenderBox& child, SizeType, const Length& size);
     WritingMode transformedWritingMode() const;
     LayoutUnit flowAwareBorderStart() const;
     LayoutUnit flowAwareBorderEnd() const;
@@ -95,52 +132,85 @@ private:
     LayoutUnit flowAwarePaddingEnd() const;
     LayoutUnit flowAwarePaddingBefore() const;
     LayoutUnit flowAwarePaddingAfter() const;
-    LayoutUnit flowAwareMarginStartForChild(RenderBox* child) const;
-    LayoutUnit flowAwareMarginEndForChild(RenderBox* child) const;
-    LayoutUnit flowAwareMarginBeforeForChild(RenderBox* child) const;
-    LayoutUnit flowAwareMarginAfterForChild(RenderBox* child) const;
-    LayoutUnit crossAxisMarginExtentForChild(RenderBox* child) const;
+    LayoutUnit flowAwareMarginStartForChild(const RenderBox& child) const;
+    LayoutUnit flowAwareMarginEndForChild(const RenderBox& child) const;
+    LayoutUnit flowAwareMarginBeforeForChild(const RenderBox& child) const;
+    LayoutUnit crossAxisMarginExtentForChild(const RenderBox& child) const;
     LayoutUnit crossAxisScrollbarExtent() const;
-    LayoutPoint flowAwareLocationForChild(RenderBox* child) const;
-    // FIXME: Supporting layout deltas.
-    void setFlowAwareLocationForChild(RenderBox* child, const LayoutPoint&);
-    void adjustAlignmentForChild(RenderBox* child, LayoutUnit);
-    LayoutUnit mainAxisBorderAndPaddingExtentForChild(RenderBox* child) const;
-    LayoutUnit mainAxisScrollbarExtentForChild(RenderBox* child) const;
-    LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child);
-
-    void layoutFlexItems(OrderIterator&, WTF::Vector<LineContext>&);
-    LayoutUnit autoMarginOffsetInMainAxis(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace);
-    void updateAutoMarginsInMainAxis(RenderBox* child, LayoutUnit autoMarginOffset);
-    bool hasAutoMarginsInCrossAxis(RenderBox* child);
-    bool updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUnit availableAlignmentSpace);
-    void repositionLogicalHeightDependentFlexItems(OrderIterator&, WTF::Vector<LineContext>&, LayoutUnit& oldClientAfterEdge);
-
-    LayoutUnit availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox*);
-    LayoutUnit marginBoxAscentForChild(RenderBox*);
-
-    void computeMainAxisPreferredSizes(bool relayoutChildren, OrderHashSet&);
-    LayoutUnit lineBreakLength();
-    LayoutUnit adjustChildSizeForMinAndMax(RenderBox*, LayoutUnit childSize, LayoutUnit flexboxAvailableContentExtent);
-    bool computeNextFlexLine(OrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalFlexGrow, float& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent);
-    LayoutUnit computeAvailableFreeSpace(LayoutUnit preferredMainAxisExtent);
-
-    bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
-    void freezeViolations(const WTF::Vector<Violation>&, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize&);
-
-    void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
-    void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode);
-    void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>&);
-    void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
-    void alignFlexLines(OrderIterator&, WTF::Vector<LineContext>&);
-    void alignChildren(OrderIterator&, const WTF::Vector<LineContext>&);
-    void applyStretchAlignmentToChild(RenderBox*, LayoutUnit lineCrossAxisExtent);
-    void flipForRightToLeftColumn(OrderIterator&);
-    void flipForWrapReverse(OrderIterator&, const WTF::Vector<LineContext>&, LayoutUnit crossAxisStartEdge);
-
-    OwnPtr<OrderIterator> m_orderIterator;
+    LayoutUnit crossAxisScrollbarExtentForChild(const RenderBox& child) const;
+    LayoutPoint flowAwareLocationForChild(const RenderBox& child) const;
+    bool useChildAspectRatio(const RenderBox& child) const;
+    LayoutUnit computeMainSizeFromAspectRatioUsing(const RenderBox& child, Length crossSizeLength) const;
+    void setFlowAwareLocationForChild(RenderBox& child, const LayoutPoint&);
+    LayoutUnit computeInnerFlexBaseSizeForChild(RenderBox& child, LayoutUnit mainAxisBorderAndPadding, bool relayoutChildren);
+    void adjustAlignmentForChild(RenderBox& child, LayoutUnit);
+    ItemPosition alignmentForChild(const RenderBox& child) const;
+    bool mainAxisLengthIsDefinite(const RenderBox& child, const Length& flexBasis) const;
+    bool crossAxisLengthIsDefinite(const RenderBox& child, const Length& flexBasis) const;
+    bool needToStretchChildLogicalHeight(const RenderBox& child) const;
+    bool childHasIntrinsicMainAxisSize(const RenderBox& child) const;
+    Overflow mainAxisOverflowForChild(const RenderBox& child) const;
+    Overflow crossAxisOverflowForChild(const RenderBox& child) const;
+    void cacheChildMainSize(const RenderBox& child);
+    
+    void layoutFlexItems(bool relayoutChildren);
+    LayoutUnit autoMarginOffsetInMainAxis(const Vector<FlexItem>&, LayoutUnit& availableFreeSpace);
+    void updateAutoMarginsInMainAxis(RenderBox& child, LayoutUnit autoMarginOffset);
+    bool hasAutoMarginsInCrossAxis(const RenderBox& child) const;
+    bool updateAutoMarginsInCrossAxis(RenderBox& child, LayoutUnit availableAlignmentSpace);
+    void repositionLogicalHeightDependentFlexItems(Vector<LineContext>&);
+    LayoutUnit clientLogicalBottomAfterRepositioning();
+    
+    LayoutUnit availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, const RenderBox& child);
+    LayoutUnit marginBoxAscentForChild(const RenderBox& child);
+    
+    LayoutUnit computeChildMarginValue(Length margin);
+    void prepareOrderIteratorAndMargins();
+    LayoutUnit adjustChildSizeForMinAndMax(const RenderBox& child, LayoutUnit childSize);
+    LayoutUnit adjustChildSizeForAspectRatioCrossAxisMinAndMax(const RenderBox& child, LayoutUnit childSize);
+    FlexItem constructFlexItem(RenderBox&, bool relayoutChildren);
+    
+    void freezeInflexibleItems(FlexSign, Vector<FlexItem>& children, LayoutUnit& remainingFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink);
+    bool resolveFlexibleLengths(FlexSign, Vector<FlexItem>&, LayoutUnit initialFreeSpace, LayoutUnit& remainingFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink);
+    void freezeViolations(Vector<FlexItem*>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink);
+    
+    void resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox& child);
+    void setOverrideMainAxisContentSizeForChild(RenderBox& child, LayoutUnit childPreferredSize);
+    void prepareChildForPositionedLayout(RenderBox& child);
+    void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, Vector<FlexItem>&, LayoutUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>&);
+    void layoutColumnReverse(const Vector<FlexItem>&, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
+    void alignFlexLines(Vector<LineContext>&);
+    void alignChildren(const Vector<LineContext>&);
+    void applyStretchAlignmentToChild(RenderBox& child, LayoutUnit lineCrossAxisExtent);
+    void flipForRightToLeftColumn(const Vector<LineContext>& lineContexts);
+    void flipForWrapReverse(const Vector<LineContext>&, LayoutUnit crossAxisStartEdge);
+    
+    void appendChildFrameRects(ChildFrameRects&);
+    void repaintChildrenDuringLayoutIfMoved(const ChildFrameRects&);
+
+    // This is used to cache the preferred size for orthogonal flow children so we
+    // don't have to relayout to get it
+    HashMap<const RenderBox*, LayoutUnit> m_intrinsicSizeAlongMainAxis;
+    
+    // This is used to cache the intrinsic size on the cross axis to avoid
+    // relayouts when stretching.
+    HashMap<const RenderBox*, LayoutUnit> m_intrinsicContentLogicalHeights;
+
+    // This set is used to keep track of which children we laid out in this
+    // current layout iteration. We need it because the ones in this set may
+    // need an additional layout pass for correct stretch alignment handling, as
+    // the first layout likely did not use the correct value for percentage
+    // sizing of children.
+    HashSet<const RenderBox*> m_relaidOutChildren;
+    
+    mutable OrderIterator m_orderIterator { *this };
+    int m_numberOfInFlowChildrenOnFirstLine { -1 };
+    
+    // This is SizeIsUnknown outside of layoutBlock()
+    mutable SizeDefiniteness m_hasDefiniteHeight { SizeDefiniteness::Unknown };
+    bool m_inLayout { false };
 };
 
 } // namespace WebCore
 
-#endif // RenderFlexibleBox_h
+SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderFlexibleBox, isFlexibleBox())