[ContentChangeObserver] Content observation should be limited to the current document.
[WebKit-https.git] / Source / WebCore / rendering / RenderFlexibleBox.h
index 65b9e00..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"
 
 namespace WebCore {
 
+class FlexItem;
+    
 class RenderFlexibleBox : public RenderBlock {
+    WTF_MAKE_ISO_ALLOCATED(RenderFlexibleBox);
 public:
-    RenderFlexibleBox(ContainerNode*);
+    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 bool canCollapseAnonymousBlockChild() const OVERRIDE { return false; }
-    virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
+    const char* renderName() const override;
 
-    virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
-    virtual int firstLineBoxBaseline() const OVERRIDE;
-    virtual int inlineBlockBaseline(LineDirectionMode) const OVERRIDE;
+    bool avoidsFloats() const final { return true; }
+    bool canDropAnonymousBlockChild() const final { return false; }
+    void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0_lu) final;
 
-    virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) OVERRIDE;
+    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:
-    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
-    virtual void computePreferredLogicalWidths() OVERRIDE;
+    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 {
-        WTF_MAKE_NONCOPYABLE(OrderIterator);
-    public:
-        OrderIterator(const RenderFlexibleBox*);
-        void setOrderValues(const OrderHashSet&);
-        RenderBox* currentChild() const { return m_currentChild; }
-        RenderBox* first();
-        RenderBox* next();
-        void reset();
-
-    private:
-        const RenderFlexibleBox* m_flexibleBox;
-        RenderBox* m_currentChild;
-        Vector<int> m_orderValues;
-        Vector<int>::const_iterator m_orderValuesIterator;
-    };
-
-    typedef HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize;
-    typedef Vector<RenderBox*> OrderedFlexItemList;
-
-    struct LineContext;
-    struct Violation;
-
+    
+    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;
 
-    bool hasOrthogonalFlow(RenderBox* child) const;
+    struct LineContext;
+    
+    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) const;
-    LayoutUnit mainAxisExtentForChild(RenderBox* child) const;
+    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 contentLogicalHeight);
-    LayoutUnit computeMainAxisExtentForChild(RenderBox* child, SizeType, const Length& size);
+    Optional<LayoutUnit> computeMainAxisExtentForChild(const RenderBox& child, SizeType, const Length& size);
     WritingMode transformedWritingMode() const;
     LayoutUnit flowAwareBorderStart() const;
     LayoutUnit flowAwareBorderEnd() const;
@@ -121,58 +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);
-    EAlignItems alignmentForChild(RenderBox* child) const;
-    LayoutUnit mainAxisBorderAndPaddingExtentForChild(RenderBox* child) const;
-    LayoutUnit mainAxisScrollbarExtentForChild(RenderBox* child) const;
-    LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child);
-
-    void layoutFlexItems(bool relayoutChildren, Vector<LineContext>&);
-    LayoutUnit autoMarginOffsetInMainAxis(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace);
-    void updateAutoMarginsInMainAxis(RenderBox* child, LayoutUnit autoMarginOffset);
-    bool hasAutoMarginsInCrossAxis(RenderBox* child) const;
-    bool updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUnit availableAlignmentSpace);
-    void repositionLogicalHeightDependentFlexItems(Vector<LineContext>&, LayoutUnit& oldClientAfterEdge);
-    void appendChildFrameRects(ChildFrameRects&);
-    void repaintChildrenDuringLayoutIfMoved(const ChildFrameRects&);
-
-    LayoutUnit availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox*);
-    LayoutUnit marginBoxAscentForChild(RenderBox*);
-
-    LayoutUnit computeChildMarginValue(Length margin, RenderView*);
-    void computeMainAxisPreferredSizes(OrderHashSet&);
-    LayoutUnit adjustChildSizeForMinAndMax(RenderBox*, LayoutUnit childSize);
-    bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent);
-
-    bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit>& childSizes);
-    void freezeViolations(const Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&);
-
-    void resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox*);
-    bool needToStretchChild(RenderBox*);
-    void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
-    void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode);
-    size_t numberOfInFlowPositionedChildren(const OrderedFlexItemList&) const;
-    void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>&);
-    void layoutColumnReverse(const OrderedFlexItemList&, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
+    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*, LayoutUnit lineCrossAxisExtent);
-    void flipForRightToLeftColumn();
+    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&);
 
-    mutable OrderIterator m_orderIterator;
-    int m_numberOfInFlowChildrenOnFirstLine;
+    // 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())