Index: third_party/WebKit/Source/core/dom/Fullscreen.cpp |
diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp |
index ff1331bd4cadc423dc311e1626746ce7ce733867..366a08e3a2b7ffdf288d07bc3d998281e2ffa3f9 100644 |
--- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp |
+++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp |
@@ -31,6 +31,7 @@ |
#include "core/dom/Document.h" |
#include "core/dom/ElementTraversal.h" |
+#include "core/dom/FullscreenCallbacks.h" |
#include "core/dom/StyleEngine.h" |
#include "core/events/Event.h" |
#include "core/frame/FrameHost.h" |
@@ -280,6 +281,33 @@ void Fullscreen::contextDestroyed() { |
m_fullscreenElementStack.clear(); |
} |
+// RequestFullscreenCallbacks hold the data for a pending request. |
+// FullscreenController invokes the success or error callback. |
+class RequestFullscreenCallbacks final : public FullscreenCallbacks { |
+ USING_FAST_MALLOC(RequestFullscreenCallbacks); |
+ WTF_MAKE_NONCOPYABLE(RequestFullscreenCallbacks); |
+ |
+ public: |
+ static std::unique_ptr<FullscreenCallbacks> |
+ create(Document& document, Element& element, Fullscreen::RequestType type) { |
+ return wrapUnique(new RequestFullscreenCallbacks(Fullscreen::from(document), |
esprehn
2016/12/01 20:26:12
The element and the document can disagree, is ther
foolip
2016/12/01 23:05:01
I was working on this today, just uploaded "handle
|
+ element, type)); |
+ } |
+ void onSuccess() override { m_fullscreen->didEnterFullscreen(*m_element); } |
+ void onError() override { |
+ m_fullscreen->enqueueErrorEvent(*m_element, m_type); |
+ } |
+ |
+ private: |
+ RequestFullscreenCallbacks(Fullscreen& fullscreen, |
+ Element& element, |
+ Fullscreen::RequestType type) |
+ : m_fullscreen(fullscreen), m_element(element), m_type(type) {} |
+ Persistent<Fullscreen> m_fullscreen; |
+ Persistent<Element> m_element; |
+ Fullscreen::RequestType m_type; |
+}; |
+ |
// https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen |
void Fullscreen::requestFullscreen(Element& element, |
RequestType requestType, |
@@ -298,8 +326,8 @@ void Fullscreen::requestFullscreen(Element& element, |
} |
} |
- // Ignore this request if the document is not in a live frame. |
- if (!document.isActive()) |
+ // Ignore this call if the document is not in a live frame. |
+ if (!document.isActive() || !document.frame()) |
return; |
// If |element| is on top of |doc|'s fullscreen element stack, terminate these |
@@ -399,7 +427,9 @@ void Fullscreen::requestFullscreen(Element& element, |
// 5. Return, and run the remaining steps asynchronously. |
// 6. Optionally, perform some animation. |
- document.frameHost()->chromeClient().enterFullscreenForElement(&element); |
+ document.frameHost()->chromeClient().enterFullscreen( |
+ *document.frame(), |
+ RequestFullscreenCallbacks::create(document, element, requestType)); |
// 7. Optionally, display a message indicating how the user can exit |
// displaying the context object fullscreen. |
@@ -441,10 +471,11 @@ void Fullscreen::fullyExitFullscreen(Document& document) { |
void Fullscreen::exitFullscreen(Document& document) { |
// The exitFullscreen() method must run these steps: |
- // 1. Let doc be the context object. (i.e. "this") |
- if (!document.isActive()) |
+ // Ignore this call if the document is not in a live frame. |
+ if (!document.isActive() || !document.frame()) |
return; |
+ // 1. Let doc be the context object. (i.e. "this") |
// 2. If doc's fullscreen element stack is empty, terminate these steps. |
if (!fullscreenElementFrom(document)) |
return; |
@@ -454,9 +485,8 @@ void Fullscreen::exitFullscreen(Document& document) { |
// child of the doc is last and the document furthest away from the doc is |
// first. |
HeapDeque<Member<Document>> descendants; |
- for (Frame* descendant = |
- document.frame() ? document.frame()->tree().traverseNext() : nullptr; |
- descendant; descendant = descendant->tree().traverseNext()) { |
+ for (Frame* descendant = document.frame()->tree().traverseNext(); descendant; |
+ descendant = descendant->tree().traverseNext()) { |
if (!descendant->isLocalFrame()) |
continue; |
DCHECK(toLocalFrame(descendant)->document()); |
@@ -529,15 +559,14 @@ void Fullscreen::exitFullscreen(Document& document) { |
if (!host) |
return; |
- // Only exit out of full screen window mode if there are no remaining elements |
- // in the full screen stack. |
+ // Only exit fullscreen mode if the fullscreen element stack is empty. |
if (!newTop) { |
- host->chromeClient().exitFullscreen(document.frame()); |
+ host->chromeClient().exitFullscreen(*document.frame()); |
return; |
} |
- // Otherwise, notify the chrome of the new full screen element. |
- host->chromeClient().enterFullscreenForElement(newTop); |
+ // Otherwise, enter fullscreen for the fullscreen element stack's top element. |
+ from(document).didEnterFullscreen(*newTop); |
} |
// https://fullscreen.spec.whatwg.org/#dom-document-fullscreenenabled |
@@ -549,19 +578,18 @@ bool Fullscreen::fullscreenEnabled(Document& document) { |
fullscreenIsSupported(document); |
} |
-void Fullscreen::didEnterFullscreenForElement(Element* element) { |
- DCHECK(element); |
+void Fullscreen::didEnterFullscreen(Element& element) { |
if (!document()->isActive() || !document()->frame()) |
return; |
- if (m_currentFullScreenElement == element) |
+ if (m_currentFullScreenElement == &element) |
return; |
if (m_fullScreenLayoutObject) |
m_fullScreenLayoutObject->unwrapLayoutObject(); |
Element* previousElement = m_currentFullScreenElement; |
- m_currentFullScreenElement = element; |
+ m_currentFullScreenElement = &element; |
// Create a placeholder block for a the full-screen element, to keep the page |
// from reflowing when the element is removed from the normal flow. Only do |
@@ -609,7 +637,7 @@ void Fullscreen::didEnterFullscreenForElement(Element* element) { |
m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); |
document()->frame()->chromeClient().fullscreenElementChanged(previousElement, |
- element); |
+ &element); |
} |
void Fullscreen::didExitFullscreen() { |
@@ -619,6 +647,13 @@ void Fullscreen::didExitFullscreen() { |
if (!m_currentFullScreenElement) |
return; |
+ // If fullscreen was canceled by the browser, e.g. if the user pressed Esc, |
+ // then |exitFullscreen()| was never called. Let |fullyExitFullscreen()| clear |
+ // the fullscreen element stack and fire any events as necessary. |
+ // TODO(foolip): Remove this when state changes and events are synchronized |
+ // with animation frames. https://crbug.com/402376 |
+ fullyExitFullscreen(*document()); |
+ |
if (m_forCrossProcessDescendant) |
m_currentFullScreenElement->setContainsFullScreenElement(false); |
@@ -692,8 +727,7 @@ void Fullscreen::enqueueChangeEvent(Document& document, |
event = createEvent(EventTypeNames::webkitfullscreenchange, *target); |
} |
m_eventQueue.append(event); |
- // NOTE: The timer is started in |
- // didEnterFullscreenForElement/didExitFullscreen. |
+ // NOTE: The timer is started in didEnterFullscreen/didExitFullscreen. |
} |
void Fullscreen::enqueueErrorEvent(Element& element, RequestType requestType) { |