CINXE.COM
User-Agent Client Hints
<!doctype html><html lang="en"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title>User-Agent Client Hints</title> <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport"> <link href="https://www.w3.org/StyleSheets/TR/2021/cg-draft" rel="stylesheet"> <meta content="Bikeshed version 82ce88815, updated Thu Sep 7 16:33:55 2023 -0700" name="generator"> <link href="https://wicg.github.io/ua-client-hints/" rel="canonical"> <meta content="000b99e6fbc29c8558a3a5e07640c254e36552c9" name="document-revision"> <style>/* Boilerplate: style-autolinks */ .css.css, .property.property, .descriptor.descriptor { color: var(--a-normal-text); font-size: inherit; font-family: inherit; } .css::before, .property::before, .descriptor::before { content: "‘"; } .css::after, .property::after, .descriptor::after { content: "’"; } .property, .descriptor { /* Don't wrap property and descriptor names */ white-space: nowrap; } .type { /* CSS value <type> */ font-style: italic; } pre .property::before, pre .property::after { content: ""; } [data-link-type="property"]::before, [data-link-type="propdesc"]::before, [data-link-type="descriptor"]::before, [data-link-type="value"]::before, [data-link-type="function"]::before, [data-link-type="at-rule"]::before, [data-link-type="selector"]::before, [data-link-type="maybe"]::before { content: "‘"; } [data-link-type="property"]::after, [data-link-type="propdesc"]::after, [data-link-type="descriptor"]::after, [data-link-type="value"]::after, [data-link-type="function"]::after, [data-link-type="at-rule"]::after, [data-link-type="selector"]::after, [data-link-type="maybe"]::after { content: "’"; } [data-link-type].production::before, [data-link-type].production::after, .prod [data-link-type]::before, .prod [data-link-type]::after { content: ""; } [data-link-type=element], [data-link-type=element-attr] { font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace; font-size: .9em; } [data-link-type=element]::before { content: "<" } [data-link-type=element]::after { content: ">" } [data-link-type=biblio] { white-space: pre; } @media (prefers-color-scheme: dark) { :root { --selflink-text: black; --selflink-bg: silver; --selflink-hover-text: white; } } </style> <style>/* Boilerplate: style-colors */ /* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */ :root { color-scheme: light dark; --text: black; --bg: white; --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark); --logo-bg: #1a5e9a; --logo-active-bg: #c00; --logo-text: white; --tocnav-normal-text: #707070; --tocnav-normal-bg: var(--bg); --tocnav-hover-text: var(--tocnav-normal-text); --tocnav-hover-bg: #f8f8f8; --tocnav-active-text: #c00; --tocnav-active-bg: var(--tocnav-normal-bg); --tocsidebar-text: var(--text); --tocsidebar-bg: #f7f8f9; --tocsidebar-shadow: rgba(0,0,0,.1); --tocsidebar-heading-text: hsla(203,20%,40%,.7); --toclink-text: var(--text); --toclink-underline: #3980b5; --toclink-visited-text: var(--toclink-text); --toclink-visited-underline: #054572; --heading-text: #005a9c; --hr-text: var(--text); --algo-border: #def; --del-text: red; --del-bg: transparent; --ins-text: #080; --ins-bg: transparent; --a-normal-text: #034575; --a-normal-underline: #bbb; --a-visited-text: var(--a-normal-text); --a-visited-underline: #707070; --a-hover-bg: rgba(75%, 75%, 75%, .25); --a-active-text: #c00; --a-active-underline: #c00; --blockquote-border: silver; --blockquote-bg: transparent; --blockquote-text: currentcolor; --issue-border: #e05252; --issue-bg: #fbe9e9; --issue-text: var(--text); --issueheading-text: #831616; --example-border: #e0cb52; --example-bg: #fcfaee; --example-text: var(--text); --exampleheading-text: #574b0f; --note-border: #52e052; --note-bg: #e9fbe9; --note-text: var(--text); --noteheading-text: hsl(120, 70%, 30%); --notesummary-underline: silver; --assertion-border: #aaa; --assertion-bg: #eee; --assertion-text: black; --advisement-border: orange; --advisement-bg: #fec; --advisement-text: var(--text); --advisementheading-text: #b35f00; --warning-border: red; --warning-bg: hsla(40,100%,50%,0.95); --warning-text: var(--text); --amendment-border: #330099; --amendment-bg: #F5F0FF; --amendment-text: var(--text); --amendmentheading-text: #220066; --def-border: #8ccbf2; --def-bg: #def; --def-text: var(--text); --defrow-border: #bbd7e9; --datacell-border: silver; --indexinfo-text: #707070; --indextable-hover-text: black; --indextable-hover-bg: #f7f8f9; --outdatedspec-bg: rgba(0, 0, 0, .5); --outdatedspec-text: black; --outdated-bg: maroon; --outdated-text: white; --outdated-shadow: red; --editedrec-bg: darkorange; } @media (prefers-color-scheme: dark) { :root { --text: #ddd; --bg: black; --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E"); --logo-bg: #1a5e9a; --logo-active-bg: #c00; --logo-text: white; --tocnav-normal-text: #999; --tocnav-normal-bg: var(--bg); --tocnav-hover-text: var(--tocnav-normal-text); --tocnav-hover-bg: #080808; --tocnav-active-text: #f44; --tocnav-active-bg: var(--tocnav-normal-bg); --tocsidebar-text: var(--text); --tocsidebar-bg: #080808; --tocsidebar-shadow: rgba(255,255,255,.1); --tocsidebar-heading-text: hsla(203,20%,40%,.7); --toclink-text: var(--text); --toclink-underline: #6af; --toclink-visited-text: var(--toclink-text); --toclink-visited-underline: #054572; --heading-text: #8af; --hr-text: var(--text); --algo-border: #456; --del-text: #f44; --del-bg: transparent; --ins-text: #4a4; --ins-bg: transparent; --a-normal-text: #6af; --a-normal-underline: #555; --a-visited-text: var(--a-normal-text); --a-visited-underline: var(--a-normal-underline); --a-hover-bg: rgba(25%, 25%, 25%, .2); --a-active-text: #f44; --a-active-underline: var(--a-active-text); --borderedblock-bg: rgba(255, 255, 255, .05); --blockquote-border: silver; --blockquote-bg: var(--borderedblock-bg); --blockquote-text: currentcolor; --issue-border: #e05252; --issue-bg: var(--borderedblock-bg); --issue-text: var(--text); --issueheading-text: hsl(0deg, 70%, 70%); --example-border: hsl(50deg, 90%, 60%); --example-bg: var(--borderedblock-bg); --example-text: var(--text); --exampleheading-text: hsl(50deg, 70%, 70%); --note-border: hsl(120deg, 100%, 35%); --note-bg: var(--borderedblock-bg); --note-text: var(--text); --noteheading-text: hsl(120, 70%, 70%); --notesummary-underline: silver; --assertion-border: #444; --assertion-bg: var(--borderedblock-bg); --assertion-text: var(--text); --advisement-border: orange; --advisement-bg: #222218; --advisement-text: var(--text); --advisementheading-text: #f84; --warning-border: red; --warning-bg: hsla(40,100%,20%,0.95); --warning-text: var(--text); --amendment-border: #330099; --amendment-bg: #080010; --amendment-text: var(--text); --amendmentheading-text: #cc00ff; --def-border: #8ccbf2; --def-bg: #080818; --def-text: var(--text); --defrow-border: #136; --datacell-border: silver; --indexinfo-text: #aaa; --indextable-hover-text: var(--text); --indextable-hover-bg: #181818; --outdatedspec-bg: rgba(255, 255, 255, .5); --outdatedspec-text: black; --outdated-bg: maroon; --outdated-text: white; --outdated-shadow: red; --editedrec-bg: darkorange; } /* In case a transparent-bg image doesn't expect to be on a dark bg, which is quite common in practice... */ img { background: white; } } </style> <style>/* Boilerplate: style-counters */ body { counter-reset: example figure issue; } .issue { counter-increment: issue; } .issue:not(.no-marker)::before { content: "Issue " counter(issue); } .example { counter-increment: example; } .example:not(.no-marker)::before { content: "Example " counter(example); } .invalid.example:not(.no-marker)::before, .illegal.example:not(.no-marker)::before { content: "Invalid Example" counter(example); } figcaption { counter-increment: figure; } figcaption:not(.no-marker)::before { content: "Figure " counter(figure) " "; } </style> <style>/* Boilerplate: style-dfn-panel */ :root { --dfnpanel-bg: #ddd; --dfnpanel-text: var(--text); } @media (prefers-color-scheme: dark) { :root { --dfnpanel-bg: #222; --dfnpanel-text: var(--text); } } .dfn-panel { position: absolute; z-index: 35; width: 20em; width: 300px; height: auto; max-height: 500px; overflow: auto; padding: 0.5em 0.75em; font: small Helvetica Neue, sans-serif, Droid Sans Fallback; background: var(--dfnpanel-bg); color: var(--dfnpanel-text); border: outset 0.2em; white-space: normal; /* in case it's moved into a pre */ } .dfn-panel:not(.on) { display: none; } .dfn-panel * { margin: 0; padding: 0; text-indent: 0; } .dfn-panel > b { display: block; } .dfn-panel a { color: var(--dfnpanel-text); } .dfn-panel a:not(:hover) { text-decoration: none !important; border-bottom: none !important; } .dfn-panel > b + b { margin-top: 0.25em; } .dfn-panel ul { padding: 0 0 0 1em; list-style: none; } .dfn-panel li a { white-space: pre; display: inline-block; max-width: calc(300px - 1.5em - 1em); overflow: hidden; text-overflow: ellipsis; } .dfn-panel.activated { display: inline-block; position: fixed; left: .5em; bottom: 2em; margin: 0 auto; max-width: calc(100vw - 1.5em - .4em - .5em); max-height: 30vh; } .dfn-paneled[role="button"] { cursor: pointer; } </style> <style>/* Boilerplate: style-dfn-panel */ :root { --dfnpanel-bg: #ddd; --dfnpanel-text: var(--text); } @media (prefers-color-scheme: dark) { :root { --dfnpanel-bg: #222; --dfnpanel-text: var(--text); } } .dfn-panel { position: absolute; z-index: 35; width: 20em; width: 300px; height: auto; max-height: 500px; overflow: auto; padding: 0.5em 0.75em; font: small Helvetica Neue, sans-serif, Droid Sans Fallback; background: var(--dfnpanel-bg); color: var(--dfnpanel-text); border: outset 0.2em; white-space: normal; /* in case it's moved into a pre */ } .dfn-panel:not(.on) { display: none; } .dfn-panel * { margin: 0; padding: 0; text-indent: 0; } .dfn-panel > b { display: block; } .dfn-panel a { color: var(--dfnpanel-text); } .dfn-panel a:not(:hover) { text-decoration: none !important; border-bottom: none !important; } .dfn-panel > b + b { margin-top: 0.25em; } .dfn-panel ul { padding: 0 0 0 1em; list-style: none; } .dfn-panel li a { white-space: pre; display: inline-block; max-width: calc(300px - 1.5em - 1em); overflow: hidden; text-overflow: ellipsis; } .dfn-panel.activated { display: inline-block; position: fixed; left: .5em; bottom: 2em; margin: 0 auto; max-width: calc(100vw - 1.5em - .4em - .5em); max-height: 30vh; } .dfn-paneled[role="button"] { cursor: pointer; } </style> <style>/* Boilerplate: style-issues */ a[href].issue-return { float: right; float: inline-end; color: var(--issueheading-text); font-weight: bold; text-decoration: none; } </style> <style>/* Boilerplate: style-md-lists */ /* This is a weird hack for me not yet following the commonmark spec regarding paragraph and lists. */ [data-md] > :first-child { margin-top: 0; } [data-md] > :last-child { margin-bottom: 0; } </style> <style>/* Boilerplate: style-selflinks */ :root { --selflink-text: white; --selflink-bg: gray; --selflink-hover-text: black; } .heading, .issue, .note, .example, li, dt { position: relative; } a.self-link { position: absolute; top: 0; left: calc(-1 * (3.5rem - 26px)); width: calc(3.5rem - 26px); height: 2em; text-align: center; border: none; transition: opacity .2s; opacity: .5; } a.self-link:hover { opacity: 1; } .heading > a.self-link { font-size: 83%; } .example > a.self-link, .note > a.self-link, .issue > a.self-link { /* These blocks are overflow:auto, so positioning outside doesn't work. */ left: auto; right: 0; } li > a.self-link { left: calc(-1 * (3.5rem - 26px) - 2em); } dfn > a.self-link { top: auto; left: auto; opacity: 0; width: 1.5em; height: 1.5em; background: var(--selflink-bg); color: var(--selflink-text); font-style: normal; transition: opacity .2s, background-color .2s, color .2s; } dfn:hover > a.self-link { opacity: 1; } dfn > a.self-link:hover { color: var(--selflink-hover-text); } a.self-link::before { content: "¶"; } .heading > a.self-link::before { content: "§"; } dfn > a.self-link::before { content: "#"; } </style> <style>/* Boilerplate: style-syntax-highlighting */ pre.idl.highlight { background: var(--borderedblock-bg, var(--def-bg)); } </style> <style>/* Boilerplate: style-syntax-highlighting */ code.highlight { padding: .1em; border-radius: .3em; } pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; } .highlight:not(.idl) { background: rgba(0, 0, 0, .03); } c-[a] { color: #990055 } /* Keyword.Declaration */ c-[b] { color: #990055 } /* Keyword.Type */ c-[c] { color: #708090 } /* Comment */ c-[d] { color: #708090 } /* Comment.Multiline */ c-[e] { color: #0077aa } /* Name.Attribute */ c-[f] { color: #669900 } /* Name.Tag */ c-[g] { color: #222222 } /* Name.Variable */ c-[k] { color: #990055 } /* Keyword */ c-[l] { color: #000000 } /* Literal */ c-[m] { color: #000000 } /* Literal.Number */ c-[n] { color: #0077aa } /* Name */ c-[o] { color: #999999 } /* Operator */ c-[p] { color: #999999 } /* Punctuation */ c-[s] { color: #a67f59 } /* Literal.String */ c-[t] { color: #a67f59 } /* Literal.String.Single */ c-[u] { color: #a67f59 } /* Literal.String.Double */ c-[cp] { color: #708090 } /* Comment.Preproc */ c-[c1] { color: #708090 } /* Comment.Single */ c-[cs] { color: #708090 } /* Comment.Special */ c-[kc] { color: #990055 } /* Keyword.Constant */ c-[kn] { color: #990055 } /* Keyword.Namespace */ c-[kp] { color: #990055 } /* Keyword.Pseudo */ c-[kr] { color: #990055 } /* Keyword.Reserved */ c-[ld] { color: #000000 } /* Literal.Date */ c-[nc] { color: #0077aa } /* Name.Class */ c-[no] { color: #0077aa } /* Name.Constant */ c-[nd] { color: #0077aa } /* Name.Decorator */ c-[ni] { color: #0077aa } /* Name.Entity */ c-[ne] { color: #0077aa } /* Name.Exception */ c-[nf] { color: #0077aa } /* Name.Function */ c-[nl] { color: #0077aa } /* Name.Label */ c-[nn] { color: #0077aa } /* Name.Namespace */ c-[py] { color: #0077aa } /* Name.Property */ c-[ow] { color: #999999 } /* Operator.Word */ c-[mb] { color: #000000 } /* Literal.Number.Bin */ c-[mf] { color: #000000 } /* Literal.Number.Float */ c-[mh] { color: #000000 } /* Literal.Number.Hex */ c-[mi] { color: #000000 } /* Literal.Number.Integer */ c-[mo] { color: #000000 } /* Literal.Number.Oct */ c-[sb] { color: #a67f59 } /* Literal.String.Backtick */ c-[sc] { color: #a67f59 } /* Literal.String.Char */ c-[sd] { color: #a67f59 } /* Literal.String.Doc */ c-[se] { color: #a67f59 } /* Literal.String.Escape */ c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */ c-[si] { color: #a67f59 } /* Literal.String.Interpol */ c-[sx] { color: #a67f59 } /* Literal.String.Other */ c-[sr] { color: #a67f59 } /* Literal.String.Regex */ c-[ss] { color: #a67f59 } /* Literal.String.Symbol */ c-[vc] { color: #0077aa } /* Name.Variable.Class */ c-[vg] { color: #0077aa } /* Name.Variable.Global */ c-[vi] { color: #0077aa } /* Name.Variable.Instance */ c-[il] { color: #000000 } /* Literal.Number.Integer.Long */ @media (prefers-color-scheme: dark) { .highlight:not(.idl) { background: rgba(255, 255, 255, .05); } c-[a] { color: #d33682 } /* Keyword.Declaration */ c-[b] { color: #d33682 } /* Keyword.Type */ c-[c] { color: #2aa198 } /* Comment */ c-[d] { color: #2aa198 } /* Comment.Multiline */ c-[e] { color: #268bd2 } /* Name.Attribute */ c-[f] { color: #b58900 } /* Name.Tag */ c-[g] { color: #cb4b16 } /* Name.Variable */ c-[k] { color: #d33682 } /* Keyword */ c-[l] { color: #657b83 } /* Literal */ c-[m] { color: #657b83 } /* Literal.Number */ c-[n] { color: #268bd2 } /* Name */ c-[o] { color: #657b83 } /* Operator */ c-[p] { color: #657b83 } /* Punctuation */ c-[s] { color: #6c71c4 } /* Literal.String */ c-[t] { color: #6c71c4 } /* Literal.String.Single */ c-[u] { color: #6c71c4 } /* Literal.String.Double */ c-[ch] { color: #2aa198 } /* Comment.Hashbang */ c-[cp] { color: #2aa198 } /* Comment.Preproc */ c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */ c-[c1] { color: #2aa198 } /* Comment.Single */ c-[cs] { color: #2aa198 } /* Comment.Special */ c-[kc] { color: #d33682 } /* Keyword.Constant */ c-[kn] { color: #d33682 } /* Keyword.Namespace */ c-[kp] { color: #d33682 } /* Keyword.Pseudo */ c-[kr] { color: #d33682 } /* Keyword.Reserved */ c-[ld] { color: #657b83 } /* Literal.Date */ c-[nc] { color: #268bd2 } /* Name.Class */ c-[no] { color: #268bd2 } /* Name.Constant */ c-[nd] { color: #268bd2 } /* Name.Decorator */ c-[ni] { color: #268bd2 } /* Name.Entity */ c-[ne] { color: #268bd2 } /* Name.Exception */ c-[nf] { color: #268bd2 } /* Name.Function */ c-[nl] { color: #268bd2 } /* Name.Label */ c-[nn] { color: #268bd2 } /* Name.Namespace */ c-[py] { color: #268bd2 } /* Name.Property */ c-[ow] { color: #657b83 } /* Operator.Word */ c-[mb] { color: #657b83 } /* Literal.Number.Bin */ c-[mf] { color: #657b83 } /* Literal.Number.Float */ c-[mh] { color: #657b83 } /* Literal.Number.Hex */ c-[mi] { color: #657b83 } /* Literal.Number.Integer */ c-[mo] { color: #657b83 } /* Literal.Number.Oct */ c-[sa] { color: #6c71c4 } /* Literal.String.Affix */ c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */ c-[sc] { color: #6c71c4 } /* Literal.String.Char */ c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */ c-[sd] { color: #6c71c4 } /* Literal.String.Doc */ c-[se] { color: #6c71c4 } /* Literal.String.Escape */ c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */ c-[si] { color: #6c71c4 } /* Literal.String.Interpol */ c-[sx] { color: #6c71c4 } /* Literal.String.Other */ c-[sr] { color: #6c71c4 } /* Literal.String.Regex */ c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */ c-[fm] { color: #268bd2 } /* Name.Function.Magic */ c-[vc] { color: #cb4b16 } /* Name.Variable.Class */ c-[vg] { color: #cb4b16 } /* Name.Variable.Global */ c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */ c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */ c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */ } </style> <style>/* Boilerplate: style-var-click-highlighting */ /* Colors were chosen in Lab using https://nixsensor.com/free-color-converter/ D50 2deg illuminant, L in [0,100], a and b in [-128, 128] 0 = lab(85,0,85) 1 = lab(85,80,30) 2 = lab(85,-40,40) 3 = lab(85,-50,0) 4 = lab(85,5,15) 5 = lab(85,-10,-50) 6 = lab(85,35,-15) */ var { cursor: pointer; } var.selected0 { background-color: #F4D200; box-shadow: 0 0 0 2px #F4D200; } var.selected1 { background-color: #FF87A2; box-shadow: 0 0 0 2px #FF87A2; } var.selected2 { background-color: #96E885; box-shadow: 0 0 0 2px #96E885; } var.selected3 { background-color: #3EEED2; box-shadow: 0 0 0 2px #3EEED2; } var.selected4 { background-color: #EACFB6; box-shadow: 0 0 0 2px #EACFB6; } var.selected5 { background-color: #82DDFF; box-shadow: 0 0 0 2px #82DDFF; } var.selected6 { background-color: #FFBCF2; box-shadow: 0 0 0 2px #FFBCF2; } </style> <body class="h-entry"> <div class="head"> <p data-fill-with="logo"><a class="logo" href="https://www.w3.org/"> <img alt="W3C" height="48" src="https://www.w3.org/StyleSheets/TR/2021/logos/W3C" width="72"> </a> </p> <h1 class="p-name no-ref" id="title">User-Agent Client Hints</h1> <p id="w3c-state"><a href="https://www.w3.org/standards/types#CG-DRAFT">Draft Community Group Report</a>, <time class="dt-updated" datetime="2024-04-01">1 April 2024</time></p> <div data-fill-with="spec-metadata"> <dl> <dt>This version: <dd><a class="u-url" href="https://wicg.github.io/ua-client-hints/">https://wicg.github.io/ua-client-hints/</a> <dt class="editor">Editors: <dd class="editor p-author h-card vcard" data-editor-id="90704"><a class="p-name fn u-email email" href="mailto:miketaylr@google.com">Mike Taylor</a> (<span class="p-org org">Google LLC</span>) <dd class="editor p-author h-card vcard" data-editor-id="58673"><a class="p-name fn u-email email" href="mailto:yoav@yoav.ws">Yoav Weiss</a> (<span class="p-org org">Google LLC</span>) <dt class="editor">Former Editor: <dd class="editor p-author h-card vcard" data-editor-id="56384"><a class="p-name fn u-email email" href="mailto:mkwst@google.com">Mike West</a> (<span class="p-org org">Google LLC</span>) <dt>Participate: <dd><a href="https://github.com/WICG/ua-client-hints/issues/new">File an issue</a> (<a href="https://github.com/WICG/ua-client-hints/issues">open issues</a>) </dl> </div> <div data-fill-with="warning"></div> <p class="copyright" data-fill-with="copyright"><a href="https://www.w3.org/policies/#copyright">Copyright</a> © 2024 the Contributors to the User-Agent Client Hints Specification, published by the <a href="https://www.w3.org/community/wicg/">Web Platform Incubator Community Group</a> under the <a href="https://www.w3.org/community/about/agreements/cla/">W3C Community Contributor License Agreement (CLA)</a>. A human-readable <a href="http://www.w3.org/community/about/agreements/cla-deed/">summary</a> is available. </p> <hr title="Separator for header"> </div> <div class="p-summary" data-fill-with="abstract"> <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2> <p>This document defines a set of Client Hints that aim to provide developers with the ability to perform agent-based content negotiation when necessary, while avoiding the historical baggage and <a data-link-type="dfn" href="https://w3c.github.io/fingerprinting-guidance/#dfn-passive-fingerprinting" id="ref-for-dfn-passive-fingerprinting">passive fingerprinting</a> surface exposed by the venerable <code>User-Agent</code> header.</p> </div> <div data-fill-with="at-risk"></div> <h2 class="no-num no-toc no-ref heading settled" id="status"><span class="content">Status of this document</span></h2> <div data-fill-with="status"> <p> This specification was published by the <a href="https://www.w3.org/community/wicg/">Web Platform Incubator Community Group</a>. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the <a href="https://www.w3.org/community/about/agreements/cla/">W3C Community Contributor License Agreement (CLA)</a> there is a limited opt-out and other conditions apply. Learn more about <a href="http://www.w3.org/community/">W3C Community and Business Groups</a>. </p> <p></p> </div> <div data-fill-with="at-risk"></div> <nav data-fill-with="table-of-contents" id="toc"> <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2> <ol class="toc" role="directory"> <li> <a href="#intro"><span class="secno">1</span> <span class="content">Introduction</span></a> <ol class="toc"> <li><a href="#examples"><span class="secno">1.1</span> <span class="content">Examples</span></a> <li> <a href="#use-cases"><span class="secno">1.2</span> <span class="content">Use Cases</span></a> <ol class="toc"> <li> <a href="#differential-serving-use-case"><span class="secno">1.2.1</span> <span class="content">Differential serving</span></a> <ol class="toc"> <li><a href="#based-on-browser-features-use-case"><span class="secno">1.2.1.1</span> <span class="content">Based on browser features</span></a> <li><a href="#browser-bug-workaround-use-case"><span class="secno">1.2.1.2</span> <span class="content">Browser bug workaround</span></a> </ol> <li><a href="#marketshare-analytics-use-case"><span class="secno">1.2.2</span> <span class="content">Market Share Analytics</span></a> <li> <a href="#content-adaptation-use-case"><span class="secno">1.2.3</span> <span class="content">Content adaptation</span></a> <ol class="toc"> <li><a href="#browser-based-adaptation-use-case"><span class="secno">1.2.3.1</span> <span class="content">Browser based adaptation</span></a> <li><a href="#mobile-specific-site-use-case"><span class="secno">1.2.3.2</span> <span class="content">Mobile specific site</span></a> <li><a href="#low-powered-devices-use-case"><span class="secno">1.2.3.3</span> <span class="content">Low-powered devices</span></a> <li><a href="#os-specific-styles-use-case"><span class="secno">1.2.3.4</span> <span class="content">OS specific styles</span></a> <li><a href="#os-integration-use-case"><span class="secno">1.2.3.5</span> <span class="content">OS integration</span></a> <li><a href="#browser-os-experiments-use-case"><span class="secno">1.2.3.6</span> <span class="content">Browser and OS specific experiments</span></a> </ol> <li><a href="#user-login-notification-use-case"><span class="secno">1.2.4</span> <span class="content">User login notification</span></a> <li><a href="#binary-executable-downloads"><span class="secno">1.2.5</span> <span class="content">Download of appropriate binary executables</span></a> <li><a href="#conversion-modeling-use-case"><span class="secno">1.2.6</span> <span class="content">Conversion modeling</span></a> <li><a href="#vulnerability-filtering-use-case"><span class="secno">1.2.7</span> <span class="content">Vulnerability filtering</span></a> <li><a href="#logs-debugging-use-case"><span class="secno">1.2.8</span> <span class="content">Logs and debugging</span></a> <li> <a href="#fingerprinting-use-case"><span class="secno">1.2.9</span> <span class="content">Fingerprinting</span></a> <ol class="toc"> <li><a href="#spam-filtering-bots-use-case"><span class="secno">1.2.9.1</span> <span class="content">Spam filtering and bot detection</span></a> <li><a href="#persistent-user-tracking"><span class="secno">1.2.9.2</span> <span class="content">Persistent user tracking</span></a> <li><a href="#blocking-known-bots-crawlers-use-case"><span class="secno">1.2.9.3</span> <span class="content">Blocking known bots and crawlers</span></a> </ol> </ol> </ol> <li><a href="#infrastructure"><span class="secno">2</span> <span class="content">Infrastructure</span></a> <li> <a href="#http-ua-hints"><span class="secno">3</span> <span class="content">User Agent Hints</span></a> <ol class="toc"> <li><a href="#sec-ch-ua"><span class="secno">3.1</span> <span class="content">The 'Sec-CH-UA' Header Field</span></a> <li><a href="#sec-ch-ua-arch"><span class="secno">3.2</span> <span class="content">The 'Sec-CH-UA-Arch' Header Field</span></a> <li><a href="#sec-ch-ua-bitness"><span class="secno">3.3</span> <span class="content">The 'Sec-CH-UA-Bitness' Header Field</span></a> <li><a href="#sec-ch-ua-form-factors"><span class="secno">3.4</span> <span class="content">The 'Sec-CH-UA-Form-Factors' Header Field</span></a> <li><a href="#sec-ch-ua-full-version"><span class="secno">3.5</span> <span class="content">The 'Sec-CH-UA-Full-Version' Header Field</span></a> <li><a href="#sec-ch-ua-full-version-list"><span class="secno">3.6</span> <span class="content">The 'Sec-CH-UA-Full-Version-List' Header Field</span></a> <li><a href="#sec-ch-ua-mobile"><span class="secno">3.7</span> <span class="content">The 'Sec-CH-UA-Mobile' Header Field</span></a> <li><a href="#sec-ch-ua-model"><span class="secno">3.8</span> <span class="content">The 'Sec-CH-UA-Model' Header Field</span></a> <li><a href="#sec-ch-ua-platform"><span class="secno">3.9</span> <span class="content">The 'Sec-CH-UA-Platform' Header Field</span></a> <li><a href="#sec-ch-ua-platform-version"><span class="secno">3.10</span> <span class="content">The 'Sec-CH-UA-Platform-Version' Header Field</span></a> <li><a href="#sec-ch-ua-wow64"><span class="secno">3.11</span> <span class="content">The 'Sec-CH-UA-WoW64' Header Field</span></a> </ol> <li> <a href="#interface"><span class="secno">4</span> <span class="content">Interface</span></a> <ol class="toc"> <li> <a href="#processing"><span class="secno">4.1</span> <span class="content">Processing model</span></a> <ol class="toc"> <li><a href="#monkeypatch-html-windoworworkerglobalscope"><span class="secno">4.1.1</span> <span class="content"><code>WindowOrWorkerGlobalScope</code></span></a> <li><a href="#create-ua-list-section"><span class="secno">4.1.2</span> <span class="content">Create brands</span></a> <li><a href="#create-arbitrary-brands-section"><span class="secno">4.1.3</span> <span class="content">Create arbitrary brand and version values</span></a> <li><a href="#create-brand-version-list"><span class="secno">4.1.4</span> <span class="content">Create a brand-version list</span></a> <li><a href="#getters"><span class="secno">4.1.5</span> <span class="content">Getters</span></a> <li><a href="#getHighEntropyValues"><span class="secno">4.1.6</span> <span class="content"><code>getHighEntropyValues</code> method</span></a> <li><a href="#toJSON"><span class="secno">4.1.7</span> <span class="content"><code>toJSON</code> method</span></a> </ol> </ol> <li> <a href="#security-privacy"><span class="secno">5</span> <span class="content">Security and Privacy Considerations</span></a> <ol class="toc"> <li><a href="#secure-transport"><span class="secno">5.1</span> <span class="content">Secure Transport</span></a> <li><a href="#delegation"><span class="secno">5.2</span> <span class="content">Delegation</span></a> <li><a href="#fingerprinting"><span class="secno">5.3</span> <span class="content">Fingerprinting</span></a> <li><a href="#access"><span class="secno">5.4</span> <span class="content">Access Restrictions</span></a> </ol> <li> <a href="#impl-considerations"><span class="secno">6</span> <span class="content">Implementation Considerations</span></a> <ol class="toc"> <li><a href="#user-agent"><span class="secno">6.1</span> <span class="content">The 'User-Agent' Header</span></a> <li><a href="#grease"><span class="secno">6.2</span> <span class="content">GREASE-like UA Brand Lists</span></a> <li><a href="#sec-ch"><span class="secno">6.3</span> <span class="content">The 'Sec-CH-' prefix</span></a> </ol> <li> <a href="#iana"><span class="secno">7</span> <span class="content">IANA Considerations</span></a> <ol class="toc"> <li><a href="#iana-ua"><span class="secno">7.1</span> <span class="content">'Sec-CH-UA' Header Field</span></a> <li><a href="#iana-arch"><span class="secno">7.2</span> <span class="content">'Sec-CH-UA-Arch' Header Field</span></a> <li><a href="#iana-bitness"><span class="secno">7.3</span> <span class="content">'Sec-CH-UA-Bitness' Header Field</span></a> <li><a href="#iana-form-factors"><span class="secno">7.4</span> <span class="content">'Sec-CH-UA-Form-Factors' Header Field</span></a> <li><a href="#iana-full-version"><span class="secno">7.5</span> <span class="content">'Sec-CH-UA-Full-Version' Header Field</span></a> <li><a href="#iana-full-version-list"><span class="secno">7.6</span> <span class="content">'Sec-CH-UA-Full-Version-List' Header Field</span></a> <li><a href="#iana-mobile"><span class="secno">7.7</span> <span class="content">'Sec-CH-UA-Mobile' Header Field</span></a> <li><a href="#iana-model"><span class="secno">7.8</span> <span class="content">'Sec-CH-UA-Model' Header Field</span></a> <li><a href="#iana-platform"><span class="secno">7.9</span> <span class="content">'Sec-CH-UA-Platform' Header Field</span></a> <li><a href="#iana-platform-version"><span class="secno">7.10</span> <span class="content">'Sec-CH-UA-Platform-Version' Header Field</span></a> <li><a href="#iana-wow64"><span class="secno">7.11</span> <span class="content">'Sec-CH-UA-WoW64' Header Field</span></a> <li><a href="#iana-user-agent"><span class="secno">7.12</span> <span class="content">'User-Agent' Header Field</span></a> </ol> <li><a href="#ack"><span class="secno">8</span> <span class="content">Acknowledgments</span></a> <li> <a href="#w3c-conformance"><span class="secno"></span> <span class="content">Conformance</span></a> <ol class="toc"> <li><a href="#w3c-conventions"><span class="secno"></span> <span class="content">Document conventions</span></a> </ol> <li> <a href="#index"><span class="secno"></span> <span class="content">Index</span></a> <ol class="toc"> <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a> <li><a href="#index-defined-elsewhere"><span class="secno"></span> <span class="content">Terms defined by reference</span></a> </ol> <li> <a href="#references"><span class="secno"></span> <span class="content">References</span></a> <ol class="toc"> <li><a href="#normative"><span class="secno"></span> <span class="content">Normative References</span></a> <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a> </ol> <li><a href="#idl-index"><span class="secno"></span> <span class="content">IDL Index</span></a> <li><a href="#issues-index"><span class="secno"></span> <span class="content">Issues Index</span></a> </ol> </nav> <main> <h2 class="heading settled" data-level="1" id="intro"><span class="secno">1. </span><span class="content">Introduction</span><a class="self-link" href="#intro"></a></h2> <p><em>This section is non-normative</em>.</p> <p>Today, user agents generally identify themselves to servers by sending a <code>User-Agent</code> HTTP request header field along with each request (defined in Section 5.5.3 of <a data-link-type="biblio" href="#biblio-rfc9110" title="HTTP Semantics">[rfc9110]</a>). Ideally, this header would give servers the ability to perform content negotiation, sending down exactly those bits that best represent the requested resource in a given user agent, optimizing both bandwidth and user experience. In practice, however, this header’s value exposes far more information about the user’s device than seems appropriate as a default, on the one hand, and intentionally obscures the true user agent in order to bypass misguided server-side heuristics, on the other.</p> <p>For example, a recent version of Chrome on iOS identifies itself as:</p> <pre class="language-http highlight">User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.105 Mobile/15E148 Safari/605.1 </pre> <p>While a recent version of Edge identifies itself as:</p> <pre class="language-http highlight">User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.2704.79 Safari/537.36 Edge/18.014 </pre> <p>There’s quite a bit of information packed into those strings (along with a fair number of lies). Version numbers, platform details, model information, etc. are all broadcast along with every request, and form the basis for fingerprinting schemes of all sorts. Individual vendors have taken stabs at altering their user agent strings, and have run into a few categories of feedback from developers that have stymied historical approaches:</p> <ol> <li data-md> <p>Brand and version information (e.g. "Chrome 69") allows websites to work around known bugs in specific releases that aren’t otherwise detectable. For example, implementations of Content Security Policy have varied wildly between vendors, and it’s difficult to know what policy to send in an HTTP response without knowing what browser is responsible for its parsing and execution.</p> <li data-md> <p>Developers will often negotiate what content to send based on the user agent and platform. Some application frameworks, for instance, will style an application on iOS differently from the same application on Android in order to match each platform’s aesthetic and design patterns.</p> <li data-md> <p>Similarly to #1, OS revisions and architecture can be responsible for specific bugs which can be worked around in website’s code, and narrowly useful for things like selecting appropriate executables for download (32 vs 64 bit, ARM vs Intel, etc).</p> <li data-md> <p>Sophisticated developers use model/make to tailor their sites to the capabilities of the device (e.g. <a data-link-type="biblio" href="#biblio-facebookyearclass" title="Year class: A classification system for Android">[FacebookYearClass]</a>) and to pinpoint performance bugs and regressions which sometimes are specific to model/make.</p> </ol> <p>This document proposes a mechanism which might allow user agents to be a bit more aggressive about removing entropy from the <code>User-Agent</code> string generally by giving servers that really need some specific details about the client the ability to opt-into receiving them. It introduces a number of new Client Hints (<a data-link-type="biblio" href="#biblio-rfc8942" title="HTTP Client Hints">[RFC8942]</a>) that can provide the client’s branding and version information, the underlying operating system’s branding and major version, as well as details about the underlying device. Rather than broadcasting this data to everyone, all the time, user agents can make reasonable decisions about how to respond to given sites' requests for more granular data, reducing the <a data-link-type="dfn" href="https://w3c.github.io/fingerprinting-guidance/#dfn-passive-fingerprinting" id="ref-for-dfn-passive-fingerprinting①">passive fingerprinting</a> surface area exposed to the network (see <a data-link-type="dfn" href="https://w3c.github.io/fingerprinting-guidance/#avoid-passive-increases" id="ref-for-avoid-passive-increases">Best Practice 1</a> in <a data-link-type="biblio" href="#biblio-fingerprinting-guidance" title="Mitigating Browser Fingerprinting in Web Specifications">[FINGERPRINTING-GUIDANCE]</a>).</p> <h3 class="heading settled" data-level="1.1" id="examples"><span class="secno">1.1. </span><span class="content">Examples</span><a class="self-link" href="#examples"></a></h3> <p><em>This section is non-normative</em>.</p> <p>A user navigates to <code>https://example.com/</code> for the first time using the latest version of the "Examplary Browser". Their user agent sends the following headers along with the HTTP request:</p> <pre class="language-http highlight">Sec-CH-UA: "Examplary Browser"; v="73", ";Not?A.Brand"; v="27" Sec-CH-UA-Mobile: ?0 Sec-CH-UA-Platform: "Windows" </pre> <p>The server is interested in rendering content consistent with the user’s underlying platform version, and asks for a little more information by sending an <code>Accept-CH</code> header (Section 2.2.1 of <a data-link-type="biblio" href="#biblio-rfc8942" title="HTTP Client Hints">[RFC8942]</a>) along with the initial response:</p> <pre class="language-http highlight">Accept-CH: Sec-CH-UA-Platform-Version </pre> <p>In response, the user agent includes the platform version information in the next request:</p> <pre class="language-http highlight">Sec-CH-UA: "Examplary Browser"; v="73", ";Not?A.Brand"; v="27" Sec-CH-UA-Mobile: ?0 Sec-CH-UA-Platform: "Windows" Sec-CH-UA-Platform-Version: "14.0.0" </pre> <h3 class="heading settled" data-level="1.2" id="use-cases"><span class="secno">1.2. </span><span class="content">Use Cases</span><a class="self-link" href="#use-cases"></a></h3> <p><em>This section is non-normative</em>.</p> <p>This section attempts to document the current uses for the <code>User-Agent</code> string, and how similar functionality could be enabled using User-Agent Client Hints (UA-CH).</p> <h4 class="heading settled" data-level="1.2.1" id="differential-serving-use-case"><span class="secno">1.2.1. </span><span class="content">Differential serving</span><a class="self-link" href="#differential-serving-use-case"></a></h4> <h5 class="heading settled" data-level="1.2.1.1" id="based-on-browser-features-use-case"><span class="secno">1.2.1.1. </span><span class="content">Based on browser features</span><a class="self-link" href="#based-on-browser-features-use-case"></a></h5> This use case enables services like <a href="https://polyfill.io">polyfill.io</a> to serve custom-tailored polyfills to their users, without bloating up the experience of modern browser users. <p>Similarly, when serving Javascript to users, one can avoid transpilation (which can result in bloat and inefficient code) for browsers that support the latest ES features that were used. Finally, when serving images, some browsers don’t update their <code>Accept</code> request headers, while in other cases the MIME type is not descriptive enough to distinguish between different variants of the same format (e.g., WebP). In those cases, knowing the browser and its version can be critical to serving the right image variant.</p> <p>For that use case to work, the server needs to be aware of the browser and its meaningful version, and map that to a list of available features. That enables it to know which polyfill or code variant to serve.</p> <p>Services that wish to do that using UA-CH will need to inspect the <code>Sec-CH-UA</code> header, that is sent by default on every request, and modify their response based on that.</p> <h5 class="heading settled" data-level="1.2.1.2" id="browser-bug-workaround-use-case"><span class="secno">1.2.1.2. </span><span class="content">Browser bug workaround</span><a class="self-link" href="#browser-bug-workaround-use-case"></a></h5> Some browser versions have well-known bugs which require content to workaround them. Triggering those bugs can result in browser crashes, content breakage and other issues, and those bugs are by definition not something that can be feature detected. Therefore, content needs to avoid them altogether for affected browser versions. <p>For that use case, servers need to be aware of the browser and its meaningful version, be aware of browser bugs that impact them, and apply workarounds if the current browser version is impacted.</p> <p>Services that wish to do that using UA-CH will need to inspect the <code>Sec-CH-UA</code> header, sent by default on every request, and use it to modify their response.</p> <h4 class="heading settled" data-level="1.2.2" id="marketshare-analytics-use-case"><span class="secno">1.2.2. </span><span class="content">Market Share Analytics</span><a class="self-link" href="#marketshare-analytics-use-case"></a></h4> A browser’s market share can be extremely important. Having visibility into a browser’s usage can encourage developers to test in that particular browser, ensuring fewer compatibility issues for its users. On top of that, a browser’s market share can have a direct impact on the browser vendors' business goals, ensuring future development of the browser. <p>For market share analytics to work, a server needs to be aware of one or more of the following: user agent name and its meaningful version, operating system and its version, and device model. It can then register them and find their relative market shares.</p> <p>Sites that wish to provide market share analytics using UA-CH will need to inspect the <code>Sec-CH-UA</code> header, that is sent by default on every request, and keep a record of it. Additional UA client hints may also be requested depending on the use case (e.g., mobile device model analytics).</p> <p>By design, looking at individual entries in the brands list makes it hard to distinguish between a less-popular browser’s truthful brand name and a more-popular browser’s arbitrary GREASE. Since the less-popular browser may include several popular brand names for compatibility purposes, its users will likely be bucketed as using the more-popular one if this approach is taken, leading to distorted views of usage share that favour already-popular browsers and with less-popular browsers possibly never gaining any visibility.</p> <p>Hence, for analytics purposes, it is better to treat the brands list as a unit, and compare it to known lists of brands sent by the various (browser, version) pairs that are to be distinguished. This will necessitate regular updates to the list of known lists of brands when new browser versions are released or new browsers become popular, or else everything will get bucketed as an unknown browser. However, as this doesn’t break sites for users, failing closed for unknown browsers is acceptable in this context.</p> <p>Such a list of known lists of brands could be maintained centrally and used by many sites (as, e.g., browser feature support is maintained by caniuse and MDN, and consumed by many webmasters).</p> <p>The specification recommends that browsers fix the brands list they send per version to make counting usage shares simpler (and also to help with caching), so the known lists of brands can be a simple list mapping from a set of brands to a (browser, version) pair.</p> <h4 class="heading settled" data-level="1.2.3" id="content-adaptation-use-case"><span class="secno">1.2.3. </span><span class="content">Content adaptation</span><a class="self-link" href="#content-adaptation-use-case"></a></h4> Content adaptation is ensuring that users get content that’s tailored to their needs. There are <a href="https://blog.yoav.ws/adapting_without_assumptions/">many dimensions to content adaptation</a> beyond the UA string: <a href="https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/client-hints">viewport dimensions</a>, <a href="https://w3c.github.io/device-memory/">device memory</a>, <a href="https://wicg.github.io/savedata/">user preferences</a> and more. This sub-section covers content adaptation needs that rely on information that is part of the current <code>User-Agent</code> string. <h5 class="heading settled" data-level="1.2.3.1" id="browser-based-adaptation-use-case"><span class="secno">1.2.3.1. </span><span class="content">Browser based adaptation</span><a class="self-link" href="#browser-based-adaptation-use-case"></a></h5> Some sites choose to serve slightly different content to different browsers. The reasons for that vary. Some reasons are legitimate (e.g. wanting to serve different experiences to different browsers due to their feature support). Other reasons are slightly less legitimate (e.g. warning users that the site’s developers haven’t tested in their browser). And then there are reasons which are outright wrong (e.g. Willingness to block certain browsers' users from accessing the site). <p>As browsers, we want to enable the former, while discouraging the latter.</p> <h5 class="heading settled" data-level="1.2.3.2" id="mobile-specific-site-use-case"><span class="secno">1.2.3.2. </span><span class="content">Mobile specific site</span><a class="self-link" href="#mobile-specific-site-use-case"></a></h5> Many site owners serve different content between mobile and desktop sites. While responsive web design has made it possible to serve multiple form factors using a single code base, there are still cases where serving a mobile-specific version can be better adapted. <p>For those cases, serving mobile-specific sites to users on mobile devices can be helpful. For that to work, the server needs to be aware, at HTML serving time, whether the user is on a mobile device or not.</p> <p>Sites that wish to serve mobile-specific sites using UA-CH can do that using the <code>Sec-CH-UA-Mobile</code> headers that are sent by default on every request.</p> <h5 class="heading settled" data-level="1.2.3.3" id="low-powered-devices-use-case"><span class="secno">1.2.3.3. </span><span class="content">Low-powered devices</span><a class="self-link" href="#low-powered-devices-use-case"></a></h5> Some sites serve different content to low powered devices that cannot deal with CPU intensive tasks, large video and images, etc. Such content adaptation typically uses the device model information that’s integrated in the current <code>User-Agent</code> string for that purpose, relying on server-side databases to convert device models into memory, CPU power, and other categories on which they want to split their content. <p>If the dimension on which the split is made is memory, the Device-Memory Client Hint can be used to make that distinction. Otherwise, with UA-CH, sites can still retrieve the device model by opting in to the <code>Sec-CH-UA-Model</code> hint.</p> <p>Both of these hints are not sent by default, so require some extra work.</p> <p>Top-level origins will need to send <code>Accept-CH: Device-Memory, Sec-CH-UA-Model</code> headers with their responses to opt-in to receiving those hints. In cases where they absolutely need to perform that adaptation on every navigation request, a redirect would be required here in the case where the hints are not present in a browser that supports them. Alternatively, they might use Critical-CH to have the client handle the additional request/response roundtrip.</p> <p>Third-party origins that need to perform such adaptation would need <a href="https://github.com/WICG/client-hints-infrastructure#cross-origin-hint-delegation">delegation</a> from the top-level origin. The top-level origin would need to opt-in using <code>Accept-CH</code>, as well as add <code>Permissions-Policy</code> headers that delegate those hints to the third-party origin.</p> <h5 class="heading settled" data-level="1.2.3.4" id="os-specific-styles-use-case"><span class="secno">1.2.3.4. </span><span class="content">OS specific styles</span><a class="self-link" href="#os-specific-styles-use-case"></a></h5> Some sites may wish to tailor their interfaces to match the user’s OS. While progressive enhancement is likely to be a better path here (e.g. through the application of different button styles using script), there may be cases where folks would wish to deliver tailored inline styles based on the platform and platform version. <p>Those cases are very similar to the case discussed above (in "Low-powered devices"), only with the <code>Sec-CH-UA-Platform</code> and <code>Sec-CH-UA-Platform-Version</code> hints.</p> <h5 class="heading settled" data-level="1.2.3.5" id="os-integration-use-case"><span class="secno">1.2.3.5. </span><span class="content">OS integration</span><a class="self-link" href="#os-integration-use-case"></a></h5> Similarly, some sites would want to change links to OS specific ones (e.g. <a href="https://developer.chrome.com/multidevice/android/intents">Android intent links</a>). While, again, progressive enhancement can be used to modify those links using script, rather than bake them into the HTML, some sites may prefer server-side adaptation. <p>Again, like the "OS specific styles" case, they’d need to use the <code>Sec-CH-UA-Platform</code> and <code>Sec-CH-UA-Platform-Version</code> hints to do so.</p> <h5 class="heading settled" data-level="1.2.3.6" id="browser-os-experiments-use-case"><span class="secno">1.2.3.6. </span><span class="content">Browser and OS specific experiments</span><a class="self-link" href="#browser-os-experiments-use-case"></a></h5> Some servers may like to limit their multi variant experimentation to specific browsers, specific platforms or specific versions of any of the above. For experiments that are limited to browser and version, those sites can use the <code>Sec-CH-UA</code> values sent by default on requests. If they require the platform and its version, they could use the default <code>Sec-CH-UA-Platform</code> hint but would have to request the <code>Sec-CH-UA-Platform-Version</code> hint, or use client-side scripts to control the experimentation. <h4 class="heading settled" data-level="1.2.4" id="user-login-notification-use-case"><span class="secno">1.2.4. </span><span class="content">User login notification</span><a class="self-link" href="#user-login-notification-use-case"></a></h4> Many sites, especially security sensitive ones, like to notify their users when a log-in from a new device happens. That enables users to be aware of those logins, and take action in case it’s not a login that’s done by them or on their behalf. <p>For those notifications to be meaningful, sites need to recognize and communicate the commercial brand of the browser to the user. These messages often also include the platform and its version in order to make sure the user knows which device is in question.</p> <p>Since such messaging doesn’t require any server-side adaptation, it’s better for this case to use the <code>userAgentData.getHighEntropyData()</code> method in order to retrieve the required information.</p> <h4 class="heading settled" data-level="1.2.5" id="binary-executable-downloads"><span class="secno">1.2.5. </span><span class="content">Download of appropriate binary executables</span><a class="self-link" href="#binary-executable-downloads"></a></h4> Some sites are used to download binary executables of native applications, and need to be able to propose the right binary to the user by default. The right binary executable for the current user depends on a few factors: their operating system, its version, its bitness, as well as their CPU architecture. <p>In order to tackle that use case, download sites can opt-in to receive the <code>Sec-CH-UA-Platform</code>, <code>Sec-CH-UA-Platform-Version</code>, <code>Sec-CH-UA-Architecture</code>, and <code>Sec-CH-UA-Bitness</code> hints (or query them through the API), in order to ensure the right binary is offered to the user by default.</p> <h4 class="heading settled" data-level="1.2.6" id="conversion-modeling-use-case"><span class="secno">1.2.6. </span><span class="content">Conversion modeling</span><a class="self-link" href="#conversion-modeling-use-case"></a></h4> Some machine learning models use various details from the <code>User-Agent</code> string in order to estimate various things about users of those user agents. Similar modeling would still be possible, but will require explicit opt-in to collect the required bits of information. <h4 class="heading settled" data-level="1.2.7" id="vulnerability-filtering-use-case"><span class="secno">1.2.7. </span><span class="content">Vulnerability filtering</span><a class="self-link" href="#vulnerability-filtering-use-case"></a></h4> In some environments, proxy servers may be used to verify that the different users accessing information are not doing so from obsolete devices that are potentially vulnerable to security issues. While the browser and version information available from <code>Sec-CH-UA</code> can provide some information, the browser and OS full version are often useful for that kind of analysis. <p>Such proxies would have to add a redirect step, or use one of the two <a href="https://github.com/WICG/client-hints-infrastructure/blob/main/reliability.md#client-hint-reliability">Client Hint reliability mechanisms</a> that opts-in to getting the browser full version and the platform version in order to continue to get access to those hints.</p> <h4 class="heading settled" data-level="1.2.8" id="logs-debugging-use-case"><span class="secno">1.2.8. </span><span class="content">Logs and debugging</span><a class="self-link" href="#logs-debugging-use-case"></a></h4> Many services log the <code>User-Agent</code> string today and can use it in various ways when analyzing past traffic or when trying to debug errors related to their service. Those services will have to use the lower entropy values available through <code>Sec-CH-UA</code> for logging purposes, or opt-in to receive higher-entropy hints. The latter doesn’t seem like something services should do just for forensic purposes. On the other hand, when specific issues are encountered, it may make sense for those services to opt-in to receive more details on the user agent, or use the <code>userAgentData.getHighEntropyData()</code> API for that purpose. <h4 class="heading settled" data-level="1.2.9" id="fingerprinting-use-case"><span class="secno">1.2.9. </span><span class="content">Fingerprinting</span><a class="self-link" href="#fingerprinting-use-case"></a></h4> <p>User fingerprinting is the practice of gathering multiple bits of user information from multiple sources and intersecting them together to create a unique signature of the user, that would enable to recognize them to be recognized later on, even if they clear state from their browsers (e.g. by deleting cookies).</p> <p>For those cases, the origin needs to gather as much entropy as possible, so it is likely to collect all the hints.</p> <h5 class="heading settled" data-level="1.2.9.1" id="spam-filtering-bots-use-case"><span class="secno">1.2.9.1. </span><span class="content">Spam filtering and bot detection</span><a class="self-link" href="#spam-filtering-bots-use-case"></a></h5> This is a case of fingerprinting that is not user-hostile, and therefore one we would like to preserve. With UA-CH this will be initially enabled by active collection of the various hints. <p>We hope that alternative methods or APIs will exist to address the spam filtering and bot detection use cases in the future, as browsers may decide to intervene on behalf of their users by limiting the collection of user-identifying entropy (e.g., the <a href="https://github.com/bslassey/privacy-budget">Privacy Budget</a> proposal).</p> <h5 class="heading settled" data-level="1.2.9.2" id="persistent-user-tracking"><span class="secno">1.2.9.2. </span><span class="content">Persistent user tracking</span><a class="self-link" href="#persistent-user-tracking"></a></h5> This is a case of fingerprinting that this proposal <em>explicitly tries to make harder</em>. Like the case of "spam filtering", it would still be feasible to actively collect all the hints about the user as bits of entropy. Unlike the above case, this is something that proposals such as the Privacy Budget aim to prevent, without providing any alternative mechanisms for persistent user tracking. <h5 class="heading settled" data-level="1.2.9.3" id="blocking-known-bots-crawlers-use-case"><span class="secno">1.2.9.3. </span><span class="content">Blocking known bots and crawlers</span><a class="self-link" href="#blocking-known-bots-crawlers-use-case"></a></h5> Currently, the <code>User-Agent</code> string is often used as a brute-force way to block known bots and crawlers. There’s a concern that moving "normal" traffic to expose less entropy by default will also make it easier for bots to hide in the crowd. While there’s some truth to that, that’s not enough reason for making the crowd be more personally identifiable. <p>Similar to the spam filtering case, there’s hope that alternative methods would be able to replace <code>User-Agent</code> string matching for this use case.</p> <h2 class="heading settled" data-level="2" id="infrastructure"><span class="secno">2. </span><span class="content">Infrastructure</span><a class="self-link" href="#infrastructure"></a></h2> <p>This specification depends on Client Hints Infrastructure, HTTP Client Hints, Infra Standard, and Permissions Policy. <a data-link-type="biblio" href="#biblio-client-hints-infrastructure" title="Client Hints Infrastructure">[CLIENT-HINTS-INFRASTRUCTURE]</a> <a data-link-type="biblio" href="#biblio-rfc8942" title="HTTP Client Hints">[RFC8942]</a> <a data-link-type="biblio" href="#biblio-infra" title="Infra Standard">[INFRA]</a> <a data-link-type="biblio" href="#biblio-permissions-policy-1" title="Permissions Policy">[permissions-policy-1]</a></p> <p>Some of the terms used in this specification are defined in <cite>Structured Field Values for HTTP</cite>. <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a></p> <h2 class="heading settled" data-level="3" id="http-ua-hints"><span class="secno">3. </span><span class="content">User Agent Hints</span><a class="self-link" href="#http-ua-hints"></a></h2> <p>The following sections define a number of HTTP request header fields that expose detail about a given <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent">user agent</a>, which servers can opt-into receiving via the Client Hints infrastructure defined in <a data-link-type="biblio" href="#biblio-rfc8942" title="HTTP Client Hints">[RFC8942]</a>. The definitions below assume that each <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①">user agent</a> has defined a number of properties for itself:</p> <ul> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-brand">brand</dfn> - The <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②">user agent</a>'s commercial name (e.g., "cURL", "Edge", "The World’s Best Web Browser"), which MUST be shorter than 32 <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#ascii-alpha" id="ref-for-ascii-alpha">ASCII alpha</a> characters.</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-form-factors">form-factors</dfn> - The form-factors of a device, historically represented as a <<a data-link-type="dfn" href="https://compat.spec.whatwg.org/#devicecompat" id="ref-for-devicecompat">deviceCompat</a>> token in the User-Agent string (e.g., "Tablet", "VR", etc.)</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-full-version">full version</dfn> - The build version (e.g., "72.0.3245.12", "3.14159", or "297.70E04154A") that corresponds to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③">user agent</a>, or any of the brands in its <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands">brands</a> list.</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-model">model</dfn> - The <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④">user agent</a>'s device model (e.g., "", or "Pixel 2 XL")</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-mobileness">mobileness</dfn> - A boolean indicating if the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤">user agent</a>'s device is a mobile device. (e.g., ?0 or ?1)</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-platform-brand">platform brand</dfn> - The <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑥">user agent</a>'s operating system’s commercial name. (e.g., "Windows", "iOS", or "AmazingOS")</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-platform-version">platform version</dfn> - The <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑦">user agent</a>'s operating system’s version. (e.g., "NT 6.0", "15", or "17G")</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-platform-architecture">platform architecture</dfn> - The <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑧">user agent</a>'s underlying CPU architecture (e.g., "ARM", or "x86")</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-platform-bitness">platform bitness</dfn> - The <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑨">user agent</a>'s underlying CPU architecture bitness (e.g., "32" or "64")</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-significant-version">significant version</dfn> - The marketing version which includes distinguishable web-exposed features (e.g., "72", "3", or "12.1"), corresponding to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①⓪">user agent</a>, or any of the brands in its <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands①">brands</a> list (e.g., rendering engine or any other <a data-link-type="dfn" href="#user-agent-equivalence-class" id="ref-for-user-agent-equivalence-class">equivalence classes</a> full version).</p> <li data-md> <p><dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-wow64-ness">wow64-ness</dfn> - A boolean indicating if the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①①">user agent</a>'s binary is running in 32-bit mode on 64-bit Windows. (e.g., ?0 or ?1)</p> </ul> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①②">User agents</a> SHOULD keep these strings short and to the point, but servers MUST accept arbitrary values for each, as they are all values constructed at the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①③">user agent</a>'s whim.</p> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①④">User agents</a> MUST map higher-entropy <a data-link-type="dfn" href="#user-agent-platform-architecture" id="ref-for-user-agent-platform-architecture">platform architecture</a> values to the following buckets:</p> <ul> <li data-md> <p>x86 CPU architectures => "x86"</p> <li data-md> <p>ARM CPU architectures => "arm"</p> </ul> <p>Other CPU architectures could be mapped into one of these values in case that makes sense, or be mapped to the empty string.</p> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①⑤">User agents</a> SHOULD return the empty string or a fictitious value for <a data-link-type="dfn" href="#user-agent-platform-architecture" id="ref-for-user-agent-platform-architecture①">platform architecture</a> or <a data-link-type="dfn" href="#user-agent-platform-bitness" id="ref-for-user-agent-platform-bitness">platform bitness</a> unless the user’s platform is one where both the following conditions apply:</p> <ul> <li data-md> <p>Binary download of executables is likely.</p> <li data-md> <p>Different CPU architectures are likely to require different binary executable resources, and different binary executable resources are likely to be available.</p> </ul> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①⑥">User Agents</a> MUST return the empty string for <a data-link-type="dfn" href="#user-agent-model" id="ref-for-user-agent-model">model</a> if <a data-link-type="dfn" href="#user-agent-mobileness" id="ref-for-user-agent-mobileness">mobileness</a> is false. <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①⑦">User Agents</a> MUST return the empty string for <a data-link-type="dfn" href="#user-agent-model" id="ref-for-user-agent-model①">model</a> even if <a data-link-type="dfn" href="#user-agent-mobileness" id="ref-for-user-agent-mobileness①">mobileness</a> is true, except on platforms where the model is typically exposed.</p> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①⑧">User agents</a> MAY return the empty string for hints of type <code>sf-string</code>, <code>false</code> for hints of type <code>sf-boolean</code>, or any other fictitious value, for privacy, compatibility, or other reasons, given a request for any the following hints: <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version">full version</a>, <a data-link-type="dfn" href="#user-agent-platform-architecture" id="ref-for-user-agent-platform-architecture②">platform architecture</a>, <a data-link-type="dfn" href="#user-agent-platform-bitness" id="ref-for-user-agent-platform-bitness①">platform bitness</a>, <a data-link-type="dfn" href="#user-agent-wow64-ness" id="ref-for-user-agent-wow64-ness">wow64-ness</a> or <a data-link-type="dfn" href="#user-agent-model" id="ref-for-user-agent-model②">model</a>.</p> <h3 class="heading settled" data-level="3.1" id="sec-ch-ua"><span class="secno">3.1. </span><span class="content">The 'Sec-CH-UA' Header Field</span><a class="self-link" href="#sec-ch-ua"></a></h3> <p>The <dfn class="dfn-paneled" data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua"><code>Sec-CH-UA</code></dfn> request header field gives a server information about a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent①⑨">user agent</a>'s <a data-link-type="dfn" href="#user-agent-brand" id="ref-for-user-agent-brand">branding</a> and <a data-link-type="dfn" href="#user-agent-significant-version" id="ref-for-user-agent-significant-version">significant version</a>. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.1" id="ref-for-section-3.1">list</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>. The list’s items MUST be <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3">string</a>. The value of each item SHOULD include a "v" parameter, indicating the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②⓪">user agent</a>'s version.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA</c-> <c- o>=</c-> <c- nc>sf-list</c-> </pre> <p>To <dfn data-dfn-type="abstract-op" data-export id="abstract-opdef-return-the-sec-ch-ua-value-for-a-request">return the <code>Sec-CH-UA</code> value for a request<a class="self-link" href="#abstract-opdef-return-the-sec-ch-ua-value-for-a-request"></a></dfn>, perform the following steps:</p> <ol> <li data-md> <p>Let <var>brands</var> be the result of running <a data-link-type="dfn" href="#create-brands" id="ref-for-create-brands">create brands</a> with "significant version".</p> <li data-md> <p>Let <var>list</var> be the result of <a data-link-type="dfn" href="#create-a-brand-version-list" id="ref-for-create-a-brand-version-list">creating a brand-version list</a>, with <var>brands</var> and "significant version".</p> <li data-md> <p>Return the output of running <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-4.1.1" id="ref-for-section-4.1.1">serializing a list</a> with <var>list</var>.</p> </ol> <p class="note" role="note"><span class="marker">Note:</span> Unlike most Client Hints, since it’s included in the <a data-link-type="dfn" href="https://wicg.github.io/client-hints-infrastructure/#low-entropy-hint-table" id="ref-for-low-entropy-hint-table">low entropy hint table</a>, the <code>Sec-CH-UA</code> header will be sent by default, whether or not the server opted-into receiving the header via an <code>Accept-CH</code> header (although it can still be controlled by it’s <a data-link-type="dfn" href="https://wicg.github.io/client-hints-infrastructure/#policy-controlled-client-hints-features" id="ref-for-policy-controlled-client-hints-features">policy-controlled client hints feature</a>. It is considered low entropy because it includes only the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②①">user agent</a>'s branding information, and the significant version number (both of which are fairly clearly sniffable by "examining the structure of other headers and by testing for the availability and semantics of the features introduced or modified between releases of a particular browser" <a data-link-type="biblio" href="#biblio-janc2014" title="Technical analysis of client identification mechanisms">[Janc2014]</a>).</p> <p class="note" role="note"><span class="marker">Note:</span> <a data-link-type="http-header" href="#http-headerdef-sec-ch-ua" id="ref-for-http-headerdef-sec-ch-ua"><code>Sec-CH-UA</code></a> reveals the major version for each brand in the <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands②">brands</a> list. For use cases requiring the <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version①">full version</a>, see <a data-link-type="http-header" href="#http-headerdef-sec-ch-ua-full-version-list" id="ref-for-http-headerdef-sec-ch-ua-full-version-list"><code>Sec-CH-UA-Full-Version-List</code></a>.</p> <h3 class="heading settled" data-level="3.2" id="sec-ch-ua-arch"><span class="secno">3.2. </span><span class="content">The 'Sec-CH-UA-Arch' Header Field</span><a class="self-link" href="#sec-ch-ua-arch"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-arch"><code>Sec-CH-UA-Arch</code><a class="self-link" href="#http-headerdef-sec-ch-ua-arch"></a></dfn> request header field gives a server information about the architecture of the platform on which a given <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②②">user agent</a> is executing. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something①">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3①">string</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Arch</c-> <c- o>=</c-> <c- nc>sf-string</c-> </pre> <h3 class="heading settled" data-level="3.3" id="sec-ch-ua-bitness"><span class="secno">3.3. </span><span class="content">The 'Sec-CH-UA-Bitness' Header Field</span><a class="self-link" href="#sec-ch-ua-bitness"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-bitness"><code>Sec-CH-UA-Bitness</code><a class="self-link" href="#http-headerdef-sec-ch-ua-bitness"></a></dfn> request header field gives a server information about the <a data-link-type="dfn" href="#user-agent-platform-bitness" id="ref-for-user-agent-platform-bitness②">platform bitness</a> of the architecture of the platform on which a given <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②③">user agent</a> is executing. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something②">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3②">string</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Bitness</c-> <c- o>=</c-> <c- nc>sf-string</c-> </pre> <h3 class="heading settled" data-level="3.4" id="sec-ch-ua-form-factors"><span class="secno">3.4. </span><span class="content">The 'Sec-CH-UA-Form-Factors' Header Field</span><a class="self-link" href="#sec-ch-ua-form-factors"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-form-factors"><code>Sec-CH-UA-Form-Factors</code><a class="self-link" href="#http-headerdef-sec-ch-ua-form-factors"></a></dfn> request header field gives a server information about the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②④">user agent</a>'s <a data-link-type="dfn" href="#user-agent-form-factors" id="ref-for-user-agent-form-factors">form-factors</a>. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something③">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.1" id="ref-for-section-3.1①">list</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>. In order to avoid providing additional fingerprinting entropy, the header’s values MUST be given in lexical order, and values are case-sensitive.</p> <p>The header SHOULD describe the form-factors of the device using one or more of the following common form-factor values: "Desktop", "Automotive", "Mobile", "Tablet", "XR", "EInk", or "Watch". All applicable form-factor values SHOULD be included.</p> <div class="note no-marker" role="note"> <div class="marker">NOTE: </div> <p>The form-factors of a user-agent describe how the user interacts with the user-agent. The meanings of the allowed values are:</p> <ul> <li data-md> <p>"Desktop" refers to a user-agent running on a personal computer.</p> <li data-md> <p>"Automotive" refers to a user-agent embedded in a vehicle, where the user may be responsible for operating the vehicle and unable to attend to small details.</p> <li data-md> <p>"Mobile" refers to small, touch-oriented device typically carried on a user’s person.</p> <li data-md> <p>"Tablet" refers to a touch-oriented device larger than "Mobile" and not typically carried on a user’s person.</p> <li data-md> <p>"XR" refers to immersive devices that augment or replace the environment around the user.</p> <li data-md> <p>"EInk" refers to a device characterized by slow screen updates and limited or no color resolution.</p> <li data-md> <p>"Watch" refers to a mobile device with a tiny screen (typically less than 2 <a href="https://drafts.csswg.org/css-values-4/#absolute-lengths">in</a>), carried in such a way that the user can glance at it quickly.</p> </ul> <p>A new value should be proposed and added to the specification when there is a new form-factor that users interact with in a meaningfully different way; a compelling use-case where sites would like to change how they interact with users on that device; and no reliable way to identify that new form-factor using existing hints.</p> </div> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Form-Factors</c-> <c- o>=</c-> <c- nc>sf-list</c-> </pre> <h3 class="heading settled" data-level="3.5" id="sec-ch-ua-full-version"><span class="secno">3.5. </span><span class="content">The 'Sec-CH-UA-Full-Version' Header Field</span><a class="self-link" href="#sec-ch-ua-full-version"></a></h3> <p><strong class="advisement"> <code>Sec-CH-UA-Full-Version</code> is deprecated and will be removed in the future. Developers should use <a href="#sec-ch-ua-full-version-list"><code>Sec-CH-UA-Full-Version-List</code></a> instead.</strong></p> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-full-version"><code>Sec-CH-UA-Full-Version</code><a class="self-link" href="#http-headerdef-sec-ch-ua-full-version"></a></dfn> request header field gives a server information about the user agent’s <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version②">full version</a>. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something④">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3③">string</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Full-Version</c-> <c- o>=</c-> <c- nc>sf-string</c-> </pre> <h3 class="heading settled" data-level="3.6" id="sec-ch-ua-full-version-list"><span class="secno">3.6. </span><span class="content">The 'Sec-CH-UA-Full-Version-List' Header Field</span><a class="self-link" href="#sec-ch-ua-full-version-list"></a></h3> <p>The <dfn class="dfn-paneled" data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-full-version-list"><code>Sec-CH-UA-Full-Version-List</code></dfn> request header field gives a server information about the <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version③">full version</a> for each brand in its <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands③">brands</a> list. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something⑤">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.1" id="ref-for-section-3.1②">list</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Full-Version-List</c-> <c- o>=</c-> <c- nc>sf-list</c-> </pre> <p>To <dfn data-dfn-type="abstract-op" data-export id="abstract-opdef-return-the-sec-ch-ua-full-version-list-value-for-a-request">return the <code>Sec-CH-UA-Full-Version-List</code> value for a request<a class="self-link" href="#abstract-opdef-return-the-sec-ch-ua-full-version-list-value-for-a-request"></a></dfn>, perform the following steps:</p> <ol> <li data-md> <p>Let <var>brands</var> be the result of running <a data-link-type="dfn" href="#create-brands" id="ref-for-create-brands①">create brands</a> with "full version".</p> <li data-md> <p>Let <var>list</var> be the result of <a data-link-type="dfn" href="#create-a-brand-version-list" id="ref-for-create-a-brand-version-list①">create a brand-version list</a>, with <var>brands</var> and "full version".</p> <li data-md> <p>Return the output of running <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-4.1.1" id="ref-for-section-4.1.1①">serializing a list</a> with <var>list</var> as input.</p> </ol> <h3 class="heading settled" data-level="3.7" id="sec-ch-ua-mobile"><span class="secno">3.7. </span><span class="content">The 'Sec-CH-UA-Mobile' Header Field</span><a class="self-link" href="#sec-ch-ua-mobile"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-mobile"><code>Sec-CH-UA-Mobile</code><a class="self-link" href="#http-headerdef-sec-ch-ua-mobile"></a></dfn> request header field gives a server information about whether or not a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②⑤">user agent</a> prefers a "mobile" user experience. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something⑥">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.6" id="ref-for-section-3.3.6">boolean</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Mobile</c-> <c- o>=</c-> <c- nc>sf-boolean</c-> </pre> <p class="note" role="note"><span class="marker">Note:</span> Like <code>Sec-CH-UA</code> above, since it’s included in the <a data-link-type="dfn" href="https://wicg.github.io/client-hints-infrastructure/#low-entropy-hint-table" id="ref-for-low-entropy-hint-table①">low entropy hint table</a>, the <code>Sec-CH-UA-Mobile</code> header will be sent by default, whether or not the server opted-into receiving the header via an <code>Accept-CH</code> header (although it can still be controlled by its <a data-link-type="dfn" href="https://wicg.github.io/client-hints-infrastructure/#policy-controlled-client-hints-features" id="ref-for-policy-controlled-client-hints-features①">policy-controlled client hints feature</a>). It is considered low entropy because it is a single bit of information directly controllable by the user.</p> <h3 class="heading settled" data-level="3.8" id="sec-ch-ua-model"><span class="secno">3.8. </span><span class="content">The 'Sec-CH-UA-Model' Header Field</span><a class="self-link" href="#sec-ch-ua-model"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-model"><code>Sec-CH-UA-Model</code><a class="self-link" href="#http-headerdef-sec-ch-ua-model"></a></dfn> request header field gives a server information about the device on which a given <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②⑥">user agent</a> is executing. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something⑦">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3④">string</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Model</c-> <c- o>=</c-> <c- nc>sf-string</c-> </pre> <h3 class="heading settled" data-level="3.9" id="sec-ch-ua-platform"><span class="secno">3.9. </span><span class="content">The 'Sec-CH-UA-Platform' Header Field</span><a class="self-link" href="#sec-ch-ua-platform"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-platform"><code>Sec-CH-UA-Platform</code><a class="self-link" href="#http-headerdef-sec-ch-ua-platform"></a></dfn> request header field gives a server information about the platform on which a given <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②⑦">user agent</a> is executing. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something⑧">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3⑤">string</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>. Its value SHOULD match one of the following common platform values: "Android", "Chrome OS", "Fuchsia", "iOS", "Linux", "macOS", "Windows", or "Unknown".</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Platform</c-> <c- o>=</c-> <c- nc>sf-string</c-> </pre> <p class="note" role="note"><span class="marker">Note:</span> Like <code>Sec-CH-UA</code> above, since it’s included in the <a data-link-type="dfn" href="https://wicg.github.io/client-hints-infrastructure/#low-entropy-hint-table" id="ref-for-low-entropy-hint-table②">low entropy hint table</a>, the <code>Sec-CH-UA-Platform</code> header will be sent by default, whether or not the server opted-into receiving the header via an <code>Accept-CH</code> header (although it can still be controlled by its <a data-link-type="dfn" href="https://wicg.github.io/client-hints-infrastructure/#policy-controlled-client-hints-features" id="ref-for-policy-controlled-client-hints-features②">policy-controlled client hints feature</a>).</p> <h3 class="heading settled" data-level="3.10" id="sec-ch-ua-platform-version"><span class="secno">3.10. </span><span class="content">The 'Sec-CH-UA-Platform-Version' Header Field</span><a class="self-link" href="#sec-ch-ua-platform-version"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-platform-version"><code>Sec-CH-UA-Platform-Version</code><a class="self-link" href="#http-headerdef-sec-ch-ua-platform-version"></a></dfn> request header field gives a server information about the <a data-link-type="dfn" href="#user-agent-platform-version" id="ref-for-user-agent-platform-version">platform version</a> on which a given <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②⑧">user agent</a> is executing. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something⑨">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3⑥">string</a><a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>. Its value is the result of <a data-link-type="dfn" href="#get-the-platform-version" id="ref-for-get-the-platform-version">getting the platform version</a> with <a data-link-type="dfn" href="#user-agent-platform-brand" id="ref-for-user-agent-platform-brand">platform brand</a>.</p> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="get-the-platform-version">get the platform version</dfn>, given a string <var>platform</var>, run the following steps:</p> <ol> <li data-md> <p>If <var>platform</var> is "Linux":</p> <ol> <li data-md> <p>Return the empty string.</p> </ol> <li data-md> <p>If <var>platform</var> is "Android":</p> <ol> <li data-md> <p>Let <var>platformReturnedVersionString</var> be the result of querying the OS’s <code>android.os.Build.VERSION.RELEASE</code> string.</p> <li data-md> <p>Return the result of <a data-link-type="dfn" href="#create-a-unified-platform-version-string" id="ref-for-create-a-unified-platform-version-string">creating a unified platform version string</a> with <var>platformReturnedVersionString</var>.</p> </ol> <li data-md> <p>If <var>platform</var> is "iOS":</p> <ol> <li data-md> <p>Let <var>platformReturnedVersionString</var> be the result of querying the <code>UIDevice</code> object returned by <code>currentDevice</code> and reading its <code>systemVersion</code>.</p> <li data-md> <p>Return the result of <a data-link-type="dfn" href="#create-a-unified-platform-version-string" id="ref-for-create-a-unified-platform-version-string①">creating a unified platform version string</a> with <var>platformReturnedVersionString</var>.</p> </ol> <li data-md> <p>If <var>platform</var> is "Windows":</p> <ol> <li data-md> <p>If available (i.e., on Windows 10 or higher), let <var>platformReturnedVersionString</var> be the result of querying the <code>Windows.Foundation.UniversalApiContract</code> integer version and converting it to a string. Otherwise, let <var>platformReturnedVersionString</var> be the result of <a data-link-type="dfn" href="#get-the-legacy-windows-version-number" id="ref-for-get-the-legacy-windows-version-number">getting the legacy Windows version number</a>.</p> <li data-md> <p>Return the result of <a data-link-type="dfn" href="#create-a-unified-platform-version-string" id="ref-for-create-a-unified-platform-version-string②">creating a unified platform version string</a> with <var>platformReturnedVersionString</var>.</p> </ol> <li data-md> <p>Let <var>platformVersionComponentList</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list">list</a>.</p> <li data-md> <p>If <var>platform</var> is "macOS":</p> <ol> <li data-md> <p>Let <var>macOSVersion</var> be the <code>operatingSystemVersion</code> property of the <code>NSProcessInfo</code> object returned by getting the <code>processInfo</code> information agent.</p> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append">Append</a> <var>macOSVersion</var>’s <code>majorVersion</code>, <code>minorVersion</code>, and <code>patchVersion</code> components (in that order) to <var>platformVersionComponentList</var>.</p> </ol> <li data-md> <p>If <var>platform</var> is some other value:</p> <ol> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append①">Append</a> one to three version parts based on the format most likely to lead to interoperability with other browsers running on <var>platform</var> to <var>platformVersionComponentList</var>.</p> <li data-md> <p>While <var>platformVersionComponentList</var>’s length is less than 3, <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append②">append</a> "0" to <var>platformVersionComponentList</var>.</p> </ol> <li data-md> <p>Return the result of the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#string-concatenate" id="ref-for-string-concatenate">concatenation</a> of <var>platformVersionComponentList</var> with a U+002E FULL STOP (<code>.</code>) separator.</p> </ol> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="get-the-legacy-windows-version-number">get the legacy Windows version number</dfn>, run the following steps:</p> <ol> <li data-md> <p>Let <var>major</var> be the value of <code>OSVERSIONINFO</code>’s <code>dwMajorVersion</code> member returned from the Win32 <code>GetVersionEx</code> API.</p> <li data-md> <p>Let <var>minor</var> be the value of <code>OSVERSIONINFO</code>’s <code>dwMinorVersion</code> member returned from the Win32 <code>GetVersionEx</code> API.</p> <li data-md> <p>If <var>major</var> is <code>6</code> and <var>minor</var> is <code>3</code> (i.e., Windows 8.1), return "0.3".</p> <li data-md> <p>If <var>major</var> is <code>6</code> and <var>minor</var> is <code>2</code> (i.e., Windows 8), return "0.2".</p> <li data-md> <p>If <var>major</var> is <code>6</code> and <var>minor</var> is <code>1</code> (i.e., Windows 7), return "0.1".</p> <li data-md> <p>Otherwise, return "0".</p> </ol> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="create-a-unified-platform-version-string">create a unified platform version string</dfn>, given a string <var>input</var>, run the following steps:</p> <ol> <li data-md> <p>Let <var>platformVersionComponentList</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list①">list</a> and <var>index</var> be 0.</p> <li data-md> <p>Let <var>platformVersionUnprocessedTokenList</var> be the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list②">list</a> returned by <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#strictly-split" id="ref-for-strictly-split">strictly splitting</a> <var>input</var> on the U+002E FULL STOP character (<code>.</code>):</p> <li data-md> <p>While <var>index</var> is less than 3:</p> <ol> <li data-md> <p>If <var>index</var> is less than the length of <var>platformVersionUnprocessedTokenList</var>:</p> <ol> <li data-md> <p>If <var>platformVersionUnprocessedTokenList</var>[<var>index</var>] is an unsigned integer, convert it to a string and <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append③">append</a> it to <var>platformVersionComponentList</var>.</p> <li data-md> <p>Otherwise, <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append④">append</a> "0" to <var>platformVersionComponentList</var>.</p> </ol> <li data-md> <p>Otherwise, if <var>index</var> is greater than or equal to the length of <var>platformVersionUnprocessedTokenList</var>:</p> <ol> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append⑤">Append</a> "0" to <var>platformVersionComponentList</var>.</p> </ol> <li data-md> <p>Increment <var>index</var> by 1.</p> </ol> <li data-md> <p>Return the result of the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#string-concatenate" id="ref-for-string-concatenate①">concatenation</a> of <var>platformVersionComponentList</var> with a U+002E FULL STOP (<code>.</code>) separator.</p> </ol> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-Platform-Version</c-> <c- o>=</c-> <c- nc>sf-string</c-> </pre> <h3 class="heading settled" data-level="3.11" id="sec-ch-ua-wow64"><span class="secno">3.11. </span><span class="content">The 'Sec-CH-UA-WoW64' Header Field</span><a class="self-link" href="#sec-ch-ua-wow64"></a></h3> <p>The <dfn data-dfn-type="http-header" data-export id="http-headerdef-sec-ch-ua-wow64"><code>Sec-CH-UA-WoW64</code><a class="self-link" href="#http-headerdef-sec-ch-ua-wow64"></a></dfn> request header field gives a server information about whether or not a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent②⑨">user agent</a> binary is running in 32-bit mode on 64-bit Windows. It is a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something①⓪">Structured Header</a> whose value MUST be a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.6" id="ref-for-section-3.3.6①">boolean</a> <a data-link-type="biblio" href="#biblio-rfc8941" title="Structured Field Values for HTTP">[RFC8941]</a>.</p> <p>The header’s ABNF is:</p> <pre class="language-abnf highlight"><c- nc>Sec-CH-UA-WoW64</c-> <c- o>=</c-> <c- nc>sf-boolean</c-> </pre> <p class="note" role="note"><span class="marker">Note:</span> These client hints can be evoked with the following set of <a data-link-type="dfn" href="https://wicg.github.io/client-hints-infrastructure/#client-hints-token" id="ref-for-client-hints-token">client hints tokens</a>: <code>Sec-CH-UA</code>, <code>Sec-CH-UA-Arch</code>, <code>Sec-CH-UA-Bitness</code>, <code>Sec-CH-UA-Form-Factors</code>, <code>Sec-CH-UA-Full-Version</code>, <code>Sec-CH-UA-Full-Version-List</code>, <code>Sec-CH-UA-Mobile</code>, <code>Sec-CH-UA-Model</code>, <code>Sec-CH-UA-Platform</code>, <code>Sec-CH-UA-Platform-Version</code>, <code>Sec-CH-UA-WoW64</code></p> <h2 class="heading settled" data-level="4" id="interface"><span class="secno">4. </span><span class="content">Interface</span><a class="self-link" href="#interface"></a></h2> <pre class="idl highlight def"><c- b>dictionary</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="dictionary" data-export id="dictdef-navigatoruabrandversion"><code><c- g>NavigatorUABrandVersion</c-></code></dfn> { <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="NavigatorUABrandVersion" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-navigatoruabrandversion-brand"><code><c- g>brand</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString①"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="NavigatorUABrandVersion" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-navigatoruabrandversion-version"><code><c- g>version</c-></code></dfn>; }; <c- b>dictionary</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="dictionary" data-export id="dictdef-uadatavalues"><code><c- g>UADataValues</c-></code></dfn> { <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString②"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-uadatavalues-architecture"><code><c- g>architecture</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString③"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-uadatavalues-bitness"><code><c- g>bitness</c-></code></dfn>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence" id="ref-for-idl-sequence"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion"><c- n>NavigatorUABrandVersion</c-></a>> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="sequence<NavigatorUABrandVersion> " id="dom-uadatavalues-brands"><code><c- g>brands</c-></code></dfn>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence" id="ref-for-idl-sequence①"><c- b>sequence</c-></a><<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString④"><c- b>DOMString</c-></a>> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="sequence<DOMString> " id="dom-uadatavalues-formfactors"><code><c- g>formFactors</c-></code></dfn>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence" id="ref-for-idl-sequence②"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion①"><c- n>NavigatorUABrandVersion</c-></a>> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="sequence<NavigatorUABrandVersion> " id="dom-uadatavalues-fullversionlist"><code><c- g>fullVersionList</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString⑤"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-uadatavalues-model"><code><c- g>model</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean" id="ref-for-idl-boolean"><c- b>boolean</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="boolean " id="dom-uadatavalues-mobile"><code><c- g>mobile</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString⑥"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-uadatavalues-platform"><code><c- g>platform</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString⑦"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-uadatavalues-platformversion"><code><c- g>platformVersion</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString⑧"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-uadatavalues-uafullversion"><code><c- g>uaFullVersion</c-></code></dfn>; // deprecated in favor of fullVersionList <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean" id="ref-for-idl-boolean①"><c- b>boolean</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UADataValues" data-dfn-type="dict-member" data-export data-type="boolean " id="dom-uadatavalues-wow64"><code><c- g>wow64</c-></code></dfn>; }; <c- b>dictionary</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="dictionary" data-export id="dictdef-ualowentropyjson"><code><c- g>UALowEntropyJSON</c-></code></dfn> { <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence" id="ref-for-idl-sequence③"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion②"><c- n>NavigatorUABrandVersion</c-></a>> <dfn class="dfn-paneled idl-code" data-dfn-for="UALowEntropyJSON" data-dfn-type="dict-member" data-export data-type="sequence<NavigatorUABrandVersion> " id="dom-ualowentropyjson-brands"><code><c- g>brands</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean" id="ref-for-idl-boolean②"><c- b>boolean</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UALowEntropyJSON" data-dfn-type="dict-member" data-export data-type="boolean " id="dom-ualowentropyjson-mobile"><code><c- g>mobile</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString⑨"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="UALowEntropyJSON" data-dfn-type="dict-member" data-export data-type="DOMString " id="dom-ualowentropyjson-platform"><code><c- g>platform</c-></code></dfn>; }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed" id="ref-for-Exposed"><c- g>Exposed</c-></a>=(<c- n>Window</c->,<c- n>Worker</c->)] <c- b>interface</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="navigatoruadata"><code><c- g>NavigatorUAData</c-></code></dfn> { <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-frozen-array" id="ref-for-idl-frozen-array"><c- b>FrozenArray</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion③"><c- n>NavigatorUABrandVersion</c-></a>> <dfn class="dfn-paneled idl-code" data-dfn-for="NavigatorUAData" data-dfn-type="attribute" data-export data-readonly data-type="FrozenArray<NavigatorUABrandVersion>" id="dom-navigatoruadata-brands"><code><c- g>brands</c-></code></dfn>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean" id="ref-for-idl-boolean③"><c- b>boolean</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="NavigatorUAData" data-dfn-type="attribute" data-export data-readonly data-type="boolean" id="dom-navigatoruadata-mobile"><code><c- g>mobile</c-></code></dfn>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString①⓪"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="NavigatorUAData" data-dfn-type="attribute" data-export data-readonly data-type="DOMString" id="dom-navigatoruadata-platform"><code><c- g>platform</c-></code></dfn>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-promise" id="ref-for-idl-promise"><c- b>Promise</c-></a><<a data-link-type="idl-name" href="#dictdef-uadatavalues" id="ref-for-dictdef-uadatavalues"><c- n>UADataValues</c-></a>> <dfn class="idl-code" data-dfn-for="NavigatorUAData" data-dfn-type="method" data-export data-lt="getHighEntropyValues(hints)" id="dom-navigatoruadata-gethighentropyvalues"><code><c- g>getHighEntropyValues</c-></code><a class="self-link" href="#dom-navigatoruadata-gethighentropyvalues"></a></dfn>(<a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence" id="ref-for-idl-sequence④"><c- b>sequence</c-></a><<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString①①"><c- b>DOMString</c-></a>> <dfn class="idl-code" data-dfn-for="NavigatorUAData/getHighEntropyValues(hints)" data-dfn-type="argument" data-export id="dom-navigatoruadata-gethighentropyvalues-hints-hints"><code><c- g>hints</c-></code><a class="self-link" href="#dom-navigatoruadata-gethighentropyvalues-hints-hints"></a></dfn>); <a data-link-type="idl-name" href="#dictdef-ualowentropyjson" id="ref-for-dictdef-ualowentropyjson"><c- n>UALowEntropyJSON</c-></a> <dfn class="idl-code" data-dfn-for="NavigatorUAData" data-dfn-type="method" data-export data-lt="toJSON()" id="dom-navigatoruadata-tojson"><code><c- g>toJSON</c-></code><a class="self-link" href="#dom-navigatoruadata-tojson"></a></dfn>(); }; <c- b>interface</c-> <c- b>mixin</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="navigatorua"><code><c- g>NavigatorUA</c-></code></dfn> { [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#SecureContext" id="ref-for-SecureContext"><c- g>SecureContext</c-></a>] <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="#navigatoruadata" id="ref-for-navigatoruadata"><c- n>NavigatorUAData</c-></a> <dfn class="idl-code" data-dfn-for="NavigatorUA" data-dfn-type="attribute" data-export data-readonly data-type="NavigatorUAData" id="dom-navigatorua-useragentdata"><code><c- g>userAgentData</c-></code><a class="self-link" href="#dom-navigatorua-useragentdata"></a></dfn>; }; <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/system-state.html#navigator" id="ref-for-navigator"><c- n>Navigator</c-></a> <c- b>includes</c-> <a data-link-type="idl-name" href="#navigatorua" id="ref-for-navigatorua"><c- n>NavigatorUA</c-></a>; <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/workers.html#workernavigator" id="ref-for-workernavigator"><c- n>WorkerNavigator</c-></a> <c- b>includes</c-> <a data-link-type="idl-name" href="#navigatorua" id="ref-for-navigatorua①"><c- n>NavigatorUA</c-></a>; </pre> <p class="note" role="note"><span class="marker">Note:</span> The high-entropy portions of the user agent information are retrieved through a <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-promise" id="ref-for-idl-promise①">Promise</a></code>, in order to give <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③⓪">user agents</a> the opportunity to gate their exposure behind potentially time-consuming checks (e.g. by asking the user for their permission).</p> <h3 class="heading settled" data-level="4.1" id="processing"><span class="secno">4.1. </span><span class="content">Processing model</span><a class="self-link" href="#processing"></a></h3> <h4 class="heading settled" data-level="4.1.1" id="monkeypatch-html-windoworworkerglobalscope"><span class="secno">4.1.1. </span><span class="content"><code>WindowOrWorkerGlobalScope</code></span><a class="self-link" href="#monkeypatch-html-windoworworkerglobalscope"></a></h4> <p>Each <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③①">user agent</a> has an associated <dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-noexport id="user-agent-brands">brands</dfn>, which is a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list③">list</a> created by running <a data-link-type="dfn" href="#create-brands" id="ref-for-create-brands②">create brands</a> with <a data-link-type="dfn" href="#user-agent-significant-version" id="ref-for-user-agent-significant-version①">significant version</a>.</p> <p>Every <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope" id="ref-for-windoworworkerglobalscope">WindowOrWorkerGlobalScope</a></code> object has an associated <dfn class="dfn-paneled" data-dfn-for="WindowOrWorkerGlobalScope" data-dfn-type="dfn" data-noexport id="windoworworkerglobalscope-brands-frozen-array">brands frozen array</dfn>, which is a <code><a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-frozen-array" id="ref-for-idl-frozen-array①">FrozenArray</a><<a class="idl-code" data-link-type="dictionary" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion④">NavigatorUABrandVersion</a>></code>. It is initially the result of <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#dfn-create-frozen-array" id="ref-for-dfn-create-frozen-array">creating a frozen array</a> from the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③②">user agent</a>'s <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands④">brands</a>.</p> <p>Additionally, every <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope" id="ref-for-windoworworkerglobalscope①">WindowOrWorkerGlobalScope</a></code> object has an associated <dfn class="dfn-paneled" data-dfn-for="WindowOrWorkerGlobalScope" data-dfn-type="dfn" data-noexport id="windoworworkerglobalscope-full-version-list-frozen-array">full version list frozen array</dfn>, which is a <code><a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-frozen-array" id="ref-for-idl-frozen-array②">FrozenArray</a><<a class="idl-code" data-link-type="dictionary" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion⑤">NavigatorUABrandVersion</a>></code>. It is the result of <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#dfn-create-frozen-array" id="ref-for-dfn-create-frozen-array①">creating a frozen array</a> from running <a data-link-type="dfn" href="#create-brands" id="ref-for-create-brands③">create brands</a> with <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version④">full version</a>.</p> <h4 class="heading settled algorithm" data-algorithm="to create brands" data-level="4.1.2" id="create-ua-list-section"><span class="secno">4.1.2. </span><span class="content">Create brands</span><a class="self-link" href="#create-ua-list-section"></a></h4> <p>When asked to <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="create-brands">create brands</dfn> with <var>version type</var>, run the following steps:</p> <ol> <li data-md> <p>Let <var>list</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list④">list</a>.</p> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#assert" id="ref-for-assert">Assert</a> <var>version type</var> is either "full version" or "significant version".</p> <li data-md> <p>For each <a data-link-type="dfn" href="#user-agent-brand" id="ref-for-user-agent-brand①">brand</a> that represents the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③③">user agent</a>—or an <a data-link-type="dfn" href="#user-agent-equivalence-class" id="ref-for-user-agent-equivalence-class①">equivalence class</a>—as <var>brand</var>:</p> <ol> <li data-md> <p>Let <var>version</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#string" id="ref-for-string">string</a>, initialized accordingly:</p> <ol> <li data-md> <p>If <var>version type</var> is "full version", set <var>version</var> to a string that corresponds to the <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version⑤">full version</a>.</p> <li data-md> <p>If <var>version type</var> is "significant version", set <var>version</var> to a string that corresponds to the <a data-link-type="dfn" href="#user-agent-significant-version" id="ref-for-user-agent-significant-version②">significant version</a>.</p> </ol> <li data-md> <p>Let <var>dict</var> be a new <code class="idl"><a data-link-type="idl" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion⑥">NavigatorUABrandVersion</a></code> dictionary, with <code class="idl"><a data-link-type="idl" href="#dom-navigatoruabrandversion-brand" id="ref-for-dom-navigatoruabrandversion-brand">brand</a></code> set to <var>brand</var> and <code class="idl"><a data-link-type="idl" href="#dom-navigatoruabrandversion-version" id="ref-for-dom-navigatoruabrandversion-version">version</a></code> set to <var>version</var>.</p> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append⑥">Append</a> <var>dict</var> to <var>list</var>.</p> </ol> <li data-md> <p>The <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③④">user agent</a> SHOULD execute the following steps:</p> <ol> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append⑦">Append</a> one additional <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-item" id="ref-for-list-item">item</a> to <var>list</var> containing a <code class="idl"><a data-link-type="idl" href="#dictdef-navigatoruabrandversion" id="ref-for-dictdef-navigatoruabrandversion⑦">NavigatorUABrandVersion</a></code> dictionary, initialized with <code class="idl"><a data-link-type="idl" href="#dom-navigatoruabrandversion-brand" id="ref-for-dom-navigatoruabrandversion-brand①">brand</a></code> set to <a data-link-type="dfn" href="#create-an-arbitrary-brand" id="ref-for-create-an-arbitrary-brand">arbitrary brand</a> and set <code class="idl"><a data-link-type="idl" href="#dom-navigatoruabrandversion-version" id="ref-for-dom-navigatoruabrandversion-version①">version</a></code> to the result of <a data-link-type="dfn" href="#create-an-arbitrary-version" id="ref-for-create-an-arbitrary-version">create an arbitrary version</a> with <var>version type</var>.</p> <li data-md> <p>Randomize the order of the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-item" id="ref-for-list-item①">items</a> in <var>list</var>.</p> </ol> <p class="note" role="note"><span class="marker">Note:</span> One approach to minimize caching variance when generating these random components could be to determine them at build time, and keep them identical throughout the lifetime of the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③⑤">user agent</a>'s significant version.</p> <p class="note" role="note"><span class="marker">Note:</span> See <a href="#grease">§ 6.2 GREASE-like UA Brand Lists</a> for more details on when and why these randomization steps might be appropriate.</p> <li data-md> <p>Return <var>list</var>.</p> </ol> <p>An <dfn class="dfn-paneled" data-dfn-for="user agent" data-dfn-type="dfn" data-export id="user-agent-equivalence-class">equivalence class</dfn> represents a group of browsers believed to be compatible with each other. A shared rendering engine may form an <a data-link-type="dfn" href="#user-agent-equivalence-class" id="ref-for-user-agent-equivalence-class②">equivalence class</a>, for example.</p> <h4 class="heading settled algorithm" data-algorithm="to create arbitrary brand and version values" data-level="4.1.3" id="create-arbitrary-brands-section"><span class="secno">4.1.3. </span><span class="content">Create arbitrary brand and version values</span><a class="self-link" href="#create-arbitrary-brands-section"></a></h4> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="create-an-arbitrary-brand">create an arbitrary brand</dfn>, the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③⑥">user agent</a> MUST run these steps:</p> <ol> <li data-md> <p>Let <var>arbitraryBrand</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#string" id="ref-for-string①">string</a> composed of <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#ascii-alpha" id="ref-for-ascii-alpha①">ASCII alpha</a> and 0x20 (SP). <var>arbitraryBrand</var> MUST contain one or more 0x20 (SP) bytes and be no longer than twenty <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#ascii-byte" id="ref-for-ascii-byte">ASCII bytes</a>, and MUST not start or end with 0x20 (SP).</p> <li data-md> <p>Let <var>arbitraryBrandList</var> be the result of <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#split-on-ascii-whitespace" id="ref-for-split-on-ascii-whitespace">splitting <var>arbitraryBrand</var> on ASCII whitespace</a>.</p> <li data-md> <p>Let <var>greaseyStack</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#stack" id="ref-for-stack">stack</a>.</p> <li data-md> <p>Let <var>greaseyChars</var> be the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list⑤">list</a> of <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#ascii-byte" id="ref-for-ascii-byte①">ASCII bytes</a> « 0x20 (SP), 0x28 (left parenthesis), 0x29 (right parenthesis), 0x2D (-), 0x2E (.), 0x2F (/), 0x3A (:), 0x3B (;), 0x3D (=), 0x3F (?), 0x5F (_) ».</p> <li data-md> <p>Let <var>index</var> be 0.</p> <li data-md> <p>While <var>index</var> is less than the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-size" id="ref-for-list-size">size</a> of <var>arbitraryBrandList</var> minus one:</p> <ol> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#stack-push" id="ref-for-stack-push">Push</a> a randomly selected <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-item" id="ref-for-list-item②">item</a> from <var>greaseyChars</var> onto <var>greaseyStack</var>.</p> <li data-md> <p>Increment <var>index</var> by 1.</p> </ol> <li data-md> <p>Let <var>greaseyBrandList</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list⑥">list</a> and set <var>index</var> to 0.</p> <li data-md> <p>While <var>greaseyStack</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-is-empty" id="ref-for-list-is-empty">is not empty</a>:</p> <ol> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append⑧">Append</a> <var>arbitraryBrandList</var>[<var>index</var>] to <var>greaseyBrandList</var>.</p> <li data-md> <p>Let <var>item</var> be the result of <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#stack-pop" id="ref-for-stack-pop">popping</a> from <var>greaseyStack</var>.</p> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append⑨">Append</a> <var>item</var> to <var>greaseyBrandList</var>.</p> <li data-md> <p>Increment <var>index</var> by 1.</p> </ol> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append①⓪">Append</a> <var>arbitraryBrandList</var>[<var>index</var>] to <var>greaseyBrandList</var>.</p> <li data-md> <p>Return the result of <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace" id="ref-for-strip-leading-and-trailing-ascii-whitespace"> stripping leading and trailing ASCII whitespace</a> from the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#string-concatenate" id="ref-for-string-concatenate②">concatenation</a> of <var>greaseyBrandList</var> (with no separator).</p> </ol> <div class="note" role="note"> This algorithm should result in an arbitrary brand without leading or trailing <var>greaseyChars</var>, as implementation experience has shown these are not web-compatible. <p>In addition, despite <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#" id="ref-for-something①①">Structured Headers</a> allowing for escaped 0x22 (\") and 0x5C (\\) inside a <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8941#section-3.3.3" id="ref-for-section-3.3.3⑦">string</a>, these characters have also created compatibility issues with firewalls.</p> </div> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="create-an-arbitrary-version">create an arbitrary version</dfn> given <var>version type</var>, run the following steps:</p> <ol> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#assert" id="ref-for-assert①">Assert</a> <var>version type</var> is either "full version" or "significant version".</p> <li data-md> <p>Let <var>arbitrary version</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#string" id="ref-for-string②">string</a>, initialized accordingly:</p> <ol> <li data-md> <p>If <var>version type</var> is "full version", set <var>arbitrary version</var> to a string that matches the format of the <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version⑥">full version</a>, but not the value.</p> <li data-md> <p>If <var>version type</var> is "significant version", set <var>arbitrary version</var> to a string that matches the format of <a data-link-type="dfn" href="#user-agent-significant-version" id="ref-for-user-agent-significant-version③">significant version</a>, but not the value.</p> </ol> <li data-md> <p>Return <var>arbitrary version</var>.</p> </ol> <p class="note" role="note"><span class="marker">Note:</span> User Agents may decide to send arbitrarily low versions to ensure proper version checking, and should vary them over time.</p> <h4 class="heading settled algorithm" data-algorithm="to create a brand-version list" data-level="4.1.4" id="create-brand-version-list"><span class="secno">4.1.4. </span><span class="content">Create a brand-version list</span><a class="self-link" href="#create-brand-version-list"></a></h4> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="create-a-brand-version-list">create a brand-version list</dfn> given <var>brands</var> and <var>version type</var>, perform the following steps:</p> <ol> <li data-md> <p>Let <var>list</var> be a <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list" id="ref-for-list⑦">list</a>, initially empty.</p> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#assert" id="ref-for-assert②">Assert</a> <var>version type</var> is either "full version" or "significant version".</p> <li data-md> <p>For each <var>brand</var> in <var>brands</var>:</p> <ol> <li data-md> <p>Let <var>version</var> be a string, initialized accordingly:</p> <ol> <li data-md> <p>If <var>version type</var> is "full version", set <var>version</var> to a string that corresponds to the <a data-link-type="dfn" href="#user-agent-full-version" id="ref-for-user-agent-full-version⑦">full version</a>.</p> <li data-md> <p>If <var>version type</var> is "significant version", set <var>version</var> to a string that corresponds to the <a data-link-type="dfn" href="#user-agent-significant-version" id="ref-for-user-agent-significant-version④">significant version</a>.</p> </ol> <li data-md> <p>Let <var>parameter</var> be a <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#dfn-dictionary" id="ref-for-dfn-dictionary">dictionary</a>, initially empty.</p> <li data-md> <p>Set <var>parameter</var>["param_key"] to "v".</p> <li data-md> <p>Set <var>parameter</var>["param_value"] to <var>version</var>.</p> <li data-md> <p>Let <var>pair</var> be a tuple comprised of <var>brand</var>’s <code class="idl"><a data-link-type="idl" href="#dom-navigatoruabrandversion-brand" id="ref-for-dom-navigatoruabrandversion-brand②">brand</a></code> and <var>parameter</var>.</p> <li data-md> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-append" id="ref-for-list-append①①">Append</a> <var>pair</var> to <var>list</var>.</p> </ol> <li data-md> <p>Return <var>list</var>.</p> </ol> <h4 class="heading settled" data-level="4.1.5" id="getters"><span class="secno">4.1.5. </span><span class="content">Getters</span><a class="self-link" href="#getters"></a></h4> <p>On getting, the <code class="idl"><a data-link-type="idl" href="#dom-navigatoruadata-brands" id="ref-for-dom-navigatoruadata-brands">brands</a></code> attribute MUST return <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this">this</a>'s <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-global" id="ref-for-concept-relevant-global">relevant global object</a>'s <a data-link-type="dfn" href="#windoworworkerglobalscope-brands-frozen-array" id="ref-for-windoworworkerglobalscope-brands-frozen-array">brands frozen array</a>.</p> <p>On getting, the <code class="idl"><a data-link-type="idl" href="#dom-navigatoruadata-mobile" id="ref-for-dom-navigatoruadata-mobile">mobile</a></code> attribute must return the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③⑦">user agent</a>'s <a data-link-type="dfn" href="#user-agent-mobileness" id="ref-for-user-agent-mobileness②">mobileness</a>.</p> <p>On getting, the <code class="idl"><a data-link-type="idl" href="#dom-navigatoruadata-platform" id="ref-for-dom-navigatoruadata-platform">platform</a></code> attribute must return the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③⑧">user agent</a>'s <a data-link-type="dfn" href="#user-agent-platform-brand" id="ref-for-user-agent-platform-brand①">platform brand</a>.</p> <h4 class="heading settled" data-level="4.1.6" id="getHighEntropyValues"><span class="secno">4.1.6. </span><span class="content"><code>getHighEntropyValues</code> method</span><a class="self-link" href="#getHighEntropyValues"></a></h4> <p>The <dfn class="idl-code" data-dfn-for="NavigatorUA" data-dfn-type="method" data-export id="dom-navigatorua-gethighentropyvalues"><code>getHighEntropyValues(<var>hints</var>)</code><a class="self-link" href="#dom-navigatorua-gethighentropyvalues"></a></dfn> method MUST run these steps:</p> <ol> <li data-md> <p>Let <var>p</var> be a <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#a-new-promise" id="ref-for-a-new-promise">a new promise</a> created in the <a data-link-type="dfn" href="https://tc39.es/ecma262/#current-realm" id="ref-for-current-realm">current realm</a>.</p> <li data-md> <p>If the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent③⑨">user agent</a> decides one or more values in <var>hints</var> should not be returned, then <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#reject" id="ref-for-reject">reject</a> and return <var>p</var> with a "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#notallowederror" id="ref-for-notallowederror">NotAllowedError</a></code>".</p> </ol> <p class="issue" id="issue-22962aa8"><a class="self-link" href="#issue-22962aa8"></a> We can improve upon when and why a UA decides to refuse a hint once <a href="https://github.com/WICG/ua-client-hints/issues/151">Issue #151</a> is resolved.</p> <ol start="3"> <li data-md> <p>Otherwise, run the following steps <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel" id="ref-for-in-parallel">in parallel</a>:</p> <ol> <li data-md> <p>Let <var>uaData</var> be a new <code class="idl"><a data-link-type="idl" href="#dictdef-uadatavalues" id="ref-for-dictdef-uadatavalues①">UADataValues</a></code>.</p> <li data-md> <p>set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-brands" id="ref-for-dom-uadatavalues-brands">brands</a></code>"] to <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this①">this</a>'s <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-global" id="ref-for-concept-relevant-global①">relevant global object</a>'s <a data-link-type="dfn" href="#windoworworkerglobalscope-brands-frozen-array" id="ref-for-windoworworkerglobalscope-brands-frozen-array①">brands frozen array</a>.</p> <li data-md> <p>set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-mobile" id="ref-for-dom-uadatavalues-mobile">mobile</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④⓪">user agent</a>'s <a data-link-type="dfn" href="#user-agent-mobileness" id="ref-for-user-agent-mobileness③">mobileness</a>.</p> <li data-md> <p>set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-platform" id="ref-for-dom-uadatavalues-platform">platform</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④①">user agent</a>'s <a data-link-type="dfn" href="#user-agent-platform-brand" id="ref-for-user-agent-platform-brand②">platform brand</a>.</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain">contains</a> "architecture", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-architecture" id="ref-for-dom-uadatavalues-architecture">architecture</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④②">user agent</a>'s <a data-link-type="dfn" href="#user-agent-platform-architecture" id="ref-for-user-agent-platform-architecture③">platform architecture</a>.</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain①">contains</a> "bitness", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-bitness" id="ref-for-dom-uadatavalues-bitness">bitness</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④③">user agent</a>'s <a data-link-type="dfn" href="#user-agent-platform-bitness" id="ref-for-user-agent-platform-bitness③">platform bitness</a>.</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain②">contains</a> "formFactors", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-formfactors" id="ref-for-dom-uadatavalues-formfactors">formFactors</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④④">user agent</a>'s <a data-link-type="dfn" href="#user-agent-form-factors" id="ref-for-user-agent-form-factors①">form-factors</a>.</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain③">contains</a> "fullVersionList", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-fullversionlist" id="ref-for-dom-uadatavalues-fullversionlist">fullVersionList</a></code>"] to <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this②">this</a>'s <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-global" id="ref-for-concept-relevant-global②">relevant global object</a>'s <a data-link-type="dfn" href="#windoworworkerglobalscope-full-version-list-frozen-array" id="ref-for-windoworworkerglobalscope-full-version-list-frozen-array">full version list frozen array</a>.</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain④">contains</a> "model", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-model" id="ref-for-dom-uadatavalues-model">model</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④⑤">user agent</a>'s <a data-link-type="dfn" href="#user-agent-model" id="ref-for-user-agent-model③">model</a>.</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain⑤">contains</a> "platformVersion", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-platformversion" id="ref-for-dom-uadatavalues-platformversion">platformVersion</a></code>"] to the result of <a data-link-type="dfn" href="#get-the-platform-version" id="ref-for-get-the-platform-version①">getting the platform version</a> with <a data-link-type="dfn" href="#user-agent-platform-brand" id="ref-for-user-agent-platform-brand③">platform brand</a>.</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain⑥">contains</a> "uaFullVersion", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-uafullversion" id="ref-for-dom-uadatavalues-uafullversion">uaFullVersion</a></code>"]</p> <li data-md> <p>If <var>hints</var> <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#list-contain" id="ref-for-list-contain⑦">contains</a> "wow64", set <var>uaData</var>["<code class="idl"><a data-link-type="idl" href="#dom-uadatavalues-wow64" id="ref-for-dom-uadatavalues-wow64">wow64</a></code>"] to the user agent’s <a data-link-type="dfn" href="#user-agent-wow64-ness" id="ref-for-user-agent-wow64-ness①">wow64-ness</a>.</p> <li data-md> <p><a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="ref-for-queue-a-task">Queue a task</a> on the <a data-link-type="dfn" href="https://w3c.github.io/permissions/#dfn-permissions-task-source" id="ref-for-dfn-permissions-task-source">permission task source</a> to <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#resolve" id="ref-for-resolve">resolve</a> <var>p</var> with <var>uaData</var>.</p> </ol> <li data-md> <p>Return <var>p</var>.</p> </ol> <h4 class="heading settled" data-level="4.1.7" id="toJSON"><span class="secno">4.1.7. </span><span class="content"><code>toJSON</code> method</span><a class="self-link" href="#toJSON"></a></h4> <p>The <dfn class="idl-code" data-dfn-for="NavigatorUA" data-dfn-type="method" data-export id="dom-navigatorua-tojson"><code>toJSON()</code><a class="self-link" href="#dom-navigatorua-tojson"></a></dfn> method MUST run these steps:</p> <ol> <li data-md> <p>Let <var>uaLowEntropyData</var> be a new <code class="idl"><a data-link-type="idl" href="#dictdef-ualowentropyjson" id="ref-for-dictdef-ualowentropyjson①">UALowEntropyJSON</a></code></p> <li data-md> <p>set <var>uaLowEntropyData</var>["<code class="idl"><a data-link-type="idl" href="#dom-ualowentropyjson-brands" id="ref-for-dom-ualowentropyjson-brands">brands</a></code>"] to <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this③">this</a>'s <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-global" id="ref-for-concept-relevant-global③">relevant global object</a>'s <a data-link-type="dfn" href="#windoworworkerglobalscope-brands-frozen-array" id="ref-for-windoworworkerglobalscope-brands-frozen-array②">brands frozen array</a>.</p> <li data-md> <p>set <var>uaLowEntropyData</var>["<code class="idl"><a data-link-type="idl" href="#dom-ualowentropyjson-mobile" id="ref-for-dom-ualowentropyjson-mobile">mobile</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④⑥">user agent</a>'s <a data-link-type="dfn" href="#user-agent-mobileness" id="ref-for-user-agent-mobileness④">mobileness</a>.</p> <li data-md> <p>set <var>uaLowEntropyData</var>["<code class="idl"><a data-link-type="idl" href="#dom-ualowentropyjson-platform" id="ref-for-dom-ualowentropyjson-platform">platform</a></code>"] to the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④⑦">user agent</a>'s <a data-link-type="dfn" href="#user-agent-platform-brand" id="ref-for-user-agent-platform-brand④">platform brand</a>.</p> <li data-md> <p>Return <var>uaLowEntropyData</var></p> </ol> <h2 class="heading settled" data-level="5" id="security-privacy"><span class="secno">5. </span><span class="content">Security and Privacy Considerations</span><a class="self-link" href="#security-privacy"></a></h2> <h3 class="heading settled" data-level="5.1" id="secure-transport"><span class="secno">5.1. </span><span class="content">Secure Transport</span><a class="self-link" href="#secure-transport"></a></h3> <p>Client Hints will not be delivered to non-secure endpoints (see the secure transport requirements in Section 2.2.1 of <a data-link-type="biblio" href="#biblio-rfc8942" title="HTTP Client Hints">[RFC8942]</a>). This means that <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④⑧">user agent</a> information will not be leaked over plaintext channels, reducing the opportunity for network attackers to build a profile of a given agent’s behavior over time.</p> <h3 class="heading settled" data-level="5.2" id="delegation"><span class="secno">5.2. </span><span class="content">Delegation</span><a class="self-link" href="#delegation"></a></h3> <p>Client Hints will be delegated from top-level pages via Permissions Policy (<a data-link-type="biblio" href="#biblio-permissions-policy-1" title="Permissions Policy">[permissions-policy-1]</a>). This reduces the likelihood that <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent④⑨">user agent</a> information will be delivered along with subresource requests, which reduces the potential for <a data-link-type="dfn" href="https://w3c.github.io/fingerprinting-guidance/#dfn-passive-fingerprinting" id="ref-for-dfn-passive-fingerprinting②">passive fingerprinting</a>.</p> <p>That delegation is defined as part of <a data-link-type="abstract-op" href="https://wicg.github.io/client-hints-infrastructure/#abstract-opdef-append-client-hints-to-request" id="ref-for-abstract-opdef-append-client-hints-to-request">append client hints to request</a>.</p> <h3 class="heading settled" data-level="5.3" id="fingerprinting"><span class="secno">5.3. </span><span class="content">Fingerprinting</span><a class="self-link" href="#fingerprinting"></a></h3> <p>The <em>primary goal</em> of User Agent Client Hints is to reduce the amount of default entropy exposed to the web at large through the User-Agent header field, which may be used for <a data-link-type="dfn" href="https://w3c.github.io/fingerprinting-guidance/#dfn-passive-fingerprinting" id="ref-for-dfn-passive-fingerprinting③">passive fingerprinting</a> purposes.</p> <p>A <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤⓪">user agent</a> is able to decide which hints it provides, with the expectation that no more information is provided than would be included in an unredacted User-Agent header field. A <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤①">user agent</a> can provide an empty string for any value that it does not wish to provide, or refuse to return a hint entirely.</p> <p>However, it will still be possible for some, or all, hints to be requested and used for <a data-link-type="dfn" href="https://w3c.github.io/fingerprinting-guidance/#dfn-active-fingerprinting" id="ref-for-dfn-active-fingerprinting">active fingerprinting</a> purposes by first or delegated third parties. As noted in <a href="#access">§ 5.4 Access Restrictions</a>, <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤②">user agents</a> should consider policies to restrict or reduce access to parties that are known to <a data-link-type="dfn" href="https://w3c.github.io/fingerprinting-guidance/#dfn-active-fingerprinting" id="ref-for-dfn-active-fingerprinting①">actively fingerprint</a> their users.</p> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤③">User agents</a> should take care to not introduce fingerprinting vectors through GREASE-like brand lists that might be unique for an individual or a very small group of users. Rather, a strategy should be employed where the arbitrary brand is shared across many users (e.g., stable across major versions for all users).</p> <h3 class="heading settled" data-level="5.4" id="access"><span class="secno">5.4. </span><span class="content">Access Restrictions</span><a class="self-link" href="#access"></a></h3> <p>The information in the Client Hints defined above reveals quite a bit of information about the user agent and the device upon which it runs. <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤④">User agents</a> ought to exercise judgement before granting access to this information, and MAY impose restrictions above and beyond the secure transport and delegation requirements noted above. For instance, <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤⑤">user agents</a> could choose to reveal <a data-link-type="dfn" href="#user-agent-platform-architecture" id="ref-for-user-agent-platform-architecture④">platform architecture</a> or <a data-link-type="dfn" href="#user-agent-platform-bitness" id="ref-for-user-agent-platform-bitness④">platform bitness</a> only on requests it intends to download, giving the server the opportunity to serve the right binary. Likewise, they could offer users control over the values revealed to servers, or gate access on explicit user interaction via a permission prompt or via a settings interface.</p> <h2 class="heading settled" data-level="6" id="impl-considerations"><span class="secno">6. </span><span class="content">Implementation Considerations</span><a class="self-link" href="#impl-considerations"></a></h2> <h3 class="heading settled" data-level="6.1" id="user-agent"><span class="secno">6.1. </span><span class="content">The 'User-Agent' Header</span><a class="self-link" href="#user-agent"></a></h3> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤⑥">User agents</a> SHOULD deprecate usage of the <code>User-Agent</code> header by reducing its information granularity in favor of the Client Hints model described in this document. The header is likely to be impossible to remove entirely in the near-term, as existing sites' content negotiation code will continue to require its presence (see <a data-link-type="biblio" href="#biblio-rossi2015" title="The Microsoft Edge Rendering Engine that makes the Web just work">[Rossi2015]</a> for a recent example of a new browser’s struggles in this area).</p> <p>One approach which might be advisable could be for each <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤⑦">user agent</a> to lock the value of its <code>User-Agent</code> header, ensuring backwards compatibility by maintaining the crufty declarations of "like Gecko" and "AppleWebKit/537.36" on into eternity. This can ratchet over time, first freezing the version number, then shifting platform and model information to something reasonably generic in order to reduce the fingerprint the header provides.</p> <h3 class="heading settled" data-level="6.2" id="grease"><span class="secno">6.2. </span><span class="content">GREASE-like UA Brand Lists</span><a class="self-link" href="#grease"></a></h3> <p>History has shown us that there are real incentives for <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤⑧">user agents</a> to lie about their branding in order to thread the needle of sites' sniffing scripts, and prevent their users from being blocked by UA-based allow/block lists.</p> <p>Resetting expectations may help to prevent abuse of the <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands⑤">brands</a> list in the short term, but probably won’t help in the long run. The world of network protocols introduced the notion of <abbr title="Generate Random Extensions And Sustain Extensibility">GREASE</abbr> <a data-link-type="biblio" href="#biblio-i-dietf-tls-grease" title="Applying GREASE to TLS Extensibility">[I-D.ietf-tls-grease]</a>. We could borrow from that concept to tackle this problem.</p> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑤⑨">User agents</a>' <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands⑥">brands</a> containing more than a single entry could encourage standardized processing of the <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands⑦">brands</a> list. By randomly including additional, intentionally incorrect, comma-separated entries with arbitrary ordering, they would reduce the chance that we ossify on a few required strings.</p> <p>Let’s examine a few examples:</p> <ul> <li data-md> <p>In order to avoid sites from barring unknown browsers from their allow lists, Chrome could send a UA set that includes an non-existent browser, and which varies once in a while.</p> <ul> <li data-md> <p><code>"Chrome"; v="73", "(Not;Browser"; v="12"</code></p> </ul> <li data-md> <p>In order to enable <a data-link-type="dfn" href="#user-agent-equivalence-class" id="ref-for-user-agent-equivalence-class③">equivalence classes</a> based on Chromium versions, Chrome could add the rendering engine and its version to that.</p> <ul> <li data-md> <p><code>"Chrome"; v="73", "(Not;Browser"; v="12", "Chromium"; v="73"</code></p> </ul> <li data-md> <p>In order to encourage sites to rely on <a data-link-type="dfn" href="#user-agent-equivalence-class" id="ref-for-user-agent-equivalence-class④">equivalence classes</a> based on Chromium versions rather than exact UA sniffing, Chrome might remove itself from the set entirely.</p> <ul> <li data-md> <p><code>"(Not;Browser"; v="12", Chromium"; v="73"</code></p> </ul> <li data-md> <p>Browsers based on Chromium may use a similar UA string, but use their own brand as part of the set, enabling sites to count them.</p> <ul> <li data-md> <p><code>"Chrome"; v="73", "Xwebs mega"; v="60", "Chromium"; v="73", "(Not;Browser"; v="12"</code></p> </ul> </ul> <p><a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑥⓪">User agents</a> MUST include more than a single value in <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands⑧">brands</a>, where one of these values is an arbitrary value.</p> <p>The value order in <a data-link-type="dfn" href="#user-agent-brands" id="ref-for-user-agent-brands⑨">brands</a> MUST change over time to prevent receivers of the header from relying on certain values being in certain locations in the list.</p> <p>When choosing GREASE strategies, <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑥①">user agents</a> SHOULD keep caching variance and analytics use cases in mind and minimize variance among identical <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑥②">user agent</a> versions.</p> <p class="note" role="note"><span class="marker">Note:</span> One approach to minimize variance for caching and analytics could be to determine the GREASE parts of the UA set at build time, and keep them identical throughout the lifetime of the <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#user-agent" id="ref-for-user-agent⑥③">user agent</a>'s significant version.</p> <h3 class="heading settled" data-level="6.3" id="sec-ch"><span class="secno">6.3. </span><span class="content">The 'Sec-CH-' prefix</span><a class="self-link" href="#sec-ch"></a></h3> <p>Restricting user-land JavaScript code from influencing and modifying UA-CH headers has various security related advantages. At the same time, there don’t seem to be any legitimate <a href="https://github.com/WICG/ua-client-hints#use-cases">use-cases</a> which require such user-land rewriting.</p> <p>As such and based on <a href="https://github.com/w3ctag/design-reviews/issues/320">discussions with the TAG</a>, it seems reasonable to forbid write access to these headers from JavaScript (e.g. through <code>fetch</code> or Service Workers), and demarcate them as browser-controlled client hints so they can be documented and included in requests without triggering CORS preflights.</p> <p>Therefore, request headers defined in this specification include a <code>Sec-CH-</code> prefix.</p> <h2 class="heading settled" data-level="7" id="iana"><span class="secno">7. </span><span class="content">IANA Considerations</span><a class="self-link" href="#iana"></a></h2> <p>This document intends to define the <code>Sec-CH-UA</code>, <code>Sec-CH-UA-Arch</code>, <code>Sec-CH-UA-Bitness</code>, <code>Sec-CH-UA-Form-Factors</code>, <code>Sec-CH-UA-Full-Version</code>, <code>Sec-CH-UA-Mobile</code>, <code>Sec-CH-UA-Model</code>, <code>Sec-CH-UA-Platform</code>, <code>Sec-CH-UA-Platform-Version</code>, <code>Sec-CH-UA-WoW64</code>, and the <code>Sec-CH-UA-Full-Version-List</code> HTTP request header fields, and register them in the permanent message header field registry (<a data-link-type="biblio" href="#biblio-rfc3864" title="Registration Procedures for Message Header Fields">[RFC3864]</a>).</p> <p>It also intends to deprecate usage of the <code>User-Agent</code> header field.</p> <h3 class="heading settled" data-level="7.1" id="iana-ua"><span class="secno">7.1. </span><span class="content">'Sec-CH-UA' Header Field</span><a class="self-link" href="#iana-ua"></a></h3> <p>Header field name: Sec-CH-UA</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua">§ 3.1 The 'Sec-CH-UA' Header Field</a>)</p> <h3 class="heading settled" data-level="7.2" id="iana-arch"><span class="secno">7.2. </span><span class="content">'Sec-CH-UA-Arch' Header Field</span><a class="self-link" href="#iana-arch"></a></h3> <p>Header field name: Sec-CH-UA-Arch</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-arch">§ 3.2 The 'Sec-CH-UA-Arch' Header Field</a>)</p> <h3 class="heading settled" data-level="7.3" id="iana-bitness"><span class="secno">7.3. </span><span class="content">'Sec-CH-UA-Bitness' Header Field</span><a class="self-link" href="#iana-bitness"></a></h3> <p>Header field name: Sec-CH-UA-Bitness</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-bitness">§ 3.3 The 'Sec-CH-UA-Bitness' Header Field</a>)</p> <h3 class="heading settled" data-level="7.4" id="iana-form-factors"><span class="secno">7.4. </span><span class="content">'Sec-CH-UA-Form-Factors' Header Field</span><a class="self-link" href="#iana-form-factors"></a></h3> <p>Header field name: Sec-CH-UA-Form-Factors</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-form-factors">§ 3.4 The 'Sec-CH-UA-Form-Factors' Header Field</a>)</p> <h3 class="heading settled" data-level="7.5" id="iana-full-version"><span class="secno">7.5. </span><span class="content">'Sec-CH-UA-Full-Version' Header Field</span><a class="self-link" href="#iana-full-version"></a></h3> <p>Header field name: Sec-CH-UA-Full-Version</p> <p>Applicable protocol: http</p> <p>Status: deprecated</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-full-version">§ 3.5 The 'Sec-CH-UA-Full-Version' Header Field</a>)</p> <h3 class="heading settled" data-level="7.6" id="iana-full-version-list"><span class="secno">7.6. </span><span class="content">'Sec-CH-UA-Full-Version-List' Header Field</span><a class="self-link" href="#iana-full-version-list"></a></h3> <p>Header field name: Sec-CH-UA-Full-Version-List</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-full-version-list">§ 3.6 The 'Sec-CH-UA-Full-Version-List' Header Field</a>)</p> <h3 class="heading settled" data-level="7.7" id="iana-mobile"><span class="secno">7.7. </span><span class="content">'Sec-CH-UA-Mobile' Header Field</span><a class="self-link" href="#iana-mobile"></a></h3> <p>Header field name: Sec-CH-UA-Mobile</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-mobile">§ 3.7 The 'Sec-CH-UA-Mobile' Header Field</a>)</p> <h3 class="heading settled" data-level="7.8" id="iana-model"><span class="secno">7.8. </span><span class="content">'Sec-CH-UA-Model' Header Field</span><a class="self-link" href="#iana-model"></a></h3> <p>Header field name: Sec-CH-UA-Model</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-model">§ 3.8 The 'Sec-CH-UA-Model' Header Field</a>)</p> <h3 class="heading settled" data-level="7.9" id="iana-platform"><span class="secno">7.9. </span><span class="content">'Sec-CH-UA-Platform' Header Field</span><a class="self-link" href="#iana-platform"></a></h3> <p>Header field name: Sec-CH-UA-Platform</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-platform">§ 3.9 The 'Sec-CH-UA-Platform' Header Field</a>)</p> <h3 class="heading settled" data-level="7.10" id="iana-platform-version"><span class="secno">7.10. </span><span class="content">'Sec-CH-UA-Platform-Version' Header Field</span><a class="self-link" href="#iana-platform-version"></a></h3> <p>Header field name: Sec-CH-UA-Platform-Version</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-platform-version">§ 3.10 The 'Sec-CH-UA-Platform-Version' Header Field</a>)</p> <h3 class="heading settled" data-level="7.11" id="iana-wow64"><span class="secno">7.11. </span><span class="content">'Sec-CH-UA-WoW64' Header Field</span><a class="self-link" href="#iana-wow64"></a></h3> <p>Header field name: Sec-CH-UA-WoW64</p> <p>Applicable protocol: http</p> <p>Status: standard</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#sec-ch-ua-wow64">§ 3.11 The 'Sec-CH-UA-WoW64' Header Field</a>)</p> <h3 class="heading settled" data-level="7.12" id="iana-user-agent"><span class="secno">7.12. </span><span class="content">'User-Agent' Header Field</span><a class="self-link" href="#iana-user-agent"></a></h3> <p>Header field name: User-Agent</p> <p>Applicable protocol: http</p> <p>Status: deprecated</p> <p>Author/Change controller: IETF</p> <p>Specification document: this specification (<a href="#user-agent">§ 6.1 The 'User-Agent' Header</a>), and Section 5.5.3 of <a data-link-type="biblio" href="#biblio-rfc9110" title="HTTP Semantics">[rfc9110]</a></p> <h2 class="heading settled" data-level="8" id="ack"><span class="secno">8. </span><span class="content">Acknowledgments</span><a class="self-link" href="#ack"></a></h2> <p>Thanks to Aaron Tagliaboschi, Ali Beyad, ArkUmbra, Dustin Mitchell, Erik Anderson, jasonwee, Luke Williams, Mike West, Martin Thomson, and Toru Kobayashi for valuable feedback and contributions to this specification.</p> </main> <div data-fill-with="conformance"> <h2 class="no-ref no-num heading settled" id="w3c-conformance"><span class="content">Conformance</span><a class="self-link" href="#w3c-conformance"></a></h2> <h3 class="no-ref no-num heading settled" id="w3c-conventions"><span class="content">Document conventions</span><a class="self-link" href="#w3c-conventions"></a></h3> <p>Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification. </p> <p>All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. <a data-link-type="biblio" href="#biblio-rfc2119" title="Key words for use in RFCs to Indicate Requirement Levels">[RFC2119]</a> </p> <p>Examples in this specification are introduced with the words “for example” or are set apart from the normative text with <code>class="example"</code>, like this: </p> <div class="example" id="w3c-example"> <a class="self-link" href="#w3c-example"></a> <p>This is an example of an informative example. </p> </div> <p>Informative notes begin with the word “Note” and are set apart from the normative text with <code>class="note"</code>, like this: </p> <p class="note" role="note">Note, this is an informative note.</p> </div> <script src="https://www.w3.org/scripts/TR/2021/fixup.js"></script> <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2> <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3> <ul class="index"> <li><a href="#dom-uadatavalues-architecture">architecture</a><span>, in § 4</span> <li><a href="#dom-uadatavalues-bitness">bitness</a><span>, in § 4</span> <li> brand <ul> <li><a href="#user-agent-brand">dfn for user agent</a><span>, in § 3</span> <li><a href="#dom-navigatoruabrandversion-brand">dict-member for NavigatorUABrandVersion</a><span>, in § 4</span> </ul> <li> brands <ul> <li><a href="#dom-navigatoruadata-brands">attribute for NavigatorUAData</a><span>, in § 4</span> <li><a href="#user-agent-brands">dfn for user agent</a><span>, in § 4.1.1</span> <li><a href="#dom-uadatavalues-brands">dict-member for UADataValues</a><span>, in § 4</span> <li><a href="#dom-ualowentropyjson-brands">dict-member for UALowEntropyJSON</a><span>, in § 4</span> </ul> <li><a href="#windoworworkerglobalscope-brands-frozen-array">brands frozen array</a><span>, in § 4.1.1</span> <li><a href="#create-a-brand-version-list">create a brand-version list</a><span>, in § 4.1.4</span> <li><a href="#create-an-arbitrary-brand">create an arbitrary brand</a><span>, in § 4.1.3</span> <li><a href="#create-an-arbitrary-version">create an arbitrary version</a><span>, in § 4.1.3</span> <li><a href="#create-a-unified-platform-version-string">create a unified platform version string</a><span>, in § 3.10</span> <li><a href="#create-brands">create brands</a><span>, in § 4.1.2</span> <li><a href="#user-agent-equivalence-class">equivalence class</a><span>, in § 4.1.2</span> <li><a href="#user-agent-form-factors">form-factors</a><span>, in § 3</span> <li><a href="#dom-uadatavalues-formfactors">formFactors</a><span>, in § 4</span> <li><a href="#user-agent-full-version">full version</a><span>, in § 3</span> <li><a href="#dom-uadatavalues-fullversionlist">fullVersionList</a><span>, in § 4</span> <li><a href="#windoworworkerglobalscope-full-version-list-frozen-array">full version list frozen array</a><span>, in § 4.1.1</span> <li> getHighEntropyValues(hints) <ul> <li><a href="#dom-navigatorua-gethighentropyvalues">method for NavigatorUA</a><span>, in § 4.1.6</span> <li><a href="#dom-navigatoruadata-gethighentropyvalues">method for NavigatorUAData</a><span>, in § 4</span> </ul> <li><a href="#get-the-legacy-windows-version-number">get the legacy Windows version number</a><span>, in § 3.10</span> <li><a href="#get-the-platform-version">get the platform version</a><span>, in § 3.10</span> <li> mobile <ul> <li><a href="#dom-navigatoruadata-mobile">attribute for NavigatorUAData</a><span>, in § 4</span> <li><a href="#dom-uadatavalues-mobile">dict-member for UADataValues</a><span>, in § 4</span> <li><a href="#dom-ualowentropyjson-mobile">dict-member for UALowEntropyJSON</a><span>, in § 4</span> </ul> <li><a href="#user-agent-mobileness">mobileness</a><span>, in § 3</span> <li> model <ul> <li><a href="#user-agent-model">dfn for user agent</a><span>, in § 3</span> <li><a href="#dom-uadatavalues-model">dict-member for UADataValues</a><span>, in § 4</span> </ul> <li><a href="#navigatorua">NavigatorUA</a><span>, in § 4</span> <li><a href="#dictdef-navigatoruabrandversion">NavigatorUABrandVersion</a><span>, in § 4</span> <li><a href="#navigatoruadata">NavigatorUAData</a><span>, in § 4</span> <li> platform <ul> <li><a href="#dom-navigatoruadata-platform">attribute for NavigatorUAData</a><span>, in § 4</span> <li><a href="#dom-uadatavalues-platform">dict-member for UADataValues</a><span>, in § 4</span> <li><a href="#dom-ualowentropyjson-platform">dict-member for UALowEntropyJSON</a><span>, in § 4</span> </ul> <li><a href="#user-agent-platform-architecture">platform architecture</a><span>, in § 3</span> <li><a href="#user-agent-platform-bitness">platform bitness</a><span>, in § 3</span> <li><a href="#user-agent-platform-brand">platform brand</a><span>, in § 3</span> <li><a href="#user-agent-platform-version">platform version</a><span>, in § 3</span> <li><a href="#dom-uadatavalues-platformversion">platformVersion</a><span>, in § 4</span> <li><a href="#abstract-opdef-return-the-sec-ch-ua-full-version-list-value-for-a-request">return the Sec-CH-UA-Full-Version-List value for a request</a><span>, in § 3.6</span> <li><a href="#abstract-opdef-return-the-sec-ch-ua-value-for-a-request">return the Sec-CH-UA value for a request</a><span>, in § 3.1</span> <li><a href="#http-headerdef-sec-ch-ua">Sec-CH-UA</a><span>, in § 3.1</span> <li><a href="#http-headerdef-sec-ch-ua-arch">Sec-CH-UA-Arch</a><span>, in § 3.2</span> <li><a href="#http-headerdef-sec-ch-ua-bitness">Sec-CH-UA-Bitness</a><span>, in § 3.3</span> <li><a href="#http-headerdef-sec-ch-ua-form-factors">Sec-CH-UA-Form-Factors</a><span>, in § 3.4</span> <li><a href="#http-headerdef-sec-ch-ua-full-version">Sec-CH-UA-Full-Version</a><span>, in § 3.5</span> <li><a href="#http-headerdef-sec-ch-ua-full-version-list">Sec-CH-UA-Full-Version-List</a><span>, in § 3.6</span> <li><a href="#http-headerdef-sec-ch-ua-mobile">Sec-CH-UA-Mobile</a><span>, in § 3.7</span> <li><a href="#http-headerdef-sec-ch-ua-model">Sec-CH-UA-Model</a><span>, in § 3.8</span> <li><a href="#http-headerdef-sec-ch-ua-platform">Sec-CH-UA-Platform</a><span>, in § 3.9</span> <li><a href="#http-headerdef-sec-ch-ua-platform-version">Sec-CH-UA-Platform-Version</a><span>, in § 3.10</span> <li><a href="#http-headerdef-sec-ch-ua-wow64">Sec-CH-UA-WoW64</a><span>, in § 3.11</span> <li><a href="#user-agent-significant-version">significant version</a><span>, in § 3</span> <li> toJSON() <ul> <li><a href="#dom-navigatorua-tojson">method for NavigatorUA</a><span>, in § 4.1.7</span> <li><a href="#dom-navigatoruadata-tojson">method for NavigatorUAData</a><span>, in § 4</span> </ul> <li><a href="#dictdef-uadatavalues">UADataValues</a><span>, in § 4</span> <li><a href="#dom-uadatavalues-uafullversion">uaFullVersion</a><span>, in § 4</span> <li><a href="#dictdef-ualowentropyjson">UALowEntropyJSON</a><span>, in § 4</span> <li><a href="#dom-navigatorua-useragentdata">userAgentData</a><span>, in § 4</span> <li><a href="#dom-navigatoruabrandversion-version">version</a><span>, in § 4</span> <li><a href="#dom-uadatavalues-wow64">wow64</a><span>, in § 4</span> <li><a href="#user-agent-wow64-ness">wow64-ness</a><span>, in § 3</span> </ul> <h3 class="no-num no-ref heading settled" id="index-defined-elsewhere"><span class="content">Terms defined by reference</span><a class="self-link" href="#index-defined-elsewhere"></a></h3> <ul class="index"> <li> <a data-link-type="biblio">[]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="15edd6b4">active fingerprinting</span> <li><span class="dfn-paneled" id="bc612dfe">best practice 1</span> <li><span class="dfn-paneled" id="3aec4bbc">current realm</span> <li><span class="dfn-paneled" id="c9898e54">passive fingerprinting</span> <li><span class="dfn-paneled" id="0407598e">permission task source</span> </ul> <li> <a data-link-type="biblio">[CLIENT-HINTS-INFRASTRUCTURE]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="6360ebfe">append client hints to request</span> <li><span class="dfn-paneled" id="ea0ecaa0">client hints token</span> <li><span class="dfn-paneled" id="c7a20f42">low entropy hint table</span> <li><span class="dfn-paneled" id="f391224b">policy-controlled client hints features</span> </ul> <li> <a data-link-type="biblio">[COMPAT]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="966ed8e9">devicecompat</span> </ul> <li> <a data-link-type="biblio">[HTML]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="be0c27b2">Navigator</span> <li><span class="dfn-paneled" id="5f6d392d">WindowOrWorkerGlobalScope</span> <li><span class="dfn-paneled" id="a4785085">WorkerNavigator</span> <li><span class="dfn-paneled" id="a72449dd">in parallel</span> <li><span class="dfn-paneled" id="9a517a7d">queue a task</span> <li><span class="dfn-paneled" id="e99bd18e">relevant global object</span> </ul> <li> <a data-link-type="biblio">[INFRA]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="53275e46">append</span> <li><span class="dfn-paneled" id="02f9bf93">ascii alpha</span> <li><span class="dfn-paneled" id="617d690e">ascii byte</span> <li><span class="dfn-paneled" id="77b4c09a">assert</span> <li><span class="dfn-paneled" id="e28ccd60">concatenation</span> <li><span class="dfn-paneled" id="ae8def21">contain</span> <li><span class="dfn-paneled" id="dd460c8e">is not empty</span> <li><span class="dfn-paneled" id="5afbefcd">item</span> <li><span class="dfn-paneled" id="649608b9">list</span> <li><span class="dfn-paneled" id="fca74142">pop</span> <li><span class="dfn-paneled" id="7c3de606">push</span> <li><span class="dfn-paneled" id="0204d188">size</span> <li><span class="dfn-paneled" id="a682cc44">split on ascii whitespace</span> <li><span class="dfn-paneled" id="ceacaa1c">stack</span> <li><span class="dfn-paneled" id="7a3dbdb1">strictly split a string</span> <li><span class="dfn-paneled" id="0698d556">string</span> <li><span class="dfn-paneled" id="a37f05fd">strip leading and trailing ascii whitespace</span> <li><span class="dfn-paneled" id="6d19ac93">user agent</span> </ul> <li> <a data-link-type="biblio">[RFC8941]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="6acd627c">boolean</span> <li><span class="dfn-paneled" id="33f5a360">list</span> <li><span class="dfn-paneled" id="25adf95e">serializing a list</span> <li><span class="dfn-paneled" id="e982618f">string</span> <li><span class="dfn-paneled" id="80c33376">structured header</span> </ul> <li> <a data-link-type="biblio">[WEBIDL]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="8855a9aa">DOMString</span> <li><span class="dfn-paneled" id="889e932f">Exposed</span> <li><span class="dfn-paneled" id="dcf5fafa">FrozenArray</span> <li><span class="dfn-paneled" id="ba556545">NotAllowedError</span> <li><span class="dfn-paneled" id="bdbd19d1">Promise</span> <li><span class="dfn-paneled" id="b75bb3bd">SecureContext</span> <li><span class="dfn-paneled" id="dacde8b5">a new promise</span> <li><span class="dfn-paneled" id="5372cca8">boolean</span> <li><span class="dfn-paneled" id="1641b9ef">create a frozen array</span> <li><span class="dfn-paneled" id="bec98d30">dictionary</span> <li><span class="dfn-paneled" id="b262501e">reject</span> <li><span class="dfn-paneled" id="3b90bdcd">resolve</span> <li><span class="dfn-paneled" id="9cce47fd">sequence</span> <li><span class="dfn-paneled" id="4013a022">this</span> </ul> </ul> <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2> <h3 class="no-num no-ref heading settled" id="normative"><span class="content">Normative References</span><a class="self-link" href="#normative"></a></h3> <dl> <dt id="biblio-client-hints-infrastructure">[CLIENT-HINTS-INFRASTRUCTURE] <dd><a href="https://wicg.github.io/client-hints-infrastructure/"><cite>Client Hints Infrastructure</cite></a>. cg-draft. URL: <a href="https://wicg.github.io/client-hints-infrastructure/">https://wicg.github.io/client-hints-infrastructure/</a> <dt id="biblio-compat">[COMPAT] <dd>Mike Taylor. <a href="https://compat.spec.whatwg.org/"><cite>Compatibility Standard</cite></a>. Living Standard. URL: <a href="https://compat.spec.whatwg.org/">https://compat.spec.whatwg.org/</a> <dt id="biblio-html">[HTML] <dd>Anne van Kesteren; et al. <a href="https://html.spec.whatwg.org/multipage/"><cite>HTML Standard</cite></a>. Living Standard. URL: <a href="https://html.spec.whatwg.org/multipage/">https://html.spec.whatwg.org/multipage/</a> <dt id="biblio-infra">[INFRA] <dd>Anne van Kesteren; Domenic Denicola. <a href="https://infra.spec.whatwg.org/"><cite>Infra Standard</cite></a>. Living Standard. URL: <a href="https://infra.spec.whatwg.org/">https://infra.spec.whatwg.org/</a> <dt id="biblio-permissions-policy-1">[PERMISSIONS-POLICY-1] <dd>Ian Clelland. <a href="https://w3c.github.io/webappsec-permissions-policy/"><cite>Permissions Policy</cite></a>. URL: <a href="https://w3c.github.io/webappsec-permissions-policy/">https://w3c.github.io/webappsec-permissions-policy/</a> <dt id="biblio-rfc2119">[RFC2119] <dd>S. Bradner. <a href="https://datatracker.ietf.org/doc/html/rfc2119"><cite>Key words for use in RFCs to Indicate Requirement Levels</cite></a>. March 1997. Best Current Practice. URL: <a href="https://datatracker.ietf.org/doc/html/rfc2119">https://datatracker.ietf.org/doc/html/rfc2119</a> <dt id="biblio-rfc8941">[RFC8941] <dd>M. Nottingham; P-H. Kamp. <a href="https://httpwg.org/specs/rfc8941.html"><cite>Structured Field Values for HTTP</cite></a>. February 2021. Proposed Standard. URL: <a href="https://httpwg.org/specs/rfc8941.html">https://httpwg.org/specs/rfc8941.html</a> <dt id="biblio-rfc8942">[RFC8942] <dd>I. Grigorik; Y. Weiss. <a href="https://www.rfc-editor.org/rfc/rfc8942"><cite>HTTP Client Hints</cite></a>. February 2021. Experimental. URL: <a href="https://www.rfc-editor.org/rfc/rfc8942">https://www.rfc-editor.org/rfc/rfc8942</a> <dt id="biblio-webidl">[WEBIDL] <dd>Edgar Chen; Timothy Gu. <a href="https://webidl.spec.whatwg.org/"><cite>Web IDL Standard</cite></a>. Living Standard. URL: <a href="https://webidl.spec.whatwg.org/">https://webidl.spec.whatwg.org/</a> </dl> <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3> <dl> <dt id="biblio-css-values-4">[CSS-VALUES-4] <dd>Tab Atkins Jr.; Elika Etemad. <a href="https://drafts.csswg.org/css-values-4/"><cite>CSS Values and Units Module Level 4</cite></a>. URL: <a href="https://drafts.csswg.org/css-values-4/">https://drafts.csswg.org/css-values-4/</a> <dt id="biblio-facebookyearclass">[FacebookYearClass] <dd>Chris Marra; Daniel Weaver. <a href="https://engineering.fb.com/android/year-class-a-classification-system-for-android/"><cite>Year class: A classification system for Android</cite></a>. URL: <a href="https://engineering.fb.com/android/year-class-a-classification-system-for-android/">https://engineering.fb.com/android/year-class-a-classification-system-for-android/</a> <dt id="biblio-fingerprinting-guidance">[FINGERPRINTING-GUIDANCE] <dd>Nick Doty. <a href="https://w3c.github.io/fingerprinting-guidance/"><cite>Mitigating Browser Fingerprinting in Web Specifications</cite></a>. URL: <a href="https://w3c.github.io/fingerprinting-guidance/">https://w3c.github.io/fingerprinting-guidance/</a> <dt id="biblio-i-dietf-tls-grease">[I-D.ietf-tls-grease] <dd>David Benjamin. <a href="https://tools.ietf.org/html/draft-ietf-tls-grease"><cite>Applying GREASE to TLS Extensibility</cite></a>. ID. URL: <a href="https://tools.ietf.org/html/draft-ietf-tls-grease">https://tools.ietf.org/html/draft-ietf-tls-grease</a> <dt id="biblio-janc2014">[Janc2014] <dd>Artur Janc; Michal Zalweski. <a href="https://dev.chromium.org/Home/chromium-security/client-identification-mechanisms#TOC-Browser-level-fingerprints"><cite>Technical analysis of client identification mechanisms</cite></a>. URL: <a href="https://dev.chromium.org/Home/chromium-security/client-identification-mechanisms#TOC-Browser-level-fingerprints">https://dev.chromium.org/Home/chromium-security/client-identification-mechanisms#TOC-Browser-level-fingerprints</a> <dt id="biblio-rfc3864">[RFC3864] <dd>G. Klyne; M. Nottingham; J. Mogul. <a href="https://www.rfc-editor.org/rfc/rfc3864"><cite>Registration Procedures for Message Header Fields</cite></a>. September 2004. Best Current Practice. URL: <a href="https://www.rfc-editor.org/rfc/rfc3864">https://www.rfc-editor.org/rfc/rfc3864</a> <dt id="biblio-rfc9110">[RFC9110] <dd>R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. <a href="https://httpwg.org/specs/rfc9110.html"><cite>HTTP Semantics</cite></a>. June 2022. Internet Standard. URL: <a href="https://httpwg.org/specs/rfc9110.html">https://httpwg.org/specs/rfc9110.html</a> <dt id="biblio-rossi2015">[Rossi2015] <dd><a href="https://channel9.msdn.com/Events/WebPlatformSummit/2015/The-Microsoft-Edge-Rendering-Engine-that-makes-the-Web-just-work#time=9m45s"><cite>The Microsoft Edge Rendering Engine that makes the Web just work</cite></a>. URL: <a href="https://channel9.msdn.com/Events/WebPlatformSummit/2015/The-Microsoft-Edge-Rendering-Engine-that-makes-the-Web-just-work#time=9m45s">https://channel9.msdn.com/Events/WebPlatformSummit/2015/The-Microsoft-Edge-Rendering-Engine-that-makes-the-Web-just-work#time=9m45s</a> </dl> <h2 class="no-num no-ref heading settled" id="idl-index"><span class="content">IDL Index</span><a class="self-link" href="#idl-index"></a></h2> <pre class="idl highlight def"><c- b>dictionary</c-> <a href="#dictdef-navigatoruabrandversion"><code><c- g>NavigatorUABrandVersion</c-></code></a> { <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-navigatoruabrandversion-brand"><code><c- g>brand</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-navigatoruabrandversion-version"><code><c- g>version</c-></code></a>; }; <c- b>dictionary</c-> <a href="#dictdef-uadatavalues"><code><c- g>UADataValues</c-></code></a> { <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-uadatavalues-architecture"><code><c- g>architecture</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-uadatavalues-bitness"><code><c- g>bitness</c-></code></a>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion"><c- n>NavigatorUABrandVersion</c-></a>> <a data-type="sequence<NavigatorUABrandVersion> " href="#dom-uadatavalues-brands"><code><c- g>brands</c-></code></a>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence"><c- b>sequence</c-></a><<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a>> <a data-type="sequence<DOMString> " href="#dom-uadatavalues-formfactors"><code><c- g>formFactors</c-></code></a>; <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion"><c- n>NavigatorUABrandVersion</c-></a>> <a data-type="sequence<NavigatorUABrandVersion> " href="#dom-uadatavalues-fullversionlist"><code><c- g>fullVersionList</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-uadatavalues-model"><code><c- g>model</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean"><c- b>boolean</c-></a> <a data-type="boolean " href="#dom-uadatavalues-mobile"><code><c- g>mobile</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-uadatavalues-platform"><code><c- g>platform</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-uadatavalues-platformversion"><code><c- g>platformVersion</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-uadatavalues-uafullversion"><code><c- g>uaFullVersion</c-></code></a>; // deprecated in favor of fullVersionList <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean"><c- b>boolean</c-></a> <a data-type="boolean " href="#dom-uadatavalues-wow64"><code><c- g>wow64</c-></code></a>; }; <c- b>dictionary</c-> <a href="#dictdef-ualowentropyjson"><code><c- g>UALowEntropyJSON</c-></code></a> { <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence"><c- b>sequence</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion"><c- n>NavigatorUABrandVersion</c-></a>> <a data-type="sequence<NavigatorUABrandVersion> " href="#dom-ualowentropyjson-brands"><code><c- g>brands</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean"><c- b>boolean</c-></a> <a data-type="boolean " href="#dom-ualowentropyjson-mobile"><code><c- g>mobile</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-type="DOMString " href="#dom-ualowentropyjson-platform"><code><c- g>platform</c-></code></a>; }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed"><c- g>Exposed</c-></a>=(<c- n>Window</c->,<c- n>Worker</c->)] <c- b>interface</c-> <a href="#navigatoruadata"><code><c- g>NavigatorUAData</c-></code></a> { <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-frozen-array"><c- b>FrozenArray</c-></a><<a data-link-type="idl-name" href="#dictdef-navigatoruabrandversion"><c- n>NavigatorUABrandVersion</c-></a>> <a data-readonly data-type="FrozenArray<NavigatorUABrandVersion>" href="#dom-navigatoruadata-brands"><code><c- g>brands</c-></code></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean"><c- b>boolean</c-></a> <a data-readonly data-type="boolean" href="#dom-navigatoruadata-mobile"><code><c- g>mobile</c-></code></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a data-readonly data-type="DOMString" href="#dom-navigatoruadata-platform"><code><c- g>platform</c-></code></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-promise"><c- b>Promise</c-></a><<a data-link-type="idl-name" href="#dictdef-uadatavalues"><c- n>UADataValues</c-></a>> <a href="#dom-navigatoruadata-gethighentropyvalues"><code><c- g>getHighEntropyValues</c-></code></a>(<a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence"><c- b>sequence</c-></a><<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a>> <a href="#dom-navigatoruadata-gethighentropyvalues-hints-hints"><code><c- g>hints</c-></code></a>); <a data-link-type="idl-name" href="#dictdef-ualowentropyjson"><c- n>UALowEntropyJSON</c-></a> <a href="#dom-navigatoruadata-tojson"><code><c- g>toJSON</c-></code></a>(); }; <c- b>interface</c-> <c- b>mixin</c-> <a href="#navigatorua"><code><c- g>NavigatorUA</c-></code></a> { [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#SecureContext"><c- g>SecureContext</c-></a>] <c- b>readonly</c-> <c- b>attribute</c-> <a data-link-type="idl-name" href="#navigatoruadata"><c- n>NavigatorUAData</c-></a> <a data-readonly data-type="NavigatorUAData" href="#dom-navigatorua-useragentdata"><code><c- g>userAgentData</c-></code></a>; }; <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/system-state.html#navigator"><c- n>Navigator</c-></a> <c- b>includes</c-> <a data-link-type="idl-name" href="#navigatorua"><c- n>NavigatorUA</c-></a>; <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/workers.html#workernavigator"><c- n>WorkerNavigator</c-></a> <c- b>includes</c-> <a data-link-type="idl-name" href="#navigatorua"><c- n>NavigatorUA</c-></a>; </pre> <h2 class="no-num no-ref heading settled" id="issues-index"><span class="content">Issues Index</span><a class="self-link" href="#issues-index"></a></h2> <div style="counter-reset:issue"> <div class="issue"> We can improve upon when and why a UA decides to refuse a hint once <a href="https://github.com/WICG/ua-client-hints/issues/151">Issue #151</a> is resolved. <a class="issue-return" href="#issue-22962aa8" title="Jump to section">↵</a></div> </div> <script>/* Boilerplate: script-dfn-panel */ "use strict"; { const dfnsJson = window.dfnsJson || {}; function genDfnPanel({dfnID, url, dfnText, refSections, external}) { return mk.aside({ class: "dfn-panel", id: `infopanel-for-${dfnID}`, "data-for": dfnID, "aria-labelled-by":`infopaneltitle-for-${dfnID}`, }, mk.span({id:`infopaneltitle-for-${dfnID}`, style:"display:none"}, `Info about the '${dfnText}' ${external?"external":""} reference.`), mk.a({href:url}, url), mk.b({}, "Referenced in:"), mk.ul({}, ...refSections.map(section=> mk.li({}, ...section.refs.map((ref, refI)=> [ mk.a({ href: `#${ref.id}` }, (refI == 0) ? section.title : `(${refI + 1})` ), " ", ] ), ), ), ), ); } function genAllDfnPanels() { for(const panelData of Object.values(window.dfnpanelData)) { const dfnID = panelData.dfnID; const dfn = document.getElementById(dfnID); if(!dfn) { console.log(`Can't find dfn#${dfnID}.`, panelData); } else { const panel = genDfnPanel(panelData); append(document.body, panel); insertDfnPopupAction(dfn, panel) } } } document.addEventListener("DOMContentLoaded", ()=>{ genAllDfnPanels(); // Add popup behavior to all dfns to show the corresponding dfn-panel. var dfns = queryAll('.dfn-paneled'); for(let dfn of dfns) { ; } document.body.addEventListener("click", (e) => { // If not handled already, just hide all dfn panels. hideAllDfnPanels(); }); }) function hideAllDfnPanels() { // Turn off any currently "on" or "activated" panels. queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(el=>hideDfnPanel(el)); } function showDfnPanel(dfnPanel, dfn) { hideAllDfnPanels(); // Only display one at this time. dfn.setAttribute("aria-expanded", "true"); dfnPanel.classList.add("on"); dfnPanel.style.left = "5px"; dfnPanel.style.top = "0px"; const panelRect = dfnPanel.getBoundingClientRect(); const panelWidth = panelRect.right - panelRect.left; if (panelRect.right > document.body.scrollWidth) { // Panel's overflowing the screen. // Just drop it below the dfn and flip it rightward instead. // This still wont' fix things if the screen is *really* wide, // but fixing that's a lot harder without 'anchor()'. dfnPanel.style.top = "1.5em"; dfnPanel.style.left = "auto"; dfnPanel.style.right = "0px"; } } function pinDfnPanel(dfnPanel) { // Switch it to "activated" state, which pins it. dfnPanel.classList.add("activated"); dfnPanel.style.left = null; dfnPanel.style.top = null; } function hideDfnPanel(dfnPanel, dfn) { if(!dfn) { dfn = document.getElementById(dfnPanel.getAttribute("data-for")); } dfn.setAttribute("aria-expanded", "false") dfnPanel.classList.remove("on"); dfnPanel.classList.remove("activated"); } function toggleDfnPanel(dfnPanel, dfn) { if(dfnPanel.classList.contains("on")) { hideDfnPanel(dfnPanel, dfn); } else { showDfnPanel(dfnPanel, dfn); } } function insertDfnPopupAction(dfn, dfnPanel) { // Find dfn panel const panelWrapper = document.createElement('span'); panelWrapper.appendChild(dfnPanel); panelWrapper.style.position = "relative"; panelWrapper.style.height = "0px"; dfn.insertAdjacentElement("afterend", panelWrapper); dfn.setAttribute('role', 'button'); dfn.setAttribute('aria-expanded', 'false') dfn.tabIndex = 0; dfn.classList.add('has-dfn-panel'); dfn.addEventListener('click', (event) => { showDfnPanel(dfnPanel, dfn); event.stopPropagation(); }); dfn.addEventListener('keypress', (event) => { const kc = event.keyCode; // 32->Space, 13->Enter if(kc == 32 || kc == 13) { toggleDfnPanel(dfnPanel, dfn); event.stopPropagation(); event.preventDefault(); } }); dfnPanel.addEventListener('click', (event) => { if (event.target.nodeName == 'A') { pinDfnPanel(dfnPanel); } event.stopPropagation(); }); dfnPanel.addEventListener('keydown', (event) => { if(event.keyCode == 27) { // Escape key hideDfnPanel(dfnPanel, dfn); event.stopPropagation(); event.preventDefault(); } }) } } </script> <script>/* Boilerplate: script-dfn-panel */ "use strict"; { const dfnsJson = window.dfnsJson || {}; function genDfnPanel({dfnID, url, dfnText, refSections, external}) { return mk.aside({ class: "dfn-panel", id: `infopanel-for-${dfnID}`, "data-for": dfnID, "aria-labelled-by":`infopaneltitle-for-${dfnID}`, }, mk.span({id:`infopaneltitle-for-${dfnID}`, style:"display:none"}, `Info about the '${dfnText}' ${external?"external":""} reference.`), mk.a({href:url}, url), mk.b({}, "Referenced in:"), mk.ul({}, ...refSections.map(section=> mk.li({}, ...section.refs.map((ref, refI)=> [ mk.a({ href: `#${ref.id}` }, (refI == 0) ? section.title : `(${refI + 1})` ), " ", ] ), ), ), ), ); } function genAllDfnPanels() { for(const panelData of Object.values(window.dfnpanelData)) { const dfnID = panelData.dfnID; const dfn = document.getElementById(dfnID); if(!dfn) { console.log(`Can't find dfn#${dfnID}.`, panelData); } else { const panel = genDfnPanel(panelData); append(document.body, panel); insertDfnPopupAction(dfn, panel) } } } document.addEventListener("DOMContentLoaded", ()=>{ genAllDfnPanels(); // Add popup behavior to all dfns to show the corresponding dfn-panel. var dfns = queryAll('.dfn-paneled'); for(let dfn of dfns) { ; } document.body.addEventListener("click", (e) => { // If not handled already, just hide all dfn panels. hideAllDfnPanels(); }); }) function hideAllDfnPanels() { // Turn off any currently "on" or "activated" panels. queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(el=>hideDfnPanel(el)); } function showDfnPanel(dfnPanel, dfn) { hideAllDfnPanels(); // Only display one at this time. dfn.setAttribute("aria-expanded", "true"); dfnPanel.classList.add("on"); dfnPanel.style.left = "5px"; dfnPanel.style.top = "0px"; const panelRect = dfnPanel.getBoundingClientRect(); const panelWidth = panelRect.right - panelRect.left; if (panelRect.right > document.body.scrollWidth) { // Panel's overflowing the screen. // Just drop it below the dfn and flip it rightward instead. // This still wont' fix things if the screen is *really* wide, // but fixing that's a lot harder without 'anchor()'. dfnPanel.style.top = "1.5em"; dfnPanel.style.left = "auto"; dfnPanel.style.right = "0px"; } } function pinDfnPanel(dfnPanel) { // Switch it to "activated" state, which pins it. dfnPanel.classList.add("activated"); dfnPanel.style.left = null; dfnPanel.style.top = null; } function hideDfnPanel(dfnPanel, dfn) { if(!dfn) { dfn = document.getElementById(dfnPanel.getAttribute("data-for")); } dfn.setAttribute("aria-expanded", "false") dfnPanel.classList.remove("on"); dfnPanel.classList.remove("activated"); } function toggleDfnPanel(dfnPanel, dfn) { if(dfnPanel.classList.contains("on")) { hideDfnPanel(dfnPanel, dfn); } else { showDfnPanel(dfnPanel, dfn); } } function insertDfnPopupAction(dfn, dfnPanel) { // Find dfn panel const panelWrapper = document.createElement('span'); panelWrapper.appendChild(dfnPanel); panelWrapper.style.position = "relative"; panelWrapper.style.height = "0px"; dfn.insertAdjacentElement("afterend", panelWrapper); dfn.setAttribute('role', 'button'); dfn.setAttribute('aria-expanded', 'false') dfn.tabIndex = 0; dfn.classList.add('has-dfn-panel'); dfn.addEventListener('click', (event) => { showDfnPanel(dfnPanel, dfn); event.stopPropagation(); }); dfn.addEventListener('keypress', (event) => { const kc = event.keyCode; // 32->Space, 13->Enter if(kc == 32 || kc == 13) { toggleDfnPanel(dfnPanel, dfn); event.stopPropagation(); event.preventDefault(); } }); dfnPanel.addEventListener('click', (event) => { if (event.target.nodeName == 'A') { pinDfnPanel(dfnPanel); } event.stopPropagation(); }); dfnPanel.addEventListener('keydown', (event) => { if(event.keyCode == 27) { // Escape key hideDfnPanel(dfnPanel, dfn); event.stopPropagation(); event.preventDefault(); } }) } } </script> <script>/* Boilerplate: script-dfn-panel-json */ window.dfnpanelData = {}; window.dfnpanelData['15edd6b4'] = {"dfnID": "15edd6b4", "url": "https://w3c.github.io/fingerprinting-guidance/#dfn-active-fingerprinting", "dfnText": "active fingerprinting", "refSections": [{"refs": [{"id": "ref-for-dfn-active-fingerprinting"}, {"id": "ref-for-dfn-active-fingerprinting\u2460"}], "title": "5.3. Fingerprinting"}], "external": true}; window.dfnpanelData['bc612dfe'] = {"dfnID": "bc612dfe", "url": "https://w3c.github.io/fingerprinting-guidance/#avoid-passive-increases", "dfnText": "best practice 1", "refSections": [{"refs": [{"id": "ref-for-avoid-passive-increases"}], "title": "1. Introduction"}], "external": true}; window.dfnpanelData['3aec4bbc'] = {"dfnID": "3aec4bbc", "url": "https://tc39.es/ecma262/#current-realm", "dfnText": "current realm", "refSections": [{"refs": [{"id": "ref-for-current-realm"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['c9898e54'] = {"dfnID": "c9898e54", "url": "https://w3c.github.io/fingerprinting-guidance/#dfn-passive-fingerprinting", "dfnText": "passive fingerprinting", "refSections": [{"refs": [{"id": "ref-for-dfn-passive-fingerprinting"}], "title": "Unnumbered Section"}, {"refs": [{"id": "ref-for-dfn-passive-fingerprinting\u2460"}], "title": "1. Introduction"}, {"refs": [{"id": "ref-for-dfn-passive-fingerprinting\u2461"}], "title": "5.2. Delegation"}, {"refs": [{"id": "ref-for-dfn-passive-fingerprinting\u2462"}], "title": "5.3. Fingerprinting"}], "external": true}; window.dfnpanelData['0407598e'] = {"dfnID": "0407598e", "url": "https://w3c.github.io/permissions/#dfn-permissions-task-source", "dfnText": "permission task source", "refSections": [{"refs": [{"id": "ref-for-dfn-permissions-task-source"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['6360ebfe'] = {"dfnID": "6360ebfe", "url": "https://wicg.github.io/client-hints-infrastructure/#abstract-opdef-append-client-hints-to-request", "dfnText": "append client hints to request", "refSections": [{"refs": [{"id": "ref-for-abstract-opdef-append-client-hints-to-request"}], "title": "5.2. Delegation"}], "external": true}; window.dfnpanelData['ea0ecaa0'] = {"dfnID": "ea0ecaa0", "url": "https://wicg.github.io/client-hints-infrastructure/#client-hints-token", "dfnText": "client hints token", "refSections": [{"refs": [{"id": "ref-for-client-hints-token"}], "title": "3.11. The 'Sec-CH-UA-WoW64' Header Field"}], "external": true}; window.dfnpanelData['c7a20f42'] = {"dfnID": "c7a20f42", "url": "https://wicg.github.io/client-hints-infrastructure/#low-entropy-hint-table", "dfnText": "low entropy hint table", "refSections": [{"refs": [{"id": "ref-for-low-entropy-hint-table"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-low-entropy-hint-table\u2460"}], "title": "3.7. The 'Sec-CH-UA-Mobile' Header Field"}, {"refs": [{"id": "ref-for-low-entropy-hint-table\u2461"}], "title": "3.9. The 'Sec-CH-UA-Platform' Header Field"}], "external": true}; window.dfnpanelData['f391224b'] = {"dfnID": "f391224b", "url": "https://wicg.github.io/client-hints-infrastructure/#policy-controlled-client-hints-features", "dfnText": "policy-controlled client hints features", "refSections": [{"refs": [{"id": "ref-for-policy-controlled-client-hints-features"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-policy-controlled-client-hints-features\u2460"}], "title": "3.7. The 'Sec-CH-UA-Mobile' Header Field"}, {"refs": [{"id": "ref-for-policy-controlled-client-hints-features\u2461"}], "title": "3.9. The 'Sec-CH-UA-Platform' Header Field"}], "external": true}; window.dfnpanelData['966ed8e9'] = {"dfnID": "966ed8e9", "url": "https://compat.spec.whatwg.org/#devicecompat", "dfnText": "devicecompat", "refSections": [{"refs": [{"id": "ref-for-devicecompat"}], "title": "3. User Agent Hints"}], "external": true}; window.dfnpanelData['be0c27b2'] = {"dfnID": "be0c27b2", "url": "https://html.spec.whatwg.org/multipage/system-state.html#navigator", "dfnText": "Navigator", "refSections": [{"refs": [{"id": "ref-for-navigator"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['5f6d392d'] = {"dfnID": "5f6d392d", "url": "https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope", "dfnText": "WindowOrWorkerGlobalScope", "refSections": [{"refs": [{"id": "ref-for-windoworworkerglobalscope"}, {"id": "ref-for-windoworworkerglobalscope\u2460"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}], "external": true}; window.dfnpanelData['a4785085'] = {"dfnID": "a4785085", "url": "https://html.spec.whatwg.org/multipage/workers.html#workernavigator", "dfnText": "WorkerNavigator", "refSections": [{"refs": [{"id": "ref-for-workernavigator"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['a72449dd'] = {"dfnID": "a72449dd", "url": "https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel", "dfnText": "in parallel", "refSections": [{"refs": [{"id": "ref-for-in-parallel"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['9a517a7d'] = {"dfnID": "9a517a7d", "url": "https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task", "dfnText": "queue a task", "refSections": [{"refs": [{"id": "ref-for-queue-a-task"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['e99bd18e'] = {"dfnID": "e99bd18e", "url": "https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-global", "dfnText": "relevant global object", "refSections": [{"refs": [{"id": "ref-for-concept-relevant-global"}], "title": "4.1.5. Getters"}, {"refs": [{"id": "ref-for-concept-relevant-global\u2460"}, {"id": "ref-for-concept-relevant-global\u2461"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-concept-relevant-global\u2462"}], "title": "4.1.7. toJSON method"}], "external": true}; window.dfnpanelData['53275e46'] = {"dfnID": "53275e46", "url": "https://infra.spec.whatwg.org/#list-append", "dfnText": "append", "refSections": [{"refs": [{"id": "ref-for-list-append"}, {"id": "ref-for-list-append\u2460"}, {"id": "ref-for-list-append\u2461"}, {"id": "ref-for-list-append\u2462"}, {"id": "ref-for-list-append\u2463"}, {"id": "ref-for-list-append\u2464"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-list-append\u2465"}, {"id": "ref-for-list-append\u2466"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-list-append\u2467"}, {"id": "ref-for-list-append\u2468"}, {"id": "ref-for-list-append\u2460\u24ea"}], "title": "4.1.3. Create arbitrary brand and version values"}, {"refs": [{"id": "ref-for-list-append\u2460\u2460"}], "title": "4.1.4. Create a brand-version list"}], "external": true}; window.dfnpanelData['02f9bf93'] = {"dfnID": "02f9bf93", "url": "https://infra.spec.whatwg.org/#ascii-alpha", "dfnText": "ascii alpha", "refSections": [{"refs": [{"id": "ref-for-ascii-alpha"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-ascii-alpha\u2460"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['617d690e'] = {"dfnID": "617d690e", "url": "https://infra.spec.whatwg.org/#ascii-byte", "dfnText": "ascii byte", "refSections": [{"refs": [{"id": "ref-for-ascii-byte"}, {"id": "ref-for-ascii-byte\u2460"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['77b4c09a'] = {"dfnID": "77b4c09a", "url": "https://infra.spec.whatwg.org/#assert", "dfnText": "assert", "refSections": [{"refs": [{"id": "ref-for-assert"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-assert\u2460"}], "title": "4.1.3. Create arbitrary brand and version values"}, {"refs": [{"id": "ref-for-assert\u2461"}], "title": "4.1.4. Create a brand-version list"}], "external": true}; window.dfnpanelData['e28ccd60'] = {"dfnID": "e28ccd60", "url": "https://infra.spec.whatwg.org/#string-concatenate", "dfnText": "concatenation", "refSections": [{"refs": [{"id": "ref-for-string-concatenate"}, {"id": "ref-for-string-concatenate\u2460"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-string-concatenate\u2461"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['ae8def21'] = {"dfnID": "ae8def21", "url": "https://infra.spec.whatwg.org/#list-contain", "dfnText": "contain", "refSections": [{"refs": [{"id": "ref-for-list-contain"}, {"id": "ref-for-list-contain\u2460"}, {"id": "ref-for-list-contain\u2461"}, {"id": "ref-for-list-contain\u2462"}, {"id": "ref-for-list-contain\u2463"}, {"id": "ref-for-list-contain\u2464"}, {"id": "ref-for-list-contain\u2465"}, {"id": "ref-for-list-contain\u2466"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['dd460c8e'] = {"dfnID": "dd460c8e", "url": "https://infra.spec.whatwg.org/#list-is-empty", "dfnText": "is not empty", "refSections": [{"refs": [{"id": "ref-for-list-is-empty"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['5afbefcd'] = {"dfnID": "5afbefcd", "url": "https://infra.spec.whatwg.org/#list-item", "dfnText": "item", "refSections": [{"refs": [{"id": "ref-for-list-item"}, {"id": "ref-for-list-item\u2460"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-list-item\u2461"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['649608b9'] = {"dfnID": "649608b9", "url": "https://infra.spec.whatwg.org/#list", "dfnText": "list", "refSections": [{"refs": [{"id": "ref-for-list"}, {"id": "ref-for-list\u2460"}, {"id": "ref-for-list\u2461"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-list\u2462"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}, {"refs": [{"id": "ref-for-list\u2463"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-list\u2464"}, {"id": "ref-for-list\u2465"}], "title": "4.1.3. Create arbitrary brand and version values"}, {"refs": [{"id": "ref-for-list\u2466"}], "title": "4.1.4. Create a brand-version list"}], "external": true}; window.dfnpanelData['fca74142'] = {"dfnID": "fca74142", "url": "https://infra.spec.whatwg.org/#stack-pop", "dfnText": "pop", "refSections": [{"refs": [{"id": "ref-for-stack-pop"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['7c3de606'] = {"dfnID": "7c3de606", "url": "https://infra.spec.whatwg.org/#stack-push", "dfnText": "push", "refSections": [{"refs": [{"id": "ref-for-stack-push"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['0204d188'] = {"dfnID": "0204d188", "url": "https://infra.spec.whatwg.org/#list-size", "dfnText": "size", "refSections": [{"refs": [{"id": "ref-for-list-size"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['a682cc44'] = {"dfnID": "a682cc44", "url": "https://infra.spec.whatwg.org/#split-on-ascii-whitespace", "dfnText": "split on ascii whitespace", "refSections": [{"refs": [{"id": "ref-for-split-on-ascii-whitespace"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['ceacaa1c'] = {"dfnID": "ceacaa1c", "url": "https://infra.spec.whatwg.org/#stack", "dfnText": "stack", "refSections": [{"refs": [{"id": "ref-for-stack"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['7a3dbdb1'] = {"dfnID": "7a3dbdb1", "url": "https://infra.spec.whatwg.org/#strictly-split", "dfnText": "strictly split a string", "refSections": [{"refs": [{"id": "ref-for-strictly-split"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}], "external": true}; window.dfnpanelData['0698d556'] = {"dfnID": "0698d556", "url": "https://infra.spec.whatwg.org/#string", "dfnText": "string", "refSections": [{"refs": [{"id": "ref-for-string"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-string\u2460"}, {"id": "ref-for-string\u2461"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['a37f05fd'] = {"dfnID": "a37f05fd", "url": "https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace", "dfnText": "strip leading and trailing ascii whitespace", "refSections": [{"refs": [{"id": "ref-for-strip-leading-and-trailing-ascii-whitespace"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['6d19ac93'] = {"dfnID": "6d19ac93", "url": "https://infra.spec.whatwg.org/#user-agent", "dfnText": "user agent", "refSections": [{"refs": [{"id": "ref-for-user-agent"}, {"id": "ref-for-user-agent\u2460"}, {"id": "ref-for-user-agent\u2461"}, {"id": "ref-for-user-agent\u2462"}, {"id": "ref-for-user-agent\u2463"}, {"id": "ref-for-user-agent\u2464"}, {"id": "ref-for-user-agent\u2465"}, {"id": "ref-for-user-agent\u2466"}, {"id": "ref-for-user-agent\u2467"}, {"id": "ref-for-user-agent\u2468"}, {"id": "ref-for-user-agent\u2460\u24ea"}, {"id": "ref-for-user-agent\u2460\u2460"}, {"id": "ref-for-user-agent\u2460\u2461"}, {"id": "ref-for-user-agent\u2460\u2462"}, {"id": "ref-for-user-agent\u2460\u2463"}, {"id": "ref-for-user-agent\u2460\u2464"}, {"id": "ref-for-user-agent\u2460\u2465"}, {"id": "ref-for-user-agent\u2460\u2466"}, {"id": "ref-for-user-agent\u2460\u2467"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent\u2460\u2468"}, {"id": "ref-for-user-agent\u2461\u24ea"}, {"id": "ref-for-user-agent\u2461\u2460"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2461"}], "title": "3.2. The 'Sec-CH-UA-Arch' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2462"}], "title": "3.3. The 'Sec-CH-UA-Bitness' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2463"}], "title": "3.4. The 'Sec-CH-UA-Form-Factors' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2464"}], "title": "3.7. The 'Sec-CH-UA-Mobile' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2465"}], "title": "3.8. The 'Sec-CH-UA-Model' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2466"}], "title": "3.9. The 'Sec-CH-UA-Platform' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2467"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2461\u2468"}], "title": "3.11. The 'Sec-CH-UA-WoW64' Header Field"}, {"refs": [{"id": "ref-for-user-agent\u2462\u24ea"}], "title": "4. Interface"}, {"refs": [{"id": "ref-for-user-agent\u2462\u2460"}, {"id": "ref-for-user-agent\u2462\u2461"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}, {"refs": [{"id": "ref-for-user-agent\u2462\u2462"}, {"id": "ref-for-user-agent\u2462\u2463"}, {"id": "ref-for-user-agent\u2462\u2464"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-user-agent\u2462\u2465"}], "title": "4.1.3. Create arbitrary brand and version values"}, {"refs": [{"id": "ref-for-user-agent\u2462\u2466"}, {"id": "ref-for-user-agent\u2462\u2467"}], "title": "4.1.5. Getters"}, {"refs": [{"id": "ref-for-user-agent\u2462\u2468"}, {"id": "ref-for-user-agent\u2463\u24ea"}, {"id": "ref-for-user-agent\u2463\u2460"}, {"id": "ref-for-user-agent\u2463\u2461"}, {"id": "ref-for-user-agent\u2463\u2462"}, {"id": "ref-for-user-agent\u2463\u2463"}, {"id": "ref-for-user-agent\u2463\u2464"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-user-agent\u2463\u2465"}, {"id": "ref-for-user-agent\u2463\u2466"}], "title": "4.1.7. toJSON method"}, {"refs": [{"id": "ref-for-user-agent\u2463\u2467"}], "title": "5.1. Secure Transport"}, {"refs": [{"id": "ref-for-user-agent\u2463\u2468"}], "title": "5.2. Delegation"}, {"refs": [{"id": "ref-for-user-agent\u2464\u24ea"}, {"id": "ref-for-user-agent\u2464\u2460"}, {"id": "ref-for-user-agent\u2464\u2461"}, {"id": "ref-for-user-agent\u2464\u2462"}], "title": "5.3. Fingerprinting"}, {"refs": [{"id": "ref-for-user-agent\u2464\u2463"}, {"id": "ref-for-user-agent\u2464\u2464"}], "title": "5.4. Access Restrictions"}, {"refs": [{"id": "ref-for-user-agent\u2464\u2465"}, {"id": "ref-for-user-agent\u2464\u2466"}], "title": "6.1. The 'User-Agent' Header"}, {"refs": [{"id": "ref-for-user-agent\u2464\u2467"}, {"id": "ref-for-user-agent\u2464\u2468"}, {"id": "ref-for-user-agent\u2465\u24ea"}, {"id": "ref-for-user-agent\u2465\u2460"}, {"id": "ref-for-user-agent\u2465\u2461"}, {"id": "ref-for-user-agent\u2465\u2462"}], "title": "6.2. GREASE-like UA Brand Lists"}], "external": true}; window.dfnpanelData['6acd627c'] = {"dfnID": "6acd627c", "url": "https://tools.ietf.org/html/rfc8941#section-3.3.6", "dfnText": "boolean", "refSections": [{"refs": [{"id": "ref-for-section-3.3.6"}], "title": "3.7. The 'Sec-CH-UA-Mobile' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.6\u2460"}], "title": "3.11. The 'Sec-CH-UA-WoW64' Header Field"}], "external": true}; window.dfnpanelData['33f5a360'] = {"dfnID": "33f5a360", "url": "https://tools.ietf.org/html/rfc8941#section-3.1", "dfnText": "list", "refSections": [{"refs": [{"id": "ref-for-section-3.1"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-section-3.1\u2460"}], "title": "3.4. The 'Sec-CH-UA-Form-Factors' Header Field"}, {"refs": [{"id": "ref-for-section-3.1\u2461"}], "title": "3.6. The 'Sec-CH-UA-Full-Version-List' Header Field"}], "external": true}; window.dfnpanelData['25adf95e'] = {"dfnID": "25adf95e", "url": "https://tools.ietf.org/html/rfc8941#section-4.1.1", "dfnText": "serializing a list", "refSections": [{"refs": [{"id": "ref-for-section-4.1.1"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-section-4.1.1\u2460"}], "title": "3.6. The 'Sec-CH-UA-Full-Version-List' Header Field"}], "external": true}; window.dfnpanelData['e982618f'] = {"dfnID": "e982618f", "url": "https://tools.ietf.org/html/rfc8941#section-3.3.3", "dfnText": "string", "refSections": [{"refs": [{"id": "ref-for-section-3.3.3"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.3\u2460"}], "title": "3.2. The 'Sec-CH-UA-Arch' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.3\u2461"}], "title": "3.3. The 'Sec-CH-UA-Bitness' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.3\u2462"}], "title": "3.5. The 'Sec-CH-UA-Full-Version' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.3\u2463"}], "title": "3.8. The 'Sec-CH-UA-Model' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.3\u2464"}], "title": "3.9. The 'Sec-CH-UA-Platform' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.3\u2465"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-section-3.3.3\u2466"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['80c33376'] = {"dfnID": "80c33376", "url": "https://tools.ietf.org/html/rfc8941#", "dfnText": "structured header", "refSections": [{"refs": [{"id": "ref-for-something"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-something\u2460"}], "title": "3.2. The 'Sec-CH-UA-Arch' Header Field"}, {"refs": [{"id": "ref-for-something\u2461"}], "title": "3.3. The 'Sec-CH-UA-Bitness' Header Field"}, {"refs": [{"id": "ref-for-something\u2462"}], "title": "3.4. The 'Sec-CH-UA-Form-Factors' Header Field"}, {"refs": [{"id": "ref-for-something\u2463"}], "title": "3.5. The 'Sec-CH-UA-Full-Version' Header Field"}, {"refs": [{"id": "ref-for-something\u2464"}], "title": "3.6. The 'Sec-CH-UA-Full-Version-List' Header Field"}, {"refs": [{"id": "ref-for-something\u2465"}], "title": "3.7. The 'Sec-CH-UA-Mobile' Header Field"}, {"refs": [{"id": "ref-for-something\u2466"}], "title": "3.8. The 'Sec-CH-UA-Model' Header Field"}, {"refs": [{"id": "ref-for-something\u2467"}], "title": "3.9. The 'Sec-CH-UA-Platform' Header Field"}, {"refs": [{"id": "ref-for-something\u2468"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-something\u2460\u24ea"}], "title": "3.11. The 'Sec-CH-UA-WoW64' Header Field"}, {"refs": [{"id": "ref-for-something\u2460\u2460"}], "title": "4.1.3. Create arbitrary brand and version values"}], "external": true}; window.dfnpanelData['8855a9aa'] = {"dfnID": "8855a9aa", "url": "https://webidl.spec.whatwg.org/#idl-DOMString", "dfnText": "DOMString", "refSections": [{"refs": [{"id": "ref-for-idl-DOMString"}, {"id": "ref-for-idl-DOMString\u2460"}, {"id": "ref-for-idl-DOMString\u2461"}, {"id": "ref-for-idl-DOMString\u2462"}, {"id": "ref-for-idl-DOMString\u2463"}, {"id": "ref-for-idl-DOMString\u2464"}, {"id": "ref-for-idl-DOMString\u2465"}, {"id": "ref-for-idl-DOMString\u2466"}, {"id": "ref-for-idl-DOMString\u2467"}, {"id": "ref-for-idl-DOMString\u2468"}, {"id": "ref-for-idl-DOMString\u2460\u24ea"}, {"id": "ref-for-idl-DOMString\u2460\u2460"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['889e932f'] = {"dfnID": "889e932f", "url": "https://webidl.spec.whatwg.org/#Exposed", "dfnText": "Exposed", "refSections": [{"refs": [{"id": "ref-for-Exposed"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['dcf5fafa'] = {"dfnID": "dcf5fafa", "url": "https://webidl.spec.whatwg.org/#idl-frozen-array", "dfnText": "FrozenArray", "refSections": [{"refs": [{"id": "ref-for-idl-frozen-array"}], "title": "4. Interface"}, {"refs": [{"id": "ref-for-idl-frozen-array\u2460"}, {"id": "ref-for-idl-frozen-array\u2461"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}], "external": true}; window.dfnpanelData['ba556545'] = {"dfnID": "ba556545", "url": "https://webidl.spec.whatwg.org/#notallowederror", "dfnText": "NotAllowedError", "refSections": [{"refs": [{"id": "ref-for-notallowederror"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['bdbd19d1'] = {"dfnID": "bdbd19d1", "url": "https://webidl.spec.whatwg.org/#idl-promise", "dfnText": "Promise", "refSections": [{"refs": [{"id": "ref-for-idl-promise"}, {"id": "ref-for-idl-promise\u2460"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['b75bb3bd'] = {"dfnID": "b75bb3bd", "url": "https://webidl.spec.whatwg.org/#SecureContext", "dfnText": "SecureContext", "refSections": [{"refs": [{"id": "ref-for-SecureContext"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['dacde8b5'] = {"dfnID": "dacde8b5", "url": "https://webidl.spec.whatwg.org/#a-new-promise", "dfnText": "a new promise", "refSections": [{"refs": [{"id": "ref-for-a-new-promise"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['5372cca8'] = {"dfnID": "5372cca8", "url": "https://webidl.spec.whatwg.org/#idl-boolean", "dfnText": "boolean", "refSections": [{"refs": [{"id": "ref-for-idl-boolean"}, {"id": "ref-for-idl-boolean\u2460"}, {"id": "ref-for-idl-boolean\u2461"}, {"id": "ref-for-idl-boolean\u2462"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['1641b9ef'] = {"dfnID": "1641b9ef", "url": "https://webidl.spec.whatwg.org/#dfn-create-frozen-array", "dfnText": "create a frozen array", "refSections": [{"refs": [{"id": "ref-for-dfn-create-frozen-array"}, {"id": "ref-for-dfn-create-frozen-array\u2460"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}], "external": true}; window.dfnpanelData['bec98d30'] = {"dfnID": "bec98d30", "url": "https://webidl.spec.whatwg.org/#dfn-dictionary", "dfnText": "dictionary", "refSections": [{"refs": [{"id": "ref-for-dfn-dictionary"}], "title": "4.1.4. Create a brand-version list"}], "external": true}; window.dfnpanelData['b262501e'] = {"dfnID": "b262501e", "url": "https://webidl.spec.whatwg.org/#reject", "dfnText": "reject", "refSections": [{"refs": [{"id": "ref-for-reject"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['3b90bdcd'] = {"dfnID": "3b90bdcd", "url": "https://webidl.spec.whatwg.org/#resolve", "dfnText": "resolve", "refSections": [{"refs": [{"id": "ref-for-resolve"}], "title": "4.1.6. getHighEntropyValues method"}], "external": true}; window.dfnpanelData['9cce47fd'] = {"dfnID": "9cce47fd", "url": "https://webidl.spec.whatwg.org/#idl-sequence", "dfnText": "sequence", "refSections": [{"refs": [{"id": "ref-for-idl-sequence"}, {"id": "ref-for-idl-sequence\u2460"}, {"id": "ref-for-idl-sequence\u2461"}, {"id": "ref-for-idl-sequence\u2462"}, {"id": "ref-for-idl-sequence\u2463"}], "title": "4. Interface"}], "external": true}; window.dfnpanelData['4013a022'] = {"dfnID": "4013a022", "url": "https://webidl.spec.whatwg.org/#this", "dfnText": "this", "refSections": [{"refs": [{"id": "ref-for-this"}], "title": "4.1.5. Getters"}, {"refs": [{"id": "ref-for-this\u2460"}, {"id": "ref-for-this\u2461"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-this\u2462"}], "title": "4.1.7. toJSON method"}], "external": true}; window.dfnpanelData['user-agent-brand'] = {"dfnID": "user-agent-brand", "url": "#user-agent-brand", "dfnText": "brand", "refSections": [{"refs": [{"id": "ref-for-user-agent-brand"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-user-agent-brand\u2460"}], "title": "4.1.2. Create brands"}], "external": false}; window.dfnpanelData['user-agent-form-factors'] = {"dfnID": "user-agent-form-factors", "url": "#user-agent-form-factors", "dfnText": "form-factors", "refSections": [{"refs": [{"id": "ref-for-user-agent-form-factors"}], "title": "3.4. The 'Sec-CH-UA-Form-Factors' Header Field"}, {"refs": [{"id": "ref-for-user-agent-form-factors\u2460"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['user-agent-full-version'] = {"dfnID": "user-agent-full-version", "url": "#user-agent-full-version", "dfnText": "full version", "refSections": [{"refs": [{"id": "ref-for-user-agent-full-version"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-full-version\u2460"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-user-agent-full-version\u2461"}], "title": "3.5. The 'Sec-CH-UA-Full-Version' Header Field"}, {"refs": [{"id": "ref-for-user-agent-full-version\u2462"}], "title": "3.6. The 'Sec-CH-UA-Full-Version-List' Header Field"}, {"refs": [{"id": "ref-for-user-agent-full-version\u2463"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}, {"refs": [{"id": "ref-for-user-agent-full-version\u2464"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-user-agent-full-version\u2465"}], "title": "4.1.3. Create arbitrary brand and version values"}, {"refs": [{"id": "ref-for-user-agent-full-version\u2466"}], "title": "4.1.4. Create a brand-version list"}], "external": false}; window.dfnpanelData['user-agent-model'] = {"dfnID": "user-agent-model", "url": "#user-agent-model", "dfnText": "model", "refSections": [{"refs": [{"id": "ref-for-user-agent-model"}, {"id": "ref-for-user-agent-model\u2460"}, {"id": "ref-for-user-agent-model\u2461"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-model\u2462"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['user-agent-mobileness'] = {"dfnID": "user-agent-mobileness", "url": "#user-agent-mobileness", "dfnText": "mobileness", "refSections": [{"refs": [{"id": "ref-for-user-agent-mobileness"}, {"id": "ref-for-user-agent-mobileness\u2460"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-mobileness\u2461"}], "title": "4.1.5. Getters"}, {"refs": [{"id": "ref-for-user-agent-mobileness\u2462"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-user-agent-mobileness\u2463"}], "title": "4.1.7. toJSON method"}], "external": false}; window.dfnpanelData['user-agent-platform-brand'] = {"dfnID": "user-agent-platform-brand", "url": "#user-agent-platform-brand", "dfnText": "platform brand", "refSections": [{"refs": [{"id": "ref-for-user-agent-platform-brand"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-user-agent-platform-brand\u2460"}], "title": "4.1.5. Getters"}, {"refs": [{"id": "ref-for-user-agent-platform-brand\u2461"}, {"id": "ref-for-user-agent-platform-brand\u2462"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-user-agent-platform-brand\u2463"}], "title": "4.1.7. toJSON method"}], "external": false}; window.dfnpanelData['user-agent-platform-version'] = {"dfnID": "user-agent-platform-version", "url": "#user-agent-platform-version", "dfnText": "platform version", "refSections": [{"refs": [{"id": "ref-for-user-agent-platform-version"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}], "external": false}; window.dfnpanelData['user-agent-platform-architecture'] = {"dfnID": "user-agent-platform-architecture", "url": "#user-agent-platform-architecture", "dfnText": "platform architecture", "refSections": [{"refs": [{"id": "ref-for-user-agent-platform-architecture"}, {"id": "ref-for-user-agent-platform-architecture\u2460"}, {"id": "ref-for-user-agent-platform-architecture\u2461"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-platform-architecture\u2462"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-user-agent-platform-architecture\u2463"}], "title": "5.4. Access Restrictions"}], "external": false}; window.dfnpanelData['user-agent-platform-bitness'] = {"dfnID": "user-agent-platform-bitness", "url": "#user-agent-platform-bitness", "dfnText": "platform bitness", "refSections": [{"refs": [{"id": "ref-for-user-agent-platform-bitness"}, {"id": "ref-for-user-agent-platform-bitness\u2460"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-platform-bitness\u2461"}], "title": "3.3. The 'Sec-CH-UA-Bitness' Header Field"}, {"refs": [{"id": "ref-for-user-agent-platform-bitness\u2462"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-user-agent-platform-bitness\u2463"}], "title": "5.4. Access Restrictions"}], "external": false}; window.dfnpanelData['user-agent-significant-version'] = {"dfnID": "user-agent-significant-version", "url": "#user-agent-significant-version", "dfnText": "significant version", "refSections": [{"refs": [{"id": "ref-for-user-agent-significant-version"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-user-agent-significant-version\u2460"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}, {"refs": [{"id": "ref-for-user-agent-significant-version\u2461"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-user-agent-significant-version\u2462"}], "title": "4.1.3. Create arbitrary brand and version values"}, {"refs": [{"id": "ref-for-user-agent-significant-version\u2463"}], "title": "4.1.4. Create a brand-version list"}], "external": false}; window.dfnpanelData['user-agent-wow64-ness'] = {"dfnID": "user-agent-wow64-ness", "url": "#user-agent-wow64-ness", "dfnText": "wow64-ness", "refSections": [{"refs": [{"id": "ref-for-user-agent-wow64-ness"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-wow64-ness\u2460"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['http-headerdef-sec-ch-ua'] = {"dfnID": "http-headerdef-sec-ch-ua", "url": "#http-headerdef-sec-ch-ua", "dfnText": "Sec-CH-UA", "refSections": [{"refs": [{"id": "ref-for-http-headerdef-sec-ch-ua"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}], "external": false}; window.dfnpanelData['http-headerdef-sec-ch-ua-full-version-list'] = {"dfnID": "http-headerdef-sec-ch-ua-full-version-list", "url": "#http-headerdef-sec-ch-ua-full-version-list", "dfnText": "Sec-CH-UA-Full-Version-List", "refSections": [{"refs": [{"id": "ref-for-http-headerdef-sec-ch-ua-full-version-list"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}], "external": false}; window.dfnpanelData['get-the-platform-version'] = {"dfnID": "get-the-platform-version", "url": "#get-the-platform-version", "dfnText": "get the platform version", "refSections": [{"refs": [{"id": "ref-for-get-the-platform-version"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}, {"refs": [{"id": "ref-for-get-the-platform-version\u2460"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['get-the-legacy-windows-version-number'] = {"dfnID": "get-the-legacy-windows-version-number", "url": "#get-the-legacy-windows-version-number", "dfnText": "get the legacy Windows version number", "refSections": [{"refs": [{"id": "ref-for-get-the-legacy-windows-version-number"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}], "external": false}; window.dfnpanelData['create-a-unified-platform-version-string'] = {"dfnID": "create-a-unified-platform-version-string", "url": "#create-a-unified-platform-version-string", "dfnText": "create a unified platform version string", "refSections": [{"refs": [{"id": "ref-for-create-a-unified-platform-version-string"}, {"id": "ref-for-create-a-unified-platform-version-string\u2460"}, {"id": "ref-for-create-a-unified-platform-version-string\u2461"}], "title": "3.10. The 'Sec-CH-UA-Platform-Version' Header Field"}], "external": false}; window.dfnpanelData['dictdef-navigatoruabrandversion'] = {"dfnID": "dictdef-navigatoruabrandversion", "url": "#dictdef-navigatoruabrandversion", "dfnText": "NavigatorUABrandVersion", "refSections": [{"refs": [{"id": "ref-for-dictdef-navigatoruabrandversion"}, {"id": "ref-for-dictdef-navigatoruabrandversion\u2460"}, {"id": "ref-for-dictdef-navigatoruabrandversion\u2461"}, {"id": "ref-for-dictdef-navigatoruabrandversion\u2462"}], "title": "4. Interface"}, {"refs": [{"id": "ref-for-dictdef-navigatoruabrandversion\u2463"}, {"id": "ref-for-dictdef-navigatoruabrandversion\u2464"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}, {"refs": [{"id": "ref-for-dictdef-navigatoruabrandversion\u2465"}, {"id": "ref-for-dictdef-navigatoruabrandversion\u2466"}], "title": "4.1.2. Create brands"}], "external": false}; window.dfnpanelData['dom-navigatoruabrandversion-brand'] = {"dfnID": "dom-navigatoruabrandversion-brand", "url": "#dom-navigatoruabrandversion-brand", "dfnText": "brand", "refSections": [{"refs": [{"id": "ref-for-dom-navigatoruabrandversion-brand"}, {"id": "ref-for-dom-navigatoruabrandversion-brand\u2460"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-dom-navigatoruabrandversion-brand\u2461"}], "title": "4.1.4. Create a brand-version list"}], "external": false}; window.dfnpanelData['dom-navigatoruabrandversion-version'] = {"dfnID": "dom-navigatoruabrandversion-version", "url": "#dom-navigatoruabrandversion-version", "dfnText": "version", "refSections": [{"refs": [{"id": "ref-for-dom-navigatoruabrandversion-version"}, {"id": "ref-for-dom-navigatoruabrandversion-version\u2460"}], "title": "4.1.2. Create brands"}], "external": false}; window.dfnpanelData['dictdef-uadatavalues'] = {"dfnID": "dictdef-uadatavalues", "url": "#dictdef-uadatavalues", "dfnText": "UADataValues", "refSections": [{"refs": [{"id": "ref-for-dictdef-uadatavalues"}], "title": "4. Interface"}, {"refs": [{"id": "ref-for-dictdef-uadatavalues\u2460"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-architecture'] = {"dfnID": "dom-uadatavalues-architecture", "url": "#dom-uadatavalues-architecture", "dfnText": "architecture", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-architecture"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-bitness'] = {"dfnID": "dom-uadatavalues-bitness", "url": "#dom-uadatavalues-bitness", "dfnText": "bitness", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-bitness"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-brands'] = {"dfnID": "dom-uadatavalues-brands", "url": "#dom-uadatavalues-brands", "dfnText": "brands", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-brands"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-formfactors'] = {"dfnID": "dom-uadatavalues-formfactors", "url": "#dom-uadatavalues-formfactors", "dfnText": "formFactors", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-formfactors"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-fullversionlist'] = {"dfnID": "dom-uadatavalues-fullversionlist", "url": "#dom-uadatavalues-fullversionlist", "dfnText": "fullVersionList", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-fullversionlist"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-model'] = {"dfnID": "dom-uadatavalues-model", "url": "#dom-uadatavalues-model", "dfnText": "model", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-model"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-mobile'] = {"dfnID": "dom-uadatavalues-mobile", "url": "#dom-uadatavalues-mobile", "dfnText": "mobile", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-mobile"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-platform'] = {"dfnID": "dom-uadatavalues-platform", "url": "#dom-uadatavalues-platform", "dfnText": "platform", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-platform"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-platformversion'] = {"dfnID": "dom-uadatavalues-platformversion", "url": "#dom-uadatavalues-platformversion", "dfnText": "platformVersion", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-platformversion"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-uafullversion'] = {"dfnID": "dom-uadatavalues-uafullversion", "url": "#dom-uadatavalues-uafullversion", "dfnText": "uaFullVersion", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-uafullversion"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dom-uadatavalues-wow64'] = {"dfnID": "dom-uadatavalues-wow64", "url": "#dom-uadatavalues-wow64", "dfnText": "wow64", "refSections": [{"refs": [{"id": "ref-for-dom-uadatavalues-wow64"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['dictdef-ualowentropyjson'] = {"dfnID": "dictdef-ualowentropyjson", "url": "#dictdef-ualowentropyjson", "dfnText": "UALowEntropyJSON", "refSections": [{"refs": [{"id": "ref-for-dictdef-ualowentropyjson"}], "title": "4. Interface"}, {"refs": [{"id": "ref-for-dictdef-ualowentropyjson\u2460"}], "title": "4.1.7. toJSON method"}], "external": false}; window.dfnpanelData['dom-ualowentropyjson-brands'] = {"dfnID": "dom-ualowentropyjson-brands", "url": "#dom-ualowentropyjson-brands", "dfnText": "brands", "refSections": [{"refs": [{"id": "ref-for-dom-ualowentropyjson-brands"}], "title": "4.1.7. toJSON method"}], "external": false}; window.dfnpanelData['dom-ualowentropyjson-mobile'] = {"dfnID": "dom-ualowentropyjson-mobile", "url": "#dom-ualowentropyjson-mobile", "dfnText": "mobile", "refSections": [{"refs": [{"id": "ref-for-dom-ualowentropyjson-mobile"}], "title": "4.1.7. toJSON method"}], "external": false}; window.dfnpanelData['dom-ualowentropyjson-platform'] = {"dfnID": "dom-ualowentropyjson-platform", "url": "#dom-ualowentropyjson-platform", "dfnText": "platform", "refSections": [{"refs": [{"id": "ref-for-dom-ualowentropyjson-platform"}], "title": "4.1.7. toJSON method"}], "external": false}; window.dfnpanelData['navigatoruadata'] = {"dfnID": "navigatoruadata", "url": "#navigatoruadata", "dfnText": "NavigatorUAData", "refSections": [{"refs": [{"id": "ref-for-navigatoruadata"}], "title": "4. Interface"}], "external": false}; window.dfnpanelData['dom-navigatoruadata-brands'] = {"dfnID": "dom-navigatoruadata-brands", "url": "#dom-navigatoruadata-brands", "dfnText": "brands", "refSections": [{"refs": [{"id": "ref-for-dom-navigatoruadata-brands"}], "title": "4.1.5. Getters"}], "external": false}; window.dfnpanelData['dom-navigatoruadata-mobile'] = {"dfnID": "dom-navigatoruadata-mobile", "url": "#dom-navigatoruadata-mobile", "dfnText": "mobile", "refSections": [{"refs": [{"id": "ref-for-dom-navigatoruadata-mobile"}], "title": "4.1.5. Getters"}], "external": false}; window.dfnpanelData['dom-navigatoruadata-platform'] = {"dfnID": "dom-navigatoruadata-platform", "url": "#dom-navigatoruadata-platform", "dfnText": "platform", "refSections": [{"refs": [{"id": "ref-for-dom-navigatoruadata-platform"}], "title": "4.1.5. Getters"}], "external": false}; window.dfnpanelData['navigatorua'] = {"dfnID": "navigatorua", "url": "#navigatorua", "dfnText": "NavigatorUA", "refSections": [{"refs": [{"id": "ref-for-navigatorua"}, {"id": "ref-for-navigatorua\u2460"}], "title": "4. Interface"}], "external": false}; window.dfnpanelData['user-agent-brands'] = {"dfnID": "user-agent-brands", "url": "#user-agent-brands", "dfnText": "brands", "refSections": [{"refs": [{"id": "ref-for-user-agent-brands"}, {"id": "ref-for-user-agent-brands\u2460"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-brands\u2461"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-user-agent-brands\u2462"}], "title": "3.6. The 'Sec-CH-UA-Full-Version-List' Header Field"}, {"refs": [{"id": "ref-for-user-agent-brands\u2463"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}, {"refs": [{"id": "ref-for-user-agent-brands\u2464"}, {"id": "ref-for-user-agent-brands\u2465"}, {"id": "ref-for-user-agent-brands\u2466"}, {"id": "ref-for-user-agent-brands\u2467"}, {"id": "ref-for-user-agent-brands\u2468"}], "title": "6.2. GREASE-like UA Brand Lists"}], "external": false}; window.dfnpanelData['windoworworkerglobalscope-brands-frozen-array'] = {"dfnID": "windoworworkerglobalscope-brands-frozen-array", "url": "#windoworworkerglobalscope-brands-frozen-array", "dfnText": "brands frozen array", "refSections": [{"refs": [{"id": "ref-for-windoworworkerglobalscope-brands-frozen-array"}], "title": "4.1.5. Getters"}, {"refs": [{"id": "ref-for-windoworworkerglobalscope-brands-frozen-array\u2460"}], "title": "4.1.6. getHighEntropyValues method"}, {"refs": [{"id": "ref-for-windoworworkerglobalscope-brands-frozen-array\u2461"}], "title": "4.1.7. toJSON method"}], "external": false}; window.dfnpanelData['windoworworkerglobalscope-full-version-list-frozen-array'] = {"dfnID": "windoworworkerglobalscope-full-version-list-frozen-array", "url": "#windoworworkerglobalscope-full-version-list-frozen-array", "dfnText": "full version list frozen array", "refSections": [{"refs": [{"id": "ref-for-windoworworkerglobalscope-full-version-list-frozen-array"}], "title": "4.1.6. getHighEntropyValues method"}], "external": false}; window.dfnpanelData['create-brands'] = {"dfnID": "create-brands", "url": "#create-brands", "dfnText": "create brands", "refSections": [{"refs": [{"id": "ref-for-create-brands"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-create-brands\u2460"}], "title": "3.6. The 'Sec-CH-UA-Full-Version-List' Header Field"}, {"refs": [{"id": "ref-for-create-brands\u2461"}, {"id": "ref-for-create-brands\u2462"}], "title": "4.1.1. WindowOrWorkerGlobalScope"}], "external": false}; window.dfnpanelData['user-agent-equivalence-class'] = {"dfnID": "user-agent-equivalence-class", "url": "#user-agent-equivalence-class", "dfnText": "equivalence class", "refSections": [{"refs": [{"id": "ref-for-user-agent-equivalence-class"}], "title": "3. User Agent Hints"}, {"refs": [{"id": "ref-for-user-agent-equivalence-class\u2460"}, {"id": "ref-for-user-agent-equivalence-class\u2461"}], "title": "4.1.2. Create brands"}, {"refs": [{"id": "ref-for-user-agent-equivalence-class\u2462"}, {"id": "ref-for-user-agent-equivalence-class\u2463"}], "title": "6.2. GREASE-like UA Brand Lists"}], "external": false}; window.dfnpanelData['create-an-arbitrary-brand'] = {"dfnID": "create-an-arbitrary-brand", "url": "#create-an-arbitrary-brand", "dfnText": "create an arbitrary brand", "refSections": [{"refs": [{"id": "ref-for-create-an-arbitrary-brand"}], "title": "4.1.2. Create brands"}], "external": false}; window.dfnpanelData['create-an-arbitrary-version'] = {"dfnID": "create-an-arbitrary-version", "url": "#create-an-arbitrary-version", "dfnText": "create an arbitrary version", "refSections": [{"refs": [{"id": "ref-for-create-an-arbitrary-version"}], "title": "4.1.2. Create brands"}], "external": false}; window.dfnpanelData['create-a-brand-version-list'] = {"dfnID": "create-a-brand-version-list", "url": "#create-a-brand-version-list", "dfnText": "create a brand-version list", "refSections": [{"refs": [{"id": "ref-for-create-a-brand-version-list"}], "title": "3.1. The 'Sec-CH-UA' Header Field"}, {"refs": [{"id": "ref-for-create-a-brand-version-list\u2460"}], "title": "3.6. The 'Sec-CH-UA-Full-Version-List' Header Field"}], "external": false}; </script> <script>/* Boilerplate: script-dom-helper */ function query(sel) { return document.querySelector(sel); } function queryAll(sel) { return [...document.querySelectorAll(sel)]; } function iter(obj) { if(!obj) return []; var it = obj[Symbol.iterator]; if(it) return it; return Object.entries(obj); } function mk(tagname, attrs, ...children) { const el = document.createElement(tagname); for(const [k,v] of iter(attrs)) { if(k.slice(0,3) == "_on") { const eventName = k.slice(3); el.addEventListener(eventName, v); } else if(k[0] == "_") { // property, not attribute el[k.slice(1)] = v; } else { if(v === false || v == null) { continue; } else if(v === true) { el.setAttribute(k, ""); continue; } else { el.setAttribute(k, v); } } } append(el, children); return el; } /* Create shortcuts for every known HTML element */ [ "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "meta", "meter", "nav", "nobr", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "u", "ul", "var", "video", "wbr", "xmp", ].forEach(tagname=>{ mk[tagname] = (...args) => mk(tagname, ...args); }); function* nodesFromChildList(children) { for(const child of children.flat(Infinity)) { if(child instanceof Node) { yield child; } else { yield new Text(child); } } } function append(el, ...children) { for(const child of nodesFromChildList(children)) { if(el instanceof Node) el.appendChild(child); else el.push(child); } return el; } function insertAfter(el, ...children) { for(const child of nodesFromChildList(children)) { el.parentNode.insertBefore(child, el.nextSibling); } return el; } function clearContents(el) { el.innerHTML = ""; return el; } function parseHTML(markup) { if(markup.toLowerCase().trim().indexOf('<!doctype') === 0) { const doc = document.implementation.createHTMLDocument(""); doc.documentElement.innerHTML = markup; return doc; } else { const el = mk.template({}); el.innerHTML = markup; return el.content; } } </script> <script>/* Boilerplate: script-var-click-highlighting */ /* Color-choosing design: Colors are ordered by goodness. Each color has a usage count (initially zero). Each variable has a last-used color. * If the var has a last-used color, and that color's usage is 0, return that color. * Otherwise, return the lowest-indexed color with the lowest usage. Increment the color's usage and set it as the last-used color for that var. * On unclicking, decrement usage of the color. */ "use strict"; { document.addEventListener("click", e=>{ if(e.target.nodeName == "VAR") { highlightSameAlgoVars(e.target); } }); const indexCounts = new Map(); const indexNames = new Map(); function highlightSameAlgoVars(v) { // Find the algorithm container. let algoContainer = null; let searchEl = v; while(algoContainer == null && searchEl != document.body) { searchEl = searchEl.parentNode; if(searchEl.hasAttribute("data-algorithm")) { algoContainer = searchEl; } } // Not highlighting document-global vars, // too likely to be unrelated. if(algoContainer == null) return; const algoName = algoContainer.getAttribute("data-algorithm"); const varName = getVarName(v); const addClass = !v.classList.contains("selected"); let highlightClass = null; if(addClass) { const index = chooseHighlightIndex(algoName, varName); indexCounts.get(algoName)[index] += 1; indexNames.set(algoName+"///"+varName, index); highlightClass = nameFromIndex(index); } else { const index = previousHighlightIndex(algoName, varName); indexCounts.get(algoName)[index] -= 1; highlightClass = nameFromIndex(index); } // Find all same-name vars, and toggle their class appropriately. for(const el of algoContainer.querySelectorAll("var")) { if(getVarName(el) == varName) { el.classList.toggle("selected", addClass); el.classList.toggle(highlightClass, addClass); } } } function getVarName(el) { return el.textContent.replace(/(\s|\xa0)+/, " ").trim(); } function chooseHighlightIndex(algoName, varName) { let indexes = null; if(indexCounts.has(algoName)) { indexes = indexCounts.get(algoName); } else { // 7 classes right now indexes = [0,0,0,0,0,0,0]; indexCounts.set(algoName, indexes); } // If the element was recently unclicked, // *and* that color is still unclaimed, // give it back the same color. const lastIndex = previousHighlightIndex(algoName, varName); if(indexes[lastIndex] === 0) return lastIndex; // Find the earliest index with the lowest count. const minCount = Math.min.apply(null, indexes); let index = null; for(var i = 0; i < indexes.length; i++) { if(indexes[i] == minCount) { return i; } } } function previousHighlightIndex(algoName, varName) { return indexNames.get(algoName+"///"+varName); } function nameFromIndex(index) { return "selected" + index; } } </script>