Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM AnimationEvent.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AnimationEventBinding.h"
4 : #include "AtomList.h"
5 : #include "EventBinding.h"
6 : #include "WrapperFactory.h"
7 : #include "mozilla/FloatingPoint.h"
8 : #include "mozilla/OwningNonNull.h"
9 : #include "mozilla/dom/AnimationEvent.h"
10 : #include "mozilla/dom/BindingUtils.h"
11 : #include "mozilla/dom/DOMJSClass.h"
12 : #include "mozilla/dom/NonRefcountedDOMObject.h"
13 : #include "mozilla/dom/PrimitiveConversions.h"
14 : #include "mozilla/dom/ScriptSettings.h"
15 : #include "mozilla/dom/SimpleGlobalObject.h"
16 : #include "mozilla/dom/XrayExpandoClass.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 :
22 0 : AnimationEventInit::AnimationEventInit()
23 0 : : EventInit(FastDictionaryInitializer())
24 : {
25 : // Safe to pass a null context if we pass a null value
26 0 : Init(nullptr, JS::NullHandleValue);
27 0 : }
28 :
29 :
30 :
31 : bool
32 0 : AnimationEventInit::InitIds(JSContext* cx, AnimationEventInitAtoms* atomsCache)
33 : {
34 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
35 :
36 : // Initialize these in reverse order so that any failure leaves the first one
37 : // uninitialized.
38 0 : if (!atomsCache->pseudoElement_id.init(cx, "pseudoElement") ||
39 0 : !atomsCache->elapsedTime_id.init(cx, "elapsedTime") ||
40 0 : !atomsCache->animationName_id.init(cx, "animationName")) {
41 0 : return false;
42 : }
43 0 : return true;
44 : }
45 :
46 : bool
47 0 : AnimationEventInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
48 : {
49 : // Passing a null JSContext is OK only if we're initing from null,
50 : // Since in that case we will not have to do any property gets
51 : // Also evaluate isNullOrUndefined in order to avoid false-positive
52 : // checkers by static analysis tools
53 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
54 0 : AnimationEventInitAtoms* atomsCache = nullptr;
55 0 : if (cx) {
56 0 : atomsCache = GetAtomCache<AnimationEventInitAtoms>(cx);
57 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
58 0 : return false;
59 : }
60 : }
61 :
62 : // Per spec, we init the parent's members first
63 0 : if (!EventInit::Init(cx, val)) {
64 0 : return false;
65 : }
66 :
67 0 : bool isNull = val.isNullOrUndefined();
68 : // We only need these if !isNull, in which case we have |cx|.
69 0 : Maybe<JS::Rooted<JSObject *> > object;
70 0 : Maybe<JS::Rooted<JS::Value> > temp;
71 0 : if (!isNull) {
72 0 : MOZ_ASSERT(cx);
73 0 : object.emplace(cx, &val.toObject());
74 0 : temp.emplace(cx);
75 : }
76 0 : if (!isNull) {
77 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->animationName_id, temp.ptr())) {
78 0 : return false;
79 : }
80 : }
81 0 : if (!isNull && !temp->isUndefined()) {
82 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mAnimationName)) {
83 0 : return false;
84 : }
85 : } else {
86 : static const char16_t data[] = { 0 };
87 0 : mAnimationName.Rebind(data, ArrayLength(data) - 1);
88 : }
89 0 : mIsAnyMemberPresent = true;
90 :
91 0 : if (!isNull) {
92 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->elapsedTime_id, temp.ptr())) {
93 0 : return false;
94 : }
95 : }
96 0 : if (!isNull && !temp->isUndefined()) {
97 0 : if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), &mElapsedTime)) {
98 0 : return false;
99 0 : } else if (!mozilla::IsFinite(mElapsedTime)) {
100 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'elapsedTime' member of AnimationEventInit");
101 0 : return false;
102 : }
103 : } else {
104 0 : mElapsedTime = 0.0F;
105 : }
106 0 : mIsAnyMemberPresent = true;
107 :
108 0 : if (!isNull) {
109 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->pseudoElement_id, temp.ptr())) {
110 0 : return false;
111 : }
112 : }
113 0 : if (!isNull && !temp->isUndefined()) {
114 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mPseudoElement)) {
115 0 : return false;
116 : }
117 : } else {
118 : static const char16_t data[] = { 0 };
119 0 : mPseudoElement.Rebind(data, ArrayLength(data) - 1);
120 : }
121 0 : mIsAnyMemberPresent = true;
122 0 : return true;
123 : }
124 :
125 : bool
126 0 : AnimationEventInit::Init(const nsAString& aJSON)
127 : {
128 0 : AutoJSAPI jsapi;
129 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
130 0 : if (!cleanGlobal) {
131 0 : return false;
132 : }
133 0 : if (!jsapi.Init(cleanGlobal)) {
134 0 : return false;
135 : }
136 0 : JSContext* cx = jsapi.cx();
137 0 : JS::Rooted<JS::Value> json(cx);
138 0 : bool ok = ParseJSON(cx, aJSON, &json);
139 0 : NS_ENSURE_TRUE(ok, false);
140 0 : return Init(cx, json);
141 : }
142 :
143 : bool
144 0 : AnimationEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
145 : {
146 0 : AnimationEventInitAtoms* atomsCache = GetAtomCache<AnimationEventInitAtoms>(cx);
147 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
148 0 : return false;
149 : }
150 :
151 : // Per spec, we define the parent's members first
152 0 : if (!EventInit::ToObjectInternal(cx, rval)) {
153 0 : return false;
154 : }
155 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
156 :
157 : do {
158 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
159 0 : JS::Rooted<JS::Value> temp(cx);
160 0 : nsString const & currentValue = mAnimationName;
161 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
162 0 : return false;
163 : }
164 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->animationName_id, temp, JSPROP_ENUMERATE)) {
165 0 : return false;
166 : }
167 0 : break;
168 : } while(0);
169 :
170 : do {
171 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
172 0 : JS::Rooted<JS::Value> temp(cx);
173 0 : float const & currentValue = mElapsedTime;
174 0 : temp.set(JS_NumberValue(double(currentValue)));
175 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->elapsedTime_id, temp, JSPROP_ENUMERATE)) {
176 0 : return false;
177 : }
178 0 : break;
179 : } while(0);
180 :
181 : do {
182 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
183 0 : JS::Rooted<JS::Value> temp(cx);
184 0 : nsString const & currentValue = mPseudoElement;
185 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
186 0 : return false;
187 : }
188 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->pseudoElement_id, temp, JSPROP_ENUMERATE)) {
189 0 : return false;
190 : }
191 0 : break;
192 : } while(0);
193 :
194 0 : return true;
195 : }
196 :
197 : bool
198 0 : AnimationEventInit::ToJSON(nsAString& aJSON) const
199 : {
200 0 : AutoJSAPI jsapi;
201 0 : jsapi.Init();
202 0 : JSContext *cx = jsapi.cx();
203 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
204 : // because we'll only be creating objects, in ways that have no
205 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
206 : // which likewise guarantees no side-effects for the sorts of
207 : // things we will pass it.
208 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
209 0 : JS::Rooted<JS::Value> val(cx);
210 0 : if (!ToObjectInternal(cx, &val)) {
211 0 : return false;
212 : }
213 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
214 0 : return StringifyToJSON(cx, obj, aJSON);
215 : }
216 :
217 : void
218 0 : AnimationEventInit::TraceDictionary(JSTracer* trc)
219 : {
220 0 : EventInit::TraceDictionary(trc);
221 0 : }
222 :
223 : AnimationEventInit&
224 0 : AnimationEventInit::operator=(const AnimationEventInit& aOther)
225 : {
226 0 : EventInit::operator=(aOther);
227 0 : mAnimationName = aOther.mAnimationName;
228 0 : mElapsedTime = aOther.mElapsedTime;
229 0 : mPseudoElement = aOther.mPseudoElement;
230 0 : return *this;
231 : }
232 :
233 : namespace binding_detail {
234 : } // namespace binding_detail
235 :
236 :
237 : namespace AnimationEventBinding {
238 :
239 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventBinding::NativeType>::value,
240 : "Can't inherit from an interface with a different ownership model.");
241 :
242 : static bool
243 0 : get_animationName(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AnimationEvent* self, JSJitGetterCallArgs args)
244 : {
245 0 : DOMString result;
246 0 : self->GetAnimationName(result);
247 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
248 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
249 0 : return false;
250 : }
251 0 : return true;
252 : }
253 :
254 : static const JSJitInfo animationName_getterinfo = {
255 : { (JSJitGetterOp)get_animationName },
256 : { prototypes::id::AnimationEvent },
257 : { PrototypeTraits<prototypes::id::AnimationEvent>::Depth },
258 : JSJitInfo::Getter,
259 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
260 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
261 : false, /* isInfallible. False in setters. */
262 : false, /* isMovable. Not relevant for setters. */
263 : false, /* isEliminatable. Not relevant for setters. */
264 : false, /* isAlwaysInSlot. Only relevant for getters. */
265 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
266 : false, /* isTypedMethod. Only relevant for methods. */
267 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
268 : };
269 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
270 : static_assert(0 < 1, "There is no slot for us");
271 :
272 : static bool
273 0 : get_elapsedTime(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AnimationEvent* self, JSJitGetterCallArgs args)
274 : {
275 0 : float result(self->ElapsedTime());
276 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
277 0 : args.rval().set(JS_NumberValue(double(result)));
278 0 : return true;
279 : }
280 :
281 : static const JSJitInfo elapsedTime_getterinfo = {
282 : { (JSJitGetterOp)get_elapsedTime },
283 : { prototypes::id::AnimationEvent },
284 : { PrototypeTraits<prototypes::id::AnimationEvent>::Depth },
285 : JSJitInfo::Getter,
286 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
287 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
288 : true, /* isInfallible. False in setters. */
289 : false, /* isMovable. Not relevant for setters. */
290 : false, /* isEliminatable. Not relevant for setters. */
291 : false, /* isAlwaysInSlot. Only relevant for getters. */
292 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
293 : false, /* isTypedMethod. Only relevant for methods. */
294 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
295 : };
296 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
297 : static_assert(0 < 1, "There is no slot for us");
298 :
299 : static bool
300 0 : get_pseudoElement(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AnimationEvent* self, JSJitGetterCallArgs args)
301 : {
302 0 : DOMString result;
303 0 : self->GetPseudoElement(result);
304 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
305 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
306 0 : return false;
307 : }
308 0 : return true;
309 : }
310 :
311 : static const JSJitInfo pseudoElement_getterinfo = {
312 : { (JSJitGetterOp)get_pseudoElement },
313 : { prototypes::id::AnimationEvent },
314 : { PrototypeTraits<prototypes::id::AnimationEvent>::Depth },
315 : JSJitInfo::Getter,
316 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
317 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
318 : false, /* isInfallible. False in setters. */
319 : false, /* isMovable. Not relevant for setters. */
320 : false, /* isEliminatable. Not relevant for setters. */
321 : false, /* isAlwaysInSlot. Only relevant for getters. */
322 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
323 : false, /* isTypedMethod. Only relevant for methods. */
324 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
325 : };
326 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
327 : static_assert(0 < 1, "There is no slot for us");
328 :
329 : static bool
330 0 : get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AnimationEvent* self, JSJitGetterCallArgs args)
331 : {
332 0 : bool result(self->IsTrusted());
333 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
334 0 : args.rval().setBoolean(result);
335 0 : return true;
336 : }
337 :
338 : static const JSJitInfo isTrusted_getterinfo = {
339 : { (JSJitGetterOp)get_isTrusted },
340 : { prototypes::id::AnimationEvent },
341 : { PrototypeTraits<prototypes::id::AnimationEvent>::Depth },
342 : JSJitInfo::Getter,
343 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
344 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
345 : true, /* isInfallible. False in setters. */
346 : true, /* isMovable. Not relevant for setters. */
347 : true, /* isEliminatable. Not relevant for setters. */
348 : false, /* isAlwaysInSlot. Only relevant for getters. */
349 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
350 : false, /* isTypedMethod. Only relevant for methods. */
351 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
352 : };
353 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
354 : static_assert(0 < 1, "There is no slot for us");
355 :
356 : static bool
357 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
358 : {
359 0 : mozilla::dom::AnimationEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AnimationEvent>(obj);
360 : // We don't want to preserve if we don't have a wrapper, and we
361 : // obviously can't preserve if we're not initialized.
362 0 : if (self && self->GetWrapperPreserveColor()) {
363 0 : PreserveWrapper(self);
364 : }
365 0 : return true;
366 : }
367 :
368 : static void
369 0 : _finalize(js::FreeOp* fop, JSObject* obj)
370 : {
371 0 : mozilla::dom::AnimationEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AnimationEvent>(obj);
372 0 : if (self) {
373 0 : ClearWrapper(self, self, obj);
374 0 : AddForDeferredFinalization<mozilla::dom::AnimationEvent>(self);
375 : }
376 0 : }
377 :
378 : static void
379 0 : _objectMoved(JSObject* obj, const JSObject* old)
380 : {
381 0 : mozilla::dom::AnimationEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AnimationEvent>(obj);
382 0 : if (self) {
383 0 : UpdateWrapper(self, self, obj, old);
384 : }
385 0 : }
386 :
387 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
388 : #if defined(__clang__)
389 : #pragma clang diagnostic push
390 : #pragma clang diagnostic ignored "-Wmissing-braces"
391 : #endif
392 : static const JSPropertySpec sAttributes_specs[] = {
393 : { "animationName", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &animationName_getterinfo, nullptr, nullptr },
394 : { "elapsedTime", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &elapsedTime_getterinfo, nullptr, nullptr },
395 : { "pseudoElement", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &pseudoElement_getterinfo, nullptr, nullptr },
396 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
397 : };
398 : #if defined(__clang__)
399 : #pragma clang diagnostic pop
400 : #endif
401 :
402 :
403 : // Can't be const because the pref-enabled boolean needs to be writable
404 : static Prefable<const JSPropertySpec> sAttributes[] = {
405 : { nullptr, &sAttributes_specs[0] },
406 : { nullptr, nullptr }
407 : };
408 :
409 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
410 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
411 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
412 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
413 :
414 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
415 : #if defined(__clang__)
416 : #pragma clang diagnostic push
417 : #pragma clang diagnostic ignored "-Wmissing-braces"
418 : #endif
419 : static const JSPropertySpec sUnforgeableAttributes_specs[] = {
420 : { "isTrusted", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &isTrusted_getterinfo, nullptr, nullptr },
421 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
422 : };
423 : #if defined(__clang__)
424 : #pragma clang diagnostic pop
425 : #endif
426 :
427 :
428 : // Can't be const because the pref-enabled boolean needs to be writable
429 : static Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
430 : { nullptr, &sUnforgeableAttributes_specs[0] },
431 : { nullptr, nullptr }
432 : };
433 :
434 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
435 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
436 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
437 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
438 :
439 :
440 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
441 : static PropertyInfo sNativeProperties_propertyInfos[4];
442 :
443 : static const NativePropertiesN<2> sNativeProperties = {
444 : false, 0,
445 : false, 0,
446 : false, 0,
447 : true, 0 /* sAttributes */,
448 : false, 0,
449 : true, 1 /* sUnforgeableAttributes */,
450 : false, 0,
451 : -1,
452 : 4,
453 : sNativeProperties_sortedPropertyIndices,
454 : {
455 : { sAttributes, &sNativeProperties_propertyInfos[0] },
456 : { sUnforgeableAttributes, &sNativeProperties_propertyInfos[3] }
457 : }
458 : };
459 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
460 : "We have a property info count that is oversized");
461 :
462 : static bool
463 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
464 : {
465 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
466 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
467 0 : if (!args.isConstructing()) {
468 : // XXXbz wish I could get the name from the callee instead of
469 : // Adding more relocations
470 0 : return ThrowConstructorWithoutNew(cx, "AnimationEvent");
471 : }
472 :
473 0 : GlobalObject global(cx, obj);
474 0 : if (global.Failed()) {
475 0 : return false;
476 : }
477 :
478 0 : JS::Rooted<JSObject*> desiredProto(cx);
479 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
480 0 : return false;
481 : }
482 :
483 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
484 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AnimationEvent");
485 : }
486 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
487 0 : binding_detail::FakeString arg0;
488 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
489 0 : return false;
490 : }
491 0 : binding_detail::FastAnimationEventInit arg1;
492 0 : if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2 of AnimationEvent.constructor", false)) {
493 0 : return false;
494 : }
495 0 : Maybe<JSAutoCompartment> ac;
496 0 : if (objIsXray) {
497 0 : obj = js::CheckedUnwrap(obj);
498 0 : if (!obj) {
499 0 : return false;
500 : }
501 0 : ac.emplace(cx, obj);
502 0 : if (!JS_WrapObject(cx, &desiredProto)) {
503 0 : return false;
504 : }
505 : }
506 0 : binding_detail::FastErrorResult rv;
507 0 : auto result(StrongOrRawPtr<mozilla::dom::AnimationEvent>(mozilla::dom::AnimationEvent::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
508 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
509 0 : return false;
510 : }
511 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
512 : static_assert(!IsPointer<decltype(result)>::value,
513 : "NewObject implies that we need to keep the object alive with a strong reference.");
514 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
515 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
516 0 : return false;
517 : }
518 0 : return true;
519 : }
520 :
521 : static const js::ClassOps sInterfaceObjectClassOps = {
522 : nullptr, /* addProperty */
523 : nullptr, /* delProperty */
524 : nullptr, /* getProperty */
525 : nullptr, /* setProperty */
526 : nullptr, /* enumerate */
527 : nullptr, /* newEnumerate */
528 : nullptr, /* resolve */
529 : nullptr, /* mayResolve */
530 : nullptr, /* finalize */
531 : _constructor, /* call */
532 : nullptr, /* hasInstance */
533 : _constructor, /* construct */
534 : nullptr, /* trace */
535 : };
536 :
537 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
538 : {
539 : "Function",
540 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
541 : &sInterfaceObjectClassOps,
542 : JS_NULL_CLASS_SPEC,
543 : JS_NULL_CLASS_EXT,
544 : &sInterfaceObjectClassObjectOps
545 : },
546 : eInterface,
547 : true,
548 : prototypes::id::AnimationEvent,
549 : PrototypeTraits<prototypes::id::AnimationEvent>::Depth,
550 : sNativePropertyHooks,
551 : "function AnimationEvent() {\n [native code]\n}",
552 : EventBinding::GetConstructorObject
553 : };
554 :
555 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
556 : {
557 : "AnimationEventPrototype",
558 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
559 : JS_NULL_CLASS_OPS,
560 : JS_NULL_CLASS_SPEC,
561 : JS_NULL_CLASS_EXT,
562 : JS_NULL_OBJECT_OPS
563 : },
564 : eInterfacePrototype,
565 : false,
566 : prototypes::id::AnimationEvent,
567 : PrototypeTraits<prototypes::id::AnimationEvent>::Depth,
568 : sNativePropertyHooks,
569 : "[object AnimationEventPrototype]",
570 : EventBinding::GetProtoObject
571 : };
572 :
573 : JSObject*
574 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
575 : {
576 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
577 : }
578 :
579 : static const js::ClassOps sClassOps = {
580 : _addProperty, /* addProperty */
581 : nullptr, /* delProperty */
582 : nullptr, /* getProperty */
583 : nullptr, /* setProperty */
584 : nullptr, /* enumerate */
585 : nullptr, /* newEnumerate */
586 : nullptr, /* resolve */
587 : nullptr, /* mayResolve */
588 : _finalize, /* finalize */
589 : nullptr, /* call */
590 : nullptr, /* hasInstance */
591 : nullptr, /* construct */
592 : nullptr, /* trace */
593 : };
594 :
595 : static const js::ClassExtension sClassExtension = {
596 : nullptr, /* weakmapKeyDelegateOp */
597 : _objectMoved /* objectMovedOp */
598 : };
599 :
600 : static const DOMJSClass sClass = {
601 : { "AnimationEvent",
602 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
603 : &sClassOps,
604 : JS_NULL_CLASS_SPEC,
605 : &sClassExtension,
606 : JS_NULL_OBJECT_OPS
607 : },
608 : { prototypes::id::Event, prototypes::id::AnimationEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
609 : IsBaseOf<nsISupports, mozilla::dom::AnimationEvent >::value,
610 : sNativePropertyHooks,
611 : FindAssociatedGlobalForNative<mozilla::dom::AnimationEvent>::Get,
612 : GetProtoObjectHandle,
613 : GetCCParticipant<mozilla::dom::AnimationEvent>::Get()
614 : };
615 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
616 : "Must have the right minimal number of reserved slots.");
617 : static_assert(1 >= 1,
618 : "Must have enough reserved slots.");
619 :
620 : const JSClass*
621 0 : GetJSClass()
622 : {
623 0 : return sClass.ToJSClass();
624 : }
625 :
626 : bool
627 0 : Wrap(JSContext* aCx, mozilla::dom::AnimationEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
628 : {
629 : MOZ_ASSERT(static_cast<mozilla::dom::AnimationEvent*>(aObject) ==
630 : reinterpret_cast<mozilla::dom::AnimationEvent*>(aObject),
631 : "Multiple inheritance for mozilla::dom::AnimationEvent is broken.");
632 : MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
633 : reinterpret_cast<mozilla::dom::Event*>(aObject),
634 : "Multiple inheritance for mozilla::dom::Event is broken.");
635 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
636 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
637 0 : MOZ_ASSERT(!aCache->GetWrapper(),
638 : "You should probably not be using Wrap() directly; use "
639 : "GetOrCreateDOMReflector instead");
640 :
641 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
642 : "nsISupports must be on our primary inheritance chain");
643 :
644 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
645 0 : if (!global) {
646 0 : return false;
647 : }
648 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
649 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
650 :
651 : // That might have ended up wrapping us already, due to the wonders
652 : // of XBL. Check for that, and bail out as needed.
653 0 : aReflector.set(aCache->GetWrapper());
654 0 : if (aReflector) {
655 : #ifdef DEBUG
656 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
657 : #endif // DEBUG
658 0 : return true;
659 : }
660 :
661 0 : JSAutoCompartment ac(aCx, global);
662 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
663 0 : if (!canonicalProto) {
664 0 : return false;
665 : }
666 0 : JS::Rooted<JSObject*> proto(aCx);
667 0 : if (aGivenProto) {
668 0 : proto = aGivenProto;
669 : // Unfortunately, while aGivenProto was in the compartment of aCx
670 : // coming in, we changed compartments to that of "parent" so may need
671 : // to wrap the proto here.
672 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
673 0 : if (!JS_WrapObject(aCx, &proto)) {
674 0 : return false;
675 : }
676 : }
677 : } else {
678 0 : proto = canonicalProto;
679 : }
680 :
681 0 : BindingJSObjectCreator<mozilla::dom::AnimationEvent> creator(aCx);
682 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
683 0 : if (!aReflector) {
684 0 : return false;
685 : }
686 :
687 0 : aCache->SetWrapper(aReflector);
688 :
689 : // Important: do unforgeable property setup after we have handed
690 : // over ownership of the C++ object to obj as needed, so that if
691 : // we fail and it ends up GCed it won't have problems in the
692 : // finalizer trying to drop its ownership of the C++ object.
693 : JS::Rooted<JSObject*> unforgeableHolder(aCx,
694 0 : &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
695 0 : if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
696 0 : aCache->ReleaseWrapper(aObject);
697 0 : aCache->ClearWrapper();
698 0 : return false;
699 : }
700 0 : creator.InitializationSucceeded();
701 :
702 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
703 : aCache->GetWrapperPreserveColor() == aReflector);
704 : // If proto != canonicalProto, we have to preserve our wrapper;
705 : // otherwise we won't be able to properly recreate it later, since
706 : // we won't know what proto to use. Note that we don't check
707 : // aGivenProto here, since it's entirely possible (and even
708 : // somewhat common) to have a non-null aGivenProto which is the
709 : // same as canonicalProto.
710 0 : if (proto != canonicalProto) {
711 0 : PreserveWrapper(aObject);
712 : }
713 :
714 0 : return true;
715 : }
716 :
717 : const NativePropertyHooks sNativePropertyHooks[] = { {
718 : nullptr,
719 : nullptr,
720 : nullptr,
721 : { sNativeProperties.Upcast(), nullptr },
722 : prototypes::id::AnimationEvent,
723 : constructors::id::AnimationEvent,
724 : EventBinding::sNativePropertyHooks,
725 : &DefaultXrayExpandoObjectClass
726 : } };
727 :
728 : void
729 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
730 : {
731 0 : JS::Handle<JSObject*> parentProto(EventBinding::GetProtoObjectHandle(aCx));
732 0 : if (!parentProto) {
733 0 : return;
734 : }
735 :
736 0 : JS::Handle<JSObject*> constructorProto(EventBinding::GetConstructorObjectHandle(aCx));
737 0 : if (!constructorProto) {
738 0 : return;
739 : }
740 :
741 : static bool sIdsInited = false;
742 0 : if (!sIdsInited && NS_IsMainThread()) {
743 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
744 0 : return;
745 : }
746 0 : sIdsInited = true;
747 : }
748 :
749 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AnimationEvent);
750 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AnimationEvent);
751 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
752 : &sPrototypeClass.mBase, protoCache,
753 : constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
754 : interfaceCache,
755 : sNativeProperties.Upcast(),
756 : nullptr,
757 : "AnimationEvent", aDefineOnGlobal,
758 : nullptr,
759 0 : false);
760 :
761 0 : JS::Rooted<JSObject*> unforgeableHolder(aCx);
762 : {
763 0 : JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
764 0 : unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
765 0 : if (!unforgeableHolder) {
766 0 : *protoCache = nullptr;
767 0 : if (interfaceCache) {
768 0 : *interfaceCache = nullptr;
769 : }
770 0 : return;
771 : }
772 : }
773 :
774 0 : if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
775 0 : *protoCache = nullptr;
776 0 : if (interfaceCache) {
777 0 : *interfaceCache = nullptr;
778 : }
779 0 : return;
780 : }
781 :
782 0 : if (*protoCache) {
783 0 : js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
784 0 : JS::ObjectValue(*unforgeableHolder));
785 : }
786 : }
787 :
788 : JS::Handle<JSObject*>
789 0 : GetProtoObjectHandle(JSContext* aCx)
790 : {
791 : /* Get the interface prototype object for this class. This will create the
792 : object as needed. */
793 0 : bool aDefineOnGlobal = true;
794 :
795 : /* Make sure our global is sane. Hopefully we can remove this sometime */
796 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
797 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
798 0 : return nullptr;
799 : }
800 :
801 : /* Check to see whether the interface objects are already installed */
802 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
803 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AnimationEvent)) {
804 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
805 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
806 : }
807 :
808 : /*
809 : * The object might _still_ be null, but that's OK.
810 : *
811 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
812 : * traced by TraceProtoAndIfaceCache() and its contents are never
813 : * changed after they have been set.
814 : *
815 : * Calling address() avoids the read read barrier that does gray
816 : * unmarking, but it's not possible for the object to be gray here.
817 : */
818 :
819 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AnimationEvent);
820 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
821 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
822 : }
823 :
824 : JS::Handle<JSObject*>
825 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
826 : {
827 : /* Get the interface object for this class. This will create the object as
828 : needed. */
829 :
830 : /* Make sure our global is sane. Hopefully we can remove this sometime */
831 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
832 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
833 0 : return nullptr;
834 : }
835 :
836 : /* Check to see whether the interface objects are already installed */
837 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
838 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AnimationEvent)) {
839 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
840 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
841 : }
842 :
843 : /*
844 : * The object might _still_ be null, but that's OK.
845 : *
846 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
847 : * traced by TraceProtoAndIfaceCache() and its contents are never
848 : * changed after they have been set.
849 : *
850 : * Calling address() avoids the read read barrier that does gray
851 : * unmarking, but it's not possible for the object to be gray here.
852 : */
853 :
854 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AnimationEvent);
855 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
856 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
857 : }
858 :
859 : JSObject*
860 0 : GetConstructorObject(JSContext* aCx)
861 : {
862 0 : return GetConstructorObjectHandle(aCx);
863 : }
864 :
865 : } // namespace AnimationEventBinding
866 :
867 :
868 :
869 : } // namespace dom
870 : } // namespace mozilla
|