Bug 1792034 [wpt PR 36019] - Make location.search always expect UTF-8, a=testonly
[gecko.git] / widget / nsFilePickerProxy.cpp
blob0f26f7ce21ae9c9faf97804209c4ace0693b35f2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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/. */
7 #include "nsFilePickerProxy.h"
8 #include "nsComponentManagerUtils.h"
9 #include "nsIFile.h"
10 #include "nsSimpleEnumerator.h"
11 #include "mozilla/dom/BlobImpl.h"
12 #include "mozilla/dom/Directory.h"
13 #include "mozilla/dom/File.h"
14 #include "mozilla/dom/BrowserChild.h"
15 #include "mozilla/dom/IPCBlobUtils.h"
17 using namespace mozilla::dom;
19 NS_IMPL_ISUPPORTS(nsFilePickerProxy, nsIFilePicker)
21 nsFilePickerProxy::nsFilePickerProxy()
22 : mSelectedType(0), mCapture(captureNone), mIPCActive(false) {}
24 nsFilePickerProxy::~nsFilePickerProxy() = default;
26 NS_IMETHODIMP
27 nsFilePickerProxy::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle,
28 int16_t aMode) {
29 BrowserChild* browserChild = BrowserChild::GetFrom(aParent);
30 if (!browserChild) {
31 return NS_ERROR_FAILURE;
34 mParent = nsPIDOMWindowOuter::From(aParent);
36 mMode = aMode;
38 NS_ADDREF_THIS();
39 browserChild->SendPFilePickerConstructor(this, aTitle, aMode);
41 mIPCActive = true;
42 return NS_OK;
45 void nsFilePickerProxy::InitNative(nsIWidget* aParent,
46 const nsAString& aTitle) {}
48 NS_IMETHODIMP
49 nsFilePickerProxy::AppendFilter(const nsAString& aTitle,
50 const nsAString& aFilter) {
51 mFilterNames.AppendElement(aTitle);
52 mFilters.AppendElement(aFilter);
53 return NS_OK;
56 NS_IMETHODIMP
57 nsFilePickerProxy::GetCapture(int16_t* aCapture) {
58 *aCapture = mCapture;
59 return NS_OK;
62 NS_IMETHODIMP
63 nsFilePickerProxy::SetCapture(int16_t aCapture) {
64 mCapture = aCapture;
65 return NS_OK;
68 NS_IMETHODIMP
69 nsFilePickerProxy::GetDefaultString(nsAString& aDefaultString) {
70 aDefaultString = mDefault;
71 return NS_OK;
74 NS_IMETHODIMP
75 nsFilePickerProxy::SetDefaultString(const nsAString& aDefaultString) {
76 mDefault = aDefaultString;
77 return NS_OK;
80 NS_IMETHODIMP
81 nsFilePickerProxy::GetDefaultExtension(nsAString& aDefaultExtension) {
82 aDefaultExtension = mDefaultExtension;
83 return NS_OK;
86 NS_IMETHODIMP
87 nsFilePickerProxy::SetDefaultExtension(const nsAString& aDefaultExtension) {
88 mDefaultExtension = aDefaultExtension;
89 return NS_OK;
92 NS_IMETHODIMP
93 nsFilePickerProxy::GetFilterIndex(int32_t* aFilterIndex) {
94 *aFilterIndex = mSelectedType;
95 return NS_OK;
98 NS_IMETHODIMP
99 nsFilePickerProxy::SetFilterIndex(int32_t aFilterIndex) {
100 mSelectedType = aFilterIndex;
101 return NS_OK;
104 NS_IMETHODIMP
105 nsFilePickerProxy::GetFile(nsIFile** aFile) {
106 MOZ_ASSERT(false, "GetFile is unimplemented; use GetDomFileOrDirectory");
107 return NS_ERROR_FAILURE;
110 NS_IMETHODIMP
111 nsFilePickerProxy::GetFileURL(nsIURI** aFileURL) {
112 MOZ_ASSERT(false, "GetFileURL is unimplemented; use GetDomFileOrDirectory");
113 return NS_ERROR_FAILURE;
116 NS_IMETHODIMP
117 nsFilePickerProxy::GetFiles(nsISimpleEnumerator** aFiles) {
118 MOZ_ASSERT(false,
119 "GetFiles is unimplemented; use GetDomFileOrDirectoryEnumerator");
120 return NS_ERROR_FAILURE;
123 nsresult nsFilePickerProxy::Show(int16_t* aReturn) {
124 MOZ_ASSERT(false, "Show is unimplemented; use Open");
125 return NS_ERROR_NOT_IMPLEMENTED;
128 NS_IMETHODIMP
129 nsFilePickerProxy::Open(nsIFilePickerShownCallback* aCallback) {
130 mCallback = aCallback;
132 nsString displayDirectory;
133 if (mDisplayDirectory) {
134 mDisplayDirectory->GetPath(displayDirectory);
137 if (!mIPCActive) {
138 return NS_ERROR_FAILURE;
141 SendOpen(mSelectedType, mAddToRecentDocs, mDefault, mDefaultExtension,
142 mFilters, mFilterNames, mRawFilters, displayDirectory,
143 mDisplaySpecialDirectory, mOkButtonLabel, mCapture);
145 return NS_OK;
148 mozilla::ipc::IPCResult nsFilePickerProxy::Recv__delete__(
149 const MaybeInputData& aData, const int16_t& aResult) {
150 nsPIDOMWindowInner* inner =
151 mParent ? mParent->GetCurrentInnerWindow() : nullptr;
153 if (NS_WARN_IF(!inner)) {
154 return IPC_OK();
157 if (aData.type() == MaybeInputData::TInputBlobs) {
158 const nsTArray<IPCBlob>& blobs = aData.get_InputBlobs().blobs();
159 for (uint32_t i = 0; i < blobs.Length(); ++i) {
160 RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(blobs[i]);
161 NS_ENSURE_TRUE(blobImpl, IPC_OK());
163 if (!blobImpl->IsFile()) {
164 return IPC_OK();
167 RefPtr<File> file = File::Create(inner->AsGlobal(), blobImpl);
168 if (NS_WARN_IF(!file)) {
169 return IPC_OK();
172 OwningFileOrDirectory* element = mFilesOrDirectories.AppendElement();
173 element->SetAsFile() = file;
175 } else if (aData.type() == MaybeInputData::TInputDirectory) {
176 nsCOMPtr<nsIFile> file;
177 const nsAString& path(aData.get_InputDirectory().directoryPath());
178 nsresult rv = NS_NewLocalFile(path, true, getter_AddRefs(file));
179 if (NS_WARN_IF(NS_FAILED(rv))) {
180 return IPC_OK();
183 RefPtr<Directory> directory = Directory::Create(inner->AsGlobal(), file);
184 MOZ_ASSERT(directory);
186 OwningFileOrDirectory* element = mFilesOrDirectories.AppendElement();
187 element->SetAsDirectory() = directory;
190 if (mCallback) {
191 mCallback->Done(aResult);
192 mCallback = nullptr;
195 return IPC_OK();
198 NS_IMETHODIMP
199 nsFilePickerProxy::GetDomFileOrDirectory(nsISupports** aValue) {
200 *aValue = nullptr;
201 if (mFilesOrDirectories.IsEmpty()) {
202 return NS_OK;
205 MOZ_ASSERT(mFilesOrDirectories.Length() == 1);
207 if (mFilesOrDirectories[0].IsFile()) {
208 nsCOMPtr<nsISupports> blob = ToSupports(mFilesOrDirectories[0].GetAsFile());
209 blob.forget(aValue);
210 return NS_OK;
213 MOZ_ASSERT(mFilesOrDirectories[0].IsDirectory());
214 RefPtr<Directory> directory = mFilesOrDirectories[0].GetAsDirectory();
215 directory.forget(aValue);
216 return NS_OK;
219 namespace {
221 class SimpleEnumerator final : public nsSimpleEnumerator {
222 public:
223 explicit SimpleEnumerator(
224 const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories)
225 : mFilesOrDirectories(aFilesOrDirectories.Clone()), mIndex(0) {}
227 NS_IMETHOD
228 HasMoreElements(bool* aRetvalue) override {
229 MOZ_ASSERT(aRetvalue);
230 *aRetvalue = mIndex < mFilesOrDirectories.Length();
231 return NS_OK;
234 NS_IMETHOD
235 GetNext(nsISupports** aValue) override {
236 NS_ENSURE_TRUE(mIndex < mFilesOrDirectories.Length(), NS_ERROR_FAILURE);
238 uint32_t index = mIndex++;
240 if (mFilesOrDirectories[index].IsFile()) {
241 nsCOMPtr<nsISupports> blob =
242 ToSupports(mFilesOrDirectories[index].GetAsFile());
243 blob.forget(aValue);
244 return NS_OK;
247 MOZ_ASSERT(mFilesOrDirectories[index].IsDirectory());
248 RefPtr<Directory> directory = mFilesOrDirectories[index].GetAsDirectory();
249 directory.forget(aValue);
250 return NS_OK;
253 private:
254 nsTArray<mozilla::dom::OwningFileOrDirectory> mFilesOrDirectories;
255 uint32_t mIndex;
258 } // namespace
260 NS_IMETHODIMP
261 nsFilePickerProxy::GetDomFileOrDirectoryEnumerator(
262 nsISimpleEnumerator** aDomfiles) {
263 RefPtr<SimpleEnumerator> enumerator =
264 new SimpleEnumerator(mFilesOrDirectories);
265 enumerator.forget(aDomfiles);
266 return NS_OK;
269 void nsFilePickerProxy::ActorDestroy(ActorDestroyReason aWhy) {
270 mIPCActive = false;
272 if (mCallback) {
273 mCallback->Done(nsIFilePicker::returnCancel);
274 mCallback = nullptr;