mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +00:00
Bug 1357981 - Allocate input type=file related member variables only when needed. f=smaug, r=baku
In order to reduce the size of HTMLInputElement for performance gain, we're going to allocate input type=file related member variables only when type=file. --HG-- extra : rebase_source : de31e8c55ee44b6ef7f8143b39e64d369d021856
This commit is contained in:
parent
d91dc284ca
commit
bdf639f264
@ -412,6 +412,72 @@ NS_DEFINE_STATIC_IID_ACCESSOR(HTMLInputElementState, NS_INPUT_ELEMENT_STATE_IID)
|
||||
|
||||
NS_IMPL_ISUPPORTS(HTMLInputElementState, HTMLInputElementState)
|
||||
|
||||
struct HTMLInputElement::FileData
|
||||
{
|
||||
/**
|
||||
* The value of the input if it is a file input. This is the list of files or
|
||||
* directories DOM objects used when uploading a file. It is vital that this
|
||||
* is kept separate from mValue so that it won't be possible to 'leak' the
|
||||
* value from a text-input to a file-input. Additionally, the logic for this
|
||||
* value is kept as simple as possible to avoid accidental errors where the
|
||||
* wrong filename is used. Therefor the list of filenames is always owned by
|
||||
* this member, never by the frame. Whenever the frame wants to change the
|
||||
* filename it has to call SetFilesOrDirectories to update this member.
|
||||
*/
|
||||
nsTArray<OwningFileOrDirectory> mFilesOrDirectories;
|
||||
|
||||
RefPtr<GetFilesHelper> mGetFilesRecursiveHelper;
|
||||
RefPtr<GetFilesHelper> mGetFilesNonRecursiveHelper;
|
||||
|
||||
/**
|
||||
* Hack for bug 1086684: Stash the .value when we're a file picker.
|
||||
*/
|
||||
nsString mFirstFilePath;
|
||||
|
||||
RefPtr<FileList> mFileList;
|
||||
Sequence<RefPtr<FileSystemEntry>> mEntries;
|
||||
|
||||
nsString mStaticDocFileList;
|
||||
|
||||
void ClearGetFilesHelpers()
|
||||
{
|
||||
if (mGetFilesNonRecursiveHelper) {
|
||||
mGetFilesRecursiveHelper->Unlink();
|
||||
mGetFilesRecursiveHelper = nullptr;
|
||||
}
|
||||
|
||||
if (mGetFilesNonRecursiveHelper) {
|
||||
mGetFilesNonRecursiveHelper->Unlink();
|
||||
mGetFilesNonRecursiveHelper = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Cycle Collection support.
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
FileData* tmp = this;
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFilesOrDirectories)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEntries)
|
||||
if (mGetFilesRecursiveHelper) {
|
||||
mGetFilesRecursiveHelper->Traverse(cb);
|
||||
}
|
||||
|
||||
if (mGetFilesNonRecursiveHelper) {
|
||||
mGetFilesNonRecursiveHelper->Traverse(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void Unlink()
|
||||
{
|
||||
FileData* tmp = this;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFilesOrDirectories)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEntries)
|
||||
ClearGetFilesHelpers();
|
||||
}
|
||||
};
|
||||
|
||||
HTMLInputElement::nsFilePickerShownCallback::nsFilePickerShownCallback(
|
||||
HTMLInputElement* aInput, nsIFilePicker* aFilePicker)
|
||||
: mFilePicker(aFilePicker)
|
||||
@ -1106,6 +1172,12 @@ HTMLInputElement::HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
||||
, mSelectionCached(true)
|
||||
, mIsPreviewEnabled(false)
|
||||
{
|
||||
// If size is above 512, mozjemalloc allocates 1kB, see
|
||||
// memory/mozjemalloc/jemalloc.c
|
||||
static_assert(sizeof(HTMLInputElement) <= 512,
|
||||
"Keep the size of HTMLInputElement under 512 to avoid "
|
||||
"performance regression!");
|
||||
|
||||
// We are in a type=text so we now we currenty need a nsTextEditorState.
|
||||
mInputData.mState =
|
||||
nsTextEditorState::Construct(this, &sCachedTextEditorState);
|
||||
@ -1171,33 +1243,23 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLInputElement,
|
||||
if (tmp->IsSingleLineTextControl(false)) {
|
||||
tmp->mInputData.mState->Traverse(cb);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFilesOrDirectories)
|
||||
|
||||
if (tmp->mGetFilesRecursiveHelper) {
|
||||
tmp->mGetFilesRecursiveHelper->Traverse(cb);
|
||||
if (tmp->mFileData) {
|
||||
tmp->mFileData->Traverse(cb);
|
||||
}
|
||||
|
||||
if (tmp->mGetFilesNonRecursiveHelper) {
|
||||
tmp->mGetFilesNonRecursiveHelper->Traverse(cb);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEntries)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
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(mFilesOrDirectories)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEntries)
|
||||
if (tmp->IsSingleLineTextControl(false)) {
|
||||
tmp->mInputData.mState->Unlink();
|
||||
}
|
||||
|
||||
tmp->ClearGetFilesHelpers();
|
||||
|
||||
if (tmp->mFileData) {
|
||||
tmp->mFileData->Unlink();
|
||||
}
|
||||
//XXX should unlink more?
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
@ -1250,11 +1312,12 @@ HTMLInputElement::Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) co
|
||||
if (it->OwnerDoc()->IsStaticDocument()) {
|
||||
// We're going to be used in print preview. Since the doc is static
|
||||
// we can just grab the pretty string and use it as wallpaper
|
||||
GetDisplayFileName(it->mStaticDocFileList);
|
||||
GetDisplayFileName(it->mFileData->mStaticDocFileList);
|
||||
} else {
|
||||
it->ClearGetFilesHelpers();
|
||||
it->mFilesOrDirectories.Clear();
|
||||
it->mFilesOrDirectories.AppendElements(mFilesOrDirectories);
|
||||
it->mFileData->ClearGetFilesHelpers();
|
||||
it->mFileData->mFilesOrDirectories.Clear();
|
||||
it->mFileData->mFilesOrDirectories.AppendElements(
|
||||
mFileData->mFilesOrDirectories);
|
||||
}
|
||||
break;
|
||||
case VALUE_MODE_DEFAULT_ON:
|
||||
@ -1671,17 +1734,17 @@ HTMLInputElement::GetValueInternal(nsAString& aValue,
|
||||
}
|
||||
|
||||
if (aCallerType == CallerType::System) {
|
||||
aValue.Assign(mFirstFilePath);
|
||||
aValue.Assign(mFileData->mFirstFilePath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFilesOrDirectories.IsEmpty()) {
|
||||
if (mFileData->mFilesOrDirectories.IsEmpty()) {
|
||||
aValue.Truncate();
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString file;
|
||||
GetDOMFileOrDirectoryName(mFilesOrDirectories[0], file);
|
||||
GetDOMFileOrDirectoryName(mFileData->mFilesOrDirectories[0], file);
|
||||
if (file.IsEmpty()) {
|
||||
aValue.Truncate();
|
||||
return;
|
||||
@ -2507,9 +2570,15 @@ void
|
||||
HTMLInputElement::MozGetFileNameArray(nsTArray<nsString>& aArray,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
for (uint32_t i = 0; i < mFilesOrDirectories.Length(); i++) {
|
||||
if (NS_WARN_IF(mType != NS_FORM_INPUT_FILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nsTArray<OwningFileOrDirectory>& filesOrDirs =
|
||||
GetFilesOrDirectoriesInternal();
|
||||
for (uint32_t i = 0; i < filesOrDirs.Length(); i++) {
|
||||
nsAutoString str;
|
||||
GetDOMFileOrDirectoryPath(mFilesOrDirectories[i], str, aRv);
|
||||
GetDOMFileOrDirectoryPath(filesOrDirs[i], str, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
@ -2521,6 +2590,10 @@ HTMLInputElement::MozGetFileNameArray(nsTArray<nsString>& aArray,
|
||||
void
|
||||
HTMLInputElement::MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles)
|
||||
{
|
||||
if (NS_WARN_IF(mType != NS_FORM_INPUT_FILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
|
||||
MOZ_ASSERT(global);
|
||||
if (!global) {
|
||||
@ -2543,6 +2616,10 @@ void
|
||||
HTMLInputElement::MozSetFileNameArray(const Sequence<nsString>& aFileNames,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (NS_WARN_IF(mType != NS_FORM_INPUT_FILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
@ -2588,6 +2665,10 @@ void
|
||||
HTMLInputElement::MozSetDirectory(const nsAString& aDirectoryPath,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (NS_WARN_IF(mType != NS_FORM_INPUT_FILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
aRv = NS_NewLocalFile(aDirectoryPath, true, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
@ -2968,19 +3049,21 @@ HTMLInputElement::GetPreviewVisibility()
|
||||
void
|
||||
HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
|
||||
{
|
||||
MOZ_ASSERT(mFileData);
|
||||
|
||||
if (OwnerDoc()->IsStaticDocument()) {
|
||||
aValue = mStaticDocFileList;
|
||||
aValue = mFileData->mStaticDocFileList;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFilesOrDirectories.Length() == 1) {
|
||||
GetDOMFileOrDirectoryName(mFilesOrDirectories[0], aValue);
|
||||
if (mFileData->mFilesOrDirectories.Length() == 1) {
|
||||
GetDOMFileOrDirectoryName(mFileData->mFilesOrDirectories[0], aValue);
|
||||
return;
|
||||
}
|
||||
|
||||
nsXPIDLString value;
|
||||
|
||||
if (mFilesOrDirectories.IsEmpty()) {
|
||||
if (mFileData->mFilesOrDirectories.IsEmpty()) {
|
||||
if ((IsDirPickerEnabled() && Allowdirs()) ||
|
||||
(IsWebkitDirPickerEnabled() &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
|
||||
@ -2995,7 +3078,7 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
|
||||
}
|
||||
} else {
|
||||
nsString count;
|
||||
count.AppendInt(int(mFilesOrDirectories.Length()));
|
||||
count.AppendInt(int(mFileData->mFilesOrDirectories.Length()));
|
||||
|
||||
const char16_t* params[] = { count.get() };
|
||||
nsContentUtils::FormatLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
|
||||
@ -3005,19 +3088,27 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
|
||||
aValue = value;
|
||||
}
|
||||
|
||||
const nsTArray<OwningFileOrDirectory>&
|
||||
HTMLInputElement::GetFilesOrDirectoriesInternal() const
|
||||
{
|
||||
return mFileData->mFilesOrDirectories;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories,
|
||||
bool aSetValueChanged)
|
||||
{
|
||||
ClearGetFilesHelpers();
|
||||
MOZ_ASSERT(mFileData);
|
||||
|
||||
mFileData->ClearGetFilesHelpers();
|
||||
|
||||
if (IsWebkitFileSystemEnabled()) {
|
||||
HTMLInputElementBinding::ClearCachedWebkitEntriesValue(this);
|
||||
mEntries.Clear();
|
||||
mFileData->mEntries.Clear();
|
||||
}
|
||||
|
||||
mFilesOrDirectories.Clear();
|
||||
mFilesOrDirectories.AppendElements(aFilesOrDirectories);
|
||||
mFileData->mFilesOrDirectories.Clear();
|
||||
mFileData->mFilesOrDirectories.AppendElements(aFilesOrDirectories);
|
||||
|
||||
AfterSetFilesOrDirectories(aSetValueChanged);
|
||||
}
|
||||
@ -3026,20 +3117,23 @@ void
|
||||
HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
|
||||
bool aSetValueChanged)
|
||||
{
|
||||
MOZ_ASSERT(mFileData);
|
||||
|
||||
RefPtr<FileList> files = static_cast<FileList*>(aFiles);
|
||||
mFilesOrDirectories.Clear();
|
||||
ClearGetFilesHelpers();
|
||||
mFileData->mFilesOrDirectories.Clear();
|
||||
mFileData->ClearGetFilesHelpers();
|
||||
|
||||
if (IsWebkitFileSystemEnabled()) {
|
||||
HTMLInputElementBinding::ClearCachedWebkitEntriesValue(this);
|
||||
mEntries.Clear();
|
||||
mFileData->mEntries.Clear();
|
||||
}
|
||||
|
||||
if (aFiles) {
|
||||
uint32_t listLength;
|
||||
aFiles->GetLength(&listLength);
|
||||
for (uint32_t i = 0; i < listLength; i++) {
|
||||
OwningFileOrDirectory* element = mFilesOrDirectories.AppendElement();
|
||||
OwningFileOrDirectory* element =
|
||||
mFileData->mFilesOrDirectories.AppendElement();
|
||||
element->SetAsFile() = files->Item(i);
|
||||
}
|
||||
}
|
||||
@ -3051,6 +3145,10 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
|
||||
void
|
||||
HTMLInputElement::MozSetDndFilesAndDirectories(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories)
|
||||
{
|
||||
if (NS_WARN_IF(mType != NS_FORM_INPUT_FILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetFilesOrDirectories(aFilesOrDirectories, true);
|
||||
|
||||
if (IsWebkitFileSystemEnabled()) {
|
||||
@ -3094,11 +3192,12 @@ HTMLInputElement::AfterSetFilesOrDirectories(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 (mFilesOrDirectories.IsEmpty()) {
|
||||
mFirstFilePath.Truncate();
|
||||
if (mFileData->mFilesOrDirectories.IsEmpty()) {
|
||||
mFileData->mFirstFilePath.Truncate();
|
||||
} else {
|
||||
ErrorResult rv;
|
||||
GetDOMFileOrDirectoryPath(mFilesOrDirectories[0], mFirstFilePath, rv);
|
||||
GetDOMFileOrDirectoryPath(mFileData->mFilesOrDirectories[0],
|
||||
mFileData->mFirstFilePath, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
}
|
||||
@ -3146,12 +3245,12 @@ HTMLInputElement::GetFiles()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mFileList) {
|
||||
mFileList = new FileList(static_cast<nsIContent*>(this));
|
||||
if (!mFileData->mFileList) {
|
||||
mFileData->mFileList = new FileList(static_cast<nsIContent*>(this));
|
||||
UpdateFileList();
|
||||
}
|
||||
|
||||
return mFileList;
|
||||
return mFileData->mFileList;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
@ -3177,15 +3276,17 @@ HTMLInputElement::HandleNumberControlSpin(void* aData)
|
||||
void
|
||||
HTMLInputElement::UpdateFileList()
|
||||
{
|
||||
if (mFileList) {
|
||||
mFileList->Clear();
|
||||
MOZ_ASSERT(mFileData);
|
||||
|
||||
if (mFileData->mFileList) {
|
||||
mFileData->mFileList->Clear();
|
||||
|
||||
const nsTArray<OwningFileOrDirectory>& array =
|
||||
GetFilesOrDirectoriesInternal();
|
||||
|
||||
for (uint32_t i = 0; i < array.Length(); ++i) {
|
||||
if (array[i].IsFile()) {
|
||||
mFileList->Append(array[i].GetAsFile());
|
||||
mFileData->mFileList->Append(array[i].GetAsFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5086,10 +5187,12 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType, bool aNotify)
|
||||
MOZ_ASSERT(oldType != aNewType);
|
||||
|
||||
if (aNewType == NS_FORM_INPUT_FILE || oldType == NS_FORM_INPUT_FILE) {
|
||||
// Strictly speaking, we only need to clear files on going _to_ or _from_
|
||||
// the NS_FORM_INPUT_FILE type, not both, since we'll never confuse values
|
||||
// and filenames. But this is safer.
|
||||
ClearFiles(false);
|
||||
if (aNewType == NS_FORM_INPUT_FILE) {
|
||||
mFileData.reset(new FileData());
|
||||
} else {
|
||||
mFileData->Unlink();
|
||||
mFileData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldType == NS_FORM_INPUT_RANGE && mIsDraggingRange) {
|
||||
@ -6647,9 +6750,9 @@ HTMLInputElement::SaveState()
|
||||
}
|
||||
break;
|
||||
case VALUE_MODE_FILENAME:
|
||||
if (!mFilesOrDirectories.IsEmpty()) {
|
||||
if (!mFileData->mFilesOrDirectories.IsEmpty()) {
|
||||
inputState = new HTMLInputElementState();
|
||||
inputState->SetFilesOrDirectories(mFilesOrDirectories);
|
||||
inputState->SetFilesOrDirectories(mFileData->mFilesOrDirectories);
|
||||
}
|
||||
break;
|
||||
case VALUE_MODE_VALUE:
|
||||
@ -8574,24 +8677,12 @@ HTMLInputElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
return HTMLInputElementBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::ClearGetFilesHelpers()
|
||||
{
|
||||
if (mGetFilesRecursiveHelper) {
|
||||
mGetFilesRecursiveHelper->Unlink();
|
||||
mGetFilesRecursiveHelper = nullptr;
|
||||
}
|
||||
|
||||
if (mGetFilesNonRecursiveHelper) {
|
||||
mGetFilesNonRecursiveHelper->Unlink();
|
||||
mGetFilesNonRecursiveHelper = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
GetFilesHelper*
|
||||
HTMLInputElement::GetOrCreateGetFilesHelper(bool aRecursiveFlag,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(mFileData);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
|
||||
MOZ_ASSERT(global);
|
||||
if (!global) {
|
||||
@ -8600,36 +8691,36 @@ HTMLInputElement::GetOrCreateGetFilesHelper(bool aRecursiveFlag,
|
||||
}
|
||||
|
||||
if (aRecursiveFlag) {
|
||||
if (!mGetFilesRecursiveHelper) {
|
||||
mGetFilesRecursiveHelper =
|
||||
GetFilesHelper::Create(global,
|
||||
GetFilesOrDirectoriesInternal(),
|
||||
aRecursiveFlag, aRv);
|
||||
if (!mFileData->mGetFilesRecursiveHelper) {
|
||||
mFileData->mGetFilesRecursiveHelper =
|
||||
GetFilesHelper::Create(global,
|
||||
GetFilesOrDirectoriesInternal(),
|
||||
aRecursiveFlag, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return mGetFilesRecursiveHelper;
|
||||
return mFileData->mGetFilesRecursiveHelper;
|
||||
}
|
||||
|
||||
if (!mGetFilesNonRecursiveHelper) {
|
||||
mGetFilesNonRecursiveHelper =
|
||||
GetFilesHelper::Create(global,
|
||||
GetFilesOrDirectoriesInternal(),
|
||||
aRecursiveFlag, aRv);
|
||||
if (!mFileData->mGetFilesNonRecursiveHelper) {
|
||||
mFileData->mGetFilesNonRecursiveHelper =
|
||||
GetFilesHelper::Create(global,
|
||||
GetFilesOrDirectoriesInternal(),
|
||||
aRecursiveFlag, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return mGetFilesNonRecursiveHelper;
|
||||
return mFileData->mGetFilesNonRecursiveHelper;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories)
|
||||
{
|
||||
MOZ_ASSERT(mEntries.IsEmpty());
|
||||
MOZ_ASSERT(mFileData && mFileData->mEntries.IsEmpty());
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
|
||||
MOZ_ASSERT(global);
|
||||
@ -8654,14 +8745,18 @@ HTMLInputElement::UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrD
|
||||
// dropped fileEntry and directoryEntry objects.
|
||||
fs->CreateRoot(entries);
|
||||
|
||||
mEntries.SwapElements(entries);
|
||||
mFileData->mEntries.SwapElements(entries);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence)
|
||||
{
|
||||
if (NS_WARN_IF(mType != NS_FORM_INPUT_FILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::BLINK_FILESYSTEM_USED, true);
|
||||
aSequence.AppendElements(mEntries);
|
||||
aSequence.AppendElements(mFileData->mEntries);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -256,10 +256,7 @@ public:
|
||||
|
||||
void GetDisplayFileName(nsAString& aFileName) const;
|
||||
|
||||
const nsTArray<OwningFileOrDirectory>& GetFilesOrDirectoriesInternal() const
|
||||
{
|
||||
return mFilesOrDirectories;
|
||||
}
|
||||
const nsTArray<OwningFileOrDirectory>& GetFilesOrDirectoriesInternal() const;
|
||||
|
||||
void SetFilesOrDirectories(const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories,
|
||||
bool aSetValueChanged);
|
||||
@ -1533,30 +1530,8 @@ protected:
|
||||
nsTextEditorState* mState;
|
||||
} mInputData;
|
||||
|
||||
/**
|
||||
* The value of the input if it is a file input. This is the list of files or
|
||||
* directories DOM objects used when uploading a file. It is vital that this
|
||||
* is kept separate from mValue so that it won't be possible to 'leak' the
|
||||
* value from a text-input to a file-input. Additionally, the logic for this
|
||||
* value is kept as simple as possible to avoid accidental errors where the
|
||||
* wrong filename is used. Therefor the list of filenames is always owned by
|
||||
* this member, never by the frame. Whenever the frame wants to change the
|
||||
* filename it has to call SetFilesOrDirectories to update this member.
|
||||
*/
|
||||
nsTArray<OwningFileOrDirectory> mFilesOrDirectories;
|
||||
|
||||
RefPtr<GetFilesHelper> mGetFilesRecursiveHelper;
|
||||
RefPtr<GetFilesHelper> mGetFilesNonRecursiveHelper;
|
||||
|
||||
/**
|
||||
* Hack for bug 1086684: Stash the .value when we're a file picker.
|
||||
*/
|
||||
nsString mFirstFilePath;
|
||||
|
||||
RefPtr<FileList> mFileList;
|
||||
Sequence<RefPtr<FileSystemEntry>> mEntries;
|
||||
|
||||
nsString mStaticDocFileList;
|
||||
struct FileData;
|
||||
UniquePtr<FileData> mFileData;
|
||||
|
||||
/**
|
||||
* The value of the input element when first initialized and it is updated
|
||||
|
Loading…
Reference in New Issue
Block a user