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

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

Powered by Google App Engine
This is Rietveld 408576698