Commit f3d6b894 authored by adele@apple.com's avatar adele@apple.com

WebCore:

2008-04-28  Adele Peterson  <adele@apple.com>

        Reviewed by Dan Bernstein, Tim Hatcher, Anders Carlsson, and Darin Adler.

        WebCore part of fix for <rdar://problem/3709505>
        Safari should have a way to upload bundles from the file upload control (as zip)

        * WebCore.base.exp: Added symbols.

        * html/HTMLFormElement.cpp: (WebCore::HTMLFormElement::formData): Ask the application if a file will need to be replaced before it's uploaded.
          It will also give the replacement filename which is used to determine the correct mime-type and to construct the correct header.

        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::submitForm): Asks the application to generate any files for the form data before a form submission starts.
        (WebCore::FrameLoader::loadItem): ditto.
        * loader/ResourceLoader.cpp:
        (WebCore::ResourceLoader::didReceiveResponse): Tells the FormData from the request to remove any generated files if it needs to.
        (WebCore::ResourceLoader::didCancel): ditto.
        (WebCore::ResourceLoader::didFail): ditto.

        * platform/network/FormData.cpp:
        (WebCore::FormData::FormData): Initializes m_hasGeneratedFiles, which keeps track of whether there are files that will need to be removed.
        (WebCore::FormData::~FormData): Added.  Assert that there are no files that need to be removed, but if there are, release builds will still remove them here.
        (WebCore::FormData::appendFile): Passes along a shouldGenerateFile flag to the FormDataElement.
        (WebCore::FormData::generateFiles): Added. Iterates through the FormDataElements, and using the ChromeClient pointer, asks the application to
         create any compressed files so the FormDataElements can store the paths.
        (WebCore::FormData::removeGeneratedFilesIfNeeded): Added.  Removes generated files and their directories (if empty).
        * platform/network/FormData.h:
        (WebCore::FormDataElement::FormDataElement): Added a boolean to track whether the file will need to be generated,
         and a string to hold the path of the generated file.

        * platform/network/mac/FormDataStreamMac.mm:
        (WebCore::advanceCurrentStream): Uses the generated file path instead of the original file path when streaming the file.
        (WebCore::setHTTPBody): Uses the generated file path when determining the size of the file to be uploaded.

        * platform/FileSystem.h: Added directoryName.
        * platform/posix/FileSystemPOSIX.cpp: (WebCore::directoryName): Added.
        * platform/gtk/FileSystemGtk.cpp: (WebCore::directoryName): Added empty implementation.
        * platform/qt/FileSystemQt.cpp: (WebCore::directoryName): ditto.
        * platform/win/FileSystemWin.cpp: (WebCore::directoryName): ditto.
        * platform/wx/FileSystemWx.cpp: (WebCore::directoryName): ditto.

        Added new ChromeClient methods to give the application control over the file compression for uploading.
        * page/Chrome.cpp:
        (WebCore::ChromeClient::shouldReplaceWithGeneratedFileForUpload): Added a default implementation.
        (WebCore::ChromeClient::generateReplacementFile): ditto.
        * page/ChromeClient.h:

WebKit/mac:

2008-04-28  Adele Peterson  <adele@apple.com>

        Reviewed by Dan Bernstein, Tim Hatcher, Anders Carlsson, and Darin Adler.

        WebKit part of fix for <rdar://problem/3709505>
        Safari should have a way to upload bundles from the file upload control (as zip)

        Added UIDelegate methods to let the application handle generating replacement files for uploads.
        In this case, Safari will create archived files for bundles so they can be uploaded properly.

        * DefaultDelegates/WebDefaultUIDelegate.m:
        (-[WebDefaultUIDelegate webView:shouldReplaceUploadFile:usingGeneratedFilename:]):
        (-[WebDefaultUIDelegate webView:generateReplacementFile:]):
        * WebCoreSupport/WebChromeClient.h:
        * WebCoreSupport/WebChromeClient.mm:
        (WebChromeClient::shouldReplaceWithGeneratedFileForUpload):
        (WebChromeClient::generateReplacementFile):
        * WebView/WebUIDelegatePrivate.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@32666 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 321e25f7
