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