/* THIS FILE IS AUTOGENERATED FROM ShadowRoot.webidl BY Codegen.py - DO NOT EDIT */ #include #include "DocumentFragmentBinding.h" #include "ElementBinding.h" #include "EventHandlerBinding.h" #include "MainThreadUtils.h" #include "SanitizerBinding.h" #include "ShadowRootBinding.h" #include "WrapperFactory.h" #include "XrayWrapper.h" #include "js/Array.h" #include "js/CallAndConstruct.h" #include "js/Exception.h" #include "js/ForOfIterator.h" #include "js/MapAndSet.h" #include "js/Object.h" #include "js/PropertyAndElement.h" #include "js/PropertyDescriptor.h" #include "js/experimental/JitInfo.h" #include "jsapi.h" #include "mozilla/Atomics.h" #include "mozilla/BasePrincipal.h" #include "mozilla/FloatingPoint.h" #include "mozilla/OwningNonNull.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/StyleSheet.h" #include "mozilla/UseCounter.h" #include "mozilla/dom/Animation.h" #include "mozilla/dom/BindingCallContext.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/CustomElementRegistry.h" #include "mozilla/dom/DOMJSClass.h" #include "mozilla/dom/DocGroup.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/NonRefcountedDOMObject.h" #include "mozilla/dom/Nullable.h" #include "mozilla/dom/ObservableArrayProxyHandler.h" #include "mozilla/dom/PrimitiveConversions.h" #include "mozilla/dom/ShadowRoot.h" #include "mozilla/dom/StyleSheetList.h" #include "mozilla/dom/ToJSValue.h" #include "mozilla/dom/TrustedHTML.h" #include "mozilla/dom/UnionTypes.h" #include "mozilla/dom/WebIDLPrefs.h" #include "mozilla/dom/XrayExpandoClass.h" #include "nsContentUtils.h" #include "nsIContent.h" #include "nsJSPrincipals.h" namespace mozilla { namespace dom { namespace binding_detail {}; // Just to make sure it's known as a namespace using namespace mozilla::dom::binding_detail; namespace binding_detail { constexpr nsLiteralCString EnumStrings::Values[2]; } // namespace binding_detail bool ToJSValue(JSContext* aCx, ShadowRootMode aArgument, JS::MutableHandle aValue) { MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings::Values)); JSString* resultStr = JS_NewStringCopyN(aCx, binding_detail::EnumStrings::Values[uint32_t(aArgument)].BeginReading(), binding_detail::EnumStrings::Values[uint32_t(aArgument)].Length()); if (!resultStr) { return false; } aValue.setString(resultStr); return true; } namespace binding_detail { constexpr nsLiteralCString EnumStrings::Values[2]; } // namespace binding_detail bool ToJSValue(JSContext* aCx, SlotAssignmentMode aArgument, JS::MutableHandle aValue) { MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings::Values)); JSString* resultStr = JS_NewStringCopyN(aCx, binding_detail::EnumStrings::Values[uint32_t(aArgument)].BeginReading(), binding_detail::EnumStrings::Values[uint32_t(aArgument)].Length()); if (!resultStr) { return false; } aValue.setString(resultStr); return true; } namespace ShadowRoot_Binding { static_assert(IsRefcounted::value == IsRefcounted::value, "Can't inherit from an interface with a different ownership model."); MOZ_CAN_RUN_SCRIPT static bool get_mode(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "mode", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); ShadowRootMode result(MOZ_KnownLive(self)->Mode()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!ToJSValue(cx, result, args.rval())) { return false; } return true; } static const JSJitInfo mode_getterinfo = { { get_mode }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_delegatesFocus(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "delegatesFocus", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); bool result(MOZ_KnownLive(self)->DelegatesFocus()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setBoolean(result); return true; } static const JSJitInfo delegatesFocus_getterinfo = { { get_delegatesFocus }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_slotAssignment(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "slotAssignment", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); SlotAssignmentMode result(MOZ_KnownLive(self)->SlotAssignment()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!ToJSValue(cx, result, args.rval())) { return false; } return true; } static const JSJitInfo slotAssignment_getterinfo = { { get_slotAssignment }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_clonable(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "clonable", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); bool result(MOZ_KnownLive(self)->Clonable()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setBoolean(result); return true; } static const JSJitInfo clonable_getterinfo = { { get_clonable }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_serializable(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "serializable", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); bool result(MOZ_KnownLive(self)->Serializable()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setBoolean(result); return true; } static const JSJitInfo serializable_getterinfo = { { get_serializable }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_host(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "host", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->Host())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo host_getterinfo = { { get_host }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_onslotchange(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "onslotchange", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); RefPtr result(MOZ_KnownLive(self)->GetOnslotchange()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (result) { args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result)); if (!MaybeWrapObjectOrNullValue(cx, args.rval())) { return false; } return true; } else { args.rval().setNull(); return true; } } MOZ_CAN_RUN_SCRIPT static bool set_onslotchange(JSContext* cx, JS::Handle obj, void* void_self, JSJitSetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "onslotchange", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); RootedCallback> arg0(cx); if (args[0].isObject()) { { // scope for tempRoot and tempGlobalRoot if needed arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx)); } } else { arg0 = nullptr; } // NOTE: This assert does NOT call the function. static_assert(std::is_void_vSetOnslotchange(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here"); MOZ_KnownLive(self)->SetOnslotchange(MOZ_KnownLive(Constify(arg0))); MOZ_ASSERT(!JS_IsExceptionPending(cx)); return true; } static const JSJitInfo onslotchange_getterinfo = { { get_onslotchange }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static const JSJitInfo onslotchange_setterinfo = { { (JSJitGetterOp)set_onslotchange }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_referenceTarget(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "referenceTarget", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); DOMString result; // NOTE: This assert does NOT call the function. static_assert(std::is_void_vGetReferenceTarget(result))>, "Should be returning void here"); MOZ_KnownLive(self)->GetReferenceTarget(result); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!xpc::StringToJsval(cx, result, args.rval())) { return false; } return true; } MOZ_CAN_RUN_SCRIPT static bool set_referenceTarget(JSContext* cx, JS::Handle obj, void* void_self, JSJitSetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "referenceTarget", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); nsAutoString arg0; if (!ConvertJSValueToString(cx, args[0], eNull, eNull, arg0)) { return false; } // NOTE: This assert does NOT call the function. static_assert(std::is_void_vSetReferenceTarget(NonNullHelper(Constify(arg0))))>, "Should be returning void here"); MOZ_KnownLive(self)->SetReferenceTarget(NonNullHelper(Constify(arg0))); MOZ_ASSERT(!JS_IsExceptionPending(cx)); return true; } static const JSJitInfo referenceTarget_getterinfo = { { get_referenceTarget }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static const JSJitInfo referenceTarget_setterinfo = { { (JSJitGetterOp)set_referenceTarget }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool getElementById(JSContext* cx, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "getElementById", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.getElementById", 1)) { return false; } nsAutoString arg0; if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) { return false; } auto result(StrongOrRawPtr(MOZ_KnownLive(self)->GetElementById(NonNullHelper(Constify(arg0))))); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo getElementById_methodinfo = { { (JSJitGetterOp)getElementById }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_innerHTML(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "innerHTML", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); OwningTrustedHTMLOrNullIsEmptyString result; // NOTE: This assert does NOT call the function. static_assert(std::is_void_vGetInnerHTML(result))>, "Should be returning void here"); MOZ_KnownLive(self)->GetInnerHTML(result); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result.ToJSVal(cx, obj, args.rval())) { return false; } return true; } MOZ_CAN_RUN_SCRIPT static bool set_innerHTML(JSContext* cx_, JS::Handle obj, void* void_self, JSJitSetterCallArgs args) { BindingCallContext cx(cx_, "ShadowRoot.innerHTML setter"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "innerHTML", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); TrustedHTMLOrNullIsEmptyString arg0; if (!arg0.Init(cx, args[0], "Value being assigned", false)) { return false; } Maybe ceReaction; DocGroup* docGroup = self->GetDocGroup(); if (docGroup) { ceReaction.emplace(docGroup->CustomElementReactionsStack(), cx); } FastErrorResult rv; nsIPrincipal* subjectPrincipal; { JS::Realm* realm = js::GetContextRealm(cx); MOZ_ASSERT(realm); JSPrincipals* principals = JS::GetRealmPrincipals(realm); nsIPrincipal* principal = nsJSPrincipals::get(principals); if (principal->IsSystemPrincipal()) { principal = nullptr; } subjectPrincipal = principal; } // NOTE: This assert does NOT call the function. static_assert(std::is_void_vSetInnerHTML(Constify(arg0), MOZ_KnownLive(subjectPrincipal), rv))>, "Should be returning void here"); MOZ_KnownLive(self)->SetInnerHTML(Constify(arg0), MOZ_KnownLive(subjectPrincipal), rv); if (rv.MaybeSetPendingException(cx, "ShadowRoot.innerHTML setter")) [[unlikely]] { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); return true; } static const JSJitInfo innerHTML_getterinfo = { { get_innerHTML }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static const JSJitInfo innerHTML_setterinfo = { { (JSJitGetterOp)set_innerHTML }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool importNodeAndAppendChildAt(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.importNodeAndAppendChildAt"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "importNodeAndAppendChildAt", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.importNodeAndAppendChildAt", 2)) { return false; } NonNull arg0; if (args[0].isObject()) { { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(args[0], arg0, cx); if (NS_FAILED(rv)) { cx.ThrowErrorMessage("Argument 1", "Node"); return false; } } } else { cx.ThrowErrorMessage("Argument 1"); return false; } NonNull arg1; if (args[1].isObject()) { { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(args[1], arg1, cx); if (NS_FAILED(rv)) { cx.ThrowErrorMessage("Argument 2", "Node"); return false; } } } else { cx.ThrowErrorMessage("Argument 2"); return false; } bool arg2; if (args.hasDefined(2)) { if (!ValueToPrimitive(cx, args[2], "Argument 3", &arg2)) { return false; } } else { arg2 = false; } Maybe ceReaction; DocGroup* docGroup = self->GetDocGroup(); if (docGroup) { ceReaction.emplace(docGroup->CustomElementReactionsStack(), cx); } FastErrorResult rv; auto result(StrongOrRawPtr(MOZ_KnownLive(self)->ImportNodeAndAppendChildAt(MOZ_KnownLive(NonNullHelper(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), arg2, rv))); if (rv.MaybeSetPendingException(cx, "ShadowRoot.importNodeAndAppendChildAt")) [[unlikely]] { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo importNodeAndAppendChildAt_methodinfo = { { (JSJitGetterOp)importNodeAndAppendChildAt }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool createElementAndAppendChildAt(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.createElementAndAppendChildAt"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "createElementAndAppendChildAt", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.createElementAndAppendChildAt", 2)) { return false; } NonNull arg0; if (args[0].isObject()) { { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(args[0], arg0, cx); if (NS_FAILED(rv)) { cx.ThrowErrorMessage("Argument 1", "Node"); return false; } } } else { cx.ThrowErrorMessage("Argument 1"); return false; } nsAutoString arg1; if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) { return false; } Maybe ceReaction; DocGroup* docGroup = self->GetDocGroup(); if (docGroup) { ceReaction.emplace(docGroup->CustomElementReactionsStack(), cx); } FastErrorResult rv; auto result(StrongOrRawPtr(MOZ_KnownLive(self)->CreateElementAndAppendChildAt(MOZ_KnownLive(NonNullHelper(arg0)), NonNullHelper(Constify(arg1)), rv))); if (rv.MaybeSetPendingException(cx, "ShadowRoot.createElementAndAppendChildAt")) [[unlikely]] { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo createElementAndAppendChildAt_methodinfo = { { (JSJitGetterOp)createElementAndAppendChildAt }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool setIsUAWidget(JSContext* cx, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "setIsUAWidget", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); // NOTE: This assert does NOT call the function. static_assert(std::is_void_vSetIsUAWidget())>, "Should be returning void here"); MOZ_KnownLive(self)->SetIsUAWidget(); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; } static const JSJitInfo setIsUAWidget_methodinfo = { { (JSJitGetterOp)setIsUAWidget }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool isUAWidget(JSContext* cx, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "isUAWidget", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); bool result(MOZ_KnownLive(self)->IsUAWidget()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setBoolean(result); return true; } static const JSJitInfo isUAWidget_methodinfo = { { (JSJitGetterOp)isUAWidget }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool setHTML(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.setHTML"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "setHTML", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.setHTML", 1)) { return false; } nsAutoString arg0; if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) { return false; } binding_detail::FastSetHTMLOptions arg1; if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2", false)) { return false; } Maybe ceReaction; DocGroup* docGroup = self->GetDocGroup(); if (docGroup) { ceReaction.emplace(docGroup->CustomElementReactionsStack(), cx); } FastErrorResult rv; // NOTE: This assert does NOT call the function. static_assert(std::is_void_vSetHTML(NonNullHelper(Constify(arg0)), Constify(arg1), rv))>, "Should be returning void here"); MOZ_KnownLive(self)->SetHTML(NonNullHelper(Constify(arg0)), Constify(arg1), rv); if (rv.MaybeSetPendingException(cx, "ShadowRoot.setHTML")) [[unlikely]] { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); SetUseCounter(obj, eUseCounter_ShadowRoot_setHTML); args.rval().setUndefined(); return true; } static const JSJitInfo setHTML_methodinfo = { { (JSJitGetterOp)setHTML }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool setHTMLUnsafe(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.setHTMLUnsafe"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "setHTMLUnsafe", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.setHTMLUnsafe", 1)) { return false; } TrustedHTMLOrString arg0; if (!arg0.Init(cx, args[0], "Argument 1", false)) { return false; } binding_detail::FastSetHTMLUnsafeOptions arg1; if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2", false)) { return false; } Maybe ceReaction; DocGroup* docGroup = self->GetDocGroup(); if (docGroup) { ceReaction.emplace(docGroup->CustomElementReactionsStack(), cx); } FastErrorResult rv; nsIPrincipal* subjectPrincipal; { JS::Realm* realm = js::GetContextRealm(cx); MOZ_ASSERT(realm); JSPrincipals* principals = JS::GetRealmPrincipals(realm); nsIPrincipal* principal = nsJSPrincipals::get(principals); if (principal->IsSystemPrincipal()) { principal = nullptr; } subjectPrincipal = principal; } // NOTE: This assert does NOT call the function. static_assert(std::is_void_vSetHTMLUnsafe(Constify(arg0), Constify(arg1), MOZ_KnownLive(subjectPrincipal), rv))>, "Should be returning void here"); MOZ_KnownLive(self)->SetHTMLUnsafe(Constify(arg0), Constify(arg1), MOZ_KnownLive(subjectPrincipal), rv); if (rv.MaybeSetPendingException(cx, "ShadowRoot.setHTMLUnsafe")) [[unlikely]] { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); SetUseCounter(obj, eUseCounter_ShadowRoot_setHTMLUnsafe); args.rval().setUndefined(); return true; } static const JSJitInfo setHTMLUnsafe_methodinfo = { { (JSJitGetterOp)setHTMLUnsafe }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool getHTML(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.getHTML"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "getHTML", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); binding_detail::FastGetHTMLOptions arg0; if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) { return false; } DOMString result; // NOTE: This assert does NOT call the function. static_assert(std::is_void_vGetHTML(Constify(arg0), result))>, "Should be returning void here"); MOZ_KnownLive(self)->GetHTML(Constify(arg0), result); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) { return false; } return true; } static const JSJitInfo getHTML_methodinfo = { { (JSJitGetterOp)getHTML }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool elementFromPoint(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.elementFromPoint"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "elementFromPoint", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.elementFromPoint", 2)) { return false; } float arg0; if (!ValueToPrimitive(cx, args[0], "Argument 1", &arg0)) { return false; } else if (!std::isfinite(arg0)) { cx.ThrowErrorMessage("Argument 1"); return false; } float arg1; if (!ValueToPrimitive(cx, args[1], "Argument 2", &arg1)) { return false; } else if (!std::isfinite(arg1)) { cx.ThrowErrorMessage("Argument 2"); return false; } auto result(StrongOrRawPtr(MOZ_KnownLive(self)->ElementFromPoint(arg0, arg1))); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo elementFromPoint_methodinfo = { { (JSJitGetterOp)elementFromPoint }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool elementsFromPoint(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.elementsFromPoint"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "elementsFromPoint", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.elementsFromPoint", 2)) { return false; } float arg0; if (!ValueToPrimitive(cx, args[0], "Argument 1", &arg0)) { return false; } else if (!std::isfinite(arg0)) { cx.ThrowErrorMessage("Argument 1"); return false; } float arg1; if (!ValueToPrimitive(cx, args[1], "Argument 2", &arg1)) { return false; } else if (!std::isfinite(arg1)) { cx.ThrowErrorMessage("Argument 2"); return false; } nsTArray> result; // NOTE: This assert does NOT call the function. static_assert(std::is_void_vElementsFromPoint(arg0, arg1, result))>, "Should be returning void here"); MOZ_KnownLive(self)->ElementsFromPoint(arg0, arg1, result); MOZ_ASSERT(!JS_IsExceptionPending(cx)); uint32_t length = result.Length(); JS::Rooted returnArray(cx, JS::NewArrayObject(cx, length)); if (!returnArray) { return false; } // Scope for 'tmp' { JS::Rooted tmp(cx); for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) { // Control block to let us common up the JS_DefineElement calls when there // are different ways to succeed at wrapping the object. do { if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } break; } while (false); if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp, JSPROP_ENUMERATE)) { return false; } } } args.rval().setObject(*returnArray); return true; } static const JSJitInfo elementsFromPoint_methodinfo = { { (JSJitGetterOp)elementsFromPoint }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool nodeFromPoint(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.nodeFromPoint"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "nodeFromPoint", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.nodeFromPoint", 2)) { return false; } float arg0; if (!ValueToPrimitive(cx, args[0], "Argument 1", &arg0)) { return false; } else if (!std::isfinite(arg0)) { cx.ThrowErrorMessage("Argument 1"); return false; } float arg1; if (!ValueToPrimitive(cx, args[1], "Argument 2", &arg1)) { return false; } else if (!std::isfinite(arg1)) { cx.ThrowErrorMessage("Argument 2"); return false; } auto result(StrongOrRawPtr(MOZ_KnownLive(self)->NodeFromPoint(arg0, arg1))); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo nodeFromPoint_methodinfo = { { (JSJitGetterOp)nodeFromPoint }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool nodesFromPoint(JSContext* cx_, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { BindingCallContext cx(cx_, "ShadowRoot.nodesFromPoint"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "nodesFromPoint", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); if (!args.requireAtLeast(cx, "ShadowRoot.nodesFromPoint", 2)) { return false; } float arg0; if (!ValueToPrimitive(cx, args[0], "Argument 1", &arg0)) { return false; } else if (!std::isfinite(arg0)) { cx.ThrowErrorMessage("Argument 1"); return false; } float arg1; if (!ValueToPrimitive(cx, args[1], "Argument 2", &arg1)) { return false; } else if (!std::isfinite(arg1)) { cx.ThrowErrorMessage("Argument 2"); return false; } nsTArray> result; // NOTE: This assert does NOT call the function. static_assert(std::is_void_vNodesFromPoint(arg0, arg1, result))>, "Should be returning void here"); MOZ_KnownLive(self)->NodesFromPoint(arg0, arg1, result); MOZ_ASSERT(!JS_IsExceptionPending(cx)); uint32_t length = result.Length(); JS::Rooted returnArray(cx, JS::NewArrayObject(cx, length)); if (!returnArray) { return false; } // Scope for 'tmp' { JS::Rooted tmp(cx); for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) { // Control block to let us common up the JS_DefineElement calls when there // are different ways to succeed at wrapping the object. do { if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } break; } while (false); if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp, JSPROP_ENUMERATE)) { return false; } } } args.rval().setObject(*returnArray); return true; } static const JSJitInfo nodesFromPoint_methodinfo = { { (JSJitGetterOp)nodesFromPoint }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_activeElement(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "activeElement", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->GetActiveElement())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo activeElement_getterinfo = { { get_activeElement }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_styleSheets(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "styleSheets", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->StyleSheets())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo styleSheets_getterinfo = { { get_styleSheets }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_pointerLockElement(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "pointerLockElement", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->GetPointerLockElement())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo pointerLockElement_getterinfo = { { get_pointerLockElement }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_fullscreenElement(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "fullscreenElement", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->GetFullscreenElement())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } MOZ_CAN_RUN_SCRIPT static bool set_fullscreenElement(JSContext* cx, JS::Handle obj, void* void_self, JSJitSetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "fullscreenElement", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); DeprecationWarning(cx, obj, DeprecatedOperations::eLenientSetter); return true; } static const JSJitInfo fullscreenElement_getterinfo = { { get_fullscreenElement }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static const JSJitInfo fullscreenElement_setterinfo = { { (JSJitGetterOp)set_fullscreenElement }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_mozFullScreenElement(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "mozFullScreenElement", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->GetFullscreenElement())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo mozFullScreenElement_getterinfo = { { get_mozFullScreenElement }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_customElementRegistry(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "customElementRegistry", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->GetCustomElementRegistry())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo customElementRegistry_getterinfo = { { get_customElementRegistry }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool get_pictureInPictureElement(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "pictureInPictureElement", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); auto result(StrongOrRawPtr(MOZ_KnownLive(self)->GetPictureInPictureElement())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!result) { args.rval().setNull(); return true; } if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo pictureInPictureElement_getterinfo = { { get_pictureInPictureElement }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; MOZ_CAN_RUN_SCRIPT static bool getAnimations(JSContext* cx, JS::Handle obj, void* void_self, const JSJitMethodCallArgs& args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "getAnimations", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); nsTArray> result; // NOTE: This assert does NOT call the function. static_assert(std::is_void_vGetAnimations(result))>, "Should be returning void here"); MOZ_KnownLive(self)->GetAnimations(result); MOZ_ASSERT(!JS_IsExceptionPending(cx)); uint32_t length = result.Length(); JS::Rooted returnArray(cx, JS::NewArrayObject(cx, length)); if (!returnArray) { return false; } // Scope for 'tmp' { JS::Rooted tmp(cx); for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) { // Control block to let us common up the JS_DefineElement calls when there // are different ways to succeed at wrapping the object. do { if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } break; } while (false); if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp, JSPROP_ENUMERATE)) { return false; } } } args.rval().setObject(*returnArray); return true; } static const JSJitInfo getAnimations_methodinfo = { { (JSJitGetterOp)getAnimations }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; namespace AdoptedStyleSheets_Binding { class MOZ_EMPTY_BASES ObservableArrayProxyHandler : public mozilla::dom::ObservableArrayProxyHandler { protected: bool OnDeleteItem(JSContext* aCx, JS::Handle aProxy, JS::Handle aValue, uint32_t aIndex) const override; bool SetIndexedValue(JSContext* aCx, JS::Handle aProxy, JS::Handle aBackingList, uint32_t aIndex, JS::Handle aValue, JS::ObjectOpResult& aResult) const override; public: static const ObservableArrayProxyHandler* getInstance(); }; bool ObservableArrayProxyHandler::OnDeleteItem(JSContext* aCx, JS::Handle aProxy, JS::Handle aValue, uint32_t aIndex) const { MOZ_ASSERT(IsObservableArrayProxy(aProxy)); BindingCallContext cx(aCx, "ObservableArray OnDeleteItem"); NonNull decl; if (aValue.isObject()) { { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(aValue, decl, cx); if (NS_FAILED(rv)) { cx.ThrowErrorMessage("Element in ObservableArray backing list", "CSSStyleSheet"); MOZ_ASSERT_UNREACHABLE("The item in ObservableArray backing list is not CSSStyleSheet (Wrapper)?"); return false; } } } else { cx.ThrowErrorMessage("Element in ObservableArray backing list"); MOZ_ASSERT_UNREACHABLE("The item in ObservableArray backing list is not CSSStyleSheet (Wrapper)?"); return false; } const JS::Value& val = js::GetProxyReservedSlot(aProxy, OBSERVABLE_ARRAY_DOM_INTERFACE_SLOT); if (!val.isUndefined()) [[likely]] { auto* interface = static_cast(val.toPrivate()); MOZ_ASSERT(interface); ErrorResult rv; MOZ_KnownLive(interface)->OnDeleteAdoptedStyleSheets(decl, aIndex, rv); if (rv.MaybeSetPendingException(cx)) { return false; } } return true; } bool ObservableArrayProxyHandler::SetIndexedValue(JSContext* aCx, JS::Handle aProxy, JS::Handle aBackingList, uint32_t aIndex, JS::Handle aValue, JS::ObjectOpResult& aResult) const { MOZ_ASSERT(IsObservableArrayProxy(aProxy)); uint32_t oldLen; if (!JS::GetArrayLength(aCx, aBackingList, &oldLen)) { return false; } if (aIndex > oldLen) { return aResult.failBadIndex(); } BindingCallContext cx(aCx, "ObservableArray SetIndexedValue"); NonNull decl; if (aValue.isObject()) { { // Our JSContext should be in the right global to do unwrapping in. nsresult rv = UnwrapObject(aValue, decl, cx); if (NS_FAILED(rv)) { cx.ThrowErrorMessage("Element in ObservableArray backing list", "CSSStyleSheet"); return false; } } } else { cx.ThrowErrorMessage("Element in ObservableArray backing list"); return false; } if (aIndex < oldLen) { JS::Rooted value(aCx); if (!JS_GetElement(aCx, aBackingList, aIndex, &value)) { return false; } if (!OnDeleteItem(aCx, aProxy, value, aIndex)) { return false; } } const JS::Value& val = js::GetProxyReservedSlot(aProxy, OBSERVABLE_ARRAY_DOM_INTERFACE_SLOT); if (!val.isUndefined()) [[likely]] { auto* interface = static_cast(val.toPrivate()); MOZ_ASSERT(interface); ErrorResult rv; MOZ_KnownLive(interface)->OnSetAdoptedStyleSheets(decl, aIndex, rv); if (rv.MaybeSetPendingException(cx)) { return false; } } if (!JS_SetElement(aCx, aBackingList, aIndex, aValue)) { return false; } return aResult.succeed(); } const ObservableArrayProxyHandler* ObservableArrayProxyHandler::getInstance() { static const ObservableArrayProxyHandler instance; return &instance; } } // namespace AdoptedStyleSheets_Binding namespace AdoptedStyleSheetsHelpers { already_AddRefed ElementAt(mozilla::dom::ShadowRoot* self, uint32_t aIndex, ErrorResult& aRv) { MOZ_ASSERT(self); AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because // all we want is to wrap into _some_ scope and then unwrap to find // the reflector, and wrapping has no side-effects. JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible); if (!scope) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } JSAutoRealm tempRealm(cx, scope); JS::Rooted v(cx); if(!ToJSValue(cx, self, &v)) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } // This is a reflector, but due to trying to name things // similarly across method generators, it's called obj here. JS::Rooted obj(cx); obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false); JSAutoRealm reflectorRealm(cx, obj); JS::Rooted backingObj(cx); bool created = false; if (!GetObservableArrayBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance(), self)) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } if (created) { PreserveWrapper(self); } JS::Rooted result(cx); aRv.MightThrowJSException(); if (!JS_GetElement(cx, backingObj, aIndex, &result)) { aRv.StealExceptionFromJSContext(cx); return nullptr; } if (result.isUndefined()) { aRv.Throw(NS_ERROR_NOT_AVAILABLE); return nullptr; } RefPtr rvalDecl; 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(result, rvalDecl, cx); if (NS_FAILED(rv)) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } } return rvalDecl.forget(); } void ReplaceElementAt(mozilla::dom::ShadowRoot* self, uint32_t aIndex, StyleSheet& aValue, ErrorResult& aRv) { MOZ_ASSERT(self); AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because // all we want is to wrap into _some_ scope and then unwrap to find // the reflector, and wrapping has no side-effects. JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible); if (!scope) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } JSAutoRealm tempRealm(cx, scope); JS::Rooted v(cx); if(!ToJSValue(cx, self, &v)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } // This is a reflector, but due to trying to name things // similarly across method generators, it's called obj here. JS::Rooted obj(cx); obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false); JSAutoRealm reflectorRealm(cx, obj); JS::RootedVector argv(cx); if (!argv.resize(1)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } do { if (!GetOrCreateDOMReflector(cx, aValue, argv[0])) { MOZ_ASSERT(JS_IsExceptionPending(cx)); aRv.Throw(NS_ERROR_UNEXPECTED); return; } break; } while (false); JS::Rooted backingObj(cx); bool created = false; if (!GetObservableArrayBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance(), self)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } if (created) { PreserveWrapper(self); } uint32_t length; aRv.MightThrowJSException(); if (!JS::GetArrayLength(cx, backingObj, &length)) { aRv.StealExceptionFromJSContext(cx); return; } if (aIndex > length) { aRv.ThrowRangeError("Invalid index"); return; } aRv.MightThrowJSException(); if (!JS_SetElement(cx, backingObj, aIndex, argv[0])) { aRv.StealExceptionFromJSContext(cx); return; } } void AppendElement(mozilla::dom::ShadowRoot* self, StyleSheet& aValue, ErrorResult& aRv) { MOZ_ASSERT(self); AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because // all we want is to wrap into _some_ scope and then unwrap to find // the reflector, and wrapping has no side-effects. JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible); if (!scope) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } JSAutoRealm tempRealm(cx, scope); JS::Rooted v(cx); if(!ToJSValue(cx, self, &v)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } // This is a reflector, but due to trying to name things // similarly across method generators, it's called obj here. JS::Rooted obj(cx); obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false); JSAutoRealm reflectorRealm(cx, obj); JS::RootedVector argv(cx); if (!argv.resize(1)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } do { if (!GetOrCreateDOMReflector(cx, aValue, argv[0])) { MOZ_ASSERT(JS_IsExceptionPending(cx)); aRv.Throw(NS_ERROR_UNEXPECTED); return; } break; } while (false); JS::Rooted backingObj(cx); bool created = false; if (!GetObservableArrayBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance(), self)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } if (created) { PreserveWrapper(self); } uint32_t length; aRv.MightThrowJSException(); if (!JS::GetArrayLength(cx, backingObj, &length)) { aRv.StealExceptionFromJSContext(cx); return; } aRv.MightThrowJSException(); if (!JS_SetElement(cx, backingObj, length, argv[0])) { aRv.StealExceptionFromJSContext(cx); return; } } void RemoveLastElement(mozilla::dom::ShadowRoot* self, ErrorResult& aRv) { MOZ_ASSERT(self); AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because // all we want is to wrap into _some_ scope and then unwrap to find // the reflector, and wrapping has no side-effects. JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible); if (!scope) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } JSAutoRealm tempRealm(cx, scope); JS::Rooted v(cx); if(!ToJSValue(cx, self, &v)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } // This is a reflector, but due to trying to name things // similarly across method generators, it's called obj here. JS::Rooted obj(cx); obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false); JSAutoRealm reflectorRealm(cx, obj); JS::Rooted backingObj(cx); bool created = false; if (!GetObservableArrayBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance(), self)) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } if (created) { PreserveWrapper(self); } uint32_t length; aRv.MightThrowJSException(); if (!JS::GetArrayLength(cx, backingObj, &length)) { aRv.StealExceptionFromJSContext(cx); return; } if (length == 0) { aRv.Throw(NS_ERROR_NOT_AVAILABLE); return; } aRv.MightThrowJSException(); if (!JS::SetArrayLength(cx, backingObj, length - 1)) { aRv.StealExceptionFromJSContext(cx); return; } } uint32_t Length(mozilla::dom::ShadowRoot* self, ErrorResult& aRv) { MOZ_ASSERT(self); AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because // all we want is to wrap into _some_ scope and then unwrap to find // the reflector, and wrapping has no side-effects. JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible); if (!scope) { aRv.Throw(NS_ERROR_UNEXPECTED); return uint32_t(0); } JSAutoRealm tempRealm(cx, scope); JS::Rooted v(cx); if(!ToJSValue(cx, self, &v)) { aRv.Throw(NS_ERROR_UNEXPECTED); return uint32_t(0); } // This is a reflector, but due to trying to name things // similarly across method generators, it's called obj here. JS::Rooted obj(cx); obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false); JSAutoRealm reflectorRealm(cx, obj); JS::Rooted backingObj(cx); bool created = false; if (!GetObservableArrayBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance(), self)) { aRv.Throw(NS_ERROR_UNEXPECTED); return uint32_t(0); } if (created) { PreserveWrapper(self); } uint32_t retVal; aRv.MightThrowJSException(); if (!JS::GetArrayLength(cx, backingObj, &retVal)) { aRv.StealExceptionFromJSContext(cx); return uint32_t(0); } return retVal; } } // namespace AdoptedStyleSheetsHelpers MOZ_CAN_RUN_SCRIPT static bool get_adoptedStyleSheets(JSContext* cx, JS::Handle obj, void* void_self, JSJitGetterCallArgs args) { AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "adoptedStyleSheets", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); JS::Rooted backingObj(cx); bool created = false; if (!GetObservableArrayBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance(), self)) { return false; } if (created) { PreserveWrapper(self); } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setObject(*backingObj); return true; } MOZ_CAN_RUN_SCRIPT static bool set_adoptedStyleSheets(JSContext* cx_, JS::Handle obj, void* void_self, JSJitSetterCallArgs args) { BindingCallContext cx(cx_, "ShadowRoot.adoptedStyleSheets setter"); AUTO_PROFILER_LABEL_DYNAMIC_FAST( "ShadowRoot", "adoptedStyleSheets", DOM, cx, uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) | uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS)); auto* self = static_cast(void_self); binding_detail::AutoSequence> arg0; if (args[0].isObject()) { JS::ForOfIterator iter(cx); if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) { return false; } if (!iter.valueIsIterable()) { cx.ThrowErrorMessage("Value being assigned", "observable array"); return false; } binding_detail::AutoSequence> &arr = arg0; if (mozilla::Maybe sizeHint = iter.sizeHint()) { if (!arr.SetCapacity(*sizeHint, mozilla::fallible)) { JS_ReportOutOfMemory(cx); return false; } } JS::Rooted temp(cx); while (true) { bool done; if (!iter.next(&temp, &done)) { return false; } if (done) { break; } OwningNonNull* slotPtr = arr.AppendElement(mozilla::fallible); if (!slotPtr) { JS_ReportOutOfMemory(cx); return false; } OwningNonNull& slot = *slotPtr; if (temp.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, slot, cx); if (NS_FAILED(rv)) { cx.ThrowErrorMessage("Element of value being assigned", "CSSStyleSheet"); return false; } } } else { cx.ThrowErrorMessage("Element of value being assigned"); return false; } } } else { cx.ThrowErrorMessage("Value being assigned", "observable array"); return false; } // Unwrap wrappers (including CCW and XrayWrapper) to get the actual Proxy object. JS::Rooted unwrappedObj(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false)); MOZ_ASSERT(IsDOMObject(unwrappedObj)); { JSAutoRealm ar(cx, unwrappedObj); JS::Rooted backingObj(cx); bool created = false; if (!GetObservableArrayBackingObject(cx, unwrappedObj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created, AdoptedStyleSheets_Binding::ObservableArrayProxyHandler::getInstance(), self)) { return false; } if (created) { PreserveWrapper(self); } const ObservableArrayProxyHandler* handler = GetObservableArrayProxyHandler(backingObj); if (!handler->SetLength(cx, backingObj, 0)) { return false; } JS::Rooted val(cx); for (size_t i = 0; i < arg0.Length(); i++) { if (!GetOrCreateDOMReflector(cx, arg0.ElementAt(i), &val)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); return false; } if (!JS_SetElement(cx, backingObj, i, val)) { return false; } } } return true; } static const JSJitInfo adoptedStyleSheets_getterinfo = { { get_adoptedStyleSheets }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ true, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ (DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us"); static const JSJitInfo adoptedStyleSheets_setterinfo = { { (JSJitGetterOp)set_adoptedStyleSheets }, { prototypes::id::ShadowRoot }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static void _finalize(JS::GCContext* gcx, JSObject* obj) { mozilla::dom::ShadowRoot* self = UnwrapPossiblyNotInitializedDOMObject(obj); if (self) { JS::SetNativeObjectReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue()); { JS::Value val = JS::GetNativeObjectReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0)); if (!val.isUndefined()) { JSObject* proxyObj = &val.toObject(); js::SetProxyReservedSlot(proxyObj, OBSERVABLE_ARRAY_DOM_INTERFACE_SLOT, JS::UndefinedValue()); } } ClearWrapper(self, self, obj); if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) { JS::RemoveAssociatedMemory(obj, mallocBytes, JS::MemoryUse::DOMBinding); } AddForDeferredFinalization(self); } } MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = { JS_FNSPEC("getElementById", (GenericMethod), reinterpret_cast(&getElementById_methodinfo), 1, JSPROP_ENUMERATE, nullptr), JS_FS_END, JS_FNSPEC("importNodeAndAppendChildAt", (GenericMethod), reinterpret_cast(&importNodeAndAppendChildAt_methodinfo), 2, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("createElementAndAppendChildAt", (GenericMethod), reinterpret_cast(&createElementAndAppendChildAt_methodinfo), 2, JSPROP_ENUMERATE, nullptr), JS_FS_END, JS_FNSPEC("setHTML", (GenericMethod), reinterpret_cast(&setHTML_methodinfo), 1, JSPROP_ENUMERATE, nullptr), JS_FS_END, JS_FNSPEC("setHTMLUnsafe", (GenericMethod), reinterpret_cast(&setHTMLUnsafe_methodinfo), 1, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("getHTML", (GenericMethod), reinterpret_cast(&getHTML_methodinfo), 0, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("elementFromPoint", (GenericMethod), reinterpret_cast(&elementFromPoint_methodinfo), 2, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("elementsFromPoint", (GenericMethod), reinterpret_cast(&elementsFromPoint_methodinfo), 2, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("getAnimations", (GenericMethod), reinterpret_cast(&getAnimations_methodinfo), 0, JSPROP_ENUMERATE, nullptr), JS_FS_END }; static const PrefableDisablers sMethods_disablers2 = { WebIDLPrefIndex::NoPref, 0, false, OriginTrial(0), &IsChromeOrUAWidget }; static const PrefableDisablers sMethods_disablers5 = { WebIDLPrefIndex::dom_security_sanitizer_enabled, 0, false, OriginTrial(0), nullptr }; static const Prefable sMethods[] = { { nullptr, &sMethods_specs[0] }, { &sMethods_disablers2, &sMethods_specs[2] }, { &sMethods_disablers5, &sMethods_specs[5] }, { nullptr, &sMethods_specs[7] }, { nullptr, nullptr } }; static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); MOZ_GLOBINIT static const JSFunctionSpec sChromeMethods_specs[] = { JS_FNSPEC("setIsUAWidget", (GenericMethod), reinterpret_cast(&setIsUAWidget_methodinfo), 0, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("isUAWidget", (GenericMethod), reinterpret_cast(&isUAWidget_methodinfo), 0, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("nodeFromPoint", (GenericMethod), reinterpret_cast(&nodeFromPoint_methodinfo), 2, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("nodesFromPoint", (GenericMethod), reinterpret_cast(&nodesFromPoint_methodinfo), 2, JSPROP_ENUMERATE, nullptr), JS_FS_END }; static const Prefable sChromeMethods[] = { { nullptr, &sChromeMethods_specs[0] }, { nullptr, nullptr } }; static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = { JSPropertySpec::nativeAccessors("mode", JSPROP_ENUMERATE, GenericGetter, &mode_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("delegatesFocus", JSPROP_ENUMERATE, GenericGetter, &delegatesFocus_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("slotAssignment", JSPROP_ENUMERATE, GenericGetter, &slotAssignment_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("clonable", JSPROP_ENUMERATE, GenericGetter, &clonable_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("serializable", JSPROP_ENUMERATE, GenericGetter, &serializable_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("host", JSPROP_ENUMERATE, GenericGetter, &host_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("onslotchange", JSPROP_ENUMERATE, GenericGetter, &onslotchange_getterinfo, GenericSetter, &onslotchange_setterinfo), JS_PS_END, JSPropertySpec::nativeAccessors("referenceTarget", JSPROP_ENUMERATE, GenericGetter, &referenceTarget_getterinfo, GenericSetter, &referenceTarget_setterinfo), JS_PS_END, JSPropertySpec::nativeAccessors("innerHTML", JSPROP_ENUMERATE, GenericGetter, &innerHTML_getterinfo, GenericSetter, &innerHTML_setterinfo), JSPropertySpec::nativeAccessors("activeElement", JSPROP_ENUMERATE, GenericGetter, &activeElement_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("styleSheets", JSPROP_ENUMERATE, GenericGetter, &styleSheets_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("pointerLockElement", JSPROP_ENUMERATE, GenericGetter, &pointerLockElement_getterinfo, nullptr, nullptr), JSPropertySpec::nativeAccessors("fullscreenElement", JSPROP_ENUMERATE, GenericGetter, &fullscreenElement_getterinfo, GenericSetter, &fullscreenElement_setterinfo), JSPropertySpec::nativeAccessors("mozFullScreenElement", JSPROP_ENUMERATE, GenericGetter, &mozFullScreenElement_getterinfo, nullptr, nullptr), JS_PS_END, JSPropertySpec::nativeAccessors("customElementRegistry", JSPROP_ENUMERATE, GenericGetter, &customElementRegistry_getterinfo, nullptr, nullptr), JS_PS_END, JSPropertySpec::nativeAccessors("pictureInPictureElement", JSPROP_ENUMERATE, GenericGetter, &pictureInPictureElement_getterinfo, nullptr, nullptr), JS_PS_END, JSPropertySpec::nativeAccessors("adoptedStyleSheets", JSPROP_ENUMERATE, GenericGetter, &adoptedStyleSheets_getterinfo, GenericSetter, &adoptedStyleSheets_setterinfo), JS_PS_END }; static const PrefableDisablers sAttributes_disablers8 = { WebIDLPrefIndex::dom_shadowdom_referenceTarget_enabled, 0, false, OriginTrial(0), nullptr }; static const PrefableDisablers sAttributes_disablers17 = { WebIDLPrefIndex::dom_scoped_custom_element_registries_enabled, 0, false, OriginTrial(0), nullptr }; static const PrefableDisablers sAttributes_disablers19 = { WebIDLPrefIndex::dom_media_pip_enabled, 0, false, OriginTrial(0), nullptr }; static const Prefable sAttributes[] = { { nullptr, &sAttributes_specs[0] }, { &sAttributes_disablers8, &sAttributes_specs[8] }, { nullptr, &sAttributes_specs[10] }, { &sAttributes_disablers17, &sAttributes_specs[17] }, { &sAttributes_disablers19, &sAttributes_specs[19] }, { nullptr, &sAttributes_specs[21] }, { nullptr, nullptr } }; static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); static_assert(7 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); static uint16_t sNativeProperties_sortedPropertyIndices[26]; static PropertyInfo sNativeProperties_propertyInfos[26]; static const NativePropertiesN<2> sNativeProperties = { false, 0, false, 0, true, 0 /* sMethods */, true, 1 /* sAttributes */, false, 0, false, 0, false, 0, -1, 26, sNativeProperties_sortedPropertyIndices, { { sMethods, &sNativeProperties_propertyInfos[0] }, { sAttributes, &sNativeProperties_propertyInfos[9] } } }; static_assert(26 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)), "We have a property info count that is oversized"); static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[4]; static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[4]; static const NativePropertiesN<1> sChromeOnlyNativeProperties = { false, 0, false, 0, true, 0 /* sChromeMethods */, false, 0, false, 0, false, 0, false, 0, -1, 4, sChromeOnlyNativeProperties_sortedPropertyIndices, { { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[0] } } }; static_assert(4 < 1ull << (CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount)), "We have a property info count that is oversized"); // This may allocate too many slots, because we only really need // slots for our non-interface-typed members that we cache. But // allocating slots only for those would make the slot index // computations much more complicated, so let's do this the simple // way for now. DEFINE_XRAY_EXPANDO_CLASS_WITH_OPS(static, sXrayExpandoObjectClass, 1, &xpc::XrayExpandoObjectClassOps); bool sNativePropertiesInited = false; const NativePropertyHooks sNativePropertyHooks = { nullptr, { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast(), &sNativePropertiesInited }, prototypes::id::ShadowRoot, constructors::id::ShadowRoot, &sXrayExpandoObjectClass }; static const DOMInterfaceInfo sInterfaceObjectInfo = { { ThrowingConstructor, &sNativePropertyHooks }, DocumentFragment_Binding::GetConstructorObjectHandle, PrototypeTraits::Depth, prototypes::id::ShadowRoot, true, 0, "ShadowRoot", }; static const DOMIfaceAndProtoJSClass sPrototypeClass = { { "ShadowRootPrototype", JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE), JS_NULL_CLASS_OPS, JS_NULL_CLASS_SPEC, JS_NULL_CLASS_EXT, JS_NULL_OBJECT_OPS }, eInterfacePrototype, prototypes::id::ShadowRoot, PrototypeTraits::Depth, &sNativePropertyHooks, DocumentFragment_Binding::GetProtoObject }; static JS::Handle GetProtoObjectHandle(JSContext* aCx); static const JSClassOps sClassOps = { nullptr, /* addProperty */ nullptr, /* delProperty */ nullptr, /* enumerate */ nullptr, /* newEnumerate */ nullptr, /* resolve */ nullptr, /* mayResolve */ _finalize, /* finalize */ nullptr, /* call */ nullptr, /* construct */ nullptr, /* trace */ }; static const DOMJSClass sClass = { { "ShadowRoot", JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_PRESERVES_WRAPPER, &sClassOps, JS_NULL_CLASS_SPEC, &NativeTypeHelpers::sClassExtension, JS_NULL_OBJECT_OPS }, { prototypes::id::EventTarget, prototypes::id::Node, prototypes::id::DocumentFragment, prototypes::id::ShadowRoot, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count }, std::is_base_of_v, &sNativePropertyHooks, GetProtoObjectHandle, GetCCParticipant::Get(), nullptr, NativeTypeHelpers::GetWrapperCache }; static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS, "Must have the right minimal number of reserved slots."); static_assert(2 >= 2, "Must have enough reserved slots."); bool Wrap(JSContext* aCx, mozilla::dom::ShadowRoot* aObject, nsWrapperCache* aCache, JS::Handle aGivenProto, JS::MutableHandle aReflector) { static_assert(!std::is_base_of_v, "Shouldn't have wrappercached things that are not refcounted."); static_assert(std::is_same_v); MOZ_ASSERT(static_cast(aObject) == reinterpret_cast(aObject), "Multiple inheritance for mozilla::dom::DocumentFragment is broken."); MOZ_ASSERT(static_cast(aObject) == reinterpret_cast(aObject), "Multiple inheritance for nsINode is broken."); MOZ_ASSERT(static_cast(aObject) == reinterpret_cast(aObject), "Multiple inheritance for mozilla::dom::EventTarget is broken."); MOZ_ASSERT(ToSupportsIsCorrect(aObject)); MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx)); MOZ_ASSERT(!aCache->GetWrapper(), "You should probably not be using Wrap() directly; use " "GetOrCreateDOMReflector instead"); MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache), "nsISupports must be on our primary inheritance chain"); // If the wrapper cache contains a dead reflector then finalize that // now, ensuring that the finalizer for the old reflector always // runs before the new reflector is created and attached. This // avoids the awkward situation where there are multiple reflector // objects that contain pointers to the same native. if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) { _finalize(nullptr /* unused */, oldReflector); MOZ_ASSERT(!aCache->GetWrapperMaybeDead()); } JS::Rooted global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject())); if (!global) { return false; } MOZ_ASSERT(JS_IsGlobalObject(global)); JS::AssertObjectIsNotGray(global); // That might have ended up wrapping us already, due to the wonders // of XBL. Check for that, and bail out as needed. aReflector.set(aCache->GetWrapper()); if (aReflector) { #ifdef DEBUG AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto); #endif // DEBUG return true; } JSAutoRealm ar(aCx, global); JS::Handle canonicalProto = GetProtoObjectHandle(aCx); if (!canonicalProto) { return false; } JS::Rooted proto(aCx); if (aGivenProto) { proto = aGivenProto; // Unfortunately, while aGivenProto was in the compartment of aCx // coming in, we changed compartments to that of "parent" so may need // to wrap the proto here. if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) { if (!JS_WrapObject(aCx, &proto)) { return false; } } } else { proto = canonicalProto; } BindingJSObjectCreator creator(aCx); creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector); if (!aReflector) { return false; } aCache->SetWrapper(aReflector); creator.InitializationSucceeded(); MOZ_ASSERT(aCache->GetWrapperPreserveColor() && aCache->GetWrapperPreserveColor() == aReflector); // If proto != canonicalProto, we have to preserve our wrapper; // otherwise we won't be able to properly recreate it later, since // we won't know what proto to use. Note that we don't check // aGivenProto here, since it's entirely possible (and even // somewhat common) to have a non-null aGivenProto which is the // same as canonicalProto. if (proto != canonicalProto) { PreserveWrapper(aObject); } return true; } void CreateInterfaceObjects(JSContext* aCx, JS::Handle aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal) { JS::Heap* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::ShadowRoot); JS::Heap* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::ShadowRoot); JS::Handle parentProto(DocumentFragment_Binding::GetProtoObjectHandle(aCx)); if (!parentProto) { return; } JS::Handle constructorProto(DocumentFragment_Binding::GetConstructorObjectHandle(aCx)); if (!constructorProto) { return; } dom::CreateInterfaceObjects(aCx, aGlobal, parentProto, &sPrototypeClass, protoCache, constructorProto, &sInterfaceObjectInfo, 0, false, Span{}, interfaceCache, sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast(), "ShadowRoot", aDefineOnGlobal != DefineInterfaceProperty::No, nullptr, false, nullptr); } static JS::Handle GetProtoObjectHandle(JSContext* aCx) { /* Get the interface prototype object for this class. This will create the object as needed. */ return GetPerInterfaceObjectHandle(aCx, prototypes::id::ShadowRoot, &CreateInterfaceObjects, DefineInterfaceProperty::CheckExposure); } JS::Handle GetConstructorObjectHandle(JSContext* aCx) { /* Get the interface object for this class. This will create the object as needed. */ return GetPerInterfaceObjectHandle(aCx, constructors::id::ShadowRoot, &CreateInterfaceObjects, DefineInterfaceProperty::CheckExposure); } } // namespace ShadowRoot_Binding } // namespace dom } // namespace mozilla