Commit f81a5040 authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

input[type=file]: Save and restore webkitRelativePath values

Before this CL, we didn't save webkitRelativePath values on saving
a tab session, and we computed them with the longest common ancestor
directory of all files on restoring the tab session. After this CL,
we save webkitRelativePath values, and restore them without finding
the common ancestor directory.  This CL is a preparation of fixing
crbug.com/124187.

* FileInputType::SaveFormControlState():
Save webktiRelativePath.

* FormStateSignature() in form_controller.cc:
Increment the version string due to the format change.

* FileInputType::RestoreFormControlState():
Create |File| instances from FormControlState directly.  We used to
create a FileChooserFileInfoList from a FormControlState, and
FileInputType::CreateFileList() converted it to |File| instances. We
bypass FileChooserFileInoList because it can't represent
webkitRelativePath.

* FileInputType::FilesFromFormControlState(), HTMLInputElement::
  FilesFromFileInputFormControlState(), and SavedFormState::
  GetReferencedFilePaths():
Pass Vector<String> instead of FileChooserFileInfoList.  These
functions just need Vector<String>.

Bug: 124187
Change-Id: I225463694d164c1f6ed1cb61da8a5bc42e2542c6
Reviewed-on: https://chromium-review.googlesource.com/c/1322671Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606286}
parent 268a2cc7
...@@ -85,18 +85,29 @@ InputTypeView* FileInputType::CreateView() { ...@@ -85,18 +85,29 @@ InputTypeView* FileInputType::CreateView() {
return this; return this;
} }
FileChooserFileInfoList FileInputType::FilesFromFormControlState( template <typename ItemType, typename VectorType>
const FormControlState& state) { VectorType CreateFilesFrom(const FormControlState& state,
FileChooserFileInfoList files; ItemType (*factory)(const String&,
for (wtf_size_t i = 0; i < state.ValueSize(); i += 2) { const String&,
if (!state[i + 1].IsEmpty()) const String&)) {
files.push_back(CreateFileChooserFileInfoNative(state[i], state[i + 1])); VectorType files;
else files.ReserveInitialCapacity(state.ValueSize() / 3);
files.push_back(CreateFileChooserFileInfoNative(state[i])); for (wtf_size_t i = 0; i < state.ValueSize(); i += 3) {
const String& path = state[i];
const String& name = state[i + 1];
const String& relative_path = state[i + 2];
files.push_back(factory(path, name, relative_path));
} }
return files; return files;
} }
Vector<String> FileInputType::FilesFromFormControlState(
const FormControlState& state) {
return CreateFilesFrom<String, Vector<String>>(
state,
[](const String& path, const String&, const String&) { return path; });
}
const AtomicString& FileInputType::FormControlType() const { const AtomicString& FileInputType::FormControlType() const {
return input_type_names::kFile; return input_type_names::kFile;
} }
...@@ -110,6 +121,7 @@ FormControlState FileInputType::SaveFormControlState() const { ...@@ -110,6 +121,7 @@ FormControlState FileInputType::SaveFormControlState() const {
if (file_list_->item(i)->HasBackingFile()) { if (file_list_->item(i)->HasBackingFile()) {
state.Append(file_list_->item(i)->GetPath()); state.Append(file_list_->item(i)->GetPath());
state.Append(file_list_->item(i)->name()); state.Append(file_list_->item(i)->name());
state.Append(file_list_->item(i)->webkitRelativePath());
} }
// FIXME: handle Blob-backed File instances, see http://crbug.com/394948 // FIXME: handle Blob-backed File instances, see http://crbug.com/394948
} }
...@@ -117,9 +129,20 @@ FormControlState FileInputType::SaveFormControlState() const { ...@@ -117,9 +129,20 @@ FormControlState FileInputType::SaveFormControlState() const {
} }
void FileInputType::RestoreFormControlState(const FormControlState& state) { void FileInputType::RestoreFormControlState(const FormControlState& state) {
if (state.ValueSize() % 2) if (state.ValueSize() % 3)
return; return;
FilesChosen(FilesFromFormControlState(state)); HeapVector<Member<File>> file_vector =
CreateFilesFrom<File*, HeapVector<Member<File>>>(
state, [](const String& path, const String& name,
const String& relative_path) {
if (relative_path.IsEmpty())
return File::CreateForUserProvidedFile(path, name);
return File::CreateWithRelativePath(path, relative_path);
});
FileList* file_list = FileList::Create();
for (const auto& file : file_vector)
file_list->Append(file);
SetFiles(file_list);
} }
void FileInputType::AppendToFormData(FormData& form_data) const { void FileInputType::AppendToFormData(FormData& form_data) const {
......
...@@ -54,8 +54,7 @@ class CORE_EXPORT FileInputType final : public InputType, ...@@ -54,8 +54,7 @@ class CORE_EXPORT FileInputType final : public InputType,
static InputType* Create(HTMLInputElement&); static InputType* Create(HTMLInputElement&);
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
using InputType::GetElement; using InputType::GetElement;
static FileChooserFileInfoList FilesFromFormControlState( static Vector<String> FilesFromFormControlState(const FormControlState&);
const FormControlState&);
static FileList* CreateFileList(const FileChooserFileInfoList& files, static FileList* CreateFileList(const FileChooserFileInfoList& files,
bool has_webkit_directory_attr); bool has_webkit_directory_attr);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
#include "third_party/blink/renderer/core/html/forms/file_chooser.h" #include "third_party/blink/renderer/core/html/forms/file_chooser.h"
#include "third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h"
...@@ -297,13 +296,9 @@ Vector<String> SavedFormState::GetReferencedFilePaths() const { ...@@ -297,13 +296,9 @@ Vector<String> SavedFormState::GetReferencedFilePaths() const {
continue; continue;
const Deque<FormControlState>& queue = form_control.value; const Deque<FormControlState>& queue = form_control.value;
for (const FormControlState& form_control_state : queue) { for (const FormControlState& form_control_state : queue) {
const FileChooserFileInfoList& selected_files = to_return.AppendVector(
HTMLInputElement::FilesFromFileInputFormControlState( HTMLInputElement::FilesFromFileInputFormControlState(
form_control_state); form_control_state));
for (const auto& file : selected_files) {
to_return.push_back(
FilePathToString(file->get_native_file()->file_path));
}
} }
} }
return to_return; return to_return;
...@@ -429,7 +424,7 @@ static String FormStateSignature() { ...@@ -429,7 +424,7 @@ static String FormStateSignature() {
// attribute value of a form control. The following string literal should // attribute value of a form control. The following string literal should
// contain some characters which are rarely used for name attribute values. // contain some characters which are rarely used for name attribute values.
DEFINE_STATIC_LOCAL(String, signature, DEFINE_STATIC_LOCAL(String, signature,
("\n\r?% Blink serialized form state version 9 \n\r=&")); ("\n\r?% Blink serialized form state version 10 \n\r=&"));
return signature; return signature;
} }
......
...@@ -164,7 +164,7 @@ const AtomicString& HTMLInputElement::GetName() const { ...@@ -164,7 +164,7 @@ const AtomicString& HTMLInputElement::GetName() const {
return name_.IsNull() ? g_empty_atom : name_; return name_.IsNull() ? g_empty_atom : name_;
} }
FileChooserFileInfoList HTMLInputElement::FilesFromFileInputFormControlState( Vector<String> HTMLInputElement::FilesFromFileInputFormControlState(
const FormControlState& state) { const FormControlState& state) {
return FileInputType::FilesFromFormControlState(state); return FileInputType::FilesFromFormControlState(state);
} }
......
...@@ -268,7 +268,7 @@ class CORE_EXPORT HTMLInputElement ...@@ -268,7 +268,7 @@ class CORE_EXPORT HTMLInputElement
void EndEditing(); void EndEditing();
static FileChooserFileInfoList FilesFromFileInputFormControlState( static Vector<String> FilesFromFileInputFormControlState(
const FormControlState&); const FormControlState&);
bool MatchesReadOnlyPseudoClass() const final; bool MatchesReadOnlyPseudoClass() const final;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment