Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single Promise, options object, revamped processing model #70

Merged
merged 14 commits into from
Mar 6, 2020
92 changes: 66 additions & 26 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ urlPrefix: https://tools.ietf.org/html/draft-ietf-httpbis-header-structure; spec
text: list; url: #section-3.1
type: abstract-op
text: serialize Structured Header; url: #section-4.1
spec:infra; type:dfn; for:/; text:list
</pre>
<pre class="biblio">
{
Expand Down Expand Up @@ -316,56 +317,96 @@ Interface {#interface}
=================

<pre class="idl">
dictionary NavigatorUABrandVersionDict {
required DOMString brand;
dictionary NavigatorUABrandVersion {
DOMString brand;
DOMString version;
yoavweiss marked this conversation as resolved.
Show resolved Hide resolved
};

dictionary UADataValues {
DOMString platform;
DOMString platformVersion;
DOMString architecture;
DOMString model;
};

[Exposed=Window]
interface NavigatorUAData {
readonly attribute FrozenArray&lt;NavigatorUABrandVersionDict&gt; brand;
readonly attribute FrozenArray&lt;NavigatorUABrandVersion&gt; uaList;
readonly attribute boolean mobile;
Promise&lt;DOMString&gt; getPlatform();
Promise&lt;SOMString&gt; getPlatformVersion();
Promise&lt;DOMString&gt; getArchitecture();
Promise&lt;DOMString&gt; getModel();
Promise&lt;UADataValues&gt; getHighEntropyValues(sequence&lt;DOMString&gt; hints);
};

interface mixin NavigatorUA {
[SecureContext] NavigatorUAData getUserAgent();
[SecureContext] readonly attribute NavigatorUAData userAgentData;
};
Navigator includes NavigatorUA;

</pre>

Processing model {#processing}
--------------
<dfn method for="NavigatorUA"><code>getUserAgent()</code></dfn> method MUST run these steps:

<h3 id="monkeypatch-html-windoworworkerglobalscope"><code>WindowOrWorkerGlobalScope</code></h3>

Each user agent has an associated <dfn>UA list</dfn>, which is a [=/list=] created by running [=create UA list=].
yoavweiss marked this conversation as resolved.
Show resolved Hide resolved

Every {{WindowOrWorkerGlobalScope}} object has an associated <dfn for="WindowOrWorkerGlobalScope">UA frozen array</dfn>, which is a <code><a interface>FrozenArray</a>&lt;<a dictionary>NavigatorUABrandVersion</a>></code>. It is initially the result of [=create a frozen array|creating a frozen array=] from [=UA list=].
yoavweiss marked this conversation as resolved.
Show resolved Hide resolved

<h3 id="create-ua-list-section">Create a UA list</h3>

When asked to run the <dfn>create UA list</dfn> algorithm, the user agent MUST run the following steps:
yoavweiss marked this conversation as resolved.
Show resolved Hide resolved
1. Let |list| be a [=/list=].

2. Collect pairs of [=user agent/brand=] and [=user agent/significant version=] which represent the user agent,
its equivalence class and/or its rendering engine.

3. For each pair:

1. Let |dict| be a new {{NavigatorUABrandVersion}} dictionary,
with [=user agent/brand=] as {{NavigatorUABrandVersion/brand}} and [=user agent/significant version=] as {{NavigatorUABrandVersion/version}}.

2. Append |dict| to |list|.

4. The user agent MAY execute the following steps:

1. [=list/Append=] additional items to |list| containing {{NavigatorUABrandVersion}} objects,
initialized with arbitrary {{NavigatorUABrandVersion/brand}} and {{NavigatorUABrandVersion/version}} combinations.

2. Randomize the order of the items in |list|.

Note: See [[#grease]] for more details on why these steps might be appropriate.

5. Return |list|.

<h3 id="getters">Getters</h3>

On getting, the {{NavigatorUAData/uaList}} attribute MUST return [=this=]'s [=relevant global object=]'s [=WindowOrWorkerGlobalScope/UA frozen array=].

On getting, the {{NavigatorUAData/mobile}} attribute must return the user agent's [=user agent/mobileness=].

<h3 id="getHighEntropyValues"><code>getHighEntropyValues</code> method</h3>

The <dfn method for="NavigatorUA"><code>getHighEntropyValues(|hints|)</code></dfn> method MUST run these steps:

1. Let |p| be a [=a new promise=].

2. Run the following steps [=in parallel=]:

1. Let |UAData| be a new {{NavigatorUAData}} object whose values are initialized as follows:
1. Let |uaData| be a new {{UADataValues}}.

: {{NavigatorUAData/brand}}
:: The user agent's [=user agent/brand=].
: {{NavigatorUAData/getPlatform}}
:: The user agent's [=user agent/platform brand=].
: {{NavigatorUAData/getPlatformVersion}}
:: The user agent's [=user agent/platform version=].
: {{NavigatorUAData/getArchitecture}}
:: The user agent's [=user agent/platform architecture=].
: {{NavigatorUAData/getModel}}
:: The user agent's [=user agent/model=].
: {{NavigatorUAData/mobile}}
:: The user agent's [=user agent/mobileness=].
2. If |hints| [=contains=] "platform", set |uaData|["{{UADataValues/platform}}"] to the user agent's [=user agent/platform brand=].

2. [=Resolve=] |p| with |UAData|.
3. If |hints| [=contains=] "platformVersion", set |uaData|["{{UADataValues/platformVersion}}"] to the user agent's [=user agent/platform version=].

3. Return |p|.
4. If |hints| [=contains=] "architecture", set |uaData|["{{UADataValues/architecture}}"] to the user agent's [=user agent/platform architecture=].

5. If |hints| [=contains=] "model", set |uaData|["{{UADataValues/model}}"] to the user agent's [=user agent/model=].

6. [=Queue a task=] to [=resolve=] |p| with |uaData|.

ISSUE: Provide a method to only access the UA's significant version.
ISSUE: Add a specific task source this is queued on.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on the task queue for this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you plan to implement in Chrome?

There's always the option of giving maximum flexibility by creating an entirely new task source.

The closest counterpart I can think of off the top of my head is createImageBitmap. Unfortunately that doesn't do this right either :(. whatwg/html#5329


3. Return |p|.

Security and Privacy Considerations {#security-privacy}
===================================
Expand Down Expand Up @@ -590,4 +631,3 @@ Author/Change controller:

Specification document:
: this specification ([[#user-agent]]), and Section 5.5.3 of [[RFC7231]]