summaryrefslogtreecommitdiff
path: root/dom/base/nsContentUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/nsContentUtils.cpp')
-rw-r--r--dom/base/nsContentUtils.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 990e1bc589..86e52984af 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -47,6 +47,7 @@
#include "mozilla/dom/HTMLTemplateElement.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
+#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/TabParent.h"
@@ -9991,3 +9992,71 @@ nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement)
}
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;
+}