diff --git a/spec.bs b/spec.bs
index 3cc34517..e1d31e00 100644
--- a/spec.bs
+++ b/spec.bs
@@ -538,45 +538,185 @@ A size is a struct with non-negative integ
"size">width and non-negative integer height.
TODO: Maybe change the numeric type.
-An interest group descriptor is a struct with owner, which is a string, and name, which is a string.
+An interest group descriptor is a struct with the following
+[=struct/items=]:
+
+
+ : owner
+ :: a [=string=]
+
+ : name
+ :: a [=string=]
+
An exhaustive set of sandbox flags is a [=sandboxing flag
set=].
-A fenced frame reporter is TODO: Specify the type for this.
+A pending event is a struct with the following [=struct/items=]:
+
+ : destination
+ :: a {{FenceReportingDestination}}
+
+ : eventType
+ :: a [=string=]
+
+ : eventData
+ :: a [=string=]
+
+
+A fenced frame reporting map is a [=map=] whose [=map/keys=]
+are {{FenceReportingDestination}}s and whose [=map/values=] are either:
+ * [=lists=] of [=fencedframetype/pending events=] (which are used to represent events that need to
+ be reported asynchronously, because the metadata has not been finalized yet); or
+ * [=maps=] whose [=map/keys=] are [=strings=] and whose [=map/values=] are [=urls=] (which are used
+ to represent the actual metadata once it is finalized).
+
+Note: This representation is meant to allow config-generating APIs to reduce latency by resolving
+the values of reporting destinations asynchronously, after they've already constructed and returned
+the fenced frame config (and even after the config has been loaded, and event reports have been
+generated inside the fenced frame). When the config-generating API declares the [=fencedframetype/
+fenced frame reporting map=], they can mark certain destinations as pending using an empty
+[=list=], and then maintain a reference to the map for later. If the fenced frame attempts to
+[=report an event=] to a destination while it is still pending, it stores the event in this
+[=list=] for later handling. When the config-generating API or its callback eventually [=finalizes
+a reporting destination=] through the reference it kept, it will handle all of the pending events
+stored in the [=list=]. If the destination is never finalized, then the pending events will never
+be sent.
- In order to report an event, run these steps:
+ In order to finalize a reporting destination, given a [=fencedframetype/fenced
+ frame reporting map=] |reporting map|, a {{FenceReportingDestination}} |destination|, and a
+ [=map=] |destination map| whose [=map/keys=] are [=strings=] and whose [=map/values=] are
+ [=urls=], run these steps:
- 1. TODO: fill this in
+ 1. [=Assert=] that |reporting map|[|destination|] is a [=list=] (i.e., that |destination|'s
+ metadata has not yet been finalized).
+
+ 1. Let |pending event list| be |reporting map|[|destination|].
+
+ 1. [=map/Set=] |reporting map|[|destination|] to |destination map|.
+
+ 1. [=list/For each=] |pending event| of |pending event list|:
+
+ 1. [=Send a beacon=] with |destination map|, |pending event|'s [=pending event/eventType=],
+ and |pending event|'s [=pending event/eventData=].
+A fenced frame reporting metadata is a struct with the
+following [=struct/items=]:
+
+
+ : fenced frame reporting map
+ :: a [=fencedframetype/fenced frame reporting map=]
+
+ : direct seller is seller
+ :: a boolean
+
+
+A fenced frame reporter is a struct with the following
+[=struct/items=]:
+
+ : fenced frame reporting metadata reference
+ :: a mutable reference to a [=fencedframetype/fenced frame reporting metadata=]
+ TODO: Handle pointers/references in a more spec-y way
+
+ : automatic beacon data
+ :: null, or a struct with the following [=struct/items=]:
+
+ : eventData
+ :: a [=string=]
+
+ : destination
+ :: a [=list=] of {{FenceReportingDestination}}s
+
+
+
- In order to report a private aggregation event, run these steps:
+ In order to send a beacon with a [=map=] |destination map| whose [=map/keys=] are
+ [=strings=] and whose [=map/values=] are [=urls=], a [=string=] |eventType|, and a [=string=]
+ |eventData|, run these steps:
+
+ 1. If |destination map|[|eventType|] does not [=map/exist=], return.
- 1. TODO: Fill this in
+ 1. Let |destination url| be |destination map|[|eventType|].
+
+ 1. Send a beacon with |eventData| to |destination url|.
+
+ Issue: Specify the [[FETCH]] integration for sending this request.
- In order to set automatic beacon data, run these steps:
+ In order to report an event using a [=fencedframetype/fenced frame reporter=]
+ |reporter| with a {{FenceReportingDestination}} |destination|, [=string=] |eventType|, and
+ [=string=] |eventData|, run these steps:
+
+ 1. If |destination| is `"direct-seller"`:
+
+ 1. If |reporter|'s [=fenced frame reporter/fenced frame reporting metadata reference=]'s
+ [=fenced frame reporting metadata/direct seller is seller=] is true, set |destination| to
+ `"seller"`.
+
+ 1. Otherwise, set |destination| to `"component-seller"`.
+
+ 1. Let |reporting map| be a reference to |reporter|'s [=fenced frame reporter/fenced frame
+ reporting metadata reference=]'s [=fenced frame reporting metadata/fenced frame reporting
+ map=].
+
+ 1. If |reporting map|[|destination|] does not [=map/exist=], return.
+
+ 1. If |reporting map|[|destination|] is a [=list=]:
+
+ 1. Let |newEvent| be a new [=fencedframetype/pending event=] with the following:
+ : [=pending event/destination=]
+ :: |destination|
- 1. TODO: Fill this in
+ : [=pending event/eventType=]
+ :: |eventType|
+
+ : [=pending event/eventData=]
+ :: |eventData|
+
+ 1. [=list/Append=] |newEvent| to |reporting map|[|destination|].
+
+ 1. Return.
+
+ Note: The pending event will be sent asynchronously.
+
+ 1. [=Assert=] that |reporting map|[|destination|] is a [=map=] (i.e. that |destination|'s
+ metadata has been finalized).
+
+ 1. [=Send a beacon=] with |reporting map|[|destination|], |eventType|, and |eventData|.
-An exfiltration budget metadata is a struct containing an
-origin, which is an [=origin=]; and an amount to debit, which is a non-negative valid
-floating point number.
+
+ In order to report a private aggregation event using a [=fencedframetype/fenced frame
+ reporter=] |reporter| with a [=string=] |event|, run these steps:
+
+ 1. |reporter| |event| TODO: Fill this in
+
+
+An exfiltration budget metadata is a struct with the following
+[=struct/items=]:
+
+
+ : origin
+ :: an [=origin=]
+
+ : amount to debit
+ :: a non-negative valid floating point number
+
+
+An exfiltration budget metadata reference is a struct with the
+following [=struct/items=]:
-An exfiltration budget metadata reference is a struct
-containing an origin, which is an
-[=origin=]; and an amount to debit
-reference, which is a mutable reference to a non-negative valid floating point number.
-TODO: are mutable references a thing in spec?
+
+ : origin
+ :: an [=origin=]
-An embedder shared storage context is a string.
+ : amount to debit reference
+ :: a mutable reference to a non-negative valid floating point number
+ TODO: Handle pointers/references in a more specy-y way
+
A partition nonce is an [=implementation-defined=] value.
@@ -641,10 +781,10 @@ A fenced frame config is a struct with the following [=struct/
"`Disabled`", the navigation to this config will fail. Any [=policy-controlled feature=] *not*
in this list will not be "`Disabled`" in the <{fencedframe}> that navigates to this config.
- : fenced frame reporter
+ : fenced frame reporting metadata
:: null, or a struct with the following fields:
- : value
- :: a [=fencedframetype/fenced frame reporter=]
+ : value
+ :: a [=fencedframetype/fenced frame reporting metadata=]
: visibility
:: a [=visibility=]
@@ -666,7 +806,7 @@ A fenced frame config is a struct with the following [=struct/
:: a [=visibility=]
: embedder shared storage context
- :: null, or an [=fencedframetype/embedder shared storage context=]
+ :: null, or a [=string=]
The [=fenced frame config instance=] [=struct=]
@@ -692,7 +832,7 @@ A fenced frame config instance is a struct with the following
: effective enabled permissions
:: null, or a [=list=] of [=policy-controlled features=]
- : fenced frame reporter TODO: including automatic beacon info
+ : fenced frame reporter
:: null, or a [=fencedframetype/fenced frame reporter=]
: exfiltration budget metadata reference
@@ -706,7 +846,7 @@ A fenced frame config instance is a struct with the following
:: a [=partition nonce=]
: embedder shared storage context
- :: null, or an [=fencedframetype/embedder shared storage context=]
+ :: null, or a [=string=]
@@ -737,13 +877,26 @@ A fenced frame config instance is a struct with the following
permissions/value=]
: [=fenced frame config instance/fenced frame reporter=]
- :: |config|'s TODO: Fill this in
+ ::
+ 1. If |config|'s [=fenced frame config/fenced frame reporting metadata=]'s [=fenced frame
+ reporting metadata/value=] is null, set to null.
+
+ 1. Otherwise, set to a [=fencedframetype/fenced frame reporter=] with the following
+ members:
+
+ : [=fenced frame reporter/fenced frame reporting metadata reference=]
+ :: a reference to |config|'s [=fenced frame config/fenced frame reporting metadata=]'s
+ [=fenced frame reporting metadata/value=]
+
+ : [=fenced frame reporter/automatic beacon data=]
+ :: null
: [=fenced frame config instance/exfiltration budget metadata reference=]
::
1. If |config|'s [=fenced frame config/exfiltration budget metadata=] is null, set to null.
1. Otherwise, set to a [=fencedframetype/exfiltration budget metadata reference=]:
+
: [=exfiltration budget metadata reference/origin=]
:: |config|'s [=fenced frame config/exfiltration budget metadata=]'s [=exfiltration
budget metadata/value=]'s [=exfiltration budget metadata/origin=]
@@ -922,11 +1075,14 @@ Several APIs specific to fenced frames are defined on the {{Fence}} interface.
1. If |instance|'s [=fenced frame config instance/fenced frame reporter=] is null, then return.
- 1. If |event| is a {{DOMString}}, run [=report a private aggregation event=] with |event| and
- |instance|'s [=fenced frame config instance/fenced frame reporter=].
+ 1. If |event| is a {{DOMString}}, run [=report a private aggregation event=] using |instance|'s
+ [=fenced frame config instance/fenced frame reporter=] with |event|.
+
+ 1. If |event| is a {{FenceEvent}}, [=list/for each=] |destination| of |event|'s {{FenceEvent/destination}}:
- 1. If |event| is a {{FenceEvent}}, run [=report an event=] with |event| and |instance|'s
- [=fenced frame config instance/fenced frame reporter=].
+ 1. Run [=report an event=] using |instance|'s [=fenced frame config instance/fenced frame
+ reporter=] with |destination|, |event|'s {{FenceEvent/eventType}}, and |event|'s
+ {{FenceEvent/eventData}}.
/fenced-frame/fence-report-event.https.html
@@ -937,6 +1093,8 @@ Several APIs specific to fenced frames are defined on the {{Fence}} interface.
The setReportEventDataForAutomaticBeacons(|event|)
method steps are:
+ 1. If |event|'s {{FenceEvent/eventType}} is not `"reserved.top_navigation"`, return.
+
1. Let |instance| be [=this=]'s [=relevant global object=]'s [=associated Document=]'s [=node
navigable=]'s [=navigable/traversable navigable=]'s [=navigable/fenced frame config instance=].
@@ -948,8 +1106,14 @@ Several APIs specific to fenced frames are defined on the {{Fence}} interface.
1. If |instance|'s [=fenced frame config instance/fenced frame reporter=] is null, then return.
- 1. Run [=set automatic beacon data=] with |event| and |instance|'s
- [=fenced frame config instance/fenced frame reporter=].
+ 1. Set |instance|'s [=fenced frame config instance/fenced frame reporter=]'s [=fenced frame
+ reporter/automatic beacon data=] to a struct with the following members:
+
+ : eventData
+ :: |event|'s {{FenceEvent/eventData}}
+
+ : destination
+ :: |event|'s {{FenceEvent/destination}}
/fenced-frame/set-automatic-beacon.https.html