Bug 598236 - nsHTMLInputElement should not ask nsFileControlFrame to know the filters for the file picker. r=smaug a=sicking

This commit is contained in:
Mounir Lamouri 2010-10-08 12:07:20 +02:00
Родитель b618e9252c
Коммит 3f99189d6b
4 изменённых файлов: 57 добавлений и 51 удалений

Просмотреть файл

@ -100,8 +100,6 @@
#include "nsILocalFile.h" #include "nsILocalFile.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsDOMFile.h" #include "nsDOMFile.h"
#include "nsFileControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsIFilePicker.h" #include "nsIFilePicker.h"
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
#include "nsIPrivateBrowsingService.h" #include "nsIPrivateBrowsingService.h"
@ -305,9 +303,6 @@ AsyncClickHandler::Run()
if (!filePicker) if (!filePicker)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
nsFileControlFrame* frame =
static_cast<nsFileControlFrame*>(mInput->GetPrimaryFrame());
PRBool multi; PRBool multi;
rv = mInput->GetMultiple(&multi); rv = mInput->GetMultiple(&multi);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -317,19 +312,22 @@ AsyncClickHandler::Run()
(PRInt16)nsIFilePicker::modeOpen); (PRInt16)nsIFilePicker::modeOpen);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// We want to get the file filter from the accept attribute and we add the if (mInput->HasAttr(kNameSpaceID_None, nsGkAtoms::accept)) {
// |filterAll| filter to be sure the user has a valid fallback. PRInt32 filters = mInput->GetFiltersFromAccept();
PRUint32 filter = 0;
if (frame)
filter = frame->GetFileFilterFromAccept();
filePicker->AppendFilters(filter | nsIFilePicker::filterAll);
// If the accept attribute asks for a filter, it has to be the default one. if (filters) {
if (filter) { // We add |filterAll| to be sure the user always has a sane fallback.
// We have two filters: |filterAll| and another one. |filterAll| is filePicker->AppendFilters(filters | nsIFilePicker::filterAll);
// always the first one (index=0) so we can assume the one we want to be
// the default is at index 1. // If the accept attribute asked for a filter, we need to make it default.
filePicker->SetFilterIndex(1); // |filterAll| will always use index=0 so we need to set index=1 as the
// current filter.
filePicker->SetFilterIndex(1);
} else {
filePicker->AppendFilters(nsIFilePicker::filterAll);
}
} else {
filePicker->AppendFilters(nsIFilePicker::filterAll);
} }
// Set default directry and filename // Set default directry and filename
@ -4413,3 +4411,32 @@ nsHTMLInputElement::FieldSetDisabledChanged(PRInt32 aStates)
nsGenericHTMLFormElement::FieldSetDisabledChanged(aStates); nsGenericHTMLFormElement::FieldSetDisabledChanged(aStates);
} }
PRInt32
nsHTMLInputElement::GetFiltersFromAccept()
{
NS_ASSERTION(HasAttr(kNameSpaceID_None, nsGkAtoms::accept),
"You should not call GetFileFiltersFromAccept if the element"
" has no accept attribute!");
PRInt32 filters = 0;
nsAutoString accept;
GetAttr(kNameSpaceID_None, nsGkAtoms::accept, accept);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
tokenizer(accept, ',');
while (tokenizer.hasMoreTokens()) {
const nsDependentSubstring token = tokenizer.nextToken();
if (token.EqualsLiteral("image/*")) {
filters |= nsIFilePicker::filterImages;
} else if (token.EqualsLiteral("audio/*")) {
filters |= nsIFilePicker::filterAudio;
} else if (token.EqualsLiteral("video/*")) {
filters |= nsIFilePicker::filterVideo;
}
}
return filters;
}

Просмотреть файл

@ -279,6 +279,19 @@ public:
nsresult GetValidationMessage(nsAString& aValidationMessage, nsresult GetValidationMessage(nsAString& aValidationMessage,
ValidityStateType aType); ValidityStateType aType);
/**
* Returns the filter which should be used for the file picker according to
* the accept attribute value.
*
* See:
* http://dev.w3.org/html5/spec/forms.html#attr-input-accept
*
* @return Filters to use on the file picker with AppendFilters, 0 if none.
*
* @note You should not call this function if the element has no @accept.
*/
PRInt32 GetFiltersFromAccept();
protected: protected:
// Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden // Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden
// by the nsITextControlElement version. // by the nsITextControlElement version.

Просмотреть файл

@ -719,28 +719,6 @@ nsFileControlFrame::ParseAcceptAttribute(AcceptAttrCallback aCallback,
(*aCallback)(tokenizer.nextToken(), aClosure)); (*aCallback)(tokenizer.nextToken(), aClosure));
} }
PRBool FileFilterCallback(const nsAString& aVal, void* aClosure)
{
PRInt32* filter = (PRInt32*)aClosure;
if (aVal.EqualsLiteral("image/*")) {
*filter |= nsIFilePicker::filterImages;
} else if (aVal.EqualsLiteral("audio/*")) {
*filter |= nsIFilePicker::filterAudio;
} else if (aVal.EqualsLiteral("video/*")) {
*filter |= nsIFilePicker::filterVideo;
}
return PR_TRUE;
}
PRInt32
nsFileControlFrame::GetFileFilterFromAccept() const
{
PRInt32 filterVal = 0;
this->ParseAcceptAttribute(&FileFilterCallback, (void*)&filterVal);
return filterVal;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Mouse listener implementation // Mouse listener implementation

Просмотреть файл

@ -99,18 +99,6 @@ public:
virtual already_AddRefed<nsAccessible> CreateAccessible(); virtual already_AddRefed<nsAccessible> CreateAccessible();
#endif #endif
/**
* This methods return the file filter mask requested by the HTML5 accept
* attribute. If the accept attribute isn't present or the value isn't valid,
* the returned value will be 0.
*
* See:
* http://dev.w3.org/html5/spec/forms.html#attr-input-accept
*
* @return the file picker filter mask or 0 if there is no filter.
*/
PRInt32 GetFileFilterFromAccept() const;
typedef PRBool (*AcceptAttrCallback)(const nsAString&, void*); typedef PRBool (*AcceptAttrCallback)(const nsAString&, void*);
void ParseAcceptAttribute(AcceptAttrCallback aCallback, void* aClosure) const; void ParseAcceptAttribute(AcceptAttrCallback aCallback, void* aClosure) const;