1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsBaseClipboard_h__
7 #define nsBaseClipboard_h__
9 #include "mozilla/dom/PContent.h"
10 #include "mozilla/Logging.h"
11 #include "mozilla/MoveOnlyFunction.h"
12 #include "mozilla/Result.h"
13 #include "nsIClipboard.h"
14 #include "nsITransferable.h"
17 static mozilla::LazyLogModule
sWidgetClipboardLog("WidgetClipboard");
18 #define MOZ_CLIPBOARD_LOG(...) \
19 MOZ_LOG(sWidgetClipboardLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
20 #define MOZ_CLIPBOARD_LOG_ENABLED() \
21 MOZ_LOG_TEST(sWidgetClipboardLog, mozilla::LogLevel::Debug)
23 class nsITransferable
;
24 class nsIClipboardOwner
;
28 * A base clipboard class for all platform, so that they can share the same
31 class nsBaseClipboard
: public nsIClipboard
{
33 explicit nsBaseClipboard(
34 const mozilla::dom::ClipboardCapabilities
& aClipboardCaps
);
40 NS_IMETHOD
SetData(nsITransferable
* aTransferable
, nsIClipboardOwner
* aOwner
,
41 int32_t aWhichClipboard
) override final
;
42 NS_IMETHOD
AsyncSetData(int32_t aWhichClipboard
,
43 nsIAsyncSetClipboardDataCallback
* aCallback
,
44 nsIAsyncSetClipboardData
** _retval
) override final
;
45 NS_IMETHOD
GetData(nsITransferable
* aTransferable
,
46 int32_t aWhichClipboard
) override final
;
47 NS_IMETHOD
EmptyClipboard(int32_t aWhichClipboard
) override final
;
48 NS_IMETHOD
HasDataMatchingFlavors(const nsTArray
<nsCString
>& aFlavorList
,
49 int32_t aWhichClipboard
,
50 bool* aOutResult
) override final
;
51 NS_IMETHOD
IsClipboardTypeSupported(int32_t aWhichClipboard
,
52 bool* aRetval
) override final
;
53 RefPtr
<mozilla::GenericPromise
> AsyncGetData(
54 nsITransferable
* aTransferable
, int32_t aWhichClipboard
) override final
;
55 RefPtr
<DataFlavorsPromise
> AsyncHasDataMatchingFlavors(
56 const nsTArray
<nsCString
>& aFlavorList
,
57 int32_t aWhichClipboard
) override final
;
59 using GetDataCallback
= mozilla::MoveOnlyFunction
<void(nsresult
)>;
60 using HasMatchingFlavorsCallback
= mozilla::MoveOnlyFunction
<void(
61 mozilla::Result
<nsTArray
<nsCString
>, nsresult
>)>;
64 virtual ~nsBaseClipboard();
66 // Implement the native clipboard behavior.
67 NS_IMETHOD
SetNativeClipboardData(nsITransferable
* aTransferable
,
68 nsIClipboardOwner
* aOwner
,
69 int32_t aWhichClipboard
) = 0;
70 NS_IMETHOD
GetNativeClipboardData(nsITransferable
* aTransferable
,
71 int32_t aWhichClipboard
) = 0;
72 virtual void AsyncGetNativeClipboardData(nsITransferable
* aTransferable
,
73 int32_t aWhichClipboard
,
74 GetDataCallback
&& aCallback
);
75 virtual nsresult
EmptyNativeClipboardData(int32_t aWhichClipboard
) = 0;
76 virtual mozilla::Result
<int32_t, nsresult
> GetNativeClipboardSequenceNumber(
77 int32_t aWhichClipboard
) = 0;
78 virtual mozilla::Result
<bool, nsresult
> HasNativeClipboardDataMatchingFlavors(
79 const nsTArray
<nsCString
>& aFlavorList
, int32_t aWhichClipboard
) = 0;
80 virtual void AsyncHasNativeClipboardDataMatchingFlavors(
81 const nsTArray
<nsCString
>& aFlavorList
, int32_t aWhichClipboard
,
82 HasMatchingFlavorsCallback
&& aCallback
);
84 void ClearClipboardCache(int32_t aClipboardType
);
87 void RejectPendingAsyncSetDataRequestIfAny(int32_t aClipboardType
);
89 class AsyncSetClipboardData final
: public nsIAsyncSetClipboardData
{
92 NS_DECL_NSIASYNCSETCLIPBOARDDATA
94 AsyncSetClipboardData(int32_t aClipboardType
, nsBaseClipboard
* aClipboard
,
95 nsIAsyncSetClipboardDataCallback
* aCallback
);
98 virtual ~AsyncSetClipboardData() = default;
99 bool IsValid() const {
100 // If this request is no longer valid, the callback should be notified.
101 MOZ_ASSERT_IF(!mClipboard
, !mCallback
);
104 void MaybeNotifyCallback(nsresult aResult
);
106 // The clipboard type defined in nsIClipboard.
107 int32_t mClipboardType
;
108 // It is safe to use a raw pointer as it will be nullified (by calling
109 // NotifyCallback()) once nsBaseClipboard stops tracking us. This is
110 // also used to indicate whether this request is valid.
111 nsBaseClipboard
* mClipboard
;
112 // mCallback will be nullified once the callback is notified to ensure the
113 // callback is only notified once.
114 nsCOMPtr
<nsIAsyncSetClipboardDataCallback
> mCallback
;
117 class ClipboardCache final
{
120 // In order to notify the old clipboard owner.
125 * Clear the cached transferable and notify the original clipboard owner
126 * that it has lost ownership.
129 void Update(nsITransferable
* aTransferable
,
130 nsIClipboardOwner
* aClipboardOwner
, int32_t aSequenceNumber
) {
131 // Clear first to notify the old clipboard owner.
133 mTransferable
= aTransferable
;
134 mClipboardOwner
= aClipboardOwner
;
135 mSequenceNumber
= aSequenceNumber
;
137 nsITransferable
* GetTransferable() const { return mTransferable
; }
138 nsIClipboardOwner
* GetClipboardOwner() const { return mClipboardOwner
; }
139 int32_t GetSequenceNumber() const { return mSequenceNumber
; }
142 nsCOMPtr
<nsITransferable
> mTransferable
;
143 nsCOMPtr
<nsIClipboardOwner
> mClipboardOwner
;
144 int32_t mSequenceNumber
= -1;
147 // Return clipboard cache if the cached data is valid, otherwise clear the
148 // cached data and returns null.
149 ClipboardCache
* GetClipboardCacheIfValid(int32_t aClipboardType
);
151 mozilla::Result
<nsTArray
<nsCString
>, nsresult
> GetFlavorsFromClipboardCache(
152 int32_t aClipboardType
);
153 nsresult
GetDataFromClipboardCache(nsITransferable
* aTransferable
,
154 int32_t aClipboardType
);
156 // Track the pending request for each clipboard type separately. And only need
157 // to track the latest request for each clipboard type as the prior pending
158 // request will be canceled when a new request is made.
159 RefPtr
<AsyncSetClipboardData
>
160 mPendingWriteRequests
[nsIClipboard::kClipboardTypeCount
];
162 mozilla::UniquePtr
<ClipboardCache
> mCaches
[nsIClipboard::kClipboardTypeCount
];
163 const mozilla::dom::ClipboardCapabilities mClipboardCaps
;
164 bool mIgnoreEmptyNotification
= false;
167 #endif // nsBaseClipboard_h__