FullscreenChange.h (5305B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * Struct for holding fullscreen request. 9 */ 10 11 #ifndef mozilla_FullscreenRequest_h 12 #define mozilla_FullscreenRequest_h 13 14 #include "mozilla/LinkedList.h" 15 #include "mozilla/PendingFullscreenEvent.h" 16 #include "mozilla/UniquePtr.h" 17 #include "mozilla/dom/Document.h" 18 #include "mozilla/dom/Element.h" 19 #include "mozilla/dom/Promise.h" 20 #include "nsIScriptError.h" 21 #include "nsRefreshDriver.h" 22 23 namespace mozilla { 24 25 class FullscreenChange : public LinkedListElement<FullscreenChange> { 26 public: 27 FullscreenChange(const FullscreenChange&) = delete; 28 29 enum ChangeType { 30 eEnter, 31 eExit, 32 }; 33 34 ChangeType Type() const { return mType; } 35 dom::Document* Document() const { return mDocument; } 36 dom::Promise* GetPromise() const { return mPromise; } 37 38 void MayResolvePromise() const { 39 if (mPromise) { 40 MOZ_ASSERT(mPromise->State() == Promise::PromiseState::Pending); 41 mPromise->MaybeResolveWithUndefined(); 42 } 43 } 44 45 void MayRejectPromise(const nsACString& aMessage) { 46 if (mPromise) { 47 MOZ_ASSERT(mPromise->State() == Promise::PromiseState::Pending); 48 mPromise->MaybeRejectWithTypeError(aMessage); 49 } 50 } 51 template <int N> 52 void MayRejectPromise(const char (&aMessage)[N]) { 53 MayRejectPromise(nsLiteralCString(aMessage)); 54 } 55 56 protected: 57 typedef dom::Promise Promise; 58 59 FullscreenChange(ChangeType aType, dom::Document* aDocument, 60 already_AddRefed<Promise> aPromise) 61 : mType(aType), mDocument(aDocument), mPromise(aPromise) { 62 MOZ_ASSERT(aDocument); 63 } 64 65 ~FullscreenChange() { 66 MOZ_ASSERT_IF(mPromise, 67 mPromise->State() != Promise::PromiseState::Pending); 68 } 69 70 private: 71 ChangeType mType; 72 nsCOMPtr<dom::Document> mDocument; 73 RefPtr<Promise> mPromise; 74 }; 75 76 class FullscreenRequest : public FullscreenChange { 77 public: 78 static const ChangeType kType = eEnter; 79 80 static UniquePtr<FullscreenRequest> Create(dom::Element* aElement, 81 dom::CallerType aCallerType, 82 ErrorResult& aRv) { 83 RefPtr<Promise> promise = Promise::Create(aElement->GetOwnerGlobal(), aRv); 84 return WrapUnique( 85 new FullscreenRequest(aElement, promise.forget(), aCallerType, true)); 86 } 87 88 static UniquePtr<FullscreenRequest> CreateForRemote(dom::Element* aElement) { 89 return WrapUnique(new FullscreenRequest(aElement, nullptr, 90 dom::CallerType::NonSystem, false)); 91 } 92 93 MOZ_COUNTED_DTOR(FullscreenRequest) 94 95 dom::Element* Element() const { return mElement; } 96 97 // Reject the fullscreen request with the given reason. 98 // It will dispatch the fullscreenerror event. 99 void Reject(const char* aReason) { 100 Document()->AddPendingFullscreenEvent(MakeUnique<PendingFullscreenEvent>( 101 FullscreenEventType::Error, mElement)); 102 MayRejectPromise("Fullscreen request denied"); 103 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns, 104 Document(), nsContentUtils::eDOM_PROPERTIES, 105 aReason); 106 } 107 108 private: 109 RefPtr<dom::Element> mElement; 110 111 public: 112 // This value should be true if the fullscreen request is 113 // originated from system code. 114 const dom::CallerType mCallerType; 115 // This value denotes whether we should trigger a NewOrigin event if 116 // requesting fullscreen in its document causes the origin which is 117 // fullscreen to change. We may want *not* to trigger that event if 118 // we're calling RequestFullscreen() as part of a continuation of a 119 // request in a subdocument in different process, whereupon the caller 120 // need to send some notification itself with the real origin. 121 const bool mShouldNotifyNewOrigin; 122 123 private: 124 FullscreenRequest(dom::Element* aElement, 125 already_AddRefed<dom::Promise> aPromise, 126 dom::CallerType aCallerType, bool aShouldNotifyNewOrigin) 127 : FullscreenChange(kType, aElement->OwnerDoc(), std::move(aPromise)), 128 mElement(aElement), 129 mCallerType(aCallerType), 130 mShouldNotifyNewOrigin(aShouldNotifyNewOrigin) { 131 MOZ_COUNT_CTOR(FullscreenRequest); 132 } 133 }; 134 135 class FullscreenExit : public FullscreenChange { 136 public: 137 static const ChangeType kType = eExit; 138 139 static UniquePtr<FullscreenExit> Create(dom::Document* aDoc, 140 ErrorResult& aRv) { 141 RefPtr<Promise> promise = Promise::Create(aDoc->GetOwnerGlobal(), aRv); 142 return WrapUnique(new FullscreenExit(aDoc, promise.forget())); 143 } 144 145 static UniquePtr<FullscreenExit> CreateForRemote(dom::Document* aDoc) { 146 return WrapUnique(new FullscreenExit(aDoc, nullptr)); 147 } 148 149 MOZ_COUNTED_DTOR(FullscreenExit) 150 151 private: 152 FullscreenExit(dom::Document* aDoc, already_AddRefed<Promise> aPromise) 153 : FullscreenChange(kType, aDoc, std::move(aPromise)) { 154 MOZ_COUNT_CTOR(FullscreenExit); 155 } 156 }; 157 158 } // namespace mozilla 159 160 #endif // mozilla_FullscreenRequest_h