1/*
2 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above
9 *    copyright notice, this list of conditions and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 *    copyright notice, this list of conditions and the following
13 *    disclaimer in the documentation and/or other materials
14 *    provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#ifndef RenderNamedFlowFragment_h
31#define RenderNamedFlowFragment_h
32
33#include "RenderRegion.h"
34
35namespace WebCore {
36
37class Element;
38class RenderStyle;
39
40// RenderNamedFlowFragment represents a region that is responsible for the fragmentation of
41// the RenderNamedFlowThread content.
42//
43// A RenderNamedFlowFragment object is created as an anonymous child for a RenderBlockFlow object
44// that has a valid -webkit-flow-from property.
45//
46// This allows a non-replaced block to behave like a region if needed, following the CSSRegions specification:
47// http://dev.w3.org/csswg/css-regions/#the-flow-from-property.
48// list-item, table-caption, table-cell can become regions in addition to block | inline-block.
49
50class RenderNamedFlowFragment final : public RenderRegion {
51public:
52    RenderNamedFlowFragment(Document&, PassRef<RenderStyle>);
53    virtual ~RenderNamedFlowFragment();
54
55    static PassRef<RenderStyle> createStyle(const RenderStyle& parentStyle);
56
57    virtual bool isRenderNamedFlowFragment() const override final { return true; }
58    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
59
60    void getRanges(Vector<RefPtr<Range>>&) const;
61
62    virtual LayoutUnit pageLogicalHeight() const;
63    LayoutUnit maxPageLogicalHeight() const;
64
65    LayoutRect flowThreadPortionRectForClipping(bool isFirstRegionInRange, bool isLastRegionInRange) const;
66
67    RenderBlockFlow& fragmentContainer() const;
68    RenderLayer& fragmentContainerLayer() const;
69
70    virtual bool shouldClipFlowThreadContent() const override;
71
72    virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const override;
73
74    bool isPseudoElementRegion() const { return parent() && parent()->isPseudoElement(); }
75
76    // When the content inside the region requires the region to have a layer, the layer will be created on the region's
77    // parent renderer instead.
78    // This method returns that renderer holding the layer.
79    // The return value cannot be null because CSS Regions create Stacking Contexts (which means they create layers).
80    RenderLayerModelObject& layerOwner() const { return *toRenderLayerModelObject(parent()); }
81
82    bool hasCustomRegionStyle() const { return m_hasCustomRegionStyle; }
83    void clearObjectStyleInRegion(const RenderObject*);
84
85    void setRegionObjectsRegionStyle();
86    void restoreRegionObjectsOriginalStyle();
87
88    virtual LayoutRect visualOverflowRect() const override;
89
90    RenderNamedFlowThread* namedFlowThread() const;
91
92    virtual bool hasAutoLogicalHeight() const override { return m_hasAutoLogicalHeight; }
93
94    LayoutUnit computedAutoHeight() const { return m_computedAutoHeight; }
95
96    void setComputedAutoHeight(LayoutUnit computedAutoHeight)
97    {
98        m_hasComputedAutoHeight = true;
99        m_computedAutoHeight = computedAutoHeight;
100    }
101
102    void clearComputedAutoHeight()
103    {
104        m_hasComputedAutoHeight = false;
105        m_computedAutoHeight = 0;
106    }
107
108    bool hasComputedAutoHeight() const { return m_hasComputedAutoHeight; }
109
110    RegionOversetState regionOversetState() const;
111
112    virtual void attachRegion() override;
113    virtual void detachRegion() override;
114
115    virtual void updateLogicalHeight() override;
116
117    void updateRegionFlags();
118
119    virtual void absoluteQuadsForBoxInRegion(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) override;
120
121    void invalidateRegionIfNeeded();
122
123private:
124    virtual const char* renderName() const override { return "RenderNamedFlowFragment"; }
125
126    PassRefPtr<RenderStyle> computeStyleInRegion(RenderElement&, RenderStyle& parentStyle);
127    void computeChildrenStyleInRegion(RenderElement&);
128    void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached);
129
130    void checkRegionStyle();
131    void setHasCustomRegionStyle(bool hasCustomRegionStyle) { m_hasCustomRegionStyle = hasCustomRegionStyle; }
132
133    void updateRegionHasAutoLogicalHeightFlag();
134
135    void incrementAutoLogicalHeightCount();
136    void decrementAutoLogicalHeightCount();
137
138    bool shouldHaveAutoLogicalHeight() const;
139
140    void updateOversetState();
141    void setRegionOversetState(RegionOversetState);
142
143    virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
144
145    struct ObjectRegionStyleInfo {
146        // Used to store the original style of the object in region
147        // so that the original style is properly restored after paint.
148        // Also used to store computed style of the object in region between
149        // region paintings, so that the style in region is computed only
150        // when necessary.
151        RefPtr<RenderStyle> style;
152        // True if the computed style in region is cached.
153        bool cached;
154    };
155
156    typedef HashMap<const RenderObject*, ObjectRegionStyleInfo > RenderObjectRegionStyleMap;
157    RenderObjectRegionStyleMap m_renderObjectRegionStyle;
158
159    bool m_hasCustomRegionStyle : 1;
160    bool m_hasAutoLogicalHeight : 1;
161    bool m_hasComputedAutoHeight : 1;
162
163    LayoutUnit m_computedAutoHeight;
164};
165
166RENDER_OBJECT_TYPE_CASTS(RenderNamedFlowFragment, isRenderNamedFlowFragment())
167
168} // namespace WebCore
169
170#endif // RenderNamedFlowFragment_h
171