/* THIS FILE IS AUTOGENERATED FROM Animatable.webidl BY Codegen.py - DO NOT EDIT */ #include #include "AnimatableBinding.h" #include "AtomList.h" #include "MainThreadUtils.h" #include "TimelineRangeOffsetBinding.h" #include "js/CallAndConstruct.h" #include "js/Exception.h" #include "js/MapAndSet.h" #include "js/Object.h" #include "js/PropertyAndElement.h" #include "js/PropertyDescriptor.h" #include "js/experimental/JitInfo.h" #include "mozilla/OwningNonNull.h" #include "mozilla/StaticPrefs_layout.h" #include "mozilla/dom/BindingCallContext.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/CSSKeywordValue.h" #include "mozilla/dom/CSSNumericValue.h" #include "mozilla/dom/NonRefcountedDOMObject.h" #include "mozilla/dom/PrimitiveConversions.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/SimpleGlobalObject.h" namespace mozilla::dom { namespace binding_detail {}; // Just to make sure it's known as a namespace using namespace mozilla::dom::binding_detail; void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String& aUnion, const char* aName, uint32_t aFlags) { if (aUnion.IsTimelineRangeOffset()) { ImplCycleCollectionTraverse(aCallback, aUnion.GetAsTimelineRangeOffset(), "mTimelineRangeOffset", aFlags); } else if (aUnion.IsCSSNumericValue()) { ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCSSNumericValue(), "mCSSNumericValue", aFlags); } else if (aUnion.IsCSSKeywordValue()) { ImplCycleCollectionTraverse(aCallback, aUnion.GetAsCSSKeywordValue(), "mCSSKeywordValue", aFlags); } } void ImplCycleCollectionUnlink(OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String& aUnion) { aUnion.Uninit(); } GetAnimationsOptions::GetAnimationsOptions() { // Safe to pass a null context if we pass a null value Init(nullptr, JS::NullHandleValue); } bool GetAnimationsOptions::InitIds(JSContext* cx, GetAnimationsOptionsAtoms* atomsCache) { MOZ_ASSERT(reinterpret_cast(atomsCache)->isVoid()); // Initialize these in reverse order so that any failure leaves the first one // uninitialized. if (!atomsCache->subtree_id.init(cx, "subtree") || !atomsCache->pseudoElement_id.init(cx, "pseudoElement")) { return false; } return true; } bool GetAnimationsOptions::Init(BindingCallContext& cx, JS::Handle val, const char* sourceDescription, bool passedToJSImpl) { // Passing a null JSContext is OK only if we're initing from null, // Since in that case we will not have to do any property gets // Also evaluate isNullOrUndefined in order to avoid false-positive // checkers by static analysis tools MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined()); GetAnimationsOptionsAtoms* atomsCache = nullptr; if (cx) { atomsCache = GetAtomCache(cx); if (reinterpret_cast(atomsCache)->isVoid() && !InitIds(cx, atomsCache)) { return false; } } if (!IsConvertibleToDictionary(val)) { return cx.ThrowErrorMessage(sourceDescription, "dictionary"); } bool isNull = val.isNullOrUndefined(); // We only need these if !isNull, in which case we have |cx|. Maybe > object; Maybe > temp; if (!isNull) { MOZ_ASSERT(cx); object.emplace(cx, &val.toObject()); temp.emplace(cx); } if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->pseudoElement_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { if (!ConvertJSValueToString(cx, temp.ref(), eNull, eNull, mPseudoElement)) { return false; } } else { mPseudoElement.SetIsVoid(true); } mIsAnyMemberPresent = true; if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->subtree_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { if (!ValueToPrimitive(cx, temp.ref(), "'subtree' member of GetAnimationsOptions", &mSubtree)) { return false; } } else { mSubtree = false; } mIsAnyMemberPresent = true; return true; } bool GetAnimationsOptions::Init(JSContext* cx_, JS::Handle val, const char* sourceDescription, bool passedToJSImpl) { // We don't want to use sourceDescription for our context here; // that's not really what it's formatted for. BindingCallContext cx(cx_, nullptr); return Init(cx, val, sourceDescription, passedToJSImpl); } void GetAnimationsOptions::TraceDictionary(JSTracer* trc) { } GetAnimationsOptions& GetAnimationsOptions::operator=(const GetAnimationsOptions& aOther) { MaybeEmptyDictionaryBase::operator=(aOther); mPseudoElement = aOther.mPseudoElement; mSubtree = aOther.mSubtree; return *this; } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToTimelineRangeOffset(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot binding_detail::FastTimelineRangeOffset& memberSlot = RawSetAsTimelineRangeOffset(); if (!IsConvertibleToDictionary(value)) { DestroyTimelineRangeOffset(); tryNext = true; return true; } if (!memberSlot.Init(cx, value, "TimelineRangeOffset branch of (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or USVString)", passedToJSImpl)) { return false; } } return true; } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToTimelineRangeOffset(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToTimelineRangeOffset(cx, value, tryNext, passedToJSImpl); } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSNumericValue(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot NonNull& memberSlot = RawSetAsCSSNumericValue(); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyCSSNumericValue(); tryNext = true; return true; } } } return true; } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSNumericValue(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToCSSNumericValue(cx, value, tryNext, passedToJSImpl); } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSKeywordValue(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot NonNull& memberSlot = RawSetAsCSSKeywordValue(); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyCSSKeywordValue(); tryNext = true; return true; } } } return true; } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSKeywordValue(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToCSSKeywordValue(cx, value, tryNext, passedToJSImpl); } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToUTF8String(JSContext* cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot nsAutoCString& memberSlot = RawSetAsUTF8String(); if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) { return false; } } return true; } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::Init(BindingCallContext& cx, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { MOZ_ASSERT(mType == eUninitialized); bool done = false, failed = false, tryNext; if (value.isObject()) { done = (failed = !TrySetToCSSNumericValue(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToCSSKeywordValue(cx, value, tryNext, passedToJSImpl)) || !tryNext; } if (!done) { done = (failed = !TrySetToTimelineRangeOffset(cx, value, tryNext, passedToJSImpl)) || !tryNext; } if (!done) { do { done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext; break; } while (false); } if (failed) { return false; } if (!done) { cx.ThrowErrorMessage(sourceDescription, "CSSNumericValue, CSSKeywordValue, TimelineRangeOffset"); return false; } return true; } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::Init(JSContext* cx_, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return Init(cx, value, sourceDescription, passedToJSImpl); } bool TimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::ToJSVal(JSContext* cx, JS::Handle scopeObj, JS::MutableHandle rval) const { switch (mType) { case eUninitialized: { return false; } case eTimelineRangeOffset: { if (!mValue.mTimelineRangeOffset.Value().ToObjectInternal(cx, rval)) { return false; } return true; } case eCSSNumericValue: { if (!GetOrCreateDOMReflector(cx, mValue.mCSSNumericValue.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eCSSKeywordValue: { if (!GetOrCreateDOMReflector(cx, mValue.mCSSKeywordValue.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eUTF8String: { if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) { return false; } return true; } default: { return false; } } } OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String(OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String&& aOther) : mType(eUninitialized) { switch (aOther.mType) { case eUninitialized: { MOZ_ASSERT(mType == eUninitialized, "We need to destroy ourselves?"); break; } case eTimelineRangeOffset: { mType = eTimelineRangeOffset; mValue.mTimelineRangeOffset.SetValue(std::move(aOther.mValue.mTimelineRangeOffset.Value())); break; } case eCSSNumericValue: { mType = eCSSNumericValue; mValue.mCSSNumericValue.SetValue(std::move(aOther.mValue.mCSSNumericValue.Value())); break; } case eCSSKeywordValue: { mType = eCSSKeywordValue; mValue.mCSSKeywordValue.SetValue(std::move(aOther.mValue.mCSSKeywordValue.Value())); break; } case eUTF8String: { mType = eUTF8String; mValue.mUTF8String.SetValue(std::move(aOther.mValue.mUTF8String.Value())); break; } } } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToTimelineRangeOffset(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot TimelineRangeOffset& memberSlot = RawSetAsTimelineRangeOffset(); if (!IsConvertibleToDictionary(value)) { DestroyTimelineRangeOffset(); tryNext = true; return true; } if (!memberSlot.Init(cx, value, "TimelineRangeOffset branch of (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or USVString)", passedToJSImpl)) { return false; } } return true; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToTimelineRangeOffset(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToTimelineRangeOffset(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] TimelineRangeOffset& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::RawSetAsTimelineRangeOffset() { if (mType == eTimelineRangeOffset) { return mValue.mTimelineRangeOffset.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eTimelineRangeOffset; return mValue.mTimelineRangeOffset.SetValue(); } [[nodiscard]] TimelineRangeOffset& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::SetAsTimelineRangeOffset() { if (mType == eTimelineRangeOffset) { return mValue.mTimelineRangeOffset.Value(); } Uninit(); mType = eTimelineRangeOffset; return mValue.mTimelineRangeOffset.SetValue(); } void OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::DestroyTimelineRangeOffset() { MOZ_RELEASE_ASSERT(IsTimelineRangeOffset(), "Wrong type!"); mValue.mTimelineRangeOffset.Destroy(); mType = eUninitialized; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSNumericValue(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot OwningNonNull& memberSlot = RawSetAsCSSNumericValue(); static_assert(IsRefcounted::value, "We can only store refcounted classes."); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyCSSNumericValue(); tryNext = true; return true; } } } return true; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSNumericValue(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToCSSNumericValue(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] OwningNonNull& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::RawSetAsCSSNumericValue() { if (mType == eCSSNumericValue) { return mValue.mCSSNumericValue.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eCSSNumericValue; return mValue.mCSSNumericValue.SetValue(); } [[nodiscard]] OwningNonNull& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::SetAsCSSNumericValue() { if (mType == eCSSNumericValue) { return mValue.mCSSNumericValue.Value(); } Uninit(); mType = eCSSNumericValue; return mValue.mCSSNumericValue.SetValue(); } void OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::DestroyCSSNumericValue() { MOZ_RELEASE_ASSERT(IsCSSNumericValue(), "Wrong type!"); mValue.mCSSNumericValue.Destroy(); mType = eUninitialized; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSKeywordValue(BindingCallContext& cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot OwningNonNull& memberSlot = RawSetAsCSSKeywordValue(); static_assert(IsRefcounted::value, "We can only store refcounted classes."); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(value, memberSlot, cx); if (NS_FAILED(rv)) { DestroyCSSKeywordValue(); tryNext = true; return true; } } } return true; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToCSSKeywordValue(JSContext* cx_, JS::Handle value, bool& tryNext, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return TrySetToCSSKeywordValue(cx, value, tryNext, passedToJSImpl); } [[nodiscard]] OwningNonNull& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::RawSetAsCSSKeywordValue() { if (mType == eCSSKeywordValue) { return mValue.mCSSKeywordValue.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eCSSKeywordValue; return mValue.mCSSKeywordValue.SetValue(); } [[nodiscard]] OwningNonNull& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::SetAsCSSKeywordValue() { if (mType == eCSSKeywordValue) { return mValue.mCSSKeywordValue.Value(); } Uninit(); mType = eCSSKeywordValue; return mValue.mCSSKeywordValue.SetValue(); } void OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::DestroyCSSKeywordValue() { MOZ_RELEASE_ASSERT(IsCSSKeywordValue(), "Wrong type!"); mValue.mCSSKeywordValue.Destroy(); mType = eUninitialized; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::TrySetToUTF8String(JSContext* cx, JS::Handle value, bool& tryNext, bool passedToJSImpl) { tryNext = false; { // scope for memberSlot nsCString& memberSlot = RawSetAsUTF8String(); if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) { return false; } } return true; } [[nodiscard]] nsCString& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::RawSetAsUTF8String() { if (mType == eUTF8String) { return mValue.mUTF8String.Value(); } MOZ_ASSERT(mType == eUninitialized); mType = eUTF8String; return mValue.mUTF8String.SetValue(); } [[nodiscard]] nsCString& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::SetAsUTF8String() { if (mType == eUTF8String) { return mValue.mUTF8String.Value(); } Uninit(); mType = eUTF8String; return mValue.mUTF8String.SetValue(); } void OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::DestroyUTF8String() { MOZ_RELEASE_ASSERT(IsUTF8String(), "Wrong type!"); mValue.mUTF8String.Destroy(); mType = eUninitialized; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::Init(BindingCallContext& cx, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { MOZ_ASSERT(mType == eUninitialized); bool done = false, failed = false, tryNext; if (value.isObject()) { done = (failed = !TrySetToCSSNumericValue(cx, value, tryNext, passedToJSImpl)) || !tryNext || (failed = !TrySetToCSSKeywordValue(cx, value, tryNext, passedToJSImpl)) || !tryNext; } if (!done) { done = (failed = !TrySetToTimelineRangeOffset(cx, value, tryNext, passedToJSImpl)) || !tryNext; } if (!done) { do { done = (failed = !TrySetToUTF8String(cx, value, tryNext)) || !tryNext; break; } while (false); } if (failed) { return false; } if (!done) { cx.ThrowErrorMessage(sourceDescription, "CSSNumericValue, CSSKeywordValue, TimelineRangeOffset"); return false; } return true; } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::Init(JSContext* cx_, JS::Handle value, const char* sourceDescription, bool passedToJSImpl) { BindingCallContext cx(cx_, nullptr); return Init(cx, value, sourceDescription, passedToJSImpl); } void OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::Uninit() { switch (mType) { case eUninitialized: { break; } case eTimelineRangeOffset: { DestroyTimelineRangeOffset(); break; } case eCSSNumericValue: { DestroyCSSNumericValue(); break; } case eCSSKeywordValue: { DestroyCSSKeywordValue(); break; } case eUTF8String: { DestroyUTF8String(); break; } } } bool OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::ToJSVal(JSContext* cx, JS::Handle scopeObj, JS::MutableHandle rval) const { switch (mType) { case eUninitialized: { return false; } case eTimelineRangeOffset: { if (!mValue.mTimelineRangeOffset.Value().ToObjectInternal(cx, rval)) { return false; } return true; } case eCSSNumericValue: { if (!GetOrCreateDOMReflector(cx, mValue.mCSSNumericValue.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eCSSKeywordValue: { if (!GetOrCreateDOMReflector(cx, mValue.mCSSKeywordValue.Value(), rval)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } case eUTF8String: { if (!NonVoidUTF8StringToJsval(cx, mValue.mUTF8String.Value(), rval)) { return false; } return true; } default: { return false; } } } OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::operator=(OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String&& aOther) { this->~OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String(); new (this) OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String (std::move(aOther)); return *this; } OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String& OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String::operator=(const OwningTimelineRangeOffsetOrCSSNumericValueOrCSSKeywordValueOrUTF8String& aOther) { switch (aOther.mType) { case eUninitialized: { MOZ_ASSERT(mType == eUninitialized, "We need to destroy ourselves?"); break; } case eTimelineRangeOffset: { SetAsTimelineRangeOffset() = aOther.GetAsTimelineRangeOffset(); break; } case eCSSNumericValue: { SetAsCSSNumericValue() = aOther.GetAsCSSNumericValue(); break; } case eCSSKeywordValue: { SetAsCSSKeywordValue() = aOther.GetAsCSSKeywordValue(); break; } case eUTF8String: { SetAsUTF8String() = aOther.GetAsUTF8String(); break; } } return *this; } KeyframeAnimationOptions::KeyframeAnimationOptions() : KeyframeEffectOptions(FastDictionaryInitializer()) { // Safe to pass a null context if we pass a null value Init(nullptr, JS::NullHandleValue); } bool KeyframeAnimationOptions::InitIds(JSContext* cx, KeyframeAnimationOptionsAtoms* atomsCache) { MOZ_ASSERT(reinterpret_cast(atomsCache)->isVoid()); // Initialize these in reverse order so that any failure leaves the first one // uninitialized. if (!atomsCache->timeline_id.init(cx, "timeline") || !atomsCache->rangeStart_id.init(cx, "rangeStart") || !atomsCache->rangeEnd_id.init(cx, "rangeEnd") || !atomsCache->id_id.init(cx, "id")) { return false; } return true; } bool KeyframeAnimationOptions::Init(BindingCallContext& cx, JS::Handle val, const char* sourceDescription, bool passedToJSImpl) { // Passing a null JSContext is OK only if we're initing from null, // Since in that case we will not have to do any property gets // Also evaluate isNullOrUndefined in order to avoid false-positive // checkers by static analysis tools MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined()); KeyframeAnimationOptionsAtoms* atomsCache = nullptr; if (cx) { atomsCache = GetAtomCache(cx); if (reinterpret_cast(atomsCache)->isVoid() && !InitIds(cx, atomsCache)) { return false; } } // Per spec, we init the parent's members first if (!KeyframeEffectOptions::Init(cx, val)) { return false; } bool isNull = val.isNullOrUndefined(); // We only need these if !isNull, in which case we have |cx|. Maybe > object; Maybe > temp; if (!isNull) { MOZ_ASSERT(cx); object.emplace(cx, &val.toObject()); temp.emplace(cx); } if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mId)) { return false; } } else { mId.AssignLiteral(u""); } mIsAnyMemberPresent = true; if (!isNull) { if (StaticPrefs::layout_css_scroll_driven_animations_enabled()) { if (!JS_GetPropertyById(cx, *object, atomsCache->rangeEnd_id, temp.ptr())) { return false; } } else { temp->setUndefined(); } } mRangeEnd.Uninit(); if (!(!isNull && !temp->isUndefined())) { mRangeEnd.SetStringLiteral("normal"); } else { if (!mRangeEnd.Init(cx, temp.ref(), "'rangeEnd' member of KeyframeAnimationOptions", passedToJSImpl)) { return false; } } mIsAnyMemberPresent = true; if (!isNull) { if (StaticPrefs::layout_css_scroll_driven_animations_enabled()) { if (!JS_GetPropertyById(cx, *object, atomsCache->rangeStart_id, temp.ptr())) { return false; } } else { temp->setUndefined(); } } mRangeStart.Uninit(); if (!(!isNull && !temp->isUndefined())) { mRangeStart.SetStringLiteral("normal"); } else { if (!mRangeStart.Init(cx, temp.ref(), "'rangeStart' member of KeyframeAnimationOptions", passedToJSImpl)) { return false; } } mIsAnyMemberPresent = true; if (!isNull) { if (StaticPrefs::layout_css_scroll_driven_animations_enabled()) { if (!JS_GetPropertyById(cx, *object, atomsCache->timeline_id, temp.ptr())) { return false; } } else { temp->setUndefined(); } } if (!isNull && !temp->isUndefined()) { mTimeline.Construct(); if (temp.ref().isObject()) { static_assert(IsRefcounted::value, "We can only store refcounted classes."); { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(temp.ptr(), (mTimeline.Value()), cx); if (NS_FAILED(rv)) { cx.ThrowErrorMessage("'timeline' member of KeyframeAnimationOptions", "AnimationTimeline"); return false; } } } else if (temp.ref().isNullOrUndefined()) { (mTimeline.Value()) = nullptr; } else { cx.ThrowErrorMessage("'timeline' member of KeyframeAnimationOptions"); return false; } mIsAnyMemberPresent = true; } return true; } bool KeyframeAnimationOptions::Init(JSContext* cx_, JS::Handle val, const char* sourceDescription, bool passedToJSImpl) { // We don't want to use sourceDescription for our context here; // that's not really what it's formatted for. BindingCallContext cx(cx_, nullptr); return Init(cx, val, sourceDescription, passedToJSImpl); } void KeyframeAnimationOptions::TraceDictionary(JSTracer* trc) { KeyframeEffectOptions::TraceDictionary(trc); } KeyframeAnimationOptions& KeyframeAnimationOptions::operator=(const KeyframeAnimationOptions& aOther) { KeyframeEffectOptions::operator=(aOther); mId = aOther.mId; mRangeEnd = aOther.mRangeEnd; mRangeStart = aOther.mRangeStart; mTimeline.Reset(); if (aOther.mTimeline.WasPassed()) { mTimeline.Construct(aOther.mTimeline.Value()); } return *this; } } // namespace mozilla::dom