2010-01-23 Oliver Hunt <oliver@apple.com>
Reviewed by Maciej Stachowiak.
Implement support for FileList cloning in postMessage
https://bugs.webkit.org/show_bug.cgi?id=34048
Add test for passing a FileList through postMessage, and
correct testing already present to test what it was meant
to be.
* fast/dom/Window/window-postmessage-clone-expected.txt:
* fast/dom/Window/window-postmessage-clone.html:
2010-01-23 Oliver Hunt <oliver@apple.com>
Reviewed by Maciej Stachowiak.
Implement support for FileList cloning in postMessage
https://bugs.webkit.org/show_bug.cgi?id=34048
Support passing FileList through postMessage APIs. Basically
mechanical task in line with other terminals in the object
graph.
* bindings/js/SerializedScriptValue.cpp:
(WebCore::SerializedFileList::create):
(WebCore::SerializedFileList::length):
(WebCore::SerializedFileList::item):
(WebCore::SerializedFileList::SerializedFileList):
(WebCore::SerializedScriptValueData::SerializedScriptValueData):
(WebCore::SharedSerializedData::asFileList):
(WebCore::SerializingTreeWalker::convertIfTerminal):
(WebCore::DeserializingTreeWalker::convertIfTerminal):
(WebCore::TeardownTreeWalker::convertIfTerminal):
Rearrange these functions to not use 'default:' handling
so that the compiler will actually tell us when we're
not handling cases.
* bindings/js/SerializedScriptValue.h:
(WebCore::SerializedScriptValueData::):
(WebCore::SerializedScriptValueData::asFileList):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53774 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/bindings/js/SerializedScriptValue.cpp b/WebCore/bindings/js/SerializedScriptValue.cpp
index f0e7b6e..b38a009 100644
--- a/WebCore/bindings/js/SerializedScriptValue.cpp
+++ b/WebCore/bindings/js/SerializedScriptValue.cpp
@@ -28,6 +28,7 @@
#include "SerializedScriptValue.h"
#include "File.h"
+#include "FileList.h"
#include "JSDOMGlobalObject.h"
#include "JSFile.h"
#include "JSFileList.h"
@@ -142,6 +143,28 @@
unsigned m_length;
};
+class SerializedFileList : public SharedSerializedData {
+public:
+ static PassRefPtr<SerializedFileList> create(const FileList* list)
+ {
+ return adoptRef(new SerializedFileList(list));
+ }
+
+ unsigned length() const { return m_files.size(); }
+ const String& item(unsigned idx) { return m_files[idx]; }
+
+private:
+ SerializedFileList(const FileList* list)
+ {
+ unsigned length = list->length();
+ m_files.reserveCapacity(length);
+ for (unsigned i = 0; i < length; i++)
+ m_files.append(list->item(i)->path().crossThreadString());
+ }
+
+ Vector<String> m_files;
+};
+
SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedObject> data)
: m_type(ObjectType)
, m_sharedData(data)
@@ -154,6 +177,12 @@
{
}
+SerializedScriptValueData::SerializedScriptValueData(const FileList* fileList)
+ : m_type(FileListType)
+ , m_sharedData(SerializedFileList::create(fileList))
+{
+}
+
SerializedScriptValueData::SerializedScriptValueData(const File* file)
: m_type(FileType)
, m_string(file->path().crossThreadString())
@@ -170,6 +199,11 @@
return static_cast<SerializedObject*>(this);
}
+SerializedFileList* SharedSerializedData::asFileList()
+{
+ return static_cast<SerializedFileList*>(this);
+}
+
static const unsigned maximumFilterRecursion = 40000;
enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
@@ -497,6 +531,8 @@
JSObject* obj = asObject(value);
if (obj->inherits(&JSFile::s_info))
return SerializedScriptValueData(toFile(obj));
+ if (obj->inherits(&JSFileList::s_info))
+ return SerializedScriptValueData(toFileList(obj));
CallData unusedData;
if (value.getCallData(unusedData) == CallTypeNone)
@@ -659,10 +695,20 @@
return new (m_exec) DateInstance(m_exec, value.asDouble());
case SerializedScriptValueData::FileType:
return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), File::create(value.asString().crossThreadString()));
- default:
+ case SerializedScriptValueData::FileListType: {
+ RefPtr<FileList> result = FileList::create();
+ SerializedFileList* serializedFileList = value.asFileList();
+ unsigned length = serializedFileList->length();
+ for (unsigned i = 0; i < length; i++)
+ result->append(File::create(serializedFileList->item(i)));
+ return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), result.get());
+ }
+ case SerializedScriptValueData::EmptyType:
ASSERT_NOT_REACHED();
- return JSValue();
+ return jsNull();
}
+ ASSERT_NOT_REACHED();
+ return jsNull();
}
void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties)
@@ -810,11 +856,14 @@
case SerializedScriptValueData::StringType:
case SerializedScriptValueData::ImmediateType:
case SerializedScriptValueData::NumberType:
+ case SerializedScriptValueData::DateType:
+ case SerializedScriptValueData::EmptyType:
+ case SerializedScriptValueData::FileType:
+ case SerializedScriptValueData::FileListType:
return true;
- default:
- ASSERT_NOT_REACHED();
- return JSValue();
}
+ ASSERT_NOT_REACHED();
+ return true;
}
void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties)