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() {
return this;
}
FileChooserFileInfoList FileInputType::FilesFromFormControlState(
const FormControlState& state) {
FileChooserFileInfoList files;
for (wtf_size_t i = 0; i < state.ValueSize(); i += 2) {
if (!state[i + 1].IsEmpty())
files.push_back(CreateFileChooserFileInfoNative(state[i], state[i + 1]));
else
files.push_back(CreateFileChooserFileInfoNative(state[i]));
template <typename ItemType, typename VectorType>
VectorType CreateFilesFrom(const FormControlState& state,
ItemType (*factory)(const String&,
const String&,
const String&)) {
VectorType files;
files.ReserveInitialCapacity(state.ValueSize() / 3);
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;
}
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 {
return input_type_names::kFile;
}
......@@ -110,6 +121,7 @@ FormControlState FileInputType::SaveFormControlState() const {
if (file_list_->item(i)->HasBackingFile()) {
state.Append(file_list_->item(i)->GetPath());
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
}
......@@ -117,9 +129,20 @@ FormControlState FileInputType::SaveFormControlState() const {
}
void FileInputType::RestoreFormControlState(const FormControlState& state) {
if (state.ValueSize() % 2)
if (state.ValueSize() % 3)
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 {
......
......@@ -54,8 +54,7 @@ class CORE_EXPORT FileInputType final : public InputType,
static InputType* Create(HTMLInputElement&);
void Trace(blink::Visitor*) override;
using InputType::GetElement;
static FileChooserFileInfoList FilesFromFormControlState(
const FormControlState&);
static Vector<String> FilesFromFormControlState(const FormControlState&);
static FileList* CreateFileList(const FileChooserFileInfoList& files,
bool has_webkit_directory_attr);
......
......@@ -25,7 +25,6 @@
#include "base/macros.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/html/forms/file_chooser.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 {
continue;
const Deque<FormControlState>& queue = form_control.value;
for (const FormControlState& form_control_state : queue) {
const FileChooserFileInfoList& selected_files =
to_return.AppendVector(
HTMLInputElement::FilesFromFileInputFormControlState(
form_control_state);
for (const auto& file : selected_files) {
to_return.push_back(
FilePathToString(file->get_native_file()->file_path));
}
form_control_state));
}
}
return to_return;
......@@ -429,7 +424,7 @@ static String FormStateSignature() {
// attribute value of a form control. The following string literal should
// contain some characters which are rarely used for name attribute values.
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;
}
......
......@@ -164,7 +164,7 @@ const AtomicString& HTMLInputElement::GetName() const {
return name_.IsNull() ? g_empty_atom : name_;
}
FileChooserFileInfoList HTMLInputElement::FilesFromFileInputFormControlState(
Vector<String> HTMLInputElement::FilesFromFileInputFormControlState(
const FormControlState& state) {
return FileInputType::FilesFromFormControlState(state);
}
......
......@@ -268,7 +268,7 @@ class CORE_EXPORT HTMLInputElement
void EndEditing();
static FileChooserFileInfoList FilesFromFileInputFormControlState(
static Vector<String> FilesFromFileInputFormControlState(
const FormControlState&);
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