1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ClipboardItem_h_
#define mozilla_dom_ClipboardItem_h_
#include "mozilla/MozPromise.h"
#include "mozilla/dom/Blob.h"
#include "mozilla/dom/ClipboardBinding.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "nsIClipboard.h"
#include "nsWrapperCache.h"
class nsITransferable;
namespace mozilla::dom {
struct ClipboardItemOptions;
template <typename KeyType, typename ValueType>
class Record;
class Promise;
class ClipboardItem final : public nsWrapperCache {
public:
class ItemEntry final : public PromiseNativeHandler,
public nsIAsyncClipboardRequestCallback {
public:
using GetDataPromise =
MozPromise<OwningStringOrBlob, nsresult, /* IsExclusive = */ true>;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIASYNCCLIPBOARDREQUESTCALLBACK
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ItemEntry, PromiseNativeHandler)
explicit ItemEntry(nsIGlobalObject* aGlobal, const nsAString& aType)
: mGlobal(aGlobal), mType(aType) {
MOZ_ASSERT(mGlobal);
}
ItemEntry(nsIGlobalObject* aGlobal, const nsAString& aType,
const nsAString& aData)
: ItemEntry(aGlobal, aType) {
mLoadResult.emplace(NS_OK);
mData.SetAsString() = aData;
}
// PromiseNativeHandler
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
ErrorResult& aRv) override;
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
ErrorResult& aRv) override;
const nsString& Type() const { return mType; }
RefPtr<GetDataPromise> GetData();
// Load data from system clipboard.
void LoadDataFromSystemClipboard(nsIClipboardDataSnapshot* aDataGetter);
void LoadDataFromDataPromise(Promise& aDataPromise);
// If clipboard data is in the process of loading from either system
// clipboard or data promise, add `aPromise` to the pending list which will
// be resolved/rejected later when process is finished. Otherwise,
// resolve/reject `aPromise` based on cached result and data.
void ReactGetTypePromise(Promise& aPromise);
private:
~ItemEntry() {
if (!mPendingGetDataRequests.IsEmpty()) {
RejectPendingPromises(NS_ERROR_FAILURE);
}
};
void MaybeResolveGetTypePromise(const OwningStringOrBlob& aData,
Promise& aPromise);
void MaybeResolvePendingPromises(OwningStringOrBlob&& aData);
void RejectPendingPromises(nsresult rv);
nsCOMPtr<nsIGlobalObject> mGlobal;
// MIME type of this entry.
nsString mType;
// Cache the loading result.
OwningStringOrBlob mData;
Maybe<nsresult> mLoadResult;
// Indicates if the data is still being loaded.
bool mIsLoadingData = false;
nsCOMPtr<nsITransferable> mTransferable;
// Pending promises for data retrieval requests.
nsTArray<MozPromiseHolder<GetDataPromise>> mPendingGetDataRequests;
nsTArray<RefPtr<Promise>> mPendingGetTypeRequests;
};
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ClipboardItem)
NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(ClipboardItem)
ClipboardItem(nsISupports* aOwner, dom::PresentationStyle aPresentationStyle,
nsTArray<RefPtr<ItemEntry>>&& aItems);
static already_AddRefed<ClipboardItem> Constructor(
const GlobalObject& aGlobal,
const Record<nsString, OwningNonNull<Promise>>& aItems,
const ClipboardItemOptions& aOptions, ErrorResult& aRv);
static bool Supports(const GlobalObject& aGlobal, const nsAString& aType);
dom::PresentationStyle PresentationStyle() const {
return mPresentationStyle;
};
void GetTypes(nsTArray<nsString>& aTypes) const;
already_AddRefed<Promise> GetType(const nsAString& aType, ErrorResult& aRv);
nsISupports* GetParentObject() const { return mOwner; }
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
const nsTArray<RefPtr<ItemEntry>>& Entries() const { return mItems; }
private:
~ClipboardItem() = default;
nsCOMPtr<nsISupports> mOwner;
dom::PresentationStyle mPresentationStyle;
nsTArray<RefPtr<ItemEntry>> mItems;
};
} // namespace mozilla::dom
#endif // mozilla_dom_ClipboardItem_h_
|