Bug 1842509 - Remove media.webvtt.regions.enabled pref r=alwu,webidl,smaug,peterv
[gecko.git] / dom / bindings / RemoteObjectProxy.h
blob8a8ef7270ce231f9ff3233e4507408136ed9f1f4
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_RemoteObjectProxy_h
8 #define mozilla_dom_RemoteObjectProxy_h
10 #include "js/Proxy.h"
11 #include "mozilla/Maybe.h"
12 #include "mozilla/dom/MaybeCrossOriginObject.h"
13 #include "mozilla/dom/PrototypeList.h"
14 #include "xpcpublic.h"
16 namespace mozilla::dom {
18 class BrowsingContext;
20 /**
21 * Base class for RemoteObjectProxy. Implements the pieces of the handler that
22 * don't depend on properties/methods of the specific WebIDL interface that this
23 * proxy implements.
25 class RemoteObjectProxyBase : public js::BaseProxyHandler,
26 public MaybeCrossOriginObjectMixins {
27 protected:
28 explicit constexpr RemoteObjectProxyBase(prototypes::ID aPrototypeID)
29 : BaseProxyHandler(&sCrossOriginProxyFamily, false),
30 mPrototypeID(aPrototypeID) {}
32 public:
33 bool finalizeInBackground(const JS::Value& priv) const final { return false; }
35 // Standard internal methods
36 bool getOwnPropertyDescriptor(
37 JSContext* aCx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId,
38 JS::MutableHandle<Maybe<JS::PropertyDescriptor>> aDesc) const override;
39 bool ownPropertyKeys(JSContext* aCx, JS::Handle<JSObject*> aProxy,
40 JS::MutableHandleVector<jsid> aProps) const override;
41 bool defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy,
42 JS::Handle<jsid> aId,
43 JS::Handle<JS::PropertyDescriptor> aDesc,
44 JS::ObjectOpResult& result) const final;
45 bool delete_(JSContext* aCx, JS::Handle<JSObject*> aProxy,
46 JS::Handle<jsid> aId, JS::ObjectOpResult& aResult) const final;
48 bool getPrototypeIfOrdinary(JSContext* aCx, JS::Handle<JSObject*> aProxy,
49 bool* aIsOrdinary,
50 JS::MutableHandle<JSObject*> aProtop) const final;
52 bool preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy,
53 JS::ObjectOpResult& aResult) const final;
54 bool isExtensible(JSContext* aCx, JS::Handle<JSObject*> aProxy,
55 bool* aExtensible) const final;
57 bool get(JSContext* cx, JS::Handle<JSObject*> aProxy,
58 JS::Handle<JS::Value> aReceiver, JS::Handle<jsid> aId,
59 JS::MutableHandle<JS::Value> aVp) const final;
60 bool set(JSContext* cx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId,
61 JS::Handle<JS::Value> aValue, JS::Handle<JS::Value> aReceiver,
62 JS::ObjectOpResult& aResult) const final;
64 // SpiderMonkey extensions
65 bool getOwnEnumerablePropertyKeys(
66 JSContext* aCx, JS::Handle<JSObject*> aProxy,
67 JS::MutableHandleVector<jsid> aProps) const override;
68 const char* className(JSContext* aCx,
69 JS::Handle<JSObject*> aProxy) const final;
71 // Cross origin objects like RemoteWindowProxy should not participate in
72 // private fields.
73 virtual bool throwOnPrivateField() const override { return true; }
75 bool isCallable(JSObject* aObj) const final { return false; }
76 bool isConstructor(JSObject* aObj) const final { return false; }
78 virtual void NoteChildren(JSObject* aProxy,
79 nsCycleCollectionTraversalCallback& aCb) const = 0;
81 static void* GetNative(JSObject* aProxy) {
82 return js::GetProxyPrivate(aProxy).toPrivate();
85 /**
86 * Returns true if aProxy is a cross-process proxy that represents
87 * an object implementing the WebIDL interface for aProtoID. aProxy
88 * should be a proxy object.
90 static inline bool IsRemoteObjectProxy(JSObject* aProxy,
91 prototypes::ID aProtoID) {
92 const js::BaseProxyHandler* handler = js::GetProxyHandler(aProxy);
93 return handler->family() == &sCrossOriginProxyFamily &&
94 static_cast<const RemoteObjectProxyBase*>(handler)->mPrototypeID ==
95 aProtoID;
98 /**
99 * Returns true if aProxy is a cross-process proxy, no matter which
100 * interface it represents. aProxy should be a proxy object.
102 static inline bool IsRemoteObjectProxy(JSObject* aProxy) {
103 const js::BaseProxyHandler* handler = js::GetProxyHandler(aProxy);
104 return handler->family() == &sCrossOriginProxyFamily;
107 protected:
109 * Gets an existing cached proxy object, or creates a new one and caches it.
110 * aProxy will be null on failure. aNewObjectCreated is set to true if a new
111 * object was created, callers probably need to addref the native in that
112 * case. aNewObjectCreated can be true even if aProxy is null, if something
113 * failed after creating the object.
115 void GetOrCreateProxyObject(JSContext* aCx, void* aNative,
116 const JSClass* aClasp,
117 JS::Handle<JSObject*> aTransplantTo,
118 JS::MutableHandle<JSObject*> aProxy,
119 bool& aNewObjectCreated) const;
121 const prototypes::ID mPrototypeID;
123 friend struct SetDOMProxyInformation;
124 static const char sCrossOriginProxyFamily;
128 * Proxy handler for proxy objects that represent an object implementing a
129 * WebIDL interface that has cross-origin accessible properties/methods, and
130 * which lives in a different process. The WebIDL code generator will create
131 * arrays of cross-origin accessible properties/methods that can be used as
132 * arguments to this template.
134 * The properties and methods can be cached on a holder JSObject, stored in a
135 * reserved slot on the proxy object.
137 * The proxy objects that use a handler derived from this one are stored in a
138 * hash map in the JS compartment's private (@see
139 * xpc::CompartmentPrivate::GetRemoteProxyMap).
141 template <class Native, const CrossOriginProperties& P>
142 class RemoteObjectProxy : public RemoteObjectProxyBase {
143 public:
144 void finalize(JS::GCContext* aGcx, JSObject* aProxy) const final {
145 auto native = static_cast<Native*>(GetNative(aProxy));
146 RefPtr<Native> self(dont_AddRef(native));
149 void GetProxyObject(JSContext* aCx, Native* aNative,
150 JS::Handle<JSObject*> aTransplantTo,
151 JS::MutableHandle<JSObject*> aProxy) const {
152 bool objectCreated = false;
153 GetOrCreateProxyObject(aCx, aNative, &sClass, aTransplantTo, aProxy,
154 objectCreated);
155 if (objectCreated) {
156 NS_ADDREF(aNative);
160 protected:
161 using RemoteObjectProxyBase::RemoteObjectProxyBase;
163 private:
164 bool EnsureHolder(JSContext* aCx, JS::Handle<JSObject*> aProxy,
165 JS::MutableHandle<JSObject*> aHolder) const final {
166 return MaybeCrossOriginObjectMixins::EnsureHolder(
167 aCx, aProxy, /* slot = */ 0, P, aHolder);
170 static const JSClass sClass;
174 * Returns true if aObj is a cross-process proxy object that
175 * represents an object implementing the WebIDL interface for
176 * aProtoID.
178 inline bool IsRemoteObjectProxy(JSObject* aObj, prototypes::ID aProtoID) {
179 if (!js::IsProxy(aObj)) {
180 return false;
182 return RemoteObjectProxyBase::IsRemoteObjectProxy(aObj, aProtoID);
186 * Returns true if aObj is a cross-process proxy object, no matter
187 * which WebIDL interface it corresponds to.
189 inline bool IsRemoteObjectProxy(JSObject* aObj) {
190 if (!js::IsProxy(aObj)) {
191 return false;
193 return RemoteObjectProxyBase::IsRemoteObjectProxy(aObj);
197 * Return the browsing context for this remote outer window proxy.
198 * Only call this function on remote outer window proxies.
200 BrowsingContext* GetBrowsingContext(JSObject* aProxy);
202 } // namespace mozilla::dom
204 #endif /* mozilla_dom_RemoteObjectProxy_h */