Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Unified Diff: third_party/WebKit/Source/core/dom/Fullscreen.cpp

Issue 2550703002: Move pending state from FullscreenController to Fullscreen (Closed)
Patch Set: tests and documentation Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..5ff6e9afb1a7efe9d35c610f605a5c28ce74a39b 100644
--- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp
+++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
@@ -33,7 +33,6 @@
#include "core/dom/ElementTraversal.h"
#include "core/dom/StyleEngine.h"
#include "core/events/Event.h"
-#include "core/frame/FrameHost.h"
#include "core/frame/HostsUsingFeatures.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
@@ -298,8 +297,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 +398,8 @@ void Fullscreen::requestFullscreen(Element& element,
// 5. Return, and run the remaining steps asynchronously.
// 6. Optionally, perform some animation.
- document.frameHost()->chromeClient().enterFullscreenForElement(&element);
+ from(document).m_pendingFullscreenElement = &element;
+ document.frame()->chromeClient().enterFullscreen(*document.frame());
// 7. Optionally, display a message indicating how the user can exit
// displaying the context object fullscreen.
@@ -441,10 +441,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 +455,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());
@@ -521,23 +521,15 @@ void Fullscreen::exitFullscreen(Document& document) {
// 6. Return, and run the remaining steps asynchronously.
// 7. Optionally, perform some animation.
- FrameHost* host = document.frameHost();
-
- // Speculative fix for engaget.com/videos per crbug.com/336239.
- // FIXME: This check is wrong. We DCHECK(document->isActive()) above
- // so this should be redundant and should be removed!
- 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());
+ document.frame()->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).m_pendingFullscreenElement = newTop;
+ from(document).didEnterFullscreen();
}
// https://fullscreen.spec.whatwg.org/#dom-document-fullscreenenabled
@@ -549,14 +541,33 @@ bool Fullscreen::fullscreenEnabled(Document& document) {
fullscreenIsSupported(document);
}
-void Fullscreen::didEnterFullscreenForElement(Element* element) {
- DCHECK(element);
+void Fullscreen::didEnterFullscreen() {
if (!document()->isActive() || !document()->frame())
return;
+ // Start the timer for events enqueued by |requestFullscreen()|. The hover
+ // state update is scheduled first so that it's done when the events fire.
+ document()->frame()->eventHandler().scheduleHoverStateUpdate();
+ m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE);
+
+ Element* element = m_pendingFullscreenElement.release();
+ if (!element)
+ return;
+
if (m_currentFullScreenElement == element)
return;
+ if (!element->isConnected() || &element->document() != document()) {
+ // The element was removed or has moved to another document since the
+ // |requestFullscreen()| call. Exit fullscreen again to recover.
+ // TODO(foolip): Fire a fullscreenerror event. This is currently difficult
+ // because the fullscreenchange event has already been enqueued and possibly
+ // even fired. https://crbug.com/402376
+ LocalFrame& frame = *document()->frame();
+ frame.chromeClient().exitFullscreen(frame);
+ return;
+ }
+
if (m_fullScreenLayoutObject)
m_fullScreenLayoutObject->unwrapLayoutObject();
@@ -604,10 +615,6 @@ void Fullscreen::didEnterFullscreenForElement(Element* element) {
// FIXME: This should not call updateStyleAndLayoutTree.
document()->updateStyleAndLayoutTree();
- document()->frame()->eventHandler().scheduleHoverStateUpdate();
-
- m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE);
-
document()->frame()->chromeClient().fullscreenElementChanged(previousElement,
element);
}
@@ -616,6 +623,18 @@ void Fullscreen::didExitFullscreen() {
if (!document()->isActive() || !document()->frame())
return;
+ // Start the timer for events enqueued by |exitFullscreen()|. The hover state
+ // update is scheduled first so that it's done when the events fire.
+ document()->frame()->eventHandler().scheduleHoverStateUpdate();
+ m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE);
+
+ // 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_currentFullScreenElement)
return;
@@ -633,17 +652,6 @@ void Fullscreen::didExitFullscreen() {
Element* previousElement = m_currentFullScreenElement;
m_currentFullScreenElement = nullptr;
- document()->frame()->eventHandler().scheduleHoverStateUpdate();
-
- // When fullyExitFullscreen is called, we call exitFullscreen on the
- // topDocument(). That means that the events will be queued there. So if we
- // have no events here, start the timer on the exiting document.
- Document* exitingDocument = document();
- if (m_eventQueue.isEmpty())
- exitingDocument = &topmostLocalAncestor(*document());
- DCHECK(exitingDocument);
- from(*exitingDocument).m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE);
-
m_forCrossProcessDescendant = false;
document()->frame()->chromeClient().fullscreenElementChanged(previousElement,
@@ -692,8 +700,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) {
@@ -766,8 +773,9 @@ void Fullscreen::pushFullscreenElementStack(Element& element,
}
DEFINE_TRACE(Fullscreen) {
- visitor->trace(m_currentFullScreenElement);
+ visitor->trace(m_pendingFullscreenElement);
visitor->trace(m_fullscreenElementStack);
+ visitor->trace(m_currentFullScreenElement);
visitor->trace(m_eventQueue);
Supplement<Document>::trace(visitor);
ContextLifecycleObserver::trace(visitor);

Powered by Google App Engine
This is Rietveld 408576698