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

Unified Diff: Source/core/dom/FullscreenElementStack.cpp

Issue 476763004: Rename FullscreenElementStack to just Fullscreen (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase Created 6 years, 4 months 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
« no previous file with comments | « Source/core/dom/FullscreenElementStack.h ('k') | Source/core/dom/RenderTreeBuilder.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/dom/FullscreenElementStack.cpp
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
deleted file mode 100644
index 81f14addbca6ede5c2a9a37abbcfd2a2328556df..0000000000000000000000000000000000000000
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/dom/FullscreenElementStack.h"
-
-#include "core/HTMLNames.h"
-#include "core/dom/Document.h"
-#include "core/events/Event.h"
-#include "core/frame/FrameHost.h"
-#include "core/frame/LocalFrame.h"
-#include "core/frame/Settings.h"
-#include "core/frame/UseCounter.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLMediaElement.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/rendering/RenderFullScreen.h"
-#include "platform/UserGestureIndicator.h"
-
-namespace blink {
-
-using namespace HTMLNames;
-
-static bool fullscreenIsAllowedForAllOwners(const Document& document)
-{
- for (const HTMLFrameOwnerElement* owner = document.ownerElement(); owner; owner = owner->document().ownerElement()) {
- if (!isHTMLIFrameElement(owner))
- return false;
- if (!owner->hasAttribute(allowfullscreenAttr))
- return false;
- }
- return true;
-}
-
-static bool fullscreenIsSupported(const Document& document)
-{
- // Fullscreen is supported if there is no previously-established user preference,
- // security risk, or platform limitation.
- return !document.settings() || document.settings()->fullscreenSupported();
-}
-
-static bool fullscreenIsSupported(const Document& document, const Element& element)
-{
- if (!document.settings() || (document.settings()->disallowFullscreenForNonMediaElements() && !isHTMLMediaElement(element)))
- return false;
- return fullscreenIsSupported(document);
-}
-
-static bool isPrefixed(const AtomicString& type)
-{
- return type == EventTypeNames::webkitfullscreenchange || type == EventTypeNames::webkitfullscreenerror;
-}
-
-static PassRefPtrWillBeRawPtr<Event> createEvent(const AtomicString& type, EventTarget& target)
-{
- EventInit initializer;
- initializer.bubbles = isPrefixed(type);
- RefPtrWillBeRawPtr<Event> event = Event::create(type, initializer);
- event->setTarget(&target);
- return event;
-}
-
-const char* FullscreenElementStack::supplementName()
-{
- return "FullscreenElementStack";
-}
-
-FullscreenElementStack& FullscreenElementStack::from(Document& document)
-{
- FullscreenElementStack* fullscreen = fromIfExists(document);
- if (!fullscreen) {
- fullscreen = new FullscreenElementStack(document);
- DocumentSupplement::provideTo(document, supplementName(), adoptPtrWillBeNoop(fullscreen));
- }
-
- return *fullscreen;
-}
-
-FullscreenElementStack* FullscreenElementStack::fromIfExistsSlow(Document& document)
-{
- return static_cast<FullscreenElementStack*>(DocumentSupplement::from(document, supplementName()));
-}
-
-Element* FullscreenElementStack::fullscreenElementFrom(Document& document)
-{
- if (FullscreenElementStack* found = fromIfExists(document))
- return found->fullscreenElement();
- return 0;
-}
-
-Element* FullscreenElementStack::currentFullScreenElementFrom(Document& document)
-{
- if (FullscreenElementStack* found = fromIfExists(document))
- return found->webkitCurrentFullScreenElement();
- return 0;
-}
-
-bool FullscreenElementStack::isFullScreen(Document& document)
-{
- if (FullscreenElementStack* found = fromIfExists(document))
- return found->webkitIsFullScreen();
- return false;
-}
-
-FullscreenElementStack::FullscreenElementStack(Document& document)
- : DocumentLifecycleObserver(&document)
- , m_areKeysEnabledInFullScreen(false)
- , m_fullScreenRenderer(nullptr)
- , m_eventQueueTimer(this, &FullscreenElementStack::eventQueueTimerFired)
-{
- document.setHasFullscreenElementStack();
-}
-
-FullscreenElementStack::~FullscreenElementStack()
-{
-}
-
-inline Document* FullscreenElementStack::document()
-{
- return lifecycleContext();
-}
-
-void FullscreenElementStack::documentWasDetached()
-{
- m_eventQueue.clear();
-
- if (m_fullScreenRenderer)
- m_fullScreenRenderer->destroy();
-
-#if ENABLE(OILPAN)
- m_fullScreenElement = nullptr;
- m_fullScreenElementStack.clear();
-#endif
-
-}
-
-#if !ENABLE(OILPAN)
-void FullscreenElementStack::documentWasDisposed()
-{
- // NOTE: the context dispose phase is not supported in oilpan. Please
- // consider using the detach phase instead.
- m_fullScreenElement = nullptr;
- m_fullScreenElementStack.clear();
-}
-#endif
-
-bool FullscreenElementStack::elementReady(Element& element, RequestType requestType)
-{
- // A fullscreen element ready check for an element |element| returns true if all of the
- // following are true, and false otherwise:
-
- // |element| is in a document.
- if (!element.inDocument())
- return false;
-
- // |element|'s node document's fullscreen enabled flag is set.
- if (!fullscreenIsAllowedForAllOwners(element.document())) {
- if (requestType == PrefixedVideoRequest)
- UseCounter::count(element.document(), UseCounter::VideoFullscreenAllowedExemption);
- else
- return false;
- }
-
- // |element|'s node document's fullscreen element stack is either empty or its top element is an
- // ancestor of |element|.
- if (Element* topElement = fullscreenElementFrom(element.document())) {
- if (!element.isDescendantOf(topElement))
- return false;
- }
-
- // |element| has no ancestor element whose local name is iframe and namespace is the HTML
- // namespace.
- if (Traversal<HTMLIFrameElement>::firstAncestor(element))
- return false;
-
- return true;
-}
-
-void FullscreenElementStack::requestFullscreen(Element& element, RequestType requestType)
-{
- // Ignore this request if the document is not in a live frame.
- if (!document()->isActive())
- return;
-
- do {
- // 1. If any of the following conditions are true, terminate these steps and queue a task to fire
- // an event named fullscreenerror with its bubbles attribute set to true on the context object's
- // node document:
-
- // The fullscreen element ready check returns false.
- if (!elementReady(element, requestType))
- break;
-
- // This algorithm is not allowed to show a pop-up:
- // An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either:
- // - an activation behavior is currently being processed whose click event was trusted, or
- // - the event listener for a trusted click event is being handled.
- if (!UserGestureIndicator::processingUserGesture())
- break;
-
- // Fullscreen is not supported.
- if (!fullscreenIsSupported(element.document(), element))
- break;
-
- // 2. Let doc be element's node document. (i.e. "this")
- Document* currentDoc = document();
-
- // 3. Let docs be all doc's ancestor browsing context's documents (if any) and doc.
- Deque<Document*> docs;
-
- do {
- docs.prepend(currentDoc);
- currentDoc = currentDoc->ownerElement() ? &currentDoc->ownerElement()->document() : 0;
- } while (currentDoc);
-
- // 4. For each document in docs, run these substeps:
- Deque<Document*>::iterator current = docs.begin(), following = docs.begin();
-
- do {
- ++following;
-
- // 1. Let following document be the document after document in docs, or null if there is no
- // such document.
- Document* currentDoc = *current;
- Document* followingDoc = following != docs.end() ? *following : 0;
-
- // 2. If following document is null, push context object on document's fullscreen element
- // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
- // set to true on the document.
- if (!followingDoc) {
- from(*currentDoc).pushFullscreenElementStack(element, requestType);
- enqueueChangeEvent(*currentDoc, requestType);
- continue;
- }
-
- // 3. Otherwise, if document's fullscreen element stack is either empty or its top element
- // is not following document's browsing context container,
- Element* topElement = fullscreenElementFrom(*currentDoc);
- if (!topElement || topElement != followingDoc->ownerElement()) {
- // ...push following document's browsing context container on document's fullscreen element
- // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
- // set to true on document.
- from(*currentDoc).pushFullscreenElementStack(*followingDoc->ownerElement(), requestType);
- enqueueChangeEvent(*currentDoc, requestType);
- continue;
- }
-
- // 4. Otherwise, do nothing for this document. It stays the same.
- } while (++current != docs.end());
-
- // 5. Return, and run the remaining steps asynchronously.
- // 6. Optionally, perform some animation.
- m_areKeysEnabledInFullScreen = requestType != PrefixedMozillaRequest && requestType != PrefixedVideoRequest;
- document()->frameHost()->chrome().client().enterFullScreenForElement(&element);
-
- // 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen.
- return;
- } while (0);
-
- enqueueErrorEvent(element, requestType);
-}
-
-void FullscreenElementStack::fullyExitFullscreen()
-{
- // "To fully exit fullscreen act as if the exitFullscreen() method was invoked on the top-level browsing
- // context's document and subsequently empty that document's fullscreen element stack."
- if (!fullscreenElementFrom(document()->topDocument()))
- return;
-
- // To achieve that aim, remove all the elements from the top document's stack except for the first before
- // calling exitFullscreen():
- WillBeHeapVector<std::pair<RefPtrWillBeMember<Element>, RequestType> > replacementFullscreenElementStack;
- FullscreenElementStack& topFullscreenElementStack = from(document()->topDocument());
- replacementFullscreenElementStack.append(topFullscreenElementStack.m_fullScreenElementStack.last());
- topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscreenElementStack);
- topFullscreenElementStack.exitFullscreen();
-}
-
-void FullscreenElementStack::exitFullscreen()
-{
- // The exitFullscreen() method must run these steps:
-
- // 1. Let doc be the context object. (i.e. "this")
- Document* currentDoc = document();
- if (!currentDoc->isActive())
- return;
-
- // 2. If doc's fullscreen element stack is empty, terminate these steps.
- if (m_fullScreenElementStack.isEmpty())
- return;
-
- // 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
- // element stack (if any), ordered so that the child of the doc is last and the document furthest
- // away from the doc is first.
- WillBeHeapDeque<RefPtrWillBeMember<Document> > descendants;
- for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
- if (!descendant->isLocalFrame())
- continue;
- ASSERT(toLocalFrame(descendant)->document());
- if (fullscreenElementFrom(*toLocalFrame(descendant)->document()))
- descendants.prepend(toLocalFrame(descendant)->document());
- }
-
- // 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
- // task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
- for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
- ASSERT(*i);
- RequestType requestType = from(**i).m_fullScreenElementStack.last().second;
- from(**i).clearFullscreenElementStack();
- enqueueChangeEvent(**i, requestType);
- }
-
- // 5. While doc is not null, run these substeps:
- Element* newTop = 0;
- while (currentDoc) {
- RequestType requestType = from(*currentDoc).m_fullScreenElementStack.last().second;
-
- // 1. Pop the top element of doc's fullscreen element stack.
- from(*currentDoc).popFullscreenElementStack();
-
- // If doc's fullscreen element stack is non-empty and the element now at the top is either
- // not in a document or its node document is not doc, repeat this substep.
- newTop = fullscreenElementFrom(*currentDoc);
- if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
- continue;
-
- // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
- // on doc.
- enqueueChangeEvent(*currentDoc, requestType);
-
- // 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context
- // container, set doc to that browsing context container's node document.
- if (!newTop && currentDoc->ownerElement()) {
- currentDoc = &currentDoc->ownerElement()->document();
- continue;
- }
-
- // 4. Otherwise, set doc to null.
- currentDoc = 0;
- }
-
- // 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 ASSERT(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.
- if (!newTop) {
- host->chrome().client().exitFullScreenForElement(m_fullScreenElement.get());
- return;
- }
-
- // Otherwise, notify the chrome of the new full screen element.
- host->chrome().client().enterFullScreenForElement(newTop);
-}
-
-bool FullscreenElementStack::fullscreenEnabled(Document& document)
-{
- // 4. The fullscreenEnabled attribute must return true if the context object has its
- // fullscreen enabled flag set and fullscreen is supported, and false otherwise.
-
- // Top-level browsing contexts are implied to have their allowFullScreen attribute set.
- return fullscreenIsAllowedForAllOwners(document) && fullscreenIsSupported(document);
-}
-
-void FullscreenElementStack::willEnterFullScreenForElement(Element* element)
-{
- ASSERT(element);
- if (!document()->isActive())
- return;
-
- if (m_fullScreenRenderer)
- m_fullScreenRenderer->unwrapRenderer();
-
- m_fullScreenElement = 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 this for a RenderBox, as only
- // a box will have a frameRect. The placeholder will be created in setFullScreenRenderer()
- // during layout.
- RenderObject* renderer = m_fullScreenElement->renderer();
- bool shouldCreatePlaceholder = renderer && renderer->isBox();
- if (shouldCreatePlaceholder) {
- m_savedPlaceholderFrameRect = toRenderBox(renderer)->frameRect();
- m_savedPlaceholderRenderStyle = RenderStyle::clone(renderer->style());
- }
-
- if (m_fullScreenElement != document()->documentElement())
- RenderFullScreen::wrapRenderer(renderer, renderer ? renderer->parent() : 0, document());
-
- m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
-
- // FIXME: This should not call updateStyleIfNeeded.
- document()->setNeedsStyleRecalc(SubtreeStyleChange);
- document()->updateRenderTreeIfNeeded();
-}
-
-void FullscreenElementStack::didEnterFullScreenForElement(Element*)
-{
- if (!m_fullScreenElement)
- return;
-
- if (!document()->isActive())
- return;
-
- m_fullScreenElement->didBecomeFullscreenElement();
-
- m_eventQueueTimer.startOneShot(0, FROM_HERE);
-}
-
-void FullscreenElementStack::willExitFullScreenForElement(Element*)
-{
- if (!m_fullScreenElement)
- return;
-
- if (!document()->isActive())
- return;
-
- m_fullScreenElement->willStopBeingFullscreenElement();
-}
-
-void FullscreenElementStack::didExitFullScreenForElement(Element*)
-{
- if (!m_fullScreenElement)
- return;
-
- if (!document()->isActive())
- return;
-
- m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
-
- m_areKeysEnabledInFullScreen = false;
-
- if (m_fullScreenRenderer)
- m_fullScreenRenderer->unwrapRenderer();
-
- m_fullScreenElement = nullptr;
- document()->setNeedsStyleRecalc(SubtreeStyleChange);
-
- // 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 = &document()->topDocument();
- ASSERT(exitingDocument);
- from(*exitingDocument).m_eventQueueTimer.startOneShot(0, FROM_HERE);
-}
-
-void FullscreenElementStack::setFullScreenRenderer(RenderFullScreen* renderer)
-{
- if (renderer == m_fullScreenRenderer)
- return;
-
- if (renderer && m_savedPlaceholderRenderStyle) {
- renderer->createPlaceholder(m_savedPlaceholderRenderStyle.release(), m_savedPlaceholderFrameRect);
- } else if (renderer && m_fullScreenRenderer && m_fullScreenRenderer->placeholder()) {
- RenderBlock* placeholder = m_fullScreenRenderer->placeholder();
- renderer->createPlaceholder(RenderStyle::clone(placeholder->style()), placeholder->frameRect());
- }
-
- if (m_fullScreenRenderer)
- m_fullScreenRenderer->unwrapRenderer();
- ASSERT(!m_fullScreenRenderer);
-
- m_fullScreenRenderer = renderer;
-}
-
-void FullscreenElementStack::fullScreenRendererDestroyed()
-{
- m_fullScreenRenderer = nullptr;
-}
-
-void FullscreenElementStack::enqueueChangeEvent(Document& document, RequestType requestType)
-{
- RefPtrWillBeRawPtr<Event> event;
- if (requestType == UnprefixedRequest) {
- event = createEvent(EventTypeNames::fullscreenchange, document);
- } else {
- ASSERT(document.hasFullscreenElementStack());
- FullscreenElementStack& fullscreen = from(document);
- EventTarget* target = fullscreen.fullscreenElement();
- if (!target)
- target = fullscreen.webkitCurrentFullScreenElement();
- if (!target)
- target = &document;
- event = createEvent(EventTypeNames::webkitfullscreenchange, *target);
- }
- m_eventQueue.append(event);
- // NOTE: The timer is started in didEnterFullScreenForElement/didExitFullScreenForElement.
-}
-
-void FullscreenElementStack::enqueueErrorEvent(Element& element, RequestType requestType)
-{
- RefPtrWillBeRawPtr<Event> event;
- if (requestType == UnprefixedRequest)
- event = createEvent(EventTypeNames::fullscreenerror, element.document());
- else
- event = createEvent(EventTypeNames::webkitfullscreenerror, element);
- m_eventQueue.append(event);
- m_eventQueueTimer.startOneShot(0, FROM_HERE);
-}
-
-void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>*)
-{
- // Since we dispatch events in this function, it's possible that the
- // document will be detached and GC'd. We protect it here to make sure we
- // can finish the function successfully.
- RefPtrWillBeRawPtr<Document> protectDocument(document());
- WillBeHeapDeque<RefPtrWillBeMember<Event> > eventQueue;
- m_eventQueue.swap(eventQueue);
-
- while (!eventQueue.isEmpty()) {
- RefPtrWillBeRawPtr<Event> event = eventQueue.takeFirst();
- Node* target = event->target()->toNode();
-
- // If the element was removed from our tree, also message the documentElement.
- if (!target->inDocument() && document()->documentElement()) {
- ASSERT(isPrefixed(event->type()));
- eventQueue.append(createEvent(event->type(), *document()->documentElement()));
- }
-
- target->dispatchEvent(event);
- }
-}
-
-void FullscreenElementStack::elementRemoved(Element& element)
-{
- // If an element |element| in a fullscreen element stack is removed from a document |document|,
- // run these steps:
-
- // 1. If |element| was at the top of |document|'s fullscreen element stack, act as if the
- // exitFullscreen() method was invoked on that document.
- if (fullscreenElement() == &element) {
- exitFullscreen();
- return;
- }
-
- // 2. Otherwise, remove |element| from |document|'s fullscreen element stack.
- for (size_t i = 0; i < m_fullScreenElementStack.size(); ++i) {
- if (m_fullScreenElementStack[i].first.get() == &element) {
- m_fullScreenElementStack.remove(i);
- return;
- }
- }
-
- // NOTE: |element| was not in the fullscreen element stack.
-}
-
-void FullscreenElementStack::clearFullscreenElementStack()
-{
- m_fullScreenElementStack.clear();
-}
-
-void FullscreenElementStack::popFullscreenElementStack()
-{
- if (m_fullScreenElementStack.isEmpty())
- return;
-
- m_fullScreenElementStack.removeLast();
-}
-
-void FullscreenElementStack::pushFullscreenElementStack(Element& element, RequestType requestType)
-{
- m_fullScreenElementStack.append(std::make_pair(&element, requestType));
-}
-
-void FullscreenElementStack::trace(Visitor* visitor)
-{
- visitor->trace(m_fullScreenElement);
- visitor->trace(m_fullScreenElementStack);
- visitor->trace(m_fullScreenRenderer);
- visitor->trace(m_eventQueue);
- DocumentSupplement::trace(visitor);
-}
-
-} // namespace blink
« no previous file with comments | « Source/core/dom/FullscreenElementStack.h ('k') | Source/core/dom/RenderTreeBuilder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698