Skip to content

Commit 0947339

Browse files
surmadomenic
authored andcommitted
Define self.structuredClone()
Closes #793.
1 parent 0d63ebc commit 0947339

File tree

1 file changed

+69
-23
lines changed

1 file changed

+69
-23
lines changed

source

+69-23
Original file line numberDiff line numberDiff line change
@@ -7967,13 +7967,24 @@ interface <dfn interface>DOMStringList</dfn> {
79677967
</div>
79687968

79697969

7970-
<div w-nodev>
7971-
79727970
<h3 split-filename="structured-data">Safe passing of structured data</h3>
79737971

7972+
<p id="structuredclone"><span id="structured-clone"></span>To support passing JavaScript objects,
7973+
including <span data-x="platform object">platform objects</span>, across <span data-x="JavaScript
7974+
realm">realm</span> boundaries, this specification defines <span w-nodev>the following
7975+
</span>infrastructure for serializing and deserializing objects, including in some cases
7976+
transferring the underlying data instead of copying it. Collectively this
7977+
serialization/deserialization process is known as "structured cloning", although most APIs perform
7978+
separate serialization and deserialization steps. (With the notable exception being the <code
7979+
data-x="dom-structuredClone">structuredClone()</code> method.)</p>
7980+
7981+
<div w-nodev>
7982+
79747983
<p>This section uses the terminology and typographic conventions from the JavaScript
79757984
specification. <ref spec=JAVASCRIPT></p>
79767985

7986+
</div>
7987+
79777988
<h4><dfn>Serializable objects</dfn></h4>
79787989

79797990
<p><span>Serializable objects</span> support being serialized, and later deserialized, in a way
@@ -7984,6 +7995,8 @@ interface <dfn interface>DOMStringList</dfn> {
79847995
<p>Not all objects are <span>serializable objects</span>, and not all aspects of objects that are
79857996
<span>serializable objects</span> are necessarily preserved when they are serialized.</p>
79867997

7998+
<div w-nodev>
7999+
79878000
<p><span data-x="platform object">Platform objects</span> can be <span>serializable objects</span>
79888001
if their <span>primary interface</span> is decorated with the <dfn extended-attribute
79898002
data-lt="Serializable" data-x="Serializable"><code>[Serializable]</code></dfn> IDL <span>extended
@@ -8091,6 +8104,8 @@ interface <dfn interface>DOMStringList</dfn> {
80918104
However, to better specify the behavior of certain more complex situations, the model was updated
80928105
to make the serialization and deserialization explicit.</p>
80938106

8107+
</div>
8108+
80948109
<h4 export data-lt="transferable object"><dfn>Transferable objects</dfn></h4>
80958110

80968111
<p><span>Transferable objects</span> support being transferred across <span
@@ -8103,6 +8118,8 @@ interface <dfn interface>DOMStringList</dfn> {
81038118
<p class="note">Transferring is an irreversible and non-idempotent operation. Once an object has
81048119
been transferred, it cannot be transferred, or indeed used, again.</p>
81058120

8121+
<div w-nodev>
8122+
81068123
<p><span data-x="platform object">Platform objects</span> can be <span>transferable objects</span>
81078124
if their <span>primary interface</span> is decorated with the <dfn extended-attribute
81088125
data-lt="Transferable" data-x="Transferable"><code>[Transferable]</code></dfn> IDL <span>extended
@@ -9138,11 +9155,6 @@ o.myself = o;</code></pre>
91389155
understood to perform an implicit <span data-x="concept-idl-convert">conversion</span> to the
91399156
JavaScript value before invoking these algorithms.</p>
91409157

9141-
<p class="note" id="structuredclone"><span id="structured-clone"></span>This specification used
9142-
to define a "structured clone" algorithm, and more recently a StructuredClone abstract operation.
9143-
However, in practice all known uses of it were better served by separate serialization and
9144-
deserialization steps, so it was removed.</p>
9145-
91469158
<hr>
91479159

91489160
<p>Call sites that are not invoked as a result of author code synchronously calling into a user
@@ -9170,6 +9182,38 @@ o.myself = o;</code></pre>
91709182

91719183
</div>
91729184

9185+
<h4 id="structured-cloning">Structured cloning API</h4>
9186+
9187+
<dl class="domintro">
9188+
<dt><code data-x=""><var>result</var> = self.<code subdfn data-x="dom-structuredClone">structuredClone</code>(<var>value</var>[, { <code data-x="dom-StructuredSerializeOptions-transfer">transfer</code> }])</dt>
9189+
<dd>
9190+
<p>Takes the input value and returns a deep copy by performing the structured clone algorithm.
9191+
<span>Transferable objects</span> listed in the <code
9192+
data-x="dom-StructuredSerializeOptions-transfer">transfer</code> array are transferred, not
9193+
just cloned, meaning that they are no longer usable in the input value.</p>
9194+
9195+
<p>Throws a <span>"<code>DataCloneError</code>"</span> <code>DOMException</code> if any part of
9196+
the input value is not <span data-x="serializable objects">serializable</span>.</p>
9197+
</dd>
9198+
</dl>
9199+
9200+
<div w-nodev>
9201+
9202+
<p>The <dfn method for="WindowOrWorkerGlobalScope"
9203+
data-x="dom-structuredClone"><code>structuredClone(<var>value</var>,
9204+
<var>options</var>)</code></dfn> method steps are:</p>
9205+
9206+
<ol>
9207+
<li><p>Let <var>serialized</var> be ?
9208+
<span>StructuredSerializeWithTransfer</span>(<var>value</var>, <var>options</var>["<code
9209+
data-x="dom-StructuredSerializeOptions-transfer">transfer</code>"]).</p></li>
9210+
9211+
<li><p>Return ? <span>StructuredDeserialize</span>(<var>serialized</var>, <span>this</span>'s
9212+
<span data-x="concept-relevant-realm">relevant Realm</span>).</p></li>
9213+
</ol>
9214+
9215+
</div>
9216+
91739217

91749218
<h2 split-filename="dom" id="dom">Semantics, structure, and APIs of HTML documents</h2>
91759219

@@ -80416,7 +80460,7 @@ interface <dfn interface>Window</dfn> : <span>EventTarget</span> {
8041680460
<span>Window</span> includes <span>GlobalEventHandlers</span>;
8041780461
<span>Window</span> includes <span>WindowEventHandlers</span>;
8041880462

80419-
dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>PostMessageOptions</span> {
80463+
dictionary <dfn dictionary>WindowPostMessageOptions</dfn> : <span>StructuredSerializeOptions</span> {
8042080464
USVString <dfn dict-member for="WindowPostMessageOptions" data-x="dom-WindowPostMessageOptions-targetOrigin">targetOrigin</dfn> = "/";
8042180465
};</code></pre>
8042280466

@@ -94809,6 +94853,9 @@ interface mixin <dfn interface>WindowOrWorkerGlobalScope</dfn> {
9480994853
// ImageBitmap
9481094854
Promise&lt;<span>ImageBitmap</span>&gt; <span data-x="dom-createImageBitmap">createImageBitmap</span>(<span>ImageBitmapSource</span> image, optional <span>ImageBitmapOptions</span> options = {});
9481194855
Promise&lt;<span>ImageBitmap</span>&gt; <span data-x="dom-createImageBitmap">createImageBitmap</span>(<span>ImageBitmapSource</span> image, long sx, long sy, long sw, long sh, optional <span>ImageBitmapOptions</span> options = {});
94856+
94857+
// structured cloning
94858+
any <span data-x="dom-structuredClone">structuredClone</span>(any value, optional <span>StructuredSerializeOptions</span> options = {});
9481294859
};
9481394860
<span>Window</span> includes <span>WindowOrWorkerGlobalScope</span>;
9481494861
<span>WorkerGlobalScope</span> includes <span>WindowOrWorkerGlobalScope</span>;</code></pre>
@@ -99740,7 +99787,7 @@ function receiver(e) {
9974099787
and can contain certain data objects such as <code>File</code> <code>Blob</code>,
9974199788
<code>FileList</code>, and <code data-x="idl-ArrayBuffer">ArrayBuffer</code> objects.</p>
9974299789

99743-
<p>Objects listed in the <code data-x="dom-PostMessageOptions-transfer">transfer</code> member
99790+
<p>Objects listed in the <code data-x="dom-StructuredSerializeOptions-transfer">transfer</code> member
9974499791
of <var>options</var> are transferred, not just cloned, meaning that they are no longer usable
9974599792
on the sending side.</p>
9974699793

@@ -99816,7 +99863,7 @@ function receiver(e) {
9981699863
</li>
9981799864

9981899865
<li><p>Let <var>transfer</var> be <var>options</var>["<code
99819-
data-x="dom-PostMessageOptions-transfer">transfer</code>"].</p></li>
99866+
data-x="dom-StructuredSerializeOptions-transfer">transfer</code>"].</p></li>
9982099867

9982199868
<li><p>Let <var>serializeWithTransferResult</var> be
9982299869
<span>StructuredSerializeWithTransfer</span>(<var>message</var>, <var>transfer</var>). Rethrow
@@ -99892,7 +99939,7 @@ function receiver(e) {
9989299939

9989399940
<li><p>Let <var>options</var> be «[ "<code
9989499941
data-x="dom-WindowPostMessageOptions-targetOrigin">targetOrigin</code>" →
99895-
<var>targetOrigin</var>, "<code data-x="dom-PostMessageOptions-transfer">transfer</code>" →
99942+
<var>targetOrigin</var>, "<code data-x="dom-StructuredSerializeOptions-transfer">transfer</code>" →
9989699943
<var>transfer</var> ]».</p></li>
9989799944

9989899945
<li><p>Run the <span>window post message steps</span> providing <var>targetWindow</var>,
@@ -100160,7 +100207,7 @@ interface <dfn interface>MessageChannel</dfn> {
100160100207
<pre><code class="idl">[Exposed=(Window,Worker,AudioWorklet), <span>Transferable</span>]
100161100208
interface <dfn interface>MessagePort</dfn> : <span>EventTarget</span> {
100162100209
undefined <span data-x="dom-MessagePort-postMessage">postMessage</span>(any message, sequence&lt;<span data-x="idl-object">object</span>&gt; transfer);
100163-
undefined <span data-x="dom-MessagePort-postMessage-options">postMessage</span>(any message, optional <span>PostMessageOptions</span> options = {});
100210+
undefined <span data-x="dom-MessagePort-postMessage-options">postMessage</span>(any message, optional <span>StructuredSerializeOptions</span> options = {});
100164100211
undefined <span data-x="dom-MessagePort-start">start</span>();
100165100212
undefined <span data-x="dom-MessagePort-close">close</span>();
100166100213

@@ -100169,8 +100216,8 @@ interface <dfn interface>MessagePort</dfn> : <span>EventTarget</span> {
100169100216
attribute <span>EventHandler</span> <span data-x="handler-MessagePort-onmessageerror">onmessageerror</span>;
100170100217
};
100171100218

100172-
dictionary <dfn dictionary>PostMessageOptions</dfn> {
100173-
sequence&lt;<span data-x="idl-object">object</span>&gt; <dfn dict-member for="PostMessageOptions" data-x="dom-PostMessageOptions-transfer">transfer</dfn> = [];
100219+
dictionary <dfn dictionary>StructuredSerializeOptions</dfn> {
100220+
sequence&lt;<span data-x="idl-object">object</span>&gt; <dfn dict-member for="StructuredSerializeOptions" data-x="dom-StructuredSerializeOptions-transfer">transfer</dfn> = [];
100174100221
};</code></pre>
100175100222

100176100223
<dl class="domintro">
@@ -100313,7 +100360,7 @@ dictionary <dfn dictionary>PostMessageOptions</dfn> {
100313100360

100314100361
<ol> <!-- a lot of this is similar or identical to the window post message steps -->
100315100362
<li><p>Let <var>transfer</var> be <var>options</var>["<code
100316-
data-x="dom-PostMessageOptions-transfer">transfer</code>"].</p></li>
100363+
data-x="dom-StructuredSerializeOptions-transfer">transfer</code>"].</p></li>
100317100364

100318100365
<li><p>If <var>transfer</var> <span data-x="list contains">contains</span> this
100319100366
<code>MessagePort</code>, then throw a <span>"<code>DataCloneError</code>"</span>
@@ -100403,7 +100450,8 @@ dictionary <dfn dictionary>PostMessageOptions</dfn> {
100403100450
entangled, if any; otherwise let it be null.</p></li>
100404100451

100405100452
<li><p>Let <var>options</var> be «[ "<code
100406-
data-x="dom-PostMessageOptions-transfer">transfer</code>" → <var>transfer</var> ]».</p></li>
100453+
data-x="dom-StructuredSerializeOptions-transfer">transfer</code>" →
100454+
<var>transfer</var> ]».</p></li>
100407100455

100408100456
<li><p>Run the <span>message port post message steps</span> providing <var>targetPort</var>,
100409100457
<var>message</var> and <var>options</var>.</p></li>
@@ -101272,7 +101320,7 @@ interface <dfn interface>DedicatedWorkerGlobalScope</dfn> : <span>WorkerGlobalSc
101272101320
[Replaceable] readonly attribute DOMString <span data-x="dom-DedicatedWorkerGlobalScope-name">name</span>;
101273101321

101274101322
undefined <span data-x="dom-DedicatedWorkerGlobalScope-postMessage">postMessage</span>(any message, sequence&lt;<span data-x="idl-object">object</span>&gt; transfer);
101275-
undefined <span data-x="dom-DedicatedWorkerGlobalScope-postMessage-options">postMessage</span>(any message, optional <span>PostMessageOptions</span> options = {});
101323+
undefined <span data-x="dom-DedicatedWorkerGlobalScope-postMessage-options">postMessage</span>(any message, optional <span>StructuredSerializeOptions</span> options = {});
101276101324

101277101325
undefined <span data-x="dom-DedicatedWorkerGlobalScope-close">close</span>();
101278101326

@@ -101294,10 +101342,8 @@ interface <dfn interface>DedicatedWorkerGlobalScope</dfn> : <span>WorkerGlobalSc
101294101342
data-x="concept-WorkerGlobalScope-name">name</span>, i.e. the value given to the
101295101343
<code>Worker</code> constructor. Primarily useful for debugging.</p></dd>
101296101344

101297-
<dt><code data-x=""><var>dedicatedWorkerGlobal</var>.<span subdfn data-x="dom-DedicatedWorkerGlobalScope-postMessage">postMessage</span>(<var>message</var> [,
101298-
<var>transfer</var> ])</code></dt>
101299-
<dt><code data-x=""><var>dedicatedWorkerGlobal</var>.<span subdfn data-x="dom-DedicatedWorkerGlobalScope-postMessage-options">postMessage</span>(<var>message</var>
101300-
[, { <span data-x="dom-PostMessageOptions-transfer">transfer</span> } ])</code></dt>
101345+
<dt><code data-x=""><var>dedicatedWorkerGlobal</var>.<span subdfn data-x="dom-DedicatedWorkerGlobalScope-postMessage">postMessage</span>(<var>message</var> [, <var>transfer</var> ])</code></dt>
101346+
<dt><code data-x=""><var>dedicatedWorkerGlobal</var>.<span subdfn data-x="dom-DedicatedWorkerGlobalScope-postMessage-options">postMessage</span>(<var>message</var> [, { <span data-x="dom-StructuredSerializeOptions-transfer">transfer</span> } ])</code></dt>
101301101347
<dd><p>Clones <var>message</var> and transmits it to the <code>Worker</code> object associated
101302101348
with <var>dedicatedWorkerGlobal</var>. <var>transfer</var> can be passed as a list of objects
101303101349
that are to be transferred rather than cloned.</p></dd>
@@ -102007,7 +102053,7 @@ interface <dfn interface>Worker</dfn> : <span>EventTarget</span> {
102007102053
undefined <span data-x="dom-Worker-terminate">terminate</span>();
102008102054

102009102055
undefined <span data-x="dom-Worker-postMessage">postMessage</span>(any message, sequence&lt;<span data-x="idl-object">object</span>&gt; transfer);
102010-
undefined <span data-x="dom-Worker-postMessage-options">postMessage</span>(any message, optional <span>PostMessageOptions</span> options = {});
102056+
undefined <span data-x="dom-Worker-postMessage-options">postMessage</span>(any message, optional <span>StructuredSerializeOptions</span> options = {});
102011102057
attribute <span>EventHandler</span> <span data-x="handler-Worker-onmessage">onmessage</span>;
102012102058
attribute <span>EventHandler</span> <span data-x="handler-Worker-onmessageerror">onmessageerror</span>;
102013102059
};
@@ -102037,7 +102083,7 @@ enum <dfn enum>WorkerType</dfn> { "classic", "module" };
102037102083
<dd>Aborts <var>worker</var>'s associated global environment.</dd>
102038102084

102039102085
<dt><code data-x=""><var>worker</var>.<span subdfn data-x="dom-Worker-postMessage">postMessage</span>(<var>message</var> [, <var>transfer</var> ])</code></dt>
102040-
<dt><code data-x=""><var>worker</var>.<span subdfn data-x="dom-Worker-postMessage-options">postMessage</span>(<var>message</var> [, { <span data-x="dom-PostMessageOptions-transfer">transfer</span> } ])</code></dt>
102086+
<dt><code data-x=""><var>worker</var>.<span subdfn data-x="dom-Worker-postMessage-options">postMessage</span>(<var>message</var> [, { <span data-x="dom-StructuredSerializeOptions-transfer">transfer</span> } ])</code></dt>
102041102087
<dd><p>Clones <var>message</var> and transmits it to <var>worker</var>'s global environment.
102042102088
<var>transfer</var> can be passed as a list of objects that are to be transferred rather than
102043102089
cloned.</p></dd>

0 commit comments

Comments
 (0)