Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM EventTarget.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "EventHandlerBinding.h"
5 : #include "EventListenerBinding.h"
6 : #include "EventTargetBinding.h"
7 : #include "WrapperFactory.h"
8 : #include "mozilla/OwningNonNull.h"
9 : #include "mozilla/dom/BindingUtils.h"
10 : #include "mozilla/dom/DOMJSClass.h"
11 : #include "mozilla/dom/Event.h"
12 : #include "mozilla/dom/EventTarget.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/Nullable.h"
15 : #include "mozilla/dom/PrimitiveConversions.h"
16 : #include "mozilla/dom/ScriptSettings.h"
17 : #include "mozilla/dom/SimpleGlobalObject.h"
18 : #include "mozilla/dom/UnionConversions.h"
19 : #include "mozilla/dom/XrayExpandoClass.h"
20 : #include "nsContentUtils.h"
21 : #include "nsIDOMEventTarget.h"
22 : #include "nsPIDOMWindow.h"
23 : #include "xpcprivate.h"
24 :
25 : namespace mozilla {
26 : namespace dom {
27 :
28 :
29 0 : EventListenerOptions::EventListenerOptions()
30 : {
31 : // Safe to pass a null context if we pass a null value
32 0 : Init(nullptr, JS::NullHandleValue);
33 0 : }
34 :
35 :
36 :
37 : bool
38 2 : EventListenerOptions::InitIds(JSContext* cx, EventListenerOptionsAtoms* atomsCache)
39 : {
40 2 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
41 :
42 : // Initialize these in reverse order so that any failure leaves the first one
43 : // uninitialized.
44 4 : if (!atomsCache->mozSystemGroup_id.init(cx, "mozSystemGroup") ||
45 2 : !atomsCache->capture_id.init(cx, "capture")) {
46 0 : return false;
47 : }
48 2 : return true;
49 : }
50 :
51 : bool
52 143 : EventListenerOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
53 : {
54 : // Passing a null JSContext is OK only if we're initing from null,
55 : // Since in that case we will not have to do any property gets
56 : // Also evaluate isNullOrUndefined in order to avoid false-positive
57 : // checkers by static analysis tools
58 143 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
59 143 : EventListenerOptionsAtoms* atomsCache = nullptr;
60 143 : if (cx) {
61 143 : atomsCache = GetAtomCache<EventListenerOptionsAtoms>(cx);
62 143 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
63 0 : return false;
64 : }
65 : }
66 :
67 143 : if (!IsConvertibleToDictionary(val)) {
68 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
69 : }
70 :
71 143 : bool isNull = val.isNullOrUndefined();
72 : // We only need these if !isNull, in which case we have |cx|.
73 286 : Maybe<JS::Rooted<JSObject *> > object;
74 286 : Maybe<JS::Rooted<JS::Value> > temp;
75 143 : if (!isNull) {
76 6 : MOZ_ASSERT(cx);
77 6 : object.emplace(cx, &val.toObject());
78 6 : temp.emplace(cx);
79 : }
80 143 : if (!isNull) {
81 6 : if (!JS_GetPropertyById(cx, *object, atomsCache->capture_id, temp.ptr())) {
82 0 : return false;
83 : }
84 : }
85 143 : if (!isNull && !temp->isUndefined()) {
86 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mCapture)) {
87 0 : return false;
88 : }
89 : } else {
90 143 : mCapture = false;
91 : }
92 143 : mIsAnyMemberPresent = true;
93 :
94 143 : if (!isNull) {
95 6 : if (ThreadSafeIsChromeOrXBL(cx, *object)) {
96 5 : if (!JS_GetPropertyById(cx, *object, atomsCache->mozSystemGroup_id, temp.ptr())) {
97 0 : return false;
98 : }
99 : } else {
100 1 : temp->setUndefined();
101 : }
102 : }
103 143 : if (!isNull && !temp->isUndefined()) {
104 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mMozSystemGroup)) {
105 0 : return false;
106 : }
107 : } else {
108 143 : mMozSystemGroup = false;
109 : }
110 143 : mIsAnyMemberPresent = true;
111 143 : return true;
112 : }
113 :
114 : bool
115 0 : EventListenerOptions::Init(const nsAString& aJSON)
116 : {
117 0 : AutoJSAPI jsapi;
118 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
119 0 : if (!cleanGlobal) {
120 0 : return false;
121 : }
122 0 : if (!jsapi.Init(cleanGlobal)) {
123 0 : return false;
124 : }
125 0 : JSContext* cx = jsapi.cx();
126 0 : JS::Rooted<JS::Value> json(cx);
127 0 : bool ok = ParseJSON(cx, aJSON, &json);
128 0 : NS_ENSURE_TRUE(ok, false);
129 0 : return Init(cx, json);
130 : }
131 :
132 : bool
133 0 : EventListenerOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
134 : {
135 0 : EventListenerOptionsAtoms* atomsCache = GetAtomCache<EventListenerOptionsAtoms>(cx);
136 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
137 0 : return false;
138 : }
139 :
140 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
141 0 : if (!obj) {
142 0 : return false;
143 : }
144 0 : rval.set(JS::ObjectValue(*obj));
145 :
146 : do {
147 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
148 0 : JS::Rooted<JS::Value> temp(cx);
149 0 : bool const & currentValue = mCapture;
150 0 : temp.setBoolean(currentValue);
151 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->capture_id, temp, JSPROP_ENUMERATE)) {
152 0 : return false;
153 : }
154 0 : break;
155 : } while(0);
156 :
157 0 : if (ThreadSafeIsChromeOrXBL(cx, obj)) {
158 : do {
159 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
160 0 : JS::Rooted<JS::Value> temp(cx);
161 0 : bool const & currentValue = mMozSystemGroup;
162 0 : temp.setBoolean(currentValue);
163 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mozSystemGroup_id, temp, JSPROP_ENUMERATE)) {
164 0 : return false;
165 : }
166 0 : break;
167 : } while(0);
168 : }
169 :
170 0 : return true;
171 : }
172 :
173 : bool
174 0 : EventListenerOptions::ToJSON(nsAString& aJSON) const
175 : {
176 0 : AutoJSAPI jsapi;
177 0 : jsapi.Init();
178 0 : JSContext *cx = jsapi.cx();
179 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
180 : // because we'll only be creating objects, in ways that have no
181 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
182 : // which likewise guarantees no side-effects for the sorts of
183 : // things we will pass it.
184 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
185 0 : JS::Rooted<JS::Value> val(cx);
186 0 : if (!ToObjectInternal(cx, &val)) {
187 0 : return false;
188 : }
189 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
190 0 : return StringifyToJSON(cx, obj, aJSON);
191 : }
192 :
193 : void
194 0 : EventListenerOptions::TraceDictionary(JSTracer* trc)
195 : {
196 0 : }
197 :
198 : EventListenerOptions&
199 0 : EventListenerOptions::operator=(const EventListenerOptions& aOther)
200 : {
201 0 : mCapture = aOther.mCapture;
202 0 : mMozSystemGroup = aOther.mMozSystemGroup;
203 0 : return *this;
204 : }
205 :
206 : namespace binding_detail {
207 : } // namespace binding_detail
208 :
209 :
210 :
211 0 : AddEventListenerOptions::AddEventListenerOptions()
212 0 : : EventListenerOptions(FastDictionaryInitializer())
213 : {
214 : // Safe to pass a null context if we pass a null value
215 0 : Init(nullptr, JS::NullHandleValue);
216 0 : }
217 :
218 :
219 :
220 : bool
221 2 : AddEventListenerOptions::InitIds(JSContext* cx, AddEventListenerOptionsAtoms* atomsCache)
222 : {
223 2 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
224 :
225 : // Initialize these in reverse order so that any failure leaves the first one
226 : // uninitialized.
227 4 : if (!atomsCache->passive_id.init(cx, "passive") ||
228 2 : !atomsCache->once_id.init(cx, "once")) {
229 0 : return false;
230 : }
231 2 : return true;
232 : }
233 :
234 : bool
235 135 : AddEventListenerOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
236 : {
237 : // Passing a null JSContext is OK only if we're initing from null,
238 : // Since in that case we will not have to do any property gets
239 : // Also evaluate isNullOrUndefined in order to avoid false-positive
240 : // checkers by static analysis tools
241 135 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
242 135 : AddEventListenerOptionsAtoms* atomsCache = nullptr;
243 135 : if (cx) {
244 135 : atomsCache = GetAtomCache<AddEventListenerOptionsAtoms>(cx);
245 135 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
246 0 : return false;
247 : }
248 : }
249 :
250 : // Per spec, we init the parent's members first
251 135 : if (!EventListenerOptions::Init(cx, val)) {
252 0 : return false;
253 : }
254 :
255 135 : bool isNull = val.isNullOrUndefined();
256 : // We only need these if !isNull, in which case we have |cx|.
257 270 : Maybe<JS::Rooted<JSObject *> > object;
258 270 : Maybe<JS::Rooted<JS::Value> > temp;
259 135 : if (!isNull) {
260 6 : MOZ_ASSERT(cx);
261 6 : object.emplace(cx, &val.toObject());
262 6 : temp.emplace(cx);
263 : }
264 135 : if (!isNull) {
265 6 : if (!JS_GetPropertyById(cx, *object, atomsCache->once_id, temp.ptr())) {
266 0 : return false;
267 : }
268 : }
269 135 : if (!isNull && !temp->isUndefined()) {
270 6 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mOnce)) {
271 0 : return false;
272 : }
273 : } else {
274 129 : mOnce = false;
275 : }
276 135 : mIsAnyMemberPresent = true;
277 :
278 135 : if (!isNull) {
279 6 : if (!JS_GetPropertyById(cx, *object, atomsCache->passive_id, temp.ptr())) {
280 0 : return false;
281 : }
282 : }
283 135 : if (!isNull && !temp->isUndefined()) {
284 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPassive)) {
285 0 : return false;
286 : }
287 : } else {
288 135 : mPassive = false;
289 : }
290 135 : mIsAnyMemberPresent = true;
291 135 : return true;
292 : }
293 :
294 : bool
295 0 : AddEventListenerOptions::Init(const nsAString& aJSON)
296 : {
297 0 : AutoJSAPI jsapi;
298 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
299 0 : if (!cleanGlobal) {
300 0 : return false;
301 : }
302 0 : if (!jsapi.Init(cleanGlobal)) {
303 0 : return false;
304 : }
305 0 : JSContext* cx = jsapi.cx();
306 0 : JS::Rooted<JS::Value> json(cx);
307 0 : bool ok = ParseJSON(cx, aJSON, &json);
308 0 : NS_ENSURE_TRUE(ok, false);
309 0 : return Init(cx, json);
310 : }
311 :
312 : bool
313 0 : AddEventListenerOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
314 : {
315 0 : AddEventListenerOptionsAtoms* atomsCache = GetAtomCache<AddEventListenerOptionsAtoms>(cx);
316 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
317 0 : return false;
318 : }
319 :
320 : // Per spec, we define the parent's members first
321 0 : if (!EventListenerOptions::ToObjectInternal(cx, rval)) {
322 0 : return false;
323 : }
324 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
325 :
326 : do {
327 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
328 0 : JS::Rooted<JS::Value> temp(cx);
329 0 : bool const & currentValue = mOnce;
330 0 : temp.setBoolean(currentValue);
331 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->once_id, temp, JSPROP_ENUMERATE)) {
332 0 : return false;
333 : }
334 0 : break;
335 : } while(0);
336 :
337 : do {
338 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
339 0 : JS::Rooted<JS::Value> temp(cx);
340 0 : bool const & currentValue = mPassive;
341 0 : temp.setBoolean(currentValue);
342 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->passive_id, temp, JSPROP_ENUMERATE)) {
343 0 : return false;
344 : }
345 0 : break;
346 : } while(0);
347 :
348 0 : return true;
349 : }
350 :
351 : bool
352 0 : AddEventListenerOptions::ToJSON(nsAString& aJSON) const
353 : {
354 0 : AutoJSAPI jsapi;
355 0 : jsapi.Init();
356 0 : JSContext *cx = jsapi.cx();
357 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
358 : // because we'll only be creating objects, in ways that have no
359 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
360 : // which likewise guarantees no side-effects for the sorts of
361 : // things we will pass it.
362 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
363 0 : JS::Rooted<JS::Value> val(cx);
364 0 : if (!ToObjectInternal(cx, &val)) {
365 0 : return false;
366 : }
367 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
368 0 : return StringifyToJSON(cx, obj, aJSON);
369 : }
370 :
371 : void
372 0 : AddEventListenerOptions::TraceDictionary(JSTracer* trc)
373 : {
374 0 : EventListenerOptions::TraceDictionary(trc);
375 0 : }
376 :
377 : AddEventListenerOptions&
378 0 : AddEventListenerOptions::operator=(const AddEventListenerOptions& aOther)
379 : {
380 0 : EventListenerOptions::operator=(aOther);
381 0 : mOnce = aOther.mOnce;
382 0 : mPassive = aOther.mPassive;
383 0 : return *this;
384 : }
385 :
386 : namespace binding_detail {
387 : } // namespace binding_detail
388 :
389 :
390 : bool
391 0 : EventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
392 : {
393 0 : switch (mType) {
394 : case eUninitialized: {
395 0 : return false;
396 : break;
397 : }
398 : case eEventListenerOptions: {
399 0 : if (!mValue.mEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
400 0 : return false;
401 : }
402 0 : return true;
403 : break;
404 : }
405 : case eBoolean: {
406 0 : rval.setBoolean(mValue.mBoolean.Value());
407 0 : return true;
408 : break;
409 : }
410 : default: {
411 0 : return false;
412 : break;
413 : }
414 : }
415 :
416 : return false;
417 : }
418 :
419 :
420 : EventListenerOptions&
421 0 : OwningEventListenerOptionsOrBoolean::RawSetAsEventListenerOptions()
422 : {
423 0 : if (mType == eEventListenerOptions) {
424 0 : return mValue.mEventListenerOptions.Value();
425 : }
426 0 : MOZ_ASSERT(mType == eUninitialized);
427 0 : mType = eEventListenerOptions;
428 0 : return mValue.mEventListenerOptions.SetValue();
429 : }
430 :
431 : EventListenerOptions&
432 0 : OwningEventListenerOptionsOrBoolean::SetAsEventListenerOptions()
433 : {
434 0 : if (mType == eEventListenerOptions) {
435 0 : return mValue.mEventListenerOptions.Value();
436 : }
437 0 : Uninit();
438 0 : mType = eEventListenerOptions;
439 0 : return mValue.mEventListenerOptions.SetValue();
440 : }
441 :
442 : bool
443 0 : OwningEventListenerOptionsOrBoolean::TrySetToEventListenerOptions(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
444 : {
445 0 : tryNext = false;
446 : { // scope for memberSlot
447 0 : EventListenerOptions& memberSlot = RawSetAsEventListenerOptions();
448 0 : if (!IsConvertibleToDictionary(value)) {
449 0 : DestroyEventListenerOptions();
450 0 : tryNext = true;
451 0 : return true;
452 : }
453 0 : if (!memberSlot.Init(cx, value, "Member of EventListenerOptionsOrBoolean", passedToJSImpl)) {
454 0 : return false;
455 : }
456 : }
457 0 : return true;
458 : }
459 :
460 : void
461 0 : OwningEventListenerOptionsOrBoolean::DestroyEventListenerOptions()
462 : {
463 0 : MOZ_ASSERT(IsEventListenerOptions(), "Wrong type!");
464 0 : mValue.mEventListenerOptions.Destroy();
465 0 : mType = eUninitialized;
466 0 : }
467 :
468 :
469 :
470 :
471 : bool&
472 0 : OwningEventListenerOptionsOrBoolean::RawSetAsBoolean()
473 : {
474 0 : if (mType == eBoolean) {
475 0 : return mValue.mBoolean.Value();
476 : }
477 0 : MOZ_ASSERT(mType == eUninitialized);
478 0 : mType = eBoolean;
479 0 : return mValue.mBoolean.SetValue();
480 : }
481 :
482 : bool&
483 0 : OwningEventListenerOptionsOrBoolean::SetAsBoolean()
484 : {
485 0 : if (mType == eBoolean) {
486 0 : return mValue.mBoolean.Value();
487 : }
488 0 : Uninit();
489 0 : mType = eBoolean;
490 0 : return mValue.mBoolean.SetValue();
491 : }
492 :
493 : bool
494 0 : OwningEventListenerOptionsOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
495 : {
496 0 : tryNext = false;
497 : { // scope for memberSlot
498 0 : bool& memberSlot = RawSetAsBoolean();
499 0 : if (!ValueToPrimitive<bool, eDefault>(cx, value, &memberSlot)) {
500 0 : return false;
501 : }
502 : }
503 0 : return true;
504 : }
505 :
506 : void
507 0 : OwningEventListenerOptionsOrBoolean::DestroyBoolean()
508 : {
509 0 : MOZ_ASSERT(IsBoolean(), "Wrong type!");
510 0 : mValue.mBoolean.Destroy();
511 0 : mType = eUninitialized;
512 0 : }
513 :
514 :
515 :
516 :
517 : void
518 0 : OwningEventListenerOptionsOrBoolean::Uninit()
519 : {
520 0 : switch (mType) {
521 : case eUninitialized: {
522 0 : break;
523 : }
524 : case eEventListenerOptions: {
525 0 : DestroyEventListenerOptions();
526 0 : break;
527 : }
528 : case eBoolean: {
529 0 : DestroyBoolean();
530 0 : break;
531 : }
532 : }
533 0 : }
534 :
535 : bool
536 0 : OwningEventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
537 : {
538 0 : switch (mType) {
539 : case eUninitialized: {
540 0 : return false;
541 : break;
542 : }
543 : case eEventListenerOptions: {
544 0 : if (!mValue.mEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
545 0 : return false;
546 : }
547 0 : return true;
548 : break;
549 : }
550 : case eBoolean: {
551 0 : rval.setBoolean(mValue.mBoolean.Value());
552 0 : return true;
553 : break;
554 : }
555 : default: {
556 0 : return false;
557 : break;
558 : }
559 : }
560 :
561 : return false;
562 : }
563 :
564 : void
565 0 : OwningEventListenerOptionsOrBoolean::TraceUnion(JSTracer* trc)
566 : {
567 0 : }
568 :
569 : OwningEventListenerOptionsOrBoolean&
570 0 : OwningEventListenerOptionsOrBoolean::operator=(const OwningEventListenerOptionsOrBoolean& aOther)
571 : {
572 0 : switch (aOther.mType) {
573 : case eUninitialized: {
574 0 : MOZ_ASSERT(mType == eUninitialized,
575 : "We need to destroy ourselves?");
576 0 : break;
577 : }
578 : case eEventListenerOptions: {
579 0 : SetAsEventListenerOptions() = aOther.GetAsEventListenerOptions();
580 0 : break;
581 : }
582 : case eBoolean: {
583 0 : SetAsBoolean() = aOther.GetAsBoolean();
584 0 : break;
585 : }
586 : }
587 0 : return *this;
588 : }
589 :
590 :
591 : bool
592 0 : AddEventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
593 : {
594 0 : switch (mType) {
595 : case eUninitialized: {
596 0 : return false;
597 : break;
598 : }
599 : case eAddEventListenerOptions: {
600 0 : if (!mValue.mAddEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
601 0 : return false;
602 : }
603 0 : return true;
604 : break;
605 : }
606 : case eBoolean: {
607 0 : rval.setBoolean(mValue.mBoolean.Value());
608 0 : return true;
609 : break;
610 : }
611 : default: {
612 0 : return false;
613 : break;
614 : }
615 : }
616 :
617 : return false;
618 : }
619 :
620 :
621 : AddEventListenerOptions&
622 0 : OwningAddEventListenerOptionsOrBoolean::RawSetAsAddEventListenerOptions()
623 : {
624 0 : if (mType == eAddEventListenerOptions) {
625 0 : return mValue.mAddEventListenerOptions.Value();
626 : }
627 0 : MOZ_ASSERT(mType == eUninitialized);
628 0 : mType = eAddEventListenerOptions;
629 0 : return mValue.mAddEventListenerOptions.SetValue();
630 : }
631 :
632 : AddEventListenerOptions&
633 0 : OwningAddEventListenerOptionsOrBoolean::SetAsAddEventListenerOptions()
634 : {
635 0 : if (mType == eAddEventListenerOptions) {
636 0 : return mValue.mAddEventListenerOptions.Value();
637 : }
638 0 : Uninit();
639 0 : mType = eAddEventListenerOptions;
640 0 : return mValue.mAddEventListenerOptions.SetValue();
641 : }
642 :
643 : bool
644 0 : OwningAddEventListenerOptionsOrBoolean::TrySetToAddEventListenerOptions(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
645 : {
646 0 : tryNext = false;
647 : { // scope for memberSlot
648 0 : AddEventListenerOptions& memberSlot = RawSetAsAddEventListenerOptions();
649 0 : if (!IsConvertibleToDictionary(value)) {
650 0 : DestroyAddEventListenerOptions();
651 0 : tryNext = true;
652 0 : return true;
653 : }
654 0 : if (!memberSlot.Init(cx, value, "Member of AddEventListenerOptionsOrBoolean", passedToJSImpl)) {
655 0 : return false;
656 : }
657 : }
658 0 : return true;
659 : }
660 :
661 : void
662 0 : OwningAddEventListenerOptionsOrBoolean::DestroyAddEventListenerOptions()
663 : {
664 0 : MOZ_ASSERT(IsAddEventListenerOptions(), "Wrong type!");
665 0 : mValue.mAddEventListenerOptions.Destroy();
666 0 : mType = eUninitialized;
667 0 : }
668 :
669 :
670 :
671 :
672 : bool&
673 0 : OwningAddEventListenerOptionsOrBoolean::RawSetAsBoolean()
674 : {
675 0 : if (mType == eBoolean) {
676 0 : return mValue.mBoolean.Value();
677 : }
678 0 : MOZ_ASSERT(mType == eUninitialized);
679 0 : mType = eBoolean;
680 0 : return mValue.mBoolean.SetValue();
681 : }
682 :
683 : bool&
684 0 : OwningAddEventListenerOptionsOrBoolean::SetAsBoolean()
685 : {
686 0 : if (mType == eBoolean) {
687 0 : return mValue.mBoolean.Value();
688 : }
689 0 : Uninit();
690 0 : mType = eBoolean;
691 0 : return mValue.mBoolean.SetValue();
692 : }
693 :
694 : bool
695 0 : OwningAddEventListenerOptionsOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
696 : {
697 0 : tryNext = false;
698 : { // scope for memberSlot
699 0 : bool& memberSlot = RawSetAsBoolean();
700 0 : if (!ValueToPrimitive<bool, eDefault>(cx, value, &memberSlot)) {
701 0 : return false;
702 : }
703 : }
704 0 : return true;
705 : }
706 :
707 : void
708 0 : OwningAddEventListenerOptionsOrBoolean::DestroyBoolean()
709 : {
710 0 : MOZ_ASSERT(IsBoolean(), "Wrong type!");
711 0 : mValue.mBoolean.Destroy();
712 0 : mType = eUninitialized;
713 0 : }
714 :
715 :
716 :
717 :
718 : void
719 0 : OwningAddEventListenerOptionsOrBoolean::Uninit()
720 : {
721 0 : switch (mType) {
722 : case eUninitialized: {
723 0 : break;
724 : }
725 : case eAddEventListenerOptions: {
726 0 : DestroyAddEventListenerOptions();
727 0 : break;
728 : }
729 : case eBoolean: {
730 0 : DestroyBoolean();
731 0 : break;
732 : }
733 : }
734 0 : }
735 :
736 : bool
737 0 : OwningAddEventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
738 : {
739 0 : switch (mType) {
740 : case eUninitialized: {
741 0 : return false;
742 : break;
743 : }
744 : case eAddEventListenerOptions: {
745 0 : if (!mValue.mAddEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
746 0 : return false;
747 : }
748 0 : return true;
749 : break;
750 : }
751 : case eBoolean: {
752 0 : rval.setBoolean(mValue.mBoolean.Value());
753 0 : return true;
754 : break;
755 : }
756 : default: {
757 0 : return false;
758 : break;
759 : }
760 : }
761 :
762 : return false;
763 : }
764 :
765 : void
766 0 : OwningAddEventListenerOptionsOrBoolean::TraceUnion(JSTracer* trc)
767 : {
768 0 : }
769 :
770 : OwningAddEventListenerOptionsOrBoolean&
771 0 : OwningAddEventListenerOptionsOrBoolean::operator=(const OwningAddEventListenerOptionsOrBoolean& aOther)
772 : {
773 0 : switch (aOther.mType) {
774 : case eUninitialized: {
775 0 : MOZ_ASSERT(mType == eUninitialized,
776 : "We need to destroy ourselves?");
777 0 : break;
778 : }
779 : case eAddEventListenerOptions: {
780 0 : SetAsAddEventListenerOptions() = aOther.GetAsAddEventListenerOptions();
781 0 : break;
782 : }
783 : case eBoolean: {
784 0 : SetAsBoolean() = aOther.GetAsBoolean();
785 0 : break;
786 : }
787 : }
788 0 : return *this;
789 : }
790 :
791 :
792 : namespace EventTargetBinding {
793 :
794 : static bool
795 176 : addEventListener(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
796 : {
797 176 : if (MOZ_UNLIKELY(args.length() < 2)) {
798 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.addEventListener");
799 : }
800 352 : binding_detail::FakeString arg0;
801 176 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
802 0 : return false;
803 : }
804 352 : RootedCallback<RefPtr<binding_detail::FastEventListener>> arg1(cx);
805 176 : if (args[1].isObject()) {
806 : { // scope for tempRoot
807 352 : JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
808 352 : arg1 = new binding_detail::FastEventListener(tempRoot);
809 : }
810 0 : } else if (args[1].isNullOrUndefined()) {
811 0 : arg1 = nullptr;
812 : } else {
813 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of EventTarget.addEventListener");
814 0 : return false;
815 : }
816 352 : AddEventListenerOptionsOrBoolean arg2;
817 176 : AddEventListenerOptionsOrBooleanArgument arg2_holder(arg2);
818 176 : if (!(args.hasDefined(2))) {
819 129 : if (!arg2.RawSetAsAddEventListenerOptions().Init(cx, JS::NullHandleValue, "Member of AddEventListenerOptionsOrBoolean")) {
820 0 : return false;
821 : }
822 : } else {
823 : {
824 47 : bool done = false, failed = false, tryNext;
825 47 : if (!done) {
826 47 : done = (failed = !arg2_holder.TrySetToAddEventListenerOptions(cx, args[2], tryNext, false)) || !tryNext;
827 : }
828 47 : if (!done) {
829 : do {
830 41 : done = (failed = !arg2_holder.TrySetToBoolean(cx, args[2], tryNext)) || !tryNext;
831 41 : break;
832 : } while (0);
833 : }
834 47 : if (failed) {
835 0 : return false;
836 : }
837 47 : if (!done) {
838 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of EventTarget.addEventListener", "AddEventListenerOptions");
839 0 : return false;
840 : }
841 : }
842 : }
843 352 : Nullable<bool> arg3;
844 176 : if (!(args.hasDefined(3)) || args[3].isNullOrUndefined()) {
845 173 : arg3.SetNull();
846 3 : } else if (!ValueToPrimitive<bool, eDefault>(cx, args[3], &arg3.SetValue())) {
847 0 : return false;
848 : }
849 352 : binding_detail::FastErrorResult rv;
850 176 : self->AddEventListener(NonNullHelper(Constify(arg0)), Constify(arg1), Constify(arg2), Constify(arg3), rv);
851 176 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
852 0 : return false;
853 : }
854 176 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
855 176 : args.rval().setUndefined();
856 176 : return true;
857 : }
858 :
859 : static const JSJitInfo addEventListener_methodinfo = {
860 : { (JSJitGetterOp)addEventListener },
861 : { prototypes::id::EventTarget },
862 : { PrototypeTraits<prototypes::id::EventTarget>::Depth },
863 : JSJitInfo::Method,
864 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
865 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
866 : false, /* isInfallible. False in setters. */
867 : false, /* isMovable. Not relevant for setters. */
868 : false, /* isEliminatable. Not relevant for setters. */
869 : false, /* isAlwaysInSlot. Only relevant for getters. */
870 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
871 : false, /* isTypedMethod. Only relevant for methods. */
872 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
873 : };
874 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
875 : static_assert(0 < 1, "There is no slot for us");
876 :
877 : static bool
878 15 : removeEventListener(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
879 : {
880 15 : if (MOZ_UNLIKELY(args.length() < 2)) {
881 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.removeEventListener");
882 : }
883 30 : binding_detail::FakeString arg0;
884 15 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
885 0 : return false;
886 : }
887 30 : RootedCallback<RefPtr<binding_detail::FastEventListener>> arg1(cx);
888 15 : if (args[1].isObject()) {
889 : { // scope for tempRoot
890 30 : JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
891 30 : arg1 = new binding_detail::FastEventListener(tempRoot);
892 : }
893 0 : } else if (args[1].isNullOrUndefined()) {
894 0 : arg1 = nullptr;
895 : } else {
896 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of EventTarget.removeEventListener");
897 0 : return false;
898 : }
899 30 : EventListenerOptionsOrBoolean arg2;
900 15 : EventListenerOptionsOrBooleanArgument arg2_holder(arg2);
901 15 : if (!(args.hasDefined(2))) {
902 8 : if (!arg2.RawSetAsEventListenerOptions().Init(cx, JS::NullHandleValue, "Member of EventListenerOptionsOrBoolean")) {
903 0 : return false;
904 : }
905 : } else {
906 : {
907 7 : bool done = false, failed = false, tryNext;
908 7 : if (!done) {
909 7 : done = (failed = !arg2_holder.TrySetToEventListenerOptions(cx, args[2], tryNext, false)) || !tryNext;
910 : }
911 7 : if (!done) {
912 : do {
913 7 : done = (failed = !arg2_holder.TrySetToBoolean(cx, args[2], tryNext)) || !tryNext;
914 7 : break;
915 : } while (0);
916 : }
917 7 : if (failed) {
918 0 : return false;
919 : }
920 7 : if (!done) {
921 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of EventTarget.removeEventListener", "EventListenerOptions");
922 0 : return false;
923 : }
924 : }
925 : }
926 30 : binding_detail::FastErrorResult rv;
927 15 : self->RemoveEventListener(NonNullHelper(Constify(arg0)), Constify(arg1), Constify(arg2), rv);
928 15 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
929 0 : return false;
930 : }
931 15 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
932 15 : args.rval().setUndefined();
933 15 : return true;
934 : }
935 :
936 : static const JSJitInfo removeEventListener_methodinfo = {
937 : { (JSJitGetterOp)removeEventListener },
938 : { prototypes::id::EventTarget },
939 : { PrototypeTraits<prototypes::id::EventTarget>::Depth },
940 : JSJitInfo::Method,
941 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
942 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
943 : false, /* isInfallible. False in setters. */
944 : false, /* isMovable. Not relevant for setters. */
945 : false, /* isEliminatable. Not relevant for setters. */
946 : false, /* isAlwaysInSlot. Only relevant for getters. */
947 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
948 : false, /* isTypedMethod. Only relevant for methods. */
949 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
950 : };
951 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
952 : static_assert(0 < 1, "There is no slot for us");
953 :
954 : static bool
955 12 : dispatchEvent(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
956 : {
957 12 : if (MOZ_UNLIKELY(args.length() < 1)) {
958 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.dispatchEvent");
959 : }
960 12 : NonNull<mozilla::dom::Event> arg0;
961 12 : if (args[0].isObject()) {
962 : {
963 12 : nsresult rv = UnwrapObject<prototypes::id::Event, mozilla::dom::Event>(args[0], arg0);
964 12 : if (NS_FAILED(rv)) {
965 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of EventTarget.dispatchEvent", "Event");
966 0 : return false;
967 : }
968 : }
969 : } else {
970 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of EventTarget.dispatchEvent");
971 0 : return false;
972 : }
973 24 : binding_detail::FastErrorResult rv;
974 12 : bool result(self->DispatchEvent(NonNullHelper(arg0), nsContentUtils::ThreadsafeIsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv));
975 12 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
976 0 : return false;
977 : }
978 12 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
979 12 : args.rval().setBoolean(result);
980 12 : return true;
981 : }
982 :
983 : static const JSJitInfo dispatchEvent_methodinfo = {
984 : { (JSJitGetterOp)dispatchEvent },
985 : { prototypes::id::EventTarget },
986 : { PrototypeTraits<prototypes::id::EventTarget>::Depth },
987 : JSJitInfo::Method,
988 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
989 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
990 : false, /* isInfallible. False in setters. */
991 : false, /* isMovable. Not relevant for setters. */
992 : false, /* isEliminatable. Not relevant for setters. */
993 : false, /* isAlwaysInSlot. Only relevant for getters. */
994 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
995 : false, /* isTypedMethod. Only relevant for methods. */
996 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
997 : };
998 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
999 : static_assert(0 < 1, "There is no slot for us");
1000 :
1001 : static bool
1002 0 : setEventHandler(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
1003 : {
1004 0 : if (MOZ_UNLIKELY(args.length() < 2)) {
1005 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.setEventHandler");
1006 : }
1007 0 : binding_detail::FakeString arg0;
1008 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1009 0 : return false;
1010 : }
1011 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg1(cx);
1012 0 : if (args[1].isObject()) {
1013 : { // scope for tempRoot
1014 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
1015 0 : arg1 = new binding_detail::FastEventHandlerNonNull(tempRoot);
1016 : }
1017 : } else {
1018 0 : arg1 = nullptr;
1019 : }
1020 0 : binding_detail::FastErrorResult rv;
1021 0 : self->SetEventHandler(NonNullHelper(Constify(arg0)), Constify(arg1), rv);
1022 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1023 0 : return false;
1024 : }
1025 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1026 0 : args.rval().setUndefined();
1027 0 : return true;
1028 : }
1029 :
1030 : static const JSJitInfo setEventHandler_methodinfo = {
1031 : { (JSJitGetterOp)setEventHandler },
1032 : { prototypes::id::EventTarget },
1033 : { PrototypeTraits<prototypes::id::EventTarget>::Depth },
1034 : JSJitInfo::Method,
1035 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1036 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1037 : false, /* isInfallible. False in setters. */
1038 : false, /* isMovable. Not relevant for setters. */
1039 : false, /* isEliminatable. Not relevant for setters. */
1040 : false, /* isAlwaysInSlot. Only relevant for getters. */
1041 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1042 : false, /* isTypedMethod. Only relevant for methods. */
1043 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1044 : };
1045 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1046 : static_assert(0 < 1, "There is no slot for us");
1047 :
1048 : static bool
1049 0 : getEventHandler(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
1050 : {
1051 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1052 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.getEventHandler");
1053 : }
1054 0 : binding_detail::FakeString arg0;
1055 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1056 0 : return false;
1057 : }
1058 0 : RefPtr<EventHandlerNonNull> result(self->GetEventHandler(NonNullHelper(Constify(arg0))));
1059 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1060 0 : if (result) {
1061 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
1062 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
1063 0 : return false;
1064 : }
1065 0 : return true;
1066 : } else {
1067 0 : args.rval().setNull();
1068 0 : return true;
1069 : }
1070 : }
1071 :
1072 : static const JSJitInfo getEventHandler_methodinfo = {
1073 : { (JSJitGetterOp)getEventHandler },
1074 : { prototypes::id::EventTarget },
1075 : { PrototypeTraits<prototypes::id::EventTarget>::Depth },
1076 : JSJitInfo::Method,
1077 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1078 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
1079 : false, /* isInfallible. False in setters. */
1080 : false, /* isMovable. Not relevant for setters. */
1081 : false, /* isEliminatable. Not relevant for setters. */
1082 : false, /* isAlwaysInSlot. Only relevant for getters. */
1083 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1084 : false, /* isTypedMethod. Only relevant for methods. */
1085 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1086 : };
1087 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1088 : static_assert(0 < 1, "There is no slot for us");
1089 :
1090 : static bool
1091 35 : get_ownerGlobal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, JSJitGetterCallArgs args)
1092 : {
1093 35 : auto result(StrongOrRawPtr<nsPIDOMWindowOuter>(self->GetOwnerGlobalForBindings()));
1094 35 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1095 35 : if (!result) {
1096 0 : args.rval().setNull();
1097 0 : return true;
1098 : }
1099 35 : if (!WrapObject(cx, result, args.rval())) {
1100 0 : return false;
1101 : }
1102 35 : return true;
1103 : }
1104 :
1105 : static const JSJitInfo ownerGlobal_getterinfo = {
1106 : { (JSJitGetterOp)get_ownerGlobal },
1107 : { prototypes::id::EventTarget },
1108 : { PrototypeTraits<prototypes::id::EventTarget>::Depth },
1109 : JSJitInfo::Getter,
1110 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1111 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
1112 : false, /* isInfallible. False in setters. */
1113 : false, /* isMovable. Not relevant for setters. */
1114 : false, /* isEliminatable. Not relevant for setters. */
1115 : false, /* isAlwaysInSlot. Only relevant for getters. */
1116 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1117 : false, /* isTypedMethod. Only relevant for methods. */
1118 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1119 : };
1120 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1121 : static_assert(0 < 1, "There is no slot for us");
1122 :
1123 : static bool
1124 203 : genericMethod(JSContext* cx, unsigned argc, JS::Value* vp)
1125 : {
1126 203 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1127 203 : if (!args.thisv().isNullOrUndefined() && !args.thisv().isObject()) {
1128 0 : return ThrowInvalidThis(cx, args, false, "EventTarget");
1129 : }
1130 406 : JS::Rooted<JSObject*> obj(cx, args.thisv().isObject() ? &args.thisv().toObject() : js::GetGlobalForObjectCrossCompartment(&args.callee()));
1131 :
1132 : mozilla::dom::EventTarget* self;
1133 406 : JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
1134 : {
1135 203 : nsresult rv = UnwrapObject<prototypes::id::EventTarget, mozilla::dom::EventTarget>(&rootSelf, self);
1136 203 : if (NS_FAILED(rv)) {
1137 0 : RefPtr<mozilla::dom::EventTarget> objPtr;
1138 0 : nsresult rv = UnwrapXPConnect<mozilla::dom::EventTarget>(cx, &rootSelf, getter_AddRefs(objPtr));
1139 0 : if (NS_FAILED(rv)) {
1140 0 : return ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO, "EventTarget");
1141 : }
1142 : // We should have an object
1143 0 : MOZ_ASSERT(objPtr);
1144 0 : self = objPtr;
1145 : }
1146 : }
1147 203 : const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
1148 203 : MOZ_ASSERT(info->type() == JSJitInfo::Method);
1149 203 : JSJitMethodOp method = info->method;
1150 203 : bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
1151 : #ifdef DEBUG
1152 203 : if (ok) {
1153 203 : AssertReturnTypeMatchesJitinfo(info, args.rval());
1154 : }
1155 : #endif
1156 203 : return ok;
1157 : }
1158 :
1159 : static bool
1160 35 : genericGetter(JSContext* cx, unsigned argc, JS::Value* vp)
1161 : {
1162 35 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1163 35 : if (!args.thisv().isNullOrUndefined() && !args.thisv().isObject()) {
1164 0 : return ThrowInvalidThis(cx, args, false, "EventTarget");
1165 : }
1166 70 : JS::Rooted<JSObject*> obj(cx, args.thisv().isObject() ? &args.thisv().toObject() : js::GetGlobalForObjectCrossCompartment(&args.callee()));
1167 :
1168 : mozilla::dom::EventTarget* self;
1169 70 : JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
1170 : {
1171 35 : nsresult rv = UnwrapObject<prototypes::id::EventTarget, mozilla::dom::EventTarget>(&rootSelf, self);
1172 35 : if (NS_FAILED(rv)) {
1173 0 : RefPtr<mozilla::dom::EventTarget> objPtr;
1174 0 : nsresult rv = UnwrapXPConnect<mozilla::dom::EventTarget>(cx, &rootSelf, getter_AddRefs(objPtr));
1175 0 : if (NS_FAILED(rv)) {
1176 0 : return ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO, "EventTarget");
1177 : }
1178 : // We should have an object
1179 0 : MOZ_ASSERT(objPtr);
1180 0 : self = objPtr;
1181 : }
1182 : }
1183 35 : const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
1184 35 : MOZ_ASSERT(info->type() == JSJitInfo::Getter);
1185 35 : JSJitGetterOp getter = info->getter;
1186 35 : bool ok = getter(cx, obj, self, JSJitGetterCallArgs(args));
1187 : #ifdef DEBUG
1188 35 : if (ok) {
1189 35 : AssertReturnTypeMatchesJitinfo(info, args.rval());
1190 : }
1191 : #endif
1192 35 : return ok;
1193 : }
1194 :
1195 : static bool
1196 0 : _hasInstance(JSContext* cx, unsigned argc, JS::Value* vp)
1197 : {
1198 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1199 0 : if (!args.get(0).isObject()) {
1200 0 : args.rval().setBoolean(false);
1201 0 : return true;
1202 : }
1203 :
1204 0 : JS::Rooted<JSObject*> instance(cx, &args[0].toObject());
1205 :
1206 : static_assert(IsBaseOf<nsISupports, mozilla::dom::EventTarget>::value,
1207 : "HasInstance only works for nsISupports-based classes.");
1208 :
1209 0 : bool ok = InterfaceHasInstance(cx, argc, vp);
1210 0 : if (!ok || args.rval().toBoolean()) {
1211 0 : return ok;
1212 : }
1213 :
1214 : // FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
1215 : nsCOMPtr<nsISupports> native =
1216 0 : xpc::UnwrapReflectorToISupports(js::UncheckedUnwrap(instance, /* stopAtWindowProxy = */ false));
1217 0 : nsCOMPtr<nsIDOMEventTarget> qiResult = do_QueryInterface(native);
1218 0 : args.rval().setBoolean(!!qiResult);
1219 0 : return true;
1220 : }
1221 :
1222 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1223 : #if defined(__clang__)
1224 : #pragma clang diagnostic push
1225 : #pragma clang diagnostic ignored "-Wmissing-braces"
1226 : #endif
1227 : static const JSFunctionSpec sStaticMethods_specs[] = {
1228 : JS_SYM_FNSPEC(hasInstance, _hasInstance, nullptr, 1, JSPROP_READONLY | JSPROP_PERMANENT, nullptr),
1229 : JS_FS_END
1230 : };
1231 : #if defined(__clang__)
1232 : #pragma clang diagnostic pop
1233 : #endif
1234 :
1235 :
1236 : // Can't be const because the pref-enabled boolean needs to be writable
1237 : static Prefable<const JSFunctionSpec> sStaticMethods[] = {
1238 : { nullptr, &sStaticMethods_specs[0] },
1239 : { nullptr, nullptr }
1240 : };
1241 :
1242 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1243 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1244 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1245 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1246 :
1247 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1248 : #if defined(__clang__)
1249 : #pragma clang diagnostic push
1250 : #pragma clang diagnostic ignored "-Wmissing-braces"
1251 : #endif
1252 : static const JSFunctionSpec sMethods_specs[] = {
1253 : JS_FNSPEC("addEventListener", genericMethod, reinterpret_cast<const JSJitInfo*>(&addEventListener_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
1254 : JS_FNSPEC("removeEventListener", genericMethod, reinterpret_cast<const JSJitInfo*>(&removeEventListener_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
1255 : JS_FNSPEC("dispatchEvent", genericMethod, reinterpret_cast<const JSJitInfo*>(&dispatchEvent_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1256 : JS_FS_END
1257 : };
1258 : #if defined(__clang__)
1259 : #pragma clang diagnostic pop
1260 : #endif
1261 :
1262 :
1263 : // Can't be const because the pref-enabled boolean needs to be writable
1264 : static Prefable<const JSFunctionSpec> sMethods[] = {
1265 : { nullptr, &sMethods_specs[0] },
1266 : { nullptr, nullptr }
1267 : };
1268 :
1269 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1270 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1271 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1272 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1273 :
1274 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1275 : #if defined(__clang__)
1276 : #pragma clang diagnostic push
1277 : #pragma clang diagnostic ignored "-Wmissing-braces"
1278 : #endif
1279 : static const JSFunctionSpec sChromeMethods_specs[] = {
1280 : JS_FNSPEC("setEventHandler", genericMethod, reinterpret_cast<const JSJitInfo*>(&setEventHandler_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
1281 : JS_FNSPEC("getEventHandler", genericMethod, reinterpret_cast<const JSJitInfo*>(&getEventHandler_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1282 : JS_FS_END
1283 : };
1284 : #if defined(__clang__)
1285 : #pragma clang diagnostic pop
1286 : #endif
1287 :
1288 :
1289 : // Can't be const because the pref-enabled boolean needs to be writable
1290 : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
1291 : { nullptr, &sChromeMethods_specs[0] },
1292 : { nullptr, nullptr }
1293 : };
1294 :
1295 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1296 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1297 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1298 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1299 :
1300 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1301 : #if defined(__clang__)
1302 : #pragma clang diagnostic push
1303 : #pragma clang diagnostic ignored "-Wmissing-braces"
1304 : #endif
1305 : static const JSPropertySpec sChromeAttributes_specs[] = {
1306 : { "ownerGlobal", JSPROP_SHARED | JSPROP_ENUMERATE, genericGetter, &ownerGlobal_getterinfo, nullptr, nullptr },
1307 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1308 : };
1309 : #if defined(__clang__)
1310 : #pragma clang diagnostic pop
1311 : #endif
1312 :
1313 : static PrefableDisablers sChromeAttributes_disablers0 = {
1314 : true, false, GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::WorkerDebuggerGlobalScope, nullptr
1315 : };
1316 :
1317 : // Can't be const because the pref-enabled boolean needs to be writable
1318 : static Prefable<const JSPropertySpec> sChromeAttributes[] = {
1319 : { &sChromeAttributes_disablers0, &sChromeAttributes_specs[0] },
1320 : { nullptr, nullptr }
1321 : };
1322 :
1323 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1324 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1325 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1326 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1327 :
1328 :
1329 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
1330 : static PropertyInfo sNativeProperties_propertyInfos[4];
1331 :
1332 : static const NativePropertiesN<2> sNativeProperties = {
1333 : true, 0 /* sStaticMethods */,
1334 : false, 0,
1335 : true, 1 /* sMethods */,
1336 : false, 0,
1337 : false, 0,
1338 : false, 0,
1339 : false, 0,
1340 : -1,
1341 : 4,
1342 : sNativeProperties_sortedPropertyIndices,
1343 : {
1344 : { sStaticMethods, &sNativeProperties_propertyInfos[0] },
1345 : { sMethods, &sNativeProperties_propertyInfos[1] }
1346 : }
1347 : };
1348 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1349 : "We have a property info count that is oversized");
1350 :
1351 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[3];
1352 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[3];
1353 :
1354 : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
1355 : false, 0,
1356 : false, 0,
1357 : true, 0 /* sChromeMethods */,
1358 : true, 1 /* sChromeAttributes */,
1359 : false, 0,
1360 : false, 0,
1361 : false, 0,
1362 : -1,
1363 : 3,
1364 : sChromeOnlyNativeProperties_sortedPropertyIndices,
1365 : {
1366 : { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
1367 : { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[2] }
1368 : }
1369 : };
1370 : static_assert(3 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
1371 : "We have a property info count that is oversized");
1372 :
1373 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1374 : {
1375 : "Function",
1376 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1377 : &sBoringInterfaceObjectClassClassOps,
1378 : JS_NULL_CLASS_SPEC,
1379 : JS_NULL_CLASS_EXT,
1380 : &sInterfaceObjectClassObjectOps
1381 : },
1382 : eInterface,
1383 : false,
1384 : prototypes::id::EventTarget,
1385 : PrototypeTraits<prototypes::id::EventTarget>::Depth,
1386 : sNativePropertyHooks,
1387 : "function EventTarget() {\n [native code]\n}",
1388 : JS::GetRealmFunctionPrototype
1389 : };
1390 :
1391 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1392 : {
1393 : "EventTargetPrototype",
1394 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1395 : JS_NULL_CLASS_OPS,
1396 : JS_NULL_CLASS_SPEC,
1397 : JS_NULL_CLASS_EXT,
1398 : JS_NULL_OBJECT_OPS
1399 : },
1400 : eInterfacePrototype,
1401 : false,
1402 : prototypes::id::EventTarget,
1403 : PrototypeTraits<prototypes::id::EventTarget>::Depth,
1404 : sNativePropertyHooks,
1405 : "[object EventTargetPrototype]",
1406 : JS::GetRealmObjectPrototype
1407 : };
1408 :
1409 : JSObject*
1410 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1411 : {
1412 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1413 : }
1414 :
1415 : const NativePropertyHooks sNativePropertyHooks[] = { {
1416 : nullptr,
1417 : nullptr,
1418 : nullptr,
1419 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1420 : prototypes::id::EventTarget,
1421 : constructors::id::EventTarget,
1422 : nullptr,
1423 : &DefaultXrayExpandoObjectClass
1424 : } };
1425 :
1426 : void
1427 34 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1428 : {
1429 68 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1430 34 : if (!parentProto) {
1431 0 : return;
1432 : }
1433 :
1434 68 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1435 34 : if (!constructorProto) {
1436 0 : return;
1437 : }
1438 :
1439 : static bool sIdsInited = false;
1440 34 : if (!sIdsInited && NS_IsMainThread()) {
1441 3 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1442 0 : return;
1443 : }
1444 3 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1445 0 : return;
1446 : }
1447 3 : sIdsInited = true;
1448 : }
1449 :
1450 34 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::EventTarget);
1451 34 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::EventTarget);
1452 102 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1453 : &sPrototypeClass.mBase, protoCache,
1454 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1455 : interfaceCache,
1456 : sNativeProperties.Upcast(),
1457 34 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
1458 : "EventTarget", aDefineOnGlobal,
1459 : nullptr,
1460 34 : false);
1461 :
1462 34 : if (*&aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::EventTarget)) {
1463 : bool succeeded;
1464 34 : JS::Handle<JSObject*> prot = GetProtoObjectHandle(aCx);
1465 34 : if (!JS_SetImmutablePrototype(aCx, prot, &succeeded)) {
1466 0 : *protoCache = nullptr;
1467 0 : if (interfaceCache) {
1468 0 : *interfaceCache = nullptr;
1469 : }
1470 0 : return;
1471 : }
1472 :
1473 34 : MOZ_ASSERT(succeeded,
1474 : "making a fresh prototype object's [[Prototype]] "
1475 : "immutable can internally fail, but it should "
1476 : "never be unsuccessful");
1477 : }
1478 : }
1479 :
1480 : JS::Handle<JSObject*>
1481 135 : GetProtoObjectHandle(JSContext* aCx)
1482 : {
1483 : /* Get the interface prototype object for this class. This will create the
1484 : object as needed. */
1485 135 : bool aDefineOnGlobal = true;
1486 :
1487 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1488 135 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1489 135 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1490 0 : return nullptr;
1491 : }
1492 :
1493 : /* Check to see whether the interface objects are already installed */
1494 135 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1495 135 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::EventTarget)) {
1496 68 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1497 34 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1498 : }
1499 :
1500 : /*
1501 : * The object might _still_ be null, but that's OK.
1502 : *
1503 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1504 : * traced by TraceProtoAndIfaceCache() and its contents are never
1505 : * changed after they have been set.
1506 : *
1507 : * Calling address() avoids the read read barrier that does gray
1508 : * unmarking, but it's not possible for the object to be gray here.
1509 : */
1510 :
1511 135 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::EventTarget);
1512 135 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1513 135 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1514 : }
1515 :
1516 : JSObject*
1517 1 : GetProtoObject(JSContext* aCx)
1518 : {
1519 1 : return GetProtoObjectHandle(aCx);
1520 : }
1521 :
1522 : JS::Handle<JSObject*>
1523 101 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1524 : {
1525 : /* Get the interface object for this class. This will create the object as
1526 : needed. */
1527 :
1528 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1529 101 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1530 101 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1531 0 : return nullptr;
1532 : }
1533 :
1534 : /* Check to see whether the interface objects are already installed */
1535 101 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1536 101 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::EventTarget)) {
1537 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1538 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1539 : }
1540 :
1541 : /*
1542 : * The object might _still_ be null, but that's OK.
1543 : *
1544 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1545 : * traced by TraceProtoAndIfaceCache() and its contents are never
1546 : * changed after they have been set.
1547 : *
1548 : * Calling address() avoids the read read barrier that does gray
1549 : * unmarking, but it's not possible for the object to be gray here.
1550 : */
1551 :
1552 101 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::EventTarget);
1553 101 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1554 101 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1555 : }
1556 :
1557 : JSObject*
1558 1 : GetConstructorObject(JSContext* aCx)
1559 : {
1560 1 : return GetConstructorObjectHandle(aCx);
1561 : }
1562 :
1563 : } // namespace EventTargetBinding
1564 :
1565 :
1566 :
1567 : } // namespace dom
1568 : } // namespace mozilla
|