2008-04-28 Adele Peterson <adele@apple.com>
Reviewed by Dan Bernstein, Tim Hatcher, Anders Carlsson, and Darin Adler.
WebCore part of fix for <rdar://problem/3709505>
Safari should have a way to upload bundles from the file upload control (as zip)
* WebCore.base.exp: Added symbols.
* html/HTMLFormElement.cpp: (WebCore::HTMLFormElement::formData): Ask the application if a file will need to be replaced before it's uploaded.
It will also give the replacement filename which is used to determine the correct mime-type and to construct the correct header.
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::submitForm): Asks the application to generate any files for the form data before a form submission starts.
(WebCore::FrameLoader::loadItem): ditto.
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::didReceiveResponse): Tells the FormData from the request to remove any generated files if it needs to.
(WebCore::ResourceLoader::didCancel): ditto.
(WebCore::ResourceLoader::didFail): ditto.
* platform/network/FormData.cpp:
(WebCore::FormData::FormData): Initializes m_hasGeneratedFiles, which keeps track of whether there are files that will need to be removed.
(WebCore::FormData::~FormData): Added. Assert that there are no files that need to be removed, but if there are, release builds will still remove them here.
(WebCore::FormData::appendFile): Passes along a shouldGenerateFile flag to the FormDataElement.
(WebCore::FormData::generateFiles): Added. Iterates through the FormDataElements, and using the ChromeClient pointer, asks the application to
create any compressed files so the FormDataElements can store the paths.
(WebCore::FormData::removeGeneratedFilesIfNeeded): Added. Removes generated files and their directories (if empty).
* platform/network/FormData.h:
(WebCore::FormDataElement::FormDataElement): Added a boolean to track whether the file will need to be generated,
and a string to hold the path of the generated file.
* platform/network/mac/FormDataStreamMac.mm:
(WebCore::advanceCurrentStream): Uses the generated file path instead of the original file path when streaming the file.
(WebCore::setHTTPBody): Uses the generated file path when determining the size of the file to be uploaded.
* platform/FileSystem.h: Added directoryName.
* platform/posix/FileSystemPOSIX.cpp: (WebCore::directoryName): Added.
* platform/gtk/FileSystemGtk.cpp: (WebCore::directoryName): Added empty implementation.
* platform/qt/FileSystemQt.cpp: (WebCore::directoryName): ditto.
* platform/win/FileSystemWin.cpp: (WebCore::directoryName): ditto.
* platform/wx/FileSystemWx.cpp: (WebCore::directoryName): ditto.
Added new ChromeClient methods to give the application control over the file compression for uploading.
* page/Chrome.cpp:
(WebCore::ChromeClient::shouldReplaceWithGeneratedFileForUpload): Added a default implementation.
(WebCore::ChromeClient::generateReplacementFile): ditto.
* page/ChromeClient.h:
2008-04-28 Anders Carlsson <andersca@apple.com>
Reviewed by Sam, Mark, Adele and Darin.
......@@ -123,6 +123,7 @@ _WebCoreSetShouldUseFontSmoothing
_WebCoreShouldUseFontSmoothing
_WebCoreTextFloatWidth
__Z26ReportBlockedObjCExceptionP11NSException
__ZN3WTF10RefCountedIN7WebCore8FormDataEE5derefEv
__ZN7WebCore10CachedPage14documentLoaderEv
__ZN7WebCore10CachedPage22cachedPagePlatformDataEv
__ZN7WebCore10CachedPage25setCachedPagePlatformDataEPNS_22CachedPagePlatformDataE
......@@ -526,6 +527,7 @@ __ZN7WebCore8Document24setShouldCreateRenderersEb
__ZN7WebCore8Document36updateLayoutIgnorePendingStylesheetsEv
__ZN7WebCore8Document4bodyEv
__ZN7WebCore8DragDataC1EP11objc_objectRKNS_8IntPointES5_NS_13DragOperationEPNS_16PasteboardHelperE
__ZN7WebCore8FormDataD1Ev
__ZN7WebCore8IntPointC1ERK8_NSPoint
__ZN7WebCore8KJSProxy10initScriptEv
__ZN7WebCore8Settings14setJavaEnabledEb
......
......@@ -26,6 +26,8 @@
#include "HTMLFormElement.h"
#include "CSSHelper.h"
#include "ChromeClient.h"
#include "Document.h"
#include "Event.h"
#include "EventNames.h"
#include "FileSystem.h"
......@@ -39,6 +41,7 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "RenderTextControl.h"
#if PLATFORM(QT)
......@@ -263,6 +266,7 @@ PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const
header.append(item.m_data.data(), item.m_data.length());
header.append('"');
bool shouldGenerateFile = false;
// if the current type is FILE, then we also need to
// include the filename
if (control->hasLocalName(inputTag)
......@@ -270,6 +274,15 @@ PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const
String path = static_cast<HTMLInputElement*>(control)->value();
String filename = pathGetFileName(path);
// Let the application specify a filename if its going to generate a replacement file for the upload
if (Page* page = document()->page()) {
String generatedFilename;
shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFilename);
if (shouldGenerateFile)
filename = generatedFilename;
}
// FIXME: This won't work if the filename includes a " mark,
// or control characters like CR or LF. This also does strange
// things if the filename includes characters you can't encode
......@@ -278,8 +291,8 @@ PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const
appendString(header, encoding.encode(filename.characters(), filename.length(), QuestionMarksForUnencodables));
header.append('"');
if (!path.isEmpty()) {
String mimeType = MIMETypeRegistry::getMIMETypeForPath(path);
if (!filename.isEmpty()) {
String mimeType = MIMETypeRegistry::getMIMETypeForPath(filename);
if (!mimeType.isEmpty()) {
appendString(header, "\r\nContent-Type: ");
appendString(header, mimeType.latin1());
......@@ -295,7 +308,7 @@ PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const
if (size_t dataSize = item.m_data.length())
result->appendData(item.m_data.data(), dataSize);
else if (!item.m_path.isEmpty())
result->appendFile(item.m_path);
result->appendFile(item.m_path, shouldGenerateFile);
result->appendData("\r\n", 2);
++j;
......
......@@ -504,6 +504,9 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F
{
ASSERT(formData);
if (!m_frame->page())
return;
KURL u = completeURL(url.isNull() ? "" : url);
// FIXME: Do we really need to special-case an empty URL?
// Would it be better to just go on with the form submisson and let the I/O fail?
......@@ -525,6 +528,8 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F
return;
}
formData->generateFiles(m_frame->page()->chrome()->client());
FrameLoadRequest frameRequest;
if (!m_outgoingReferrer.isEmpty())
......@@ -4115,6 +4120,9 @@ void FrameLoader::saveDocumentState()
// Loads content into this frame, as specified by history item
void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
{
if (!m_frame->page())
return;
KURL itemURL = item->url();
KURL itemOriginalURL = item->originalURL();
KURL currentURL;
......@@ -4186,6 +4194,9 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
// If this was a repost that failed the page cache, we might try to repost the form.
NavigationAction action;
if (formData) {
formData->generateFiles(m_frame->page()->chrome()->client());
request.setHTTPMethod("POST");
request.setHTTPReferrer(item->formReferrer());
request.setHTTPBody(formData);
......
......@@ -225,6 +225,9 @@ void ResourceLoader::didReceiveResponse(const ResourceResponse& r)
m_response = r;
if (FormData* data = m_request.httpBody())
data->removeGeneratedFilesIfNeeded();
if (m_sendResourceLoadCallbacks)
frameLoader()->didReceiveResponse(this, m_response);
}
......@@ -293,6 +296,9 @@ void ResourceLoader::didFail(const ResourceError& error)
// anything including possibly derefing this; one example of this is Radar 3266216.
RefPtr<ResourceLoader> protector(this);
if (FormData* data = m_request.httpBody())
data->removeGeneratedFilesIfNeeded();
if (m_sendResourceLoadCallbacks && !m_calledDidFinishLoad)
frameLoader()->didFailToLoad(this, error);
......@@ -304,6 +310,9 @@ void ResourceLoader::didCancel(const ResourceError& error)
ASSERT(!m_cancelled);
ASSERT(!m_reachedTerminalState);
if (FormData* data = m_request.httpBody())
data->removeGeneratedFilesIfNeeded();
// This flag prevents bad behavior when loads that finish cause the
// load itself to be cancelled (which could happen with a javascript that
// changes the window location). This is used to prevent both the body
......
......@@ -366,6 +366,17 @@ void ChromeClient::paintCustomHighlight(Node*, const AtomicString&, const FloatR
{
}
bool ChromeClient::shouldReplaceWithGeneratedFileForUpload(const String&, String&)
{
return false;
}
String ChromeClient::generateReplacementFile(const String&)
{
ASSERT_NOT_REACHED();
return String();
}
// --------
PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
......
......@@ -127,6 +127,9 @@ namespace WebCore {
virtual FloatRect customHighlightRect(Node*, const AtomicString& type, const FloatRect& lineRect);
virtual void paintCustomHighlight(Node*, const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect,
bool behindText, bool entireLine);
virtual bool shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename);
virtual String generateReplacementFile(const String& path);
#if PLATFORM(MAC)
virtual void runOpenPanel(PassRefPtr<FileChooser>);
......
......@@ -88,6 +88,7 @@ String pathByAppendingComponent(const String& path, const String& component);
bool makeAllDirectories(const String& path);
String homeDirectoryPath();
String pathGetFileName(const String&);
String directoryName(const String&);
CString fileSystemRepresentation(const String&);
......
......@@ -140,6 +140,12 @@ String pathGetFileName(const String& pathName)
return fileName;
}
String directoryName(const String& path)
{
notImplemented();
return String();
}
CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
{
gchar* filename = g_strdup_printf("%sXXXXXX", prefix);
......
......@@ -21,14 +21,41 @@
#include "FormData.h"
#include "CString.h"
#include "ChromeClient.h"
#include "FileSystem.h"
#include "TextEncoding.h"
namespace WebCore {
inline FormData::FormData()
inline FormData::FormData() : m_hasGeneratedFiles(false)
{
}
inline FormData::FormData(const FormData& data)
: RefCounted<FormData>(1)
, m_elements(data.m_elements)
, m_hasGeneratedFiles(false)
{
// We shouldn't be copying FormData that hasn't already removed its generated files
// but just in case, make sure the new FormData is ready to generate its own files.
if (data.m_hasGeneratedFiles) {
size_t n = m_elements.size();
for (size_t i = 0; i < n; ++i) {
FormDataElement& e = m_elements[i];
if (e.m_type == FormDataElement::encodedFile)
e.m_generatedFilename = String();
}
}
}
FormData::~FormData()
{
// This cleanup should've happened when the form submission finished.
// Just in case, let's assert, and do the cleanup anyway in release builds.
ASSERT(!m_hasGeneratedFiles);
removeGeneratedFilesIfNeeded();
}
PassRefPtr<FormData> FormData::create()
{
return adoptRef(new FormData);
......@@ -55,12 +82,6 @@ PassRefPtr<FormData> FormData::create(const Vector<char>& vector)
return result.release();
}
inline FormData::FormData(const FormData& data)
: RefCounted<FormData>(1)
, m_elements(data.m_elements)
{
}
PassRefPtr<FormData> FormData::copy() const
{
return adoptRef(new FormData(*this));
......@@ -76,9 +97,9 @@ void FormData::appendData(const void* data, size_t size)
memcpy(e.m_data.data() + oldSize, data, size);
}
void FormData::appendFile(const String& filename)
void FormData::appendFile(const String& filename, bool shouldGenerateFile)
{
m_elements.append(filename);
m_elements.append(FormDataElement(filename, shouldGenerateFile));
}
void FormData::flatten(Vector<char>& data) const
......@@ -104,4 +125,40 @@ String FormData::flattenToString() const
return Latin1Encoding().decode(bytes.data(), bytes.size());
}
void FormData::generateFiles(ChromeClient* client)
{
ASSERT(!m_hasGeneratedFiles);
if (m_hasGeneratedFiles)
return;
size_t n = m_elements.size();
for (size_t i = 0; i < n; ++i) {
FormDataElement& e = m_elements[i];
if (e.m_type == FormDataElement::encodedFile && e.m_shouldGenerateFile) {
e.m_generatedFilename = client->generateReplacementFile(e.m_filename);
m_hasGeneratedFiles = true;
}
}
}
void FormData::removeGeneratedFilesIfNeeded()
{
if (!m_hasGeneratedFiles)
return;
size_t n = m_elements.size();
for (size_t i = 0; i < n; ++i) {
FormDataElement& e = m_elements[i];
if (e.m_type == FormDataElement::encodedFile && !e.m_generatedFilename.isEmpty()) {
ASSERT(e.m_shouldGenerateFile);
String directory = directoryName(e.m_generatedFilename);
deleteFile(e.m_generatedFilename);
deleteEmptyDirectory(directory);
e.m_generatedFilename = String();
}
}
m_hasGeneratedFiles = false;
}
} // namespace WebCore
......@@ -26,15 +26,19 @@
namespace WebCore {
class ChromeClient;
class FormDataElement {
public:
FormDataElement() : m_type(data) { }
FormDataElement(const Vector<char>& array) : m_type(data), m_data(array) { }
FormDataElement(const String& filename) : m_type(encodedFile), m_filename(filename) { }
FormDataElement(const String& filename, bool shouldGenerateFile) : m_type(encodedFile), m_filename(filename), m_shouldGenerateFile(shouldGenerateFile) { }
enum { data, encodedFile } m_type;
Vector<char> m_data;
String m_filename;
String m_generatedFilename;
bool m_shouldGenerateFile;
};
inline bool operator==(const FormDataElement& a, const FormDataElement& b)
......@@ -64,9 +68,10 @@ public:
static PassRefPtr<FormData> create(const CString&);
static PassRefPtr<FormData> create(const Vector<char>&);
PassRefPtr<FormData> copy() const;
~FormData();
void appendData(const void* data, size_t);
void appendFile(const String& filename);
void appendFile(const String& filename, bool shouldGenerateFile = false);
void flatten(Vector<char>&) const; // omits files
String flattenToString() const; // omits files
......@@ -74,11 +79,15 @@ public:
bool isEmpty() const { return m_elements.isEmpty(); }
const Vector<FormDataElement>& elements() const { return m_elements; }
void generateFiles(ChromeClient*);
void removeGeneratedFilesIfNeeded();
private:
FormData();
FormData(const FormData&);
Vector<FormDataElement> m_elements;
bool m_hasGeneratedFiles;
};
inline bool operator==(const FormData& a, const FormData& b)
......
......@@ -87,7 +87,8 @@ static void advanceCurrentStream(FormStreamFields *form)
form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data), size, kCFAllocatorNull);
form->currentData = data;
} else {
CFStringRef filename = nextInput.m_filename.createCFString();
const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_generatedFilename : nextInput.m_filename;
CFStringRef filename = path.createCFString();
CFURLRef fileURL = CFURLCreateWithFileSystemPath(0, filename, kCFURLPOSIXPathStyle, FALSE);
CFRelease(filename);
form->currentStream = CFReadStreamCreateWithFile(0, fileURL);
......@@ -275,8 +276,9 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
if (element.m_type == FormDataElement::data)
length += element.m_data.size();
else {
const String& filename = element.m_shouldGenerateFile ? element.m_generatedFilename : element.m_filename;
struct stat sb;
int statResult = stat(element.m_filename.utf8().data(), &sb);
int statResult = stat(filename.utf8().data(), &sb);
if (statResult == 0 && (sb.st_mode & S_IFMT) == S_IFREG)
length += sb.st_size;
}
......
......@@ -33,6 +33,7 @@
#include "PlatformString.h"
#include <sys/stat.h>
#include <libgen.h>
#include <unistd.h>
namespace WebCore {
......@@ -146,4 +147,14 @@ String pathGetFileName(const String& path)
return path.substring(path.reverseFind('/') + 1);
}
String directoryName(const String& path)
{
CString fsRep = fileSystemRepresentation(path);
if (!fsRep.data() || fsRep.data()[0] == '\0')
return String();
return dirname(fsRep.mutableData());
}
} // namespace WebCore
......@@ -88,6 +88,12 @@ String pathGetFileName(const String& path)
return QFileInfo(path).fileName();
}
String directoryName(const String& path)
{
notImplemented();
return String();
}
bool unloadModule(PlatformModule)
{
notImplemented();
......
......@@ -131,6 +131,12 @@ String pathGetFileName(const String& path)
return String(::PathFindFileName(String(path).charactersWithNullTermination()));
}
String directoryName(const String& path)
{
notImplemented();
return String();
}
static String bundleName()
{
static bool initialized;
......
......@@ -91,6 +91,12 @@ String pathGetFileName(const String& path)
return wxFileName(path).GetFullName();
}
String directoryName(const String& path)
{
notImplemented();
return String();
}
CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
{
notImplemented();
......
2008-04-28 Adele Peterson <adele@apple.com>
Reviewed by Dan Bernstein, Tim Hatcher, Anders Carlsson, and Darin Adler.
WebKit part of fix for <rdar://problem/3709505>
Safari should have a way to upload bundles from the file upload control (as zip)
Added UIDelegate methods to let the application handle generating replacement files for uploads.
In this case, Safari will create archived files for bundles so they can be uploaded properly.
* DefaultDelegates/WebDefaultUIDelegate.m:
(-[WebDefaultUIDelegate webView:shouldReplaceUploadFile:usingGeneratedFilename:]):
(-[WebDefaultUIDelegate webView:generateReplacementFile:]):
* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::shouldReplaceWithGeneratedFileForUpload):
(WebChromeClient::generateReplacementFile):
* WebView/WebUIDelegatePrivate.h:
2008-04-28 Anders Carlsson <andersca@apple.com>
Reviewed by Sam, Mark, Adele and Darin.
......
......@@ -227,4 +227,14 @@ - (void)webView:(WebView *)sender contextMenuItemSelected:(NSMenuItem *)item for
{
}
- (BOOL)webView:(WebView *)sender shouldReplaceUploadFile:(NSString *)path usingGeneratedFilename:(NSString **)filename
{
return NO;
}
- (NSString *)webView:(WebView *)sender generateReplacementFile:(NSString *)path
{
return nil;
}
@end
......@@ -120,6 +120,9 @@ public:
virtual void makeFirstResponder(NSResponder *);
virtual void willPopUpMenu(NSMenu *);
virtual bool shouldReplaceWithGeneratedFileForUpload(const WebCore::String& path, WebCore::String &generatedFilename);
virtual WebCore::String generateReplacementFile(const WebCore::String& path);
private:
WebView *m_webView;
......
......@@ -541,6 +541,20 @@ void WebChromeClient::willPopUpMenu(NSMenu *menu)
END_BLOCK_OBJC_EXCEPTIONS;
}
bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename)
{
NSString* filename;
if (![[m_webView _UIDelegateForwarder] webView:m_webView shouldReplaceUploadFile:path usingGeneratedFilename:&filename])
return false;
generatedFilename = filename;
return true;
}
String WebChromeClient::generateReplacementFile(const String& path)
{
return [[m_webView _UIDelegateForwarder] webView:m_webView generateReplacementFile:path];
}
@implementation WebOpenPanelResultListener
- (id)initWithChooser:(PassRefPtr<FileChooser>)chooser
......
......@@ -97,4 +97,7 @@ enum {
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features;
- (BOOL)webView:(WebView *)sender shouldReplaceUploadFile:(NSString *)path usingGeneratedFilename:(NSString **)filename;
- (NSString *)webView:(WebView *)sender generateReplacementFile:(NSString *)path;
@end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment