Commit cc3f7633 authored by philipj@opera.com's avatar philipj@opera.com

Sync fullscreen element removal with the spec

http://fullscreen.spec.whatwg.org/#model
https://www.w3.org/Bugs/Public/show_bug.cgi?id=26326

TEST=LayoutTests/fullscreen/model/remove-*.html (new)
TEST=LayoutTests/fullscreen/full-screen-remove-*.html (no regression)

The distinction between fullyExitFullscreen() and exitFullscreen() was
not tested, but the new remove-last.html test fails with the old code.

BUG=383813

Review URL: https://codereview.chromium.org/476433002

git-svn-id: svn://svn.chromium.org/blink/trunk@180259 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent b056883a
<!DOCTYPE html>
<title>Remove the first element on the fullscreen element stack</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../trusted-event.js"></script>
<div id="log"></div>
<div id="first">
<div id="last"></div>
</div>
<script>
async_test(function(t)
{
var first = document.getElementById("first");
trusted_request(first);
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, first);
var last = document.getElementById("last");
trusted_request(last);
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, last);
first.remove();
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, null);
t.done();
});
});
});
});
</script>
<!DOCTYPE html>
<title>Remove the last element on the fullscreen element stack</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../trusted-event.js"></script>
<div id="log"></div>
<div id="first">
<div id="last"></div>
</div>
<script>
async_test(function(t)
{
var first = document.getElementById("first");
trusted_request(first);
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, first);
var last = document.getElementById("last");
trusted_request(last);
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, last);
last.remove();
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, first);
t.done();
});
});
});
});
</script>
<!DOCTYPE html>
<title>Remove the single element on the fullscreen element stack</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../trusted-event.js"></script>
<div id="log"></div>
<div id="single"></div>
<script>
async_test(function(t)
{
var single = document.getElementById("single");
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, single);
single.remove();
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, null);
t.done();
});
});
trusted_request(single);
});
</script>
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "core/dom/ClassCollection.h" #include "core/dom/ClassCollection.h"
#include "core/dom/ElementTraversal.h" #include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h" #include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/NameNodeList.h" #include "core/dom/NameNodeList.h"
#include "core/dom/NodeChildRemovalTracker.h" #include "core/dom/NodeChildRemovalTracker.h"
#include "core/dom/NodeRareData.h" #include "core/dom/NodeRareData.h"
...@@ -544,9 +543,6 @@ PassRefPtrWillBeRawPtr<Node> ContainerNode::removeChild(PassRefPtrWillBeRawPtr<N ...@@ -544,9 +543,6 @@ PassRefPtrWillBeRawPtr<Node> ContainerNode::removeChild(PassRefPtrWillBeRawPtr<N
document().removeFocusedElementOfSubtree(child.get()); document().removeFocusedElementOfSubtree(child.get());
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
fullscreen->removeFullScreenElementOfSubtree(child.get());
// Events fired when blurring currently focused node might have moved this // Events fired when blurring currently focused node might have moved this
// child into a different parent. // child into a different parent.
if (child->parentNode() != this) { if (child->parentNode() != this) {
...@@ -629,9 +625,6 @@ void ContainerNode::removeChildren() ...@@ -629,9 +625,6 @@ void ContainerNode::removeChildren()
// The container node can be removed from event handlers. // The container node can be removed from event handlers.
RefPtrWillBeRawPtr<ContainerNode> protect(this); RefPtrWillBeRawPtr<ContainerNode> protect(this);
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
fullscreen->removeFullScreenElementOfSubtree(this, true);
// Do any prep work needed before actually starting to detach // Do any prep work needed before actually starting to detach
// and remove... e.g. stop loading frames, fire unload events. // and remove... e.g. stop loading frames, fire unload events.
willRemoveChildren(); willRemoveChildren();
......
...@@ -1279,6 +1279,9 @@ void Element::removedFrom(ContainerNode* insertionPoint) ...@@ -1279,6 +1279,9 @@ void Element::removedFrom(ContainerNode* insertionPoint)
if (containsFullScreenElement()) if (containsFullScreenElement())
setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false); setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
fullscreen->elementRemoved(*this);
if (document().page()) if (document().page())
document().page()->pointerLockController().elementRemoved(this); document().page()->pointerLockController().elementRemoved(this);
......
...@@ -556,29 +556,27 @@ void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>* ...@@ -556,29 +556,27 @@ void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>*
} }
} }
void FullscreenElementStack::fullScreenElementRemoved() void FullscreenElementStack::elementRemoved(Element& element)
{ {
m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false); // If an element |element| in a fullscreen element stack is removed from a document |document|,
fullyExitFullscreen(); // run these steps:
}
void FullscreenElementStack::removeFullScreenElementOfSubtree(Node* node, bool amongChildrenOnly)
{
if (!m_fullScreenElement)
return;
// If the node isn't in a document it can't have a fullscreen'd child. // 1. If |element| was at the top of |document|'s fullscreen element stack, act as if the
if (!node->inDocument()) // exitFullscreen() method was invoked on that document.
if (fullscreenElement() == &element) {
exitFullscreen();
return; return;
}
bool elementInSubtree = false; // 2. Otherwise, remove |element| from |document|'s fullscreen element stack.
if (amongChildrenOnly) for (size_t i = 0; i < m_fullScreenElementStack.size(); ++i) {
elementInSubtree = m_fullScreenElement->isDescendantOf(node); if (m_fullScreenElementStack[i].first.get() == &element) {
else m_fullScreenElementStack.remove(i);
elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement->isDescendantOf(node); return;
}
}
if (elementInSubtree) // NOTE: |element| was not in the fullscreen element stack.
fullScreenElementRemoved();
} }
void FullscreenElementStack::clearFullscreenElementStack() void FullscreenElementStack::clearFullscreenElementStack()
......
...@@ -82,7 +82,7 @@ public: ...@@ -82,7 +82,7 @@ public:
RenderFullScreen* fullScreenRenderer() const { return m_fullScreenRenderer; } RenderFullScreen* fullScreenRenderer() const { return m_fullScreenRenderer; }
void fullScreenRendererDestroyed(); void fullScreenRendererDestroyed();
void removeFullScreenElementOfSubtree(Node*, bool amongChildrenOnly = false); void elementRemoved(Element&);
// Mozilla API // Mozilla API
bool webkitIsFullScreen() const { return m_fullScreenElement.get(); } bool webkitIsFullScreen() const { return m_fullScreenElement.get(); }
...@@ -113,8 +113,6 @@ private: ...@@ -113,8 +113,6 @@ private:
void enqueueErrorEvent(Element&, RequestType); void enqueueErrorEvent(Element&, RequestType);
void eventQueueTimerFired(Timer<FullscreenElementStack>*); void eventQueueTimerFired(Timer<FullscreenElementStack>*);
void fullScreenElementRemoved();
bool m_areKeysEnabledInFullScreen; bool m_areKeysEnabledInFullScreen;
RefPtrWillBeMember<Element> m_fullScreenElement; RefPtrWillBeMember<Element> m_fullScreenElement;
WillBeHeapVector<std::pair<RefPtrWillBeMember<Element>, RequestType> > m_fullScreenElementStack; WillBeHeapVector<std::pair<RefPtrWillBeMember<Element>, RequestType> > m_fullScreenElementStack;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment