1'use strict' 2 3const { webidl } = require('../fetch/webidl') 4const { kEnumerableProperty } = require('../core/util') 5const { MessagePort } = require('worker_threads') 6 7/** 8 * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent 9 */ 10class MessageEvent extends Event { 11 #eventInit 12 13 constructor (type, eventInitDict = {}) { 14 webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent constructor' }) 15 16 type = webidl.converters.DOMString(type) 17 eventInitDict = webidl.converters.MessageEventInit(eventInitDict) 18 19 super(type, eventInitDict) 20 21 this.#eventInit = eventInitDict 22 } 23 24 get data () { 25 webidl.brandCheck(this, MessageEvent) 26 27 return this.#eventInit.data 28 } 29 30 get origin () { 31 webidl.brandCheck(this, MessageEvent) 32 33 return this.#eventInit.origin 34 } 35 36 get lastEventId () { 37 webidl.brandCheck(this, MessageEvent) 38 39 return this.#eventInit.lastEventId 40 } 41 42 get source () { 43 webidl.brandCheck(this, MessageEvent) 44 45 return this.#eventInit.source 46 } 47 48 get ports () { 49 webidl.brandCheck(this, MessageEvent) 50 51 if (!Object.isFrozen(this.#eventInit.ports)) { 52 Object.freeze(this.#eventInit.ports) 53 } 54 55 return this.#eventInit.ports 56 } 57 58 initMessageEvent ( 59 type, 60 bubbles = false, 61 cancelable = false, 62 data = null, 63 origin = '', 64 lastEventId = '', 65 source = null, 66 ports = [] 67 ) { 68 webidl.brandCheck(this, MessageEvent) 69 70 webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent.initMessageEvent' }) 71 72 return new MessageEvent(type, { 73 bubbles, cancelable, data, origin, lastEventId, source, ports 74 }) 75 } 76} 77 78/** 79 * @see https://websockets.spec.whatwg.org/#the-closeevent-interface 80 */ 81class CloseEvent extends Event { 82 #eventInit 83 84 constructor (type, eventInitDict = {}) { 85 webidl.argumentLengthCheck(arguments, 1, { header: 'CloseEvent constructor' }) 86 87 type = webidl.converters.DOMString(type) 88 eventInitDict = webidl.converters.CloseEventInit(eventInitDict) 89 90 super(type, eventInitDict) 91 92 this.#eventInit = eventInitDict 93 } 94 95 get wasClean () { 96 webidl.brandCheck(this, CloseEvent) 97 98 return this.#eventInit.wasClean 99 } 100 101 get code () { 102 webidl.brandCheck(this, CloseEvent) 103 104 return this.#eventInit.code 105 } 106 107 get reason () { 108 webidl.brandCheck(this, CloseEvent) 109 110 return this.#eventInit.reason 111 } 112} 113 114// https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface 115class ErrorEvent extends Event { 116 #eventInit 117 118 constructor (type, eventInitDict) { 119 webidl.argumentLengthCheck(arguments, 1, { header: 'ErrorEvent constructor' }) 120 121 super(type, eventInitDict) 122 123 type = webidl.converters.DOMString(type) 124 eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}) 125 126 this.#eventInit = eventInitDict 127 } 128 129 get message () { 130 webidl.brandCheck(this, ErrorEvent) 131 132 return this.#eventInit.message 133 } 134 135 get filename () { 136 webidl.brandCheck(this, ErrorEvent) 137 138 return this.#eventInit.filename 139 } 140 141 get lineno () { 142 webidl.brandCheck(this, ErrorEvent) 143 144 return this.#eventInit.lineno 145 } 146 147 get colno () { 148 webidl.brandCheck(this, ErrorEvent) 149 150 return this.#eventInit.colno 151 } 152 153 get error () { 154 webidl.brandCheck(this, ErrorEvent) 155 156 return this.#eventInit.error 157 } 158} 159 160Object.defineProperties(MessageEvent.prototype, { 161 [Symbol.toStringTag]: { 162 value: 'MessageEvent', 163 configurable: true 164 }, 165 data: kEnumerableProperty, 166 origin: kEnumerableProperty, 167 lastEventId: kEnumerableProperty, 168 source: kEnumerableProperty, 169 ports: kEnumerableProperty, 170 initMessageEvent: kEnumerableProperty 171}) 172 173Object.defineProperties(CloseEvent.prototype, { 174 [Symbol.toStringTag]: { 175 value: 'CloseEvent', 176 configurable: true 177 }, 178 reason: kEnumerableProperty, 179 code: kEnumerableProperty, 180 wasClean: kEnumerableProperty 181}) 182 183Object.defineProperties(ErrorEvent.prototype, { 184 [Symbol.toStringTag]: { 185 value: 'ErrorEvent', 186 configurable: true 187 }, 188 message: kEnumerableProperty, 189 filename: kEnumerableProperty, 190 lineno: kEnumerableProperty, 191 colno: kEnumerableProperty, 192 error: kEnumerableProperty 193}) 194 195webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort) 196 197webidl.converters['sequence<MessagePort>'] = webidl.sequenceConverter( 198 webidl.converters.MessagePort 199) 200 201const eventInit = [ 202 { 203 key: 'bubbles', 204 converter: webidl.converters.boolean, 205 defaultValue: false 206 }, 207 { 208 key: 'cancelable', 209 converter: webidl.converters.boolean, 210 defaultValue: false 211 }, 212 { 213 key: 'composed', 214 converter: webidl.converters.boolean, 215 defaultValue: false 216 } 217] 218 219webidl.converters.MessageEventInit = webidl.dictionaryConverter([ 220 ...eventInit, 221 { 222 key: 'data', 223 converter: webidl.converters.any, 224 defaultValue: null 225 }, 226 { 227 key: 'origin', 228 converter: webidl.converters.USVString, 229 defaultValue: '' 230 }, 231 { 232 key: 'lastEventId', 233 converter: webidl.converters.DOMString, 234 defaultValue: '' 235 }, 236 { 237 key: 'source', 238 // Node doesn't implement WindowProxy or ServiceWorker, so the only 239 // valid value for source is a MessagePort. 240 converter: webidl.nullableConverter(webidl.converters.MessagePort), 241 defaultValue: null 242 }, 243 { 244 key: 'ports', 245 converter: webidl.converters['sequence<MessagePort>'], 246 get defaultValue () { 247 return [] 248 } 249 } 250]) 251 252webidl.converters.CloseEventInit = webidl.dictionaryConverter([ 253 ...eventInit, 254 { 255 key: 'wasClean', 256 converter: webidl.converters.boolean, 257 defaultValue: false 258 }, 259 { 260 key: 'code', 261 converter: webidl.converters['unsigned short'], 262 defaultValue: 0 263 }, 264 { 265 key: 'reason', 266 converter: webidl.converters.USVString, 267 defaultValue: '' 268 } 269]) 270 271webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ 272 ...eventInit, 273 { 274 key: 'message', 275 converter: webidl.converters.DOMString, 276 defaultValue: '' 277 }, 278 { 279 key: 'filename', 280 converter: webidl.converters.USVString, 281 defaultValue: '' 282 }, 283 { 284 key: 'lineno', 285 converter: webidl.converters['unsigned long'], 286 defaultValue: 0 287 }, 288 { 289 key: 'colno', 290 converter: webidl.converters['unsigned long'], 291 defaultValue: 0 292 }, 293 { 294 key: 'error', 295 converter: webidl.converters.any 296 } 297]) 298 299module.exports = { 300 MessageEvent, 301 CloseEvent, 302 ErrorEvent 303} 304