Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM PaymentRequest.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "EventHandlerBinding.h"
5 : #include "EventTargetBinding.h"
6 : #include "PaymentRequestBinding.h"
7 : #include "WrapperFactory.h"
8 : #include "jsapi.h"
9 : #include "mozilla/OwningNonNull.h"
10 : #include "mozilla/dom/BindingUtils.h"
11 : #include "mozilla/dom/DOMJSClass.h"
12 : #include "mozilla/dom/NonRefcountedDOMObject.h"
13 : #include "mozilla/dom/Nullable.h"
14 : #include "mozilla/dom/PaymentAddress.h"
15 : #include "mozilla/dom/PaymentRequest.h"
16 : #include "mozilla/dom/PrimitiveConversions.h"
17 : #include "mozilla/dom/Promise.h"
18 : #include "mozilla/dom/ScriptSettings.h"
19 : #include "mozilla/dom/SimpleGlobalObject.h"
20 : #include "mozilla/dom/ToJSValue.h"
21 : #include "mozilla/dom/XrayExpandoClass.h"
22 :
23 : namespace mozilla {
24 : namespace dom {
25 :
26 : namespace PaymentShippingTypeValues {
27 : extern const EnumEntry strings[4] = {
28 : {"shipping", 8},
29 : {"delivery", 8},
30 : {"pickup", 6},
31 : { nullptr, 0 }
32 : };
33 : } // namespace PaymentShippingTypeValues
34 :
35 : bool
36 0 : ToJSValue(JSContext* aCx, PaymentShippingType aArgument, JS::MutableHandle<JS::Value> aValue)
37 : {
38 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(PaymentShippingTypeValues::strings));
39 : JSString* resultStr =
40 0 : JS_NewStringCopyN(aCx, PaymentShippingTypeValues::strings[uint32_t(aArgument)].value,
41 0 : PaymentShippingTypeValues::strings[uint32_t(aArgument)].length);
42 0 : if (!resultStr) {
43 0 : return false;
44 : }
45 0 : aValue.setString(resultStr);
46 0 : return true;
47 : }
48 :
49 :
50 :
51 0 : PaymentCurrencyAmount::PaymentCurrencyAmount()
52 : {
53 : // Safe to pass a null context if we pass a null value
54 0 : Init(nullptr, JS::NullHandleValue);
55 0 : }
56 :
57 :
58 :
59 : bool
60 0 : PaymentCurrencyAmount::InitIds(JSContext* cx, PaymentCurrencyAmountAtoms* atomsCache)
61 : {
62 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
63 :
64 : // Initialize these in reverse order so that any failure leaves the first one
65 : // uninitialized.
66 0 : if (!atomsCache->value_id.init(cx, "value") ||
67 0 : !atomsCache->currencySystem_id.init(cx, "currencySystem") ||
68 0 : !atomsCache->currency_id.init(cx, "currency")) {
69 0 : return false;
70 : }
71 0 : return true;
72 : }
73 :
74 : bool
75 0 : PaymentCurrencyAmount::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
76 : {
77 : // Passing a null JSContext is OK only if we're initing from null,
78 : // Since in that case we will not have to do any property gets
79 : // Also evaluate isNullOrUndefined in order to avoid false-positive
80 : // checkers by static analysis tools
81 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
82 0 : PaymentCurrencyAmountAtoms* atomsCache = nullptr;
83 0 : if (cx) {
84 0 : atomsCache = GetAtomCache<PaymentCurrencyAmountAtoms>(cx);
85 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
86 0 : return false;
87 : }
88 : }
89 :
90 0 : if (!IsConvertibleToDictionary(val)) {
91 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
92 : }
93 :
94 0 : bool isNull = val.isNullOrUndefined();
95 : // We only need these if !isNull, in which case we have |cx|.
96 0 : Maybe<JS::Rooted<JSObject *> > object;
97 0 : Maybe<JS::Rooted<JS::Value> > temp;
98 0 : if (!isNull) {
99 0 : MOZ_ASSERT(cx);
100 0 : object.emplace(cx, &val.toObject());
101 0 : temp.emplace(cx);
102 : }
103 0 : if (!isNull) {
104 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->currency_id, temp.ptr())) {
105 0 : return false;
106 : }
107 : }
108 0 : if (!isNull && !temp->isUndefined()) {
109 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mCurrency)) {
110 0 : return false;
111 : }
112 0 : mIsAnyMemberPresent = true;
113 0 : } else if (cx) {
114 : // Don't error out if we have no cx. In that
115 : // situation the caller is default-constructing us and we'll
116 : // just assume they know what they're doing.
117 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
118 0 : "'currency' member of PaymentCurrencyAmount");
119 : }
120 :
121 0 : if (!isNull) {
122 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->currencySystem_id, temp.ptr())) {
123 0 : return false;
124 : }
125 : }
126 0 : if (!isNull && !temp->isUndefined()) {
127 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mCurrencySystem)) {
128 0 : return false;
129 : }
130 : } else {
131 : static const char16_t data[] = { 'u', 'r', 'n', ':', 'i', 's', 'o', ':', 's', 't', 'd', ':', 'i', 's', 'o', ':', '4', '2', '1', '7', 0 };
132 0 : mCurrencySystem.Rebind(data, ArrayLength(data) - 1);
133 : }
134 0 : mIsAnyMemberPresent = true;
135 :
136 0 : if (!isNull) {
137 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->value_id, temp.ptr())) {
138 0 : return false;
139 : }
140 : }
141 0 : if (!isNull && !temp->isUndefined()) {
142 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mValue)) {
143 0 : return false;
144 : }
145 0 : mIsAnyMemberPresent = true;
146 0 : } else if (cx) {
147 : // Don't error out if we have no cx. In that
148 : // situation the caller is default-constructing us and we'll
149 : // just assume they know what they're doing.
150 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
151 0 : "'value' member of PaymentCurrencyAmount");
152 : }
153 0 : return true;
154 : }
155 :
156 : bool
157 0 : PaymentCurrencyAmount::Init(const nsAString& aJSON)
158 : {
159 0 : AutoJSAPI jsapi;
160 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
161 0 : if (!cleanGlobal) {
162 0 : return false;
163 : }
164 0 : if (!jsapi.Init(cleanGlobal)) {
165 0 : return false;
166 : }
167 0 : JSContext* cx = jsapi.cx();
168 0 : JS::Rooted<JS::Value> json(cx);
169 0 : bool ok = ParseJSON(cx, aJSON, &json);
170 0 : NS_ENSURE_TRUE(ok, false);
171 0 : return Init(cx, json);
172 : }
173 :
174 : bool
175 0 : PaymentCurrencyAmount::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
176 : {
177 0 : PaymentCurrencyAmountAtoms* atomsCache = GetAtomCache<PaymentCurrencyAmountAtoms>(cx);
178 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
179 0 : return false;
180 : }
181 :
182 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
183 0 : if (!obj) {
184 0 : return false;
185 : }
186 0 : rval.set(JS::ObjectValue(*obj));
187 :
188 : do {
189 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
190 0 : JS::Rooted<JS::Value> temp(cx);
191 0 : nsString const & currentValue = mCurrency;
192 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
193 0 : return false;
194 : }
195 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->currency_id, temp, JSPROP_ENUMERATE)) {
196 0 : return false;
197 : }
198 0 : break;
199 : } while(0);
200 :
201 : do {
202 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
203 0 : JS::Rooted<JS::Value> temp(cx);
204 0 : nsString const & currentValue = mCurrencySystem;
205 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
206 0 : return false;
207 : }
208 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->currencySystem_id, temp, JSPROP_ENUMERATE)) {
209 0 : return false;
210 : }
211 0 : break;
212 : } while(0);
213 :
214 : do {
215 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
216 0 : JS::Rooted<JS::Value> temp(cx);
217 0 : nsString const & currentValue = mValue;
218 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
219 0 : return false;
220 : }
221 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->value_id, temp, JSPROP_ENUMERATE)) {
222 0 : return false;
223 : }
224 0 : break;
225 : } while(0);
226 :
227 0 : return true;
228 : }
229 :
230 : bool
231 0 : PaymentCurrencyAmount::ToJSON(nsAString& aJSON) const
232 : {
233 0 : AutoJSAPI jsapi;
234 0 : jsapi.Init();
235 0 : JSContext *cx = jsapi.cx();
236 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
237 : // because we'll only be creating objects, in ways that have no
238 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
239 : // which likewise guarantees no side-effects for the sorts of
240 : // things we will pass it.
241 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
242 0 : JS::Rooted<JS::Value> val(cx);
243 0 : if (!ToObjectInternal(cx, &val)) {
244 0 : return false;
245 : }
246 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
247 0 : return StringifyToJSON(cx, obj, aJSON);
248 : }
249 :
250 : void
251 0 : PaymentCurrencyAmount::TraceDictionary(JSTracer* trc)
252 : {
253 0 : }
254 :
255 : PaymentCurrencyAmount&
256 0 : PaymentCurrencyAmount::operator=(const PaymentCurrencyAmount& aOther)
257 : {
258 0 : mCurrency = aOther.mCurrency;
259 0 : mCurrencySystem = aOther.mCurrencySystem;
260 0 : mValue = aOther.mValue;
261 0 : return *this;
262 : }
263 :
264 : namespace binding_detail {
265 : } // namespace binding_detail
266 :
267 :
268 :
269 0 : PaymentMethodData::PaymentMethodData()
270 : {
271 : // Safe to pass a null context if we pass a null value
272 0 : Init(nullptr, JS::NullHandleValue);
273 0 : }
274 :
275 :
276 : bool
277 0 : PaymentMethodData::InitIds(JSContext* cx, PaymentMethodDataAtoms* atomsCache)
278 : {
279 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
280 :
281 : // Initialize these in reverse order so that any failure leaves the first one
282 : // uninitialized.
283 0 : if (!atomsCache->supportedMethods_id.init(cx, "supportedMethods") ||
284 0 : !atomsCache->data_id.init(cx, "data")) {
285 0 : return false;
286 : }
287 0 : return true;
288 : }
289 :
290 : bool
291 0 : PaymentMethodData::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
292 : {
293 : // Passing a null JSContext is OK only if we're initing from null,
294 : // Since in that case we will not have to do any property gets
295 : // Also evaluate isNullOrUndefined in order to avoid false-positive
296 : // checkers by static analysis tools
297 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
298 0 : PaymentMethodDataAtoms* atomsCache = nullptr;
299 0 : if (cx) {
300 0 : atomsCache = GetAtomCache<PaymentMethodDataAtoms>(cx);
301 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
302 0 : return false;
303 : }
304 : }
305 :
306 0 : if (!IsConvertibleToDictionary(val)) {
307 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
308 : }
309 :
310 0 : bool isNull = val.isNullOrUndefined();
311 : // We only need these if !isNull, in which case we have |cx|.
312 0 : Maybe<JS::Rooted<JSObject *> > object;
313 0 : Maybe<JS::Rooted<JS::Value> > temp;
314 0 : if (!isNull) {
315 0 : MOZ_ASSERT(cx);
316 0 : object.emplace(cx, &val.toObject());
317 0 : temp.emplace(cx);
318 : }
319 0 : if (!isNull) {
320 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
321 0 : return false;
322 : }
323 : }
324 0 : if (!isNull && !temp->isUndefined()) {
325 0 : mData.Construct();
326 0 : if (temp.ref().isObject()) {
327 : #ifdef __clang__
328 : #pragma clang diagnostic push
329 : #pragma clang diagnostic ignored "-Wunreachable-code"
330 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
331 : #endif // __clang__
332 0 : if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
333 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'data' member of PaymentMethodData");
334 0 : return false;
335 : }
336 : #ifdef __clang__
337 : #pragma clang diagnostic pop
338 : #endif // __clang__
339 0 : (mData.Value()) = &temp.ref().toObject();
340 : } else {
341 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'data' member of PaymentMethodData");
342 0 : return false;
343 : }
344 0 : mIsAnyMemberPresent = true;
345 : }
346 :
347 0 : if (!isNull) {
348 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->supportedMethods_id, temp.ptr())) {
349 0 : return false;
350 : }
351 : }
352 0 : if (!isNull && !temp->isUndefined()) {
353 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mSupportedMethods)) {
354 0 : return false;
355 : }
356 0 : mIsAnyMemberPresent = true;
357 0 : } else if (cx) {
358 : // Don't error out if we have no cx. In that
359 : // situation the caller is default-constructing us and we'll
360 : // just assume they know what they're doing.
361 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
362 0 : "'supportedMethods' member of PaymentMethodData");
363 : }
364 0 : return true;
365 : }
366 :
367 : bool
368 0 : PaymentMethodData::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
369 : {
370 0 : PaymentMethodDataAtoms* atomsCache = GetAtomCache<PaymentMethodDataAtoms>(cx);
371 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
372 0 : return false;
373 : }
374 :
375 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
376 0 : if (!obj) {
377 0 : return false;
378 : }
379 0 : rval.set(JS::ObjectValue(*obj));
380 :
381 0 : if (mData.WasPassed()) {
382 : do {
383 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
384 0 : JS::Rooted<JS::Value> temp(cx);
385 0 : JSObject* const & currentValue = mData.InternalValue();
386 0 : JS::ExposeObjectToActiveJS(currentValue);
387 0 : temp.setObject(*currentValue);
388 0 : if (!MaybeWrapObjectValue(cx, &temp)) {
389 0 : return false;
390 : }
391 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
392 0 : return false;
393 : }
394 0 : break;
395 : } while(0);
396 : }
397 :
398 : do {
399 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
400 0 : JS::Rooted<JS::Value> temp(cx);
401 0 : nsString const & currentValue = mSupportedMethods;
402 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
403 0 : return false;
404 : }
405 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->supportedMethods_id, temp, JSPROP_ENUMERATE)) {
406 0 : return false;
407 : }
408 0 : break;
409 : } while(0);
410 :
411 0 : return true;
412 : }
413 :
414 : void
415 0 : PaymentMethodData::TraceDictionary(JSTracer* trc)
416 : {
417 0 : if (mData.WasPassed()) {
418 0 : JS::UnsafeTraceRoot(trc, &mData.Value(), "PaymentMethodData.mData");
419 : }
420 0 : }
421 :
422 : namespace binding_detail {
423 : } // namespace binding_detail
424 :
425 :
426 :
427 0 : PaymentOptions::PaymentOptions()
428 : {
429 : // Safe to pass a null context if we pass a null value
430 0 : Init(nullptr, JS::NullHandleValue);
431 0 : }
432 :
433 :
434 :
435 : bool
436 0 : PaymentOptions::InitIds(JSContext* cx, PaymentOptionsAtoms* atomsCache)
437 : {
438 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
439 :
440 : // Initialize these in reverse order so that any failure leaves the first one
441 : // uninitialized.
442 0 : if (!atomsCache->shippingType_id.init(cx, "shippingType") ||
443 0 : !atomsCache->requestShipping_id.init(cx, "requestShipping") ||
444 0 : !atomsCache->requestPayerPhone_id.init(cx, "requestPayerPhone") ||
445 0 : !atomsCache->requestPayerName_id.init(cx, "requestPayerName") ||
446 0 : !atomsCache->requestPayerEmail_id.init(cx, "requestPayerEmail")) {
447 0 : return false;
448 : }
449 0 : return true;
450 : }
451 :
452 : bool
453 0 : PaymentOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
454 : {
455 : // Passing a null JSContext is OK only if we're initing from null,
456 : // Since in that case we will not have to do any property gets
457 : // Also evaluate isNullOrUndefined in order to avoid false-positive
458 : // checkers by static analysis tools
459 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
460 0 : PaymentOptionsAtoms* atomsCache = nullptr;
461 0 : if (cx) {
462 0 : atomsCache = GetAtomCache<PaymentOptionsAtoms>(cx);
463 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
464 0 : return false;
465 : }
466 : }
467 :
468 0 : if (!IsConvertibleToDictionary(val)) {
469 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
470 : }
471 :
472 0 : bool isNull = val.isNullOrUndefined();
473 : // We only need these if !isNull, in which case we have |cx|.
474 0 : Maybe<JS::Rooted<JSObject *> > object;
475 0 : Maybe<JS::Rooted<JS::Value> > temp;
476 0 : if (!isNull) {
477 0 : MOZ_ASSERT(cx);
478 0 : object.emplace(cx, &val.toObject());
479 0 : temp.emplace(cx);
480 : }
481 0 : if (!isNull) {
482 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->requestPayerEmail_id, temp.ptr())) {
483 0 : return false;
484 : }
485 : }
486 0 : if (!isNull && !temp->isUndefined()) {
487 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestPayerEmail)) {
488 0 : return false;
489 : }
490 : } else {
491 0 : mRequestPayerEmail = false;
492 : }
493 0 : mIsAnyMemberPresent = true;
494 :
495 0 : if (!isNull) {
496 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->requestPayerName_id, temp.ptr())) {
497 0 : return false;
498 : }
499 : }
500 0 : if (!isNull && !temp->isUndefined()) {
501 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestPayerName)) {
502 0 : return false;
503 : }
504 : } else {
505 0 : mRequestPayerName = false;
506 : }
507 0 : mIsAnyMemberPresent = true;
508 :
509 0 : if (!isNull) {
510 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->requestPayerPhone_id, temp.ptr())) {
511 0 : return false;
512 : }
513 : }
514 0 : if (!isNull && !temp->isUndefined()) {
515 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestPayerPhone)) {
516 0 : return false;
517 : }
518 : } else {
519 0 : mRequestPayerPhone = false;
520 : }
521 0 : mIsAnyMemberPresent = true;
522 :
523 0 : if (!isNull) {
524 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->requestShipping_id, temp.ptr())) {
525 0 : return false;
526 : }
527 : }
528 0 : if (!isNull && !temp->isUndefined()) {
529 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestShipping)) {
530 0 : return false;
531 : }
532 : } else {
533 0 : mRequestShipping = false;
534 : }
535 0 : mIsAnyMemberPresent = true;
536 :
537 0 : if (!isNull) {
538 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->shippingType_id, temp.ptr())) {
539 0 : return false;
540 : }
541 : }
542 0 : if (!isNull && !temp->isUndefined()) {
543 : {
544 : int index;
545 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), PaymentShippingTypeValues::strings, "PaymentShippingType", "'shippingType' member of PaymentOptions", &index)) {
546 0 : return false;
547 : }
548 0 : MOZ_ASSERT(index >= 0);
549 0 : mShippingType = static_cast<PaymentShippingType>(index);
550 : }
551 : } else {
552 0 : mShippingType = PaymentShippingType::Shipping;
553 : }
554 0 : mIsAnyMemberPresent = true;
555 0 : return true;
556 : }
557 :
558 : bool
559 0 : PaymentOptions::Init(const nsAString& aJSON)
560 : {
561 0 : AutoJSAPI jsapi;
562 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
563 0 : if (!cleanGlobal) {
564 0 : return false;
565 : }
566 0 : if (!jsapi.Init(cleanGlobal)) {
567 0 : return false;
568 : }
569 0 : JSContext* cx = jsapi.cx();
570 0 : JS::Rooted<JS::Value> json(cx);
571 0 : bool ok = ParseJSON(cx, aJSON, &json);
572 0 : NS_ENSURE_TRUE(ok, false);
573 0 : return Init(cx, json);
574 : }
575 :
576 : bool
577 0 : PaymentOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
578 : {
579 0 : PaymentOptionsAtoms* atomsCache = GetAtomCache<PaymentOptionsAtoms>(cx);
580 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
581 0 : return false;
582 : }
583 :
584 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
585 0 : if (!obj) {
586 0 : return false;
587 : }
588 0 : rval.set(JS::ObjectValue(*obj));
589 :
590 : do {
591 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
592 0 : JS::Rooted<JS::Value> temp(cx);
593 0 : bool const & currentValue = mRequestPayerEmail;
594 0 : temp.setBoolean(currentValue);
595 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->requestPayerEmail_id, temp, JSPROP_ENUMERATE)) {
596 0 : return false;
597 : }
598 0 : break;
599 : } while(0);
600 :
601 : do {
602 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
603 0 : JS::Rooted<JS::Value> temp(cx);
604 0 : bool const & currentValue = mRequestPayerName;
605 0 : temp.setBoolean(currentValue);
606 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->requestPayerName_id, temp, JSPROP_ENUMERATE)) {
607 0 : return false;
608 : }
609 0 : break;
610 : } while(0);
611 :
612 : do {
613 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
614 0 : JS::Rooted<JS::Value> temp(cx);
615 0 : bool const & currentValue = mRequestPayerPhone;
616 0 : temp.setBoolean(currentValue);
617 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->requestPayerPhone_id, temp, JSPROP_ENUMERATE)) {
618 0 : return false;
619 : }
620 0 : break;
621 : } while(0);
622 :
623 : do {
624 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
625 0 : JS::Rooted<JS::Value> temp(cx);
626 0 : bool const & currentValue = mRequestShipping;
627 0 : temp.setBoolean(currentValue);
628 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->requestShipping_id, temp, JSPROP_ENUMERATE)) {
629 0 : return false;
630 : }
631 0 : break;
632 : } while(0);
633 :
634 : do {
635 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
636 0 : JS::Rooted<JS::Value> temp(cx);
637 0 : PaymentShippingType const & currentValue = mShippingType;
638 0 : if (!ToJSValue(cx, currentValue, &temp)) {
639 0 : return false;
640 : }
641 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->shippingType_id, temp, JSPROP_ENUMERATE)) {
642 0 : return false;
643 : }
644 0 : break;
645 : } while(0);
646 :
647 0 : return true;
648 : }
649 :
650 : bool
651 0 : PaymentOptions::ToJSON(nsAString& aJSON) const
652 : {
653 0 : AutoJSAPI jsapi;
654 0 : jsapi.Init();
655 0 : JSContext *cx = jsapi.cx();
656 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
657 : // because we'll only be creating objects, in ways that have no
658 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
659 : // which likewise guarantees no side-effects for the sorts of
660 : // things we will pass it.
661 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
662 0 : JS::Rooted<JS::Value> val(cx);
663 0 : if (!ToObjectInternal(cx, &val)) {
664 0 : return false;
665 : }
666 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
667 0 : return StringifyToJSON(cx, obj, aJSON);
668 : }
669 :
670 : void
671 0 : PaymentOptions::TraceDictionary(JSTracer* trc)
672 : {
673 0 : }
674 :
675 : PaymentOptions&
676 0 : PaymentOptions::operator=(const PaymentOptions& aOther)
677 : {
678 0 : mRequestPayerEmail = aOther.mRequestPayerEmail;
679 0 : mRequestPayerName = aOther.mRequestPayerName;
680 0 : mRequestPayerPhone = aOther.mRequestPayerPhone;
681 0 : mRequestShipping = aOther.mRequestShipping;
682 0 : mShippingType = aOther.mShippingType;
683 0 : return *this;
684 : }
685 :
686 : namespace binding_detail {
687 : } // namespace binding_detail
688 :
689 :
690 :
691 0 : PaymentItem::PaymentItem()
692 0 : : mAmount(FastDictionaryInitializer())
693 : {
694 : // Safe to pass a null context if we pass a null value
695 0 : Init(nullptr, JS::NullHandleValue);
696 0 : }
697 :
698 :
699 :
700 : bool
701 0 : PaymentItem::InitIds(JSContext* cx, PaymentItemAtoms* atomsCache)
702 : {
703 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
704 :
705 : // Initialize these in reverse order so that any failure leaves the first one
706 : // uninitialized.
707 0 : if (!atomsCache->pending_id.init(cx, "pending") ||
708 0 : !atomsCache->label_id.init(cx, "label") ||
709 0 : !atomsCache->amount_id.init(cx, "amount")) {
710 0 : return false;
711 : }
712 0 : return true;
713 : }
714 :
715 : bool
716 0 : PaymentItem::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
717 : {
718 : // Passing a null JSContext is OK only if we're initing from null,
719 : // Since in that case we will not have to do any property gets
720 : // Also evaluate isNullOrUndefined in order to avoid false-positive
721 : // checkers by static analysis tools
722 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
723 0 : PaymentItemAtoms* atomsCache = nullptr;
724 0 : if (cx) {
725 0 : atomsCache = GetAtomCache<PaymentItemAtoms>(cx);
726 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
727 0 : return false;
728 : }
729 : }
730 :
731 0 : if (!IsConvertibleToDictionary(val)) {
732 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
733 : }
734 :
735 0 : bool isNull = val.isNullOrUndefined();
736 : // We only need these if !isNull, in which case we have |cx|.
737 0 : Maybe<JS::Rooted<JSObject *> > object;
738 0 : Maybe<JS::Rooted<JS::Value> > temp;
739 0 : if (!isNull) {
740 0 : MOZ_ASSERT(cx);
741 0 : object.emplace(cx, &val.toObject());
742 0 : temp.emplace(cx);
743 : }
744 0 : if (!isNull) {
745 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->amount_id, temp.ptr())) {
746 0 : return false;
747 : }
748 : }
749 0 : if (!isNull && !temp->isUndefined()) {
750 0 : if (!mAmount.Init(cx, temp.ref(), "'amount' member of PaymentItem", passedToJSImpl)) {
751 0 : return false;
752 : }
753 0 : mIsAnyMemberPresent = true;
754 0 : } else if (cx) {
755 : // Don't error out if we have no cx. In that
756 : // situation the caller is default-constructing us and we'll
757 : // just assume they know what they're doing.
758 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
759 0 : "'amount' member of PaymentItem");
760 : }
761 :
762 0 : if (!isNull) {
763 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->label_id, temp.ptr())) {
764 0 : return false;
765 : }
766 : }
767 0 : if (!isNull && !temp->isUndefined()) {
768 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mLabel)) {
769 0 : return false;
770 : }
771 0 : mIsAnyMemberPresent = true;
772 0 : } else if (cx) {
773 : // Don't error out if we have no cx. In that
774 : // situation the caller is default-constructing us and we'll
775 : // just assume they know what they're doing.
776 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
777 0 : "'label' member of PaymentItem");
778 : }
779 :
780 0 : if (!isNull) {
781 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->pending_id, temp.ptr())) {
782 0 : return false;
783 : }
784 : }
785 0 : if (!isNull && !temp->isUndefined()) {
786 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPending)) {
787 0 : return false;
788 : }
789 : } else {
790 0 : mPending = false;
791 : }
792 0 : mIsAnyMemberPresent = true;
793 0 : return true;
794 : }
795 :
796 : bool
797 0 : PaymentItem::Init(const nsAString& aJSON)
798 : {
799 0 : AutoJSAPI jsapi;
800 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
801 0 : if (!cleanGlobal) {
802 0 : return false;
803 : }
804 0 : if (!jsapi.Init(cleanGlobal)) {
805 0 : return false;
806 : }
807 0 : JSContext* cx = jsapi.cx();
808 0 : JS::Rooted<JS::Value> json(cx);
809 0 : bool ok = ParseJSON(cx, aJSON, &json);
810 0 : NS_ENSURE_TRUE(ok, false);
811 0 : return Init(cx, json);
812 : }
813 :
814 : bool
815 0 : PaymentItem::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
816 : {
817 0 : PaymentItemAtoms* atomsCache = GetAtomCache<PaymentItemAtoms>(cx);
818 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
819 0 : return false;
820 : }
821 :
822 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
823 0 : if (!obj) {
824 0 : return false;
825 : }
826 0 : rval.set(JS::ObjectValue(*obj));
827 :
828 : do {
829 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
830 0 : JS::Rooted<JS::Value> temp(cx);
831 0 : PaymentCurrencyAmount const & currentValue = mAmount;
832 0 : if (!currentValue.ToObjectInternal(cx, &temp)) {
833 0 : return false;
834 : }
835 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->amount_id, temp, JSPROP_ENUMERATE)) {
836 0 : return false;
837 : }
838 0 : break;
839 : } while(0);
840 :
841 : do {
842 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
843 0 : JS::Rooted<JS::Value> temp(cx);
844 0 : nsString const & currentValue = mLabel;
845 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
846 0 : return false;
847 : }
848 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->label_id, temp, JSPROP_ENUMERATE)) {
849 0 : return false;
850 : }
851 0 : break;
852 : } while(0);
853 :
854 : do {
855 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
856 0 : JS::Rooted<JS::Value> temp(cx);
857 0 : bool const & currentValue = mPending;
858 0 : temp.setBoolean(currentValue);
859 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->pending_id, temp, JSPROP_ENUMERATE)) {
860 0 : return false;
861 : }
862 0 : break;
863 : } while(0);
864 :
865 0 : return true;
866 : }
867 :
868 : bool
869 0 : PaymentItem::ToJSON(nsAString& aJSON) const
870 : {
871 0 : AutoJSAPI jsapi;
872 0 : jsapi.Init();
873 0 : JSContext *cx = jsapi.cx();
874 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
875 : // because we'll only be creating objects, in ways that have no
876 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
877 : // which likewise guarantees no side-effects for the sorts of
878 : // things we will pass it.
879 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
880 0 : JS::Rooted<JS::Value> val(cx);
881 0 : if (!ToObjectInternal(cx, &val)) {
882 0 : return false;
883 : }
884 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
885 0 : return StringifyToJSON(cx, obj, aJSON);
886 : }
887 :
888 : void
889 0 : PaymentItem::TraceDictionary(JSTracer* trc)
890 : {
891 0 : }
892 :
893 : PaymentItem&
894 0 : PaymentItem::operator=(const PaymentItem& aOther)
895 : {
896 0 : mAmount = aOther.mAmount;
897 0 : mLabel = aOther.mLabel;
898 0 : mPending = aOther.mPending;
899 0 : return *this;
900 : }
901 :
902 : namespace binding_detail {
903 : } // namespace binding_detail
904 :
905 :
906 :
907 0 : PaymentShippingOption::PaymentShippingOption()
908 0 : : mAmount(FastDictionaryInitializer())
909 : {
910 : // Safe to pass a null context if we pass a null value
911 0 : Init(nullptr, JS::NullHandleValue);
912 0 : }
913 :
914 :
915 :
916 : bool
917 0 : PaymentShippingOption::InitIds(JSContext* cx, PaymentShippingOptionAtoms* atomsCache)
918 : {
919 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
920 :
921 : // Initialize these in reverse order so that any failure leaves the first one
922 : // uninitialized.
923 0 : if (!atomsCache->selected_id.init(cx, "selected") ||
924 0 : !atomsCache->label_id.init(cx, "label") ||
925 0 : !atomsCache->id_id.init(cx, "id") ||
926 0 : !atomsCache->amount_id.init(cx, "amount")) {
927 0 : return false;
928 : }
929 0 : return true;
930 : }
931 :
932 : bool
933 0 : PaymentShippingOption::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
934 : {
935 : // Passing a null JSContext is OK only if we're initing from null,
936 : // Since in that case we will not have to do any property gets
937 : // Also evaluate isNullOrUndefined in order to avoid false-positive
938 : // checkers by static analysis tools
939 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
940 0 : PaymentShippingOptionAtoms* atomsCache = nullptr;
941 0 : if (cx) {
942 0 : atomsCache = GetAtomCache<PaymentShippingOptionAtoms>(cx);
943 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
944 0 : return false;
945 : }
946 : }
947 :
948 0 : if (!IsConvertibleToDictionary(val)) {
949 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
950 : }
951 :
952 0 : bool isNull = val.isNullOrUndefined();
953 : // We only need these if !isNull, in which case we have |cx|.
954 0 : Maybe<JS::Rooted<JSObject *> > object;
955 0 : Maybe<JS::Rooted<JS::Value> > temp;
956 0 : if (!isNull) {
957 0 : MOZ_ASSERT(cx);
958 0 : object.emplace(cx, &val.toObject());
959 0 : temp.emplace(cx);
960 : }
961 0 : if (!isNull) {
962 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->amount_id, temp.ptr())) {
963 0 : return false;
964 : }
965 : }
966 0 : if (!isNull && !temp->isUndefined()) {
967 0 : if (!mAmount.Init(cx, temp.ref(), "'amount' member of PaymentShippingOption", passedToJSImpl)) {
968 0 : return false;
969 : }
970 0 : mIsAnyMemberPresent = true;
971 0 : } else if (cx) {
972 : // Don't error out if we have no cx. In that
973 : // situation the caller is default-constructing us and we'll
974 : // just assume they know what they're doing.
975 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
976 0 : "'amount' member of PaymentShippingOption");
977 : }
978 :
979 0 : if (!isNull) {
980 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
981 0 : return false;
982 : }
983 : }
984 0 : if (!isNull && !temp->isUndefined()) {
985 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mId)) {
986 0 : return false;
987 : }
988 0 : mIsAnyMemberPresent = true;
989 0 : } else if (cx) {
990 : // Don't error out if we have no cx. In that
991 : // situation the caller is default-constructing us and we'll
992 : // just assume they know what they're doing.
993 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
994 0 : "'id' member of PaymentShippingOption");
995 : }
996 :
997 0 : if (!isNull) {
998 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->label_id, temp.ptr())) {
999 0 : return false;
1000 : }
1001 : }
1002 0 : if (!isNull && !temp->isUndefined()) {
1003 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mLabel)) {
1004 0 : return false;
1005 : }
1006 0 : mIsAnyMemberPresent = true;
1007 0 : } else if (cx) {
1008 : // Don't error out if we have no cx. In that
1009 : // situation the caller is default-constructing us and we'll
1010 : // just assume they know what they're doing.
1011 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1012 0 : "'label' member of PaymentShippingOption");
1013 : }
1014 :
1015 0 : if (!isNull) {
1016 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->selected_id, temp.ptr())) {
1017 0 : return false;
1018 : }
1019 : }
1020 0 : if (!isNull && !temp->isUndefined()) {
1021 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mSelected)) {
1022 0 : return false;
1023 : }
1024 : } else {
1025 0 : mSelected = false;
1026 : }
1027 0 : mIsAnyMemberPresent = true;
1028 0 : return true;
1029 : }
1030 :
1031 : bool
1032 0 : PaymentShippingOption::Init(const nsAString& aJSON)
1033 : {
1034 0 : AutoJSAPI jsapi;
1035 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1036 0 : if (!cleanGlobal) {
1037 0 : return false;
1038 : }
1039 0 : if (!jsapi.Init(cleanGlobal)) {
1040 0 : return false;
1041 : }
1042 0 : JSContext* cx = jsapi.cx();
1043 0 : JS::Rooted<JS::Value> json(cx);
1044 0 : bool ok = ParseJSON(cx, aJSON, &json);
1045 0 : NS_ENSURE_TRUE(ok, false);
1046 0 : return Init(cx, json);
1047 : }
1048 :
1049 : bool
1050 0 : PaymentShippingOption::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1051 : {
1052 0 : PaymentShippingOptionAtoms* atomsCache = GetAtomCache<PaymentShippingOptionAtoms>(cx);
1053 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1054 0 : return false;
1055 : }
1056 :
1057 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1058 0 : if (!obj) {
1059 0 : return false;
1060 : }
1061 0 : rval.set(JS::ObjectValue(*obj));
1062 :
1063 : do {
1064 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1065 0 : JS::Rooted<JS::Value> temp(cx);
1066 0 : PaymentCurrencyAmount const & currentValue = mAmount;
1067 0 : if (!currentValue.ToObjectInternal(cx, &temp)) {
1068 0 : return false;
1069 : }
1070 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->amount_id, temp, JSPROP_ENUMERATE)) {
1071 0 : return false;
1072 : }
1073 0 : break;
1074 : } while(0);
1075 :
1076 : do {
1077 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1078 0 : JS::Rooted<JS::Value> temp(cx);
1079 0 : nsString const & currentValue = mId;
1080 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1081 0 : return false;
1082 : }
1083 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
1084 0 : return false;
1085 : }
1086 0 : break;
1087 : } while(0);
1088 :
1089 : do {
1090 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1091 0 : JS::Rooted<JS::Value> temp(cx);
1092 0 : nsString const & currentValue = mLabel;
1093 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1094 0 : return false;
1095 : }
1096 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->label_id, temp, JSPROP_ENUMERATE)) {
1097 0 : return false;
1098 : }
1099 0 : break;
1100 : } while(0);
1101 :
1102 : do {
1103 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1104 0 : JS::Rooted<JS::Value> temp(cx);
1105 0 : bool const & currentValue = mSelected;
1106 0 : temp.setBoolean(currentValue);
1107 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->selected_id, temp, JSPROP_ENUMERATE)) {
1108 0 : return false;
1109 : }
1110 0 : break;
1111 : } while(0);
1112 :
1113 0 : return true;
1114 : }
1115 :
1116 : bool
1117 0 : PaymentShippingOption::ToJSON(nsAString& aJSON) const
1118 : {
1119 0 : AutoJSAPI jsapi;
1120 0 : jsapi.Init();
1121 0 : JSContext *cx = jsapi.cx();
1122 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1123 : // because we'll only be creating objects, in ways that have no
1124 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1125 : // which likewise guarantees no side-effects for the sorts of
1126 : // things we will pass it.
1127 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1128 0 : JS::Rooted<JS::Value> val(cx);
1129 0 : if (!ToObjectInternal(cx, &val)) {
1130 0 : return false;
1131 : }
1132 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1133 0 : return StringifyToJSON(cx, obj, aJSON);
1134 : }
1135 :
1136 : void
1137 0 : PaymentShippingOption::TraceDictionary(JSTracer* trc)
1138 : {
1139 0 : }
1140 :
1141 : PaymentShippingOption&
1142 0 : PaymentShippingOption::operator=(const PaymentShippingOption& aOther)
1143 : {
1144 0 : mAmount = aOther.mAmount;
1145 0 : mId = aOther.mId;
1146 0 : mLabel = aOther.mLabel;
1147 0 : mSelected = aOther.mSelected;
1148 0 : return *this;
1149 : }
1150 :
1151 : namespace binding_detail {
1152 : } // namespace binding_detail
1153 :
1154 :
1155 :
1156 0 : PaymentDetailsModifier::PaymentDetailsModifier()
1157 0 : : mTotal(FastDictionaryInitializer())
1158 : {
1159 : // Safe to pass a null context if we pass a null value
1160 0 : Init(nullptr, JS::NullHandleValue);
1161 0 : }
1162 :
1163 :
1164 : bool
1165 0 : PaymentDetailsModifier::InitIds(JSContext* cx, PaymentDetailsModifierAtoms* atomsCache)
1166 : {
1167 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1168 :
1169 : // Initialize these in reverse order so that any failure leaves the first one
1170 : // uninitialized.
1171 0 : if (!atomsCache->total_id.init(cx, "total") ||
1172 0 : !atomsCache->supportedMethods_id.init(cx, "supportedMethods") ||
1173 0 : !atomsCache->data_id.init(cx, "data") ||
1174 0 : !atomsCache->additionalDisplayItems_id.init(cx, "additionalDisplayItems")) {
1175 0 : return false;
1176 : }
1177 0 : return true;
1178 : }
1179 :
1180 : bool
1181 0 : PaymentDetailsModifier::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1182 : {
1183 : // Passing a null JSContext is OK only if we're initing from null,
1184 : // Since in that case we will not have to do any property gets
1185 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1186 : // checkers by static analysis tools
1187 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1188 0 : PaymentDetailsModifierAtoms* atomsCache = nullptr;
1189 0 : if (cx) {
1190 0 : atomsCache = GetAtomCache<PaymentDetailsModifierAtoms>(cx);
1191 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1192 0 : return false;
1193 : }
1194 : }
1195 :
1196 0 : if (!IsConvertibleToDictionary(val)) {
1197 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1198 : }
1199 :
1200 0 : bool isNull = val.isNullOrUndefined();
1201 : // We only need these if !isNull, in which case we have |cx|.
1202 0 : Maybe<JS::Rooted<JSObject *> > object;
1203 0 : Maybe<JS::Rooted<JS::Value> > temp;
1204 0 : if (!isNull) {
1205 0 : MOZ_ASSERT(cx);
1206 0 : object.emplace(cx, &val.toObject());
1207 0 : temp.emplace(cx);
1208 : }
1209 0 : if (!isNull) {
1210 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->additionalDisplayItems_id, temp.ptr())) {
1211 0 : return false;
1212 : }
1213 : }
1214 0 : if (!isNull && !temp->isUndefined()) {
1215 0 : mAdditionalDisplayItems.Construct();
1216 0 : if (temp.ref().isObject()) {
1217 0 : JS::ForOfIterator iter(cx);
1218 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1219 0 : return false;
1220 : }
1221 0 : if (!iter.valueIsIterable()) {
1222 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'additionalDisplayItems' member of PaymentDetailsModifier");
1223 0 : return false;
1224 : }
1225 0 : Sequence<PaymentItem> &arr = (mAdditionalDisplayItems.Value());
1226 0 : JS::Rooted<JS::Value> temp(cx);
1227 : while (true) {
1228 : bool done;
1229 0 : if (!iter.next(&temp, &done)) {
1230 0 : return false;
1231 : }
1232 0 : if (done) {
1233 0 : break;
1234 : }
1235 0 : PaymentItem* slotPtr = arr.AppendElement(mozilla::fallible);
1236 0 : if (!slotPtr) {
1237 0 : JS_ReportOutOfMemory(cx);
1238 0 : return false;
1239 : }
1240 0 : PaymentItem& slot = *slotPtr;
1241 0 : if (!slot.Init(cx, temp, "Element of 'additionalDisplayItems' member of PaymentDetailsModifier", passedToJSImpl)) {
1242 0 : return false;
1243 : }
1244 0 : }
1245 : } else {
1246 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'additionalDisplayItems' member of PaymentDetailsModifier");
1247 0 : return false;
1248 : }
1249 0 : mIsAnyMemberPresent = true;
1250 : }
1251 :
1252 0 : if (!isNull) {
1253 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
1254 0 : return false;
1255 : }
1256 : }
1257 0 : if (!isNull && !temp->isUndefined()) {
1258 0 : mData.Construct();
1259 0 : if (temp.ref().isObject()) {
1260 : #ifdef __clang__
1261 : #pragma clang diagnostic push
1262 : #pragma clang diagnostic ignored "-Wunreachable-code"
1263 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
1264 : #endif // __clang__
1265 0 : if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
1266 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'data' member of PaymentDetailsModifier");
1267 0 : return false;
1268 : }
1269 : #ifdef __clang__
1270 : #pragma clang diagnostic pop
1271 : #endif // __clang__
1272 0 : (mData.Value()) = &temp.ref().toObject();
1273 : } else {
1274 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'data' member of PaymentDetailsModifier");
1275 0 : return false;
1276 : }
1277 0 : mIsAnyMemberPresent = true;
1278 : }
1279 :
1280 0 : if (!isNull) {
1281 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->supportedMethods_id, temp.ptr())) {
1282 0 : return false;
1283 : }
1284 : }
1285 0 : if (!isNull && !temp->isUndefined()) {
1286 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mSupportedMethods)) {
1287 0 : return false;
1288 : }
1289 0 : mIsAnyMemberPresent = true;
1290 0 : } else if (cx) {
1291 : // Don't error out if we have no cx. In that
1292 : // situation the caller is default-constructing us and we'll
1293 : // just assume they know what they're doing.
1294 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1295 0 : "'supportedMethods' member of PaymentDetailsModifier");
1296 : }
1297 :
1298 0 : if (!isNull) {
1299 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->total_id, temp.ptr())) {
1300 0 : return false;
1301 : }
1302 : }
1303 0 : if (!mTotal.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'total' member of PaymentDetailsModifier", passedToJSImpl)) {
1304 0 : return false;
1305 : }
1306 0 : mIsAnyMemberPresent = true;
1307 0 : return true;
1308 : }
1309 :
1310 : bool
1311 0 : PaymentDetailsModifier::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1312 : {
1313 0 : PaymentDetailsModifierAtoms* atomsCache = GetAtomCache<PaymentDetailsModifierAtoms>(cx);
1314 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1315 0 : return false;
1316 : }
1317 :
1318 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1319 0 : if (!obj) {
1320 0 : return false;
1321 : }
1322 0 : rval.set(JS::ObjectValue(*obj));
1323 :
1324 0 : if (mAdditionalDisplayItems.WasPassed()) {
1325 : do {
1326 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1327 0 : JS::Rooted<JS::Value> temp(cx);
1328 0 : Sequence<PaymentItem> const & currentValue = mAdditionalDisplayItems.InternalValue();
1329 :
1330 0 : uint32_t length = currentValue.Length();
1331 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1332 0 : if (!returnArray) {
1333 0 : return false;
1334 : }
1335 : // Scope for 'tmp'
1336 : {
1337 0 : JS::Rooted<JS::Value> tmp(cx);
1338 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1339 : // Control block to let us common up the JS_DefineElement calls when there
1340 : // are different ways to succeed at wrapping the object.
1341 : do {
1342 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
1343 0 : return false;
1344 : }
1345 0 : break;
1346 : } while (0);
1347 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1348 : JSPROP_ENUMERATE)) {
1349 0 : return false;
1350 : }
1351 : }
1352 : }
1353 0 : temp.setObject(*returnArray);
1354 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->additionalDisplayItems_id, temp, JSPROP_ENUMERATE)) {
1355 0 : return false;
1356 : }
1357 0 : break;
1358 : } while(0);
1359 : }
1360 :
1361 0 : if (mData.WasPassed()) {
1362 : do {
1363 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1364 0 : JS::Rooted<JS::Value> temp(cx);
1365 0 : JSObject* const & currentValue = mData.InternalValue();
1366 0 : JS::ExposeObjectToActiveJS(currentValue);
1367 0 : temp.setObject(*currentValue);
1368 0 : if (!MaybeWrapObjectValue(cx, &temp)) {
1369 0 : return false;
1370 : }
1371 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
1372 0 : return false;
1373 : }
1374 0 : break;
1375 : } while(0);
1376 : }
1377 :
1378 : do {
1379 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1380 0 : JS::Rooted<JS::Value> temp(cx);
1381 0 : nsString const & currentValue = mSupportedMethods;
1382 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1383 0 : return false;
1384 : }
1385 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->supportedMethods_id, temp, JSPROP_ENUMERATE)) {
1386 0 : return false;
1387 : }
1388 0 : break;
1389 : } while(0);
1390 :
1391 : do {
1392 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1393 0 : JS::Rooted<JS::Value> temp(cx);
1394 0 : PaymentItem const & currentValue = mTotal;
1395 0 : if (!currentValue.ToObjectInternal(cx, &temp)) {
1396 0 : return false;
1397 : }
1398 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->total_id, temp, JSPROP_ENUMERATE)) {
1399 0 : return false;
1400 : }
1401 0 : break;
1402 : } while(0);
1403 :
1404 0 : return true;
1405 : }
1406 :
1407 : void
1408 0 : PaymentDetailsModifier::TraceDictionary(JSTracer* trc)
1409 : {
1410 0 : if (mData.WasPassed()) {
1411 0 : JS::UnsafeTraceRoot(trc, &mData.Value(), "PaymentDetailsModifier.mData");
1412 : }
1413 0 : }
1414 :
1415 : namespace binding_detail {
1416 : } // namespace binding_detail
1417 :
1418 :
1419 :
1420 0 : PaymentDetailsBase::PaymentDetailsBase()
1421 : {
1422 : // Safe to pass a null context if we pass a null value
1423 0 : Init(nullptr, JS::NullHandleValue);
1424 0 : }
1425 :
1426 :
1427 : bool
1428 0 : PaymentDetailsBase::InitIds(JSContext* cx, PaymentDetailsBaseAtoms* atomsCache)
1429 : {
1430 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1431 :
1432 : // Initialize these in reverse order so that any failure leaves the first one
1433 : // uninitialized.
1434 0 : if (!atomsCache->shippingOptions_id.init(cx, "shippingOptions") ||
1435 0 : !atomsCache->modifiers_id.init(cx, "modifiers") ||
1436 0 : !atomsCache->displayItems_id.init(cx, "displayItems")) {
1437 0 : return false;
1438 : }
1439 0 : return true;
1440 : }
1441 :
1442 : bool
1443 0 : PaymentDetailsBase::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1444 : {
1445 : // Passing a null JSContext is OK only if we're initing from null,
1446 : // Since in that case we will not have to do any property gets
1447 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1448 : // checkers by static analysis tools
1449 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1450 0 : PaymentDetailsBaseAtoms* atomsCache = nullptr;
1451 0 : if (cx) {
1452 0 : atomsCache = GetAtomCache<PaymentDetailsBaseAtoms>(cx);
1453 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1454 0 : return false;
1455 : }
1456 : }
1457 :
1458 0 : if (!IsConvertibleToDictionary(val)) {
1459 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1460 : }
1461 :
1462 0 : bool isNull = val.isNullOrUndefined();
1463 : // We only need these if !isNull, in which case we have |cx|.
1464 0 : Maybe<JS::Rooted<JSObject *> > object;
1465 0 : Maybe<JS::Rooted<JS::Value> > temp;
1466 0 : if (!isNull) {
1467 0 : MOZ_ASSERT(cx);
1468 0 : object.emplace(cx, &val.toObject());
1469 0 : temp.emplace(cx);
1470 : }
1471 0 : if (!isNull) {
1472 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->displayItems_id, temp.ptr())) {
1473 0 : return false;
1474 : }
1475 : }
1476 0 : if (!isNull && !temp->isUndefined()) {
1477 0 : mDisplayItems.Construct();
1478 0 : if (temp.ref().isObject()) {
1479 0 : JS::ForOfIterator iter(cx);
1480 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1481 0 : return false;
1482 : }
1483 0 : if (!iter.valueIsIterable()) {
1484 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'displayItems' member of PaymentDetailsBase");
1485 0 : return false;
1486 : }
1487 0 : Sequence<PaymentItem> &arr = (mDisplayItems.Value());
1488 0 : JS::Rooted<JS::Value> temp(cx);
1489 : while (true) {
1490 : bool done;
1491 0 : if (!iter.next(&temp, &done)) {
1492 0 : return false;
1493 : }
1494 0 : if (done) {
1495 0 : break;
1496 : }
1497 0 : PaymentItem* slotPtr = arr.AppendElement(mozilla::fallible);
1498 0 : if (!slotPtr) {
1499 0 : JS_ReportOutOfMemory(cx);
1500 0 : return false;
1501 : }
1502 0 : PaymentItem& slot = *slotPtr;
1503 0 : if (!slot.Init(cx, temp, "Element of 'displayItems' member of PaymentDetailsBase", passedToJSImpl)) {
1504 0 : return false;
1505 : }
1506 0 : }
1507 : } else {
1508 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'displayItems' member of PaymentDetailsBase");
1509 0 : return false;
1510 : }
1511 0 : mIsAnyMemberPresent = true;
1512 : }
1513 :
1514 0 : if (!isNull) {
1515 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->modifiers_id, temp.ptr())) {
1516 0 : return false;
1517 : }
1518 : }
1519 0 : if (!isNull && !temp->isUndefined()) {
1520 0 : mModifiers.Construct();
1521 0 : if (temp.ref().isObject()) {
1522 0 : JS::ForOfIterator iter(cx);
1523 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1524 0 : return false;
1525 : }
1526 0 : if (!iter.valueIsIterable()) {
1527 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'modifiers' member of PaymentDetailsBase");
1528 0 : return false;
1529 : }
1530 0 : Sequence<PaymentDetailsModifier> &arr = (mModifiers.Value());
1531 0 : JS::Rooted<JS::Value> temp(cx);
1532 : while (true) {
1533 : bool done;
1534 0 : if (!iter.next(&temp, &done)) {
1535 0 : return false;
1536 : }
1537 0 : if (done) {
1538 0 : break;
1539 : }
1540 0 : PaymentDetailsModifier* slotPtr = arr.AppendElement(mozilla::fallible);
1541 0 : if (!slotPtr) {
1542 0 : JS_ReportOutOfMemory(cx);
1543 0 : return false;
1544 : }
1545 0 : PaymentDetailsModifier& slot = *slotPtr;
1546 0 : if (!slot.Init(cx, temp, "Element of 'modifiers' member of PaymentDetailsBase", passedToJSImpl)) {
1547 0 : return false;
1548 : }
1549 0 : }
1550 : } else {
1551 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'modifiers' member of PaymentDetailsBase");
1552 0 : return false;
1553 : }
1554 0 : mIsAnyMemberPresent = true;
1555 : }
1556 :
1557 0 : if (!isNull) {
1558 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->shippingOptions_id, temp.ptr())) {
1559 0 : return false;
1560 : }
1561 : }
1562 0 : if (!isNull && !temp->isUndefined()) {
1563 0 : mShippingOptions.Construct();
1564 0 : if (temp.ref().isObject()) {
1565 0 : JS::ForOfIterator iter(cx);
1566 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1567 0 : return false;
1568 : }
1569 0 : if (!iter.valueIsIterable()) {
1570 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'shippingOptions' member of PaymentDetailsBase");
1571 0 : return false;
1572 : }
1573 0 : Sequence<PaymentShippingOption> &arr = (mShippingOptions.Value());
1574 0 : JS::Rooted<JS::Value> temp(cx);
1575 : while (true) {
1576 : bool done;
1577 0 : if (!iter.next(&temp, &done)) {
1578 0 : return false;
1579 : }
1580 0 : if (done) {
1581 0 : break;
1582 : }
1583 0 : PaymentShippingOption* slotPtr = arr.AppendElement(mozilla::fallible);
1584 0 : if (!slotPtr) {
1585 0 : JS_ReportOutOfMemory(cx);
1586 0 : return false;
1587 : }
1588 0 : PaymentShippingOption& slot = *slotPtr;
1589 0 : if (!slot.Init(cx, temp, "Element of 'shippingOptions' member of PaymentDetailsBase", passedToJSImpl)) {
1590 0 : return false;
1591 : }
1592 0 : }
1593 : } else {
1594 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'shippingOptions' member of PaymentDetailsBase");
1595 0 : return false;
1596 : }
1597 0 : mIsAnyMemberPresent = true;
1598 : }
1599 0 : return true;
1600 : }
1601 :
1602 : bool
1603 0 : PaymentDetailsBase::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1604 : {
1605 0 : PaymentDetailsBaseAtoms* atomsCache = GetAtomCache<PaymentDetailsBaseAtoms>(cx);
1606 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1607 0 : return false;
1608 : }
1609 :
1610 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1611 0 : if (!obj) {
1612 0 : return false;
1613 : }
1614 0 : rval.set(JS::ObjectValue(*obj));
1615 :
1616 0 : if (mDisplayItems.WasPassed()) {
1617 : do {
1618 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1619 0 : JS::Rooted<JS::Value> temp(cx);
1620 0 : Sequence<PaymentItem> const & currentValue = mDisplayItems.InternalValue();
1621 :
1622 0 : uint32_t length = currentValue.Length();
1623 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1624 0 : if (!returnArray) {
1625 0 : return false;
1626 : }
1627 : // Scope for 'tmp'
1628 : {
1629 0 : JS::Rooted<JS::Value> tmp(cx);
1630 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1631 : // Control block to let us common up the JS_DefineElement calls when there
1632 : // are different ways to succeed at wrapping the object.
1633 : do {
1634 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
1635 0 : return false;
1636 : }
1637 0 : break;
1638 : } while (0);
1639 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1640 : JSPROP_ENUMERATE)) {
1641 0 : return false;
1642 : }
1643 : }
1644 : }
1645 0 : temp.setObject(*returnArray);
1646 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->displayItems_id, temp, JSPROP_ENUMERATE)) {
1647 0 : return false;
1648 : }
1649 0 : break;
1650 : } while(0);
1651 : }
1652 :
1653 0 : if (mModifiers.WasPassed()) {
1654 : do {
1655 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1656 0 : JS::Rooted<JS::Value> temp(cx);
1657 0 : Sequence<PaymentDetailsModifier> const & currentValue = mModifiers.InternalValue();
1658 :
1659 0 : uint32_t length = currentValue.Length();
1660 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1661 0 : if (!returnArray) {
1662 0 : return false;
1663 : }
1664 : // Scope for 'tmp'
1665 : {
1666 0 : JS::Rooted<JS::Value> tmp(cx);
1667 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1668 : // Control block to let us common up the JS_DefineElement calls when there
1669 : // are different ways to succeed at wrapping the object.
1670 : do {
1671 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
1672 0 : return false;
1673 : }
1674 0 : break;
1675 : } while (0);
1676 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1677 : JSPROP_ENUMERATE)) {
1678 0 : return false;
1679 : }
1680 : }
1681 : }
1682 0 : temp.setObject(*returnArray);
1683 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->modifiers_id, temp, JSPROP_ENUMERATE)) {
1684 0 : return false;
1685 : }
1686 0 : break;
1687 : } while(0);
1688 : }
1689 :
1690 0 : if (mShippingOptions.WasPassed()) {
1691 : do {
1692 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1693 0 : JS::Rooted<JS::Value> temp(cx);
1694 0 : Sequence<PaymentShippingOption> const & currentValue = mShippingOptions.InternalValue();
1695 :
1696 0 : uint32_t length = currentValue.Length();
1697 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1698 0 : if (!returnArray) {
1699 0 : return false;
1700 : }
1701 : // Scope for 'tmp'
1702 : {
1703 0 : JS::Rooted<JS::Value> tmp(cx);
1704 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1705 : // Control block to let us common up the JS_DefineElement calls when there
1706 : // are different ways to succeed at wrapping the object.
1707 : do {
1708 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
1709 0 : return false;
1710 : }
1711 0 : break;
1712 : } while (0);
1713 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1714 : JSPROP_ENUMERATE)) {
1715 0 : return false;
1716 : }
1717 : }
1718 : }
1719 0 : temp.setObject(*returnArray);
1720 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->shippingOptions_id, temp, JSPROP_ENUMERATE)) {
1721 0 : return false;
1722 : }
1723 0 : break;
1724 : } while(0);
1725 : }
1726 :
1727 0 : return true;
1728 : }
1729 :
1730 : void
1731 0 : PaymentDetailsBase::TraceDictionary(JSTracer* trc)
1732 : {
1733 0 : if (mModifiers.WasPassed()) {
1734 0 : DoTraceSequence(trc, mModifiers.Value());
1735 : }
1736 0 : }
1737 :
1738 : namespace binding_detail {
1739 : } // namespace binding_detail
1740 :
1741 :
1742 :
1743 0 : PaymentDetailsInit::PaymentDetailsInit()
1744 0 : : PaymentDetailsBase(FastDictionaryInitializer()),
1745 0 : mTotal(FastDictionaryInitializer())
1746 : {
1747 : // Safe to pass a null context if we pass a null value
1748 0 : Init(nullptr, JS::NullHandleValue);
1749 0 : }
1750 :
1751 :
1752 : bool
1753 0 : PaymentDetailsInit::InitIds(JSContext* cx, PaymentDetailsInitAtoms* atomsCache)
1754 : {
1755 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1756 :
1757 : // Initialize these in reverse order so that any failure leaves the first one
1758 : // uninitialized.
1759 0 : if (!atomsCache->total_id.init(cx, "total") ||
1760 0 : !atomsCache->id_id.init(cx, "id")) {
1761 0 : return false;
1762 : }
1763 0 : return true;
1764 : }
1765 :
1766 : bool
1767 0 : PaymentDetailsInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1768 : {
1769 : // Passing a null JSContext is OK only if we're initing from null,
1770 : // Since in that case we will not have to do any property gets
1771 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1772 : // checkers by static analysis tools
1773 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1774 0 : PaymentDetailsInitAtoms* atomsCache = nullptr;
1775 0 : if (cx) {
1776 0 : atomsCache = GetAtomCache<PaymentDetailsInitAtoms>(cx);
1777 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1778 0 : return false;
1779 : }
1780 : }
1781 :
1782 : // Per spec, we init the parent's members first
1783 0 : if (!PaymentDetailsBase::Init(cx, val)) {
1784 0 : return false;
1785 : }
1786 :
1787 0 : bool isNull = val.isNullOrUndefined();
1788 : // We only need these if !isNull, in which case we have |cx|.
1789 0 : Maybe<JS::Rooted<JSObject *> > object;
1790 0 : Maybe<JS::Rooted<JS::Value> > temp;
1791 0 : if (!isNull) {
1792 0 : MOZ_ASSERT(cx);
1793 0 : object.emplace(cx, &val.toObject());
1794 0 : temp.emplace(cx);
1795 : }
1796 0 : if (!isNull) {
1797 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
1798 0 : return false;
1799 : }
1800 : }
1801 0 : if (!isNull && !temp->isUndefined()) {
1802 0 : mId.Construct();
1803 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mId.Value()))) {
1804 0 : return false;
1805 : }
1806 0 : mIsAnyMemberPresent = true;
1807 : }
1808 :
1809 0 : if (!isNull) {
1810 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->total_id, temp.ptr())) {
1811 0 : return false;
1812 : }
1813 : }
1814 0 : if (!isNull && !temp->isUndefined()) {
1815 0 : if (!mTotal.Init(cx, temp.ref(), "'total' member of PaymentDetailsInit", passedToJSImpl)) {
1816 0 : return false;
1817 : }
1818 0 : mIsAnyMemberPresent = true;
1819 0 : } else if (cx) {
1820 : // Don't error out if we have no cx. In that
1821 : // situation the caller is default-constructing us and we'll
1822 : // just assume they know what they're doing.
1823 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1824 0 : "'total' member of PaymentDetailsInit");
1825 : }
1826 0 : return true;
1827 : }
1828 :
1829 : bool
1830 0 : PaymentDetailsInit::Init(const nsAString& aJSON)
1831 : {
1832 0 : AutoJSAPI jsapi;
1833 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1834 0 : if (!cleanGlobal) {
1835 0 : return false;
1836 : }
1837 0 : if (!jsapi.Init(cleanGlobal)) {
1838 0 : return false;
1839 : }
1840 0 : JSContext* cx = jsapi.cx();
1841 0 : JS::Rooted<JS::Value> json(cx);
1842 0 : bool ok = ParseJSON(cx, aJSON, &json);
1843 0 : NS_ENSURE_TRUE(ok, false);
1844 0 : return Init(cx, json);
1845 : }
1846 :
1847 : bool
1848 0 : PaymentDetailsInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1849 : {
1850 0 : PaymentDetailsInitAtoms* atomsCache = GetAtomCache<PaymentDetailsInitAtoms>(cx);
1851 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1852 0 : return false;
1853 : }
1854 :
1855 : // Per spec, we define the parent's members first
1856 0 : if (!PaymentDetailsBase::ToObjectInternal(cx, rval)) {
1857 0 : return false;
1858 : }
1859 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1860 :
1861 0 : if (mId.WasPassed()) {
1862 : do {
1863 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1864 0 : JS::Rooted<JS::Value> temp(cx);
1865 0 : nsString const & currentValue = mId.InternalValue();
1866 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1867 0 : return false;
1868 : }
1869 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
1870 0 : return false;
1871 : }
1872 0 : break;
1873 : } while(0);
1874 : }
1875 :
1876 : do {
1877 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1878 0 : JS::Rooted<JS::Value> temp(cx);
1879 0 : PaymentItem const & currentValue = mTotal;
1880 0 : if (!currentValue.ToObjectInternal(cx, &temp)) {
1881 0 : return false;
1882 : }
1883 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->total_id, temp, JSPROP_ENUMERATE)) {
1884 0 : return false;
1885 : }
1886 0 : break;
1887 : } while(0);
1888 :
1889 0 : return true;
1890 : }
1891 :
1892 : bool
1893 0 : PaymentDetailsInit::ToJSON(nsAString& aJSON) const
1894 : {
1895 0 : AutoJSAPI jsapi;
1896 0 : jsapi.Init();
1897 0 : JSContext *cx = jsapi.cx();
1898 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1899 : // because we'll only be creating objects, in ways that have no
1900 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1901 : // which likewise guarantees no side-effects for the sorts of
1902 : // things we will pass it.
1903 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1904 0 : JS::Rooted<JS::Value> val(cx);
1905 0 : if (!ToObjectInternal(cx, &val)) {
1906 0 : return false;
1907 : }
1908 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1909 0 : return StringifyToJSON(cx, obj, aJSON);
1910 : }
1911 :
1912 : void
1913 0 : PaymentDetailsInit::TraceDictionary(JSTracer* trc)
1914 : {
1915 0 : PaymentDetailsBase::TraceDictionary(trc);
1916 0 : }
1917 :
1918 : namespace binding_detail {
1919 : } // namespace binding_detail
1920 :
1921 :
1922 : namespace PaymentRequestBinding {
1923 :
1924 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
1925 : "Can't inherit from an interface with a different ownership model.");
1926 :
1927 : static bool
1928 0 : show(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
1929 : {
1930 0 : binding_detail::FastErrorResult rv;
1931 0 : auto result(StrongOrRawPtr<Promise>(self->Show(rv)));
1932 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1933 0 : return false;
1934 : }
1935 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1936 : static_assert(!IsPointer<decltype(result)>::value,
1937 : "NewObject implies that we need to keep the object alive with a strong reference.");
1938 0 : if (!ToJSValue(cx, result, args.rval())) {
1939 0 : return false;
1940 : }
1941 0 : return true;
1942 : }
1943 :
1944 : static bool
1945 0 : show_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
1946 : {
1947 : // Make sure to save the callee before someone maybe messes
1948 : // with rval().
1949 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1950 0 : bool ok = show(cx, obj, self, args);
1951 0 : if (ok) {
1952 0 : return true;
1953 : }
1954 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
1955 0 : args.rval());
1956 : }
1957 :
1958 : static const JSJitInfo show_methodinfo = {
1959 : { (JSJitGetterOp)show_promiseWrapper },
1960 : { prototypes::id::PaymentRequest },
1961 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
1962 : JSJitInfo::Method,
1963 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1964 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1965 : false, /* isInfallible. False in setters. */
1966 : false, /* isMovable. Not relevant for setters. */
1967 : false, /* isEliminatable. Not relevant for setters. */
1968 : false, /* isAlwaysInSlot. Only relevant for getters. */
1969 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1970 : false, /* isTypedMethod. Only relevant for methods. */
1971 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1972 : };
1973 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1974 : static_assert(0 < 1, "There is no slot for us");
1975 :
1976 : static bool
1977 0 : abort(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
1978 : {
1979 0 : binding_detail::FastErrorResult rv;
1980 0 : auto result(StrongOrRawPtr<Promise>(self->Abort(rv)));
1981 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1982 0 : return false;
1983 : }
1984 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1985 : static_assert(!IsPointer<decltype(result)>::value,
1986 : "NewObject implies that we need to keep the object alive with a strong reference.");
1987 0 : if (!ToJSValue(cx, result, args.rval())) {
1988 0 : return false;
1989 : }
1990 0 : return true;
1991 : }
1992 :
1993 : static bool
1994 0 : abort_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
1995 : {
1996 : // Make sure to save the callee before someone maybe messes
1997 : // with rval().
1998 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1999 0 : bool ok = abort(cx, obj, self, args);
2000 0 : if (ok) {
2001 0 : return true;
2002 : }
2003 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
2004 0 : args.rval());
2005 : }
2006 :
2007 : static const JSJitInfo abort_methodinfo = {
2008 : { (JSJitGetterOp)abort_promiseWrapper },
2009 : { prototypes::id::PaymentRequest },
2010 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2011 : JSJitInfo::Method,
2012 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2013 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2014 : false, /* isInfallible. False in setters. */
2015 : false, /* isMovable. Not relevant for setters. */
2016 : false, /* isEliminatable. Not relevant for setters. */
2017 : false, /* isAlwaysInSlot. Only relevant for getters. */
2018 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2019 : false, /* isTypedMethod. Only relevant for methods. */
2020 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2021 : };
2022 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2023 : static_assert(0 < 1, "There is no slot for us");
2024 :
2025 : static bool
2026 0 : canMakePayment(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
2027 : {
2028 0 : binding_detail::FastErrorResult rv;
2029 0 : auto result(StrongOrRawPtr<Promise>(self->CanMakePayment(rv)));
2030 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2031 0 : return false;
2032 : }
2033 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2034 : static_assert(!IsPointer<decltype(result)>::value,
2035 : "NewObject implies that we need to keep the object alive with a strong reference.");
2036 0 : if (!ToJSValue(cx, result, args.rval())) {
2037 0 : return false;
2038 : }
2039 0 : return true;
2040 : }
2041 :
2042 : static bool
2043 0 : canMakePayment_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
2044 : {
2045 : // Make sure to save the callee before someone maybe messes
2046 : // with rval().
2047 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
2048 0 : bool ok = canMakePayment(cx, obj, self, args);
2049 0 : if (ok) {
2050 0 : return true;
2051 : }
2052 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
2053 0 : args.rval());
2054 : }
2055 :
2056 : static const JSJitInfo canMakePayment_methodinfo = {
2057 : { (JSJitGetterOp)canMakePayment_promiseWrapper },
2058 : { prototypes::id::PaymentRequest },
2059 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2060 : JSJitInfo::Method,
2061 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2062 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2063 : false, /* isInfallible. False in setters. */
2064 : false, /* isMovable. Not relevant for setters. */
2065 : false, /* isEliminatable. Not relevant for setters. */
2066 : false, /* isAlwaysInSlot. Only relevant for getters. */
2067 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2068 : false, /* isTypedMethod. Only relevant for methods. */
2069 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2070 : };
2071 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2072 : static_assert(0 < 1, "There is no slot for us");
2073 :
2074 : static bool
2075 0 : get_id(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
2076 : {
2077 0 : DOMString result;
2078 0 : self->GetId(result);
2079 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2080 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
2081 0 : return false;
2082 : }
2083 0 : return true;
2084 : }
2085 :
2086 : static const JSJitInfo id_getterinfo = {
2087 : { (JSJitGetterOp)get_id },
2088 : { prototypes::id::PaymentRequest },
2089 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2090 : JSJitInfo::Getter,
2091 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2092 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
2093 : false, /* isInfallible. False in setters. */
2094 : false, /* isMovable. Not relevant for setters. */
2095 : false, /* isEliminatable. Not relevant for setters. */
2096 : false, /* isAlwaysInSlot. Only relevant for getters. */
2097 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2098 : false, /* isTypedMethod. Only relevant for methods. */
2099 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2100 : };
2101 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2102 : static_assert(0 < 1, "There is no slot for us");
2103 :
2104 : static bool
2105 0 : get_shippingAddress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
2106 : {
2107 0 : auto result(StrongOrRawPtr<mozilla::dom::PaymentAddress>(self->GetShippingAddress()));
2108 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2109 0 : if (!result) {
2110 0 : args.rval().setNull();
2111 0 : return true;
2112 : }
2113 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
2114 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
2115 0 : return false;
2116 : }
2117 0 : return true;
2118 : }
2119 :
2120 : static const JSJitInfo shippingAddress_getterinfo = {
2121 : { (JSJitGetterOp)get_shippingAddress },
2122 : { prototypes::id::PaymentRequest },
2123 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2124 : JSJitInfo::Getter,
2125 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2126 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
2127 : false, /* isInfallible. False in setters. */
2128 : false, /* isMovable. Not relevant for setters. */
2129 : false, /* isEliminatable. Not relevant for setters. */
2130 : false, /* isAlwaysInSlot. Only relevant for getters. */
2131 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2132 : false, /* isTypedMethod. Only relevant for methods. */
2133 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2134 : };
2135 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2136 : static_assert(0 < 1, "There is no slot for us");
2137 :
2138 : static bool
2139 0 : get_shippingOption(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
2140 : {
2141 0 : DOMString result;
2142 0 : self->GetShippingOption(result);
2143 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2144 0 : if (!xpc::StringToJsval(cx, result, args.rval())) {
2145 0 : return false;
2146 : }
2147 0 : return true;
2148 : }
2149 :
2150 : static const JSJitInfo shippingOption_getterinfo = {
2151 : { (JSJitGetterOp)get_shippingOption },
2152 : { prototypes::id::PaymentRequest },
2153 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2154 : JSJitInfo::Getter,
2155 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2156 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
2157 : false, /* isInfallible. False in setters. */
2158 : false, /* isMovable. Not relevant for setters. */
2159 : false, /* isEliminatable. Not relevant for setters. */
2160 : false, /* isAlwaysInSlot. Only relevant for getters. */
2161 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2162 : false, /* isTypedMethod. Only relevant for methods. */
2163 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2164 : };
2165 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2166 : static_assert(0 < 1, "There is no slot for us");
2167 :
2168 : static bool
2169 0 : get_shippingType(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
2170 : {
2171 0 : Nullable<PaymentShippingType> result(self->GetShippingType());
2172 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2173 0 : if (result.IsNull()) {
2174 0 : args.rval().setNull();
2175 0 : return true;
2176 : } else {
2177 0 : if (!ToJSValue(cx, result.Value(), args.rval())) {
2178 0 : return false;
2179 : }
2180 0 : return true;
2181 : }
2182 : }
2183 :
2184 : static const JSJitInfo shippingType_getterinfo = {
2185 : { (JSJitGetterOp)get_shippingType },
2186 : { prototypes::id::PaymentRequest },
2187 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2188 : JSJitInfo::Getter,
2189 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2190 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
2191 : false, /* isInfallible. False in setters. */
2192 : false, /* isMovable. Not relevant for setters. */
2193 : false, /* isEliminatable. Not relevant for setters. */
2194 : false, /* isAlwaysInSlot. Only relevant for getters. */
2195 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2196 : false, /* isTypedMethod. Only relevant for methods. */
2197 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2198 : };
2199 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2200 : static_assert(0 < 1, "There is no slot for us");
2201 :
2202 : static bool
2203 0 : get_onshippingaddresschange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
2204 : {
2205 0 : RefPtr<EventHandlerNonNull> result(self->GetOnshippingaddresschange());
2206 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2207 0 : if (result) {
2208 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
2209 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
2210 0 : return false;
2211 : }
2212 0 : return true;
2213 : } else {
2214 0 : args.rval().setNull();
2215 0 : return true;
2216 : }
2217 : }
2218 :
2219 : static bool
2220 0 : set_onshippingaddresschange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitSetterCallArgs args)
2221 : {
2222 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
2223 0 : if (args[0].isObject()) {
2224 : { // scope for tempRoot
2225 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
2226 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
2227 : }
2228 : } else {
2229 0 : arg0 = nullptr;
2230 : }
2231 0 : self->SetOnshippingaddresschange(Constify(arg0));
2232 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2233 :
2234 0 : return true;
2235 : }
2236 :
2237 : static const JSJitInfo onshippingaddresschange_getterinfo = {
2238 : { (JSJitGetterOp)get_onshippingaddresschange },
2239 : { prototypes::id::PaymentRequest },
2240 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2241 : JSJitInfo::Getter,
2242 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2243 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
2244 : false, /* isInfallible. False in setters. */
2245 : false, /* isMovable. Not relevant for setters. */
2246 : false, /* isEliminatable. Not relevant for setters. */
2247 : false, /* isAlwaysInSlot. Only relevant for getters. */
2248 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2249 : false, /* isTypedMethod. Only relevant for methods. */
2250 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2251 : };
2252 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2253 : static_assert(0 < 1, "There is no slot for us");
2254 : static const JSJitInfo onshippingaddresschange_setterinfo = {
2255 : { (JSJitGetterOp)set_onshippingaddresschange },
2256 : { prototypes::id::PaymentRequest },
2257 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2258 : JSJitInfo::Setter,
2259 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2260 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
2261 : false, /* isInfallible. False in setters. */
2262 : false, /* isMovable. Not relevant for setters. */
2263 : false, /* isEliminatable. Not relevant for setters. */
2264 : false, /* isAlwaysInSlot. Only relevant for getters. */
2265 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2266 : false, /* isTypedMethod. Only relevant for methods. */
2267 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2268 : };
2269 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2270 : static_assert(0 < 1, "There is no slot for us");
2271 :
2272 : static bool
2273 0 : get_onshippingoptionchange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
2274 : {
2275 0 : RefPtr<EventHandlerNonNull> result(self->GetOnshippingoptionchange());
2276 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2277 0 : if (result) {
2278 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
2279 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
2280 0 : return false;
2281 : }
2282 0 : return true;
2283 : } else {
2284 0 : args.rval().setNull();
2285 0 : return true;
2286 : }
2287 : }
2288 :
2289 : static bool
2290 0 : set_onshippingoptionchange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitSetterCallArgs args)
2291 : {
2292 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
2293 0 : if (args[0].isObject()) {
2294 : { // scope for tempRoot
2295 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
2296 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
2297 : }
2298 : } else {
2299 0 : arg0 = nullptr;
2300 : }
2301 0 : self->SetOnshippingoptionchange(Constify(arg0));
2302 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2303 :
2304 0 : return true;
2305 : }
2306 :
2307 : static const JSJitInfo onshippingoptionchange_getterinfo = {
2308 : { (JSJitGetterOp)get_onshippingoptionchange },
2309 : { prototypes::id::PaymentRequest },
2310 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2311 : JSJitInfo::Getter,
2312 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2313 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
2314 : false, /* isInfallible. False in setters. */
2315 : false, /* isMovable. Not relevant for setters. */
2316 : false, /* isEliminatable. Not relevant for setters. */
2317 : false, /* isAlwaysInSlot. Only relevant for getters. */
2318 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2319 : false, /* isTypedMethod. Only relevant for methods. */
2320 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2321 : };
2322 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2323 : static_assert(0 < 1, "There is no slot for us");
2324 : static const JSJitInfo onshippingoptionchange_setterinfo = {
2325 : { (JSJitGetterOp)set_onshippingoptionchange },
2326 : { prototypes::id::PaymentRequest },
2327 : { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
2328 : JSJitInfo::Setter,
2329 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2330 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
2331 : false, /* isInfallible. False in setters. */
2332 : false, /* isMovable. Not relevant for setters. */
2333 : false, /* isEliminatable. Not relevant for setters. */
2334 : false, /* isAlwaysInSlot. Only relevant for getters. */
2335 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2336 : false, /* isTypedMethod. Only relevant for methods. */
2337 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2338 : };
2339 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2340 : static_assert(0 < 1, "There is no slot for us");
2341 :
2342 : static bool
2343 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
2344 : {
2345 0 : mozilla::dom::PaymentRequest* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PaymentRequest>(obj);
2346 : // We don't want to preserve if we don't have a wrapper, and we
2347 : // obviously can't preserve if we're not initialized.
2348 0 : if (self && self->GetWrapperPreserveColor()) {
2349 0 : PreserveWrapper(self);
2350 : }
2351 0 : return true;
2352 : }
2353 :
2354 : static void
2355 0 : _finalize(js::FreeOp* fop, JSObject* obj)
2356 : {
2357 0 : mozilla::dom::PaymentRequest* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PaymentRequest>(obj);
2358 0 : if (self) {
2359 0 : ClearWrapper(self, self, obj);
2360 0 : AddForDeferredFinalization<mozilla::dom::PaymentRequest>(self);
2361 : }
2362 0 : }
2363 :
2364 : static void
2365 0 : _objectMoved(JSObject* obj, const JSObject* old)
2366 : {
2367 0 : mozilla::dom::PaymentRequest* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PaymentRequest>(obj);
2368 0 : if (self) {
2369 0 : UpdateWrapper(self, self, obj, old);
2370 : }
2371 0 : }
2372 :
2373 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2374 : #if defined(__clang__)
2375 : #pragma clang diagnostic push
2376 : #pragma clang diagnostic ignored "-Wmissing-braces"
2377 : #endif
2378 : static const JSFunctionSpec sMethods_specs[] = {
2379 : JS_FNSPEC("show", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&show_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
2380 : JS_FNSPEC("abort", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&abort_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
2381 : JS_FNSPEC("canMakePayment", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&canMakePayment_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
2382 : JS_FS_END
2383 : };
2384 : #if defined(__clang__)
2385 : #pragma clang diagnostic pop
2386 : #endif
2387 :
2388 : static PrefableDisablers sMethods_disablers0 = {
2389 : true, true, 0, nullptr
2390 : };
2391 :
2392 : // Can't be const because the pref-enabled boolean needs to be writable
2393 : static Prefable<const JSFunctionSpec> sMethods[] = {
2394 : { &sMethods_disablers0, &sMethods_specs[0] },
2395 : { nullptr, nullptr }
2396 : };
2397 :
2398 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2399 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2400 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2401 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2402 :
2403 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2404 : #if defined(__clang__)
2405 : #pragma clang diagnostic push
2406 : #pragma clang diagnostic ignored "-Wmissing-braces"
2407 : #endif
2408 : static const JSPropertySpec sAttributes_specs[] = {
2409 : { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr },
2410 : { "shippingAddress", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &shippingAddress_getterinfo, nullptr, nullptr },
2411 : { "shippingOption", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &shippingOption_getterinfo, nullptr, nullptr },
2412 : { "shippingType", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &shippingType_getterinfo, nullptr, nullptr },
2413 : { "onshippingaddresschange", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onshippingaddresschange_getterinfo, GenericBindingSetter, &onshippingaddresschange_setterinfo },
2414 : { "onshippingoptionchange", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onshippingoptionchange_getterinfo, GenericBindingSetter, &onshippingoptionchange_setterinfo },
2415 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
2416 : };
2417 : #if defined(__clang__)
2418 : #pragma clang diagnostic pop
2419 : #endif
2420 :
2421 : static PrefableDisablers sAttributes_disablers0 = {
2422 : true, true, 0, nullptr
2423 : };
2424 :
2425 : // Can't be const because the pref-enabled boolean needs to be writable
2426 : static Prefable<const JSPropertySpec> sAttributes[] = {
2427 : { &sAttributes_disablers0, &sAttributes_specs[0] },
2428 : { nullptr, nullptr }
2429 : };
2430 :
2431 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2432 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2433 : static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2434 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2435 :
2436 :
2437 : static uint16_t sNativeProperties_sortedPropertyIndices[9];
2438 : static PropertyInfo sNativeProperties_propertyInfos[9];
2439 :
2440 : static const NativePropertiesN<2> sNativeProperties = {
2441 : false, 0,
2442 : false, 0,
2443 : true, 0 /* sMethods */,
2444 : true, 1 /* sAttributes */,
2445 : false, 0,
2446 : false, 0,
2447 : false, 0,
2448 : -1,
2449 : 9,
2450 : sNativeProperties_sortedPropertyIndices,
2451 : {
2452 : { sMethods, &sNativeProperties_propertyInfos[0] },
2453 : { sAttributes, &sNativeProperties_propertyInfos[3] }
2454 : }
2455 : };
2456 : static_assert(9 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
2457 : "We have a property info count that is oversized");
2458 :
2459 : static bool
2460 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
2461 : {
2462 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2463 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
2464 0 : if (!args.isConstructing()) {
2465 : // XXXbz wish I could get the name from the callee instead of
2466 : // Adding more relocations
2467 0 : return ThrowConstructorWithoutNew(cx, "PaymentRequest");
2468 : }
2469 :
2470 0 : GlobalObject global(cx, obj);
2471 0 : if (global.Failed()) {
2472 0 : return false;
2473 : }
2474 :
2475 0 : JS::Rooted<JSObject*> desiredProto(cx);
2476 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
2477 0 : return false;
2478 : }
2479 :
2480 0 : if (MOZ_UNLIKELY(args.length() < 2)) {
2481 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "PaymentRequest");
2482 : }
2483 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2484 0 : binding_detail::AutoSequence<PaymentMethodData> arg0;
2485 0 : SequenceRooter<PaymentMethodData> arg0_holder(cx, &arg0);
2486 0 : if (args[0].isObject()) {
2487 0 : JS::ForOfIterator iter(cx);
2488 0 : if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
2489 0 : return false;
2490 : }
2491 0 : if (!iter.valueIsIterable()) {
2492 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of PaymentRequest.constructor");
2493 0 : return false;
2494 : }
2495 0 : binding_detail::AutoSequence<PaymentMethodData> &arr = arg0;
2496 0 : JS::Rooted<JS::Value> temp(cx);
2497 : while (true) {
2498 : bool done;
2499 0 : if (!iter.next(&temp, &done)) {
2500 0 : return false;
2501 : }
2502 0 : if (done) {
2503 0 : break;
2504 : }
2505 0 : PaymentMethodData* slotPtr = arr.AppendElement(mozilla::fallible);
2506 0 : if (!slotPtr) {
2507 0 : JS_ReportOutOfMemory(cx);
2508 0 : return false;
2509 : }
2510 0 : PaymentMethodData& slot = *slotPtr;
2511 0 : if (!slot.Init(cx, temp, "Element of argument 1 of PaymentRequest.constructor", false)) {
2512 0 : return false;
2513 : }
2514 0 : }
2515 : } else {
2516 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of PaymentRequest.constructor");
2517 0 : return false;
2518 : }
2519 0 : RootedDictionary<binding_detail::FastPaymentDetailsInit> arg1(cx);
2520 0 : if (!arg1.Init(cx, args[1], "Argument 2 of PaymentRequest.constructor", false)) {
2521 0 : return false;
2522 : }
2523 0 : binding_detail::FastPaymentOptions arg2;
2524 0 : if (!arg2.Init(cx, (args.hasDefined(2)) ? args[2] : JS::NullHandleValue, "Argument 3 of PaymentRequest.constructor", false)) {
2525 0 : return false;
2526 : }
2527 0 : Maybe<JSAutoCompartment> ac;
2528 0 : if (objIsXray) {
2529 0 : obj = js::CheckedUnwrap(obj);
2530 0 : if (!obj) {
2531 0 : return false;
2532 : }
2533 0 : ac.emplace(cx, obj);
2534 0 : if (!JS_WrapObject(cx, &desiredProto)) {
2535 0 : return false;
2536 : }
2537 0 : for (uint32_t indexName0 = 0; indexName0 < arg0.Length(); ++indexName0) {
2538 0 : if (arg0[indexName0].mData.WasPassed()) {
2539 0 : if (!JS_WrapObject(cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&arg0[indexName0].mData.Value()))) {
2540 0 : return false;
2541 : }
2542 : }
2543 : }
2544 0 : if (arg1.mModifiers.WasPassed()) {
2545 0 : for (uint32_t indexName0 = 0; indexName0 < arg1.mModifiers.Value().Length(); ++indexName0) {
2546 0 : if (arg1.mModifiers.Value()[indexName0].mData.WasPassed()) {
2547 0 : if (!JS_WrapObject(cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&arg1.mModifiers.Value()[indexName0].mData.Value()))) {
2548 0 : return false;
2549 : }
2550 : }
2551 : }
2552 : }
2553 : }
2554 0 : binding_detail::FastErrorResult rv;
2555 0 : auto result(StrongOrRawPtr<mozilla::dom::PaymentRequest>(mozilla::dom::PaymentRequest::Constructor(global, Constify(arg0), Constify(arg1), Constify(arg2), rv)));
2556 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2557 0 : return false;
2558 : }
2559 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2560 : static_assert(!IsPointer<decltype(result)>::value,
2561 : "NewObject implies that we need to keep the object alive with a strong reference.");
2562 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
2563 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
2564 0 : return false;
2565 : }
2566 0 : return true;
2567 : }
2568 :
2569 : static const js::ClassOps sInterfaceObjectClassOps = {
2570 : nullptr, /* addProperty */
2571 : nullptr, /* delProperty */
2572 : nullptr, /* getProperty */
2573 : nullptr, /* setProperty */
2574 : nullptr, /* enumerate */
2575 : nullptr, /* newEnumerate */
2576 : nullptr, /* resolve */
2577 : nullptr, /* mayResolve */
2578 : nullptr, /* finalize */
2579 : _constructor, /* call */
2580 : nullptr, /* hasInstance */
2581 : _constructor, /* construct */
2582 : nullptr, /* trace */
2583 : };
2584 :
2585 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
2586 : {
2587 : "Function",
2588 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
2589 : &sInterfaceObjectClassOps,
2590 : JS_NULL_CLASS_SPEC,
2591 : JS_NULL_CLASS_EXT,
2592 : &sInterfaceObjectClassObjectOps
2593 : },
2594 : eInterface,
2595 : true,
2596 : prototypes::id::PaymentRequest,
2597 : PrototypeTraits<prototypes::id::PaymentRequest>::Depth,
2598 : sNativePropertyHooks,
2599 : "function PaymentRequest() {\n [native code]\n}",
2600 : EventTargetBinding::GetConstructorObject
2601 : };
2602 :
2603 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
2604 : {
2605 : "PaymentRequestPrototype",
2606 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
2607 : JS_NULL_CLASS_OPS,
2608 : JS_NULL_CLASS_SPEC,
2609 : JS_NULL_CLASS_EXT,
2610 : JS_NULL_OBJECT_OPS
2611 : },
2612 : eInterfacePrototype,
2613 : false,
2614 : prototypes::id::PaymentRequest,
2615 : PrototypeTraits<prototypes::id::PaymentRequest>::Depth,
2616 : sNativePropertyHooks,
2617 : "[object PaymentRequestPrototype]",
2618 : EventTargetBinding::GetProtoObject
2619 : };
2620 :
2621 : bool
2622 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
2623 : {
2624 0 : return mozilla::dom::PaymentRequest::PrefEnabled(aCx, aObj) &&
2625 0 : mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
2626 : }
2627 :
2628 : JSObject*
2629 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
2630 : {
2631 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
2632 : }
2633 :
2634 : static const js::ClassOps sClassOps = {
2635 : _addProperty, /* addProperty */
2636 : nullptr, /* delProperty */
2637 : nullptr, /* getProperty */
2638 : nullptr, /* setProperty */
2639 : nullptr, /* enumerate */
2640 : nullptr, /* newEnumerate */
2641 : nullptr, /* resolve */
2642 : nullptr, /* mayResolve */
2643 : _finalize, /* finalize */
2644 : nullptr, /* call */
2645 : nullptr, /* hasInstance */
2646 : nullptr, /* construct */
2647 : nullptr, /* trace */
2648 : };
2649 :
2650 : static const js::ClassExtension sClassExtension = {
2651 : nullptr, /* weakmapKeyDelegateOp */
2652 : _objectMoved /* objectMovedOp */
2653 : };
2654 :
2655 : static const DOMJSClass sClass = {
2656 : { "PaymentRequest",
2657 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
2658 : &sClassOps,
2659 : JS_NULL_CLASS_SPEC,
2660 : &sClassExtension,
2661 : JS_NULL_OBJECT_OPS
2662 : },
2663 : { prototypes::id::EventTarget, prototypes::id::PaymentRequest, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
2664 : IsBaseOf<nsISupports, mozilla::dom::PaymentRequest >::value,
2665 : sNativePropertyHooks,
2666 : FindAssociatedGlobalForNative<mozilla::dom::PaymentRequest>::Get,
2667 : GetProtoObjectHandle,
2668 : GetCCParticipant<mozilla::dom::PaymentRequest>::Get()
2669 : };
2670 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
2671 : "Must have the right minimal number of reserved slots.");
2672 : static_assert(1 >= 1,
2673 : "Must have enough reserved slots.");
2674 :
2675 : const JSClass*
2676 0 : GetJSClass()
2677 : {
2678 0 : return sClass.ToJSClass();
2679 : }
2680 :
2681 : bool
2682 0 : Wrap(JSContext* aCx, mozilla::dom::PaymentRequest* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
2683 : {
2684 : MOZ_ASSERT(static_cast<mozilla::dom::PaymentRequest*>(aObject) ==
2685 : reinterpret_cast<mozilla::dom::PaymentRequest*>(aObject),
2686 : "Multiple inheritance for mozilla::dom::PaymentRequest is broken.");
2687 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
2688 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
2689 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
2690 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
2691 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
2692 0 : MOZ_ASSERT(!aCache->GetWrapper(),
2693 : "You should probably not be using Wrap() directly; use "
2694 : "GetOrCreateDOMReflector instead");
2695 :
2696 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
2697 : "nsISupports must be on our primary inheritance chain");
2698 :
2699 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
2700 0 : if (!global) {
2701 0 : return false;
2702 : }
2703 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
2704 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
2705 :
2706 : // That might have ended up wrapping us already, due to the wonders
2707 : // of XBL. Check for that, and bail out as needed.
2708 0 : aReflector.set(aCache->GetWrapper());
2709 0 : if (aReflector) {
2710 : #ifdef DEBUG
2711 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
2712 : #endif // DEBUG
2713 0 : return true;
2714 : }
2715 :
2716 0 : JSAutoCompartment ac(aCx, global);
2717 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
2718 0 : if (!canonicalProto) {
2719 0 : return false;
2720 : }
2721 0 : JS::Rooted<JSObject*> proto(aCx);
2722 0 : if (aGivenProto) {
2723 0 : proto = aGivenProto;
2724 : // Unfortunately, while aGivenProto was in the compartment of aCx
2725 : // coming in, we changed compartments to that of "parent" so may need
2726 : // to wrap the proto here.
2727 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
2728 0 : if (!JS_WrapObject(aCx, &proto)) {
2729 0 : return false;
2730 : }
2731 : }
2732 : } else {
2733 0 : proto = canonicalProto;
2734 : }
2735 :
2736 0 : BindingJSObjectCreator<mozilla::dom::PaymentRequest> creator(aCx);
2737 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
2738 0 : if (!aReflector) {
2739 0 : return false;
2740 : }
2741 :
2742 0 : aCache->SetWrapper(aReflector);
2743 0 : creator.InitializationSucceeded();
2744 :
2745 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
2746 : aCache->GetWrapperPreserveColor() == aReflector);
2747 : // If proto != canonicalProto, we have to preserve our wrapper;
2748 : // otherwise we won't be able to properly recreate it later, since
2749 : // we won't know what proto to use. Note that we don't check
2750 : // aGivenProto here, since it's entirely possible (and even
2751 : // somewhat common) to have a non-null aGivenProto which is the
2752 : // same as canonicalProto.
2753 0 : if (proto != canonicalProto) {
2754 0 : PreserveWrapper(aObject);
2755 : }
2756 :
2757 0 : return true;
2758 : }
2759 :
2760 : const NativePropertyHooks sNativePropertyHooks[] = { {
2761 : nullptr,
2762 : nullptr,
2763 : nullptr,
2764 : { sNativeProperties.Upcast(), nullptr },
2765 : prototypes::id::PaymentRequest,
2766 : constructors::id::PaymentRequest,
2767 : EventTargetBinding::sNativePropertyHooks,
2768 : &DefaultXrayExpandoObjectClass
2769 : } };
2770 :
2771 : void
2772 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
2773 : {
2774 0 : JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
2775 0 : if (!parentProto) {
2776 0 : return;
2777 : }
2778 :
2779 0 : JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
2780 0 : if (!constructorProto) {
2781 0 : return;
2782 : }
2783 :
2784 : static bool sIdsInited = false;
2785 0 : if (!sIdsInited && NS_IsMainThread()) {
2786 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
2787 0 : return;
2788 : }
2789 0 : sIdsInited = true;
2790 : }
2791 :
2792 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::PaymentRequest);
2793 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PaymentRequest);
2794 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
2795 : &sPrototypeClass.mBase, protoCache,
2796 : constructorProto, &sInterfaceObjectClass.mBase, 2, nullptr,
2797 : interfaceCache,
2798 : sNativeProperties.Upcast(),
2799 : nullptr,
2800 : "PaymentRequest", aDefineOnGlobal,
2801 : nullptr,
2802 0 : false);
2803 : }
2804 :
2805 : JS::Handle<JSObject*>
2806 0 : GetProtoObjectHandle(JSContext* aCx)
2807 : {
2808 : /* Get the interface prototype object for this class. This will create the
2809 : object as needed. */
2810 0 : bool aDefineOnGlobal = true;
2811 :
2812 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2813 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2814 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2815 0 : return nullptr;
2816 : }
2817 :
2818 : /* Check to see whether the interface objects are already installed */
2819 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2820 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::PaymentRequest)) {
2821 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2822 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2823 : }
2824 :
2825 : /*
2826 : * The object might _still_ be null, but that's OK.
2827 : *
2828 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2829 : * traced by TraceProtoAndIfaceCache() and its contents are never
2830 : * changed after they have been set.
2831 : *
2832 : * Calling address() avoids the read read barrier that does gray
2833 : * unmarking, but it's not possible for the object to be gray here.
2834 : */
2835 :
2836 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::PaymentRequest);
2837 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2838 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2839 : }
2840 :
2841 : JS::Handle<JSObject*>
2842 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
2843 : {
2844 : /* Get the interface object for this class. This will create the object as
2845 : needed. */
2846 :
2847 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2848 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2849 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2850 0 : return nullptr;
2851 : }
2852 :
2853 : /* Check to see whether the interface objects are already installed */
2854 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2855 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::PaymentRequest)) {
2856 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2857 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2858 : }
2859 :
2860 : /*
2861 : * The object might _still_ be null, but that's OK.
2862 : *
2863 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2864 : * traced by TraceProtoAndIfaceCache() and its contents are never
2865 : * changed after they have been set.
2866 : *
2867 : * Calling address() avoids the read read barrier that does gray
2868 : * unmarking, but it's not possible for the object to be gray here.
2869 : */
2870 :
2871 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::PaymentRequest);
2872 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2873 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2874 : }
2875 :
2876 : JSObject*
2877 0 : GetConstructorObject(JSContext* aCx)
2878 : {
2879 0 : return GetConstructorObjectHandle(aCx);
2880 : }
2881 :
2882 : } // namespace PaymentRequestBinding
2883 :
2884 :
2885 :
2886 : } // namespace dom
2887 : } // namespace mozilla
|