http://dvcs.w3.org/hg/web-intents/raw-file/tip/spec/Overview.html
This adds the ability to pass transferables (i.e. MessagePorts)
through web intents, and puts the calling convention in line
with the Web Messaging spec:
http://dev.w3.org/html5/postmsg/
Implementation in chromium API follows the port-passing method
of PlatformMessagePortChannel.
https://bugs.webkit.org/show_bug.cgi?id=80200
Patch by Greg Billock <gbillock@google.com> on 2012-04-10
Reviewed by Adam Barth.
* Modules/intents/Intent.cpp:
(WebCore::Intent::create):
* Modules/intents/Intent.idl:
* WebCore.gypi:
* bindings/v8/custom/V8IntentCustom.cpp: Added.
(WebCore):
(WebCore::V8Intent::constructorCallback):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@113799
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
--- /dev/null
+Received Web Intent: action=action1 type=mime/type1
+Have 1 ports
+PASS successfullyParsed is true
+
+TEST COMPLETE
+* sent intent
+
--- /dev/null
+<html>
+ <head>
+ <script src="../fast/js/resources/js-test-pre.js"></script>
+ <script src="resources/web-intents-testing.js"></script>
+ <script>
+ var channel = new MessageChannel();
+ channel.port2.onMessage = function(e) {
+ debug("* got message");
+ };
+
+ function buttonClicked() {
+ try {
+ var intent1 = new WebKitIntent("action1", "mime/type1", channel.port1, "not a port");
+ testFailed("Should have thrown TypeError");
+ } catch (e) {
+ if (!(e instanceof TypeError)) testFailed("Should throw type error on non-port arg");
+ }
+ try {
+ var intent1 = new WebKitIntent("action1", "mime/type1", channel.port1, ["not a port"]);
+ testFailed("Should have thrown TypeError");
+ } catch (e) {
+ if (!(e instanceof TypeError)) testFailed("Should throw type error on non-port arg");
+ }
+
+ navigator.webkitStartActivity(new WebKitIntent("action1", "mime/type1", channel.port1, [channel.port1]));
+ debug("* sent intent");
+ }
+ </script>
+ </head>
+<body onload="simulateButtonPress()">
+<input type="button" id="button" value="Start Web Intent" onmouseup="buttonClicked()">
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
+2012-04-10 Greg Billock <gbillock@google.com>
+
+ Add transfer map argument to Intent constructor
+ http://dvcs.w3.org/hg/web-intents/raw-file/tip/spec/Overview.html
+ This adds the ability to pass transferables (i.e. MessagePorts)
+ through web intents, and puts the calling convention in line
+ with the Web Messaging spec:
+ http://dev.w3.org/html5/postmsg/
+
+ Implementation in chromium API follows the port-passing method
+ of PlatformMessagePortChannel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=80200
+
+ Reviewed by Adam Barth.
+
+ * Modules/intents/Intent.cpp:
+ (WebCore::Intent::create):
+ * Modules/intents/Intent.idl:
+ * WebCore.gypi:
+ * bindings/v8/custom/V8IntentCustom.cpp: Added.
+ (WebCore):
+ (WebCore::V8Intent::constructorCallback):
+
2012-04-10 Patrick Gansterer <paroga@webkit.org>
Cleanup wtf/Platform.h and config.h files
#if ENABLE(WEB_INTENTS)
#include "ExceptionCode.h"
+#include "MessagePort.h"
#include "SerializedScriptValue.h"
namespace WebCore {
return adoptRef(new Intent(action, type, data));
}
+PassRefPtr<Intent> Intent::create(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, const MessagePortArray& ports, ExceptionCode& ec)
+{
+ if (action.isEmpty()) {
+ ec = SYNTAX_ERR;
+ return 0;
+ }
+ if (type.isEmpty()) {
+ ec = SYNTAX_ERR;
+ return 0;
+ }
+
+ OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(&ports, ec);
+
+ return adoptRef(new Intent(action, type, data, channels.release()));
+}
+
Intent::Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data)
: m_action(action)
, m_type(type)
{
if (data)
- m_data = SerializedScriptValue::createFromWire(data->toWireString());
+ m_data = data;
+ else
+ m_data = SerializedScriptValue::nullValue();
+}
+
+Intent::Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, PassOwnPtr<MessagePortChannelArray> ports)
+ : m_action(action)
+ , m_type(type)
+ , m_ports(ports)
+{
+ if (data)
+ m_data = data;
else
m_data = SerializedScriptValue::nullValue();
}
return m_data.get();
}
+MessagePortChannelArray* Intent::messagePorts() const
+{
+ return m_ports.get();
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_INTENTS)
#if ENABLE(WEB_INTENTS)
+#include "MessagePort.h"
+#include "MessagePortChannel.h"
#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
class Intent : public RefCounted<Intent> {
public:
static PassRefPtr<Intent> create(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, ExceptionCode&);
+ static PassRefPtr<Intent> create(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, const MessagePortArray& ports, ExceptionCode&);
const String& action() const;
const String& type() const;
int identifier() const;
void setIdentifier(int);
+ MessagePortChannelArray* messagePorts() const;
+
private:
Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data);
+ Intent(const String& action, const String& type, PassRefPtr<SerializedScriptValue> data, PassOwnPtr<MessagePortChannelArray> ports);
String m_action;
String m_type;
RefPtr<SerializedScriptValue> m_data;
+ OwnPtr<MessagePortChannelArray> m_ports;
};
} // namespace WebCore
module window {
interface [
Conditional=WEB_INTENTS,
- Constructor(in DOMString action, in DOMString type, in [Optional=DefaultIsNullString] SerializedScriptValue data),
+ Constructor(in DOMString action, in DOMString type, in [Optional=DefaultIsNullString, TransferList=transferList] SerializedScriptValue data, in [Optional=DefaultIsUndefined] Array transferList),
ConstructorRaisesException
] Intent {
readonly attribute DOMString action;
die "IDL error: TransferList refers to a nonexistent argument";
}
- AddToImplIncludes("ArrayBuffer.h");
+ AddToImplIncludes("wtf/ArrayBuffer.h");
AddToImplIncludes("MessagePort.h");
$TransferListName = ucfirst($transferListName);
$parameterCheckString .= " MessagePortArray messagePortArray$TransferListName;\n";
#if ENABLE(Condition1) || ENABLE(Condition2)
-#include "ArrayBuffer.h"
#include "ExceptionCode.h"
#include "MessagePort.h"
#include "RuntimeEnabledFeatures.h"
#include "V8DOMWrapper.h"
#include "V8IsolatedContext.h"
#include "V8Proxy.h"
+#include <wtf/ArrayBuffer.h>
#include <wtf/UnusedParam.h>
namespace WebCore {
#ifndef WebIntent_h
#define WebIntent_h
+#include "WebMessagePortChannel.h"
#include "platform/WebCommon.h"
#include "platform/WebPrivatePtr.h"
#include "platform/WebString.h"
+#include "platform/WebVector.h"
namespace WebCore { class Intent; }
WEBKIT_EXPORT WebString type() const;
WEBKIT_EXPORT WebString data() const;
+ // Caller takes ownership of the ports.
+ WEBKIT_EXPORT WebMessagePortChannelArray* messagePortChannelsRelease() const;
+
#if WEBKIT_IMPLEMENTATION
WebIntent(const WTF::PassRefPtr<WebCore::Intent>&);
#endif
#include "WebIntent.h"
#include "Intent.h"
+#include "PlatformMessagePortChannel.h"
#include "SerializedScriptValue.h"
namespace WebKit {
#endif
}
+WebMessagePortChannelArray* WebIntent::messagePortChannelsRelease() const
+{
+ // Note: see PlatformMessagePortChannel::postMessageToRemote.
+ WebMessagePortChannelArray* webChannels = 0;
+ WebCore::MessagePortChannelArray* messagePorts = m_private->messagePorts();
+ if (messagePorts) {
+ webChannels = new WebMessagePortChannelArray(messagePorts->size());
+ for (size_t i = 0; i < messagePorts->size(); ++i) {
+ WebCore::PlatformMessagePortChannel* platformChannel = messagePorts->at(i)->channel();
+ (*webChannels)[i] = platformChannel->webChannelRelease();
+ (*webChannels)[i]->setClient(0);
+ }
+ }
+
+ return webChannels;
+}
+
} // namespace WebKit
printf("Received Web Intent: action=%s type=%s\n",
request.intent().action().utf8().data(),
request.intent().type().utf8().data());
+ WebMessagePortChannelArray* ports = request.intent().messagePortChannelsRelease();
m_currentRequest = request;
+ if (ports) {
+ printf("Have %d ports\n", static_cast<int>(ports->size()));
+ for (size_t i = 0; i < ports->size(); ++i)
+ (*ports)[i]->destroy();
+ delete ports;
+ }
}
// Public functions -----------------------------------------------------------