Update WebWorkers API to return message object in onmessage

Summary:
public

I wasn't obeying the web workers API correctly: I had missed that the message isn't sent directly but is attached to a message object in a data field.

Reviewed By: lexs

Differential Revision: D2811247

fb-gh-sync-id: 8e51414766e0cfe382ee9bdde8f0d66e269cb83a
This commit is contained in:
Andy Street 2016-01-12 04:51:15 -08:00 committed by facebook-github-bot-4
parent 72d1826ae3
commit b0519c8280
5 changed files with 51 additions and 6 deletions

View File

@ -239,14 +239,14 @@ std::shared_ptr<JMessageQueueThread> JSCExecutor::getMessageQueueThread() {
}
void JSCExecutor::onMessageReceived(int workerId, const std::string& json) {
Value rebornJSMsg = Value::fromJSON(m_context, String(json.c_str()));
JSValueRef args[] = { rebornJSMsg };
Object& worker = m_webWorkerJSObjs.at(workerId);
Value onmessageValue = worker.getProperty("onmessage");
if (onmessageValue.isUndefined()) {
return;
}
JSValueRef args[] = { JSCWebWorker::createMessageObject(m_context, json) };
onmessageValue.asObject().callAsFunction(1, args);
m_flushImmediateCallback(flush(), true);

View File

@ -53,8 +53,8 @@ void JSCWebWorker::postMessage(JSValueRef msg) {
if (isFinished()) {
return;
}
Value rebornJSMsg = Value::fromJSON(context_, String(msgString.c_str()));
JSValueRef args[] = { rebornJSMsg };
JSValueRef args[] = { createMessageObject(context_, msgString) };
Value onmessageValue = Object::getGlobalObject(context_).getProperty("onmessage");
onmessageValue.asObject().callAsFunction(1, args);
});
@ -111,5 +111,13 @@ JSValueRef JSCWebWorker::nativePostMessage(
return JSValueMakeUndefined(ctx);
}
/*static*/
Object JSCWebWorker::createMessageObject(JSContextRef context, const std::string& msgJson) {
Value rebornJSMsg = Value::fromJSON(context, String(msgJson.c_str()));
Object messageObject = Object::create(context);
messageObject.setProperty("data", rebornJSMsg);
return std::move(messageObject);
}
}
}

View File

@ -58,6 +58,8 @@ public:
void postMessage(JSValueRef msg);
void finish();
bool isFinished();
static Object createMessageObject(JSContextRef context, const std::string& msgData);
private:
void initJSVMAndLoadScript();
void postRunnableToEventLoop(std::function<void()>&& runnable);

View File

@ -58,6 +58,10 @@ Object Value::asObject() {
return std::move(ret);
}
Object::operator Value() const {
return Value(m_context, m_obj);
}
Value Object::callAsFunction(int nArgs, JSValueRef args[]) {
JSValueRef exn;
JSValueRef result = JSObjectCallAsFunction(m_context, m_obj, NULL, nArgs, args, &exn);
@ -68,7 +72,7 @@ Value Object::callAsFunction(int nArgs, JSValueRef args[]) {
return Value(m_context, result);
}
Value Object::getProperty(String propName) const {
Value Object::getProperty(const String& propName) const {
JSValueRef exn;
JSValueRef property = JSObjectGetProperty(m_context, m_obj, propName, &exn);
if (!property) {
@ -82,4 +86,26 @@ Value Object::getProperty(const char *propName) const {
return getProperty(String(propName));
}
void Object::setProperty(const String& propName, const Value& value) const {
JSValueRef exn = NULL;
JSObjectSetProperty(m_context, m_obj, propName, value, kJSPropertyAttributeNone, &exn);
if (exn) {
std::string exceptionText = Value(m_context, exn).toString().str();
throwJSExecutionException("Failed to set property: %s", exceptionText.c_str());
}
}
void Object::setProperty(const char *propName, const Value& value) const {
setProperty(String(propName), value);
}
/* static */
Object Object::create(JSContextRef ctx) {
JSObjectRef newObj = JSObjectMake(
ctx,
NULL, // create instance of default object class
NULL); // no private data
return Object(ctx, newObj);
}
} }

View File

@ -111,14 +111,18 @@ public:
return m_obj;
}
operator Value() const;
bool isFunction() const {
return JSObjectIsFunction(m_context, m_obj);
}
Value callAsFunction(int nArgs, JSValueRef args[]);
Value getProperty(String propName) const;
Value getProperty(const String& propName) const;
Value getProperty(const char *propName) const;
void setProperty(const String& propName, const Value& value) const;
void setProperty(const char *propName, const Value& value) const;
void makeProtected() {
if (!m_isProtected && m_obj) {
@ -132,6 +136,11 @@ public:
return Object(ctx, globalObj);
}
/**
* Creates an instance of the default object class.
*/
static Object create(JSContextRef ctx);
private:
JSContextRef m_context;
JSObjectRef m_obj;