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 #include "mozilla/dom/ClipboardItem.h"
8 #include "mozilla/dom/Promise.h"
9 #include "mozilla/dom/Record.h"
10 
11 namespace mozilla::dom {
12 
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback & aCallback,ClipboardItem::ItemEntry & aField,const char * aName,uint32_t aFlags=0)13 void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
14                                  ClipboardItem::ItemEntry& aField,
15                                  const char* aName, uint32_t aFlags = 0) {
16   ImplCycleCollectionTraverse(aCallback, aField.mData, aName, aFlags);
17 }
18 
ImplCycleCollectionUnlink(ClipboardItem::ItemEntry & aField)19 void ImplCycleCollectionUnlink(ClipboardItem::ItemEntry& aField) {
20   ImplCycleCollectionUnlink(aField.mData);
21 }
22 
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ClipboardItem,mOwner,mItems)23 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ClipboardItem, mOwner, mItems)
24 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ClipboardItem, AddRef)
25 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ClipboardItem, Release)
26 
27 ClipboardItem::ClipboardItem(nsISupports* aOwner,
28                              const dom::PresentationStyle aPresentationStyle,
29                              nsTArray<ItemEntry>&& aItems)
30     : mOwner(aOwner),
31       mPresentationStyle(aPresentationStyle),
32       mItems(std::move(aItems)) {}
33 
34 // static
Constructor(const GlobalObject & aGlobal,const Record<nsString,OwningStringOrBlob> & aItems,const ClipboardItemOptions & aOptions,ErrorResult & aRv)35 already_AddRefed<ClipboardItem> ClipboardItem::Constructor(
36     const GlobalObject& aGlobal,
37     const Record<nsString, OwningStringOrBlob>& aItems,
38     const ClipboardItemOptions& aOptions, ErrorResult& aRv) {
39   if (aItems.Entries().IsEmpty()) {
40     aRv.ThrowTypeError("At least one entry required");
41     return nullptr;
42   }
43 
44   nsTArray<ItemEntry> items;
45   for (const auto& entry : aItems.Entries()) {
46     ItemEntry* item = items.AppendElement();
47     item->mType = entry.mKey;
48     item->mData = entry.mValue;
49   }
50 
51   RefPtr<ClipboardItem> item = new ClipboardItem(
52       aGlobal.GetAsSupports(), aOptions.mPresentationStyle, std::move(items));
53   return item.forget();
54 }
55 
GetTypes(nsTArray<nsString> & aTypes) const56 void ClipboardItem::GetTypes(nsTArray<nsString>& aTypes) const {
57   for (const auto& item : mItems) {
58     aTypes.AppendElement(item.mType);
59   }
60 }
61 
GetType(const nsAString & aType,ErrorResult & aRv)62 already_AddRefed<Promise> ClipboardItem::GetType(const nsAString& aType,
63                                                  ErrorResult& aRv) {
64   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
65   RefPtr<Promise> p = Promise::Create(global, aRv);
66   if (aRv.Failed()) {
67     return nullptr;
68   }
69 
70   for (const auto& item : mItems) {
71     if (item.mType == aType) {
72       if (item.mData.IsBlob()) {
73         p->MaybeResolve(item.mData);
74       } else {
75         NS_ConvertUTF16toUTF8 string(item.mData.GetAsString());
76         RefPtr<Blob> blob = Blob::CreateStringBlob(global, string, item.mType);
77         p->MaybeResolve(blob);
78       }
79       return p.forget();
80     }
81   }
82 
83   p->MaybeRejectWithNotFoundError(
84       "The type '"_ns + NS_ConvertUTF16toUTF8(aType) + "' was not found"_ns);
85   return p.forget();
86 }
87 
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)88 JSObject* ClipboardItem::WrapObject(JSContext* aCx,
89                                     JS::Handle<JSObject*> aGivenProto) {
90   return mozilla::dom::ClipboardItem_Binding::Wrap(aCx, this, aGivenProto);
91 }
92 
93 }  // namespace mozilla::dom
94