Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM CSSPseudoElement.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AnimatableBinding.h"
4 : #include "CSSPseudoElementBinding.h"
5 : #include "KeyframeAnimationOptionsBinding.h"
6 : #include "WrapperFactory.h"
7 : #include "mozilla/OwningNonNull.h"
8 : #include "mozilla/dom/Animation.h"
9 : #include "mozilla/dom/BindingUtils.h"
10 : #include "mozilla/dom/CSSPseudoElement.h"
11 : #include "mozilla/dom/DOMJSClass.h"
12 : #include "mozilla/dom/Element.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/Nullable.h"
15 : #include "mozilla/dom/UnionConversions.h"
16 : #include "mozilla/dom/XrayExpandoClass.h"
17 : #include "nsDocument.h"
18 :
19 : namespace mozilla {
20 : namespace dom {
21 :
22 : namespace CSSPseudoElementBinding {
23 :
24 : static bool
25 0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CSSPseudoElement* self, JSJitGetterCallArgs args)
26 : {
27 0 : DOMString result;
28 0 : self->GetType(result);
29 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
30 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
31 0 : return false;
32 : }
33 0 : return true;
34 : }
35 :
36 : static const JSJitInfo type_getterinfo = {
37 : { (JSJitGetterOp)get_type },
38 : { prototypes::id::CSSPseudoElement },
39 : { PrototypeTraits<prototypes::id::CSSPseudoElement>::Depth },
40 : JSJitInfo::Getter,
41 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
42 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
43 : false, /* isInfallible. False in setters. */
44 : false, /* isMovable. Not relevant for setters. */
45 : false, /* isEliminatable. Not relevant for setters. */
46 : false, /* isAlwaysInSlot. Only relevant for getters. */
47 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
48 : false, /* isTypedMethod. Only relevant for methods. */
49 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
50 : };
51 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
52 : static_assert(0 < 1, "There is no slot for us");
53 :
54 : static bool
55 0 : get_parentElement(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CSSPseudoElement* self, JSJitGetterCallArgs args)
56 : {
57 0 : auto result(StrongOrRawPtr<mozilla::dom::Element>(self->ParentElement()));
58 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
59 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
60 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
61 0 : return false;
62 : }
63 0 : return true;
64 : }
65 :
66 : static const JSJitInfo parentElement_getterinfo = {
67 : { (JSJitGetterOp)get_parentElement },
68 : { prototypes::id::CSSPseudoElement },
69 : { PrototypeTraits<prototypes::id::CSSPseudoElement>::Depth },
70 : JSJitInfo::Getter,
71 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
72 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
73 : false, /* isInfallible. False in setters. */
74 : false, /* isMovable. Not relevant for setters. */
75 : false, /* isEliminatable. Not relevant for setters. */
76 : false, /* isAlwaysInSlot. Only relevant for getters. */
77 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
78 : false, /* isTypedMethod. Only relevant for methods. */
79 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
80 : };
81 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
82 : static_assert(0 < 1, "There is no slot for us");
83 :
84 : static bool
85 0 : animate(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CSSPseudoElement* self, const JSJitMethodCallArgs& args)
86 : {
87 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
88 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "CSSPseudoElement.animate");
89 : }
90 0 : JS::Rooted<JSObject*> arg0(cx);
91 0 : if (args[0].isObject()) {
92 0 : arg0 = &args[0].toObject();
93 0 : } else if (args[0].isNullOrUndefined()) {
94 0 : arg0 = nullptr;
95 : } else {
96 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of CSSPseudoElement.animate");
97 0 : return false;
98 : }
99 0 : UnrestrictedDoubleOrKeyframeAnimationOptions arg1;
100 0 : UnrestrictedDoubleOrKeyframeAnimationOptionsArgument arg1_holder(arg1);
101 0 : if (!(args.hasDefined(1))) {
102 0 : if (!arg1.RawSetAsKeyframeAnimationOptions().Init(cx, JS::NullHandleValue, "Member of UnrestrictedDoubleOrKeyframeAnimationOptions")) {
103 0 : return false;
104 : }
105 : } else {
106 : {
107 0 : bool done = false, failed = false, tryNext;
108 0 : if (!done) {
109 0 : done = (failed = !arg1_holder.TrySetToKeyframeAnimationOptions(cx, args[1], tryNext, false)) || !tryNext;
110 : }
111 0 : if (!done) {
112 : do {
113 0 : done = (failed = !arg1_holder.TrySetToUnrestrictedDouble(cx, args[1], tryNext)) || !tryNext;
114 0 : break;
115 : } while (0);
116 : }
117 0 : if (failed) {
118 0 : return false;
119 : }
120 0 : if (!done) {
121 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 2 of CSSPseudoElement.animate", "KeyframeAnimationOptions");
122 0 : return false;
123 : }
124 : }
125 : }
126 0 : binding_detail::FastErrorResult rv;
127 0 : auto result(StrongOrRawPtr<mozilla::dom::Animation>(self->Animate(cx, arg0, Constify(arg1), rv)));
128 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
129 0 : return false;
130 : }
131 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
132 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
133 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
134 0 : return false;
135 : }
136 0 : return true;
137 : }
138 :
139 : static const JSJitInfo animate_methodinfo = {
140 : { (JSJitGetterOp)animate },
141 : { prototypes::id::CSSPseudoElement },
142 : { PrototypeTraits<prototypes::id::CSSPseudoElement>::Depth },
143 : JSJitInfo::Method,
144 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
145 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
146 : false, /* isInfallible. False in setters. */
147 : false, /* isMovable. Not relevant for setters. */
148 : false, /* isEliminatable. Not relevant for setters. */
149 : false, /* isAlwaysInSlot. Only relevant for getters. */
150 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
151 : false, /* isTypedMethod. Only relevant for methods. */
152 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
153 : };
154 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
155 : static_assert(0 < 1, "There is no slot for us");
156 :
157 : static bool
158 0 : getAnimations(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CSSPseudoElement* self, const JSJitMethodCallArgs& args)
159 : {
160 0 : binding_detail::FastAnimationFilter arg0;
161 0 : if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1 of CSSPseudoElement.getAnimations", false)) {
162 0 : return false;
163 : }
164 0 : nsTArray<StrongPtrForMember<mozilla::dom::Animation>::Type> result;
165 0 : self->GetAnimations(Constify(arg0), result);
166 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
167 :
168 0 : uint32_t length = result.Length();
169 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
170 0 : if (!returnArray) {
171 0 : return false;
172 : }
173 : // Scope for 'tmp'
174 : {
175 0 : JS::Rooted<JS::Value> tmp(cx);
176 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
177 : // Control block to let us common up the JS_DefineElement calls when there
178 : // are different ways to succeed at wrapping the object.
179 : do {
180 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
181 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
182 0 : return false;
183 : }
184 0 : break;
185 : } while (0);
186 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
187 : JSPROP_ENUMERATE)) {
188 0 : return false;
189 : }
190 : }
191 : }
192 0 : args.rval().setObject(*returnArray);
193 0 : return true;
194 : }
195 :
196 : static const JSJitInfo getAnimations_methodinfo = {
197 : { (JSJitGetterOp)getAnimations },
198 : { prototypes::id::CSSPseudoElement },
199 : { PrototypeTraits<prototypes::id::CSSPseudoElement>::Depth },
200 : JSJitInfo::Method,
201 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
202 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
203 : false, /* isInfallible. False in setters. */
204 : false, /* isMovable. Not relevant for setters. */
205 : false, /* isEliminatable. Not relevant for setters. */
206 : false, /* isAlwaysInSlot. Only relevant for getters. */
207 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
208 : false, /* isTypedMethod. Only relevant for methods. */
209 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
210 : };
211 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
212 : static_assert(0 < 1, "There is no slot for us");
213 :
214 : static bool
215 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
216 : {
217 0 : mozilla::dom::CSSPseudoElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CSSPseudoElement>(obj);
218 : // We don't want to preserve if we don't have a wrapper, and we
219 : // obviously can't preserve if we're not initialized.
220 0 : if (self && self->GetWrapperPreserveColor()) {
221 0 : PreserveWrapper(self);
222 : }
223 0 : return true;
224 : }
225 :
226 : static void
227 0 : _finalize(js::FreeOp* fop, JSObject* obj)
228 : {
229 0 : mozilla::dom::CSSPseudoElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CSSPseudoElement>(obj);
230 0 : if (self) {
231 0 : ClearWrapper(self, self, obj);
232 0 : AddForDeferredFinalization<mozilla::dom::CSSPseudoElement>(self);
233 : }
234 0 : }
235 :
236 : static void
237 0 : _objectMoved(JSObject* obj, const JSObject* old)
238 : {
239 0 : mozilla::dom::CSSPseudoElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CSSPseudoElement>(obj);
240 0 : if (self) {
241 0 : UpdateWrapper(self, self, obj, old);
242 : }
243 0 : }
244 :
245 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
246 : #if defined(__clang__)
247 : #pragma clang diagnostic push
248 : #pragma clang diagnostic ignored "-Wmissing-braces"
249 : #endif
250 : static const JSFunctionSpec sMethods_specs[] = {
251 : JS_FNSPEC("animate", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&animate_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
252 : JS_FS_END,
253 : JS_FNSPEC("getAnimations", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getAnimations_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
254 : JS_FS_END
255 : };
256 : #if defined(__clang__)
257 : #pragma clang diagnostic pop
258 : #endif
259 :
260 : static PrefableDisablers sMethods_disablers0 = {
261 : true, false, 0, &nsDocument::IsElementAnimateEnabled
262 : };
263 :
264 : static PrefableDisablers sMethods_disablers2 = {
265 : true, false, 0, &nsDocument::IsWebAnimationsEnabled
266 : };
267 :
268 : // Can't be const because the pref-enabled boolean needs to be writable
269 : static Prefable<const JSFunctionSpec> sMethods[] = {
270 : { &sMethods_disablers0, &sMethods_specs[0] },
271 : { &sMethods_disablers2, &sMethods_specs[2] },
272 : { nullptr, nullptr }
273 : };
274 :
275 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
276 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
277 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
278 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
279 :
280 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
281 : #if defined(__clang__)
282 : #pragma clang diagnostic push
283 : #pragma clang diagnostic ignored "-Wmissing-braces"
284 : #endif
285 : static const JSPropertySpec sAttributes_specs[] = {
286 : { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, nullptr, nullptr },
287 : { "parentElement", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &parentElement_getterinfo, nullptr, nullptr },
288 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
289 : };
290 : #if defined(__clang__)
291 : #pragma clang diagnostic pop
292 : #endif
293 :
294 :
295 : // Can't be const because the pref-enabled boolean needs to be writable
296 : static Prefable<const JSPropertySpec> sAttributes[] = {
297 : { nullptr, &sAttributes_specs[0] },
298 : { nullptr, nullptr }
299 : };
300 :
301 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
302 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
303 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
304 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
305 :
306 :
307 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
308 : static PropertyInfo sNativeProperties_propertyInfos[4];
309 :
310 : static const NativePropertiesN<2> sNativeProperties = {
311 : false, 0,
312 : false, 0,
313 : true, 0 /* sMethods */,
314 : true, 1 /* sAttributes */,
315 : false, 0,
316 : false, 0,
317 : false, 0,
318 : -1,
319 : 4,
320 : sNativeProperties_sortedPropertyIndices,
321 : {
322 : { sMethods, &sNativeProperties_propertyInfos[0] },
323 : { sAttributes, &sNativeProperties_propertyInfos[2] }
324 : }
325 : };
326 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
327 : "We have a property info count that is oversized");
328 :
329 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
330 : {
331 : "Function",
332 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
333 : &sBoringInterfaceObjectClassClassOps,
334 : JS_NULL_CLASS_SPEC,
335 : JS_NULL_CLASS_EXT,
336 : &sInterfaceObjectClassObjectOps
337 : },
338 : eInterface,
339 : true,
340 : prototypes::id::CSSPseudoElement,
341 : PrototypeTraits<prototypes::id::CSSPseudoElement>::Depth,
342 : sNativePropertyHooks,
343 : "function CSSPseudoElement() {\n [native code]\n}",
344 : JS::GetRealmFunctionPrototype
345 : };
346 :
347 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
348 : {
349 : "CSSPseudoElementPrototype",
350 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
351 : JS_NULL_CLASS_OPS,
352 : JS_NULL_CLASS_SPEC,
353 : JS_NULL_CLASS_EXT,
354 : JS_NULL_OBJECT_OPS
355 : },
356 : eInterfacePrototype,
357 : false,
358 : prototypes::id::CSSPseudoElement,
359 : PrototypeTraits<prototypes::id::CSSPseudoElement>::Depth,
360 : sNativePropertyHooks,
361 : "[object CSSPseudoElementPrototype]",
362 : JS::GetRealmObjectPrototype
363 : };
364 :
365 : bool
366 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
367 : {
368 0 : return nsDocument::IsWebAnimationsEnabled(aCx, aObj);
369 : }
370 :
371 : JSObject*
372 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
373 : {
374 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
375 : }
376 :
377 : static const js::ClassOps sClassOps = {
378 : _addProperty, /* addProperty */
379 : nullptr, /* delProperty */
380 : nullptr, /* getProperty */
381 : nullptr, /* setProperty */
382 : nullptr, /* enumerate */
383 : nullptr, /* newEnumerate */
384 : nullptr, /* resolve */
385 : nullptr, /* mayResolve */
386 : _finalize, /* finalize */
387 : nullptr, /* call */
388 : nullptr, /* hasInstance */
389 : nullptr, /* construct */
390 : nullptr, /* trace */
391 : };
392 :
393 : static const js::ClassExtension sClassExtension = {
394 : nullptr, /* weakmapKeyDelegateOp */
395 : _objectMoved /* objectMovedOp */
396 : };
397 :
398 : static const DOMJSClass sClass = {
399 : { "CSSPseudoElement",
400 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
401 : &sClassOps,
402 : JS_NULL_CLASS_SPEC,
403 : &sClassExtension,
404 : JS_NULL_OBJECT_OPS
405 : },
406 : { prototypes::id::CSSPseudoElement, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
407 : IsBaseOf<nsISupports, mozilla::dom::CSSPseudoElement >::value,
408 : sNativePropertyHooks,
409 : FindAssociatedGlobalForNative<mozilla::dom::CSSPseudoElement>::Get,
410 : GetProtoObjectHandle,
411 : GetCCParticipant<mozilla::dom::CSSPseudoElement>::Get()
412 : };
413 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
414 : "Must have the right minimal number of reserved slots.");
415 : static_assert(1 >= 1,
416 : "Must have enough reserved slots.");
417 :
418 : const JSClass*
419 0 : GetJSClass()
420 : {
421 0 : return sClass.ToJSClass();
422 : }
423 :
424 : bool
425 0 : Wrap(JSContext* aCx, mozilla::dom::CSSPseudoElement* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
426 : {
427 : MOZ_ASSERT(static_cast<mozilla::dom::CSSPseudoElement*>(aObject) ==
428 : reinterpret_cast<mozilla::dom::CSSPseudoElement*>(aObject),
429 : "Multiple inheritance for mozilla::dom::CSSPseudoElement is broken.");
430 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
431 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
432 0 : MOZ_ASSERT(!aCache->GetWrapper(),
433 : "You should probably not be using Wrap() directly; use "
434 : "GetOrCreateDOMReflector instead");
435 :
436 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
437 : "nsISupports must be on our primary inheritance chain");
438 :
439 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
440 0 : if (!global) {
441 0 : return false;
442 : }
443 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
444 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
445 :
446 : // That might have ended up wrapping us already, due to the wonders
447 : // of XBL. Check for that, and bail out as needed.
448 0 : aReflector.set(aCache->GetWrapper());
449 0 : if (aReflector) {
450 : #ifdef DEBUG
451 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
452 : #endif // DEBUG
453 0 : return true;
454 : }
455 :
456 0 : JSAutoCompartment ac(aCx, global);
457 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
458 0 : if (!canonicalProto) {
459 0 : return false;
460 : }
461 0 : JS::Rooted<JSObject*> proto(aCx);
462 0 : if (aGivenProto) {
463 0 : proto = aGivenProto;
464 : // Unfortunately, while aGivenProto was in the compartment of aCx
465 : // coming in, we changed compartments to that of "parent" so may need
466 : // to wrap the proto here.
467 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
468 0 : if (!JS_WrapObject(aCx, &proto)) {
469 0 : return false;
470 : }
471 : }
472 : } else {
473 0 : proto = canonicalProto;
474 : }
475 :
476 0 : BindingJSObjectCreator<mozilla::dom::CSSPseudoElement> creator(aCx);
477 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
478 0 : if (!aReflector) {
479 0 : return false;
480 : }
481 :
482 0 : aCache->SetWrapper(aReflector);
483 0 : creator.InitializationSucceeded();
484 :
485 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
486 : aCache->GetWrapperPreserveColor() == aReflector);
487 : // If proto != canonicalProto, we have to preserve our wrapper;
488 : // otherwise we won't be able to properly recreate it later, since
489 : // we won't know what proto to use. Note that we don't check
490 : // aGivenProto here, since it's entirely possible (and even
491 : // somewhat common) to have a non-null aGivenProto which is the
492 : // same as canonicalProto.
493 0 : if (proto != canonicalProto) {
494 0 : PreserveWrapper(aObject);
495 : }
496 :
497 0 : return true;
498 : }
499 :
500 : const NativePropertyHooks sNativePropertyHooks[] = { {
501 : nullptr,
502 : nullptr,
503 : nullptr,
504 : { sNativeProperties.Upcast(), nullptr },
505 : prototypes::id::CSSPseudoElement,
506 : constructors::id::CSSPseudoElement,
507 : nullptr,
508 : &DefaultXrayExpandoObjectClass
509 : } };
510 :
511 : void
512 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
513 : {
514 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
515 0 : if (!parentProto) {
516 0 : return;
517 : }
518 :
519 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
520 0 : if (!constructorProto) {
521 0 : return;
522 : }
523 :
524 : static bool sIdsInited = false;
525 0 : if (!sIdsInited && NS_IsMainThread()) {
526 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
527 0 : return;
528 : }
529 0 : sIdsInited = true;
530 : }
531 :
532 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::CSSPseudoElement);
533 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::CSSPseudoElement);
534 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
535 : &sPrototypeClass.mBase, protoCache,
536 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
537 : interfaceCache,
538 : sNativeProperties.Upcast(),
539 : nullptr,
540 : "CSSPseudoElement", aDefineOnGlobal,
541 : nullptr,
542 0 : false);
543 : }
544 :
545 : JS::Handle<JSObject*>
546 0 : GetProtoObjectHandle(JSContext* aCx)
547 : {
548 : /* Get the interface prototype object for this class. This will create the
549 : object as needed. */
550 0 : bool aDefineOnGlobal = true;
551 :
552 : /* Make sure our global is sane. Hopefully we can remove this sometime */
553 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
554 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
555 0 : return nullptr;
556 : }
557 :
558 : /* Check to see whether the interface objects are already installed */
559 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
560 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::CSSPseudoElement)) {
561 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
562 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
563 : }
564 :
565 : /*
566 : * The object might _still_ be null, but that's OK.
567 : *
568 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
569 : * traced by TraceProtoAndIfaceCache() and its contents are never
570 : * changed after they have been set.
571 : *
572 : * Calling address() avoids the read read barrier that does gray
573 : * unmarking, but it's not possible for the object to be gray here.
574 : */
575 :
576 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::CSSPseudoElement);
577 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
578 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
579 : }
580 :
581 : JS::Handle<JSObject*>
582 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
583 : {
584 : /* Get the interface object for this class. This will create the object as
585 : needed. */
586 :
587 : /* Make sure our global is sane. Hopefully we can remove this sometime */
588 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
589 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
590 0 : return nullptr;
591 : }
592 :
593 : /* Check to see whether the interface objects are already installed */
594 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
595 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::CSSPseudoElement)) {
596 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
597 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
598 : }
599 :
600 : /*
601 : * The object might _still_ be null, but that's OK.
602 : *
603 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
604 : * traced by TraceProtoAndIfaceCache() and its contents are never
605 : * changed after they have been set.
606 : *
607 : * Calling address() avoids the read read barrier that does gray
608 : * unmarking, but it's not possible for the object to be gray here.
609 : */
610 :
611 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::CSSPseudoElement);
612 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
613 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
614 : }
615 :
616 : JSObject*
617 0 : GetConstructorObject(JSContext* aCx)
618 : {
619 0 : return GetConstructorObjectHandle(aCx);
620 : }
621 :
622 : } // namespace CSSPseudoElementBinding
623 :
624 :
625 :
626 : } // namespace dom
627 : } // namespace mozilla
|