Bug 1683281 - Part 4: Add helper method to get ObservableArray backing object; r=peterv

Depends on D112278

Differential Revision: https://phabricator.services.mozilla.com/D112279
This commit is contained in:
Edgar Chen 2022-03-10 22:44:28 +00:00
Родитель 2ecc5e3af1
Коммит f56fbb0c77
2 изменённых файлов: 41 добавлений и 10 удалений

Просмотреть файл

@ -65,6 +65,7 @@
#include "mozilla/dom/HTMLElementBinding.h"
#include "mozilla/dom/HTMLEmbedElementBinding.h"
#include "mozilla/dom/MaybeCrossOriginObject.h"
#include "mozilla/dom/ObservableArrayProxyHandler.h"
#include "mozilla/dom/ReportingUtils.h"
#include "mozilla/dom/XULElementBinding.h"
#include "mozilla/dom/XULFrameElementBinding.h"
@ -3505,11 +3506,11 @@ nsresult UnwrapWindowProxyArg(JSContext* cx, JS::Handle<JSObject*> src,
return NS_OK;
}
template <decltype(JS::NewMapObject) Method>
bool GetMaplikeSetlikeBackingObject(JSContext* aCx, JS::Handle<JSObject*> aObj,
size_t aSlotIndex,
JS::MutableHandle<JSObject*> aBackingObj,
bool* aBackingObjCreated) {
template <auto Method, typename... Args>
static bool GetBackingObject(JSContext* aCx, JS::Handle<JSObject*> aObj,
size_t aSlotIndex,
JS::MutableHandle<JSObject*> aBackingObj,
bool* aBackingObjCreated, Args... aArgs) {
JS::Rooted<JSObject*> reflector(aCx);
reflector = IsDOMObject(aObj)
? aObj
@ -3526,7 +3527,7 @@ bool GetMaplikeSetlikeBackingObject(JSContext* aCx, JS::Handle<JSObject*> aObj,
{
JSAutoRealm ar(aCx, reflector);
JS::Rooted<JSObject*> newBackingObj(aCx);
newBackingObj.set(Method(aCx));
newBackingObj.set(Method(aCx, aArgs...));
if (NS_WARN_IF(!newBackingObj)) {
return false;
}
@ -3549,16 +3550,35 @@ bool GetMaplikeBackingObject(JSContext* aCx, JS::Handle<JSObject*> aObj,
size_t aSlotIndex,
JS::MutableHandle<JSObject*> aBackingObj,
bool* aBackingObjCreated) {
return GetMaplikeSetlikeBackingObject<JS::NewMapObject>(
aCx, aObj, aSlotIndex, aBackingObj, aBackingObjCreated);
return GetBackingObject<JS::NewMapObject>(aCx, aObj, aSlotIndex, aBackingObj,
aBackingObjCreated);
}
bool GetSetlikeBackingObject(JSContext* aCx, JS::Handle<JSObject*> aObj,
size_t aSlotIndex,
JS::MutableHandle<JSObject*> aBackingObj,
bool* aBackingObjCreated) {
return GetMaplikeSetlikeBackingObject<JS::NewSetObject>(
aCx, aObj, aSlotIndex, aBackingObj, aBackingObjCreated);
return GetBackingObject<JS::NewSetObject>(aCx, aObj, aSlotIndex, aBackingObj,
aBackingObjCreated);
}
static inline JSObject* NewObservableArrayProxyObject(
JSContext* aCx, const ObservableArrayProxyHandler* aHandler) {
JS::RootedObject target(aCx, JS::NewArrayObject(aCx, 0));
if (NS_WARN_IF(!target)) {
return nullptr;
}
JS::RootedValue targetValue(aCx, JS::ObjectValue(*target));
return js::NewProxyObject(aCx, aHandler, targetValue, nullptr);
}
bool GetObservableArrayBackingObject(
JSContext* aCx, JS::Handle<JSObject*> aObj, size_t aSlotIndex,
JS::MutableHandle<JSObject*> aBackingObj, bool* aBackingObjCreated,
const ObservableArrayProxyHandler* aHandler) {
return GetBackingObject<NewObservableArrayProxyObject>(
aCx, aObj, aSlotIndex, aBackingObj, aBackingObjCreated, aHandler);
}
bool ForEachHandler(JSContext* aCx, unsigned aArgc, JS::Value* aVp) {

Просмотреть файл

@ -62,6 +62,7 @@ class CustomElementReactionsStack;
class Document;
class EventTarget;
class MessageManagerGlobal;
class ObservableArrayProxyHandler;
class DedicatedWorkerGlobalScope;
template <typename KeyType, typename ValueType>
class Record;
@ -3104,6 +3105,16 @@ bool GetSetlikeBackingObject(JSContext* aCx, JS::Handle<JSObject*> aObj,
JS::MutableHandle<JSObject*> aBackingObj,
bool* aBackingObjCreated);
// Unpacks backing object (ES Proxy exotic object) from the reserved slot of a
// reflector for a observableArray attribute. If backing object does not exist,
// creates backing object in the compartment of the reflector involved, making
// this safe to use across compartments/via xrays. Return values of these
// methods will always be in the context compartment.
bool GetObservableArrayBackingObject(
JSContext* aCx, JS::Handle<JSObject*> aObj, size_t aSlotIndex,
JS::MutableHandle<JSObject*> aBackingObj, bool* aBackingObjCreated,
const ObservableArrayProxyHandler* aHandler);
// Get the desired prototype object for an object construction from the given
// CallArgs. The CallArgs must be for a constructor call. The
// aProtoId/aCreator arguments are used to get a default if we don't find a