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