@@ -1402,14 +1402,21 @@ and a [=moment=] |now|:
14021402<div algorithm>
14031403The <dfn method for=Attribution>saveImpression(|options|)</dfn> method steps are:
14041404
1405- 1. Let |realm| be [=this=] 's [=relevant realm=] .
1406- 1. Let |window| be [=this=] 's [=relevant global object=] .
1407- 1. [=Assert=] : |window| is a {{Window}} .
1408- 1. If |window|'s [=associated Document=] is not
1409- [=allowed to use=] the [=policy-controlled feature=] named
1405+ 1. Let |implicitInputs| be the result of [=obtaining the implicit API inputs=] from [=this=] .
1406+ 1. [=Assert=] : |implicitInputs| is not null.
1407+ 1. Return the result of running [=save an impression=] with |options| and |implicitInputs|.
1408+
1409+ </div>
1410+
1411+ <div algorithm>
1412+ To <dfn>save an impression</dfn> given {{AttributionImpressionOptions}} |options|
1413+ and [=implicit API inputs=] |implicitInputs|:
1414+
1415+ 1. Let |document| be |implicitInputs|'s [=implicit API inputs/associated document=] .
1416+ 1. Let |realm| be |document|'s [=relevant realm=] .
1417+ 1. If |document| is not [=allowed to use=] the [=policy-controlled feature=] named
14101418 "{{PermissionPolicy/save-impression}} ", return [=a promise rejected with=]
14111419 a {{"NotAllowedError"}} {{DOMException}} in |realm|.
1412- 1. Let |implicitInputs| be the result of [=obtaining the implicit API inputs=] from [=this=] .
141314201. Validate the page-supplied API inputs:
14141421 1. If |options|.{{AttributionImpressionOptions/histogramIndex}} is
14151422 greater than or equal to the [=implementation-defined=] [=maximum histogram size=] ,
@@ -1481,16 +1488,20 @@ The <dfn>implicit API inputs</dfn> is a [=struct=] with the following fields:
14811488<dfn>Top-Level Site</dfn> : A [=site=] .
14821489<dfn>Intermediary Site</dfn> : A [=site=] or `undefined`.
14831490<dfn>Timestamp</dfn> : A [=moment=] .
1491+ <dfn>Associated Document</dfn> : A {{Document}} .
14841492</pre>
14851493</div>
14861494
14871495<div algorithm>
1488- To <dfn>obtain the implicit API inputs</dfn> from [=this=] :
1496+ To <dfn>obtain the implicit API inputs</dfn> from [=realm=] |realm| with
1497+ optional [=origin=] (default null):
14891498
1490- 1. Let |settings| be [=this=] 's [=relevant settings object=] .
1499+ 1. Let |window| be |realm|'s [=realm/global object=] .
1500+ 1. If |window| is not a {{Window}} , return null.
1501+ 1. Let |settings| be |realm|'s [=realm/settings object=] .
149115021. Let |timestamp| be |settings|' [=environment settings object/current wall time=] .
149215031. Let |topLevelOrigin| be |settings|' [=environment/top-level origin=] .
1493- 1. Let |origin| be |settings|' [=environment settings object/origin=] .
1504+ 1. If |origin| is null, set |origin| to |settings|' [=environment settings object/origin=] .
149415051. Let |topLevelSite| be the result of [=obtain a site|obtaining a site=] from |topLevelOrigin|.
149515061. Let |intermediarySite| be:
14961507 1. a value of `undefined` if |origin| is [=same site=] with |topLevelOrigin|,
@@ -1502,6 +1513,8 @@ To <dfn>obtain the implicit API inputs</dfn> from [=this=]:
15021513 :: |intermediarySite|
15031514 : [=implicit API inputs/timestamp=]
15041515 :: |timestamp|
1516+ : [=implicit API inputs/associated document=] :
1517+ :: |window|'s [=associated document=]
15051518
15061519</div>
15071520
@@ -1513,14 +1526,13 @@ asynchronously, queuing work on the <dfn>Attribution [=task source=]</dfn>.
15131526<div algorithm>
15141527The <dfn method for=Attribution>measureConversion(|options|)</dfn> method steps are:
15151528
1516- 1. Let |realm | be [=this=] 's [=relevant realm =] .
1517- 1. Let |window| be [=this=] 's [=relevant global object=] .
1518- 1. [=Assert=] : |window| is a {{Window}} .
1519- 1. If |window| 's [=associated Document=] is not
1520- [=allowed to use=] the [=policy-controlled feature=] named
1529+ 1. Let |implicitInputs | be the result of [=obtaining the implicit API inputs=] from [=this =] .
1530+ 1. [=Assert=] : |implicitInputs| is not null .
1531+ 1. Let |document| be |implicitInputs|'s [=implicit API inputs/associated document=] .
1532+ 1. Let |realm| be |document| 's [=relevant realm=] .
1533+ 1. If |document| is not [=allowed to use=] the [=policy-controlled feature=] named
15211534 "{{PermissionPolicy/measure-conversion}} ", return [=a promise rejected with=]
15221535 a {{"NotAllowedError"}} {{DOMException}} in |realm|.
1523- 1. Let |implicitInputs| be the result of [=obtaining the implicit API inputs=] from [=this=] .
152415361. Let |validatedOptions| be the result of
15251537 [=validate AttributionConversionOptions|validating=] |options|,
15261538 returning [=a promise rejected with=] any thrown reason.
@@ -2000,6 +2012,52 @@ To <dfn noexport>parse a `Save-Impression` header</dfn> given a [=header value=]
20002012
20012013</div>
20022014
2015+ <div algorithm>
2016+ To <dfn noexport>handle Attribution headers</dfn> given a [=request=] |request|
2017+ and [=response=] |response|, run these steps:
2018+
2019+ 1. If |request|'s [=request/destination=] is not one of the following,
2020+ return: `""`, `"audio"`, `"document"`, `"frame"`, `"iframe"`, `"image"`,
2021+ `"script"`, `"track"`, `"video"`.
2022+
2023+ 1. If |request|'s [=request/client=] is not a [=secure context=] , return.
2024+
2025+ 1. If |response|'s [=response/URL=] is not a [=potentially trustworthy URL=] , return.
2026+
2027+ 1. If |response|'s [=response/URL=]' s [=url/scheme=] is not not "`http`" or "`https`", return.
2028+
2029+ 1. Let |implicitInputs| be the result of [=obtaining the implicit API inputs=] from |request|'s [=request/client=]
2030+ with |response|'s [=response/URL=]' s [=url/origin=] .
2031+
2032+ 1. If |implicitInputs| is null, return.
2033+
2034+ 1. Let |saveImpressionHeader| be the result of [=header list/get|getting=] <code> [:Save-Impression:] </code> from |response|'s [=response/header list=] .
2035+
2036+ 1. If |saveImpressionHeader| is null, return.
2037+
2038+ 1. Let |impressionOptions| be the result of [=parse a Save-Impression header|parsing=] |saveImpressionHeader|.
2039+
2040+ 1. If |impressionOptions| is an error, return.
2041+
2042+ 1. [=save an impression|Save=] |impressionOptions| with |implicitInputs|.
2043+
2044+ </div>
2045+
2046+ ## Fetch monkey patches ## {#fetch-monkey-patches}
2047+
2048+ Modify [=HTTP-network fetch=] as follows:
2049+
2050+ <div algorithm=fetch-monkey-patch>
2051+ After the step
2052+
2053+ > If <var ignore> includeCredentials</var> is true, then the user agent should parse and store response `Set-Cookie` headers given |request| and |response|.
2054+
2055+ add the step
2056+
2057+ 1. [=Handle Attribution headers=] with |request| and |response|.
2058+
2059+ </div>
2060+
20032061# Implementation Considerations # {#implementation-considerations}
20042062
20052063* Management and distribution of values for the following:
@@ -3037,6 +3095,7 @@ The privacy architecture is courtesy of the authors of [[PPA-DP]].
30373095<pre class=anchors>
30383096urlPrefix: https://fetch.spec.whatwg.org/; spec: html; type: dfn
30393097 text: request origin; url: #concept-request-origin
3098+ text: HTTP-network fetch; url: #concept-http-network-fetch
30403099urlPrefix: https://html.spec.whatwg.org/; spec: html; type: dfn
30413100 text: host; url: #concept-origin-host
30423101 text: obtain a site
@@ -3066,6 +3125,8 @@ urlPrefix: https://w3ctag.github.io/privacy-principles/; type: dfn;
30663125urlPrefix: https://www.w3.org/TR/fingerprinting-guidance/; type: dfn;
30673126 text: fingerprint; url: #dfn-browser-fingerprinting
30683127 text: fingerprinting; url: #dfn-browser-fingerprinting
3128+ urlPrefix:https://tc39.es/ecma262/#;type:dfn;spec:ecma-262
3129+ url:realm;text:realm
30693130</pre>
30703131<pre class=anchors>
30713132spec:structured header; type:dfn; urlPrefix: https://httpwg.org/specs/rfc9651;
0 commit comments