diff options
author | Moonchild <moonchild@palemoon.org> | 2021-02-21 10:32:47 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2021-02-21 10:32:47 +0000 |
commit | 98f6ad61f4f3c66209036db4bc7a4ae6ff4d1d3d (patch) | |
tree | 5d194dc3e53b4f5a4fa6b31b7756bf426fbe3cb9 | |
parent | 2b6effbf29cb4f7aa85e4f697c79c473cc4c9ea4 (diff) | |
download | uxp-98f6ad61f4f3c66209036db4bc7a4ae6ff4d1d3d.tar.gz |
[widget] Require user interaction when picking files or folders v2
Now with extra sauce to make it work cross-platform and cross-versions and
for HTML input elements only.
-rw-r--r-- | dom/html/HTMLInputElement.cpp | 2 | ||||
-rw-r--r-- | dom/ipc/FilePickerParent.cpp | 3 | ||||
-rw-r--r-- | widget/nsBaseFilePicker.cpp | 3 | ||||
-rw-r--r-- | widget/nsBaseFilePicker.h | 3 | ||||
-rw-r--r-- | widget/nsFilePickerProxy.cpp | 2 | ||||
-rw-r--r-- | widget/nsFilePickerProxy.h | 2 | ||||
-rw-r--r-- | widget/nsIFilePicker.idl | 5 | ||||
-rw-r--r-- | widget/windows/nsFilePicker.cpp | 23 | ||||
-rw-r--r-- | widget/windows/nsFilePicker.h | 4 |
9 files changed, 36 insertions, 11 deletions
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 86d03d8f59..557e673e15 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -866,7 +866,7 @@ HTMLInputElement::InitFilePicker(FilePickerType aType) mode = static_cast<int16_t>(nsIFilePicker::modeOpen); } - nsresult rv = filePicker->Init(win, title, mode); + nsresult rv = filePicker->Init(win, title, mode, /*aRequireInteraction = */ true); NS_ENSURE_SUCCESS(rv, rv); if (!okButtonLabel.IsEmpty()) { diff --git a/dom/ipc/FilePickerParent.cpp b/dom/ipc/FilePickerParent.cpp index 3e8301f246..1438e374fe 100644 --- a/dom/ipc/FilePickerParent.cpp +++ b/dom/ipc/FilePickerParent.cpp @@ -248,7 +248,8 @@ FilePickerParent::CreateFilePicker() return false; } - return NS_SUCCEEDED(mFilePicker->Init(window, mTitle, mMode)); + return NS_SUCCEEDED(mFilePicker->Init(window, mTitle, mMode, + element->IsNodeOfType(nsINode::eHTML_FORM_CONTROL))); } bool diff --git a/widget/nsBaseFilePicker.cpp b/widget/nsBaseFilePicker.cpp index d65ffb651a..1bcd78b462 100644 --- a/widget/nsBaseFilePicker.cpp +++ b/widget/nsBaseFilePicker.cpp @@ -166,7 +166,8 @@ nsBaseFilePicker::~nsBaseFilePicker() NS_IMETHODIMP nsBaseFilePicker::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle, - int16_t aMode) + int16_t aMode, + bool aRequireInteraction) { NS_PRECONDITION(aParent, "Null parent passed to filepicker, no file " "picker for you!"); diff --git a/widget/nsBaseFilePicker.h b/widget/nsBaseFilePicker.h index 56ca5acc8d..c0a197e263 100644 --- a/widget/nsBaseFilePicker.h +++ b/widget/nsBaseFilePicker.h @@ -25,7 +25,8 @@ public: NS_IMETHOD Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle, - int16_t aMode); + int16_t aMode, + bool aRequireInteraction = false); NS_IMETHOD Open(nsIFilePickerShownCallback *aCallback); NS_IMETHOD AppendFilters(int32_t filterMask); diff --git a/widget/nsFilePickerProxy.cpp b/widget/nsFilePickerProxy.cpp index 8828c416e9..077168c455 100644 --- a/widget/nsFilePickerProxy.cpp +++ b/widget/nsFilePickerProxy.cpp @@ -27,7 +27,7 @@ nsFilePickerProxy::~nsFilePickerProxy() NS_IMETHODIMP nsFilePickerProxy::Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle, - int16_t aMode) + int16_t aMode, bool aRequireInteraction) { TabChild* tabChild = TabChild::GetFrom(aParent); if (!tabChild) { diff --git a/widget/nsFilePickerProxy.h b/widget/nsFilePickerProxy.h index fbffb93dee..62d343d72f 100644 --- a/widget/nsFilePickerProxy.h +++ b/widget/nsFilePickerProxy.h @@ -34,7 +34,7 @@ public: NS_DECL_ISUPPORTS // nsIFilePicker (less what's in nsBaseFilePicker) - NS_IMETHOD Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle, int16_t aMode) override; + NS_IMETHOD Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle, int16_t aMode, bool aRequireInteraction = false) override; NS_IMETHOD AppendFilter(const nsAString& aTitle, const nsAString& aFilter) override; NS_IMETHOD GetDefaultString(nsAString& aDefaultString) override; NS_IMETHOD SetDefaultString(const nsAString& aDefaultString) override; diff --git a/widget/nsIFilePicker.idl b/widget/nsIFilePicker.idl index 62efe93ecf..8de69c56e9 100644 --- a/widget/nsIFilePicker.idl +++ b/widget/nsIFilePicker.idl @@ -66,9 +66,12 @@ interface nsIFilePicker : nsISupports * on this parent. parent must be non-null. * @param title The title for the file widget * @param mode load, save, or get folder + * @param requireinteraction (optional) + * require interaction before confirmation is possible * */ - void init(in mozIDOMWindowProxy parent, in AString title, in short mode); + void init(in mozIDOMWindowProxy parent, in AString title, in short mode, + [optional] in boolean requireinteraction); /** * Append to the filter list with things from the predefined list diff --git a/widget/windows/nsFilePicker.cpp b/widget/windows/nsFilePicker.cpp index 78656165d9..59ae152ec6 100644 --- a/widget/windows/nsFilePicker.cpp +++ b/widget/windows/nsFilePicker.cpp @@ -29,6 +29,7 @@ #include "GeckoProfiler.h" using mozilla::IsWin8OrLater; +using mozilla::IsWin10OrLater; using mozilla::MakeUnique; using mozilla::mscom::EnsureMTA; using mozilla::UniquePtr; @@ -193,11 +194,13 @@ nsFilePicker::~nsFilePicker() NS_IMPL_ISUPPORTS(nsFilePicker, nsIFilePicker) -NS_IMETHODIMP nsFilePicker::Init(mozIDOMWindowProxy *aParent, const nsAString& aTitle, int16_t aMode) +NS_IMETHODIMP nsFilePicker::Init(mozIDOMWindowProxy *aParent, const nsAString& aTitle, int16_t aMode, + bool aRequireInteraction) { nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aParent); nsIDocShell* docShell = window ? window->GetDocShell() : nullptr; mLoadContext = do_QueryInterface(docShell); + mRequireInteraction = aRequireInteraction; return nsBaseFilePicker::Init(aParent, aTitle, aMode); } @@ -360,7 +363,14 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir) dialog->Advise(this, &mFDECookie); // options - FILEOPENDIALOGOPTIONS fos = FOS_PICKFOLDERS | FOS_OKBUTTONNEEDSINTERACTION; + FILEOPENDIALOGOPTIONS fos = FOS_PICKFOLDERS; + // Require interaction if the folder picker is triggered by an element that + // is potentially unsafe to use the default value in. + // Win 10+ only, because this dialog flag is broken in earlier versions. + if (IsWin10OrLater() && mRequireInteraction) { + fos |= FOS_OKBUTTONNEEDSINTERACTION; + } + dialog->SetOptions(fos); // initial strings @@ -459,7 +469,14 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir) FILEOPENDIALOGOPTIONS fos = 0; fos |= FOS_SHAREAWARE | FOS_OVERWRITEPROMPT | - FOS_FORCEFILESYSTEM | FOS_OKBUTTONNEEDSINTERACTION; + FOS_FORCEFILESYSTEM; + + // Require interaction if the file picker is triggered by an element that + // is potentially unsafe to use the default value in. + // Win 10+ only, because this dialog flag is broken in earlier versions. + if (IsWin10OrLater() && mRequireInteraction) { + fos |= FOS_OKBUTTONNEEDSINTERACTION; + } // Handle add to recent docs settings if (IsPrivacyModeEnabled() || !mAddToRecentDocs) { diff --git a/widget/windows/nsFilePicker.h b/widget/windows/nsFilePicker.h index 740f07a7d8..7a3fbbe073 100644 --- a/widget/windows/nsFilePicker.h +++ b/widget/windows/nsFilePicker.h @@ -49,7 +49,8 @@ class nsFilePicker : public: nsFilePicker(); - NS_IMETHOD Init(mozIDOMWindowProxy *aParent, const nsAString& aTitle, int16_t aMode); + NS_IMETHOD Init(mozIDOMWindowProxy *aParent, const nsAString& aTitle, int16_t aMode, + bool aRequireInteraction = false); NS_DECL_ISUPPORTS @@ -101,6 +102,7 @@ protected: nsString mUnicodeFile; static char16_t *mLastUsedUnicodeDirectory; HWND mDlgWnd; + bool mRequireInteraction; class ComDlgFilterSpec { |