Bug 1550519 - Show a translucent parent highlight when a subgrid is highlighted....
[gecko.git] / dom / base / MaybeCrossOriginObject.h
blob04c985edcf3667bfe34c366e6bdc10693abfb9df
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_MaybeCrossOriginObject_h
8 #define mozilla_dom_MaybeCrossOriginObject_h
10 /**
11 * Shared infrastructure for WindowProxy and Location objects. These
12 * are the objects that can be accessed cross-origin in the HTML
13 * specification.
15 * This class can be inherited from by the relevant proxy handlers to
16 * help implement spec algorithms.
18 * The algorithms this class implements come from
19 * <https://html.spec.whatwg.org/multipage/browsers.html#shared-abstract-operations>,
20 * <https://html.spec.whatwg.org/multipage/window-object.html#the-windowproxy-exotic-object>,
21 * and
22 * <https://html.spec.whatwg.org/multipage/history.html#the-location-interface>.
24 * The class is templated on its base so we can directly implement the things
25 * that should have identical implementations for WindowProxy and Location. The
26 * templating is needed because WindowProxy needs to be a wrapper and Location
27 * shouldn't be one.
30 #include "js/Class.h"
31 #include "js/TypeDecls.h"
32 #include "nsStringFwd.h"
34 namespace mozilla {
35 namespace dom {
37 // Methods that MaybeCrossOriginObject wants that do not depend on the "Base"
38 // template parameter. We can avoid having multiple instantiations of them by
39 // pulling them out into this helper class.
40 class MaybeCrossOriginObjectMixins {
41 public:
42 /**
43 * Implementation of
44 * <https://html.spec.whatwg.org/multipage/browsers.html#isplatformobjectsameorigin-(-o-)>.
45 * "cx" and "obj" may or may not be same-compartment and even when
46 * same-compartment may not be same-Realm. "obj" can be a WindowProxy, a
47 * Window, or a Location.
49 static bool IsPlatformObjectSameOrigin(JSContext* cx, JSObject* obj);
51 protected:
52 /**
53 * Implementation of
54 * <https://html.spec.whatwg.org/multipage/browsers.html#crossorigingetownpropertyhelper-(-o,-p-)>.
56 * "cx" and "obj" are expected to be different-Realm here, and may be
57 * different-compartment. "obj" can be a "WindowProxy" or a "Location" or a
58 * cross-process proxy for one of those.
60 bool CrossOriginGetOwnPropertyHelper(
61 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
62 JS::MutableHandle<JS::PropertyDescriptor> desc) const;
64 /**
65 * Implementation of
66 * <https://html.spec.whatwg.org/multipage/browsers.html#crossoriginpropertyfallback-(-p-)>.
68 * This should be called at the end of getOwnPropertyDescriptor
69 * methods in the cross-origin case.
71 * "cx" and "obj" are expected to be different-Realm here, and may
72 * be different-compartment. "obj" can be a "WindowProxy" or a
73 * "Location" or a cross-process proxy for one of those.
75 static bool CrossOriginPropertyFallback(
76 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
77 JS::MutableHandle<JS::PropertyDescriptor> desc);
79 /**
80 * Implementation of
81 * <https://html.spec.whatwg.org/multipage/browsers.html#crossoriginget-(-o,-p,-receiver-)>.
83 * "cx" and "obj" are expected to be different-Realm here and may be
84 * different-compartment. "obj" can be a "WindowProxy" or a
85 * "Location" or a cross-process proxy for one of those.
87 * "receiver" will be in the compartment of "cx". The return value will
88 * be in the compartment of "cx".
90 static bool CrossOriginGet(JSContext* cx, JS::Handle<JSObject*> obj,
91 JS::Handle<JS::Value> receiver,
92 JS::Handle<jsid> id,
93 JS::MutableHandle<JS::Value> vp);
95 /**
96 * Implementation of
97 * <https://html.spec.whatwg.org/multipage/browsers.html#crossoriginset-(-o,-p,-v,-receiver-)>.
99 * "cx" and "obj" are expected to be different-Realm here and may be
100 * different-compartment. "obj" can be a "WindowProxy" or a
101 * "Location" or a cross-process proxy for one of those.
103 * "receiver" and "v" will be in the compartment of "cx".
105 static bool CrossOriginSet(JSContext* cx, JS::Handle<JSObject*> obj,
106 JS::Handle<jsid> id, JS::Handle<JS::Value> v,
107 JS::Handle<JS::Value> receiver,
108 JS::ObjectOpResult& result);
111 * Utility method to ensure a holder for cross-origin properties for the
112 * current global of the JSContext.
114 * When this is called, "cx" and "obj" are _always_ different-Realm, because
115 * this is only used in cross-origin situations. The "holder" return value is
116 * always in the Realm of "cx".
118 * "obj" is the object which has space to store the collection of holders in
119 * the given slot.
121 * "attributes" and "methods" are the cross-origin attributes and methods we
122 * care about, which should get defined on holders.
124 static bool EnsureHolder(JSContext* cx, JS::Handle<JSObject*> obj,
125 size_t slot, JSPropertySpec* attributes,
126 JSFunctionSpec* methods,
127 JS::MutableHandle<JSObject*> holder);
130 * Ensures we have a holder object for the current Realm. When this is
131 * called, "obj" is guaranteed to not be same-Realm with "cx", because this
132 * is only used for cross-origin cases.
134 * Subclasses are expected to implement this by calling our static
135 * EnsureHolder with the appropriate arguments.
137 virtual bool EnsureHolder(JSContext* cx, JS::Handle<JSObject*> proxy,
138 JS::MutableHandle<JSObject*> holder) const = 0;
141 * Report a cross-origin denial for a property named by aId. Always
142 * returns false, so it can be used as "return
143 * ReportCrossOriginDenial(...);".
145 static bool ReportCrossOriginDenial(JSContext* aCx, JS::Handle<jsid> aId,
146 const nsACString& aAccessType);
149 // A proxy handler for objects that may be cross-origin objects. Whether they
150 // actually _are_ cross-origin objects can change dynamically if document.domain
151 // is set.
152 template <typename Base>
153 class MaybeCrossOriginObject : public Base,
154 public MaybeCrossOriginObjectMixins {
155 protected:
156 template <typename... Args>
157 constexpr MaybeCrossOriginObject(Args&&... aArgs)
158 : Base(std::forward<Args>(aArgs)...) {}
161 * Implementation of [[GetPrototypeOf]] as defined in
162 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-getprototypeof>
163 * and
164 * <https://html.spec.whatwg.org/multipage/history.html#location-getprototypeof>.
166 * Our prototype-storage model looks quite different from the spec's, so we
167 * need to implement some hooks that don't directly map to the spec.
169 * "proxy" is the WindowProxy or Location involved. It may or may not be
170 * same-compartment with cx.
172 * "protop" is the prototype value (possibly null). It is guaranteed to be
173 * same-compartment with cx after this function returns successfully.
175 bool getPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
176 JS::MutableHandle<JSObject*> protop) const final;
179 * Hook for doing the OrdinaryGetPrototypeOf bits that [[GetPrototypeOf]] does
180 * in the spec. Location and WindowProxy store that information somewhat
181 * differently.
183 * The prototype should come from the Realm of "cx".
185 virtual JSObject* getSameOriginPrototype(JSContext* cx) const = 0;
188 * Implementation of [[SetPrototypeOf]] as defined in
189 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-setprototypeof>
190 * and
191 * <https://html.spec.whatwg.org/multipage/history.html#location-setprototypeof>.
193 * "proxy" is the WindowProxy or Location object involved. It may or may not
194 * be same-compartment with "cx".
196 * "proto" is the new prototype object (possibly null). It must be
197 * same-compartment with "cx".
199 bool setPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
200 JS::Handle<JSObject*> proto,
201 JS::ObjectOpResult& result) const final;
204 * Our non-standard getPrototypeIfOrdinary hook. We don't need to implement
205 * setImmutablePrototype, because the default behavior of not allowing it is
206 * fine for us.
208 bool getPrototypeIfOrdinary(JSContext* cx, JS::Handle<JSObject*> proxy,
209 bool* isOrdinary,
210 JS::MutableHandle<JSObject*> protop) const final;
213 * Implementation of [[IsExtensible]] as defined in
214 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-isextensible>
215 * and
216 * <https://html.spec.whatwg.org/multipage/history.html#location-isextensible>.
218 bool isExtensible(JSContext* cx, JS::Handle<JSObject*> proxy,
219 bool* extensible) const final;
222 * Implementation of [[PreventExtensions]] as defined in
223 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-preventextensions>
224 * and
225 * <https://html.spec.whatwg.org/multipage/history.html#location-preventextensions>.
227 bool preventExtensions(JSContext* cx, JS::Handle<JSObject*> proxy,
228 JS::ObjectOpResult& result) const final;
231 * Implementation of [[GetOwnProperty]] is completely delegated to subclasses.
233 * "proxy" is the WindowProxy or Location object involved. It may or may not
234 * be same-compartment with cx.
236 bool getOwnPropertyDescriptor(
237 JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
238 JS::MutableHandle<JS::PropertyDescriptor> desc) const override = 0;
241 * Implementation of [[DefineOwnProperty]] as defined in
242 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-defineownproperty>
243 * and
244 * <https://html.spec.whatwg.org/multipage/history.html#location-defineownproperty>.
245 * "proxy" is the WindowProxy or Location object involved. It may or may not
246 * be same-compartment with cx.
249 bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy,
250 JS::Handle<jsid> id,
251 JS::Handle<JS::PropertyDescriptor> desc,
252 JS::ObjectOpResult& result) const final;
255 * Some of our base classes define _another_ virtual defineProperty, and we
256 * get overloaded-virtual warnings as a result due to us hiding it, if we
257 * don't pull it in here.
259 using Base::defineProperty;
262 * Hook for handling the same-origin case in defineProperty.
264 * "proxy" is the WindowProxy or Location object involved. It will be
265 * same-compartment with cx.
267 * "desc" is a the descriptor being defined. It will be same-compartment with
268 * cx.
270 virtual bool definePropertySameOrigin(JSContext* cx,
271 JS::Handle<JSObject*> proxy,
272 JS::Handle<jsid> id,
273 JS::Handle<JS::PropertyDescriptor> desc,
274 JS::ObjectOpResult& result) const = 0;
277 * Implementation of [[Get]] is completely delegated to subclasses.
279 * "proxy" is the WindowProxy or Location object involved. It may or may not
280 * be same-compartment with "cx".
282 * "receiver" is the receiver ("this") for the get. It will be
283 * same-compartment with "cx"
285 * "vp" is the return value. It will be same-compartment with "cx".
287 bool get(JSContext* cx, JS::Handle<JSObject*> proxy,
288 JS::Handle<JS::Value> receiver, JS::Handle<jsid> id,
289 JS::MutableHandle<JS::Value> vp) const override = 0;
292 * Implementation of [[Set]] is completely delegated to subclasses.
294 * "proxy" is the WindowProxy or Location object involved. It may or may not
295 * be same-compartment with "cx".
297 * "v" is the value being set. It will be same-compartment with "cx".
299 * "receiver" is the receiver ("this") for the set. It will be
300 * same-compartment with "cx".
302 bool set(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
303 JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
304 JS::ObjectOpResult& result) const override = 0;
307 * Implementation of [[Delete]] is completely delegated to subclasses.
309 * "proxy" is the WindowProxy or Location object involved. It may or may not
310 * be same-compartment with "cx".
312 bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
313 JS::ObjectOpResult& result) const override = 0;
316 * Spidermonkey-internal hook for enumerating objects.
318 bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
319 JS::MutableHandleVector<jsid> props) const final;
322 * Spidermonkey-internal hook used for instanceof. We need to override this
323 * because otherwise we can end up doing instanceof work in the wrong
324 * compartment.
326 bool hasInstance(JSContext* cx, JS::Handle<JSObject*> proxy,
327 JS::MutableHandle<JS::Value> v, bool* bp) const final;
330 * Spidermonkey-internal hook used by Object.prototype.toString. Subclasses
331 * need to implement this, because we don't know what className they want.
332 * Except in the cross-origin case, when we could maybe handle it...
334 const char* className(JSContext* cx,
335 JS::Handle<JSObject*> proxy) const override = 0;
338 } // namespace dom
339 } // namespace mozilla
341 #endif /* mozilla_dom_MaybeCrossOriginObject_h */