Backed out changeset 17e20404362d (bug 1258489)

This commit is contained in:
Wes Kocher
2016-05-23 12:46:05 -07:00
parent 8aa935c1d5
commit bc4a58f2ac
10 changed files with 45 additions and 395 deletions

View File

@@ -218,18 +218,6 @@ const Decimal HTMLInputElement::kStepAny = Decimal(0);
#define PROGRESS_STR "progress"
static const uint32_t kProgressEventInterval = 50; // ms
class GetFilesCallback
{
public:
NS_INLINE_DECL_REFCOUNTING(GetFilesCallback);
virtual void
Callback(nsresult aStatus, const Sequence<RefPtr<File>>& aFiles) = 0;
protected:
virtual ~GetFilesCallback() {}
};
// Retrieving the list of files can be very time/IO consuming. We use this
// helper class to do it just once.
class GetFilesHelper final : public Runnable
@@ -307,21 +295,6 @@ public:
ResolveOrRejectPromise(aPromise);
}
void
AddCallback(GetFilesCallback* aCallback)
{
MOZ_ASSERT(aCallback);
// Still working.
if (!mListingCompleted) {
mCallbacks.AppendElement(aCallback);
return;
}
MOZ_ASSERT(mCallbacks.IsEmpty());
RunCallback(aCallback);
}
// CC methods
void Unlink()
{
@@ -380,14 +353,6 @@ private:
ResolveOrRejectPromise(promises[i]);
}
// Let's process the pending callbacks.
nsTArray<RefPtr<GetFilesCallback>> callbacks;
callbacks.SwapElements(mCallbacks);
for (uint32_t i = 0; i < callbacks.Length(); ++i) {
RunCallback(callbacks[i]);
}
return NS_OK;
}
@@ -542,16 +507,6 @@ private:
aPromise->MaybeResolve(mFiles);
}
void
RunCallback(GetFilesCallback* aCallback)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mListingCompleted);
MOZ_ASSERT(aCallback);
aCallback->Callback(mErrorResult, mFiles);
}
nsCOMPtr<nsIGlobalObject> mGlobal;
bool mRecursiveFlag;
@@ -573,78 +528,6 @@ private:
nsresult mErrorResult;
nsTArray<RefPtr<Promise>> mPromises;
nsTArray<RefPtr<GetFilesCallback>> mCallbacks;
};
// An helper class for the dispatching of the 'change' event.
class DispatchChangeEventCallback final : public GetFilesCallback
{
public:
explicit DispatchChangeEventCallback(HTMLInputElement* aInputElement)
: mInputElement(aInputElement)
{
MOZ_ASSERT(aInputElement);
}
virtual void
Callback(nsresult aStatus, const Sequence<RefPtr<File>>& aFiles) override
{
nsTArray<OwningFileOrDirectory> array;
for (uint32_t i = 0; i < aFiles.Length(); ++i) {
OwningFileOrDirectory* element = array.AppendElement();
element->SetAsFile() = aFiles[i];
}
mInputElement->SetFilesOrDirectories(array, true);
NS_WARN_IF(NS_FAILED(DispatchEvents()));
}
nsresult
DispatchEvents()
{
nsresult rv = NS_OK;
rv = nsContentUtils::DispatchTrustedEvent(mInputElement->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInputElement.get()),
NS_LITERAL_STRING("input"), true,
false);
NS_WARN_IF(NS_FAILED(rv));
rv = nsContentUtils::DispatchTrustedEvent(mInputElement->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInputElement.get()),
NS_LITERAL_STRING("change"), true,
false);
return rv;
}
private:
RefPtr<HTMLInputElement> mInputElement;
};
// This callback is used for postponing the calling of SetFilesOrDirectories
// when the exploration of the directory is completed.
class AfterSetFilesOrDirectoriesCallback : public GetFilesCallback
{
public:
AfterSetFilesOrDirectoriesCallback(HTMLInputElement* aInputElement,
bool aSetValueChanged)
: mInputElement(aInputElement)
, mSetValueChanged(aSetValueChanged)
{
MOZ_ASSERT(aInputElement);
}
void
Callback(nsresult aStatus, const Sequence<RefPtr<File>>& aFiles) override
{
if (NS_SUCCEEDED(aStatus)) {
mInputElement->AfterSetFilesOrDirectoriesInternal(mSetValueChanged);
}
}
private:
RefPtr<HTMLInputElement> mInputElement;
bool mSetValueChanged;
};
class HTMLInputElementState final : public nsISupports
@@ -979,22 +862,19 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
// So, we can safely send one by ourself.
mInput->SetFilesOrDirectories(newFilesOrDirectories, true);
RefPtr<DispatchChangeEventCallback> dispatchChangeEventCallback =
new DispatchChangeEventCallback(mInput);
nsresult rv = NS_OK;
rv = nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("input"), true,
false);
NS_WARN_IF(NS_FAILED(rv));
if (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
mInput->HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)) {
ErrorResult error;
GetFilesHelper* helper = mInput->GetOrCreateGetFilesHelper(true, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
rv = nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
false);
helper->AddCallback(dispatchChangeEventCallback);
return NS_OK;
}
return dispatchChangeEventCallback->DispatchEvents();
return rv;
}
NS_IMPL_ISUPPORTS(HTMLInputElement::nsFilePickerShownCallback,
@@ -3037,19 +2917,6 @@ HTMLInputElement::SetFiles(nsIDOMFileList* aFiles,
void
HTMLInputElement::AfterSetFilesOrDirectories(bool aSetValueChanged)
{
if (Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)) {
// This will call AfterSetFilesOrDirectoriesInternal eventually.
ExploreDirectoryRecursively(aSetValueChanged);
return;
}
AfterSetFilesOrDirectoriesInternal(aSetValueChanged);
}
void
HTMLInputElement::AfterSetFilesOrDirectoriesInternal(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
@@ -3113,9 +2980,7 @@ HTMLInputElement::GetFiles()
}
if (Preferences::GetBool("dom.input.dirpicker", false) &&
HasAttr(kNameSpaceID_None, nsGkAtoms::directory) &&
(!Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) ||
!HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
HasAttr(kNameSpaceID_None, nsGkAtoms::directory)) {
return nullptr;
}
@@ -4205,10 +4070,8 @@ HTMLInputElement::MaybeInitPickers(EventChainPostVisitor& aVisitor)
if (target &&
target->GetParent() == this &&
target->IsRootOfNativeAnonymousSubtree() &&
(target->HasAttr(kNameSpaceID_None, nsGkAtoms::directory) ||
target->HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
MOZ_ASSERT(Preferences::GetBool("dom.input.dirpicker", false) ||
Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false),
target->HasAttr(kNameSpaceID_None, nsGkAtoms::directory)) {
MOZ_ASSERT(Preferences::GetBool("dom.input.dirpicker", false),
"No API or UI should have been exposed to allow this code to "
"be reached");
type = FILE_PICKER_DIRECTORY;
@@ -5418,8 +5281,7 @@ HTMLInputElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
if (aAttribute == nsGkAtoms::type ||
// The presence or absence of the 'directory' attribute determines what
// buttons we show for type=file.
aAttribute == nsGkAtoms::directory ||
aAttribute == nsGkAtoms::webkitdirectory) {
aAttribute == nsGkAtoms::directory) {
retval |= NS_STYLE_HINT_FRAMECHANGE;
} else if (mType == NS_FORM_INPUT_IMAGE &&
(aAttribute == nsGkAtoms::alt ||
@@ -5555,18 +5417,41 @@ HTMLInputElement::GetFiles(bool aRecursiveFlag, ErrorResult& aRv)
return nullptr;
}
GetFilesHelper* helper = GetOrCreateGetFilesHelper(aRecursiveFlag, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
MOZ_ASSERT(helper);
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
MOZ_ASSERT(global);
if (!global) {
return nullptr;
}
RefPtr<GetFilesHelper> helper;
if (aRecursiveFlag) {
if (!mGetFilesRecursiveHelper) {
mGetFilesRecursiveHelper =
GetFilesHelper::Create(global,
GetFilesOrDirectoriesInternal(),
aRecursiveFlag, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
helper = mGetFilesRecursiveHelper;
} else {
if (!mGetFilesNonRecursiveHelper) {
mGetFilesNonRecursiveHelper =
GetFilesHelper::Create(global,
GetFilesOrDirectoriesInternal(),
aRecursiveFlag, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
helper = mGetFilesNonRecursiveHelper;
}
MOZ_ASSERT(helper);
RefPtr<Promise> p = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
@@ -8087,60 +7972,6 @@ HTMLInputElement::ClearGetFilesHelpers()
}
}
GetFilesHelper*
HTMLInputElement::GetOrCreateGetFilesHelper(bool aRecursiveFlag,
ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = OwnerDoc()->GetScopeObject();
MOZ_ASSERT(global);
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
if (aRecursiveFlag) {
if (!mGetFilesRecursiveHelper) {
mGetFilesRecursiveHelper =
GetFilesHelper::Create(global,
GetFilesOrDirectoriesInternal(),
aRecursiveFlag, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
return mGetFilesRecursiveHelper;
}
if (!mGetFilesNonRecursiveHelper) {
mGetFilesNonRecursiveHelper =
GetFilesHelper::Create(global,
GetFilesOrDirectoriesInternal(),
aRecursiveFlag, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
return mGetFilesNonRecursiveHelper;
}
void
HTMLInputElement::ExploreDirectoryRecursively(bool aSetValueChanged)
{
ErrorResult rv;
GetFilesHelper* helper = GetOrCreateGetFilesHelper(true /* recursionFlag */,
rv);
if (NS_WARN_IF(rv.Failed())) {
AfterSetFilesOrDirectoriesInternal(aSetValueChanged);
return;
}
RefPtr<AfterSetFilesOrDirectoriesCallback> callback =
new AfterSetFilesOrDirectoriesCallback(this, aSetValueChanged);
helper->AddCallback(callback);
}
} // namespace dom
} // namespace mozilla