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

Side by Side Diff: Source/core/dom/FullscreenElementStack.cpp

Issue 395633011: Implement the unprefixed the Fullscreen API (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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r ights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r ights reserved.
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
9 * Copyright (C) 2013 Google Inc. All rights reserved. 9 * Copyright (C) 2013 Google Inc. All rights reserved.
10 * 10 *
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 static bool fullscreenIsSupported(const Document& document, const Element& eleme nt) 67 static bool fullscreenIsSupported(const Document& document, const Element& eleme nt)
68 { 68 {
69 if (!document.settings() || (document.settings()->disallowFullscreenForNonMe diaElements() && !isHTMLMediaElement(element))) 69 if (!document.settings() || (document.settings()->disallowFullscreenForNonMe diaElements() && !isHTMLMediaElement(element)))
70 return false; 70 return false;
71 return fullscreenIsSupported(document); 71 return fullscreenIsSupported(document);
72 } 72 }
73 73
74 static PassRefPtrWillBeRawPtr<Event> createEvent(const AtomicString& type, Event Target& target) 74 static PassRefPtrWillBeRawPtr<Event> createEvent(const AtomicString& type, Event Target& target)
75 { 75 {
76 RefPtrWillBeRawPtr<Event> event = Event::createBubble(type); 76 EventInit initializer;
77 // The prefixed events bubble, the unprefixed ones do not.
78 initializer.bubbles = type == EventTypeNames::webkitfullscreenchange || type == EventTypeNames::webkitfullscreenerror;
falken 2014/08/12 03:26:08 This boolean expression appears again later. wdyt
philipj_slow 2014/08/12 08:09:53 Good idea, done!
79 RefPtrWillBeRawPtr<Event> event = Event::create(type, initializer);
77 event->setTarget(&target); 80 event->setTarget(&target);
78 return event; 81 return event;
79 } 82 }
80 83
81 const char* FullscreenElementStack::supplementName() 84 const char* FullscreenElementStack::supplementName()
82 { 85 {
83 return "FullscreenElementStack"; 86 return "FullscreenElementStack";
84 } 87 }
85 88
86 FullscreenElementStack& FullscreenElementStack::from(Document& document) 89 FullscreenElementStack& FullscreenElementStack::from(Document& document)
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 253
251 // 1. Let following document be the document after document in docs, or null if there is no 254 // 1. Let following document be the document after document in docs, or null if there is no
252 // such document. 255 // such document.
253 Document* currentDoc = *current; 256 Document* currentDoc = *current;
254 Document* followingDoc = following != docs.end() ? *following : 0; 257 Document* followingDoc = following != docs.end() ? *following : 0;
255 258
256 // 2. If following document is null, push context object on document 's fullscreen element 259 // 2. If following document is null, push context object on document 's fullscreen element
257 // stack, and queue a task to fire an event named fullscreenchange w ith its bubbles attribute 260 // stack, and queue a task to fire an event named fullscreenchange w ith its bubbles attribute
258 // set to true on the document. 261 // set to true on the document.
259 if (!followingDoc) { 262 if (!followingDoc) {
260 from(*currentDoc).pushFullscreenElementStack(element); 263 from(*currentDoc).pushFullscreenElementStack(element, requestTyp e);
261 enqueueChangeEvent(*currentDoc); 264 enqueueChangeEvent(*currentDoc, requestType);
262 continue; 265 continue;
263 } 266 }
264 267
265 // 3. Otherwise, if document's fullscreen element stack is either em pty or its top element 268 // 3. Otherwise, if document's fullscreen element stack is either em pty or its top element
266 // is not following document's browsing context container, 269 // is not following document's browsing context container,
267 Element* topElement = fullscreenElementFrom(*currentDoc); 270 Element* topElement = fullscreenElementFrom(*currentDoc);
268 if (!topElement || topElement != followingDoc->ownerElement()) { 271 if (!topElement || topElement != followingDoc->ownerElement()) {
269 // ...push following document's browsing context container on do cument's fullscreen element 272 // ...push following document's browsing context container on do cument's fullscreen element
270 // stack, and queue a task to fire an event named fullscreenchan ge with its bubbles attribute 273 // stack, and queue a task to fire an event named fullscreenchan ge with its bubbles attribute
271 // set to true on document. 274 // set to true on document.
272 from(*currentDoc).pushFullscreenElementStack(*followingDoc->owne rElement()); 275 from(*currentDoc).pushFullscreenElementStack(*followingDoc->owne rElement(), requestType);
273 enqueueChangeEvent(*currentDoc); 276 enqueueChangeEvent(*currentDoc, requestType);
274 continue; 277 continue;
275 } 278 }
276 279
277 // 4. Otherwise, do nothing for this document. It stays the same. 280 // 4. Otherwise, do nothing for this document. It stays the same.
278 } while (++current != docs.end()); 281 } while (++current != docs.end());
279 282
280 // 5. Return, and run the remaining steps asynchronously. 283 // 5. Return, and run the remaining steps asynchronously.
281 // 6. Optionally, perform some animation. 284 // 6. Optionally, perform some animation.
282 m_areKeysEnabledInFullScreen = requestType != PrefixedMozillaRequest && requestType != PrefixedVideoRequest; 285 m_areKeysEnabledInFullScreen = requestType != PrefixedMozillaRequest && requestType != PrefixedVideoRequest;
283 document()->frameHost()->chrome().client().enterFullScreenForElement(&el ement); 286 document()->frameHost()->chrome().client().enterFullScreenForElement(&el ement);
284 287
285 // 7. Optionally, display a message indicating how the user can exit dis playing the context object fullscreen. 288 // 7. Optionally, display a message indicating how the user can exit dis playing the context object fullscreen.
286 return; 289 return;
287 } while (0); 290 } while (0);
288 291
289 enqueueErrorEvent(element); 292 enqueueErrorEvent(element, requestType);
290 } 293 }
291 294
292 void FullscreenElementStack::fullyExitFullscreen() 295 void FullscreenElementStack::fullyExitFullscreen()
293 { 296 {
294 // "To fully exit fullscreen act as if the exitFullscreen() method was invok ed on the top-level browsing 297 // "To fully exit fullscreen act as if the exitFullscreen() method was invok ed on the top-level browsing
295 // context's document and subsequently empty that document's fullscreen elem ent stack." 298 // context's document and subsequently empty that document's fullscreen elem ent stack."
296 if (!fullscreenElementFrom(document()->topDocument())) 299 if (!fullscreenElementFrom(document()->topDocument()))
297 return; 300 return;
298 301
299 // To achieve that aim, remove all the elements from the top document's stac k except for the first before 302 // To achieve that aim, remove all the elements from the top document's stac k except for the first before
300 // calling exitFullscreen(): 303 // calling exitFullscreen():
301 WillBeHeapVector<RefPtrWillBeMember<Element> > replacementFullscreenElementS tack; 304 WillBeHeapVector<std::pair<RefPtrWillBeMember<Element>, RequestType> > repla cementFullscreenElementStack;
302 replacementFullscreenElementStack.append(fullscreenElementFrom(document()->t opDocument()));
303 FullscreenElementStack& topFullscreenElementStack = from(document()->topDocu ment()); 305 FullscreenElementStack& topFullscreenElementStack = from(document()->topDocu ment());
306 replacementFullscreenElementStack.append(topFullscreenElementStack.m_fullScr eenElementStack.last());
304 topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscree nElementStack); 307 topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscree nElementStack);
305 topFullscreenElementStack.exitFullscreen(); 308 topFullscreenElementStack.exitFullscreen();
306 } 309 }
307 310
308 void FullscreenElementStack::exitFullscreen() 311 void FullscreenElementStack::exitFullscreen()
309 { 312 {
310 // The exitFullscreen() method must run these steps: 313 // The exitFullscreen() method must run these steps:
311 314
312 // 1. Let doc be the context object. (i.e. "this") 315 // 1. Let doc be the context object. (i.e. "this")
313 Document* currentDoc = document(); 316 Document* currentDoc = document();
(...skipping 13 matching lines...) Expand all
327 continue; 330 continue;
328 ASSERT(toLocalFrame(descendant)->document()); 331 ASSERT(toLocalFrame(descendant)->document());
329 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) 332 if (fullscreenElementFrom(*toLocalFrame(descendant)->document()))
330 descendants.prepend(toLocalFrame(descendant)->document()); 333 descendants.prepend(toLocalFrame(descendant)->document());
331 } 334 }
332 335
333 // 4. For each descendant in descendants, empty descendant's fullscreen elem ent stack, and queue a 336 // 4. For each descendant in descendants, empty descendant's fullscreen elem ent stack, and queue a
334 // task to fire an event named fullscreenchange with its bubbles attribute s et to true on descendant. 337 // task to fire an event named fullscreenchange with its bubbles attribute s et to true on descendant.
335 for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendant s.begin(); i != descendants.end(); ++i) { 338 for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendant s.begin(); i != descendants.end(); ++i) {
336 ASSERT(*i); 339 ASSERT(*i);
340 RequestType requestType = from(**i).m_fullScreenElementStack.last().seco nd;
337 from(**i).clearFullscreenElementStack(); 341 from(**i).clearFullscreenElementStack();
338 enqueueChangeEvent(**i); 342 enqueueChangeEvent(**i, requestType);
339 } 343 }
340 344
341 // 5. While doc is not null, run these substeps: 345 // 5. While doc is not null, run these substeps:
342 Element* newTop = 0; 346 Element* newTop = 0;
343 while (currentDoc) { 347 while (currentDoc) {
348 RequestType requestType = from(*currentDoc).m_fullScreenElementStack.las t().second;
349
344 // 1. Pop the top element of doc's fullscreen element stack. 350 // 1. Pop the top element of doc's fullscreen element stack.
345 from(*currentDoc).popFullscreenElementStack(); 351 from(*currentDoc).popFullscreenElementStack();
346 352
347 // If doc's fullscreen element stack is non-empty and the element now at the top is either 353 // If doc's fullscreen element stack is non-empty and the element now at the top is either
348 // not in a document or its node document is not doc, repeat this sub step. 354 // not in a document or its node document is not doc, repeat this sub step.
349 newTop = fullscreenElementFrom(*currentDoc); 355 newTop = fullscreenElementFrom(*currentDoc);
350 if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc )) 356 if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc ))
351 continue; 357 continue;
352 358
353 // 2. Queue a task to fire an event named fullscreenchange with its bubb les attribute set to true 359 // 2. Queue a task to fire an event named fullscreenchange with its bubb les attribute set to true
354 // on doc. 360 // on doc.
355 enqueueChangeEvent(*currentDoc); 361 enqueueChangeEvent(*currentDoc, requestType);
356 362
357 // 3. If doc's fullscreen element stack is empty and doc's browsing cont ext has a browsing context 363 // 3. If doc's fullscreen element stack is empty and doc's browsing cont ext has a browsing context
358 // container, set doc to that browsing context container's node document . 364 // container, set doc to that browsing context container's node document .
359 if (!newTop && currentDoc->ownerElement()) { 365 if (!newTop && currentDoc->ownerElement()) {
360 currentDoc = &currentDoc->ownerElement()->document(); 366 currentDoc = &currentDoc->ownerElement()->document();
361 continue; 367 continue;
362 } 368 }
363 369
364 // 4. Otherwise, set doc to null. 370 // 4. Otherwise, set doc to null.
365 currentDoc = 0; 371 currentDoc = 0;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 ASSERT(!m_fullScreenRenderer); 503 ASSERT(!m_fullScreenRenderer);
498 504
499 m_fullScreenRenderer = renderer; 505 m_fullScreenRenderer = renderer;
500 } 506 }
501 507
502 void FullscreenElementStack::fullScreenRendererDestroyed() 508 void FullscreenElementStack::fullScreenRendererDestroyed()
503 { 509 {
504 m_fullScreenRenderer = nullptr; 510 m_fullScreenRenderer = nullptr;
505 } 511 }
506 512
507 void FullscreenElementStack::enqueueChangeEvent(Document& document) 513 void FullscreenElementStack::enqueueChangeEvent(Document& document, RequestType requestType)
508 { 514 {
509 ASSERT(document.hasFullscreenElementStack()); 515 RefPtrWillBeRawPtr<Event> event;
510 FullscreenElementStack& fullscreen = from(document); 516 if (requestType == UnprefixedRequest) {
511 517 event = createEvent(EventTypeNames::fullscreenchange, document);
512 EventTarget* target = fullscreen.fullscreenElement(); 518 } else {
513 if (!target) 519 ASSERT(document.hasFullscreenElementStack());
514 target = fullscreen.webkitCurrentFullScreenElement(); 520 FullscreenElementStack& fullscreen = from(document);
515 if (!target) 521 EventTarget* target = fullscreen.fullscreenElement();
516 target = &document; 522 if (!target)
517 m_eventQueue.append(createEvent(EventTypeNames::webkitfullscreenchange, *tar get)); 523 target = fullscreen.webkitCurrentFullScreenElement();
524 if (!target)
525 target = &document;
526 event = createEvent(EventTypeNames::webkitfullscreenchange, *target);
527 }
528 m_eventQueue.append(event);
518 // NOTE: The timer is started in didEnterFullScreenForElement/didExitFullScr eenForElement. 529 // NOTE: The timer is started in didEnterFullScreenForElement/didExitFullScr eenForElement.
519 } 530 }
520 531
521 void FullscreenElementStack::enqueueErrorEvent(Element& element) 532 void FullscreenElementStack::enqueueErrorEvent(Element& element, RequestType req uestType)
522 { 533 {
523 m_eventQueue.append(createEvent(EventTypeNames::webkitfullscreenerror, eleme nt)); 534 RefPtrWillBeRawPtr<Event> event;
535 if (requestType == UnprefixedRequest)
536 event = createEvent(EventTypeNames::fullscreenerror, element.document()) ;
537 else
538 event = createEvent(EventTypeNames::webkitfullscreenerror, element);
539 m_eventQueue.append(event);
524 m_eventQueueTimer.startOneShot(0, FROM_HERE); 540 m_eventQueueTimer.startOneShot(0, FROM_HERE);
525 } 541 }
526 542
527 void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>* ) 543 void FullscreenElementStack::eventQueueTimerFired(Timer<FullscreenElementStack>* )
528 { 544 {
529 // Since we dispatch events in this function, it's possible that the 545 // Since we dispatch events in this function, it's possible that the
530 // document will be detached and GC'd. We protect it here to make sure we 546 // document will be detached and GC'd. We protect it here to make sure we
531 // can finish the function successfully. 547 // can finish the function successfully.
532 RefPtrWillBeRawPtr<Document> protectDocument(document()); 548 RefPtrWillBeRawPtr<Document> protectDocument(document());
533 WillBeHeapDeque<RefPtrWillBeMember<Event> > eventQueue; 549 WillBeHeapDeque<RefPtrWillBeMember<Event> > eventQueue;
534 m_eventQueue.swap(eventQueue); 550 m_eventQueue.swap(eventQueue);
535 551
536 while (!eventQueue.isEmpty()) { 552 while (!eventQueue.isEmpty()) {
537 RefPtrWillBeRawPtr<Event> event = eventQueue.takeFirst(); 553 RefPtrWillBeRawPtr<Event> event = eventQueue.takeFirst();
538 Node* target = event->target()->toNode(); 554 Node* target = event->target()->toNode();
539 555
540 // If the element was removed from our tree, also message the documentEl ement. 556 // If the element was removed from our tree, also message the documentEl ement.
541 if (!target->inDocument() && document()->documentElement()) 557 if (!target->inDocument() && document()->documentElement()) {
558 ASSERT(event->type() == EventTypeNames::webkitfullscreenchange || ev ent->type() == EventTypeNames::webkitfullscreenerror);
542 eventQueue.append(createEvent(event->type(), *document()->documentEl ement())); 559 eventQueue.append(createEvent(event->type(), *document()->documentEl ement()));
560 }
543 561
544 target->dispatchEvent(event); 562 target->dispatchEvent(event);
545 } 563 }
546 } 564 }
547 565
548 void FullscreenElementStack::fullScreenElementRemoved() 566 void FullscreenElementStack::fullScreenElementRemoved()
549 { 567 {
550 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou ndaries(false); 568 m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBou ndaries(false);
551 fullyExitFullscreen(); 569 fullyExitFullscreen();
552 } 570 }
(...skipping 23 matching lines...) Expand all
576 } 594 }
577 595
578 void FullscreenElementStack::popFullscreenElementStack() 596 void FullscreenElementStack::popFullscreenElementStack()
579 { 597 {
580 if (m_fullScreenElementStack.isEmpty()) 598 if (m_fullScreenElementStack.isEmpty())
581 return; 599 return;
582 600
583 m_fullScreenElementStack.removeLast(); 601 m_fullScreenElementStack.removeLast();
584 } 602 }
585 603
586 void FullscreenElementStack::pushFullscreenElementStack(Element& element) 604 void FullscreenElementStack::pushFullscreenElementStack(Element& element, Reques tType requestType)
587 { 605 {
588 m_fullScreenElementStack.append(&element); 606 m_fullScreenElementStack.append(std::make_pair(&element, requestType));
589 } 607 }
590 608
591 void FullscreenElementStack::trace(Visitor* visitor) 609 void FullscreenElementStack::trace(Visitor* visitor)
592 { 610 {
593 visitor->trace(m_fullScreenElement); 611 visitor->trace(m_fullScreenElement);
594 visitor->trace(m_fullScreenElementStack); 612 visitor->trace(m_fullScreenElementStack);
595 visitor->trace(m_fullScreenRenderer); 613 visitor->trace(m_fullScreenRenderer);
596 visitor->trace(m_eventQueue); 614 visitor->trace(m_eventQueue);
597 DocumentSupplement::trace(visitor); 615 DocumentSupplement::trace(visitor);
598 } 616 }
599 617
600 } // namespace blink 618 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698