Bug 1173320 - patch 1/8 - Implement Directory object as string and not as BlobImpl, r=smaug

This commit is contained in:
Andrea Marchesini
2016-03-20 11:56:10 +01:00
parent f8a03c5645
commit d10e0b4b34
42 changed files with 1579 additions and 883 deletions

View File

@@ -251,16 +251,63 @@ class HTMLInputElementState final : public nsISupports
mValue = aValue;
}
const nsTArray<RefPtr<BlobImpl>>& GetBlobImpls()
void
GetFilesOrDirectories(nsPIDOMWindowInner* aWindow,
nsTArray<OwningFileOrDirectory>& aResult) const
{
return mBlobImpls;
for (uint32_t i = 0; i < mBlobImplsOrDirectoryPaths.Length(); ++i) {
if (mBlobImplsOrDirectoryPaths[i].mType == Directory::BlobImplOrDirectoryPath::eBlobImpl) {
RefPtr<File> file =
File::Create(aWindow,
mBlobImplsOrDirectoryPaths[i].mBlobImpl);
MOZ_ASSERT(file);
OwningFileOrDirectory* element = aResult.AppendElement();
element->SetAsFile() = file;
} else {
MOZ_ASSERT(mBlobImplsOrDirectoryPaths[i].mType == Directory::BlobImplOrDirectoryPath::eDirectoryPath);
nsCOMPtr<nsIFile> file;
NS_ConvertUTF16toUTF8 path(mBlobImplsOrDirectoryPaths[i].mDirectoryPath);
nsresult rv = NS_NewNativeLocalFile(path, true, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
RefPtr<Directory> directory = Directory::Create(aWindow, file,
Directory::eDOMRootDirectory);
MOZ_ASSERT(directory);
OwningFileOrDirectory* element = aResult.AppendElement();
element->SetAsDirectory() = directory;
}
}
}
void SetBlobImpls(const nsTArray<RefPtr<File>>& aFile)
void SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& aArray)
{
mBlobImpls.Clear();
for (uint32_t i = 0, len = aFile.Length(); i < len; ++i) {
mBlobImpls.AppendElement(aFile[i]->Impl());
mBlobImplsOrDirectoryPaths.Clear();
for (uint32_t i = 0; i < aArray.Length(); ++i) {
if (aArray[i].IsFile()) {
Directory::BlobImplOrDirectoryPath* data =
mBlobImplsOrDirectoryPaths.AppendElement();
data->mBlobImpl = aArray[i].GetAsFile()->Impl();
data->mType = Directory::BlobImplOrDirectoryPath::eBlobImpl;
} else {
MOZ_ASSERT(aArray[i].IsDirectory());
nsAutoString fullPath;
nsresult rv = aArray[i].GetAsDirectory()->GetFullRealPath(fullPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
Directory::BlobImplOrDirectoryPath* data =
mBlobImplsOrDirectoryPaths.AppendElement();
data->mDirectoryPath = fullPath;
data->mType = Directory::BlobImplOrDirectoryPath::eDirectoryPath;
}
}
}
@@ -274,7 +321,9 @@ class HTMLInputElementState final : public nsISupports
~HTMLInputElementState() {}
nsString mValue;
nsTArray<RefPtr<BlobImpl>> mBlobImpls;
nsTArray<Directory::BlobImplOrDirectoryPath> mBlobImplsOrDirectoryPaths;
bool mChecked;
bool mCheckedSet;
};
@@ -340,33 +389,65 @@ UploadLastDir::ContentPrefCallback::HandleError(nsresult error)
namespace {
/**
* This may return nullptr if aDomFile's implementation of
* This may return nullptr if the DOM File's implementation of
* File::mozFullPathInternal does not successfully return a non-empty
* string that is a valid path. This can happen on Firefox OS, for example,
* where the file picker can create Blobs.
*/
static already_AddRefed<nsIFile>
DOMFileToLocalFile(File* aDomFile)
DOMFileOrDirectoryToLocalFile(const OwningFileOrDirectory& aData)
{
nsString path;
ErrorResult rv;
aDomFile->GetMozFullPathInternal(path, rv);
if (rv.Failed() || path.IsEmpty()) {
rv.SuppressException();
return nullptr;
if (aData.IsFile()) {
ErrorResult rv;
aData.GetAsFile()->GetMozFullPathInternal(path, rv);
if (rv.Failed() || path.IsEmpty()) {
rv.SuppressException();
return nullptr;
}
} else {
MOZ_ASSERT(aData.IsDirectory());
aData.GetAsDirectory()->GetFullRealPath(path);
}
nsCOMPtr<nsIFile> localFile;
rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true,
getter_AddRefs(localFile));
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true,
getter_AddRefs(localFile));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return localFile.forget();
}
void
GetDOMFileOrDirectoryName(const OwningFileOrDirectory& aData,
nsAString& aName)
{
if (aData.IsFile()) {
aData.GetAsFile()->GetName(aName);
} else {
MOZ_ASSERT(aData.IsDirectory());
ErrorResult rv;
aData.GetAsDirectory()->GetName(aName, rv);
NS_WARN_IF(rv.Failed());
}
}
void
GetDOMFileOrDirectoryPath(const OwningFileOrDirectory& aData,
nsAString& aPath,
ErrorResult& aRv)
{
if (aData.IsFile()) {
aData.GetAsFile()->GetMozFullPathInternal(aPath, aRv);
} else {
MOZ_ASSERT(aData.IsDirectory());
aData.GetAsDirectory()->GetFullRealPath(aPath);
}
}
} // namespace
@@ -383,7 +464,7 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
mFilePicker->GetMode(&mode);
// Collect new selected filenames
nsTArray<RefPtr<File>> newFiles;
nsTArray<OwningFileOrDirectory> newFilesOrDirectories;
if (mode == static_cast<int16_t>(nsIFilePicker::modeOpenMultiple)) {
nsCOMPtr<nsISimpleEnumerator> iter;
nsresult rv =
@@ -402,9 +483,12 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(tmp);
MOZ_ASSERT(domBlob,
"Null file object from FilePicker's file enumerator?");
if (domBlob) {
newFiles.AppendElement(static_cast<File*>(domBlob.get()));
if (!domBlob) {
continue;
}
OwningFileOrDirectory* element = newFilesOrDirectories.AppendElement();
element->SetAsFile() = static_cast<File*>(domBlob.get());
}
} else {
MOZ_ASSERT(mode == static_cast<int16_t>(nsIFilePicker::modeOpen) ||
@@ -416,16 +500,25 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(tmp);
if (blob) {
RefPtr<File> file = static_cast<Blob*>(blob.get())->ToFile();
newFiles.AppendElement(file);
MOZ_ASSERT(file);
OwningFileOrDirectory* element = newFilesOrDirectories.AppendElement();
element->SetAsFile() = file;
} else if (tmp) {
RefPtr<Directory> directory = static_cast<Directory*>(tmp.get());
OwningFileOrDirectory* element = newFilesOrDirectories.AppendElement();
element->SetAsDirectory() = directory;
}
}
if (newFiles.IsEmpty()) {
if (newFilesOrDirectories.IsEmpty()) {
return NS_OK;
}
// Store the last used directory using the content pref service:
nsCOMPtr<nsIFile> file = DOMFileToLocalFile(newFiles[0]);
nsCOMPtr<nsIFile> file =
DOMFileOrDirectoryToLocalFile(newFilesOrDirectories[0]);
if (file) {
nsCOMPtr<nsIFile> lastUsedDir;
file->GetParent(getter_AddRefs(lastUsedDir));
@@ -436,7 +529,7 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
// The text control frame (if there is one) isn't going to send a change
// event because it will think this is done by a script.
// So, we can safely send one by ourself.
mInput->SetFiles(newFiles, true);
mInput->SetFilesOrDirectories(newFilesOrDirectories, true);
return nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
@@ -672,7 +765,8 @@ HTMLInputElement::InitFilePicker(FilePickerType aType)
// Set default directry and filename
nsAutoString defaultName;
const nsTArray<RefPtr<File>>& oldFiles = GetFilesInternal();
const nsTArray<OwningFileOrDirectory>& oldFiles =
GetFilesOrDirectoriesInternal();
nsCOMPtr<nsIFilePickerShownCallback> callback =
new HTMLInputElement::nsFilePickerShownCallback(this, filePicker);
@@ -681,18 +775,10 @@ HTMLInputElement::InitFilePicker(FilePickerType aType)
aType != FILE_PICKER_DIRECTORY) {
nsString path;
ErrorResult error;
oldFiles[0]->GetMozFullPathInternal(path, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
nsCOMPtr<nsIFile> localFile;
rv = NS_NewLocalFile(path, false, getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIFile> localFile = DOMFileOrDirectoryToLocalFile(oldFiles[0]);
if (localFile) {
nsCOMPtr<nsIFile> parentFile;
rv = localFile->GetParent(getter_AddRefs(parentFile));
nsresult rv = localFile->GetParent(getter_AddRefs(parentFile));
if (NS_SUCCEEDED(rv)) {
filePicker->SetDisplayDirectory(parentFile);
}
@@ -703,7 +789,8 @@ HTMLInputElement::InitFilePicker(FilePickerType aType)
// one file was selected before.
if (oldFiles.Length() == 1) {
nsAutoString leafName;
oldFiles[0]->GetName(leafName);
GetDOMFileOrDirectoryName(oldFiles[0], leafName);
if (!leafName.IsEmpty()) {
filePicker->SetDefaultString(leafName);
}
@@ -756,7 +843,7 @@ UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
NS_PRECONDITION(docURI, "docURI is null");
nsCOMPtr<nsILoadContext> loadContext = aDoc->GetLoadContext();
nsCOMPtr<nsIContentPrefCallback2> prefCallback =
nsCOMPtr<nsIContentPrefCallback2> prefCallback =
new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback);
#ifdef MOZ_B2G
@@ -935,7 +1022,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLInputElement,
if (tmp->IsSingleLineTextControl(false)) {
tmp->mInputData.mState->Traverse(cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFiles)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFilesOrDirectories)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFilesAndDirectoriesPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -944,7 +1031,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLInputElement,
nsGenericHTMLFormElementWithState)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFiles)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFilesOrDirectories)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFilesAndDirectoriesPromise)
if (tmp->IsSingleLineTextControl(false)) {
@@ -1003,8 +1090,8 @@ HTMLInputElement::Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) co
// we can just grab the pretty string and use it as wallpaper
GetDisplayFileName(it->mStaticDocFileList);
} else {
it->mFiles.Clear();
it->mFiles.AppendElements(mFiles);
it->mFilesOrDirectories.Clear();
it->mFilesOrDirectories.AppendElements(mFilesOrDirectories);
}
break;
case VALUE_MODE_DEFAULT_ON:
@@ -1442,9 +1529,9 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const
#else
// XXX We'd love to assert that this can't happen, but some mochitests
// use SpecialPowers to circumvent our more sane security model.
if (!mFiles.IsEmpty()) {
if (!mFilesOrDirectories.IsEmpty()) {
ErrorResult rv;
mFiles[0]->GetMozFullPath(aValue, rv);
GetDOMFileOrDirectoryPath(mFilesOrDirectories[0], aValue, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
@@ -1456,10 +1543,10 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const
#endif
} else {
// Just return the leaf name
if (mFiles.IsEmpty()) {
if (mFilesOrDirectories.IsEmpty()) {
aValue.Truncate();
} else {
mFiles[0]->GetName(aValue);
GetDOMFileOrDirectoryName(mFilesOrDirectories[0], aValue);
}
}
@@ -1494,8 +1581,8 @@ HTMLInputElement::IsValueEmpty() const
void
HTMLInputElement::ClearFiles(bool aSetValueChanged)
{
nsTArray<RefPtr<File>> files;
SetFiles(files, aSetValueChanged);
nsTArray<OwningFileOrDirectory> data;
SetFilesOrDirectories(data, aSetValueChanged);
}
/* static */ Decimal
@@ -2065,9 +2152,9 @@ void
HTMLInputElement::MozGetFileNameArray(nsTArray<nsString>& aArray,
ErrorResult& aRv)
{
for (uint32_t i = 0; i < mFiles.Length(); i++) {
nsString str;
mFiles[i]->GetMozFullPathInternal(str, aRv);
for (uint32_t i = 0; i < mFilesOrDirectories.Length(); i++) {
nsAutoString str;
GetDOMFileOrDirectoryPath(mFilesOrDirectories[i], str, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@@ -2117,25 +2204,29 @@ HTMLInputElement::MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles)
if (!global) {
return;
}
nsTArray<RefPtr<File>> files;
nsTArray<OwningFileOrDirectory> files;
for (uint32_t i = 0; i < aFiles.Length(); ++i) {
RefPtr<File> file = File::Create(global, aFiles[i].get()->Impl());
MOZ_ASSERT(file);
files.AppendElement(file);
OwningFileOrDirectory* element = files.AppendElement();
element->SetAsFile() = file;
}
SetFiles(files, true);
SetFilesOrDirectories(files, true);
}
void
HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv)
HTMLInputElement::MozSetFileNameArray(const Sequence<nsString>& aFileNames,
ErrorResult& aRv)
{
if (XRE_IsContentProcess()) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
nsTArray<RefPtr<File>> files;
nsTArray<OwningFileOrDirectory> files;
for (uint32_t i = 0; i < aFileNames.Length(); ++i) {
nsCOMPtr<nsIFile> file;
@@ -2152,21 +2243,28 @@ HTMLInputElement::MozSetFileNameArray(const Sequence< nsString >& aFileNames, Er
NS_NewLocalFile(aFileNames[i], false, getter_AddRefs(file));
}
if (file) {
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
RefPtr<File> domFile = File::CreateFromFile(global, file);
files.AppendElement(domFile);
} else {
if (!file) {
continue; // Not much we can do if the file doesn't exist
}
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
RefPtr<File> domFile = File::CreateFromFile(global, file);
OwningFileOrDirectory* element = files.AppendElement();
element->SetAsFile() = domFile;
}
SetFiles(files, true);
SetFilesOrDirectories(files, true);
}
NS_IMETHODIMP
HTMLInputElement::MozSetFileNameArray(const char16_t** aFileNames, uint32_t aLength)
HTMLInputElement::MozSetFileNameArray(const char16_t** aFileNames,
uint32_t aLength)
{
if (!nsContentUtils::IsCallerChrome()) {
// setting the value of a "FILE" input widget requires chrome privilege
@@ -2379,14 +2477,14 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
return;
}
if (mFiles.Length() == 1) {
mFiles[0]->GetName(aValue);
if (mFilesOrDirectories.Length() == 1) {
GetDOMFileOrDirectoryName(mFilesOrDirectories[0], aValue);
return;
}
nsXPIDLString value;
if (mFiles.IsEmpty()) {
if (mFilesOrDirectories.IsEmpty()) {
if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"NoFilesSelected", value);
@@ -2396,7 +2494,7 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
}
} else {
nsString count;
count.AppendInt(int(mFiles.Length()));
count.AppendInt(int(mFilesOrDirectories.Length()));
const char16_t* params[] = { count.get() };
nsContentUtils::FormatLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
@@ -2407,13 +2505,13 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
}
void
HTMLInputElement::SetFiles(const nsTArray<RefPtr<File>>& aFiles,
bool aSetValueChanged)
HTMLInputElement::SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories,
bool aSetValueChanged)
{
mFiles.Clear();
mFiles.AppendElements(aFiles);
mFilesOrDirectories.Clear();
mFilesOrDirectories.AppendElements(aFilesOrDirectories);
AfterSetFiles(aSetValueChanged);
AfterSetFilesOrDirectories(aSetValueChanged);
}
void
@@ -2421,22 +2519,24 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
bool aSetValueChanged)
{
RefPtr<FileList> files = static_cast<FileList*>(aFiles);
mFiles.Clear();
mFilesOrDirectories.Clear();
if (aFiles) {
uint32_t listLength;
aFiles->GetLength(&listLength);
for (uint32_t i = 0; i < listLength; i++) {
RefPtr<File> file = files->Item(i);
mFiles.AppendElement(file);
OwningFileOrDirectory* element = mFilesOrDirectories.AppendElement();
element->SetAsFile() = file;
}
}
AfterSetFiles(aSetValueChanged);
AfterSetFilesOrDirectories(aSetValueChanged);
}
void
HTMLInputElement::AfterSetFiles(bool aSetValueChanged)
HTMLInputElement::AfterSetFilesOrDirectories(bool aSetValueChanged)
{
// No need to flush here, if there's no frame at this point we
// don't need to force creation of one just to tell it about this
@@ -2454,11 +2554,11 @@ HTMLInputElement::AfterSetFiles(bool aSetValueChanged)
// call under GetMozFullPath won't be rejected for not being urgent.
// XXX Protected by the ifndef because the blob code doesn't allow us to send
// this message in b2g.
if (mFiles.IsEmpty()) {
if (mFilesOrDirectories.IsEmpty()) {
mFirstFilePath.Truncate();
} else {
ErrorResult rv;
mFiles[0]->GetMozFullPath(mFirstFilePath, rv);
GetDOMFileOrDirectoryPath(mFilesOrDirectories[0], mFirstFilePath, rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
}
@@ -2538,9 +2638,11 @@ HTMLInputElement::UpdateFileList()
if (mFileList) {
mFileList->Clear();
const nsTArray<RefPtr<File>>& files = GetFilesInternal();
for (uint32_t i = 0; i < files.Length(); ++i) {
if (!mFileList->Append(files[i])) {
const nsTArray<OwningFileOrDirectory>& array =
GetFilesOrDirectoriesInternal();
for (uint32_t i = 0; i < array.Length(); ++i) {
if (array[i].IsFile() && !mFileList->Append(array[i].GetAsFile())) {
return NS_ERROR_FAILURE;
}
}
@@ -3975,7 +4077,7 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
nsNumberControlFrame* numberControlFrame =
do_QueryFrame(GetPrimaryFrame());
if (numberControlFrame) {
if (aVisitor.mEvent->mMessage == eMouseDown &&
if (aVisitor.mEvent->mMessage == eMouseDown &&
IsMutable()) {
switch (numberControlFrame->GetSpinButtonForPointerEvent(
aVisitor.mEvent->AsMouseEvent())) {
@@ -4526,7 +4628,7 @@ HTMLInputElement::GetValueAsDate(const nsAString& aValue,
}
uint32_t endOfYearOffset = aValue.Length() - 6;
if (aValue[endOfYearOffset] != '-' ||
aValue[endOfYearOffset + 3] != '-') {
return false;
@@ -4894,45 +4996,38 @@ HTMLInputElement::GetFilesAndDirectories(ErrorResult& aRv)
return nullptr;
}
const nsTArray<RefPtr<File>>& filesAndDirs = GetFilesInternal();
const nsTArray<OwningFileOrDirectory>& filesAndDirs =
GetFilesOrDirectoriesInternal();
Sequence<OwningFileOrDirectory> filesAndDirsSeq;
if (!filesAndDirsSeq.SetLength(filesAndDirs.Length(), mozilla::fallible_t())) {
if (!filesAndDirsSeq.SetLength(filesAndDirs.Length(),
mozilla::fallible_t())) {
p->MaybeReject(NS_ERROR_OUT_OF_MEMORY);
return p.forget();
}
for (uint32_t i = 0; i < filesAndDirs.Length(); ++i) {
if (filesAndDirs[i]->IsDirectory()) {
if (filesAndDirs[i].IsDirectory()) {
#if defined(ANDROID) || defined(MOZ_B2G)
MOZ_ASSERT(false,
"Directory picking should have been redirected to normal "
"file picking for platforms that don't have a directory "
"picker");
#endif
nsAutoString path;
filesAndDirs[i]->GetMozFullPathInternal(path, aRv);
if (aRv.Failed()) {
return nullptr;
}
int32_t leafSeparatorIndex = path.RFind(FILE_PATH_SEPARATOR);
nsDependentSubstring dirname = Substring(path, 0, leafSeparatorIndex);
RefPtr<OSFileSystem> fs = new OSFileSystem(dirname);
fs->Init(OwnerDoc()->GetInnerWindow());
RefPtr<Directory> directory = filesAndDirs[i].GetAsDirectory();
nsAutoString dompath(NS_LITERAL_STRING(FILESYSTEM_DOM_PATH_SEPARATOR));
dompath.Append(Substring(path, leafSeparatorIndex + 1));
RefPtr<Directory> directory = new Directory(fs, dompath);
// In future we could refactor SetFilePickerFiltersFromAccept to return a
// semicolon separated list of file extensions and include that in the
// filter string passed here.
directory->SetContentFilters(NS_LITERAL_STRING("filter-out-sensitive"));
filesAndDirsSeq[i].SetAsDirectory() = directory;
} else {
MOZ_ASSERT(filesAndDirs[i].IsFile());
// This file was directly selected by the user, so don't filter it.
filesAndDirsSeq[i].SetAsFile() = filesAndDirs[i];
filesAndDirsSeq[i].SetAsFile() = filesAndDirs[i].GetAsFile();
}
}
@@ -5566,13 +5661,18 @@ HTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
if (mType == NS_FORM_INPUT_FILE) {
// Submit files
const nsTArray<RefPtr<File>>& files = GetFilesInternal();
const nsTArray<OwningFileOrDirectory>& files =
GetFilesOrDirectoriesInternal();
bool hasBlobs = false;
for (uint32_t i = 0; i < files.Length(); ++i) {
aFormSubmission->AddNameBlobOrNullPair(name, files[i]);
if (files[i].IsFile()) {
hasBlobs = true;
aFormSubmission->AddNameBlobOrNullPair(name, files[i].GetAsFile());
}
}
if (files.IsEmpty()) {
if (!hasBlobs) {
aFormSubmission->AddNameBlobOrNullPair(name, nullptr);
}
@@ -5606,9 +5706,9 @@ HTMLInputElement::SaveState()
}
break;
case VALUE_MODE_FILENAME:
if (!mFiles.IsEmpty()) {
if (!mFilesOrDirectories.IsEmpty()) {
inputState = new HTMLInputElementState();
inputState->SetBlobImpls(mFiles);
inputState->SetFilesOrDirectories(mFilesOrDirectories);
}
break;
case VALUE_MODE_VALUE:
@@ -5777,7 +5877,7 @@ HTMLInputElement::AddStates(EventStates aStates)
}
}
}
nsGenericHTMLFormElementWithState::AddStates(aStates);
nsGenericHTMLFormElementWithState::AddStates(aStates);
}
void
@@ -5814,20 +5914,13 @@ HTMLInputElement::RestoreState(nsPresState* aState)
break;
case VALUE_MODE_FILENAME:
{
const nsTArray<RefPtr<BlobImpl>>& blobImpls = inputState->GetBlobImpls();
nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow();
if (window) {
nsTArray<OwningFileOrDirectory> array;
inputState->GetFilesOrDirectories(window, array);
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
MOZ_ASSERT(global);
nsTArray<RefPtr<File>> files;
for (uint32_t i = 0, len = blobImpls.Length(); i < len; ++i) {
RefPtr<File> file = File::Create(global, blobImpls[i]);
MOZ_ASSERT(file);
files.AppendElement(file);
SetFilesOrDirectories(array, true);
}
SetFiles(files, true);
}
break;
case VALUE_MODE_VALUE:
@@ -6337,15 +6430,15 @@ HTMLInputElement::IsValueMissing() const
switch (GetValueMode()) {
case VALUE_MODE_VALUE:
return IsValueEmpty();
case VALUE_MODE_FILENAME:
{
const nsTArray<RefPtr<File>>& files = GetFilesInternal();
return files.IsEmpty();
}
return GetFilesOrDirectoriesInternal().IsEmpty();
case VALUE_MODE_DEFAULT_ON:
// This should not be used for type radio.
// See the MOZ_ASSERT at the beginning of the method.
return !mChecked;
case VALUE_MODE_DEFAULT:
default:
return false;