Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM HTMLAllCollection.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "HTMLAllCollectionBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "mozilla/OwningNonNull.h"
6 : #include "mozilla/dom/BindingUtils.h"
7 : #include "mozilla/dom/DOMJSClass.h"
8 : #include "mozilla/dom/DOMJSProxyHandler.h"
9 : #include "mozilla/dom/HTMLAllCollection.h"
10 : #include "mozilla/dom/NonRefcountedDOMObject.h"
11 : #include "mozilla/dom/Nullable.h"
12 : #include "mozilla/dom/PrimitiveConversions.h"
13 : #include "mozilla/dom/UnionConversions.h"
14 : #include "mozilla/dom/XrayExpandoClass.h"
15 : #include "nsContentList.h"
16 : #include "nsINode.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 : void
22 0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningNodeOrHTMLCollection& aUnion, const char* aName, uint32_t aFlags)
23 : {
24 0 : if (aUnion.IsNode()) {
25 0 : ImplCycleCollectionTraverse(aCallback, aUnion.GetAsNode(), "mNode", aFlags);
26 0 : } else if (aUnion.IsHTMLCollection()) {
27 0 : ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLCollection(), "mHTMLCollection", aFlags);
28 : }
29 0 : }
30 :
31 :
32 : void
33 0 : ImplCycleCollectionUnlink(OwningNodeOrHTMLCollection& aUnion)
34 : {
35 0 : aUnion.Uninit();
36 0 : }
37 :
38 :
39 : bool
40 0 : NodeOrHTMLCollection::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
41 : {
42 0 : switch (mType) {
43 : case eUninitialized: {
44 0 : return false;
45 : break;
46 : }
47 : case eNode: {
48 0 : if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
49 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
50 0 : return false;
51 : }
52 0 : return true;
53 : break;
54 : }
55 : case eHTMLCollection: {
56 0 : if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCollection.Value(), rval)) {
57 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
58 0 : return false;
59 : }
60 0 : return true;
61 : break;
62 : }
63 : default: {
64 0 : return false;
65 : break;
66 : }
67 : }
68 :
69 : return false;
70 : }
71 :
72 :
73 : OwningNonNull<nsINode>&
74 0 : OwningNodeOrHTMLCollection::RawSetAsNode()
75 : {
76 0 : if (mType == eNode) {
77 0 : return mValue.mNode.Value();
78 : }
79 0 : MOZ_ASSERT(mType == eUninitialized);
80 0 : mType = eNode;
81 0 : return mValue.mNode.SetValue();
82 : }
83 :
84 : OwningNonNull<nsINode>&
85 0 : OwningNodeOrHTMLCollection::SetAsNode()
86 : {
87 0 : if (mType == eNode) {
88 0 : return mValue.mNode.Value();
89 : }
90 0 : Uninit();
91 0 : mType = eNode;
92 0 : return mValue.mNode.SetValue();
93 : }
94 :
95 : bool
96 0 : OwningNodeOrHTMLCollection::TrySetToNode(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
97 : {
98 0 : tryNext = false;
99 : { // scope for memberSlot
100 0 : OwningNonNull<nsINode>& memberSlot = RawSetAsNode();
101 : static_assert(IsRefcounted<nsINode>::value, "We can only store refcounted classes.");{
102 0 : nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(value, memberSlot);
103 0 : if (NS_FAILED(rv)) {
104 0 : DestroyNode();
105 0 : tryNext = true;
106 0 : return true;
107 : }
108 : }
109 : }
110 0 : return true;
111 : }
112 :
113 : void
114 0 : OwningNodeOrHTMLCollection::DestroyNode()
115 : {
116 0 : MOZ_ASSERT(IsNode(), "Wrong type!");
117 0 : mValue.mNode.Destroy();
118 0 : mType = eUninitialized;
119 0 : }
120 :
121 :
122 :
123 :
124 : OwningNonNull<nsIHTMLCollection>&
125 0 : OwningNodeOrHTMLCollection::RawSetAsHTMLCollection()
126 : {
127 0 : if (mType == eHTMLCollection) {
128 0 : return mValue.mHTMLCollection.Value();
129 : }
130 0 : MOZ_ASSERT(mType == eUninitialized);
131 0 : mType = eHTMLCollection;
132 0 : return mValue.mHTMLCollection.SetValue();
133 : }
134 :
135 : OwningNonNull<nsIHTMLCollection>&
136 0 : OwningNodeOrHTMLCollection::SetAsHTMLCollection()
137 : {
138 0 : if (mType == eHTMLCollection) {
139 0 : return mValue.mHTMLCollection.Value();
140 : }
141 0 : Uninit();
142 0 : mType = eHTMLCollection;
143 0 : return mValue.mHTMLCollection.SetValue();
144 : }
145 :
146 : bool
147 0 : OwningNodeOrHTMLCollection::TrySetToHTMLCollection(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
148 : {
149 0 : tryNext = false;
150 : { // scope for memberSlot
151 0 : OwningNonNull<nsIHTMLCollection>& memberSlot = RawSetAsHTMLCollection();
152 : static_assert(IsRefcounted<nsIHTMLCollection>::value, "We can only store refcounted classes.");{
153 0 : nsresult rv = UnwrapObject<prototypes::id::HTMLCollection, nsIHTMLCollection>(value, memberSlot);
154 0 : if (NS_FAILED(rv)) {
155 0 : DestroyHTMLCollection();
156 0 : tryNext = true;
157 0 : return true;
158 : }
159 : }
160 : }
161 0 : return true;
162 : }
163 :
164 : void
165 0 : OwningNodeOrHTMLCollection::DestroyHTMLCollection()
166 : {
167 0 : MOZ_ASSERT(IsHTMLCollection(), "Wrong type!");
168 0 : mValue.mHTMLCollection.Destroy();
169 0 : mType = eUninitialized;
170 0 : }
171 :
172 :
173 :
174 :
175 : void
176 0 : OwningNodeOrHTMLCollection::Uninit()
177 : {
178 0 : switch (mType) {
179 : case eUninitialized: {
180 0 : break;
181 : }
182 : case eNode: {
183 0 : DestroyNode();
184 0 : break;
185 : }
186 : case eHTMLCollection: {
187 0 : DestroyHTMLCollection();
188 0 : break;
189 : }
190 : }
191 0 : }
192 :
193 : bool
194 0 : OwningNodeOrHTMLCollection::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
195 : {
196 0 : switch (mType) {
197 : case eUninitialized: {
198 0 : return false;
199 : break;
200 : }
201 : case eNode: {
202 0 : if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
203 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
204 0 : return false;
205 : }
206 0 : return true;
207 : break;
208 : }
209 : case eHTMLCollection: {
210 0 : if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCollection.Value(), rval)) {
211 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
212 0 : return false;
213 : }
214 0 : return true;
215 : break;
216 : }
217 : default: {
218 0 : return false;
219 : break;
220 : }
221 : }
222 :
223 : return false;
224 : }
225 :
226 : void
227 0 : OwningNodeOrHTMLCollection::TraceUnion(JSTracer* trc)
228 : {
229 0 : }
230 :
231 : OwningNodeOrHTMLCollection&
232 0 : OwningNodeOrHTMLCollection::operator=(const OwningNodeOrHTMLCollection& aOther)
233 : {
234 0 : switch (aOther.mType) {
235 : case eUninitialized: {
236 0 : MOZ_ASSERT(mType == eUninitialized,
237 : "We need to destroy ourselves?");
238 0 : break;
239 : }
240 : case eNode: {
241 0 : SetAsNode() = aOther.GetAsNode();
242 0 : break;
243 : }
244 : case eHTMLCollection: {
245 0 : SetAsHTMLCollection() = aOther.GetAsHTMLCollection();
246 0 : break;
247 : }
248 : }
249 0 : return *this;
250 : }
251 :
252 :
253 : namespace HTMLAllCollectionBinding {
254 :
255 : static bool
256 0 : get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLAllCollection* self, JSJitGetterCallArgs args)
257 : {
258 0 : uint32_t result(self->Length());
259 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
260 0 : args.rval().setNumber(result);
261 0 : return true;
262 : }
263 :
264 : static const JSJitInfo length_getterinfo = {
265 : { (JSJitGetterOp)get_length },
266 : { prototypes::id::HTMLAllCollection },
267 : { PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth },
268 : JSJitInfo::Getter,
269 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
270 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
271 : true, /* isInfallible. False in setters. */
272 : false, /* isMovable. Not relevant for setters. */
273 : false, /* isEliminatable. Not relevant for setters. */
274 : false, /* isAlwaysInSlot. Only relevant for getters. */
275 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
276 : false, /* isTypedMethod. Only relevant for methods. */
277 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
278 : };
279 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
280 : static_assert(0 < 1, "There is no slot for us");
281 :
282 : static bool
283 0 : item(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLAllCollection* self, const JSJitMethodCallArgs& args)
284 : {
285 0 : unsigned argcount = std::min(args.length(), 1u);
286 0 : switch (argcount) {
287 : case 1: {
288 0 : if (args[0].isNumber()) {
289 : uint32_t arg0;
290 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
291 0 : return false;
292 : }
293 0 : auto result(StrongOrRawPtr<nsINode>(self->Item(arg0)));
294 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
295 0 : if (!result) {
296 0 : args.rval().setNull();
297 0 : return true;
298 : }
299 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
300 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
301 0 : return false;
302 : }
303 0 : return true;
304 : }
305 0 : binding_detail::FakeString arg0;
306 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
307 0 : return false;
308 : }
309 0 : Nullable<OwningNodeOrHTMLCollection> result;
310 0 : self->Item(NonNullHelper(Constify(arg0)), result);
311 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
312 0 : if (result.IsNull()) {
313 0 : args.rval().setNull();
314 0 : return true;
315 : }
316 0 : if (!result.Value().ToJSVal(cx, obj, args.rval())) {
317 0 : return false;
318 : }
319 0 : return true;
320 : break;
321 : }
322 : default: {
323 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLAllCollection.item");
324 : break;
325 : }
326 : }
327 : MOZ_CRASH("We have an always-returning default case");
328 : return false;
329 : }
330 :
331 : static const JSJitInfo item_methodinfo = {
332 : { (JSJitGetterOp)item },
333 : { prototypes::id::HTMLAllCollection },
334 : { PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth },
335 : JSJitInfo::Method,
336 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
337 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
338 : false, /* isInfallible. False in setters. */
339 : false, /* isMovable. Not relevant for setters. */
340 : false, /* isEliminatable. Not relevant for setters. */
341 : false, /* isAlwaysInSlot. Only relevant for getters. */
342 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
343 : false, /* isTypedMethod. Only relevant for methods. */
344 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
345 : };
346 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
347 : static_assert(0 < 1, "There is no slot for us");
348 :
349 : static bool
350 0 : namedItem(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLAllCollection* self, const JSJitMethodCallArgs& args)
351 : {
352 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
353 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLAllCollection.namedItem");
354 : }
355 0 : binding_detail::FakeString arg0;
356 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
357 0 : return false;
358 : }
359 0 : Nullable<OwningNodeOrHTMLCollection> result;
360 0 : self->NamedItem(NonNullHelper(Constify(arg0)), result);
361 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
362 0 : if (result.IsNull()) {
363 0 : args.rval().setNull();
364 0 : return true;
365 : }
366 0 : if (!result.Value().ToJSVal(cx, obj, args.rval())) {
367 0 : return false;
368 : }
369 0 : return true;
370 : }
371 :
372 : static const JSJitInfo namedItem_methodinfo = {
373 : { (JSJitGetterOp)namedItem },
374 : { prototypes::id::HTMLAllCollection },
375 : { PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth },
376 : JSJitInfo::Method,
377 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
378 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
379 : false, /* isInfallible. False in setters. */
380 : false, /* isMovable. Not relevant for setters. */
381 : false, /* isEliminatable. Not relevant for setters. */
382 : false, /* isAlwaysInSlot. Only relevant for getters. */
383 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
384 : false, /* isTypedMethod. Only relevant for methods. */
385 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
386 : };
387 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
388 : static_assert(0 < 1, "There is no slot for us");
389 :
390 : static void
391 0 : _objectMoved(JSObject* obj, const JSObject* old)
392 : {
393 0 : mozilla::dom::HTMLAllCollection* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLAllCollection>(obj);
394 0 : if (self) {
395 0 : UpdateWrapper(self, self, obj, old);
396 : }
397 0 : }
398 :
399 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
400 : #if defined(__clang__)
401 : #pragma clang diagnostic push
402 : #pragma clang diagnostic ignored "-Wmissing-braces"
403 : #endif
404 : static const JSFunctionSpec sMethods_specs[] = {
405 : JS_FNSPEC("item", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&item_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
406 : JS_FNSPEC("namedItem", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&namedItem_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
407 : JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "ArrayValues"),
408 : JS_FS_END
409 : };
410 : #if defined(__clang__)
411 : #pragma clang diagnostic pop
412 : #endif
413 :
414 :
415 : // Can't be const because the pref-enabled boolean needs to be writable
416 : static Prefable<const JSFunctionSpec> sMethods[] = {
417 : { nullptr, &sMethods_specs[0] },
418 : { nullptr, nullptr }
419 : };
420 :
421 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
422 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
423 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
424 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
425 :
426 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
427 : #if defined(__clang__)
428 : #pragma clang diagnostic push
429 : #pragma clang diagnostic ignored "-Wmissing-braces"
430 : #endif
431 : static const JSPropertySpec sAttributes_specs[] = {
432 : { "length", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &length_getterinfo, nullptr, nullptr },
433 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
434 : };
435 : #if defined(__clang__)
436 : #pragma clang diagnostic pop
437 : #endif
438 :
439 :
440 : // Can't be const because the pref-enabled boolean needs to be writable
441 : static Prefable<const JSPropertySpec> sAttributes[] = {
442 : { nullptr, &sAttributes_specs[0] },
443 : { nullptr, nullptr }
444 : };
445 :
446 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
447 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
448 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
449 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
450 :
451 :
452 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
453 : static PropertyInfo sNativeProperties_propertyInfos[4];
454 :
455 : static const NativePropertiesN<2> sNativeProperties = {
456 : false, 0,
457 : false, 0,
458 : true, 0 /* sMethods */,
459 : true, 1 /* sAttributes */,
460 : false, 0,
461 : false, 0,
462 : false, 0,
463 : -1,
464 : 4,
465 : sNativeProperties_sortedPropertyIndices,
466 : {
467 : { sMethods, &sNativeProperties_propertyInfos[0] },
468 : { sAttributes, &sNativeProperties_propertyInfos[3] }
469 : }
470 : };
471 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
472 : "We have a property info count that is oversized");
473 :
474 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
475 : {
476 : "Function",
477 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
478 : &sBoringInterfaceObjectClassClassOps,
479 : JS_NULL_CLASS_SPEC,
480 : JS_NULL_CLASS_EXT,
481 : &sInterfaceObjectClassObjectOps
482 : },
483 : eInterface,
484 : true,
485 : prototypes::id::HTMLAllCollection,
486 : PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth,
487 : sNativePropertyHooks,
488 : "function HTMLAllCollection() {\n [native code]\n}",
489 : JS::GetRealmFunctionPrototype
490 : };
491 :
492 : static bool
493 0 : _legacycaller(JSContext* cx, unsigned argc, JS::Value* vp)
494 : {
495 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
496 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
497 :
498 : mozilla::dom::HTMLAllCollection* self;
499 0 : JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
500 : {
501 0 : nsresult rv = UnwrapObject<prototypes::id::HTMLAllCollection, mozilla::dom::HTMLAllCollection>(&rootSelf, self);
502 0 : if (NS_FAILED(rv)) {
503 0 : return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "HTMLAllCollection");
504 : }
505 : }
506 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
507 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLAllCollection.__legacycaller");
508 : }
509 0 : binding_detail::FakeString arg0;
510 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
511 0 : return false;
512 : }
513 0 : Nullable<OwningNodeOrHTMLCollection> result;
514 0 : self->LegacyCall(args.thisv(), NonNullHelper(Constify(arg0)), result);
515 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
516 0 : if (result.IsNull()) {
517 0 : args.rval().setNull();
518 0 : return true;
519 : }
520 0 : if (!result.Value().ToJSVal(cx, obj, args.rval())) {
521 0 : return false;
522 : }
523 0 : return true;
524 : }
525 :
526 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
527 : {
528 : "HTMLAllCollectionPrototype",
529 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
530 : JS_NULL_CLASS_OPS,
531 : JS_NULL_CLASS_SPEC,
532 : JS_NULL_CLASS_EXT,
533 : JS_NULL_OBJECT_OPS
534 : },
535 : eInterfacePrototype,
536 : false,
537 : prototypes::id::HTMLAllCollection,
538 : PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth,
539 : sNativePropertyHooks,
540 : "[object HTMLAllCollectionPrototype]",
541 : JS::GetRealmObjectPrototype
542 : };
543 :
544 : JSObject*
545 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
546 : {
547 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
548 : }
549 :
550 : static_assert(IsBaseOf<nsISupports, mozilla::dom::HTMLAllCollection >::value,
551 : "We don't support non-nsISupports native classes for "
552 : "proxy-based bindings yet");
553 :
554 :
555 : class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
556 : {
557 : public:
558 : explicit constexpr DOMProxyHandler()
559 : {
560 : }
561 :
562 : virtual bool
563 : getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
564 :
565 : virtual bool
566 : defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
567 :
568 : using mozilla::dom::DOMProxyHandler::defineProperty;
569 :
570 : virtual bool
571 : ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
572 :
573 : virtual bool
574 : hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
575 :
576 : virtual bool
577 : get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
578 :
579 : virtual const char*
580 : className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
581 :
582 : virtual bool
583 : finalizeInBackground(const JS::Value& priv) const override;
584 :
585 : virtual void
586 : finalize(JSFreeOp* fop, JSObject* proxy) const override;
587 :
588 : static const DOMProxyHandler*
589 : getInstance();
590 :
591 : virtual bool
592 : delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
593 :
594 : virtual bool
595 : getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
596 :
597 : virtual bool
598 : call(JSContext* cx, JS::Handle<JSObject*> proxy, const JS::CallArgs& args) const override;
599 :
600 : virtual bool
601 : isCallable(JSObject* obj) const override;
602 : };
603 :
604 : MOZ_ALWAYS_INLINE bool
605 0 : IsProxy(JSObject* obj)
606 : {
607 0 : return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
608 : }
609 :
610 : MOZ_ALWAYS_INLINE mozilla::dom::HTMLAllCollection*
611 0 : UnwrapProxy(JSObject* obj)
612 : {
613 0 : MOZ_ASSERT(js::IsProxy(obj));
614 0 : if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
615 0 : MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
616 0 : obj = js::UncheckedUnwrap(obj);
617 : }
618 0 : MOZ_ASSERT(IsProxy(obj));
619 0 : return static_cast<mozilla::dom::HTMLAllCollection*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
620 : }
621 :
622 : bool
623 0 : DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
624 : {
625 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
626 0 : uint32_t index = GetArrayIndexFromId(cx, id);
627 0 : if (IsArrayIndex(index)) {
628 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
629 0 : bool found = false;
630 0 : auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
631 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
632 :
633 0 : if (found) {
634 0 : if (!result) {
635 0 : desc.value().setNull();
636 0 : FillPropertyDescriptor(desc, proxy, true);
637 0 : return true;
638 : }
639 0 : if (!GetOrCreateDOMReflector(cx, result, desc.value())) {
640 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
641 0 : return false;
642 : }
643 0 : FillPropertyDescriptor(desc, proxy, true);
644 0 : return true;
645 : }
646 : }
647 :
648 0 : JS::Rooted<JSObject*> expando(cx);
649 0 : if (!isXray && (expando = GetExpandoObject(proxy))) {
650 0 : if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
651 0 : return false;
652 : }
653 0 : if (desc.object()) {
654 : // Pretend the property lives on the wrapper.
655 0 : desc.object().set(proxy);
656 0 : return true;
657 : }
658 : }
659 :
660 0 : bool callNamedGetter = false;
661 0 : if (!IsArrayIndex(index) && !ignoreNamedProps) {
662 : bool hasOnProto;
663 0 : if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
664 0 : return false;
665 : }
666 0 : callNamedGetter = !hasOnProto;
667 : }
668 0 : if (callNamedGetter) {
669 0 : binding_detail::FakeString name;
670 : bool isSymbol;
671 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
672 0 : return false;
673 : }
674 0 : if (!isSymbol) {
675 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
676 0 : bool found = false;
677 0 : Nullable<OwningNodeOrHTMLCollection> result;
678 0 : self->NamedGetter(NonNullHelper(Constify(name)), found, result);
679 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
680 :
681 0 : if (found) {
682 0 : if (result.IsNull()) {
683 0 : desc.value().setNull();
684 0 : FillPropertyDescriptor(desc, proxy, true, false);
685 0 : return true;
686 : }
687 0 : if (!result.Value().ToJSVal(cx, proxy, desc.value())) {
688 0 : return false;
689 : }
690 0 : FillPropertyDescriptor(desc, proxy, true, false);
691 0 : return true;
692 : }
693 : }
694 : }
695 :
696 0 : desc.object().set(nullptr);
697 0 : return true;
698 : }
699 :
700 : bool
701 0 : DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
702 : {
703 0 : if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
704 0 : *defined = true;
705 0 : return opresult.failNoIndexedSetter();
706 : }
707 0 : bool found = false;
708 0 : binding_detail::FakeString name;
709 : bool isSymbol;
710 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
711 0 : return false;
712 : }
713 0 : if (!isSymbol) {
714 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
715 0 : Nullable<OwningNodeOrHTMLCollection> result;
716 0 : self->NamedGetter(NonNullHelper(Constify(name)), found, result);
717 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
718 : (void)result;
719 : }
720 :
721 0 : if (found) {
722 0 : *defined = true;
723 0 : return opresult.failNoNamedSetter();
724 : }
725 0 : return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
726 : }
727 :
728 :
729 : bool
730 0 : DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
731 : {
732 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
733 :
734 0 : uint32_t length = UnwrapProxy(proxy)->Length();
735 0 : MOZ_ASSERT(int32_t(length) >= 0);
736 0 : for (int32_t i = 0; i < int32_t(length); ++i) {
737 0 : if (!props.append(INT_TO_JSID(i))) {
738 0 : return false;
739 : }
740 : }
741 :
742 0 : if (flags & JSITER_HIDDEN) {
743 0 : nsTArray<nsString> names;
744 0 : UnwrapProxy(proxy)->GetSupportedNames(names);
745 0 : if (!AppendNamedPropertyIds(cx, proxy, names, false, props)) {
746 0 : return false;
747 : }
748 : }
749 :
750 0 : JS::Rooted<JSObject*> expando(cx);
751 0 : if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
752 0 : !js::GetPropertyKeys(cx, expando, flags, &props)) {
753 0 : return false;
754 : }
755 :
756 0 : return true;
757 : }
758 :
759 : bool
760 0 : DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
761 : {
762 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
763 : "Should not have a XrayWrapper here");
764 :
765 0 : uint32_t index = GetArrayIndexFromId(cx, id);
766 0 : if (IsArrayIndex(index)) {
767 0 : bool found = false;
768 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
769 0 : auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
770 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
771 : (void)result;
772 :
773 0 : *bp = found;
774 0 : return true;
775 : }
776 :
777 :
778 0 : JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
779 0 : if (expando) {
780 0 : bool b = true;
781 0 : bool ok = JS_HasPropertyById(cx, expando, id, &b);
782 0 : *bp = !!b;
783 0 : if (!ok || *bp) {
784 0 : return ok;
785 : }
786 : }
787 :
788 : bool hasOnProto;
789 0 : if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
790 0 : return false;
791 : }
792 0 : if (!hasOnProto) {
793 0 : bool found = false;
794 0 : binding_detail::FakeString name;
795 : bool isSymbol;
796 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
797 0 : return false;
798 : }
799 0 : if (!isSymbol) {
800 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
801 0 : Nullable<OwningNodeOrHTMLCollection> result;
802 0 : self->NamedGetter(NonNullHelper(Constify(name)), found, result);
803 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
804 : (void)result;
805 : }
806 :
807 0 : *bp = found;
808 0 : return true;
809 : }
810 0 : *bp = false;
811 0 : return true;
812 : }
813 :
814 : bool
815 0 : DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
816 : {
817 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
818 : "Should not have a XrayWrapper here");
819 :
820 0 : uint32_t index = GetArrayIndexFromId(cx, id);
821 0 : if (IsArrayIndex(index)) {
822 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
823 0 : bool found = false;
824 0 : auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
825 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
826 :
827 0 : if (found) {
828 0 : if (!result) {
829 0 : vp.setNull();
830 0 : return true;
831 : }
832 0 : if (!GetOrCreateDOMReflector(cx, result, vp)) {
833 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
834 0 : return false;
835 : }
836 0 : return true;
837 : }
838 : // Even if we don't have this index, we don't forward the
839 : // get on to our expando object.
840 : } else {
841 : { // Scope for expando
842 0 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
843 0 : if (expando) {
844 : bool hasProp;
845 0 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
846 0 : return false;
847 : }
848 :
849 0 : if (hasProp) {
850 : // Forward the get to the expando object, but our receiver is whatever our
851 : // receiver is.
852 0 : return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
853 : }
854 : }
855 : }
856 : }
857 :
858 : bool foundOnPrototype;
859 0 : if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
860 0 : return false;
861 : }
862 :
863 0 : if (foundOnPrototype) {
864 0 : return true;
865 : }
866 :
867 0 : if (!IsArrayIndex(index)) {
868 0 : binding_detail::FakeString name;
869 : bool isSymbol;
870 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
871 0 : return false;
872 : }
873 0 : if (!isSymbol) {
874 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
875 0 : bool found = false;
876 0 : Nullable<OwningNodeOrHTMLCollection> result;
877 0 : self->NamedGetter(NonNullHelper(Constify(name)), found, result);
878 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
879 :
880 0 : if (found) {
881 0 : if (result.IsNull()) {
882 0 : vp.setNull();
883 0 : return true;
884 : }
885 0 : if (!result.Value().ToJSVal(cx, proxy, vp)) {
886 0 : return false;
887 : }
888 0 : return true;
889 : }
890 : }
891 : }
892 :
893 0 : vp.setUndefined();
894 0 : return true;
895 : }
896 :
897 : const char*
898 0 : DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
899 : {
900 0 : return "HTMLAllCollection";
901 : }
902 :
903 : bool
904 0 : DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
905 : {
906 0 : return false;
907 : }
908 :
909 : void
910 0 : DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
911 : {
912 0 : mozilla::dom::HTMLAllCollection* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLAllCollection>(proxy);
913 0 : if (self) {
914 0 : ClearWrapper(self, self, proxy);
915 0 : AddForDeferredFinalization<mozilla::dom::HTMLAllCollection>(self);
916 : }
917 0 : }
918 :
919 : const DOMProxyHandler*
920 0 : DOMProxyHandler::getInstance()
921 : {
922 : static const DOMProxyHandler instance;
923 0 : return &instance;
924 : }
925 :
926 : bool
927 0 : DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
928 : {
929 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
930 : "Should not have a XrayWrapper here");
931 :
932 0 : uint32_t index = GetArrayIndexFromId(cx, id);
933 0 : if (IsArrayIndex(index)) {
934 : bool deleteSucceeded;
935 0 : bool found = false;
936 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
937 0 : auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
938 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
939 : (void)result;
940 0 : deleteSucceeded = !found;
941 0 : return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
942 : }
943 : // Try named delete only if the named property visibility
944 : // algorithm says the property is visible.
945 0 : bool tryNamedDelete = true;
946 : { // Scope for expando
947 0 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
948 0 : if (expando) {
949 : bool hasProp;
950 0 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
951 0 : return false;
952 : }
953 0 : tryNamedDelete = !hasProp;
954 : }
955 : }
956 0 : if (tryNamedDelete) {
957 : bool hasOnProto;
958 0 : if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
959 0 : return false;
960 : }
961 0 : tryNamedDelete = !hasOnProto;
962 : }
963 0 : if (tryNamedDelete) {
964 0 : bool found = false;
965 : bool deleteSucceeded;
966 0 : binding_detail::FakeString name;
967 : bool isSymbol;
968 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
969 0 : return false;
970 : }
971 0 : if (!isSymbol) {
972 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
973 0 : Nullable<OwningNodeOrHTMLCollection> result;
974 0 : self->NamedGetter(NonNullHelper(Constify(name)), found, result);
975 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
976 : (void)result;
977 : }
978 0 : deleteSucceeded = !found;
979 0 : if (found) {
980 0 : return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
981 : }
982 : }
983 :
984 0 : return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
985 : }
986 :
987 : bool
988 0 : DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
989 : {
990 0 : JS::Rooted<JS::Value> temp(cx);
991 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
992 : "Should not have a XrayWrapper here");
993 :
994 0 : mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
995 0 : uint32_t length = self->Length();
996 : // Compute the end of the indices we'll get ourselves
997 0 : uint32_t ourEnd = std::max(begin, std::min(end, length));
998 :
999 0 : for (uint32_t index = begin; index < ourEnd; ++index) {
1000 0 : bool found = false;
1001 0 : auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
1002 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1003 :
1004 0 : MOZ_ASSERT(found);
1005 0 : if (!result) {
1006 0 : temp.setNull();
1007 0 : if (!adder->append(cx, temp)) return false;
1008 0 : continue;
1009 : }
1010 0 : if (!GetOrCreateDOMReflector(cx, result, &temp)) {
1011 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1012 0 : return false;
1013 : }
1014 0 : if (!adder->append(cx, temp)) return false;
1015 0 : continue;
1016 : }
1017 :
1018 0 : if (end > ourEnd) {
1019 0 : JS::Rooted<JSObject*> proto(cx);
1020 0 : if (!js::GetObjectProto(cx, proxy, &proto)) {
1021 0 : return false;
1022 : }
1023 0 : return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
1024 : }
1025 :
1026 0 : return true;
1027 : }
1028 :
1029 : bool
1030 0 : DOMProxyHandler::call(JSContext* cx, JS::Handle<JSObject*> proxy, const JS::CallArgs& args) const
1031 : {
1032 0 : return js::ForwardToNative(cx, _legacycaller, args);
1033 : }
1034 :
1035 : bool
1036 0 : DOMProxyHandler::isCallable(JSObject* obj) const
1037 : {
1038 0 : return true;
1039 : }
1040 :
1041 : static const js::ClassExtension sClassExtension = PROXY_MAKE_EXT(
1042 : _objectMoved
1043 : );
1044 :
1045 : static const DOMJSClass sClass = {
1046 : PROXY_CLASS_WITH_EXT("HTMLAllCollection",
1047 : JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_EMULATES_UNDEFINED,
1048 : &sClassExtension),
1049 : { prototypes::id::HTMLAllCollection, 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 },
1050 : IsBaseOf<nsISupports, mozilla::dom::HTMLAllCollection >::value,
1051 : sNativePropertyHooks,
1052 : FindAssociatedGlobalForNative<mozilla::dom::HTMLAllCollection>::Get,
1053 : GetProtoObjectHandle,
1054 : GetCCParticipant<mozilla::dom::HTMLAllCollection>::Get()
1055 : };
1056 :
1057 : bool
1058 0 : Wrap(JSContext* aCx, mozilla::dom::HTMLAllCollection* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1059 : {
1060 : MOZ_ASSERT(static_cast<mozilla::dom::HTMLAllCollection*>(aObject) ==
1061 : reinterpret_cast<mozilla::dom::HTMLAllCollection*>(aObject),
1062 : "Multiple inheritance for mozilla::dom::HTMLAllCollection is broken.");
1063 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1064 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1065 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1066 : "You should probably not be using Wrap() directly; use "
1067 : "GetOrCreateDOMReflector instead");
1068 :
1069 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1070 : "nsISupports must be on our primary inheritance chain");
1071 :
1072 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1073 0 : if (!global) {
1074 0 : return false;
1075 : }
1076 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1077 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1078 :
1079 : // That might have ended up wrapping us already, due to the wonders
1080 : // of XBL. Check for that, and bail out as needed.
1081 0 : aReflector.set(aCache->GetWrapper());
1082 0 : if (aReflector) {
1083 : #ifdef DEBUG
1084 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1085 : #endif // DEBUG
1086 0 : return true;
1087 : }
1088 :
1089 0 : JSAutoCompartment ac(aCx, global);
1090 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1091 0 : if (!canonicalProto) {
1092 0 : return false;
1093 : }
1094 0 : JS::Rooted<JSObject*> proto(aCx);
1095 0 : if (aGivenProto) {
1096 0 : proto = aGivenProto;
1097 : // Unfortunately, while aGivenProto was in the compartment of aCx
1098 : // coming in, we changed compartments to that of "parent" so may need
1099 : // to wrap the proto here.
1100 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1101 0 : if (!JS_WrapObject(aCx, &proto)) {
1102 0 : return false;
1103 : }
1104 : }
1105 : } else {
1106 0 : proto = canonicalProto;
1107 : }
1108 :
1109 0 : BindingJSObjectCreator<mozilla::dom::HTMLAllCollection> creator(aCx);
1110 0 : JS::Rooted<JS::Value> expandoValue(aCx, JS::UndefinedValue());
1111 0 : creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
1112 0 : proto, aObject, expandoValue, aReflector);
1113 0 : if (!aReflector) {
1114 0 : return false;
1115 : }
1116 :
1117 :
1118 0 : aCache->SetWrapper(aReflector);
1119 0 : creator.InitializationSucceeded();
1120 :
1121 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1122 : aCache->GetWrapperPreserveColor() == aReflector);
1123 : // If proto != canonicalProto, we have to preserve our wrapper;
1124 : // otherwise we won't be able to properly recreate it later, since
1125 : // we won't know what proto to use. Note that we don't check
1126 : // aGivenProto here, since it's entirely possible (and even
1127 : // somewhat common) to have a non-null aGivenProto which is the
1128 : // same as canonicalProto.
1129 0 : if (proto != canonicalProto) {
1130 0 : PreserveWrapper(aObject);
1131 : }
1132 :
1133 0 : return true;
1134 : }
1135 :
1136 : static bool
1137 0 : ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
1138 : {
1139 0 : return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
1140 : }
1141 :
1142 : static bool
1143 0 : EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
1144 : {
1145 0 : return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
1146 : }
1147 :
1148 : const NativePropertyHooks sNativePropertyHooks[] = { {
1149 : ResolveOwnProperty,
1150 : EnumerateOwnProperties,
1151 : nullptr,
1152 : { sNativeProperties.Upcast(), nullptr },
1153 : prototypes::id::HTMLAllCollection,
1154 : constructors::id::HTMLAllCollection,
1155 : nullptr,
1156 : &DefaultXrayExpandoObjectClass
1157 : } };
1158 :
1159 : void
1160 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1161 : {
1162 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1163 0 : if (!parentProto) {
1164 0 : return;
1165 : }
1166 :
1167 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1168 0 : if (!constructorProto) {
1169 0 : return;
1170 : }
1171 :
1172 : static bool sIdsInited = false;
1173 0 : if (!sIdsInited && NS_IsMainThread()) {
1174 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1175 0 : return;
1176 : }
1177 0 : sIdsInited = true;
1178 : }
1179 :
1180 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::HTMLAllCollection);
1181 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::HTMLAllCollection);
1182 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1183 : &sPrototypeClass.mBase, protoCache,
1184 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1185 : interfaceCache,
1186 : sNativeProperties.Upcast(),
1187 : nullptr,
1188 : "HTMLAllCollection", aDefineOnGlobal,
1189 : nullptr,
1190 0 : false);
1191 : }
1192 :
1193 : JS::Handle<JSObject*>
1194 0 : GetProtoObjectHandle(JSContext* aCx)
1195 : {
1196 : /* Get the interface prototype object for this class. This will create the
1197 : object as needed. */
1198 0 : bool aDefineOnGlobal = true;
1199 :
1200 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1201 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1202 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1203 0 : return nullptr;
1204 : }
1205 :
1206 : /* Check to see whether the interface objects are already installed */
1207 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1208 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::HTMLAllCollection)) {
1209 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1210 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1211 : }
1212 :
1213 : /*
1214 : * The object might _still_ be null, but that's OK.
1215 : *
1216 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1217 : * traced by TraceProtoAndIfaceCache() and its contents are never
1218 : * changed after they have been set.
1219 : *
1220 : * Calling address() avoids the read read barrier that does gray
1221 : * unmarking, but it's not possible for the object to be gray here.
1222 : */
1223 :
1224 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::HTMLAllCollection);
1225 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1226 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1227 : }
1228 :
1229 : JS::Handle<JSObject*>
1230 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1231 : {
1232 : /* Get the interface object for this class. This will create the object as
1233 : needed. */
1234 :
1235 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1236 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1237 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1238 0 : return nullptr;
1239 : }
1240 :
1241 : /* Check to see whether the interface objects are already installed */
1242 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1243 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::HTMLAllCollection)) {
1244 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1245 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1246 : }
1247 :
1248 : /*
1249 : * The object might _still_ be null, but that's OK.
1250 : *
1251 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1252 : * traced by TraceProtoAndIfaceCache() and its contents are never
1253 : * changed after they have been set.
1254 : *
1255 : * Calling address() avoids the read read barrier that does gray
1256 : * unmarking, but it's not possible for the object to be gray here.
1257 : */
1258 :
1259 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::HTMLAllCollection);
1260 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1261 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1262 : }
1263 :
1264 : JSObject*
1265 0 : GetConstructorObject(JSContext* aCx)
1266 : {
1267 0 : return GetConstructorObjectHandle(aCx);
1268 : }
1269 :
1270 : } // namespace HTMLAllCollectionBinding
1271 :
1272 :
1273 :
1274 : } // namespace dom
1275 : } // namespace mozilla
|