Commit 8fc482ed authored by philipj@opera.com's avatar philipj@opera.com

Implement the unprefixed the Fullscreen API

Intent to Implement and Ship:
https://groups.google.com/a/chromium.org/d/msg/blink-dev/GLl6aWs9-EM/uTqxEmM4iGcJ

The API is only enabled for testing, to allow the recent spec changes
to be implemented with tests for the new API: http://crbug.com/402376

This does not add support for the :fullscreen pseudo-class, which is
tracked by a dedicate issue: http://crbug.com/402378

BUG=383813

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

git-svn-id: svn://svn.chromium.org/blink/trunk@180052 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 6d2c5b83
<!DOCTYPE html>
<title>Document.exitFullscreen()</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../trusted-event.js"></script>
<div id="log"></div>
<script>
async_test(function(t)
{
trusted_request(document.querySelector("div"));
document.addEventListener("fullscreenchange", t.step_func(function()
{
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
assert_equals(event.target, document, "event.target");
assert_false(event.bubbles, "event.bubbles");
assert_false(event.cancelable, "event.cancelable");
t.done();
}
}));
});
</script>
<!DOCTYPE html>
<title>Document.fullscreenElement</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../trusted-event.js"></script>
<div id="log"></div>
<script>
async_test(function(t)
{
var div = document.querySelector("div");
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, div, "fullscreenElement before exitFullscreen()");
document.exitFullscreen();
// FIXME: per spec fullscreenElement should still be div
assert_equals(document.fullscreenElement, null, "fullscreenElement after exitFullscreen()");
document.onfullscreenchange = t.step_func(function()
{
assert_equals(document.fullscreenElement, null, "fullscreenElement after exiting fullscreen");
t.done();
});
});
trusted_event(t.step_func(function()
{
assert_equals(document.fullscreenElement, null, "fullscreenElement before requestFullscreen()");
div.requestFullscreen();
// FIXME: per spec fullscreenElement should still be null
assert_equals(document.fullscreenElement, div, "fullscreenElement after requestFullscreen()");
}), document.body);
});
</script>
<!DOCTYPE html>
<title>Document.fullscreenEnabled</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<iframe></iframe>
<iframe allowfullscreen></iframe>
<script>
test(function()
{
assert_true(document.fullscreenEnabled, "top-level document");
var iframes = document.getElementsByTagName("iframe");
assert_false(iframes[0].contentDocument.fullscreenEnabled, "iframe without allowfullscreen");
assert_true(iframes[1].contentDocument.fullscreenEnabled, "iframe with allowfullscreen");
});
</script>
<!DOCTYPE html>
<title>Document.onfullscreenchange</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../trusted-event.js"></script>
<div id="log"></div>
<script>
async_test(function(t)
{
var div = document.querySelector("div");
assert_equals(document.onfullscreenchange, null, "initial onfullscreenchange");
document.onfullscreenchange = t.step_func_done();
trusted_request(div);
});
</script>
<!DOCTYPE html>
<title>Document.onfullscreenerror</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
async_test(function(t)
{
assert_equals(document.onfullscreenerror, null, "initial onfullscreenerror");
document.onfullscreenerror = t.step_func_done();
document.createElement("a").requestFullscreen();
});
</script>
<!DOCTYPE html>
<title>Element.requestFullscreen()</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../trusted-event.js"></script>
<div id="log"></div>
<script>
async_test(function(t)
{
var div = document.querySelector("div");
document.addEventListener("fullscreenchange", t.step_func(function(event)
{
assert_equals(event.target, document, "event.target");
assert_false(event.bubbles, "event.bubbles");
assert_false(event.cancelable, "event.cancelable");
t.done();
}));
trusted_request(div);
});
</script>
EVENT(webkitfullscreenchange)
EXPECTED (document.fullscreenElement == '[object HTMLDivElement]') OK
EXPECTED (document.webkitFullscreenElement == '[object HTMLDivElement]') OK
EVENT(fullscreenchange)
EXPECTED (document.fullscreenElement == '[object HTMLSpanElement]') OK
EXPECTED (document.webkitFullscreenElement == '[object HTMLSpanElement]') OK
EVENT(fullscreenchange)
EXPECTED (document.fullscreenElement == '[object HTMLDivElement]') OK
EXPECTED (document.webkitFullscreenElement == '[object HTMLDivElement]') OK
EVENT(webkitfullscreenchange)
EXPECTED (document.fullscreenElement == 'null') OK
EXPECTED (document.webkitFullscreenElement == 'null') OK
END OF TEST
<!DOCTYPE html>
<title>Mixed prefixed and unprefixed requests</title>
<script src="full-screen-test.js"></script>
<div><span></span></div>
<script>
var callback;
function fullscreenChanged(event)
{
if (callback)
callback(event)
}
waitForEvent(document, "fullscreenchange", fullscreenChanged);
waitForEvent(document, "webkitfullscreenchange", fullscreenChanged);
var div = document.querySelector("div");
var span = document.querySelector("span");
function divEnteredFullscreen()
{
testExpected("document.fullscreenElement", div);
testExpected("document.webkitFullscreenElement", div);
callback = spanEnteredFullscreen;
runWithKeyDown(function() { span.requestFullscreen(); });
}
function spanEnteredFullscreen()
{
testExpected("document.fullscreenElement", span);
testExpected("document.webkitFullscreenElement", span);
callback = spanExitedFullscreen;
document.webkitExitFullscreen();
}
function spanExitedFullscreen()
{
testExpected("document.fullscreenElement", div);
testExpected("document.webkitFullscreenElement", div);
callback = divExitedFullscreen;
document.webkitExitFullscreen();
}
function divExitedFullscreen()
{
testExpected("document.fullscreenElement", null);
testExpected("document.webkitFullscreenElement", null);
endTest();
}
callback = divEnteredFullscreen;
runWithKeyDown(function() { div.webkitRequestFullscreen(); });
</script>
EVENT(fullscreenchange)
EXPECTED (document.fullscreenElement == '[object HTMLDivElement]') OK
EXPECTED (document.webkitFullscreenElement == '[object HTMLDivElement]') OK
EVENT(webkitfullscreenchange)
EXPECTED (document.fullscreenElement == '[object HTMLSpanElement]') OK
EXPECTED (document.webkitFullscreenElement == '[object HTMLSpanElement]') OK
EVENT(webkitfullscreenchange)
EXPECTED (document.fullscreenElement == '[object HTMLDivElement]') OK
EXPECTED (document.webkitFullscreenElement == '[object HTMLDivElement]') OK
EVENT(fullscreenchange)
EXPECTED (document.fullscreenElement == 'null') OK
EXPECTED (document.webkitFullscreenElement == 'null') OK
END OF TEST
<!DOCTYPE html>
<title>Mixed unprefixed and prefixed requests</title>
<script src="full-screen-test.js"></script>
<div><span></span></div>
<script>
var callback;
function fullscreenChanged(event)
{
if (callback)
callback(event)
}
waitForEvent(document, "fullscreenchange", fullscreenChanged);
waitForEvent(document, "webkitfullscreenchange", fullscreenChanged);
var div = document.querySelector("div");
var span = document.querySelector("span");
function divEnteredFullscreen()
{
testExpected("document.fullscreenElement", div);
testExpected("document.webkitFullscreenElement", div);
callback = spanEnteredFullscreen;
runWithKeyDown(function() { span.webkitRequestFullscreen(); });
}
function spanEnteredFullscreen()
{
testExpected("document.fullscreenElement", span);
testExpected("document.webkitFullscreenElement", span);
callback = spanExitedFullscreen;
document.exitFullscreen();
}
function spanExitedFullscreen()
{
testExpected("document.fullscreenElement", div);
testExpected("document.webkitFullscreenElement", div);
callback = divExitedFullscreen;
document.exitFullscreen();
}
function divExitedFullscreen()
{
testExpected("document.fullscreenElement", null);
testExpected("document.webkitFullscreenElement", null);
endTest();
}
callback = divEnteredFullscreen;
runWithKeyDown(function() { div.requestFullscreen(); });
</script>
// Invokes callback from a trusted event.
// When testing manually, a button is added to the container.
function trusted_event(callback, container)
{
var document = container.ownerDocument;
if (window.testRunner) {
// Running under LayoutTests. Use timeout to be async.
setTimeout(function()
{
document.addEventListener("click", callback);
eventSender.mouseDown();
eventSender.mouseUp();
document.removeEventListener("click", callback);
}, 0);
} else {
// Running as manual test. Show a button to click.
var button = document.createElement("button");
button.textContent = "click to run test";
button.style.fontSize = "20px";
button.style.padding = "10px";
button.onclick = function()
{
callback();
button.onclick = null;
container.removeChild(button);
};
container.appendChild(button);
}
}
// Invokes element.requestFullscreen() from a trusted event.
function trusted_request(element)
{
var request = element.requestFullscreen.bind(element);
trusted_event(request, element.parentNode);
}
...@@ -30,6 +30,23 @@ ...@@ -30,6 +30,23 @@
namespace blink { namespace blink {
bool DocumentFullscreen::fullscreenEnabled(Document& document)
{
return FullscreenElementStack::fullscreenEnabled(document);
}
Element* DocumentFullscreen::fullscreenElement(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->fullscreenElement();
return 0;
}
void DocumentFullscreen::exitFullscreen(Document& document)
{
FullscreenElementStack::from(document).exitFullscreen();
}
bool DocumentFullscreen::webkitIsFullScreen(Document& document) bool DocumentFullscreen::webkitIsFullScreen(Document& document)
{ {
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document)) if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
...@@ -51,21 +68,4 @@ Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document& document) ...@@ -51,21 +68,4 @@ Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document& document)
return 0; return 0;
} }
bool DocumentFullscreen::webkitFullscreenEnabled(Document& document)
{
return FullscreenElementStack::fullscreenEnabled(document);
}
Element* DocumentFullscreen::webkitFullscreenElement(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->fullscreenElement();
return 0;
}
void DocumentFullscreen::webkitExitFullscreen(Document& document)
{
FullscreenElementStack::from(document).exitFullscreen();
}
} // namespace blink } // namespace blink
...@@ -35,14 +35,18 @@ class Element; ...@@ -35,14 +35,18 @@ class Element;
class DocumentFullscreen { class DocumentFullscreen {
public: public:
static bool fullscreenEnabled(Document&);
static Element* fullscreenElement(Document&);
static void exitFullscreen(Document&);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenchange);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenerror);
// Mozilla version
static bool webkitIsFullScreen(Document&); static bool webkitIsFullScreen(Document&);
static bool webkitFullScreenKeyboardInputAllowed(Document&); static bool webkitFullScreenKeyboardInputAllowed(Document&);
static Element* webkitCurrentFullScreenElement(Document&); static Element* webkitCurrentFullScreenElement(Document&);
static bool webkitFullscreenEnabled(Document&);
static Element* webkitFullscreenElement(Document&);
static void webkitExitFullscreen(Document&);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange); DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenchange);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror); DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitfullscreenerror);
}; };
......
...@@ -20,16 +20,24 @@ ...@@ -20,16 +20,24 @@
*/ */
partial interface Document { partial interface Document {
[RuntimeEnabled=FullscreenUnprefixed] readonly attribute boolean fullscreenEnabled;
[RuntimeEnabled=FullscreenUnprefixed] readonly attribute Element? fullscreenElement;
[RuntimeEnabled=FullscreenUnprefixed] void exitFullscreen();
[RuntimeEnabled=FullscreenUnprefixed] attribute EventHandler onfullscreenchange;
[RuntimeEnabled=FullscreenUnprefixed] attribute EventHandler onfullscreenerror;
// Mozilla version // Mozilla version
[MeasureAs=PrefixedDocumentIsFullscreen] readonly attribute boolean webkitIsFullScreen; [MeasureAs=PrefixedDocumentIsFullscreen] readonly attribute boolean webkitIsFullScreen;
[MeasureAs=PrefixedDocumentFullScreenKeyboardInputAllowed] readonly attribute boolean webkitFullScreenKeyboardInputAllowed; [MeasureAs=PrefixedDocumentFullScreenKeyboardInputAllowed] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
[MeasureAs=PrefixedDocumentCurrentFullScreenElement] readonly attribute Element webkitCurrentFullScreenElement; [MeasureAs=PrefixedDocumentCurrentFullScreenElement] readonly attribute Element webkitCurrentFullScreenElement;
[MeasureAs=PrefixedDocumentCancelFullScreen, ImplementedAs=webkitExitFullscreen] void webkitCancelFullScreen(); [MeasureAs=PrefixedDocumentCancelFullScreen, ImplementedAs=exitFullscreen] void webkitCancelFullScreen();
// W3C version // W3C version
[MeasureAs=PrefixedDocumentFullscreenEnabled] readonly attribute boolean webkitFullscreenEnabled; [MeasureAs=PrefixedDocumentFullscreenEnabled, ImplementedAs=fullscreenEnabled] readonly attribute boolean webkitFullscreenEnabled;
[MeasureAs=PrefixedDocumentFullscreenElement] readonly attribute Element webkitFullscreenElement; [MeasureAs=PrefixedDocumentFullscreenElement, ImplementedAs=fullscreenElement] readonly attribute Element webkitFullscreenElement;
[MeasureAs=PrefixedDocumentExitFullscreen] void webkitExitFullscreen(); [MeasureAs=PrefixedDocumentExitFullscreen, ImplementedAs=exitFullscreen] void webkitExitFullscreen();
attribute EventHandler onwebkitfullscreenchange; attribute EventHandler onwebkitfullscreenchange;
attribute EventHandler onwebkitfullscreenerror; attribute EventHandler onwebkitfullscreenerror;
......
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
namespace blink { namespace blink {
void ElementFullscreen::requestFullscreen(Element& element)
{
FullscreenElementStack::from(element.document()).requestFullscreen(element, FullscreenElementStack::UnprefixedRequest);
}
void ElementFullscreen::webkitRequestFullscreen(Element& element) void ElementFullscreen::webkitRequestFullscreen(Element& element)
{ {
FullscreenElementStack::from(element.document()).requestFullscreen(element, FullscreenElementStack::PrefixedRequest); FullscreenElementStack::from(element.document()).requestFullscreen(element, FullscreenElementStack::PrefixedRequest);
......
...@@ -13,6 +13,8 @@ class Element; ...@@ -13,6 +13,8 @@ class Element;
class ElementFullscreen { class ElementFullscreen {
public: public:
static void requestFullscreen(Element&);
// Mozilla version // Mozilla version
static const unsigned short ALLOW_KEYBOARD_INPUT = 1; static const unsigned short ALLOW_KEYBOARD_INPUT = 1;
static void webkitRequestFullScreen(Element&, unsigned short flags); static void webkitRequestFullScreen(Element&, unsigned short flags);
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
partial interface Element { partial interface Element {
[RuntimeEnabled=FullscreenUnprefixed] void requestFullscreen();
// Mozilla version // Mozilla version
const unsigned short ALLOW_KEYBOARD_INPUT = 1; const unsigned short ALLOW_KEYBOARD_INPUT = 1;
[LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags); [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
......
...@@ -71,9 +71,16 @@ static bool fullscreenIsSupported(const Document& document, const Element& eleme ...@@ -71,9 +71,16 @@ static bool fullscreenIsSupported(const Document& document, const Element& eleme
return fullscreenIsSupported(document); 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) static PassRefPtrWillBeRawPtr<Event> createEvent(const AtomicString& type, EventTarget& target)
{ {
RefPtrWillBeRawPtr<Event> event = Event::createBubble(type); EventInit initializer;
initializer.bubbles = isPrefixed(type);
RefPtrWillBeRawPtr<Event> event = Event::create(type, initializer);
event->setTarget(&target); event->setTarget(&target);
return event; return event;
} }
...@@ -257,8 +264,8 @@ void FullscreenElementStack::requestFullscreen(Element& element, RequestType req ...@@ -257,8 +264,8 @@ void FullscreenElementStack::requestFullscreen(Element& element, RequestType req
// stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
// set to true on the document. // set to true on the document.
if (!followingDoc) { if (!followingDoc) {
from(*currentDoc).pushFullscreenElementStack(element); from(*currentDoc).pushFullscreenElementStack(element, requestType);
enqueueChangeEvent(*currentDoc); enqueueChangeEvent(*currentDoc, requestType);
continue; continue;
} }
...@@ -269,8 +276,8 @@ void FullscreenElementStack::requestFullscreen(Element& element, RequestType req ...@@ -269,8 +276,8 @@ void FullscreenElementStack::requestFullscreen(Element& element, RequestType req
// ...push following document's browsing context container on document's fullscreen element // ...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 // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
// set to true on document. // set to true on document.
from(*currentDoc).pushFullscreenElementStack(*followingDoc->ownerElement()); from(*currentDoc).pushFullscreenElementStack(*followingDoc->ownerElement(), requestType);
enqueueChangeEvent(*currentDoc); enqueueChangeEvent(*currentDoc, requestType);
continue; continue;
} }
...@@ -286,7 +293,7 @@ void FullscreenElementStack::requestFullscreen(Element& element, RequestType req ...@@ -286,7 +293,7 @@ void FullscreenElementStack::requestFullscreen(Element& element, RequestType req
return; return;
} while (0); } while (0);
enqueueErrorEvent(element); enqueueErrorEvent(element, requestType);
} }
void FullscreenElementStack::fullyExitFullscreen() void FullscreenElementStack::fullyExitFullscreen()
...@@ -298,9 +305,9 @@ void FullscreenElementStack::fullyExitFullscreen() ...@@ -298,9 +305,9 @@ void FullscreenElementStack::fullyExitFullscreen()
// To achieve that aim, remove all the elements from the top document's stack except for the first before // To achieve that aim, remove all the elements from the top document's stack except for the first before
// calling exitFullscreen(): // calling exitFullscreen():
WillBeHeapVector<RefPtrWillBeMember<Element> > replacementFullscreenElementStack; WillBeHeapVector<std::pair<RefPtrWillBeMember<Element>, RequestType> > replacementFullscreenElementStack;
replacementFullscreenElementStack.append(fullscreenElementFrom(document()->topDocument()));
FullscreenElementStack& topFullscreenElementStack = from(document()->topDocument()); FullscreenElementStack& topFullscreenElementStack = from(document()->topDocument());
replacementFullscreenElementStack.append(topFullscreenElementStack.m_fullScreenElementStack.last());
topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscreenElementStack); topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscreenElementStack);
topFullscreenElementStack.exitFullscreen(); topFullscreenElementStack.exitFullscreen();
} }
...@@ -334,13 +341,16 @@ void FullscreenElementStack::exitFullscreen() ...@@ -334,13 +341,16 @@ void FullscreenElementStack::exitFullscreen()
// task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant. // 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) { for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
ASSERT(*i); ASSERT(*i);
RequestType requestType = from(**i).m_fullScreenElementStack.last().second;
from(**i).clearFullscreenElementStack(); from(**i).clearFullscreenElementStack();
enqueueChangeEvent(**i); enqueueChangeEvent(**i, requestType);
} }
// 5. While doc is not null, run these substeps: // 5. While doc is not null, run these substeps:
Element* newTop = 0; Element* newTop = 0;
while (currentDoc) { while (currentDoc) {
RequestType requestType = from(*currentDoc).m_fullScreenElementStack.last().second;
// 1. Pop the top element of doc's fullscreen element stack. // 1. Pop the top element of doc's fullscreen element stack.
from(*currentDoc).popFullscreenElementStack(); from(*currentDoc).popFullscreenElementStack();
...@@ -352,7 +362,7 @@ void FullscreenElementStack::exitFullscreen() ...@@ -352,7 +362,7 @@ void FullscreenElementStack::exitFullscreen()
// 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
// on doc. // on doc.
enqueueChangeEvent(*currentDoc); enqueueChangeEvent(*currentDoc, requestType);
// 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context // 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. // container, set doc to that browsing context container's node document.
...@@ -504,23 +514,33 @@ void FullscreenElementStack::fullScreenRendererDestroyed() ...@@ -504,23 +514,33 @@ void FullscreenElementStack::fullScreenRendererDestroyed()
m_fullScreenRenderer = nullptr; m_fullScreenRenderer = nullptr;
} }
void FullscreenElementStack::enqueueChangeEvent(Document& document) void FullscreenElementStack::enqueueChangeEvent(Document& document, RequestType requestType)
{ {
ASSERT(document.hasFullscreenElementStack()); RefPtrWillBeRawPtr<Event> event;
FullscreenElementStack& fullscreen = from(document); if (requestType == UnprefixedRequest) {
event = createEvent(EventTypeNames::fullscreenchange, document);
EventTarget* target = fullscreen.fullscreenElement(); } else {
if (!target) ASSERT(document.hasFullscreenElementStack());
target = fullscreen.webkitCurrentFullScreenElement(); FullscreenElementStack& fullscreen = from(document);
if (!target) EventTarget* target = fullscreen.fullscreenElement();
target = &document; if (!target)
m_eventQueue.append(createEvent(EventTypeNames::webkitfullscreenchange, *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. // NOTE: The timer is started in didEnterFullScreenForElement/didExitFullScreenForElement.
} }
void FullscreenElementStack::enqueueErrorEvent(Element& element) void FullscreenElementStack::enqueueErrorEvent(Element& element, RequestType requestType)
{ {
m_eventQueue.append(createEvent(EventTypeNames::webkitfullscreenerror, element)); 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); m_eventQueueTimer.startOneShot(0, FROM_HERE);
} }
...@@ -538,8 +558,10 @@ void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>* ...@@ -538,8 +558,10 @@ void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>*
Node* target = event->target()->toNode(); Node* target = event->target()->toNode();
// If the element was removed from our tree, also message the documentElement. // If the element was removed from our tree, also message the documentElement.
if (!target->inDocument() && document()->documentElement()) if (!target->inDocument() && document()->documentElement()) {
ASSERT(isPrefixed(event->type()));
eventQueue.append(createEvent(event->type(), *document()->documentElement())); eventQueue.append(createEvent(event->type(), *document()->documentElement()));
}
target->dispatchEvent(event); target->dispatchEvent(event);
} }
...@@ -583,9 +605,9 @@ void FullscreenElementStack::popFullscreenElementStack() ...@@ -583,9 +605,9 @@ void FullscreenElementStack::popFullscreenElementStack()
m_fullScreenElementStack.removeLast(); m_fullScreenElementStack.removeLast();
} }
void FullscreenElementStack::pushFullscreenElementStack(Element& element) void FullscreenElementStack::pushFullscreenElementStack(Element& element, RequestType requestType)
{ {
m_fullScreenElementStack.append(&element); m_fullScreenElementStack.append(std::make_pair(&element, requestType));
} }
void FullscreenElementStack::trace(Visitor* visitor) void FullscreenElementStack::trace(Visitor* visitor)
......
...@@ -59,6 +59,7 @@ public: ...@@ -59,6 +59,7 @@ public:
static bool isActiveFullScreenElement(const Element&); static bool isActiveFullScreenElement(const Element&);
enum RequestType { enum RequestType {
UnprefixedRequest, // Element.requestFullscreen()
PrefixedRequest, // Element.webkitRequestFullscreen() PrefixedRequest, // Element.webkitRequestFullscreen()
PrefixedMozillaRequest, // Element.webkitRequestFullScreen() PrefixedMozillaRequest, // Element.webkitRequestFullScreen()
PrefixedMozillaAllowKeyboardInputRequest, // Element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) PrefixedMozillaAllowKeyboardInputRequest, // Element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)
...@@ -70,7 +71,7 @@ public: ...@@ -70,7 +71,7 @@ public:
void exitFullscreen(); void exitFullscreen();
static bool fullscreenEnabled(Document&); static bool fullscreenEnabled(Document&);
Element* fullscreenElement() const { return !m_fullScreenElementStack.isEmpty() ? m_fullScreenElementStack.last().get() : 0; } Element* fullscreenElement() const { return !m_fullScreenElementStack.isEmpty() ? m_fullScreenElementStack.last().first.get() : 0; }
void willEnterFullScreenForElement(Element*); void willEnterFullScreenForElement(Element*);
void didEnterFullScreenForElement(Element*); void didEnterFullScreenForElement(Element*);
...@@ -104,17 +105,17 @@ private: ...@@ -104,17 +105,17 @@ private:
void clearFullscreenElementStack(); void clearFullscreenElementStack();
void popFullscreenElementStack(); void popFullscreenElementStack();
void pushFullscreenElementStack(Element&); void pushFullscreenElementStack(Element&, RequestType);
void enqueueChangeEvent(Document&); void enqueueChangeEvent(Document&, RequestType);
void enqueueErrorEvent(Element&); void enqueueErrorEvent(Element&, RequestType);
void eventQueueTimerFired(Timer<FullscreenElementStack>*); void eventQueueTimerFired(Timer<FullscreenElementStack>*);
void fullScreenElementRemoved(); void fullScreenElementRemoved();
bool m_areKeysEnabledInFullScreen; bool m_areKeysEnabledInFullScreen;
RefPtrWillBeMember<Element> m_fullScreenElement; RefPtrWillBeMember<Element> m_fullScreenElement;
WillBeHeapVector<RefPtrWillBeMember<Element> > m_fullScreenElementStack; WillBeHeapVector<std::pair<RefPtrWillBeMember<Element>, RequestType> > m_fullScreenElementStack;
RawPtrWillBeMember<RenderFullScreen> m_fullScreenRenderer; RawPtrWillBeMember<RenderFullScreen> m_fullScreenRenderer;
Timer<FullscreenElementStack> m_eventQueueTimer; Timer<FullscreenElementStack> m_eventQueueTimer;
WillBeHeapDeque<RefPtrWillBeMember<Event> > m_eventQueue; WillBeHeapDeque<RefPtrWillBeMember<Event> > m_eventQueue;
......
...@@ -85,6 +85,8 @@ finish ...@@ -85,6 +85,8 @@ finish
focus focus
focusin focusin
focusout focusout
fullscreenchange
fullscreenerror
gamepadconnected gamepadconnected
gamepaddisconnected gamepaddisconnected
gesturescrollend gesturescrollend
......
...@@ -65,6 +65,7 @@ FileAPIBlobClose status=experimental ...@@ -65,6 +65,7 @@ FileAPIBlobClose status=experimental
FileConstructor status=stable FileConstructor status=stable
FileSystem status=stable FileSystem status=stable
FontLoadEvents status=stable FontLoadEvents status=stable
FullscreenUnprefixed status=test
Gamepad status=stable Gamepad status=stable
Geofencing status=test Geofencing status=test
GeometryInterfaces status=test GeometryInterfaces status=test
......
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