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 14 matching lines...) Expand all Loading... |
25 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 25 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
26 * Boston, MA 02110-1301, USA. | 26 * Boston, MA 02110-1301, USA. |
27 * | 27 * |
28 */ | 28 */ |
29 | 29 |
30 #include "core/dom/Fullscreen.h" | 30 #include "core/dom/Fullscreen.h" |
31 | 31 |
32 #include "bindings/core/v8/ConditionalFeatures.h" | 32 #include "bindings/core/v8/ConditionalFeatures.h" |
33 #include "core/dom/Document.h" | 33 #include "core/dom/Document.h" |
34 #include "core/dom/ElementTraversal.h" | 34 #include "core/dom/ElementTraversal.h" |
| 35 #include "core/dom/FullscreenCallbacks.h" |
35 #include "core/dom/StyleEngine.h" | 36 #include "core/dom/StyleEngine.h" |
36 #include "core/events/Event.h" | 37 #include "core/events/Event.h" |
37 #include "core/frame/HostsUsingFeatures.h" | 38 #include "core/frame/HostsUsingFeatures.h" |
38 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
39 #include "core/frame/Settings.h" | 40 #include "core/frame/Settings.h" |
40 #include "core/frame/UseCounter.h" | 41 #include "core/frame/UseCounter.h" |
41 #include "core/html/HTMLIFrameElement.h" | 42 #include "core/html/HTMLIFrameElement.h" |
42 #include "core/input/EventHandler.h" | 43 #include "core/input/EventHandler.h" |
43 #include "core/inspector/ConsoleMessage.h" | 44 #include "core/inspector/ConsoleMessage.h" |
44 #include "core/layout/LayoutBlockFlow.h" | 45 #include "core/layout/LayoutBlockFlow.h" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 void Fullscreen::contextDestroyed() { | 307 void Fullscreen::contextDestroyed() { |
307 m_eventQueue.clear(); | 308 m_eventQueue.clear(); |
308 | 309 |
309 if (m_fullScreenLayoutObject) | 310 if (m_fullScreenLayoutObject) |
310 m_fullScreenLayoutObject->destroy(); | 311 m_fullScreenLayoutObject->destroy(); |
311 | 312 |
312 m_currentFullScreenElement = nullptr; | 313 m_currentFullScreenElement = nullptr; |
313 m_fullscreenElementStack.clear(); | 314 m_fullscreenElementStack.clear(); |
314 } | 315 } |
315 | 316 |
| 317 // RequestFullscreenCallbacks hold the data for a pending request. |
| 318 // FullscreenController invokes the success or error callback. |
| 319 class RequestFullscreenCallbacks final : public FullscreenCallbacks { |
| 320 USING_FAST_MALLOC(RequestFullscreenCallbacks); |
| 321 WTF_MAKE_NONCOPYABLE(RequestFullscreenCallbacks); |
| 322 |
| 323 public: |
| 324 static std::unique_ptr<FullscreenCallbacks> |
| 325 create(Document& document, Element& element, Fullscreen::RequestType type) { |
| 326 return wrapUnique(new RequestFullscreenCallbacks(document, element, type)); |
| 327 } |
| 328 |
| 329 void onSuccess() override { |
| 330 Fullscreen::from(*m_document).didEnterFullscreen(*m_element); |
| 331 } |
| 332 |
| 333 void onError() override { |
| 334 Fullscreen::from(*m_document).enqueueErrorEvent(*m_element, m_type); |
| 335 } |
| 336 |
| 337 private: |
| 338 RequestFullscreenCallbacks(Document& document, |
| 339 Element& element, |
| 340 Fullscreen::RequestType type) |
| 341 : m_document(document), m_element(element), m_type(type) {} |
| 342 Persistent<Document> m_document; |
| 343 Persistent<Element> m_element; |
| 344 Fullscreen::RequestType m_type; |
| 345 }; |
| 346 |
316 // https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen | 347 // https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen |
317 void Fullscreen::requestFullscreen(Element& element, | 348 void Fullscreen::requestFullscreen(Element& element, |
318 RequestType requestType, | 349 RequestType requestType, |
319 bool forCrossProcessDescendant) { | 350 bool forCrossProcessDescendant) { |
320 Document& document = element.document(); | 351 Document& document = element.document(); |
321 | 352 |
322 // Use counters only need to be incremented in the process of the actual | 353 // Use counters only need to be incremented in the process of the actual |
323 // fullscreen element. | 354 // fullscreen element. |
324 if (!forCrossProcessDescendant) { | 355 if (!forCrossProcessDescendant) { |
325 if (document.isSecureContext()) { | 356 if (document.isSecureContext()) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 continue; | 456 continue; |
426 } | 457 } |
427 | 458 |
428 // 4. Otherwise, do nothing for this document. It stays the same. | 459 // 4. Otherwise, do nothing for this document. It stays the same. |
429 } while (++current != docs.end()); | 460 } while (++current != docs.end()); |
430 | 461 |
431 from(document).m_forCrossProcessDescendant = forCrossProcessDescendant; | 462 from(document).m_forCrossProcessDescendant = forCrossProcessDescendant; |
432 | 463 |
433 // 5. Return, and run the remaining steps asynchronously. | 464 // 5. Return, and run the remaining steps asynchronously. |
434 // 6. Optionally, perform some animation. | 465 // 6. Optionally, perform some animation. |
435 from(document).m_pendingFullscreenElement = &element; | 466 document.frame()->chromeClient().enterFullscreen( |
436 document.frame()->chromeClient().enterFullscreen(*document.frame()); | 467 *document.frame(), |
| 468 RequestFullscreenCallbacks::create(document, element, requestType)); |
437 | 469 |
438 // 7. Optionally, display a message indicating how the user can exit | 470 // 7. Optionally, display a message indicating how the user can exit |
439 // displaying the context object fullscreen. | 471 // displaying the context object fullscreen. |
440 return; | 472 return; |
441 } while (false); | 473 } while (false); |
442 | 474 |
443 from(document).enqueueErrorEvent(element, requestType); | 475 from(document).enqueueErrorEvent(element, requestType); |
444 } | 476 } |
445 | 477 |
446 // https://fullscreen.spec.whatwg.org/#fully-exit-fullscreen | 478 // https://fullscreen.spec.whatwg.org/#fully-exit-fullscreen |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 // 6. Return, and run the remaining steps asynchronously. | 587 // 6. Return, and run the remaining steps asynchronously. |
556 // 7. Optionally, perform some animation. | 588 // 7. Optionally, perform some animation. |
557 | 589 |
558 // Only exit fullscreen mode if the fullscreen element stack is empty. | 590 // Only exit fullscreen mode if the fullscreen element stack is empty. |
559 if (!newTop) { | 591 if (!newTop) { |
560 document.frame()->chromeClient().exitFullscreen(*document.frame()); | 592 document.frame()->chromeClient().exitFullscreen(*document.frame()); |
561 return; | 593 return; |
562 } | 594 } |
563 | 595 |
564 // Otherwise, enter fullscreen for the fullscreen element stack's top element. | 596 // Otherwise, enter fullscreen for the fullscreen element stack's top element. |
565 from(document).m_pendingFullscreenElement = newTop; | 597 from(document).didEnterFullscreen(*newTop); |
566 from(document).didEnterFullscreen(); | |
567 } | 598 } |
568 | 599 |
569 // https://fullscreen.spec.whatwg.org/#dom-document-fullscreenenabled | 600 // https://fullscreen.spec.whatwg.org/#dom-document-fullscreenenabled |
570 bool Fullscreen::fullscreenEnabled(Document& document) { | 601 bool Fullscreen::fullscreenEnabled(Document& document) { |
571 // The fullscreenEnabled attribute's getter must return true if the context | 602 // The fullscreenEnabled attribute's getter must return true if the context |
572 // object is allowed to use the feature indicated by attribute name | 603 // object is allowed to use the feature indicated by attribute name |
573 // allowfullscreen and fullscreen is supported, and false otherwise. | 604 // allowfullscreen and fullscreen is supported, and false otherwise. |
574 return allowedToUseFullscreen(document.frame()) && | 605 return allowedToUseFullscreen(document.frame()) && |
575 fullscreenIsSupported(document); | 606 fullscreenIsSupported(document); |
576 } | 607 } |
577 | 608 |
578 void Fullscreen::didEnterFullscreen() { | 609 void Fullscreen::didEnterFullscreen(Element& element) { |
579 if (!document()->isActive() || !document()->frame()) | 610 if (!document() || !document()->isActive() || !document()->frame()) |
580 return; | 611 return; |
581 | 612 |
582 // Start the timer for events enqueued by |requestFullscreen()|. The hover | 613 // Start the timer for events enqueued by |requestFullscreen()|. The hover |
583 // state update is scheduled first so that it's done when the events fire. | 614 // state update is scheduled first so that it's done when the events fire. |
584 document()->frame()->eventHandler().scheduleHoverStateUpdate(); | 615 document()->frame()->eventHandler().scheduleHoverStateUpdate(); |
585 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); | 616 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); |
586 | 617 |
587 Element* element = m_pendingFullscreenElement.release(); | 618 if (m_currentFullScreenElement == &element) |
588 if (!element) | |
589 return; | 619 return; |
590 | 620 |
591 if (m_currentFullScreenElement == element) | 621 if (!element.isConnected() || &element.document() != document()) { |
592 return; | |
593 | |
594 if (!element->isConnected() || &element->document() != document()) { | |
595 // The element was removed or has moved to another document since the | 622 // The element was removed or has moved to another document since the |
596 // |requestFullscreen()| call. Exit fullscreen again to recover. | 623 // |requestFullscreen()| call. Exit fullscreen again to recover. |
597 // TODO(foolip): Fire a fullscreenerror event. This is currently difficult | 624 // TODO(foolip): Fire a fullscreenerror event. This is currently difficult |
598 // because the fullscreenchange event has already been enqueued and possibly | 625 // because the fullscreenchange event has already been enqueued and possibly |
599 // even fired. https://crbug.com/402376 | 626 // even fired. https://crbug.com/402376 |
600 LocalFrame& frame = *document()->frame(); | 627 LocalFrame& frame = *document()->frame(); |
601 frame.chromeClient().exitFullscreen(frame); | 628 frame.chromeClient().exitFullscreen(frame); |
602 return; | 629 return; |
603 } | 630 } |
604 | 631 |
| 632 if (m_currentFullScreenElement == &element) |
| 633 return; |
| 634 |
605 if (m_fullScreenLayoutObject) | 635 if (m_fullScreenLayoutObject) |
606 m_fullScreenLayoutObject->unwrapLayoutObject(); | 636 m_fullScreenLayoutObject->unwrapLayoutObject(); |
607 | 637 |
608 Element* previousElement = m_currentFullScreenElement; | 638 Element* previousElement = m_currentFullScreenElement; |
609 m_currentFullScreenElement = element; | 639 m_currentFullScreenElement = &element; |
610 | 640 |
611 // Create a placeholder block for a the full-screen element, to keep the page | 641 // Create a placeholder block for a the full-screen element, to keep the page |
612 // from reflowing when the element is removed from the normal flow. Only do | 642 // from reflowing when the element is removed from the normal flow. Only do |
613 // this for a LayoutBox, as only a box will have a frameRect. The placeholder | 643 // this for a LayoutBox, as only a box will have a frameRect. The placeholder |
614 // will be created in setFullScreenLayoutObject() during layout. | 644 // will be created in setFullScreenLayoutObject() during layout. |
615 LayoutObject* layoutObject = m_currentFullScreenElement->layoutObject(); | 645 LayoutObject* layoutObject = m_currentFullScreenElement->layoutObject(); |
616 bool shouldCreatePlaceholder = layoutObject && layoutObject->isBox(); | 646 bool shouldCreatePlaceholder = layoutObject && layoutObject->isBox(); |
617 if (shouldCreatePlaceholder) { | 647 if (shouldCreatePlaceholder) { |
618 m_savedPlaceholderFrameRect = toLayoutBox(layoutObject)->frameRect(); | 648 m_savedPlaceholderFrameRect = toLayoutBox(layoutObject)->frameRect(); |
619 m_savedPlaceholderComputedStyle = | 649 m_savedPlaceholderComputedStyle = |
(...skipping 23 matching lines...) Expand all Loading... |
643 m_currentFullScreenElement | 673 m_currentFullScreenElement |
644 ->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true); | 674 ->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true); |
645 | 675 |
646 document()->styleEngine().ensureUAStyleForFullscreen(); | 676 document()->styleEngine().ensureUAStyleForFullscreen(); |
647 m_currentFullScreenElement->pseudoStateChanged(CSSSelector::PseudoFullScreen); | 677 m_currentFullScreenElement->pseudoStateChanged(CSSSelector::PseudoFullScreen); |
648 | 678 |
649 // FIXME: This should not call updateStyleAndLayoutTree. | 679 // FIXME: This should not call updateStyleAndLayoutTree. |
650 document()->updateStyleAndLayoutTree(); | 680 document()->updateStyleAndLayoutTree(); |
651 | 681 |
652 document()->frame()->chromeClient().fullscreenElementChanged(previousElement, | 682 document()->frame()->chromeClient().fullscreenElementChanged(previousElement, |
653 element); | 683 &element); |
654 } | 684 } |
655 | 685 |
656 void Fullscreen::didExitFullscreen() { | 686 void Fullscreen::didExitFullscreen() { |
657 if (!document()->isActive() || !document()->frame()) | 687 if (!document() || !document()->isActive() || !document()->frame()) |
658 return; | 688 return; |
659 | 689 |
660 // Start the timer for events enqueued by |exitFullscreen()|. The hover state | 690 // Start the timer for events enqueued by |exitFullscreen()|. The hover state |
661 // update is scheduled first so that it's done when the events fire. | 691 // update is scheduled first so that it's done when the events fire. |
662 document()->frame()->eventHandler().scheduleHoverStateUpdate(); | 692 document()->frame()->eventHandler().scheduleHoverStateUpdate(); |
663 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); | 693 m_eventQueueTimer.startOneShot(0, BLINK_FROM_HERE); |
664 | 694 |
665 // If fullscreen was canceled by the browser, e.g. if the user pressed Esc, | 695 // If fullscreen was canceled by the browser, e.g. if the user pressed Esc, |
666 // then |exitFullscreen()| was never called. Let |fullyExitFullscreen()| clear | 696 // then |exitFullscreen()| was never called. Let |fullyExitFullscreen()| clear |
667 // the fullscreen element stack and fire any events as necessary. | 697 // the fullscreen element stack and fire any events as necessary. |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 | 830 |
801 m_fullscreenElementStack.pop_back(); | 831 m_fullscreenElementStack.pop_back(); |
802 } | 832 } |
803 | 833 |
804 void Fullscreen::pushFullscreenElementStack(Element& element, | 834 void Fullscreen::pushFullscreenElementStack(Element& element, |
805 RequestType requestType) { | 835 RequestType requestType) { |
806 m_fullscreenElementStack.append(std::make_pair(&element, requestType)); | 836 m_fullscreenElementStack.append(std::make_pair(&element, requestType)); |
807 } | 837 } |
808 | 838 |
809 DEFINE_TRACE(Fullscreen) { | 839 DEFINE_TRACE(Fullscreen) { |
810 visitor->trace(m_pendingFullscreenElement); | |
811 visitor->trace(m_fullscreenElementStack); | 840 visitor->trace(m_fullscreenElementStack); |
812 visitor->trace(m_currentFullScreenElement); | 841 visitor->trace(m_currentFullScreenElement); |
813 visitor->trace(m_eventQueue); | 842 visitor->trace(m_eventQueue); |
814 Supplement<Document>::trace(visitor); | 843 Supplement<Document>::trace(visitor); |
815 ContextLifecycleObserver::trace(visitor); | 844 ContextLifecycleObserver::trace(visitor); |
816 } | 845 } |
817 | 846 |
818 } // namespace blink | 847 } // namespace blink |
OLD | NEW |