https://bugs.webkit.org/show_bug.cgi?id=116195
Reviewed by Andreas Kling.
FileChooserClient doesn't match the standard WebCore client idiom of only having virtual member functions.
Instead it holds on to its FileChooser and it's even a factory for creating new file choosers(!).
Fix this by making it an abstract class, and moving FileChooser into FileInputType.
* html/FileInputType.cpp:
(WebCore::FileInputType::~FileInputType):
Invalidate the file chooser.
(WebCore::FileInputType::handleDOMActivateEvent):
Apply the file chooser settings.
(WebCore::FileInputType::applyFileChooserSettings):
Recreate the file chooser with new settings.
(WebCore::FileInputType::receiveDropForDirectoryUpload):
Apply the settings.
* platform/FileChooser.cpp:
(WebCore::FileChooser::invalidate):
Set m_client to null.
(WebCore::FileChooser::chooseFiles):
Early return.
* platform/FileChooser.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@150163
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2013-05-15 Anders Carlsson <andersca@apple.com>
+
+ Fix FileChooserClient design
+ https://bugs.webkit.org/show_bug.cgi?id=116195
+
+ Reviewed by Andreas Kling.
+
+ FileChooserClient doesn't match the standard WebCore client idiom of only having virtual member functions.
+ Instead it holds on to its FileChooser and it's even a factory for creating new file choosers(!).
+
+ Fix this by making it an abstract class, and moving FileChooser into FileInputType.
+
+ * html/FileInputType.cpp:
+ (WebCore::FileInputType::~FileInputType):
+ Invalidate the file chooser.
+
+ (WebCore::FileInputType::handleDOMActivateEvent):
+ Apply the file chooser settings.
+
+ (WebCore::FileInputType::applyFileChooserSettings):
+ Recreate the file chooser with new settings.
+
+ (WebCore::FileInputType::receiveDropForDirectoryUpload):
+ Apply the settings.
+
+ * platform/FileChooser.cpp:
+ (WebCore::FileChooser::invalidate):
+ Set m_client to null.
+
+ (WebCore::FileChooser::chooseFiles):
+ Early return.
+
+ * platform/FileChooser.h:
+
2013-05-15 Gavin Barraclough <barraclough@apple.com>
ScriptedAnimationController::setThrottled should extend MinimumAnimationInterval
return pseudoId;
}
-inline FileInputType::FileInputType(HTMLInputElement* element)
+PassOwnPtr<InputType> FileInputType::create(HTMLInputElement* element)
+{
+ return adoptPtr(new FileInputType(element));
+}
+
+FileInputType::FileInputType(HTMLInputElement* element)
: BaseClickableWithKeyInputType(element)
, m_fileList(FileList::create())
{
}
-PassOwnPtr<InputType> FileInputType::create(HTMLInputElement* element)
+FileInputType::~FileInputType()
{
- return adoptPtr(new FileInputType(element));
+ if (m_fileChooser)
+ m_fileChooser->invalidate();
}
Vector<FileChooserFileInfo> FileInputType::filesFromFormControlState(const FormControlState& state)
#if ENABLE(MEDIA_CAPTURE)
settings.capture = input->capture();
#endif
- chrome->runOpenPanel(input->document()->frame(), newFileChooser(settings));
+
+ applyFileChooserSettings(settings);
+ chrome->runOpenPanel(input->document()->frame(), m_fileChooser);
}
+
event->setDefaultHandled();
}
chrome->loadIconForFiles(paths, newFileIconLoader());
}
+void FileInputType::applyFileChooserSettings(const FileChooserSettings& settings)
+{
+ if (m_fileChooser)
+ m_fileChooser->invalidate();
+
+ m_fileChooser = FileChooser::create(this, settings);
+}
+
void FileInputType::setFiles(PassRefPtr<FileList> files)
{
if (!files)
#if ENABLE(DIRECTORY_UPLOAD)
void FileInputType::receiveDropForDirectoryUpload(const Vector<String>& paths)
{
- if (Chrome* chrome = this->chrome()) {
- FileChooserSettings settings;
- HTMLInputElement* input = element();
- settings.allowsDirectoryUpload = true;
- settings.allowsMultipleFiles = true;
- settings.selectedFiles.append(paths[0]);
- settings.acceptMIMETypes = input->acceptMIMETypes();
- settings.acceptFileExtensions = input->acceptFileExtensions();
- chrome->enumerateChosenDirectory(newFileChooser(settings));
- }
+ Chrome* chrome = this->chrome();
+ if (!chrome)
+ return;
+
+ FileChooserSettings settings;
+ HTMLInputElement* input = element();
+ settings.allowsDirectoryUpload = true;
+ settings.allowsMultipleFiles = true;
+ settings.selectedFiles.append(paths[0]);
+ settings.acceptMIMETypes = input->acceptMIMETypes();
+ settings.acceptFileExtensions = input->acceptFileExtensions();
+
+ applyFileChooserSettings(settings);
+ chrome->enumerateChosenDirectory(m_fileChooser);
}
#endif
return names.toString();
}
+
} // namespace WebCore
class FileInputType : public BaseClickableWithKeyInputType, private FileChooserClient, private FileIconLoaderClient {
public:
static PassOwnPtr<InputType> create(HTMLInputElement*);
+ virtual ~FileInputType();
+
static Vector<FileChooserFileInfo> filesFromFormControlState(const FormControlState&);
private:
FileInputType(HTMLInputElement*);
+
virtual const AtomicString& formControlType() const OVERRIDE;
virtual FormControlState saveFormControlState() const OVERRIDE;
virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
#endif
void requestIcon(const Vector<String>&);
+ void applyFileChooserSettings(const FileChooserSettings&);
+
+ RefPtr<FileChooser> m_fileChooser;
+
RefPtr<FileList> m_fileList;
RefPtr<Icon> m_icon;
namespace WebCore {
-FileChooserClient::~FileChooserClient()
-{
- discardChooser();
-}
-
-FileChooser* FileChooserClient::newFileChooser(const FileChooserSettings& settings)
-{
- discardChooser();
-
- m_chooser = FileChooser::create(this, settings);
- return m_chooser.get();
-}
-
-void FileChooserClient::discardChooser()
-{
- if (m_chooser)
- m_chooser->disconnectClient();
-}
-
-inline FileChooser::FileChooser(FileChooserClient* client, const FileChooserSettings& settings)
+FileChooser::FileChooser(FileChooserClient* client, const FileChooserSettings& settings)
: m_client(client)
, m_settings(settings)
{
{
}
+void FileChooser::invalidate()
+{
+ ASSERT(m_client);
+
+ m_client = 0;
+}
+
void FileChooser::chooseFile(const String& filename)
{
Vector<String> filenames;
if (m_settings.selectedFiles == filenames)
return;
- if (m_client) {
- Vector<FileChooserFileInfo> files;
- for (unsigned i = 0; i < filenames.size(); ++i)
- files.append(FileChooserFileInfo(filenames[i]));
- m_client->filesChosen(files);
- }
+ if (!m_client)
+ return;
+
+ Vector<FileChooserFileInfo> files;
+ for (unsigned i = 0; i < filenames.size(); ++i)
+ files.append(FileChooserFileInfo(filenames[i]));
+ m_client->filesChosen(files);
}
void FileChooser::chooseFiles(const Vector<FileChooserFileInfo>& files)
Vector<String> paths;
for (unsigned i = 0; i < files.size(); ++i)
paths.append(files[i].path);
+
if (m_settings.selectedFiles == paths)
return;
class FileChooserClient {
public:
- virtual void filesChosen(const Vector<FileChooserFileInfo>&) = 0;
- virtual ~FileChooserClient();
-
-protected:
- FileChooser* newFileChooser(const FileChooserSettings&);
+ virtual ~FileChooserClient() { }
-private:
- void discardChooser();
-
- RefPtr<FileChooser> m_chooser;
+ virtual void filesChosen(const Vector<FileChooserFileInfo>&) = 0;
};
class FileChooser : public RefCounted<FileChooser> {
static PassRefPtr<FileChooser> create(FileChooserClient*, const FileChooserSettings&);
~FileChooser();
- void disconnectClient() { m_client = 0; }
+ void invalidate();
void chooseFile(const String& path);
void chooseFiles(const Vector<String>& paths);