[CSS Grid Layout] Upgrade align-self and align-items parsing to CSS 3
[WebKit-https.git] / Source / WebCore / rendering / RenderFullScreen.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. 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  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  * 
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #if ENABLE(FULLSCREEN_API)
28
29 #include "RenderFullScreen.h"
30
31 #include "RenderBlockFlow.h"
32 #include "RenderLayer.h"
33 #include "RenderLayerCompositor.h"
34
35 namespace WebCore {
36
37 class RenderFullScreenPlaceholder final : public RenderBlockFlow {
38 public:
39     RenderFullScreenPlaceholder(RenderFullScreen& owner, PassRef<RenderStyle> style)
40         : RenderBlockFlow(owner.document(), WTF::move(style))
41         , m_owner(owner) 
42     {
43     }
44
45 private:
46     virtual bool isRenderFullScreenPlaceholder() const { return true; }
47     virtual void willBeDestroyed();
48     RenderFullScreen& m_owner;
49 };
50
51 void RenderFullScreenPlaceholder::willBeDestroyed()
52 {
53     m_owner.setPlaceholder(0);
54     RenderBlockFlow::willBeDestroyed();
55 }
56
57 RenderFullScreen::RenderFullScreen(Document& document, PassRef<RenderStyle> style)
58     : RenderFlexibleBox(document, WTF::move(style))
59     , m_placeholder(0)
60 {
61     setReplaced(false); 
62 }
63
64 void RenderFullScreen::willBeDestroyed()
65 {
66     if (m_placeholder) {
67         removeFromParent();
68         if (!m_placeholder->beingDestroyed())
69             m_placeholder->destroy();
70         ASSERT(!m_placeholder);
71     }
72
73     // RenderObjects are unretained, so notify the document (which holds a pointer to a RenderFullScreen)
74     // if it's RenderFullScreen is destroyed.
75     if (document().fullScreenRenderer() == this)
76         document().fullScreenRendererDestroyed();
77
78     RenderFlexibleBox::willBeDestroyed();
79 }
80
81 static PassRef<RenderStyle> createFullScreenStyle()
82 {
83     auto fullscreenStyle = RenderStyle::createDefaultStyle();
84
85     // Create a stacking context:
86     fullscreenStyle.get().setZIndex(INT_MAX);
87
88     fullscreenStyle.get().setFontDescription(FontDescription());
89     fullscreenStyle.get().font().update(0);
90
91     fullscreenStyle.get().setDisplay(FLEX);
92     fullscreenStyle.get().setJustifyContent(JustifyCenter);
93     fullscreenStyle.get().setAlignItems(ItemPositionCenter);
94     fullscreenStyle.get().setFlexDirection(FlowColumn);
95     
96     fullscreenStyle.get().setPosition(FixedPosition);
97     fullscreenStyle.get().setWidth(Length(100.0, Percent));
98     fullscreenStyle.get().setHeight(Length(100.0, Percent));
99     fullscreenStyle.get().setLeft(Length(0, WebCore::Fixed));
100     fullscreenStyle.get().setTop(Length(0, WebCore::Fixed));
101     
102     fullscreenStyle.get().setBackgroundColor(Color::black);
103
104     return fullscreenStyle;
105 }
106
107 RenderFullScreen* RenderFullScreen::wrapRenderer(RenderObject* object, RenderElement* parent, Document& document)
108 {
109     RenderFullScreen* fullscreenRenderer = new RenderFullScreen(document, createFullScreenStyle());
110     fullscreenRenderer->initializeStyle();
111     if (parent && !parent->isChildAllowed(*fullscreenRenderer, fullscreenRenderer->style())) {
112         fullscreenRenderer->destroy();
113         return 0;
114     }
115     if (object) {
116         // |object->parent()| can be null if the object is not yet attached
117         // to |parent|.
118         if (RenderElement* parent = object->parent()) {
119             RenderBlock* containingBlock = object->containingBlock();
120             ASSERT(containingBlock);
121             // Since we are moving the |object| to a new parent |fullscreenRenderer|,
122             // the line box tree underneath our |containingBlock| is not longer valid.
123             containingBlock->deleteLines();
124
125             parent->addChild(fullscreenRenderer, object);
126             object->removeFromParent();
127             
128             // Always just do a full layout to ensure that line boxes get deleted properly.
129             // Because objects moved from |parent| to |fullscreenRenderer|, we want to
130             // make new line boxes instead of leaving the old ones around.
131             parent->setNeedsLayoutAndPrefWidthsRecalc();
132             containingBlock->setNeedsLayoutAndPrefWidthsRecalc();
133         }
134         fullscreenRenderer->addChild(object);
135         fullscreenRenderer->setNeedsLayoutAndPrefWidthsRecalc();
136     }
137     document.setFullScreenRenderer(fullscreenRenderer);
138     return fullscreenRenderer;
139 }
140
141 void RenderFullScreen::unwrapRenderer(bool& requiresRenderTreeRebuild)
142 {
143     requiresRenderTreeRebuild = false;
144     if (parent()) {
145         auto* child = firstChild();
146         // Things can get very complicated with anonymous block generation.
147         // We can restore correctly without rebuild in simple cases only.
148         // FIXME: We should have a mechanism for removing a block without reconstructing the tree.
149         if (child != lastChild())
150             requiresRenderTreeRebuild = true;
151         else if (child && child->isAnonymousBlock()) {
152             auto& anonymousBlock = downcast<RenderBlock>(*child);
153             if (anonymousBlock.firstChild() != anonymousBlock.lastChild())
154                 requiresRenderTreeRebuild = true;
155         }
156
157         while ((child = firstChild())) {
158             if (child->isAnonymousBlock() && !requiresRenderTreeRebuild) {
159                 if (auto* nonAnonymousChild = downcast<RenderBlock>(*child).firstChild())
160                     child = nonAnonymousChild;
161                 else {
162                     child->removeFromParent();
163                     child->destroy();
164                     continue;
165                 }
166             }
167             // We have to clear the override size, because as a flexbox, we
168             // may have set one on the child, and we don't want to leave that
169             // lying around on the child.
170             if (is<RenderBox>(*child))
171                 downcast<RenderBox>(*child).clearOverrideSize();
172             child->removeFromParent();
173             parent()->addChild(child, this);
174             parent()->setNeedsLayoutAndPrefWidthsRecalc();
175         }
176     }
177     if (placeholder())
178         placeholder()->removeFromParent();
179     removeFromParent();
180     document().setFullScreenRenderer(0);
181 }
182
183 void RenderFullScreen::setPlaceholder(RenderBlock* placeholder)
184 {
185     m_placeholder = placeholder;
186 }
187
188 void RenderFullScreen::createPlaceholder(PassRef<RenderStyle> style, const LayoutRect& frameRect)
189 {
190     if (style.get().width().isAuto())
191         style.get().setWidth(Length(frameRect.width(), Fixed));
192     if (style.get().height().isAuto())
193         style.get().setHeight(Length(frameRect.height(), Fixed));
194
195     if (m_placeholder) {
196         m_placeholder->setStyle(WTF::move(style));
197         return;
198     }
199
200     m_placeholder = new RenderFullScreenPlaceholder(*this, WTF::move(style));
201     m_placeholder->initializeStyle();
202     if (parent()) {
203         parent()->addChild(m_placeholder, this);
204         parent()->setNeedsLayoutAndPrefWidthsRecalc();
205     }
206 }
207
208 }
209
210 #endif