Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 = ¤tDoc->ownerElement()->document(); | 366 currentDoc = ¤tDoc->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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |