mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-17 20:57:30 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
20b787a4df
37 changed files with 523 additions and 153 deletions
|
|
@ -824,6 +824,10 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||||
aVisitor.mCanHandle = true;
|
aVisitor.mCanHandle = true;
|
||||||
aVisitor.mMayHaveListenerManager = HasListenerManager();
|
aVisitor.mMayHaveListenerManager = HasListenerManager();
|
||||||
|
|
||||||
|
if (IsInShadowTree()) {
|
||||||
|
aVisitor.mItemInShadowTree = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't propagate mouseover and mouseout events when mouse is moving
|
// Don't propagate mouseover and mouseout events when mouse is moving
|
||||||
// inside chrome access only content.
|
// inside chrome access only content.
|
||||||
bool isAnonForEvents = IsRootOfChromeAccessOnlySubtree();
|
bool isAnonForEvents = IsRootOfChromeAccessOnlySubtree();
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
#include "mozilla/dom/HTMLTemplateElement.h"
|
#include "mozilla/dom/HTMLTemplateElement.h"
|
||||||
#include "mozilla/dom/ipc/BlobChild.h"
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
#include "mozilla/dom/ipc/BlobParent.h"
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
|
#include "mozilla/dom/MessagePort.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "mozilla/dom/TabParent.h"
|
#include "mozilla/dom/TabParent.h"
|
||||||
|
|
@ -9993,3 +9994,71 @@ nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement)
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsresult
|
||||||
|
nsContentUtils::CreateJSValueFromSequenceOfObject(JSContext* aCx,
|
||||||
|
const Sequence<JSObject*>& aTransfer,
|
||||||
|
JS::MutableHandle<JS::Value> aValue)
|
||||||
|
{
|
||||||
|
if (aTransfer.IsEmpty()) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aTransfer.Length()));
|
||||||
|
if (!array) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < aTransfer.Length(); ++i) {
|
||||||
|
JS::Rooted<JSObject*> object(aCx, aTransfer[i]);
|
||||||
|
if (!object) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!JS_DefineElement(aCx, array, i, object,
|
||||||
|
JSPROP_ENUMERATE))) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aValue.setObject(*array);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void nsContentUtils::StructuredClone(JSContext* aCx,
|
||||||
|
nsIGlobalObject* aGlobal,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
JS::MutableHandle<JS::Value> aRv,
|
||||||
|
ErrorResult& aError) {
|
||||||
|
JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
|
||||||
|
aError = nsContentUtils::CreateJSValueFromSequenceOfObject(
|
||||||
|
aCx, aOptions.mTransfer, &transferArray);
|
||||||
|
if (NS_WARN_IF(aError.Failed())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::CloneDataPolicy clonePolicy;
|
||||||
|
// FIXME: Uncomment once bug 1609990 and bug 1611855 lands.
|
||||||
|
//clonePolicy.allowIntraClusterClonableSharedObjects();
|
||||||
|
//clonePolicy.allowSharedMemoryObjects();
|
||||||
|
|
||||||
|
StructuredCloneHolder holder(StructuredCloneHolder::CloningSupported,
|
||||||
|
StructuredCloneHolder::TransferringSupported,
|
||||||
|
JS::StructuredCloneScope::SameProcessDifferentThread);
|
||||||
|
holder.Write(aCx, aValue, transferArray, clonePolicy, aError);
|
||||||
|
if (NS_WARN_IF(aError.Failed())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Pass clonePolicy.
|
||||||
|
//holder.Read(this, aCx, aRv, clonePolicy, aError);
|
||||||
|
holder.Read(aGlobal, aCx, aRv, aError);
|
||||||
|
if (NS_WARN_IF(aError.Failed())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsTArray<RefPtr<MessagePort>> ports = holder.TakeTransferredPorts();
|
||||||
|
Unused << ports;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ class nsIContentParent;
|
||||||
class TabChild;
|
class TabChild;
|
||||||
class Selection;
|
class Selection;
|
||||||
class TabParent;
|
class TabParent;
|
||||||
|
struct StructuredSerializeOptions;
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
@ -2812,6 +2813,23 @@ public:
|
||||||
static bool
|
static bool
|
||||||
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
|
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
CreateJSValueFromSequenceOfObject(JSContext* aCx,
|
||||||
|
const mozilla::dom::Sequence<JSObject*>& aTransfer,
|
||||||
|
JS::MutableHandle<JS::Value> aValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implements the structured cloning algorithm as described by
|
||||||
|
* https://html.spec.whatwg.org/#structured-cloning.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
StructuredClone(JSContext* aCx,
|
||||||
|
nsIGlobalObject* aGlobal,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
const mozilla::dom::StructuredSerializeOptions& aOptions,
|
||||||
|
JS::MutableHandle<JS::Value> aRv,
|
||||||
|
mozilla::ErrorResult& aError);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool InitializeEventTable();
|
static bool InitializeEventTable();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -909,7 +909,8 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
|
||||||
mOuterWindow(aOuterWindow),
|
mOuterWindow(aOuterWindow),
|
||||||
// Make sure no actual window ends up with mWindowID == 0
|
// Make sure no actual window ends up with mWindowID == 0
|
||||||
mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
|
mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
|
||||||
mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false)
|
mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false),
|
||||||
|
mEvent(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
@ -5245,6 +5246,16 @@ nsGlobalWindow::SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
|
||||||
SetOpenerWindow(outer, false);
|
SetOpenerWindow(outer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGlobalWindow::GetEvent(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval)
|
||||||
|
{
|
||||||
|
if (mEvent) {
|
||||||
|
Unused << nsContentUtils::WrapNative(aCx, mEvent, aRetval);
|
||||||
|
} else {
|
||||||
|
aRetval.setUndefined();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGlobalWindow::GetStatusOuter(nsAString& aStatus)
|
nsGlobalWindow::GetStatusOuter(nsAString& aStatus)
|
||||||
{
|
{
|
||||||
|
|
@ -8886,30 +8897,33 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
nsGlobalWindow::PostMessageMoz(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
const nsAString& aTargetOrigin,
|
const nsAString& aTargetOrigin,
|
||||||
const Optional<Sequence<JS::Value>>& aTransfer,
|
const Sequence<JSObject*>& aTransfer,
|
||||||
nsIPrincipal& aSubjectPrincipal,
|
nsIPrincipal& aSubjectPrincipal,
|
||||||
ErrorResult& aError)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
|
||||||
if (aTransfer.WasPassed()) {
|
aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransfer,
|
||||||
const Sequence<JS::Value >& values = aTransfer.Value();
|
&transferArray);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
// The input sequence only comes from the generated bindings code, which
|
return;
|
||||||
// ensures it is rooted.
|
|
||||||
JS::HandleValueArray elements =
|
|
||||||
JS::HandleValueArray::fromMarkedLocation(values.Length(), values.Elements());
|
|
||||||
|
|
||||||
transferArray = JS::ObjectOrNullValue(JS_NewArrayObject(aCx, elements));
|
|
||||||
if (transferArray.isNull()) {
|
|
||||||
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray,
|
PostMessageMoz(aCx, aMessage, aTargetOrigin, transferArray,
|
||||||
aSubjectPrincipal, aError);
|
aSubjectPrincipal, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGlobalWindow::PostMessageMoz(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const WindowPostMessageOptions& aOptions,
|
||||||
|
nsIPrincipal& aSubjectPrincipal,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
PostMessageMoz(aCx, aMessage, aOptions.mTargetOrigin, aOptions.mTransfer,
|
||||||
|
aSubjectPrincipal, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
class nsCloseEvent : public Runnable {
|
class nsCloseEvent : public Runnable {
|
||||||
|
|
@ -14641,6 +14655,17 @@ nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/#structured-cloning
|
||||||
|
void
|
||||||
|
nsGlobalWindow::StructuredClone(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
JS::MutableHandle<JS::Value> aRv,
|
||||||
|
ErrorResult& aError)
|
||||||
|
{
|
||||||
|
nsContentUtils::StructuredClone(aCx, this, aValue, aOptions, aRv, aError);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper called by methods that move/resize the window,
|
// Helper called by methods that move/resize the window,
|
||||||
// to ensure the presContext (if any) is aware of resolution
|
// to ensure the presContext (if any) is aware of resolution
|
||||||
// change that may happen in multi-monitor configuration.
|
// change that may happen in multi-monitor configuration.
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ class TabGroup;
|
||||||
class Timeout;
|
class Timeout;
|
||||||
class U2F;
|
class U2F;
|
||||||
class WakeLock;
|
class WakeLock;
|
||||||
|
struct WindowPostMessageOptions;
|
||||||
class Worklet;
|
class Worklet;
|
||||||
namespace cache {
|
namespace cache {
|
||||||
class CacheStorage;
|
class CacheStorage;
|
||||||
|
|
@ -845,6 +846,7 @@ public:
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetOpener() override;
|
already_AddRefed<nsPIDOMWindowOuter> GetOpener() override;
|
||||||
void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
|
void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
|
void GetEvent(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval);
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetParentOuter();
|
already_AddRefed<nsPIDOMWindowOuter> GetParentOuter();
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetParent(mozilla::ErrorResult& aError);
|
already_AddRefed<nsPIDOMWindowOuter> GetParent(mozilla::ErrorResult& aError);
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetParent() override;
|
already_AddRefed<nsPIDOMWindowOuter> GetParent() override;
|
||||||
|
|
@ -933,7 +935,12 @@ public:
|
||||||
void Print(mozilla::ErrorResult& aError);
|
void Print(mozilla::ErrorResult& aError);
|
||||||
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const nsAString& aTargetOrigin,
|
const nsAString& aTargetOrigin,
|
||||||
const mozilla::dom::Optional<mozilla::dom::Sequence<JS::Value > >& aTransfer,
|
const mozilla::dom::Sequence<JSObject*>& aTransfer,
|
||||||
|
nsIPrincipal& aSubjectPrincipal,
|
||||||
|
mozilla::ErrorResult& aRv);
|
||||||
|
void PostMessageMoz(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const mozilla::dom::WindowPostMessageOptions& aOptions,
|
||||||
nsIPrincipal& aSubjectPrincipal,
|
nsIPrincipal& aSubjectPrincipal,
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
int32_t SetTimeout(JSContext* aCx, mozilla::dom::Function& aFunction,
|
int32_t SetTimeout(JSContext* aCx, mozilla::dom::Function& aFunction,
|
||||||
|
|
@ -1177,6 +1184,10 @@ public:
|
||||||
const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
|
const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
|
||||||
mozilla::ErrorResult& aRv);
|
mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
|
void StructuredClone(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||||
|
const mozilla::dom::StructuredSerializeOptions& aOptions,
|
||||||
|
JS::MutableHandle<JS::Value> aRv,
|
||||||
|
mozilla::ErrorResult& aError);
|
||||||
|
|
||||||
// ChromeWindow bits. Do NOT call these unless your window is in
|
// ChromeWindow bits. Do NOT call these unless your window is in
|
||||||
// fact an nsGlobalChromeWindow.
|
// fact an nsGlobalChromeWindow.
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,10 @@ protected:
|
||||||
// we have what it takes to do so.
|
// we have what it takes to do so.
|
||||||
void MaybeCreateDoc();
|
void MaybeCreateDoc();
|
||||||
|
|
||||||
|
// The event dispatch code sets and unsets this while keeping
|
||||||
|
// the event object alive.
|
||||||
|
nsIDOMEvent* mEvent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline bool IsLoadingOrRunningTimeout() const;
|
inline bool IsLoadingOrRunningTimeout() const;
|
||||||
|
|
||||||
|
|
@ -789,6 +793,17 @@ public:
|
||||||
return mInnerObjectsFreed;
|
return mInnerObjectsFreed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the event for window.event. Does NOT take ownership, so
|
||||||
|
// the caller is responsible for clearing the event before the
|
||||||
|
// event gets deallocated. Pass nullptr to set window.event to
|
||||||
|
// undefined. Returns the previous value.
|
||||||
|
nsIDOMEvent* SetEvent(nsIDOMEvent* aEvent)
|
||||||
|
{
|
||||||
|
nsIDOMEvent* old = mEvent;
|
||||||
|
mEvent = aEvent;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether this window is a secure context.
|
* Check whether this window is a secure context.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,16 @@ public:
|
||||||
return mFlags.mRootOfClosedTree;
|
return mFlags.mRootOfClosedTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetItemInShadowTree(bool aSet)
|
||||||
|
{
|
||||||
|
mFlags.mItemInShadowTree = aSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsItemInShadowTree()
|
||||||
|
{
|
||||||
|
return mFlags.mItemInShadowTree;
|
||||||
|
}
|
||||||
|
|
||||||
void SetIsSlotInClosedTree(bool aSet)
|
void SetIsSlotInClosedTree(bool aSet)
|
||||||
{
|
{
|
||||||
mFlags.mIsSlotInClosedTree = aSet;
|
mFlags.mIsSlotInClosedTree = aSet;
|
||||||
|
|
@ -351,7 +361,8 @@ public:
|
||||||
mManager->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent,
|
mManager->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent,
|
||||||
&aVisitor.mDOMEvent,
|
&aVisitor.mDOMEvent,
|
||||||
CurrentTarget(),
|
CurrentTarget(),
|
||||||
&aVisitor.mEventStatus);
|
&aVisitor.mEventStatus,
|
||||||
|
IsItemInShadowTree());
|
||||||
NS_ASSERTION(aVisitor.mEvent->mCurrentTarget == nullptr,
|
NS_ASSERTION(aVisitor.mEvent->mCurrentTarget == nullptr,
|
||||||
"CurrentTarget should be null!");
|
"CurrentTarget should be null!");
|
||||||
}
|
}
|
||||||
|
|
@ -384,6 +395,7 @@ private:
|
||||||
bool mWantsPreHandleEvent : 1;
|
bool mWantsPreHandleEvent : 1;
|
||||||
bool mPreHandleEventOnly : 1;
|
bool mPreHandleEventOnly : 1;
|
||||||
bool mRootOfClosedTree : 1;
|
bool mRootOfClosedTree : 1;
|
||||||
|
bool mItemInShadowTree : 1;
|
||||||
bool mIsSlotInClosedTree : 1;
|
bool mIsSlotInClosedTree : 1;
|
||||||
bool mIsChromeHandler : 1;
|
bool mIsChromeHandler : 1;
|
||||||
private:
|
private:
|
||||||
|
|
@ -433,6 +445,7 @@ EventTargetChainItem::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||||
SetWantsPreHandleEvent(aVisitor.mWantsPreHandleEvent);
|
SetWantsPreHandleEvent(aVisitor.mWantsPreHandleEvent);
|
||||||
SetPreHandleEventOnly(aVisitor.mWantsPreHandleEvent && !aVisitor.mCanHandle);
|
SetPreHandleEventOnly(aVisitor.mWantsPreHandleEvent && !aVisitor.mCanHandle);
|
||||||
SetRootOfClosedTree(aVisitor.mRootOfClosedTree);
|
SetRootOfClosedTree(aVisitor.mRootOfClosedTree);
|
||||||
|
SetItemInShadowTree(aVisitor.mItemInShadowTree);
|
||||||
SetRetargetedRelatedTarget(aVisitor.mRetargetedRelatedTarget);
|
SetRetargetedRelatedTarget(aVisitor.mRetargetedRelatedTarget);
|
||||||
mItemFlags = aVisitor.mItemFlags;
|
mItemFlags = aVisitor.mItemFlags;
|
||||||
mItemData = aVisitor.mItemData;
|
mItemData = aVisitor.mItemData;
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ public:
|
||||||
, mMayHaveListenerManager(true)
|
, mMayHaveListenerManager(true)
|
||||||
, mWantsPreHandleEvent(false)
|
, mWantsPreHandleEvent(false)
|
||||||
, mRootOfClosedTree(false)
|
, mRootOfClosedTree(false)
|
||||||
|
, mItemInShadowTree(false)
|
||||||
, mParentIsSlotInClosedTree(false)
|
, mParentIsSlotInClosedTree(false)
|
||||||
, mParentIsChromeHandler(false)
|
, mParentIsChromeHandler(false)
|
||||||
, mRelatedTargetRetargetedInCurrentScope(false)
|
, mRelatedTargetRetargetedInCurrentScope(false)
|
||||||
|
|
@ -147,6 +148,7 @@ public:
|
||||||
mMayHaveListenerManager = true;
|
mMayHaveListenerManager = true;
|
||||||
mWantsPreHandleEvent = false;
|
mWantsPreHandleEvent = false;
|
||||||
mRootOfClosedTree = false;
|
mRootOfClosedTree = false;
|
||||||
|
mItemInShadowTree = false;
|
||||||
mParentIsSlotInClosedTree = false;
|
mParentIsSlotInClosedTree = false;
|
||||||
mParentIsChromeHandler = false;
|
mParentIsChromeHandler = false;
|
||||||
// Note, we don't clear mRelatedTargetRetargetedInCurrentScope explicitly,
|
// Note, we don't clear mRelatedTargetRetargetedInCurrentScope explicitly,
|
||||||
|
|
@ -236,6 +238,12 @@ public:
|
||||||
*/
|
*/
|
||||||
bool mRootOfClosedTree;
|
bool mRootOfClosedTree;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If target is node and its root is a shadow root.
|
||||||
|
* https://dom.spec.whatwg.org/#event-path-item-in-shadow-tree
|
||||||
|
*/
|
||||||
|
bool mItemInShadowTree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if mParentTarget is HTMLSlotElement in a closed shadow tree and the
|
* True if mParentTarget is HTMLSlotElement in a closed shadow tree and the
|
||||||
* current target is assigned to that slot.
|
* current target is assigned to that slot.
|
||||||
|
|
|
||||||
|
|
@ -1121,6 +1121,38 @@ EventListenerManager::GetLegacyEventMessage(EventMessage aEventMessage) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsPIDOMWindowInner>
|
||||||
|
EventListenerManager::WindowFromListener(Listener* aListener,
|
||||||
|
bool aItemInShadowTree)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> innerWindow;
|
||||||
|
if (!aItemInShadowTree) {
|
||||||
|
if (aListener->mListener.HasWebIDLCallback()) {
|
||||||
|
CallbackObject* callback = aListener->mListener.GetWebIDLCallback();
|
||||||
|
nsGlobalWindow* win;
|
||||||
|
if (callback) {
|
||||||
|
// Find the real underlying callback.
|
||||||
|
JSObject* realCallback =
|
||||||
|
js::UncheckedUnwrap(callback->CallbackPreserveColor());
|
||||||
|
// Get the global for this callback.
|
||||||
|
win = mIsMainThreadELM ?
|
||||||
|
xpc::WindowGlobalOrNull(realCallback) :
|
||||||
|
nullptr;
|
||||||
|
}
|
||||||
|
if (win && win->IsInnerWindow()) {
|
||||||
|
innerWindow = win->AsInner(); // Can be nullptr
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Can't get the global from
|
||||||
|
// listener->mListener.GetXPCOMCallback().
|
||||||
|
// In most cases, it would be the same as for
|
||||||
|
// the target, so let's do that.
|
||||||
|
innerWindow = GetInnerWindowForTarget(); // Can be nullptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return innerWindow.forget();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Causes a check for event listeners and processing by them if they exist.
|
* Causes a check for event listeners and processing by them if they exist.
|
||||||
* @param an event listener
|
* @param an event listener
|
||||||
|
|
@ -1131,7 +1163,8 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||||
WidgetEvent* aEvent,
|
WidgetEvent* aEvent,
|
||||||
nsIDOMEvent** aDOMEvent,
|
nsIDOMEvent** aDOMEvent,
|
||||||
EventTarget* aCurrentTarget,
|
EventTarget* aCurrentTarget,
|
||||||
nsEventStatus* aEventStatus)
|
nsEventStatus* aEventStatus,
|
||||||
|
bool aItemInShadowTree)
|
||||||
{
|
{
|
||||||
//Set the value of the internal PreventDefault flag properly based on aEventStatus
|
//Set the value of the internal PreventDefault flag properly based on aEventStatus
|
||||||
if (!aEvent->DefaultPrevented() &&
|
if (!aEvent->DefaultPrevented() &&
|
||||||
|
|
@ -1223,9 +1256,18 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||||
listener = listenerHolder.ptr();
|
listener = listenerHolder.ptr();
|
||||||
hasRemovedListener = true;
|
hasRemovedListener = true;
|
||||||
}
|
}
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> innerWindow =
|
||||||
|
WindowFromListener(listener, aItemInShadowTree);
|
||||||
|
nsIDOMEvent* oldWindowEvent = nullptr;
|
||||||
|
if (innerWindow) {
|
||||||
|
oldWindowEvent = innerWindow->SetEvent(*aDOMEvent);
|
||||||
|
}
|
||||||
if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
|
if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
|
||||||
aEvent->mFlags.mExceptionWasRaised = true;
|
aEvent->mFlags.mExceptionWasRaised = true;
|
||||||
}
|
}
|
||||||
|
if (innerWindow) {
|
||||||
|
Unused << innerWindow->SetEvent(oldWindowEvent);
|
||||||
|
}
|
||||||
aEvent->mFlags.mInPassiveListener = false;
|
aEvent->mFlags.mInPassiveListener = false;
|
||||||
|
|
||||||
if (needsEndEventMarker) {
|
if (needsEndEventMarker) {
|
||||||
|
|
|
||||||
|
|
@ -350,7 +350,8 @@ public:
|
||||||
WidgetEvent* aEvent,
|
WidgetEvent* aEvent,
|
||||||
nsIDOMEvent** aDOMEvent,
|
nsIDOMEvent** aDOMEvent,
|
||||||
dom::EventTarget* aCurrentTarget,
|
dom::EventTarget* aCurrentTarget,
|
||||||
nsEventStatus* aEventStatus)
|
nsEventStatus* aEventStatus,
|
||||||
|
bool aItemInShadowTree)
|
||||||
{
|
{
|
||||||
if (mListeners.IsEmpty() || aEvent->PropagationStopped()) {
|
if (mListeners.IsEmpty() || aEvent->PropagationStopped()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -371,7 +372,7 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HandleEventInternal(aPresContext, aEvent, aDOMEvent, aCurrentTarget,
|
HandleEventInternal(aPresContext, aEvent, aDOMEvent, aCurrentTarget,
|
||||||
aEventStatus);
|
aEventStatus, aItemInShadowTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -482,7 +483,8 @@ protected:
|
||||||
WidgetEvent* aEvent,
|
WidgetEvent* aEvent,
|
||||||
nsIDOMEvent** aDOMEvent,
|
nsIDOMEvent** aDOMEvent,
|
||||||
dom::EventTarget* aCurrentTarget,
|
dom::EventTarget* aCurrentTarget,
|
||||||
nsEventStatus* aEventStatus);
|
nsEventStatus* aEventStatus,
|
||||||
|
bool aItemInShadowTree);
|
||||||
|
|
||||||
nsresult HandleEventSubType(Listener* aListener,
|
nsresult HandleEventSubType(Listener* aListener,
|
||||||
nsIDOMEvent* aDOMEvent,
|
nsIDOMEvent* aDOMEvent,
|
||||||
|
|
@ -573,6 +575,10 @@ public:
|
||||||
return typedHandler ? typedHandler->OnBeforeUnloadEventHandler() : nullptr;
|
return typedHandler ? typedHandler->OnBeforeUnloadEventHandler() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
already_AddRefed<nsPIDOMWindowInner> WindowFromListener(Listener* aListener,
|
||||||
|
bool aItemInShadowTree);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Helper method for implementing the various Get*EventHandler above. Will
|
* Helper method for implementing the various Get*EventHandler above. Will
|
||||||
|
|
|
||||||
|
|
@ -394,52 +394,39 @@ MessagePort::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
MessagePort::PostMessage(JSContext* aCx,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
// We *must* clone the data here, or the JS::Value could be modified
|
// We *must* clone the data here, or the JS::Value could be modified
|
||||||
// by script
|
// by script
|
||||||
|
|
||||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
// Here we want to check if the transferable object list contains
|
||||||
if (aTransferable.WasPassed()) {
|
// this port.
|
||||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
for (uint32_t i = 0; i < aTransferable.Length(); ++i) {
|
||||||
|
JSObject* rawObject = aTransferable[i];
|
||||||
// Here we want to check if the transerable object list contains
|
if (!rawObject) {
|
||||||
// this port. No other checks are done.
|
continue;
|
||||||
for (const JS::Value& value : realTransferable) {
|
|
||||||
if (!value.isObject()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
JS::Rooted<JSObject*> object(aCx, &value.toObject());
|
|
||||||
|
|
||||||
MessagePort* port = nullptr;
|
|
||||||
nsresult rv = UNWRAP_OBJECT(MessagePort, &object, port);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port == this) {
|
|
||||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The input sequence only comes from the generated bindings code, which
|
JS::Rooted<JSObject*> object(aCx, rawObject);
|
||||||
// ensures it is rooted.
|
|
||||||
JS::HandleValueArray elements =
|
|
||||||
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
|
|
||||||
realTransferable.Elements());
|
|
||||||
|
|
||||||
JSObject* array =
|
MessagePort* port = nullptr;
|
||||||
JS_NewArrayObject(aCx, elements);
|
nsresult rv = UNWRAP_OBJECT(MessagePort, &object, port);
|
||||||
if (!array) {
|
if (NS_SUCCEEDED(rv) && port == this) {
|
||||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transferable.setObject(*array);
|
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||||
|
|
||||||
|
aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx,
|
||||||
|
aTransferable,
|
||||||
|
&transferable);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<SharedMessagePortMessage> data = new SharedMessagePortMessage();
|
RefPtr<SharedMessagePortMessage> data = new SharedMessagePortMessage();
|
||||||
|
|
@ -508,6 +495,14 @@ MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
mActor->SendPostMessages(messages);
|
mActor->SendPostMessages(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
PostMessage(aCx, aMessage, aOptions.mTransfer, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MessagePort::Start()
|
MessagePort::Start()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ class MessagePortIdentifier;
|
||||||
class MessagePortMessage;
|
class MessagePortMessage;
|
||||||
class PostMessageRunnable;
|
class PostMessageRunnable;
|
||||||
class SharedMessagePortMessage;
|
class SharedMessagePortMessage;
|
||||||
|
struct StructuredSerializeOptions;
|
||||||
|
|
||||||
namespace workers {
|
namespace workers {
|
||||||
class WorkerHolder;
|
class WorkerHolder;
|
||||||
|
|
@ -62,7 +63,12 @@ public:
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
|
|
|
||||||
|
|
@ -383,13 +383,6 @@ var tests =
|
||||||
|
|
||||||
hasWrongReturnOriginBug: true
|
hasWrongReturnOriginBug: true
|
||||||
},
|
},
|
||||||
// 55
|
|
||||||
{
|
|
||||||
args: ["NOT-RECEIVED", undefined],
|
|
||||||
source: "sameDomain",
|
|
||||||
name: "SyntaxError",
|
|
||||||
code: DOMException.SYNTAX_ERR
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function allTests(callback)
|
function allTests(callback)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@ interface Client {
|
||||||
readonly attribute DOMString id;
|
readonly attribute DOMString id;
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
void postMessage(any message, optional sequence<Transferable> transfer);
|
void postMessage(any message, sequence<object> transferable);
|
||||||
|
[Throws]
|
||||||
|
void postMessage(any message, optional StructuredSerializeOptions options);
|
||||||
};
|
};
|
||||||
|
|
||||||
[Exposed=ServiceWorker]
|
[Exposed=ServiceWorker]
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,9 @@
|
||||||
Exposed=DedicatedWorker]
|
Exposed=DedicatedWorker]
|
||||||
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
|
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
|
||||||
[Throws]
|
[Throws]
|
||||||
void postMessage(any message, optional sequence<any> transfer);
|
void postMessage(any message, sequence<object> transfer);
|
||||||
|
[Throws]
|
||||||
|
void postMessage(any message, optional StructuredSerializeOptions options);
|
||||||
|
|
||||||
attribute EventHandler onmessage;
|
attribute EventHandler onmessage;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@
|
||||||
[Exposed=(Window,Worker,System)]
|
[Exposed=(Window,Worker,System)]
|
||||||
interface MessagePort : EventTarget {
|
interface MessagePort : EventTarget {
|
||||||
[Throws]
|
[Throws]
|
||||||
void postMessage(any message, optional sequence<Transferable> transferable);
|
void postMessage(any message, sequence<object> transferable);
|
||||||
|
[Throws]
|
||||||
|
void postMessage(any message, optional StructuredSerializeOptions options);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void close();
|
void close();
|
||||||
|
|
@ -19,3 +21,8 @@ interface MessagePort : EventTarget {
|
||||||
attribute EventHandler onmessage;
|
attribute EventHandler onmessage;
|
||||||
};
|
};
|
||||||
// MessagePort implements Transferable;
|
// MessagePort implements Transferable;
|
||||||
|
|
||||||
|
// Used to declare which objects should be transferred.
|
||||||
|
dictionary StructuredSerializeOptions {
|
||||||
|
sequence<object> transfer = [];
|
||||||
|
};
|
||||||
|
|
@ -19,9 +19,10 @@ interface ServiceWorker : EventTarget {
|
||||||
|
|
||||||
attribute EventHandler onstatechange;
|
attribute EventHandler onstatechange;
|
||||||
|
|
||||||
// FIXME(catalinb): Should inherit this from Worker.
|
|
||||||
[Throws]
|
[Throws]
|
||||||
void postMessage(any message, optional sequence<Transferable> transferable);
|
void postMessage(any message, sequence<object> transferable);
|
||||||
|
[Throws]
|
||||||
|
void postMessage(any message, optional StructuredSerializeOptions options);
|
||||||
};
|
};
|
||||||
|
|
||||||
ServiceWorker implements AbstractWorker;
|
ServiceWorker implements AbstractWorker;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ interface IID;
|
||||||
interface nsIBrowserDOMWindow;
|
interface nsIBrowserDOMWindow;
|
||||||
interface nsIMessageBroadcaster;
|
interface nsIMessageBroadcaster;
|
||||||
interface nsIDOMCrypto;
|
interface nsIDOMCrypto;
|
||||||
typedef any Transferable;
|
|
||||||
|
|
||||||
// http://www.whatwg.org/specs/web-apps/current-work/
|
// http://www.whatwg.org/specs/web-apps/current-work/
|
||||||
[PrimaryGlobal, LegacyUnenumerableNamedProperties, NeedResolve]
|
[PrimaryGlobal, LegacyUnenumerableNamedProperties, NeedResolve]
|
||||||
|
|
@ -51,6 +50,7 @@ typedef any Transferable;
|
||||||
[Throws] void stop();
|
[Throws] void stop();
|
||||||
[Throws, CrossOriginCallable, UnsafeInPrerendering] void focus();
|
[Throws, CrossOriginCallable, UnsafeInPrerendering] void focus();
|
||||||
[Throws, CrossOriginCallable] void blur();
|
[Throws, CrossOriginCallable] void blur();
|
||||||
|
[Replaceable, Pref="dom.window.event.enabled"] readonly attribute any event;
|
||||||
|
|
||||||
// other browsing contexts
|
// other browsing contexts
|
||||||
[Replaceable, Throws, CrossOriginReadable] readonly attribute WindowProxy frames;
|
[Replaceable, Throws, CrossOriginReadable] readonly attribute WindowProxy frames;
|
||||||
|
|
@ -80,7 +80,9 @@ typedef any Transferable;
|
||||||
[Throws, UnsafeInPrerendering] void print();
|
[Throws, UnsafeInPrerendering] void print();
|
||||||
|
|
||||||
[Throws, CrossOriginCallable, NeedsSubjectPrincipal]
|
[Throws, CrossOriginCallable, NeedsSubjectPrincipal]
|
||||||
void postMessage(any message, DOMString targetOrigin, optional sequence<Transferable> transfer);
|
void postMessage(any message, DOMString targetOrigin, optional sequence<object> transfer = []);
|
||||||
|
[Throws, CrossOriginCallable, NeedsSubjectPrincipal]
|
||||||
|
void postMessage(any message, optional WindowPostMessageOptions options);
|
||||||
|
|
||||||
// also has obsolete members
|
// also has obsolete members
|
||||||
};
|
};
|
||||||
|
|
@ -486,3 +488,7 @@ callback IdleRequestCallback = void (IdleDeadline deadline);
|
||||||
partial interface Window {
|
partial interface Window {
|
||||||
[ChromeOnly] readonly attribute boolean isSecureContextIfOpenerIgnored;
|
[ChromeOnly] readonly attribute boolean isSecureContextIfOpenerIgnored;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dictionary WindowPostMessageOptions : StructuredSerializeOptions {
|
||||||
|
USVString targetOrigin = "/";
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ interface WindowOrWorkerGlobalScope {
|
||||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage);
|
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage);
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage, long aSx, long aSy, long aSw, long aSh);
|
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage, long aSx, long aSy, long aSw, long aSh);
|
||||||
|
|
||||||
|
// structured cloning
|
||||||
|
[Throws]
|
||||||
|
any structuredClone(any value, optional StructuredSerializeOptions options);
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://fetch.spec.whatwg.org/#fetch-method
|
// https://fetch.spec.whatwg.org/#fetch-method
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ interface Worker : EventTarget {
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
[Throws]
|
[Throws]
|
||||||
void postMessage(any message, optional sequence<any> transfer);
|
void postMessage(any message, sequence<object> transfer);
|
||||||
|
[Throws]
|
||||||
|
void postMessage(any message, optional StructuredSerializeOptions options);
|
||||||
|
|
||||||
attribute EventHandler onmessage;
|
attribute EventHandler onmessage;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/MessagePortBinding.h"
|
||||||
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
|
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
|
|
@ -77,7 +78,7 @@ ServiceWorker::GetScriptURL(nsString& aURL) const
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
if (State() == ServiceWorkerState::Redundant) {
|
if (State() == ServiceWorkerState::Redundant) {
|
||||||
|
|
@ -97,6 +98,15 @@ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
aRv = workerPrivate->SendMessageEvent(aCx, aMessage, aTransferable, Move(clientInfo));
|
aRv = workerPrivate->SendMessageEvent(aCx, aMessage, aTransferable, Move(clientInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorker::PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
PostMessage(aCx, aMessage, aOptions.mTransfer, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace workers
|
} // namespace workers
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ class nsPIDOMWindowInner;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
struct StructuredSerializeOptions;
|
||||||
|
|
||||||
namespace workers {
|
namespace workers {
|
||||||
|
|
||||||
class ServiceWorkerInfo;
|
class ServiceWorkerInfo;
|
||||||
|
|
@ -63,7 +65,13 @@ public:
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/dom/Navigator.h"
|
#include "mozilla/dom/Navigator.h"
|
||||||
#include "mozilla/dom/ServiceWorkerMessageEvent.h"
|
#include "mozilla/dom/ServiceWorkerMessageEvent.h"
|
||||||
#include "mozilla/dom/ServiceWorkerMessageEventBinding.h"
|
#include "mozilla/dom/ServiceWorkerMessageEventBinding.h"
|
||||||
|
#include "mozilla/dom/MessagePortBinding.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsIBrowserDOMWindow.h"
|
#include "nsIBrowserDOMWindow.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
|
|
@ -190,7 +191,7 @@ private:
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||||
|
|
@ -198,20 +199,11 @@ ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
workerPrivate->AssertIsOnWorkerThread();
|
workerPrivate->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||||
if (aTransferable.WasPassed()) {
|
aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx,
|
||||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
aTransferable,
|
||||||
|
&transferable);
|
||||||
JS::HandleValueArray elements =
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
|
return;
|
||||||
realTransferable.Elements());
|
|
||||||
|
|
||||||
JSObject* array = JS_NewArrayObject(aCx, elements);
|
|
||||||
if (!array) {
|
|
||||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
transferable.setObject(*array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ServiceWorkerClientPostMessageRunnable> runnable =
|
RefPtr<ServiceWorkerClientPostMessageRunnable> runnable =
|
||||||
|
|
@ -229,3 +221,11 @@ ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerClient::PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
PostMessage(aCx, aMessage, aOptions.mTransfer, aRv);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,13 @@ public:
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ NS_IMPL_ISUPPORTS0(MessageWaitUntilHandler)
|
||||||
nsresult
|
nsresult
|
||||||
ServiceWorkerPrivate::SendMessageEvent(JSContext* aCx,
|
ServiceWorkerPrivate::SendMessageEvent(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aMessage,
|
JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
|
||||||
{
|
{
|
||||||
ErrorResult rv(SpawnWorkerIfNeeded(MessageEvent, nullptr));
|
ErrorResult rv(SpawnWorkerIfNeeded(MessageEvent, nullptr));
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ public:
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
SendMessageEvent(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
SendMessageEvent(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo);
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo);
|
||||||
|
|
||||||
// This is used to validate the worker script and continue the installation
|
// This is used to validate the worker script and continue the installation
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
using mozilla::dom::Optional;
|
using mozilla::dom::Optional;
|
||||||
using mozilla::dom::Sequence;
|
using mozilla::dom::Sequence;
|
||||||
using mozilla::dom::MessagePort;
|
using mozilla::dom::MessagePort;
|
||||||
|
using mozilla::dom::StructuredSerializeOptions;
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
USING_WORKERS_NAMESPACE
|
USING_WORKERS_NAMESPACE
|
||||||
|
|
@ -142,7 +143,7 @@ SharedWorker::Close()
|
||||||
|
|
||||||
void
|
void
|
||||||
SharedWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
SharedWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
|
@ -152,6 +153,15 @@ SharedWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
mMessagePort->PostMessage(aCx, aMessage, aTransferable, aRv);
|
mMessagePort->PostMessage(aCx, aMessage, aTransferable, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SharedWorker::PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
PostMessage(aCx, aMessage, aOptions.mTransfer, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(SharedWorker, DOMEventTargetHelper)
|
NS_IMPL_ADDREF_INHERITED(SharedWorker, DOMEventTargetHelper)
|
||||||
NS_IMPL_RELEASE_INHERITED(SharedWorker, DOMEventTargetHelper)
|
NS_IMPL_RELEASE_INHERITED(SharedWorker, DOMEventTargetHelper)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,15 @@ private:
|
||||||
|
|
||||||
// Only called by MessagePort.
|
// Only called by MessagePort.
|
||||||
void
|
void
|
||||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessage(JSContext* aCx,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const Sequence<JSObject*>& aTransferable,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3006,13 +3006,12 @@ WorkerPrivateParent<Derived>::ForgetMainThreadObjects(
|
||||||
|
|
||||||
template <class Derived>
|
template <class Derived>
|
||||||
void
|
void
|
||||||
WorkerPrivateParent<Derived>::PostMessageInternal(
|
WorkerPrivateParent<Derived>::PostMessageInternal(JSContext* aCx,
|
||||||
JSContext* aCx,
|
JS::Handle<JS::Value> aMessage,
|
||||||
JS::Handle<JS::Value> aMessage,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
||||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
PromiseNativeHandler* aHandler,
|
||||||
PromiseNativeHandler* aHandler,
|
ErrorResult& aRv)
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
{
|
||||||
AssertIsOnParentThread();
|
AssertIsOnParentThread();
|
||||||
|
|
||||||
|
|
@ -3024,22 +3023,11 @@ WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||||
if (aTransferable.WasPassed()) {
|
aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx,
|
||||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
aTransferable,
|
||||||
|
&transferable);
|
||||||
// The input sequence only comes from the generated bindings code, which
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
// ensures it is rooted.
|
return;
|
||||||
JS::HandleValueArray elements =
|
|
||||||
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
|
|
||||||
realTransferable.Elements());
|
|
||||||
|
|
||||||
JSObject* array =
|
|
||||||
JS_NewArrayObject(aCx, elements);
|
|
||||||
if (!array) {
|
|
||||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transferable.setObject(*array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<MessageEventRunnable> runnable =
|
RefPtr<MessageEventRunnable> runnable =
|
||||||
|
|
@ -3083,18 +3071,31 @@ WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||||
template <class Derived>
|
template <class Derived>
|
||||||
void
|
void
|
||||||
WorkerPrivateParent<Derived>::PostMessage(
|
WorkerPrivateParent<Derived>::PostMessage(
|
||||||
JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
JSContext* aCx,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
PostMessageInternal(aCx, aMessage, aTransferable, nullptr, nullptr, aRv);
|
PostMessageInternal(aCx, aMessage, aTransferable, nullptr, nullptr, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
void
|
||||||
|
WorkerPrivateParent<Derived>::PostMessage(
|
||||||
|
JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
PostMessageInternal(aCx, aMessage, aOptions.mTransfer, nullptr, nullptr, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
template <class Derived>
|
template <class Derived>
|
||||||
void
|
void
|
||||||
WorkerPrivateParent<Derived>::PostMessageToServiceWorker(
|
WorkerPrivateParent<Derived>::PostMessageToServiceWorker(
|
||||||
JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
JSContext* aCx,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const Sequence<JSObject*>& aTransferable,
|
||||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
||||||
PromiseNativeHandler* aHandler,
|
PromiseNativeHandler* aHandler,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
|
|
@ -5677,27 +5678,17 @@ void
|
||||||
WorkerPrivate::PostMessageToParentInternal(
|
WorkerPrivate::PostMessageToParentInternal(
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aMessage,
|
JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
AssertIsOnWorkerThread();
|
AssertIsOnWorkerThread();
|
||||||
|
|
||||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||||
if (aTransferable.WasPassed()) {
|
aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx,
|
||||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
aTransferable,
|
||||||
|
&transferable);
|
||||||
// The input sequence only comes from the generated bindings code, which
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
// ensures it is rooted.
|
return;
|
||||||
JS::HandleValueArray elements =
|
|
||||||
JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(),
|
|
||||||
realTransferable.Elements());
|
|
||||||
|
|
||||||
JSObject* array = JS_NewArrayObject(aCx, elements);
|
|
||||||
if (!array) {
|
|
||||||
aRv = NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
transferable.setObject(*array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<MessageEventRunnable> runnable =
|
RefPtr<MessageEventRunnable> runnable =
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ class PromiseNativeHandler;
|
||||||
class StructuredCloneHolder;
|
class StructuredCloneHolder;
|
||||||
class WorkerDebuggerGlobalScope;
|
class WorkerDebuggerGlobalScope;
|
||||||
class WorkerGlobalScope;
|
class WorkerGlobalScope;
|
||||||
|
struct StructuredSerializeOptions;
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
class PrincipalInfo;
|
class PrincipalInfo;
|
||||||
|
|
@ -287,7 +288,7 @@ private:
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
||||||
PromiseNativeHandler* aHandler,
|
PromiseNativeHandler* aHandler,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
@ -400,12 +401,18 @@ public:
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessageToServiceWorker(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessageToServiceWorker(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
||||||
PromiseNativeHandler* aHandler,
|
PromiseNativeHandler* aHandler,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
@ -1161,18 +1168,17 @@ public:
|
||||||
void
|
void
|
||||||
PostMessageToParent(JSContext* aCx,
|
PostMessageToParent(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aMessage,
|
JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
PostMessageToParentInternal(aCx, aMessage, aTransferable, aRv);
|
PostMessageToParentInternal(aCx, aMessage, aTransferable, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessageToParentMessagePort(
|
PostMessageToParentMessagePort(JSContext* aCx,
|
||||||
JSContext* aCx,
|
JS::Handle<JS::Value> aMessage,
|
||||||
JS::Handle<JS::Value> aMessage,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
ErrorResult& aRv);
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EnterDebuggerEventLoop();
|
EnterDebuggerEventLoop();
|
||||||
|
|
@ -1471,7 +1477,7 @@ private:
|
||||||
void
|
void
|
||||||
PostMessageToParentInternal(JSContext* aCx,
|
PostMessageToParentInternal(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aMessage,
|
JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "mozilla/EventListenerManager.h"
|
#include "mozilla/EventListenerManager.h"
|
||||||
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
#include "mozilla/dom/Console.h"
|
#include "mozilla/dom/Console.h"
|
||||||
#include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
|
#include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
|
||||||
|
|
@ -492,6 +493,15 @@ WorkerGlobalScope::CreateImageBitmap(const ImageBitmapSource& aImage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/#structured-cloning
|
||||||
|
void WorkerGlobalScope::StructuredClone(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
JS::MutableHandle<JS::Value> aRv,
|
||||||
|
ErrorResult& aError) {
|
||||||
|
nsContentUtils::StructuredClone(aCx, this, aValue, aOptions, aRv, aError);
|
||||||
|
}
|
||||||
|
|
||||||
DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
|
DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
|
||||||
: WorkerGlobalScope(aWorkerPrivate)
|
: WorkerGlobalScope(aWorkerPrivate)
|
||||||
{
|
{
|
||||||
|
|
@ -535,13 +545,22 @@ DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
|
||||||
void
|
void
|
||||||
DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
|
DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aMessage,
|
JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
mWorkerPrivate->PostMessageToParent(aCx, aMessage, aTransferable, aRv);
|
mWorkerPrivate->PostMessageToParent(aCx, aMessage, aTransferable, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
PostMessage(aCx, aMessage, aOptions.mTransfer, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
|
SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
|
||||||
const nsCString& aName)
|
const nsCString& aName)
|
||||||
: WorkerGlobalScope(aWorkerPrivate), mName(aName)
|
: WorkerGlobalScope(aWorkerPrivate), mName(aName)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ class Function;
|
||||||
class IDBFactory;
|
class IDBFactory;
|
||||||
enum class ImageBitmapFormat : uint32_t;
|
enum class ImageBitmapFormat : uint32_t;
|
||||||
class Performance;
|
class Performance;
|
||||||
|
struct StructuredSerializeOptions;
|
||||||
class Promise;
|
class Promise;
|
||||||
class RequestOrUSVString;
|
class RequestOrUSVString;
|
||||||
class ServiceWorkerRegistration;
|
class ServiceWorkerRegistration;
|
||||||
|
|
@ -182,6 +183,11 @@ public:
|
||||||
const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
|
const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
|
||||||
mozilla::ErrorResult& aRv);
|
mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
|
void StructuredClone(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
|
JS::MutableHandle<JS::Value> aRv,
|
||||||
|
ErrorResult& aError);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WindowInteractionAllowed() const
|
WindowInteractionAllowed() const
|
||||||
{
|
{
|
||||||
|
|
@ -215,7 +221,13 @@ public:
|
||||||
|
|
||||||
void
|
void
|
||||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||||
const Optional<Sequence<JS::Value>>& aTransferable,
|
const Sequence<JSObject*>& aTransferable,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
PostMessage(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aMessage,
|
||||||
|
const StructuredSerializeOptions& aOptions,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(message)
|
IMPL_EVENT_HANDLER(message)
|
||||||
|
|
|
||||||
|
|
@ -326,6 +326,43 @@ SandboxCreateFetch(JSContext* cx, HandleObject obj)
|
||||||
dom::HeadersBinding::GetConstructorObject(cx);
|
dom::HeadersBinding::GetConstructorObject(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool SandboxStructuredClone(JSContext* cx, unsigned argc, Value* vp) {
|
||||||
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
|
||||||
|
if (!args.requireAtLeast(cx, "structuredClone", 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedDictionary<dom::StructuredSerializeOptions> options(cx);
|
||||||
|
if (!options.Init(cx, args.hasDefined(1) ? args[1] : JS::NullHandleValue,
|
||||||
|
"Argument 2", false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(cx));
|
||||||
|
if (!global) {
|
||||||
|
JS_ReportErrorASCII(cx, "structuredClone: Missing global");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> result(cx);
|
||||||
|
ErrorResult rv;
|
||||||
|
nsContentUtils::StructuredClone(cx, global, args[0], options, &result, rv);
|
||||||
|
if (rv.MaybeSetPendingException(cx)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.rval().set(result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SandboxCreateStructuredClone(JSContext* cx, HandleObject obj) {
|
||||||
|
MOZ_ASSERT(JS_IsGlobalObject(obj));
|
||||||
|
|
||||||
|
return JS_DefineFunction(cx, obj, "structuredClone", SandboxStructuredClone,
|
||||||
|
1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
SandboxIsProxy(JSContext* cx, unsigned argc, Value* vp)
|
SandboxIsProxy(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
|
|
@ -931,6 +968,8 @@ xpc::GlobalProperties::Parse(JSContext* cx, JS::HandleObject obj)
|
||||||
#endif
|
#endif
|
||||||
} else if (!strcmp(name.ptr(), "fetch")) {
|
} else if (!strcmp(name.ptr(), "fetch")) {
|
||||||
fetch = true;
|
fetch = true;
|
||||||
|
} else if (!strcmp(name.ptr(), "structuredClone")) {
|
||||||
|
structuredClone = true;
|
||||||
} else if (!strcmp(name.ptr(), "caches")) {
|
} else if (!strcmp(name.ptr(), "caches")) {
|
||||||
caches = true;
|
caches = true;
|
||||||
} else if (!strcmp(name.ptr(), "FileReader")) {
|
} else if (!strcmp(name.ptr(), "FileReader")) {
|
||||||
|
|
@ -1006,6 +1045,9 @@ xpc::GlobalProperties::Define(JSContext* cx, JS::HandleObject obj)
|
||||||
if (fetch && !SandboxCreateFetch(cx, obj))
|
if (fetch && !SandboxCreateFetch(cx, obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (structuredClone && !SandboxCreateStructuredClone(cx, obj))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (caches && !dom::cache::CacheStorage::DefineCaches(cx, obj))
|
if (caches && !dom::cache::CacheStorage::DefineCaches(cx, obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2879,6 +2879,7 @@ struct GlobalProperties {
|
||||||
bool crypto : 1;
|
bool crypto : 1;
|
||||||
bool rtcIdentityProvider : 1;
|
bool rtcIdentityProvider : 1;
|
||||||
bool fetch : 1;
|
bool fetch : 1;
|
||||||
|
bool structuredClone : 1;
|
||||||
bool caches : 1;
|
bool caches : 1;
|
||||||
bool fileReader: 1;
|
bool fileReader: 1;
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
25
js/xpconnect/tests/unit/test_structuredClone.js
Normal file
25
js/xpconnect/tests/unit/test_structuredClone.js
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
function run_test() {
|
||||||
|
var sb = new Cu.Sandbox('http://www.example.com',
|
||||||
|
{ wantGlobalProperties: ["structuredClone"] });
|
||||||
|
|
||||||
|
sb.equal = equal;
|
||||||
|
|
||||||
|
sb.testing = Components.utils.cloneInto({xyz: 123}, sb);
|
||||||
|
Cu.evalInSandbox(`
|
||||||
|
equal(structuredClone("abc"), "abc");
|
||||||
|
|
||||||
|
var obj = {a: 1};
|
||||||
|
obj.self = obj;
|
||||||
|
var clone = structuredClone(obj);
|
||||||
|
equal(clone.a, 1);
|
||||||
|
equal(clone.self, clone);
|
||||||
|
|
||||||
|
var ab = new ArrayBuffer(1);
|
||||||
|
clone = structuredClone(ab, {transfer: [ab]});
|
||||||
|
equal(clone.byteLength, 1);
|
||||||
|
equal(ab.byteLength, 0);
|
||||||
|
|
||||||
|
clone = structuredClone(testing);
|
||||||
|
equal(clone.xyz, 123);
|
||||||
|
`, sb);
|
||||||
|
}
|
||||||
|
|
@ -114,6 +114,7 @@ skip-if = os == "android" # native test components aren't available on Android
|
||||||
[test_css.js]
|
[test_css.js]
|
||||||
[test_rtcIdentityProvider.js]
|
[test_rtcIdentityProvider.js]
|
||||||
[test_sandbox_atob.js]
|
[test_sandbox_atob.js]
|
||||||
|
[test_structuredClone.js]
|
||||||
[test_isProxy.js]
|
[test_isProxy.js]
|
||||||
[test_getObjectPrincipal.js]
|
[test_getObjectPrincipal.js]
|
||||||
[test_sandbox_name.js]
|
[test_sandbox_name.js]
|
||||||
|
|
|
||||||
|
|
@ -5252,6 +5252,9 @@ pref("prompts.content_handling_dialog_modal.enabled", false);
|
||||||
// Whether module scripts (<script type="module">) are enabled for content.
|
// Whether module scripts (<script type="module">) are enabled for content.
|
||||||
pref("dom.moduleScripts.enabled", true);
|
pref("dom.moduleScripts.enabled", true);
|
||||||
|
|
||||||
|
// Whether read-only Window property event is enabled for content.
|
||||||
|
pref("dom.window.event.enabled", false);
|
||||||
|
|
||||||
// Report details when a media source error occurs?
|
// Report details when a media source error occurs?
|
||||||
// Enabled by default in debug builds, otherwise should be explicitly enabled
|
// Enabled by default in debug builds, otherwise should be explicitly enabled
|
||||||
// by the user to prevent XO leaking of the response status (CVE-2020-15666)
|
// by the user to prevent XO leaking of the response status (CVE-2020-15666)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue