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