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 | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All |
| 7 * rights reserved. | 7 * rights reserved. |
| 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
| 10 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 10 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 #include "core/html/HTMLIFrameElement.h" | 41 #include "core/html/HTMLIFrameElement.h" |
| 42 #include "core/input/EventHandler.h" | 42 #include "core/input/EventHandler.h" |
| 43 #include "core/inspector/ConsoleMessage.h" | 43 #include "core/inspector/ConsoleMessage.h" |
| 44 #include "core/layout/LayoutBlockFlow.h" | 44 #include "core/layout/LayoutBlockFlow.h" |
| 45 #include "core/layout/LayoutFullScreen.h" | 45 #include "core/layout/LayoutFullScreen.h" |
| 46 #include "core/layout/api/LayoutFullScreenItem.h" | 46 #include "core/layout/api/LayoutFullScreenItem.h" |
| 47 #include "core/page/ChromeClient.h" | 47 #include "core/page/ChromeClient.h" |
| 48 #include "core/svg/SVGSVGElement.h" | 48 #include "core/svg/SVGSVGElement.h" |
| 49 #include "platform/ScopedOrientationChangeIndicator.h" | 49 #include "platform/ScopedOrientationChangeIndicator.h" |
| 50 #include "platform/UserGestureIndicator.h" | 50 #include "platform/UserGestureIndicator.h" |
| 51 #include "public/platform/WebFullscreenCallbacks.h" | |
| 51 | 52 |
| 52 namespace blink { | 53 namespace blink { |
| 53 | 54 |
| 54 namespace { | 55 namespace { |
| 55 | 56 |
| 56 // https://html.spec.whatwg.org/multipage/embedded-content.html#allowed-to-use | 57 // https://html.spec.whatwg.org/multipage/embedded-content.html#allowed-to-use |
| 57 bool allowedToUseFullscreen(const Frame* frame) { | 58 bool allowedToUseFullscreen(const Frame* frame) { |
| 58 // To determine whether a Document object |document| is allowed to use the | 59 // To determine whether a Document object |document| is allowed to use the |
| 59 // feature indicated by attribute name |allowattribute|, run these steps: | 60 // feature indicated by attribute name |allowattribute|, run these steps: |
| 60 | 61 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 // works even in OOPIF scenarios like A-B-A, where there may be remote frames | 180 // works even in OOPIF scenarios like A-B-A, where there may be remote frames |
| 180 // in between |doc| and |descendant|. | 181 // in between |doc| and |descendant|. |
| 181 HTMLFrameOwnerElement* findContainerForDescendant(const Document& doc, | 182 HTMLFrameOwnerElement* findContainerForDescendant(const Document& doc, |
| 182 const Document& descendant) { | 183 const Document& descendant) { |
| 183 Frame* frame = descendant.frame(); | 184 Frame* frame = descendant.frame(); |
| 184 while (frame->tree().parent() != doc.frame()) | 185 while (frame->tree().parent() != doc.frame()) |
| 185 frame = frame->tree().parent(); | 186 frame = frame->tree().parent(); |
| 186 return toHTMLFrameOwnerElement(frame->owner()); | 187 return toHTMLFrameOwnerElement(frame->owner()); |
| 187 } | 188 } |
| 188 | 189 |
| 190 class FullscreenCallbacks final : public WebFullscreenCallbacks { | |
| 191 // FIXME(tasak): When making public/platform classes to use PartitionAlloc, | |
| 192 // the following macro should be moved to WebCallbacks defined in | |
| 193 // public/platform/WebCallbacks.h. | |
| 194 USING_FAST_MALLOC(FullscreenCallbacks); | |
| 195 WTF_MAKE_NONCOPYABLE(FullscreenCallbacks); | |
| 196 | |
| 197 public: | |
| 198 FullscreenCallbacks(std::unique_ptr<WTF::Closure> success, | |
| 199 std::unique_ptr<WTF::Closure> error) | |
| 200 : m_success(std::move(success)), m_error(std::move(error)) {} | |
| 201 void onSuccess() override { (*m_success)(); } | |
| 202 void onError() override { (*m_error)(); } | |
| 203 | |
| 204 private: | |
| 205 std::unique_ptr<WTF::Closure> m_success; | |
| 206 std::unique_ptr<WTF::Closure> m_error; | |
| 207 }; | |
| 208 | |
| 189 } // anonymous namespace | 209 } // anonymous namespace |
| 190 | 210 |
| 191 const char* Fullscreen::supplementName() { | 211 const char* Fullscreen::supplementName() { |
| 192 return "Fullscreen"; | 212 return "Fullscreen"; |
| 193 } | 213 } |
| 194 | 214 |
| 195 Fullscreen& Fullscreen::from(Document& document) { | 215 Fullscreen& Fullscreen::from(Document& document) { |
| 196 Fullscreen* fullscreen = fromIfExists(document); | 216 Fullscreen* fullscreen = fromIfExists(document); |
| 197 if (!fullscreen) { | 217 if (!fullscreen) { |
| 198 fullscreen = new Fullscreen(document); | 218 fullscreen = new Fullscreen(document); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 if (!forCrossProcessDescendant) { | 311 if (!forCrossProcessDescendant) { |
| 292 if (document.isSecureContext()) { | 312 if (document.isSecureContext()) { |
| 293 UseCounter::count(document, UseCounter::FullscreenSecureOrigin); | 313 UseCounter::count(document, UseCounter::FullscreenSecureOrigin); |
| 294 } else { | 314 } else { |
| 295 UseCounter::count(document, UseCounter::FullscreenInsecureOrigin); | 315 UseCounter::count(document, UseCounter::FullscreenInsecureOrigin); |
| 296 HostsUsingFeatures::countAnyWorld( | 316 HostsUsingFeatures::countAnyWorld( |
| 297 document, HostsUsingFeatures::Feature::FullscreenInsecureHost); | 317 document, HostsUsingFeatures::Feature::FullscreenInsecureHost); |
| 298 } | 318 } |
| 299 } | 319 } |
| 300 | 320 |
| 301 // Ignore this request if the document is not in a live frame. | 321 // Ignore this call if the document is not in a live frame. |
| 302 if (!document.isActive()) | 322 if (!document.isActive() || !document.frame()) |
| 303 return; | 323 return; |
| 304 | 324 |
| 305 // If |element| is on top of |doc|'s fullscreen element stack, terminate these | 325 // If |element| is on top of |doc|'s fullscreen element stack, terminate these |
| 306 // substeps. | 326 // substeps. |
| 307 if (&element == fullscreenElementFrom(document)) | 327 if (&element == fullscreenElementFrom(document)) |
| 308 return; | 328 return; |
| 309 | 329 |
| 310 do { | 330 do { |
| 311 // 1. If any of the following conditions are false, then terminate these | 331 // 1. If any of the following conditions are false, then terminate these |
| 312 // steps and queue a task to fire an event named fullscreenerror with its | 332 // steps and queue a task to fire an event named fullscreenerror with its |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 continue; | 412 continue; |
| 393 } | 413 } |
| 394 | 414 |
| 395 // 4. Otherwise, do nothing for this document. It stays the same. | 415 // 4. Otherwise, do nothing for this document. It stays the same. |
| 396 } while (++current != docs.end()); | 416 } while (++current != docs.end()); |
| 397 | 417 |
| 398 from(document).m_forCrossProcessDescendant = forCrossProcessDescendant; | 418 from(document).m_forCrossProcessDescendant = forCrossProcessDescendant; |
| 399 | 419 |
| 400 // 5. Return, and run the remaining steps asynchronously. | 420 // 5. Return, and run the remaining steps asynchronously. |
| 401 // 6. Optionally, perform some animation. | 421 // 6. Optionally, perform some animation. |
| 402 document.frameHost()->chromeClient().enterFullscreenForElement(&element); | 422 document.frameHost()->chromeClient().enterFullscreen( |
| 423 *document.frame(), | |
| 424 wrapUnique(new FullscreenCallbacks( | |
|
mlamouri (slow - plz ping)
2016/11/30 09:24:57
Any particular reason why not keepinp track of `do
foolip
2016/11/30 10:23:52
This is a wart from before when I was using callba
| |
| 425 WTF::bind(&Fullscreen::didEnterFullscreenForElement, | |
| 426 wrapPersistent(&from(document)), | |
| 427 wrapPersistent(&element)), | |
| 428 WTF::bind(&Fullscreen::enqueueErrorEvent, | |
| 429 wrapPersistent(&from(document)), wrapPersistent(&element), | |
| 430 requestType)))); | |
| 403 | 431 |
| 404 // 7. Optionally, display a message indicating how the user can exit | 432 // 7. Optionally, display a message indicating how the user can exit |
| 405 // displaying the context object fullscreen. | 433 // displaying the context object fullscreen. |
| 406 return; | 434 return; |
| 407 } while (false); | 435 } while (false); |
| 408 | 436 |
| 409 from(document).enqueueErrorEvent(element, requestType); | 437 from(document).enqueueErrorEvent(&element, requestType); |
| 410 } | 438 } |
| 411 | 439 |
| 412 // https://fullscreen.spec.whatwg.org/#fully-exit-fullscreen | 440 // https://fullscreen.spec.whatwg.org/#fully-exit-fullscreen |
| 413 void Fullscreen::fullyExitFullscreen(Document& document) { | 441 void Fullscreen::fullyExitFullscreen(Document& document) { |
| 414 // To fully exit fullscreen, run these steps: | 442 // To fully exit fullscreen, run these steps: |
| 415 | 443 |
| 416 // 1. Let |doc| be the top-level browsing context's document. | 444 // 1. Let |doc| be the top-level browsing context's document. |
| 417 // | 445 // |
| 418 // Since the top-level browsing context's document might be unavailable in | 446 // Since the top-level browsing context's document might be unavailable in |
| 419 // OOPIF scenarios (i.e., when the top frame is remote), this actually uses | 447 // OOPIF scenarios (i.e., when the top frame is remote), this actually uses |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 434 DCHECK_EQ(from(doc).m_fullscreenElementStack.size(), 1u); | 462 DCHECK_EQ(from(doc).m_fullscreenElementStack.size(), 1u); |
| 435 | 463 |
| 436 // 4. Act as if the exitFullscreen() method was invoked on |doc|. | 464 // 4. Act as if the exitFullscreen() method was invoked on |doc|. |
| 437 exitFullscreen(doc); | 465 exitFullscreen(doc); |
| 438 } | 466 } |
| 439 | 467 |
| 440 // https://fullscreen.spec.whatwg.org/#exit-fullscreen | 468 // https://fullscreen.spec.whatwg.org/#exit-fullscreen |
| 441 void Fullscreen::exitFullscreen(Document& document) { | 469 void Fullscreen::exitFullscreen(Document& document) { |
| 442 // The exitFullscreen() method must run these steps: | 470 // The exitFullscreen() method must run these steps: |
| 443 | 471 |
| 444 // 1. Let doc be the context object. (i.e. "this") | 472 // Ignore this call if the document is not in a live frame. |
| 445 if (!document.isActive()) | 473 if (!document.isActive() || !document.frame()) |
| 446 return; | 474 return; |
| 447 | 475 |
| 476 // 1. Let doc be the context object. (i.e. "this") | |
| 448 // 2. If doc's fullscreen element stack is empty, terminate these steps. | 477 // 2. If doc's fullscreen element stack is empty, terminate these steps. |
| 449 if (!fullscreenElementFrom(document)) | 478 if (!fullscreenElementFrom(document)) |
| 450 return; | 479 return; |
| 451 | 480 |
| 452 // 3. Let descendants be all the doc's descendant browsing context's documents | 481 // 3. Let descendants be all the doc's descendant browsing context's documents |
| 453 // with a non-empty fullscreen element stack (if any), ordered so that the | 482 // with a non-empty fullscreen element stack (if any), ordered so that the |
| 454 // child of the doc is last and the document furthest away from the doc is | 483 // child of the doc is last and the document furthest away from the doc is |
| 455 // first. | 484 // first. |
| 456 HeapDeque<Member<Document>> descendants; | 485 HeapDeque<Member<Document>> descendants; |
| 457 for (Frame* descendant = | 486 for (Frame* descendant = document.frame()->tree().traverseNext(); descendant; |
| 458 document.frame() ? document.frame()->tree().traverseNext() : nullptr; | 487 descendant = descendant->tree().traverseNext()) { |
| 459 descendant; descendant = descendant->tree().traverseNext()) { | |
| 460 if (!descendant->isLocalFrame()) | 488 if (!descendant->isLocalFrame()) |
| 461 continue; | 489 continue; |
| 462 DCHECK(toLocalFrame(descendant)->document()); | 490 DCHECK(toLocalFrame(descendant)->document()); |
| 463 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) | 491 if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) |
| 464 descendants.prepend(toLocalFrame(descendant)->document()); | 492 descendants.prepend(toLocalFrame(descendant)->document()); |
| 465 } | 493 } |
| 466 | 494 |
| 467 // 4. For each descendant in descendants, empty descendant's fullscreen | 495 // 4. For each descendant in descendants, empty descendant's fullscreen |
| 468 // element stack, and queue a task to fire an event named fullscreenchange | 496 // element stack, and queue a task to fire an event named fullscreenchange |
| 469 // with its bubbles attribute set to true on descendant. | 497 // with its bubbles attribute set to true on descendant. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 // 7. Optionally, perform some animation. | 550 // 7. Optionally, perform some animation. |
| 523 | 551 |
| 524 FrameHost* host = document.frameHost(); | 552 FrameHost* host = document.frameHost(); |
| 525 | 553 |
| 526 // Speculative fix for engaget.com/videos per crbug.com/336239. | 554 // Speculative fix for engaget.com/videos per crbug.com/336239. |
| 527 // FIXME: This check is wrong. We DCHECK(document->isActive()) above | 555 // FIXME: This check is wrong. We DCHECK(document->isActive()) above |
| 528 // so this should be redundant and should be removed! | 556 // so this should be redundant and should be removed! |
| 529 if (!host) | 557 if (!host) |
| 530 return; | 558 return; |
| 531 | 559 |
| 532 // Only exit out of full screen window mode if there are no remaining elements | 560 // Only exit fullscreen mode if the fullscreen element stack is empty. |
| 533 // in the full screen stack. | |
| 534 if (!newTop) { | 561 if (!newTop) { |
| 535 host->chromeClient().exitFullscreen(document.frame()); | 562 host->chromeClient().exitFullscreen(*document.frame()); |
| 536 return; | 563 return; |
| 537 } | 564 } |
| 538 | 565 |
| 539 // Otherwise, notify the chrome of the new full screen element. | 566 // Otherwise, enter fullscreen for the fullscreen element stack's top element. |
| 540 host->chromeClient().enterFullscreenForElement(newTop); | 567 from(document).didEnterFullscreenForElement(newTop); |
| 541 } | 568 } |
| 542 | 569 |
| 543 // https://fullscreen.spec.whatwg.org/#dom-document-fullscreenenabled | 570 // https://fullscreen.spec.whatwg.org/#dom-document-fullscreenenabled |
| 544 bool Fullscreen::fullscreenEnabled(Document& document) { | 571 bool Fullscreen::fullscreenEnabled(Document& document) { |
| 545 // The fullscreenEnabled attribute's getter must return true if the context | 572 // The fullscreenEnabled attribute's getter must return true if the context |
| 546 // object is allowed to use the feature indicated by attribute name | 573 // object is allowed to use the feature indicated by attribute name |
| 547 // allowfullscreen and fullscreen is supported, and false otherwise. | 574 // allowfullscreen and fullscreen is supported, and false otherwise. |
| 548 return allowedToUseFullscreen(document.frame()) && | 575 return allowedToUseFullscreen(document.frame()) && |
| 549 fullscreenIsSupported(document); | 576 fullscreenIsSupported(document); |
| 550 } | 577 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 element); | 636 element); |
| 610 } | 637 } |
| 611 | 638 |
| 612 void Fullscreen::didExitFullscreen() { | 639 void Fullscreen::didExitFullscreen() { |
| 613 if (!document()->isActive() || !document()->frame()) | 640 if (!document()->isActive() || !document()->frame()) |
| 614 return; | 641 return; |
| 615 | 642 |
| 616 if (!m_currentFullScreenElement) | 643 if (!m_currentFullScreenElement) |
| 617 return; | 644 return; |
| 618 | 645 |
| 646 // If fullscreen was canceled by the browser, e.g. if the user pressed Esc, | |
| 647 // then |exitFullscreen()| was never called. Let |fullyExitFullscreen()| clear | |
| 648 // the fullscreen element stack and fire any events as necessary. | |
| 649 // TODO(foolip): Remove this when state changes and events are synchronized | |
| 650 // with animation frames. https://crbug.com/402376 | |
| 651 fullyExitFullscreen(*document()); | |
| 652 | |
| 619 if (m_forCrossProcessDescendant) | 653 if (m_forCrossProcessDescendant) |
| 620 m_currentFullScreenElement->setContainsFullScreenElement(false); | 654 m_currentFullScreenElement->setContainsFullScreenElement(false); |
| 621 | 655 |
| 622 m_currentFullScreenElement | 656 m_currentFullScreenElement |
| 623 ->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false); | 657 ->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false); |
| 624 | 658 |
| 625 if (m_fullScreenLayoutObject) | 659 if (m_fullScreenLayoutObject) |
| 626 LayoutFullScreenItem(m_fullScreenLayoutObject).unwrapLayoutObject(); | 660 LayoutFullScreenItem(m_fullScreenLayoutObject).unwrapLayoutObject(); |
| 627 | 661 |
| 628 document()->styleEngine().ensureUAStyleForFullscreen(); | 662 document()->styleEngine().ensureUAStyleForFullscreen(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 686 target = fullscreen.currentFullScreenElement(); | 720 target = fullscreen.currentFullScreenElement(); |
| 687 if (!target) | 721 if (!target) |
| 688 target = &document; | 722 target = &document; |
| 689 event = createEvent(EventTypeNames::webkitfullscreenchange, *target); | 723 event = createEvent(EventTypeNames::webkitfullscreenchange, *target); |
| 690 } | 724 } |
| 691 m_eventQueue.append(event); | 725 m_eventQueue.append(event); |
| 692 // NOTE: The timer is started in | 726 // NOTE: The timer is started in |
| 693 // didEnterFullscreenForElement/didExitFullscreen. | 727 // didEnterFullscreenForElement/didExitFullscreen. |
| 694 } | 728 } |
| 695 | 729 |
| 696 void Fullscreen::enqueueErrorEvent(Element& element, RequestType requestType) { | 730 void Fullscreen::enqueueErrorEvent(Element* element, RequestType requestType) { |
| 731 DCHECK(element); | |
| 732 | |
| 697 Event* event; | 733 Event* event; |
| 698 if (requestType == UnprefixedRequest) | 734 if (requestType == UnprefixedRequest) |
| 699 event = createEvent(EventTypeNames::fullscreenerror, element.document()); | 735 event = createEvent(EventTypeNames::fullscreenerror, element->document()); |
| 700 else | 736 else |
| 701 event = createEvent(EventTypeNames::webkitfullscreenerror, element); | 737 event = createEvent(EventTypeNames::webkitfullscreenerror, *element); |
| 702 m_eventQueue.append(event); | 738 m_eventQueue.append(event); |
| 703 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); | 739 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); |
| 704 } | 740 } |
| 705 | 741 |
| 706 void Fullscreen::eventQueueTimerFired(TimerBase*) { | 742 void Fullscreen::eventQueueTimerFired(TimerBase*) { |
| 707 HeapDeque<Member<Event>> eventQueue; | 743 HeapDeque<Member<Event>> eventQueue; |
| 708 m_eventQueue.swap(eventQueue); | 744 m_eventQueue.swap(eventQueue); |
| 709 | 745 |
| 710 while (!eventQueue.isEmpty()) { | 746 while (!eventQueue.isEmpty()) { |
| 711 Event* event = eventQueue.takeFirst(); | 747 Event* event = eventQueue.takeFirst(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 | 800 |
| 765 DEFINE_TRACE(Fullscreen) { | 801 DEFINE_TRACE(Fullscreen) { |
| 766 visitor->trace(m_currentFullScreenElement); | 802 visitor->trace(m_currentFullScreenElement); |
| 767 visitor->trace(m_fullscreenElementStack); | 803 visitor->trace(m_fullscreenElementStack); |
| 768 visitor->trace(m_eventQueue); | 804 visitor->trace(m_eventQueue); |
| 769 Supplement<Document>::trace(visitor); | 805 Supplement<Document>::trace(visitor); |
| 770 ContextLifecycleObserver::trace(visitor); | 806 ContextLifecycleObserver::trace(visitor); |
| 771 } | 807 } |
| 772 | 808 |
| 773 } // namespace blink | 809 } // namespace blink |
| OLD | NEW |