• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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