OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 #include "web/FullscreenController.h" | 31 #include "web/FullscreenController.h" |
32 | 32 |
33 #include "core/dom/Document.h" | 33 #include "core/dom/Document.h" |
34 #include "core/dom/Fullscreen.h" | 34 #include "core/dom/Fullscreen.h" |
35 #include "core/frame/FrameView.h" | 35 #include "core/frame/FrameView.h" |
36 #include "core/frame/LocalFrame.h" | 36 #include "core/frame/LocalFrame.h" |
37 #include "core/frame/PageScaleConstraintsSet.h" | 37 #include "core/frame/PageScaleConstraintsSet.h" |
38 #include "core/html/HTMLMediaElement.h" | 38 #include "core/html/HTMLMediaElement.h" |
39 #include "core/html/HTMLVideoElement.h" | 39 #include "core/html/HTMLVideoElement.h" |
40 #include "core/layout/LayoutFullScreen.h" | |
41 #include "platform/RuntimeEnabledFeatures.h" | |
42 #include "public/platform/WebLayerTreeView.h" | 40 #include "public/platform/WebLayerTreeView.h" |
43 #include "public/web/WebFrameClient.h" | 41 #include "public/web/WebFrameClient.h" |
44 #include "web/WebLocalFrameImpl.h" | 42 #include "web/WebLocalFrameImpl.h" |
45 #include "web/WebSettingsImpl.h" | 43 #include "web/WebSettingsImpl.h" |
46 #include "web/WebViewImpl.h" | 44 #include "web/WebViewImpl.h" |
47 | 45 |
48 namespace blink { | 46 namespace blink { |
49 | 47 |
50 FullscreenController* FullscreenController::create(WebViewImpl* webViewImpl) { | 48 FullscreenController* FullscreenController::create(WebViewImpl* webViewImpl) { |
51 return new FullscreenController(webViewImpl); | 49 return new FullscreenController(webViewImpl); |
52 } | 50 } |
53 | 51 |
54 FullscreenController::FullscreenController(WebViewImpl* webViewImpl) | 52 FullscreenController::FullscreenController(WebViewImpl* webViewImpl) |
55 : m_webViewImpl(webViewImpl), | 53 : m_webViewImpl(webViewImpl), |
56 m_haveEnteredFullscreen(false), | 54 m_haveEnteredFullscreen(false), |
57 m_exitFullscreenPageScaleFactor(0), | 55 m_exitFullscreenPageScaleFactor(0), |
58 m_needsScrollAndScaleRestore(false), | 56 m_needsScrollAndScaleRestore(false), |
59 m_isCancelingFullscreen(false) {} | 57 m_isCancelingFullscreen(false) {} |
60 | 58 |
61 void FullscreenController::didEnterFullscreen() { | 59 void FullscreenController::didEnterFullscreen() { |
62 if (!m_provisionalFullscreenElement) | 60 if (m_pendingFullscreenElements.isEmpty()) |
63 return; | |
64 | |
65 Element* element = m_provisionalFullscreenElement.release(); | |
66 Document& document = element->document(); | |
67 m_fullscreenFrame = document.frame(); | |
68 | |
69 if (!m_fullscreenFrame) | |
70 return; | 61 return; |
71 | 62 |
72 if (!m_haveEnteredFullscreen) { | 63 if (!m_haveEnteredFullscreen) { |
73 updatePageScaleConstraints(false); | 64 updatePageScaleConstraints(false); |
74 m_webViewImpl->setPageScaleFactor(1.0f); | 65 m_webViewImpl->setPageScaleFactor(1.0f); |
75 if (m_webViewImpl->mainFrame()->isWebLocalFrame()) | 66 if (m_webViewImpl->mainFrame()->isWebLocalFrame()) |
76 m_webViewImpl->mainFrame()->setScrollOffset(WebSize()); | 67 m_webViewImpl->mainFrame()->setScrollOffset(WebSize()); |
77 m_webViewImpl->setVisualViewportOffset(FloatPoint()); | 68 m_webViewImpl->setVisualViewportOffset(FloatPoint()); |
78 m_haveEnteredFullscreen = true; | 69 m_haveEnteredFullscreen = true; |
79 } | 70 } |
80 | 71 |
81 Fullscreen::from(document).didEnterFullscreenForElement(element); | 72 // TODO(foolip): Unprefixed requests |
82 DCHECK_EQ(Fullscreen::currentFullScreenElementFrom(document), element); | 73 HeapVector<Member<Element>> pendingFullscreenElements; |
| 74 pendingFullscreenElements.swap(m_pendingFullscreenElements); |
83 | 75 |
84 if (isHTMLVideoElement(element)) { | 76 for (Element* element : pendingFullscreenElements) { |
85 HTMLVideoElement* videoElement = toHTMLVideoElement(element); | 77 Fullscreen::didEnterFullscreenForElement(*element, |
86 if (videoElement->usesOverlayFullscreenVideo() && | 78 Fullscreen::PrefixedRequest); |
87 m_webViewImpl->layerTreeView()) | 79 |
88 m_webViewImpl->layerTreeView()->setHasTransparentBackground(true); | 80 // TODO(foolip): this and the exit stuff has to be synced with animation |
| 81 // frames tasks too |
| 82 if (isHTMLVideoElement(element)) { |
| 83 HTMLVideoElement* videoElement = toHTMLVideoElement(element); |
| 84 if (videoElement->usesOverlayFullscreenVideo() && |
| 85 m_webViewImpl->layerTreeView()) |
| 86 m_webViewImpl->layerTreeView()->setHasTransparentBackground(true); |
| 87 } |
89 } | 88 } |
90 } | 89 } |
91 | 90 |
92 void FullscreenController::didExitFullscreen() { | 91 void FullscreenController::didExitFullscreen() { |
93 if (!m_fullscreenFrame) | 92 if (!m_fullscreenFrame) |
94 return; | 93 return; |
95 | 94 |
96 if (m_haveEnteredFullscreen) | 95 if (m_haveEnteredFullscreen) |
97 updatePageScaleConstraints(true); | 96 updatePageScaleConstraints(true); |
98 | 97 |
99 if (Document* document = m_fullscreenFrame->document()) { | 98 if (Document* document = m_fullscreenFrame->document()) { |
100 if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document)) { | 99 if (Element* element = Fullscreen::fullscreenElement(*document)) { |
101 Element* element = fullscreen->currentFullScreenElement(); | 100 // When the client exits from full screen we have to call |
102 if (element) { | 101 // fullyExitFullscreen to notify the document. While doing that, suppress |
103 // When the client exits from full screen we have to call | 102 // notifications back to the client. |
104 // fullyExitFullscreen to notify the document. While doing that, | 103 m_isCancelingFullscreen = true; |
105 // suppress notifications back to the client. | 104 Fullscreen::fullyExitFullscreen(*document); |
106 m_isCancelingFullscreen = true; | 105 m_isCancelingFullscreen = false; |
107 Fullscreen::fullyExitFullscreen(*document); | |
108 m_isCancelingFullscreen = false; | |
109 | 106 |
110 // If the video used overlay fullscreen mode, the background was made | 107 // If the video used overlay fullscreen mode, the background was made |
111 // transparent. Restore the transparency. | 108 // transparent. Restore the transparency. |
112 if (isHTMLVideoElement(element) && m_webViewImpl->layerTreeView()) | 109 if (isHTMLVideoElement(element) && m_webViewImpl->layerTreeView()) { |
113 m_webViewImpl->layerTreeView()->setHasTransparentBackground( | 110 m_webViewImpl->layerTreeView()->setHasTransparentBackground( |
114 m_webViewImpl->isTransparent()); | 111 m_webViewImpl->isTransparent()); |
| 112 } |
115 | 113 |
116 // We need to wait until style and layout are updated in order | 114 // We need to wait until style and layout are updated in order |
117 // to propertly restore scroll offsets since content may not be | 115 // to propertly restore scroll offsets since content may not be |
118 // overflowing in the same way until they do. | 116 // overflowing in the same way until they do. |
119 if (m_haveEnteredFullscreen) | 117 if (m_haveEnteredFullscreen) |
120 m_needsScrollAndScaleRestore = true; | 118 m_needsScrollAndScaleRestore = true; |
121 | 119 |
122 fullscreen->didExitFullscreen(); | 120 Fullscreen::didExitFullscreen(*document); |
123 } | |
124 } | 121 } |
125 } | 122 } |
126 | 123 |
127 m_haveEnteredFullscreen = false; | 124 m_haveEnteredFullscreen = false; |
128 m_fullscreenFrame.clear(); | 125 m_fullscreenFrame.clear(); |
129 } | 126 } |
130 | 127 |
131 void FullscreenController::enterFullscreenForElement(Element* element) { | 128 void FullscreenController::enterFullscreenForElement(Element* element) { |
132 // We are already transitioning to fullscreen for a different element. | 129 m_pendingFullscreenElements.append(element); |
133 if (m_provisionalFullscreenElement) { | |
134 m_provisionalFullscreenElement = element; | |
135 return; | |
136 } | |
137 | 130 |
138 // We are already in fullscreen mode. | 131 // We are already in fullscreen mode. |
139 if (m_fullscreenFrame) { | 132 if (m_fullscreenFrame) { |
140 m_provisionalFullscreenElement = element; | |
141 didEnterFullscreen(); | 133 didEnterFullscreen(); |
142 return; | 134 return; |
143 } | 135 } |
144 | 136 |
145 // We need to store these values here rather than didEnterFullscreen since | 137 // We need to store these values here rather than didEnterFullscreen since |
146 // by the time the latter is called, a Resize has already occured, clamping | 138 // by the time the latter is called, a Resize has already occured, clamping |
147 // the scroll offset. Don't save values if we're still waiting to restore | 139 // the scroll offset. Don't save values if we're still waiting to restore |
148 // a previous set. This can happen if we exit and quickly reenter fullscreen | 140 // a previous set. This can happen if we exit and quickly reenter fullscreen |
149 // without performing a layout. | 141 // without performing a layout. |
150 if (!m_haveEnteredFullscreen && !m_needsScrollAndScaleRestore) { | 142 if (!m_haveEnteredFullscreen && !m_needsScrollAndScaleRestore) { |
151 m_exitFullscreenPageScaleFactor = m_webViewImpl->pageScaleFactor(); | 143 m_exitFullscreenPageScaleFactor = m_webViewImpl->pageScaleFactor(); |
152 m_exitFullscreenScrollOffset = | 144 m_exitFullscreenScrollOffset = |
153 m_webViewImpl->mainFrame()->isWebLocalFrame() | 145 m_webViewImpl->mainFrame()->isWebLocalFrame() |
154 ? m_webViewImpl->mainFrame()->scrollOffset() | 146 ? m_webViewImpl->mainFrame()->scrollOffset() |
155 : WebSize(); | 147 : WebSize(); |
156 m_exitFullscreenVisualViewportOffset = | 148 m_exitFullscreenVisualViewportOffset = |
157 m_webViewImpl->visualViewportOffset(); | 149 m_webViewImpl->visualViewportOffset(); |
158 } | 150 } |
159 | 151 |
160 // We need to transition to fullscreen mode. | 152 // We need to transition to fullscreen mode. |
161 WebLocalFrameImpl* frame = | 153 WebLocalFrameImpl* frame = |
162 WebLocalFrameImpl::fromFrame(element->document().frame()); | 154 WebLocalFrameImpl::fromFrame(element->document().frame()); |
163 if (frame && frame->client()) { | 155 if (frame && frame->client()) { |
164 if (!Fullscreen::from(element->document()).forCrossProcessDescendant()) | 156 frame->client()->enterFullscreen(); |
165 frame->client()->enterFullscreen(); | 157 } else { |
166 m_provisionalFullscreenElement = element; | 158 // TODO(foolip): now what? |
| 159 DCHECK(0); |
167 } | 160 } |
168 } | 161 } |
169 | 162 |
170 void FullscreenController::exitFullscreenForElement(Element* element) { | 163 void FullscreenController::exitFullscreenForElement(Element* element) { |
171 DCHECK(element); | 164 DCHECK(element); |
172 | 165 |
| 166 // TODO(dsinclair): This should not be needed because we addToTopLayer |
| 167 // in Fullscreen::popFullscreenElementStack but, the WebView code doesn't |
| 168 // call Fullscreen::requestFullscreen() and, instead, just enters and |
| 169 // exists itself. This should be unified so there is one way to go |
| 170 // fullscreen. crbug.com/538158 |
| 171 element->document().removeFromTopLayer(element); |
| 172 |
173 // The client is exiting full screen, so don't send a notification. | 173 // The client is exiting full screen, so don't send a notification. |
174 if (m_isCancelingFullscreen) | 174 if (m_isCancelingFullscreen) |
175 return; | 175 return; |
176 | 176 |
177 WebLocalFrameImpl* frame = | 177 WebLocalFrameImpl* frame = |
178 WebLocalFrameImpl::fromFrame(element->document().frame()); | 178 WebLocalFrameImpl::fromFrame(element->document().frame()); |
179 if (frame && frame->client()) | 179 if (frame && frame->client()) |
180 frame->client()->exitFullscreen(); | 180 frame->client()->exitFullscreen(); |
181 } | 181 } |
182 | 182 |
183 void FullscreenController::updateSize() { | 183 void FullscreenController::updateSize() { |
184 if (!isFullscreen()) | 184 if (!isFullscreen()) |
185 return; | 185 return; |
186 | 186 |
187 updatePageScaleConstraints(false); | 187 updatePageScaleConstraints(false); |
188 | 188 |
189 LayoutFullScreen* layoutObject = | 189 Document* document = m_fullscreenFrame->document(); |
190 Fullscreen::from(*m_fullscreenFrame->document()).fullScreenLayoutObject(); | 190 if (Element* fullscreenElement = Fullscreen::fullscreenElement(*document)) |
191 if (layoutObject) | 191 Fullscreen::didUpdateSize(*fullscreenElement); |
192 layoutObject->updateStyle(); | |
193 } | 192 } |
194 | 193 |
195 void FullscreenController::didUpdateLayout() { | 194 void FullscreenController::didUpdateLayout() { |
196 if (!m_needsScrollAndScaleRestore) | 195 if (!m_needsScrollAndScaleRestore) |
197 return; | 196 return; |
198 | 197 |
199 // If we re-entered fullscreen before we could restore the scroll and scale | 198 // If we re-entered fullscreen before we could restore the scroll and scale |
200 // don't try restoring them yet. | 199 // don't try restoring them yet. |
201 if (isFullscreen()) | 200 if (isFullscreen()) |
202 return; | 201 return; |
(...skipping 25 matching lines...) Expand all Loading... |
228 // contents size. | 227 // contents size. |
229 m_webViewImpl->didChangeContentsSize(); | 228 m_webViewImpl->didChangeContentsSize(); |
230 if (m_webViewImpl->mainFrameImpl() && | 229 if (m_webViewImpl->mainFrameImpl() && |
231 m_webViewImpl->mainFrameImpl()->frameView()) | 230 m_webViewImpl->mainFrameImpl()->frameView()) |
232 m_webViewImpl->mainFrameImpl()->frameView()->setNeedsLayout(); | 231 m_webViewImpl->mainFrameImpl()->frameView()->setNeedsLayout(); |
233 | 232 |
234 m_webViewImpl->updateMainFrameLayoutSize(); | 233 m_webViewImpl->updateMainFrameLayoutSize(); |
235 } | 234 } |
236 | 235 |
237 DEFINE_TRACE(FullscreenController) { | 236 DEFINE_TRACE(FullscreenController) { |
238 visitor->trace(m_provisionalFullscreenElement); | 237 visitor->trace(m_pendingFullscreenElements); |
239 visitor->trace(m_fullscreenFrame); | 238 visitor->trace(m_fullscreenFrame); |
240 } | 239 } |
241 | 240 |
242 } // namespace blink | 241 } // namespace blink |
OLD | NEW |