Skip to content

Commit 705d888

Browse files
addaleaxnodejs-github-bot
authored andcommitted
worker: make MessageEvent class more Web-compatible
PR-URL: #35496Fixes: #35495 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Shelley Vohr <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Khaidi Chu <[email protected]>
1 parent 828518c commit 705d888

File tree

4 files changed

+154
-4
lines changed

4 files changed

+154
-4
lines changed

‎lib/internal/worker/io.js‎

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const{
44
ObjectAssign,
55
ObjectCreate,
66
ObjectDefineProperty,
7+
ObjectDefineProperties,
78
ObjectGetOwnPropertyDescriptors,
89
ObjectGetPrototypeOf,
910
ObjectSetPrototypeOf,
@@ -21,7 +22,8 @@ const{
2122
drainMessagePort,
2223
moveMessagePortToContext,
2324
receiveMessageOnPort: receiveMessageOnPort_,
24-
stopMessagePort
25+
stopMessagePort,
26+
checkMessagePort
2527
}=internalBinding('messaging');
2628
const{
2729
getEnvMessagePort
@@ -38,12 +40,20 @@ const{
3840
kRemoveListener,
3941
}=require('internal/event_target');
4042
const{ inspect }=require('internal/util/inspect');
43+
const{
44+
ERR_INVALID_ARG_TYPE
45+
}=require('internal/errors').codes;
4146

47+
constkData=Symbol('kData');
4248
constkIncrementsPortRef=Symbol('kIncrementsPortRef');
49+
constkLastEventId=Symbol('kLastEventId');
4350
constkName=Symbol('kName');
51+
constkOrigin=Symbol('kOrigin');
4452
constkPort=Symbol('kPort');
53+
constkPorts=Symbol('kPorts');
4554
constkWaitingStreams=Symbol('kWaitingStreams');
4655
constkWritableCallbacks=Symbol('kWritableCallbacks');
56+
constkSource=Symbol('kSource');
4757
constkStartedReading=Symbol('kStartedReading');
4858
constkStdioWantsMoreDataCallback=Symbol('kStdioWantsMoreDataCallback');
4959

@@ -72,19 +82,57 @@ ObjectSetPrototypeOf(MessagePort.prototype, NodeEventTarget.prototype);
7282
MessagePort.prototype.ref=MessagePortPrototype.ref;
7383
MessagePort.prototype.unref=MessagePortPrototype.unref;
7484

85+
functionvalidateMessagePort(port,name){
86+
if(!checkMessagePort(port))
87+
thrownewERR_INVALID_ARG_TYPE(name,'MessagePort',port);
88+
}
89+
7590
classMessageEventextendsEvent{
76-
constructor(data,target,type){
91+
constructor(type,{
92+
data =null,
93+
origin ='',
94+
lastEventId ='',
95+
source =null,
96+
ports =[],
97+
}={}){
7798
super(type);
78-
this.data=data;
99+
this[kData]=data;
100+
this[kOrigin]=`${origin}`;
101+
this[kLastEventId]=`${lastEventId}`;
102+
this[kSource]=source;
103+
this[kPorts]=[...ports];
104+
105+
if(this[kSource]!==null)
106+
validateMessagePort(this[kSource],'init.source');
107+
for(leti=0;i<this[kPorts].length;i++)
108+
validateMessagePort(this[kPorts][i],`init.ports[${i}]`);
79109
}
80110
}
81111

112+
ObjectDefineProperties(MessageEvent.prototype,{
113+
data: {
114+
get(){returnthis[kData];},enumerable: true,configurable: true
115+
},
116+
origin: {
117+
get(){returnthis[kOrigin];},enumerable: true,configurable: true
118+
},
119+
lastEventId: {
120+
get(){returnthis[kLastEventId];},enumerable: true,configurable: true
121+
},
122+
source: {
123+
get(){returnthis[kSource];},enumerable: true,configurable: true
124+
},
125+
ports: {
126+
get(){returnthis[kPorts];},enumerable: true,configurable: true
127+
},
128+
});
129+
82130
ObjectDefineProperty(
83131
MessagePort.prototype,
84132
kCreateEvent,
85133
{
86134
value: function(data,type){
87-
returnnewMessageEvent(data,this,type);
135+
returnnewMessageEvent(type,{ data });
88136
},
89137
configurable: false,
90138
writable: false,
@@ -283,6 +331,7 @@ module.exports ={
283331
moveMessagePortToContext,
284332
MessagePort,
285333
MessageChannel,
334+
MessageEvent,
286335
receiveMessageOnPort,
287336
setupPortReferencing,
288337
ReadableWorkerStdio,

‎src/node_messaging.cc‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,12 @@ void MessagePort::Stop(const FunctionCallbackInfo<Value>& args){
10041004
port->Stop();
10051005
}
10061006

1007+
voidMessagePort::CheckType(const FunctionCallbackInfo<Value>& args){
1008+
Environment* env = Environment::GetCurrent(args);
1009+
args.GetReturnValue().Set(
1010+
GetMessagePortConstructorTemplate(env)->HasInstance(args[0]));
1011+
}
1012+
10071013
voidMessagePort::Drain(const FunctionCallbackInfo<Value>& args){
10081014
MessagePort* port;
10091015
ASSIGN_OR_RETURN_UNWRAP(&port, args[0].As<Object>());
@@ -1339,6 +1345,7 @@ static void InitMessaging(Local<Object> target,
13391345
// These are not methods on the MessagePort prototype, because
13401346
// the browser equivalents do not provide them.
13411347
env->SetMethod(target, "stopMessagePort", MessagePort::Stop);
1348+
env->SetMethod(target, "checkMessagePort", MessagePort::CheckType);
13421349
env->SetMethod(target, "drainMessagePort", MessagePort::Drain);
13431350
env->SetMethod(target, "receiveMessageOnPort", MessagePort::ReceiveMessage);
13441351
env->SetMethod(target, "moveMessagePortToContext",
@@ -1363,6 +1370,7 @@ static void RegisterExternalReferences(ExternalReferenceRegistry* registry){
13631370
registry->Register(MessagePort::PostMessage);
13641371
registry->Register(MessagePort::Start);
13651372
registry->Register(MessagePort::Stop);
1373+
registry->Register(MessagePort::CheckType);
13661374
registry->Register(MessagePort::Drain);
13671375
registry->Register(MessagePort::ReceiveMessage);
13681376
registry->Register(MessagePort::MoveToContext);

‎src/node_messaging.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ class MessagePort : public HandleWrap{
195195
staticvoidPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args);
196196
staticvoidStart(const v8::FunctionCallbackInfo<v8::Value>& args);
197197
staticvoidStop(const v8::FunctionCallbackInfo<v8::Value>& args);
198+
staticvoidCheckType(const v8::FunctionCallbackInfo<v8::Value>& args);
198199
staticvoidDrain(const v8::FunctionCallbackInfo<v8::Value>& args);
199200
staticvoidReceiveMessage(const v8::FunctionCallbackInfo<v8::Value>& args);
200201

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
require('../common');
4+
constassert=require('assert');
5+
const{ MessageEvent, MessageChannel }=require('internal/worker/io');
6+
7+
constdummyPort=newMessageChannel().port1;
8+
9+
{
10+
for(const[args,expected]of[
11+
[
12+
['message'],
13+
{
14+
type: 'message',data: null,origin: '',
15+
lastEventId: '',source: null,ports: []
16+
}
17+
],
18+
[
19+
['message',{data: undefined,origin: 'foo'}],
20+
{
21+
type: 'message',data: null,origin: 'foo',
22+
lastEventId: '',source: null,ports: []
23+
}
24+
],
25+
[
26+
['message',{data: 2,origin: 1,lastEventId: 0}],
27+
{
28+
type: 'message',data: 2,origin: '1',
29+
lastEventId: '0',source: null,ports: []
30+
}
31+
],
32+
[
33+
['message',{lastEventId: 'foo'}],
34+
{
35+
type: 'message',data: null,origin: '',
36+
lastEventId: 'foo',source: null,ports: []
37+
}
38+
],
39+
[
40+
['messageerror',{lastEventId: 'foo',source: dummyPort}],
41+
{
42+
type: 'messageerror',data: null,origin: '',
43+
lastEventId: 'foo',source: dummyPort,ports: []
44+
}
45+
],
46+
[
47+
['message',{ports: [dummyPort],source: null}],
48+
{
49+
type: 'message',data: null,origin: '',
50+
lastEventId: '',source: null,ports: [dummyPort]
51+
}
52+
],
53+
]){
54+
constev=newMessageEvent(...args);
55+
const{ type, data, origin, lastEventId, source, ports }=ev;
56+
assert.deepStrictEqual(expected,{
57+
type, data, origin, lastEventId, source, ports
58+
});
59+
}
60+
}
61+
62+
{
63+
assert.throws(()=>{
64+
newMessageEvent('message',{source: 1});
65+
},{
66+
code: 'ERR_INVALID_ARG_TYPE',
67+
message: /The"init\.source"propertymustbeaninstanceofMessagePort/,
68+
});
69+
assert.throws(()=>{
70+
newMessageEvent('message',{source: {}});
71+
},{
72+
code: 'ERR_INVALID_ARG_TYPE',
73+
message: /The"init\.source"propertymustbeaninstanceofMessagePort/,
74+
});
75+
assert.throws(()=>{
76+
newMessageEvent('message',{ports: 0});
77+
},{
78+
message: /portsisnotiterable/,
79+
});
80+
assert.throws(()=>{
81+
newMessageEvent('message',{ports: [null]});
82+
},{
83+
code: 'ERR_INVALID_ARG_TYPE',
84+
message: /The"init\.ports\[0\]"propertymustbeaninstanceofMessagePort/,
85+
});
86+
assert.throws(()=>{
87+
newMessageEvent('message',{ports: [{}]});
88+
},{
89+
code: 'ERR_INVALID_ARG_TYPE',
90+
message: /The"init\.ports\[0\]"propertymustbeaninstanceofMessagePort/,
91+
});
92+
}

0 commit comments

Comments
(0)