diff --git a/spec.bs b/spec.bs
index e30ffa49..41f38f75 100644
--- a/spec.bs
+++ b/spec.bs
@@ -287,10 +287,10 @@ href="https://html.spec.whatwg.org/multipage/embedded-content-other.html#dimensi
attributes section. This section will be updated to include <{fencedframe}> in the list of
elements that the [=width=]
and [=height=]
dimension attributes apply to.
-
Configuration mapping
+Fenced frame config mapping
-Each [=traversable navigable=] has a urn configuration
-mapping, a [=map=] mapping [=urn uuids=] to [=fenced frame config=] [=structs=].
+Each [=traversable navigable=] has a fenced frame config
+mapping, which is a new [=fenced frame config mapping=].
Note: This mapping is consulted during [=navigate|navigation=], and written to by what we
colloquially refer to as *URN-generating APIs* or *config-generating APIs*, that generate both [=urn
@@ -298,7 +298,372 @@ uuids=] and [=fenced frame configs=] for use in navigating <{fencedframe}> and <
See for example, the FLEDGE and Shared Storage specifications.
-The {{FencedFrameConfig}} interface
+A fenced frame config mapping has three submappings:
+
+
+ : pending config mapping
+ :: a [=map=] whose [=map/keys=] are [=urn uuids=] and whose [=map/values=] are [=fenced frame
+ configs=]
+
+ : finalized config mapping
+ :: a [=map=] whose [=map/keys=] are [=urn uuids=] and whose [=map/values=] are [=fenced frame
+ configs=]
+
+ : nested config mapping
+ :: a [=map=] whose [=map/keys=] are [=urn uuids=] and whose [=map/values=] are [=fenced frame
+ configs=]
+
+
+Each [=fenced frame config mapping=] has a maximum number of
+configs, which is implementation-defined. The [=fenced frame config mapping/maximum number of
+configs=] may be a nonnegative number or infinity.
+
+Note: It is important to specify the behavior of
+[=fenced frame config mapping/maximum number of configs=] because its semantics can interact with
+config-generating APIs in a privacy sensitive way.
+
+At a high level, in order to store a [=fenced frame config=] in the
+[=traversable navigable/fenced frame config mapping=], one must first store a pending config, and
+then turn the pending config into a finalized config. Those procedures are as follows:
+
+
+ To store a pending config into a particular
+ [=fenced frame config mapping=] given a [=fenced frame config=] |config|, run these steps:
+
+ 1. Let |pendingMapping| be the [=fenced frame config mapping/pending config mapping=] of the
+ associated [=fenced frame config mapping=].
+
+ 1. If the [=map/size=] of the [=fenced frame config mapping/pending config mapping=] + the
+ [=map/size=] of the [=fenced frame config mapping/finalized config mapping=] >= the [=fenced
+ frame config mapping/maximum number of configs=], return failure.
+
+ 1. Let |urn| be a randomly generated [=urn uuid=].
+
+ 1. [=map/Set=] |pendingMapping|[|urn|] to |config|.
+
+
+
+ To finalize a pending config in a particular
+ [=fenced frame config mapping=] given a [=urn uuid=] |urn|, run these steps:
+
+ 1. Let |pendingMapping| be the [=fenced frame config mapping/pending config mapping=] of the
+ associated [=fenced frame config mapping=].
+
+ 1. Let |finalizedMapping| be the [=fenced frame config mapping/finalized config mapping=] of the
+ associated [=fenced frame config mapping=].
+
+ 1. If |pendingMapping|[|urn|] does not [=map/exist=], return failure.
+
+ 1. Let |finalizedConfig| be |pendingMapping|[|urn|].
+
+ 1. [=map/Remove=] |pendingMapping|[|urn|].
+
+ 1. [=map/Set=] |finalizedMapping|[|urn|] be |finalizedConfig|.
+
+
+
+ To store nested configs into a particular
+ [=fenced frame config mapping=] given a [=fenced frame config instance/nested configs=]
+ |nestedConfigs|, run these steps:
+
+ 1. Let |nestedMapping| be the [=fenced frame config mapping/nested config mapping=] of the
+ associated [=fenced frame config mapping=].
+
+ 1. If |nestedConfigs| is null, return.
+
+ 1. [=map/iterate|For each=] |urn| → |config| of |nestedConfigs|:
+
+ 1. [=map/Set=] |nestedMapping|[|urn|] to |config|.
+
+
+
+ To find a config in a particular [=fenced
+ frame config mapping=] given a [=urn uuid=] |urn|, run these steps:
+
+ 1. Let |nestedMapping| be the [=fenced frame config mapping/nested config mapping=] of the
+ associated [=fenced frame config mapping=].
+
+ 1. Let |pendingMapping| be the [=fenced frame config mapping/pending config mapping=] of the
+ associated [=fenced frame config mapping=].
+
+ 1. Let |finalizedMapping| be the [=fenced frame config mapping/finalized config mapping=] of
+ the associated [=fenced frame config mapping=].
+
+ 1. If |nestedMapping|[|urn|] [=map/exists=], return its value.
+
+ 1. If |pendingMapping|[|urn|] [=map/exists=], wait until it does not [=map/exist=].
+ TODO: Formalize waiting?
+
+ 1. If |finalizedMapping|[|urn|] [=map/exists=], return its value.
+
+ 1. Return failure.
+
+
+Fenced frame configs
+
+Introduction
+
+*This section is non-normative.*
+
+A key feature of the <{fencedframe}> element is that web platform APIs can configure the behavior
+of the frame in a way that limits the ability of other execution contexts to modify or inspect this
+configuration, for security or privacy reasons. For example, the
+FLEDGE API performs on-device ad auctions over
+cross-site data, and it is important that the ad that wins the auction can be loaded into a frame,
+without the API caller knowing *which ad* won the auction or being able to manipulate the
+environment in which the ad loads.
+
+We achieve this using the concept of a "[=fenced frame config=]". A [=fenced frame config=] is a
+collection of fields that can be loaded into <{fencedframe}> elements and that specifies the
+resulting environments. [=Fenced frame configs=] can only be constructed by web platform APIs, not
+initialized or modified arbitrarily. Their fields also contain "[=visibilities=]", which dictate
+whether the field should be "redacted" when inspected through the {{FencedFrameConfig}} interface.
+Config-generating APIs (like FLEDGE and Shared Storage) must specify values for all fields
+of their fenced frame configs in order to ensure that they have considered the privacy implications
+of each field, though they may choose to set the values to null.
+
+Each time a <{fencedframe}> navigates to a [=fenced frame config=], it is instantiated as a new
+[=fenced frame config instance=], which governs that particular context inside the [=fenced
+navigable container/fenced navigable=].
+
+The [=fenced frame config=] [=struct=]
+
+We now establish some preliminary types:
+
+A visibility is either "
+`opaque`" or "`transparent`".
+
+A mapped url is a [=url=]. TODO: Stipulate a
+url with particular schemes?
+
+A size is a struct with non-negative integer 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 exhaustive set of sandbox flags is a [=sandboxing flag
+set=].
+
+An exhaustive set of permissions is a [=list=] of
+[=policy-controlled features=].
+
+A fenced frame reporter is TODO: Specify the type for this.
+
+
+ In order to report an event, run these steps:
+
+ 1. TODO: fill this in
+
+
+
+ In order to report a private aggregation event, run these steps:
+
+ 1. TODO: Fill this in
+
+
+
+ In order to set automatic beacon data, run these steps:
+
+ 1. TODO: Fill this in
+
+
+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.
+
+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?
+
+An embedder shared storage context is a string.
+
+A partition nonce is an [=implementation-defined=] value.
+
+Note: This is similar to the network
+partition key used by Fetch.
+
+A fenced frame config is a struct with the following [=struct/items=]:
+
+
+ : mapped url
+ :: null, or a struct with the following fields:
+ : value
+ :: a [=fencedframetype/mapped url=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : container size
+ :: null, or a [=fencedframetype/size=]
+
+ : content size
+ :: null, or a struct with the following fields:
+ : value
+ :: a [=fencedframetype/size=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : interest group descriptor
+ :: null, or a struct with the following fields:
+ : value
+ :: an [=fencedframetype/interest group descriptor=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : effective sandbox flags
+ :: null, or a struct with the following fields:
+ : value
+ :: an [=fencedframetype/exhaustive set of sandbox flags=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : effective permissions
+ :: null, or a struct with the following fields:
+ : value
+ :: an [=fencedframetype/exhaustive set of permissions=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : fenced frame reporter
+ :: null, or a struct with the following fields:
+ : value
+ :: a [=fencedframetype/fenced frame reporter=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : exfiltration budget metadata
+ :: null, or a struct with the following fields:
+ : value
+ :: an [=fencedframetype/exfiltration budget metadata=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : nested configs
+ :: null, or a struct with the following fields:
+ : value
+ :: a sequence of [=fenced frame configs=]
+
+ : visibility
+ :: a [=visibility=]
+
+ : embedder shared storage context
+ :: null, or an [=fencedframetype/embedder shared storage context=]
+
+
+The [=fenced frame config instance=] [=struct=]
+
+A fenced frame config instance is a struct with the following [=struct/items=]:
+
+
+ : mapped url
+ :: null, or a [=fencedframetype/mapped url=]
+
+ : container size
+ :: null, or a [=fencedframetype/size=]
+
+ : content size
+ :: null, or a [=fencedframetype/size=]
+
+ : interest group descriptor
+ :: null, or an [=fencedframetype/interest group descriptor=]
+
+ : effective sandbox flags
+ :: null, or an [=fencedframetype/exhaustive set of sandbox flags=]
+
+ : effective permissions
+ :: null, or an [=fencedframetype/exhaustive set of permissions=]
+
+ : fenced frame reporter TODO: including automatic beacon info
+ :: null, or a [=fencedframetype/fenced frame reporter=]
+
+ : exfiltration budget metadata reference
+ :: null, or an [=fencedframetype/exfiltration budget metadata reference=]
+
+ : nested configs
+ :: null, or an [=ordered map=] whose [=map/keys=] are [=urn uuids=] and whose [=map/values=] are
+ [=fenced frame configs=]
+
+ : partition nonce
+ :: a [=partition nonce=]
+
+ : embedder shared storage context
+ :: null, or an [=fencedframetype/embedder shared storage context=]
+
+
+
+ To instantiate a config given a [=fenced frame config=] |config|, return a
+ [=fenced frame config instance=] with the following members:
+
+ : [=fenced frame config instance/mapped url=]
+ :: |config|'s [=fenced frame config/mapped url=] if null, otherwise |config|'s [=fenced frame
+ config/mapped url=]'s [=mapped url/value=]
+
+ : [=fenced frame config instance/container size=]
+ :: |config|'s [=fenced frame config/container size=] if null
+
+ : [=fenced frame config instance/content size=]
+ :: |config|'s [=fenced frame config/content size=] if null, otherwise |config|'s [=fenced frame
+ config/content size=]'s [=content size/value=]
+
+ : [=fenced frame config instance/interest group descriptor=]
+ :: |config|'s [=fenced frame config/interest group descriptor=] if null, otherwise |config|'s
+ [=fenced frame config/interest group descriptor=]'s [=interest group descriptor/value=]
+
+ : [=fenced frame config instance/effective sandbox flags=]
+ :: |config|'s [=fenced frame config/effective sandbox flags=] if null, otherwise |config|'s
+ [=fenced frame config/effective sandbox flags=]'s [=effective sandbox flags/value=]
+
+ : [=fenced frame config instance/effective permissions=]
+ :: |config|'s [=fenced frame config/effective permissions=] if null, otherwise |config|'s
+ [=fenced frame config/effective permissions=]'s [=effective permissions/value=]
+
+ : [=fenced frame config instance/fenced frame reporter=]
+ :: |config|'s TODO: Fill this in
+
+ : [=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=]
+
+ : [=exfiltration budget metadata reference/amount to debit reference=]
+ :: a reference to |config|'s [=fenced frame config/exfiltration budget metadata=]'s
+ [=exfiltration budget metadata/value=]'s [=exfiltration budget metadata/amount to
+ debit=]
+
+ : [=fenced frame config instance/nested configs=]
+ ::
+ 1. If |config|'s [=fenced frame config/nested configs=] is null, set to null.
+
+ 1. Otherwise, set to an [=ordered map=], where for each [=fenced frame config=] in
+ |config|'s [=fenced frame config/nested configs=]'s [=nested configs/value=], there is
+ an entry where the key is a randomly sampled [=urn uuid=] and the value is the [=fenced
+ frame config=]. TODO: Write this in the proper syntax
+
+ : [=fenced frame config instance/partition nonce=]
+ :: a random, unique [=partition nonce=]
+
+ : [=fenced frame config instance/embedder shared storage context=]
+ :: |config|'s [=fenced frame config/embedder shared storage context=]
+
+
+The {{FencedFrameConfig}} interface
One major input to the <{fencedframe}> element is the {{FencedFrameConfig}} interface, which
maps to an internal [=fenced frame config=] [=struct=].
@@ -312,34 +677,48 @@ maps to an internal [=fenced frame config=] [=struct=].
[Exposed=Window]
interface FencedFrameConfig {
constructor(USVString url);
+
readonly attribute FencedFrameConfigURL? url;
readonly attribute FencedFrameConfigSize? width;
readonly attribute FencedFrameConfigSize? height;
+
+ undefined setSharedStorageContext(DOMString contextString);
};
Issue: Fix the "indistinguishable" IDL bug with the unions above.
-Each {{FencedFrameConfig}} has a url, which is a string, initially
-null.
+Each {{FencedFrameConfig}} has a url, which is a [=URL=].
-Each {{FencedFrameConfig}} has a urn uuid, which is a [=urn uuid=]
-string, initially null.
+1. TODO: add more fields to {{FencedFrameConfig}}
-Note: A {{FencedFrameConfig}}'s [=fencedframeconfig/urn uuid=] is a non-web-exposed unique ID that
-serves as the key to the <{fencedframe}> element's [=fenced navigable container/fenced navigable=]'s
-URN config mapping, which maps [=urn uuids=] to [=fenced frame config=]
-[=structs=] (that represent the web-exposed {{FencedFrameConfig}} object).
+
+ The {{FencedFrameConfig/url}} IDL attribute getter steps are:
-A fenced frame config is a struct with the following [=struct/items=]:
+ 1. TODO
+
+
+
+ The {{FencedFrameConfig/width}} IDL attribute getter steps are:
-* An urn uuid, a [=urn uuid=] string
-* TODO: Specify the other members
+ 1. TODO
+
+
+
+ The {{FencedFrameConfig/height}} IDL attribute getter steps are:
+
+ 1. TODO
+
+
+
+ The setSharedStorageContext(contextString) method steps are:
+ 1. TODO
+
The {{Fence}} interface
-Describe this infrastructure in detail.
+Several APIs specific to fenced frames are defined on the {{Fence}} interface.
enum FenceReportingDestination {
@@ -369,19 +748,71 @@ A fenced frame config is a struct with the following [=struct/
The reportEvent(event) method steps are:
- 1. Fill this out!
+ 1. Let |instance| be [=this=]'s [=relevant global object=]'s [=associated Document=]'s [=node
+ navigable=]'s [=navigable/traversable navigable=]'s [=fenced frame config instance=].
+
+ This and the below references should point to an actual member on [=traversable
+ navigable=], not just the type.
+
+ 1. If |instance| is null, then return.
+
+ 1. [=Assert=] |instance|'s [=fenced frame config instance/mapped url=] is not null.
+
+ 1. If the [=relevant settings object=]'s [=origin=] and |instance|'s
+ [=fenced frame config instance/mapped url=]'s origin are not [=same origin=], then return.
+
+ 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 {{FenceEvent}}, run [=report an event=] with |event| and |instance|'s
+ [=fenced frame config instance/fenced frame reporter=].
- The setReportEventDataForAutomaticBeacons(event) method steps are:
+ The setReportEventDataForAutomaticBeacons(event)
+ method steps are:
+
+ 1. Let |instance| be [=this=]'s [=relevant global object=]'s [=associated Document=]'s [=node
+ navigable=]'s [=navigable/traversable navigable=]'s [=fenced frame config instance=].
+
+ 1. If |instance| is null, then return.
+
+ 1. [=Assert=] |instance|'s [=fenced frame config instance/mapped url=] is not null.
- 1. Fill this out!
+ 1. If the [=relevant settings object=]'s [=origin=] and |instance|'s
+ [=fenced frame config instance/mapped url=]'s origin are not [=same origin=], then return.
+
+ 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=].
The getNestedConfigs() method steps are:
- 1. Fill this out!
+ 1. Let |instance| be [=this=]'s [=relevant global object=]'s [=associated Document=]'s [=node
+ navigable=]'s [=navigable/traversable navigable=]'s [=fenced frame config instance=].
+
+ 1. If |instance| is null, then return.
+
+ 1. [=Assert=] |instance|'s [=fenced frame config instance/mapped url=] is not null.
+
+ 1. If the [=relevant settings object=]'s [=origin=] and |instance|'s
+ [=fenced frame config instance/mapped url=]'s origin are not [=same origin=], then return.
+
+ 1. If |instance|'s [=fenced frame config instance/nested configs=] is null, then return.
+
+ 1. Let |results| be an empty [=list=] of {{FencedFrameConfig}}s.
+
+ 1. [=map/For each=] |urn| → |config| of |instance|'s [=fenced frame config instance/nested
+ configs=]:
+
+ 1. TODO: construct a {{FencedFrameConfig}} from |config| and |urn|.
+
+ 1. Return |results|.
New [=request=] [=request/destination=]
@@ -489,8 +920,8 @@ Each {{Window}} object has an associated fence, which is a
The fence getter steps are:
- 1. If [=this=]'s [=Window/navigable=]'s [=navigable/loading mode=] is "`fencedframe`", return
- [=this=]'s [=Window/fence=].
+ 1. If [=this=]'s [=Window/navigable=]'s [=fenced frame config instance=] is not null, then
+ return [=this=]'s [=Window/fence=].
1. Return null.