tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ClipboardItem.h (4623B)


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