mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Pass mime type values as file dialog accept filters (see #3314)
File dialogs that specify mime type (e.g. "image/*") accept filters will pass
those values unchanged to the OnFileDialog |accept_filters| parameter. The
default dialog implementation will show those filters in addition to a combined
"Custom Files" filter. This is a change from preexisting Google Chrome
behavior where only the combined "Custom Files" filter is displayed, and
restores CEF behavior that existed prior to 2ea7459a89
.
Document the fact that OnFileDialog may be called twice, once before MIME type
expansion and once afterwards.
Add new OnFileDialog |accept_extensions| and |accept_descriptions| parameters
for MIME type extensions and descriptions.
Details: This change adds a SelectFileDialog::FileTypeInfo::extension_mimetypes
member and improves the logic in FileSelectHelper::GetFileTypesFromAcceptType
and file_dialog_manager.cc SelectFileToFileChooserParams to support recall of
the source mime type when populating the FileChooserParams structure.
To test:
- Run `ceftests --gtest_filter=DialogTest.*`
- Run `cefclient --url=https://tests/dialogs`
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
diff --git chrome/browser/file_select_helper.cc chrome/browser/file_select_helper.cc
|
||||
index 447a91b9ac380..cf5ad1b907977 100644
|
||||
index 447a91b9ac380..0452f0a8b57cf 100644
|
||||
--- chrome/browser/file_select_helper.cc
|
||||
+++ chrome/browser/file_select_helper.cc
|
||||
@@ -20,6 +20,7 @@
|
||||
@ -43,30 +43,23 @@ index 447a91b9ac380..cf5ad1b907977 100644
|
||||
#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS)
|
||||
enterprise_connectors::ContentAnalysisDelegate::Data data;
|
||||
if (enterprise_connectors::ContentAnalysisDelegate::IsEnabled(
|
||||
@@ -459,7 +479,8 @@ void FileSelectHelper::DontAbortOnMissingWebContentsForTesting() {
|
||||
|
||||
std::unique_ptr<ui::SelectFileDialog::FileTypeInfo>
|
||||
FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
- const std::vector<std::u16string>& accept_types) {
|
||||
+ const std::vector<std::u16string>& accept_types,
|
||||
+ bool run_from_cef) {
|
||||
auto base_file_type = std::make_unique<ui::SelectFileDialog::FileTypeInfo>();
|
||||
if (accept_types.empty())
|
||||
return base_file_type;
|
||||
@@ -472,17 +493,24 @@ FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
@@ -472,31 +492,51 @@ FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
std::vector<base::FilePath::StringType>* extensions =
|
||||
&file_type->extensions.back();
|
||||
|
||||
+ // Create individual filters for each accept type.
|
||||
+ std::vector<std::vector<base::FilePath::StringType>> all_extensions;
|
||||
+ std::vector<std::u16string> all_overrides;
|
||||
+ std::vector<std::u16string> all_mimetypes;
|
||||
+
|
||||
// Find the corresponding extensions.
|
||||
int valid_type_count = 0;
|
||||
int description_id = 0;
|
||||
+ std::string ascii_type;
|
||||
for (const auto& accept_type : accept_types) {
|
||||
+ std::vector<base::FilePath::StringType> current_extensions;
|
||||
+ description_id = 0;
|
||||
+ ascii_type.clear();
|
||||
+
|
||||
size_t old_extension_size = extensions->size();
|
||||
if (accept_type[0] == '.') {
|
||||
@ -79,7 +72,11 @@ index 447a91b9ac380..cf5ad1b907977 100644
|
||||
} else {
|
||||
if (!base::IsStringASCII(accept_type))
|
||||
continue;
|
||||
@@ -493,10 +521,18 @@ FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
- std::string ascii_type = base::UTF16ToASCII(accept_type);
|
||||
+ ascii_type = base::UTF16ToASCII(accept_type);
|
||||
if (ascii_type == "image/*")
|
||||
description_id = IDS_IMAGE_FILES;
|
||||
else if (ascii_type == "audio/*")
|
||||
description_id = IDS_AUDIO_FILES;
|
||||
else if (ascii_type == "video/*")
|
||||
description_id = IDS_VIDEO_FILES;
|
||||
@ -93,6 +90,8 @@ index 447a91b9ac380..cf5ad1b907977 100644
|
||||
+ all_overrides.push_back(description_id != 0 ?
|
||||
+ l10n_util::GetStringUTF16(description_id) :
|
||||
+ std::u16string());
|
||||
+ all_mimetypes.push_back(ascii_type.empty() ?
|
||||
+ std::u16string() : accept_type);
|
||||
+
|
||||
+ extensions->insert(extensions->end(), current_extensions.begin(),
|
||||
+ current_extensions.end());
|
||||
@ -100,23 +99,40 @@ index 447a91b9ac380..cf5ad1b907977 100644
|
||||
if (extensions->size() > old_extension_size)
|
||||
valid_type_count++;
|
||||
}
|
||||
@@ -521,6 +557,15 @@ FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
l10n_util::GetStringUTF16(description_id));
|
||||
}
|
||||
@@ -513,12 +553,28 @@ FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
// dialog uses the first extension in the list to form the description,
|
||||
// like "EHTML Files". This is not what we want.
|
||||
if (valid_type_count > 1 ||
|
||||
- (valid_type_count == 1 && description_id == 0 && extensions->size() > 1))
|
||||
+ (valid_type_count == 1 && description_id == 0 && extensions->size() > 1)) {
|
||||
description_id = IDS_CUSTOM_FILES;
|
||||
+ ascii_type.clear();
|
||||
+ }
|
||||
|
||||
+ if (run_from_cef && all_extensions.size() > 1) {
|
||||
- if (description_id) {
|
||||
- file_type->extension_description_overrides.push_back(
|
||||
- l10n_util::GetStringUTF16(description_id));
|
||||
+ file_type->extension_description_overrides.push_back(
|
||||
+ description_id != 0 ?
|
||||
+ l10n_util::GetStringUTF16(description_id) :
|
||||
+ std::u16string());
|
||||
+ file_type->extension_mimetypes.push_back(
|
||||
+ ascii_type.empty() ? std::u16string() : base::ASCIIToUTF16(ascii_type));
|
||||
+
|
||||
+ if (all_extensions.size() > 1) {
|
||||
+ // Insert filters for the specific accept types at the beginning.
|
||||
+ file_type->extensions.insert(file_type->extensions.begin(),
|
||||
+ all_extensions.begin(), all_extensions.end());
|
||||
+ file_type->extension_description_overrides.insert(
|
||||
+ file_type->extension_description_overrides.begin(),
|
||||
+ all_overrides.begin(), all_overrides.end());
|
||||
+ }
|
||||
+
|
||||
return file_type;
|
||||
}
|
||||
+ file_type->extension_mimetypes.insert(
|
||||
+ file_type->extension_mimetypes.begin(),
|
||||
+ all_mimetypes.begin(), all_mimetypes.end());
|
||||
}
|
||||
|
||||
@@ -528,7 +573,8 @@ FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
return file_type;
|
||||
@@ -528,7 +584,8 @@ FileSelectHelper::GetFileTypesFromAcceptType(
|
||||
void FileSelectHelper::RunFileChooser(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
scoped_refptr<content::FileSelectListener> listener,
|
||||
@ -126,7 +142,7 @@ index 447a91b9ac380..cf5ad1b907977 100644
|
||||
Profile* profile = Profile::FromBrowserContext(
|
||||
render_frame_host->GetProcess()->GetBrowserContext());
|
||||
|
||||
@@ -547,6 +593,7 @@ void FileSelectHelper::RunFileChooser(
|
||||
@@ -547,6 +604,7 @@ void FileSelectHelper::RunFileChooser(
|
||||
// message.
|
||||
scoped_refptr<FileSelectHelper> file_select_helper(
|
||||
new FileSelectHelper(profile));
|
||||
@ -134,18 +150,8 @@ index 447a91b9ac380..cf5ad1b907977 100644
|
||||
file_select_helper->RunFileChooser(render_frame_host, std::move(listener),
|
||||
params.Clone());
|
||||
}
|
||||
@@ -598,7 +645,8 @@ void FileSelectHelper::RunFileChooser(
|
||||
}
|
||||
|
||||
void FileSelectHelper::GetFileTypesInThreadPool(FileChooserParamsPtr params) {
|
||||
- select_file_types_ = GetFileTypesFromAcceptType(params->accept_types);
|
||||
+ select_file_types_ = GetFileTypesFromAcceptType(params->accept_types,
|
||||
+ run_from_cef_);
|
||||
select_file_types_->allowed_paths =
|
||||
params->need_local_path ? ui::SelectFileDialog::FileTypeInfo::NATIVE_PATH
|
||||
: ui::SelectFileDialog::FileTypeInfo::ANY_PATH;
|
||||
diff --git chrome/browser/file_select_helper.h chrome/browser/file_select_helper.h
|
||||
index 7194323c36956..903cdf0c294fc 100644
|
||||
index 7194323c36956..fd4a5361798f0 100644
|
||||
--- chrome/browser/file_select_helper.h
|
||||
+++ chrome/browser/file_select_helper.h
|
||||
@@ -62,7 +62,8 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
|
||||
@ -158,17 +164,7 @@ index 7194323c36956..903cdf0c294fc 100644
|
||||
|
||||
// Enumerates all the files in directory.
|
||||
static void EnumerateDirectory(
|
||||
@@ -264,7 +265,8 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
|
||||
// |accept_types| contains only valid lowercased MIME types or file extensions
|
||||
// beginning with a period (.).
|
||||
static std::unique_ptr<ui::SelectFileDialog::FileTypeInfo>
|
||||
- GetFileTypesFromAcceptType(const std::vector<std::u16string>& accept_types);
|
||||
+ GetFileTypesFromAcceptType(const std::vector<std::u16string>& accept_types,
|
||||
+ bool run_from_cef);
|
||||
|
||||
// Check the accept type is valid. It is expected to be all lower case with
|
||||
// no whitespace.
|
||||
@@ -325,6 +327,9 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
|
||||
@@ -325,6 +326,9 @@ class FileSelectHelper : public base::RefCountedThreadSafe<
|
||||
// Set to false in unit tests since there is no WebContents.
|
||||
bool abort_on_missing_web_contents_in_tests_ = true;
|
||||
|
||||
@ -261,7 +257,7 @@ index 68dd62159b686..e94831cd44a2d 100644
|
||||
return CreateSelectFileDialog(listener, std::move(policy));
|
||||
}
|
||||
diff --git ui/shell_dialogs/select_file_dialog.h ui/shell_dialogs/select_file_dialog.h
|
||||
index 9b12fae59c3cc..dfb534a6f06e6 100644
|
||||
index 9b12fae59c3cc..a80873f421c8d 100644
|
||||
--- ui/shell_dialogs/select_file_dialog.h
|
||||
+++ ui/shell_dialogs/select_file_dialog.h
|
||||
@@ -102,7 +102,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
@ -274,7 +270,18 @@ index 9b12fae59c3cc..dfb534a6f06e6 100644
|
||||
|
||||
SelectFileDialog(const SelectFileDialog&) = delete;
|
||||
SelectFileDialog& operator=(const SelectFileDialog&) = delete;
|
||||
@@ -199,6 +200,19 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
@@ -126,6 +127,10 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
// be used.
|
||||
std::vector<std::u16string> extension_description_overrides;
|
||||
|
||||
+ // Original mime types for the specified extensions. Entries correspond to
|
||||
+ // |extensions|; if left blank then there was no mime type.
|
||||
+ std::vector<std::u16string> extension_mimetypes;
|
||||
+
|
||||
// Specifies whether there will be a filter added for all files (i.e. *.*).
|
||||
bool include_all_files = false;
|
||||
|
||||
@@ -199,6 +204,19 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
const GURL* caller = nullptr);
|
||||
bool HasMultipleFileTypeChoices();
|
||||
|
||||
@ -294,7 +301,7 @@ index 9b12fae59c3cc..dfb534a6f06e6 100644
|
||||
protected:
|
||||
friend class base::RefCountedThreadSafe<SelectFileDialog>;
|
||||
|
||||
@@ -224,6 +238,11 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
@@ -224,6 +242,11 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
// The listener to be notified of selection completion.
|
||||
raw_ptr<Listener> listener_;
|
||||
|
||||
@ -306,7 +313,7 @@ index 9b12fae59c3cc..dfb534a6f06e6 100644
|
||||
private:
|
||||
// Tests if the file selection dialog can be displayed by
|
||||
// testing if the AllowFileSelectionDialogs-Policy is
|
||||
@@ -236,8 +255,6 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
@@ -236,8 +259,6 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
|
||||
|
||||
// Returns true if the dialog has multiple file type choices.
|
||||
virtual bool HasMultipleFileTypeChoicesImpl() = 0;
|
||||
|
Reference in New Issue
Block a user