Speculation Rules Draft Community Group Report , 1 September 2025 This version: https://wicg.github.io/nav-speculation/speculation-rules.html Issue Tracking: GitHub Editors: Jeremy Roman ( Google ) Domenic Denicola ( Google ) Copyright © 2025 the Contributors to the Speculation Rules Specification, published by the Web Platform Incubator Community Group under the W3C Community Contributor License Agreement (CLA) . A human-readable summary is available. Abstract Extensions to speculation rules to support navigational prerendering. Status of this document This specification was published by the Web Platform Incubator Community Group . It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups . Table of Contents 1 This specification is moving to HTML 2 Parsing 3 Processing model 4 Triggering Index Terms defined by this specification Terms defined by reference References Normative References 1. This specification is moving to HTML The majority of this specification is being upstreamed to the HTML Standard: see whatwg/html#11426 and whatwg/html#11123 . The rendered specification text can currently be found at this PR preview . What remains in this document are some additional patches to support prerendering, which the upstreamed version does not yet cover. Once prefetch is also upstreamed, what remains in this document will likely migrate to [PRERENDERING-REVAMPED] . 2. Parsing Extend the speculation rule set struct with one additional item : prerender rules , a list of speculation rules , initially empty Extend the speculation rule struct with one additional item : target navigable name hint , a string or null Modify parse a speculation rule set string as follows: Remove the typesToTreatAsPrefetch construct, and instead parse parsed [" prerender "] into the prerender rules list, in an identical manner to what is done for parsed [" prefetch "] and the prefetch rules . Discard rules parsed from parsed [" prefetch "] if the target navigable name hint is not null. Discard rules parsed from parsed [" prerender "] if the requirements contain " anonymous-client-ip-when-cross-origin ". Implementations will still be allowed to treat prerender candidates as prefetches, per the modifications in § 3 Processing model . Modify parse a speculation rule by adding the following steps: Let targetHint be null. If input [" target_hint "] exists : If input [" target_hint "] is not a valid navigable target name or keyword : The user agent may report a warning to the console indicating that the supplied target hint was invalid. Return null. Set targetHint to input [" target_hint "]. and then updating the final step which returns a speculation rule to include setting the target navigable name hint to targetHint . 3. Processing model A prerender candidate is a speculative load candidate with the following additional item : target navigable name hint , a valid navigable target name or keyword or null Update the inner consider speculative loads steps algorithm by appending the following steps near the beginning, after assembling prefetchCandidates : Let prerenderCandidates be an empty list . For each ruleSet of document ’s speculation rule sets : For each rule of ruleSet ’s prerender rules : For each url of rule ’s URLs : Let referrerPolicy be the result of computing a speculative load referrer policy given rule and null. Append a new prerender candidate with URL url No-Vary-Search hint rule ’s No-Vary-Search hint eagerness rule ’s eagerness referrer policy referrerPolicy tags rule ’s tags target navigable name hint rule ’s target navigable name hint to prerenderCandidates . If rule ’s predicate is not null, then: Let links be the result of finding matching links given document and rule ’s predicate . For each link of links : Let target be rule ’s target navigable name hint . If target is null, set it to the result of getting an element’s target given link . Let referrerPolicy be the result of computing a speculative load referrer policy given rule and link . Append a prerender candidate with URL link ’s url No-Vary-Search hint rule ’s No-Vary-Search hint eagerness rule ’s eagerness referrer policy referrerPolicy tags rule ’s tags target navigable name hint target to prerenderCandidates . Let speculativeLoadCandidates be the union of prefetchCandidates and prerenderCandidates . Update subsequent steps for canceling not-still-being-speculated prefetch records to operate on speculativeLoadCandidates instead of prefetchCandidates . Create a list prerenderCandidateGroups in an analogous way to prefetchCandidateGroups , but using prerenderCandidates instead of prefetchCandidates . Replace the step which performs the actual prefetching by looping over prefetchCandidateGroups with the following: Let speculativeLoadCandidateGroups be the union of prefetchCandidateGroups and prerenderCandidateGroups . For each group of speculativeLoadCandidateGroups : The user agent may run the following steps: Let candidate be group [0]. Let tagsToSend be the result of collecting tags from speculative load candidates given group . Let prefetchRecord be a new prefetch record with source " speculation rules " URL candidate ’s URL No-Vary-Search hint candidate ’s No-Vary-Search hint referrer policy candidate ’s referrer policy tags tagsToSend If candidate is a prefetch candidate , then set prefetchRecord ’s anonymization policy to candidate ’s anonymization policy . If candidate is a prerender candidate , then the user agent may run the following steps: Set prefetchRecord ’s prerendering traversable to " to be created ". Set prefetchRecord ’s prerendering target navigable name hint to candidate ’s target navigable name hint . Start a referrer-initiated navigational prerender given document and prefetchRecord . If the user agent did not run the previous step, then start a referrer-initiated navigational prefetch given document and prefetchRecord . (And keep the subsequent discussion of when to execute this "may" step.) 4. Triggering Update the attribute change steps for a and area elements to also monitor the target attribute and consider speculative loads if it changes. Index Terms defined by this specification prerender candidate , in § 3 prerender rules , in § 2 target navigable name hint dfn for prerender candidate , in § 3 dfn for speculation rule , in § 2 Terms defined by reference [CONSOLE] defines the following terms: report a warning to the console [DOM] defines the following terms: attribute change steps [HTML] defines the following terms: a anonymization policy area collecting tags from speculative load candidates compute a speculative load referrer policy consider speculative loads eagerness (for speculation rule) eagerness (for speculative load candidate) finding matching links get an element's target inner consider speculative loads steps No-Vary-Search hint (for speculation rule) No-Vary-Search hint (for speculative load candidate) parse a speculation rule parse a speculation rule set string predicate prefetch candidate prefetch rules referrer policy requirements speculation rule speculation rule set speculation rule sets speculative load candidate tags (for speculation rule) tags (for speculative load candidate) target url (for HTMLHyperlinkElementUtils) URL (for speculative load candidate) URLs valid navigable target name or keyword [INFRA] defines the following terms: append exist for each item list string struct [PREFETCH] defines the following terms: anonymization policy No-Vary-Search hint prefetch record prerendering target navigable name hint prerendering traversable referrer policy source start a referrer-initiated navigational prefetch tags URL [PRERENDERING-REVAMPED] defines the following terms: start a referrer-initiated navigational prerender References Normative References [CONSOLE] Dominic Farolino; Robert Kowalski; Terin Stock. Console Standard . Living Standard. URL: https://console.spec.whatwg.org/ [DOM] Anne van Kesteren. DOM Standard . Living Standard. URL: https://dom.spec.whatwg.org/ [HTML] Anne van Kesteren; et al. HTML Standard . Living Standard. URL: https://html.spec.whatwg.org/multipage/ [INFRA] Anne van Kesteren; Domenic Denicola. Infra Standard . Living Standard. URL: https://infra.spec.whatwg.org/ [PREFETCH] Prefetch . Draft Community Group Report. URL: https://wicg.github.io/nav-speculation/prefetch.html [PRERENDERING-REVAMPED] Prerendering Revamped . Draft Community Group Report. URL: https://wicg.github.io/nav-speculation/prerendering.html /* Boilerplate: script-dom-helper */ "use strict"; 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; } } /* Boilerplate: script-dfn-panel */ "use strict"; { let dfnPanelData = { "00064bc4": {"dfnID":"00064bc4","dfnText":"get an element's target","external":true,"refSections":[{"refs":[{"id":"ref-for-get-an-element's-target"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/semantics.html#get-an-element's-target"}, "043ab775": {"dfnID":"043ab775","dfnText":"predicate","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-predicate"},{"id":"ref-for-sr-predicate\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-predicate"}, "05390e01": {"dfnID":"05390e01","dfnText":"start a referrer-initiated navigational prefetch","external":true,"refSections":[{"refs":[{"id":"ref-for-start-a-referrer-initiated-navigational-prefetch"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch"}, "0698d556": {"dfnID":"0698d556","dfnText":"string","external":true,"refSections":[{"refs":[{"id":"ref-for-string"}],"title":"2. Parsing"}],"url":"https://infra.spec.whatwg.org/#string"}, "1243a891": {"dfnID":"1243a891","dfnText":"exist","external":true,"refSections":[{"refs":[{"id":"ref-for-map-exists"}],"title":"2. Parsing"}],"url":"https://infra.spec.whatwg.org/#map-exists"}, "16808e53": {"dfnID":"16808e53","dfnText":"parse a speculation rule set string","external":true,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-set"},{"id":"ref-for-speculation-rule-set\u2460"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"}, "16d07e10": {"dfnID":"16d07e10","dfnText":"for each","external":true,"refSections":[{"refs":[{"id":"ref-for-list-iterate"},{"id":"ref-for-list-iterate\u2460"},{"id":"ref-for-list-iterate\u2461"},{"id":"ref-for-list-iterate\u2462"},{"id":"ref-for-list-iterate\u2463"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#list-iterate"}, "3637d409": {"dfnID":"3637d409","dfnText":"eagerness (for speculation rule)","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-eagerness"},{"id":"ref-for-sr-eagerness\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-eagerness"}, "36706746": {"dfnID":"36706746","dfnText":"valid navigable target name or keyword","external":true,"refSections":[{"refs":[{"id":"ref-for-valid-navigable-target-name-or-keyword"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-valid-navigable-target-name-or-keyword\u2460"}],"title":"3. Processing model"}],"url":"https://html.spec.whatwg.org/multipage/document-sequences.html#valid-navigable-target-name-or-keyword"}, "37e32f12": {"dfnID":"37e32f12","dfnText":"report a warning to the console","external":true,"refSections":[{"refs":[{"id":"ref-for-report-a-warning-to-the-console"}],"title":"2. Parsing"}],"url":"https://console.spec.whatwg.org/#report-a-warning-to-the-console"}, "44ae7369": {"dfnID":"44ae7369","dfnText":"No-Vary-Search hint (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-nvs-hint"},{"id":"ref-for-sl-candidate-nvs-hint\u2460"},{"id":"ref-for-sl-candidate-nvs-hint\u2461"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-nvs-hint"}, "482fd8d4": {"dfnID":"482fd8d4","dfnText":"No-Vary-Search hint (for speculation rule)","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-nvs-hint"},{"id":"ref-for-sr-nvs-hint\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-nvs-hint"}, "4ce800e8": {"dfnID":"4ce800e8","dfnText":"No-Vary-Search hint","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-no-vary-search-hint"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint"}, "4d80a6e7": {"dfnID":"4d80a6e7","dfnText":"referrer policy","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-referrer-policy"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy"}, "5303d536": {"dfnID":"5303d536","dfnText":"tags (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-tags"},{"id":"ref-for-sl-candidate-tags\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-tags"}, "53275e46": {"dfnID":"53275e46","dfnText":"append","external":true,"refSections":[{"refs":[{"id":"ref-for-list-append"},{"id":"ref-for-list-append\u2460"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#list-append"}, "5a57d186": {"dfnID":"5a57d186","dfnText":"anonymization policy","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-anonymization-policy"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-anonymization-policy"}, "5bc14177": {"dfnID":"5bc14177","dfnText":"URL","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-url"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url"}, "631182ca": {"dfnID":"631182ca","dfnText":"inner consider speculative loads steps","external":true,"refSections":[{"refs":[{"id":"ref-for-inner-consider-speculative-loads-steps"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#inner-consider-speculative-loads-steps"}, "6393b8ef": {"dfnID":"6393b8ef","dfnText":"prefetch rules","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-set-prefetch"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-set-prefetch"}, "649608b9": {"dfnID":"649608b9","dfnText":"list","external":true,"refSections":[{"refs":[{"id":"ref-for-list"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-list\u2460"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#list"}, "68bf3d31": {"dfnID":"68bf3d31","dfnText":"a","external":true,"refSections":[{"refs":[{"id":"ref-for-the-a-element"}],"title":"4. Triggering"}],"url":"https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element"}, "6da138da": {"dfnID":"6da138da","dfnText":"source","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-source"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source"}, "6ff9cf24": {"dfnID":"6ff9cf24","dfnText":"parse a speculation rule","external":true,"refSections":[{"refs":[{"id":"ref-for-parse-a-speculation-rule"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#parse-a-speculation-rule"}, "7684ffde": {"dfnID":"7684ffde","dfnText":"speculation rule","external":true,"refSections":[{"refs":[{"id":"ref-for-speculation-rule"},{"id":"ref-for-speculation-rule\u2460"},{"id":"ref-for-speculation-rule\u2461"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule"}, "769b0f6e": {"dfnID":"769b0f6e","dfnText":"collecting tags from speculative load candidates","external":true,"refSections":[{"refs":[{"id":"ref-for-collect-tags-from-speculative-load-candidates"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#collect-tags-from-speculative-load-candidates"}, "86e3118f": {"dfnID":"86e3118f","dfnText":"tags","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-tags"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags"}, "87c3c6f6": {"dfnID":"87c3c6f6","dfnText":"anonymization policy","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-anonymization-policy"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy"}, "91dda5f9": {"dfnID":"91dda5f9","dfnText":"prerendering traversable","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-prerendering-traversable"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-traversable"}, "980dda1d": {"dfnID":"980dda1d","dfnText":"speculation rule set","external":true,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-set"},{"id":"ref-for-speculation-rule-set\u2460"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"}, "984221ca": {"dfnID":"984221ca","dfnText":"struct","external":true,"refSections":[{"refs":[{"id":"ref-for-struct"},{"id":"ref-for-struct\u2460"}],"title":"2. Parsing"}],"url":"https://infra.spec.whatwg.org/#struct"}, "99c55261": {"dfnID":"99c55261","dfnText":"prefetch record","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record"},{"id":"ref-for-prefetch-record\u2460"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record"}, "9a8e15f0": {"dfnID":"9a8e15f0","dfnText":"target","external":true,"refSections":[{"refs":[{"id":"ref-for-attr-hyperlink-target"}],"title":"4. Triggering"}],"url":"https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target"}, "9fe18dd3": {"dfnID":"9fe18dd3","dfnText":"start a referrer-initiated navigational prerender","external":true,"refSections":[{"refs":[{"id":"ref-for-start-a-referrer-initiated-navigational-prerender"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prerendering.html#start-a-referrer-initiated-navigational-prerender"}, "a16866c7": {"dfnID":"a16866c7","dfnText":"eagerness (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-eagerness"},{"id":"ref-for-sl-candidate-eagerness\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-eagerness"}, "a1a807e5": {"dfnID":"a1a807e5","dfnText":"area","external":true,"refSections":[{"refs":[{"id":"ref-for-the-area-element"}],"title":"4. Triggering"}],"url":"https://html.spec.whatwg.org/multipage/image-maps.html#the-area-element"}, "a20ea266": {"dfnID":"a20ea266","dfnText":"URLs","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-urls"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-urls"}, "a47f7739": {"dfnID":"a47f7739","dfnText":"prerendering target navigable name hint","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-prerendering-target-navigable-name-hint"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-target-navigable-name-hint"}, "a4d78a5c": {"dfnID":"a4d78a5c","dfnText":"speculation rule sets","external":true,"refSections":[{"refs":[{"id":"ref-for-document-sr-sets"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#document-sr-sets"}, "b141168a": {"dfnID":"b141168a","dfnText":"URL (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-url"},{"id":"ref-for-sl-candidate-url\u2460"},{"id":"ref-for-sl-candidate-url\u2461"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-url"}, "c6371648": {"dfnID":"c6371648","dfnText":"finding matching links","external":true,"refSections":[{"refs":[{"id":"ref-for-finding-matching-links"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#finding-matching-links"}, "c666e05d": {"dfnID":"c666e05d","dfnText":"speculative load candidate","external":true,"refSections":[{"refs":[{"id":"ref-for-speculative-load-candidate"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculative-load-candidate"}, "c7c0dde1": {"dfnID":"c7c0dde1","dfnText":"url (for HTMLHyperlinkElementUtils)","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-hyperlink-url"}],"title":"3. Processing model"}],"url":"https://html.spec.whatwg.org/multipage/links.html#concept-hyperlink-url"}, "c88f3887": {"dfnID":"c88f3887","dfnText":"item","external":true,"refSections":[{"refs":[{"id":"ref-for-struct-item"},{"id":"ref-for-struct-item\u2460"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-struct-item\u2461"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#struct-item"}, "c8c44926": {"dfnID":"c8c44926","dfnText":"prefetch candidate","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-candidate"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#prefetch-candidate"}, "d1a6c008": {"dfnID":"d1a6c008","dfnText":"attribute change steps","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-element-attributes-change-ext"}],"title":"4. Triggering"}],"url":"https://dom.spec.whatwg.org/#concept-element-attributes-change-ext"}, "e014bb81": {"dfnID":"e014bb81","dfnText":"consider speculative loads","external":true,"refSections":[{"refs":[{"id":"ref-for-consider-speculative-loads"}],"title":"4. Triggering"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#consider-speculative-loads"}, "e535a7f6": {"dfnID":"e535a7f6","dfnText":"compute a speculative load referrer policy","external":true,"refSections":[{"refs":[{"id":"ref-for-compute-speculative-load-referrer-policy"},{"id":"ref-for-compute-speculative-load-referrer-policy\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#compute-speculative-load-referrer-policy"}, "ea540423": {"dfnID":"ea540423","dfnText":"requirements","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-requirements"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-requirements"}, "ed08d686": {"dfnID":"ed08d686","dfnText":"tags (for speculation rule)","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-tags"},{"id":"ref-for-sr-tags\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-tags"}, "f64cd240": {"dfnID":"f64cd240","dfnText":"referrer policy","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-referrer-policy"},{"id":"ref-for-sl-candidate-referrer-policy\u2460"},{"id":"ref-for-sl-candidate-referrer-policy\u2461"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-referrer-policy"}, "prerender-candidate": {"dfnID":"prerender-candidate","dfnText":"prerender candidate","external":false,"refSections":[{"refs":[{"id":"ref-for-prerender-candidate"},{"id":"ref-for-prerender-candidate\u2460"},{"id":"ref-for-prerender-candidate\u2461"}],"title":"3. Processing model"}],"url":"#prerender-candidate"}, "prerender-candidate-target-navigable-name-hint": {"dfnID":"prerender-candidate-target-navigable-name-hint","dfnText":"target navigable name hint","external":false,"refSections":[{"refs":[{"id":"ref-for-prerender-candidate-target-navigable-name-hint"},{"id":"ref-for-prerender-candidate-target-navigable-name-hint\u2460"},{"id":"ref-for-prerender-candidate-target-navigable-name-hint\u2461"}],"title":"3. Processing model"}],"url":"#prerender-candidate-target-navigable-name-hint"}, "speculation-rule-set-prerender-rules": {"dfnID":"speculation-rule-set-prerender-rules","dfnText":"prerender rules","external":false,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-set-prerender-rules"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-speculation-rule-set-prerender-rules\u2460"}],"title":"3. Processing model"}],"url":"#speculation-rule-set-prerender-rules"}, "speculation-rule-target-navigable-name-hint": {"dfnID":"speculation-rule-target-navigable-name-hint","dfnText":"target navigable name hint","external":false,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-target-navigable-name-hint"},{"id":"ref-for-speculation-rule-target-navigable-name-hint\u2460"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-speculation-rule-target-navigable-name-hint\u2461"},{"id":"ref-for-speculation-rule-target-navigable-name-hint\u2462"}],"title":"3. Processing model"}],"url":"#speculation-rule-target-navigable-name-hint"}, }; document.addEventListener("DOMContentLoaded", ()=> { genAllDfnPanels(); document.body.addEventListener("click", (e) => { // If not handled already, just hide all dfn panels. hideAllDfnPanels(); }); }); window.addEventListener("resize", () => { // Pin any visible dfn panel queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(el=> positionDfnPanel(el)); }); function genAllDfnPanels() { for(const panelData of Object.values(dfnPanelData)) { const dfnID = panelData.dfnID; const dfn = document.getElementById(dfnID); if(!dfn) { console.log(`Can't find dfn#${dfnID}.`, panelData); continue; } dfn.panelData = panelData; insertDfnPopupAction(dfn); } } function genDfnPanel(dfn, { dfnID, url, dfnText, refSections, external }) { const dfnPanel = mk.aside({ class: "dfn-panel on", 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, class:"dfn-link"}, url), refSections.length == 0 ? [] : 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})` ), " ", ] ), ), ), ), genLinkingSyntaxes(dfn), ); dfnPanel.addEventListener('click', (event) => { if (event.target.nodeName == 'A') { scrollToTargetAndHighlight(event); pinDfnPanel(dfnPanel); } event.stopPropagation(); refocusOnTarget(event); }); dfnPanel.addEventListener('keydown', (event) => { if(event.keyCode == 27) { // Escape key hideDfnPanel({dfnPanel}); event.stopPropagation(); event.preventDefault(); } }); dfnPanel.dfn = dfn; dfn.dfnPanel = dfnPanel; return dfnPanel; } function hideAllDfnPanels() { // Delete the currently-active dfn panel. queryAll(".dfn-panel").forEach(dfnPanel=> hideDfnPanel({dfnPanel})); } function showDfnPanel(dfn) { hideAllDfnPanels(); // Only display one at a time. dfn.setAttribute("aria-expanded", "true"); const dfnPanel = genDfnPanel(dfn, dfn.panelData); // Give the dfn a unique tabindex, and then // give all the tabbable panel bits successive indexes. let tabIndex = 100; dfn.tabIndex = tabIndex++; const tabbable = dfnPanel.querySelectorAll(":is(a, button)"); for (const el of tabbable) { el.tabIndex = tabIndex++; } append(document.body, dfnPanel); positionDfnPanel(dfnPanel); } function positionDfnPanel(dfnPanel) { const dfn = dfnPanel.dfn; const dfnPos = getBounds(dfn); dfnPanel.style.top = dfnPos.bottom + "px"; dfnPanel.style.left = dfnPos.left + "px"; const panelPos = dfnPanel.getBoundingClientRect(); const panelMargin = 8; const maxRight = document.body.parentNode.clientWidth - panelMargin; if (panelPos.right > maxRight) { const overflowAmount = panelPos.right - maxRight; const newLeft = Math.max(panelMargin, dfnPos.left - overflowAmount); dfnPanel.style.left = newLeft + "px"; } } function pinDfnPanel(dfnPanel) { // Switch it to "activated" state, which pins it. dfnPanel.classList.add("activated"); dfnPanel.style.position = "fixed"; dfnPanel.style.left = null; dfnPanel.style.top = null; } function hideDfnPanel({dfn, dfnPanel}) { if(!dfnPanel) dfnPanel = dfn.dfnPanel; if(!dfn) dfn = dfnPanel.dfn; dfn.dfnPanel = undefined; dfnPanel.dfn = undefined; dfn.setAttribute("aria-expanded", "false"); dfn.tabIndex = undefined; dfnPanel.remove() } function toggleDfnPanel(dfn) { if(dfn.dfnPanel) { hideDfnPanel(dfn); } else { showDfnPanel(dfn); } } function insertDfnPopupAction(dfn) { dfn.setAttribute('role', 'button'); dfn.setAttribute('aria-expanded', 'false') dfn.tabIndex = 0; dfn.classList.add('has-dfn-panel'); dfn.addEventListener('click', (event) => { toggleDfnPanel(dfn); event.stopPropagation(); }); dfn.addEventListener('keypress', (event) => { const kc = event.keyCode; // 32-> Space, 13-> Enter if(kc == 32 || kc == 13) { toggleDfnPanel(dfn); event.stopPropagation(); event.preventDefault(); } }); } function refocusOnTarget(event) { const target = event.target; setTimeout(() => { // Refocus on the event.target element. // This is needed after browser scrolls to the destination. target.focus(); }); } // TODO: shared util // Returns the root-level absolute position {left and top} of element. function getBounds(el, relativeTo=document.body) { const relativeRect = relativeTo.getBoundingClientRect(); const elRect = el.getBoundingClientRect(); const top = elRect.top - relativeRect.top; const left = elRect.left - relativeRect.left; return { top, left, bottom: top + elRect.height, right: left + elRect.width, } } function scrollToTargetAndHighlight(event) { let hash = event.target.hash; if (hash) { hash = decodeURIComponent(hash.substring(1)); const dest = document.getElementById(hash); if (dest) { dest.classList.add('highlighted'); setTimeout(() => dest.classList.remove('highlighted'), 1000); } } } // Functions, divided by link type, that wrap an autolink's // contents with the appropriate outer syntax. // Alternately, a string naming another type they format // the same as. function needsFor(type) { switch(type) { case "descriptor": case "value": case "element-attr": case "attr-value": case "element-state": case "method": case "constructor": case "argument": case "attribute": case "const": case "dict-member": case "event": case "enum-value": case "stringifier": case "serializer": case "iterator": case "maplike": case "setlike": case "state": case "mode": case "context": case "facet": return true; default: return false; } } function refusesFor(type) { switch(type) { case "property": case "element": case "interface": case "namespace": case "callback": case "dictionary": case "enum": case "exception": case "typedef": case "http-header": case "permission": return true; default: return false; } } function linkFormatterFromType(type) { switch(type) { case 'scheme': case 'permission': case 'dfn': return (text) => `[=${text}=]`; case 'abstract-op': return (text) => `[\$${text}\$]`; case 'function': case 'at-rule': case 'selector': case 'value': return (text) => `''${text}''`; case 'http-header': return (text) => `[:${text}:]`; case 'interface': case 'constructor': case 'method': case 'argument': case 'attribute': case 'callback': case 'dictionary': case 'dict-member': case 'enum': case 'enum-value': case 'exception': case 'const': case 'typedef': case 'stringifier': case 'serializer': case 'iterator': case 'maplike': case 'setlike': case 'extended-attribute': case 'event': case 'idl': return (text) => `{{${text}}}`; case 'element-state': case 'element-attr': case 'attr-value': case 'element': return (element) => ` `; case 'grammar': return (text) => `${text} (within a )`; case 'type': return (text)=> ``; case 'descriptor': case 'property': return (text) => `'${text}'`; default: return; }; }; function genLinkingSyntaxes(dfn) { if(dfn.tagName != "DFN") return; const type = dfn.getAttribute('data-dfn-type'); if(!type) { console.log(` doesn't have a data-dfn-type:`, dfn); return []; } // Return a function that wraps link text based on the type const linkFormatter = linkFormatterFromType(type); if(!linkFormatter) { console.log(` has an unknown data-dfn-type:`, dfn); return []; } let ltAlts; if(dfn.hasAttribute('data-lt')) { ltAlts = dfn.getAttribute('data-lt') .split("|") .map(x=>x.trim()); } else { ltAlts = [dfn.textContent.trim()]; } if(type == "type") { // lt of "", but "foo" is the interior; // is how you write it with a for, // not or whatever. for(var i = 0; i < ltAlts.length; i++) { const lt = ltAlts[i]; const match = //.exec(lt); if(match) { ltAlts[i] = match[1]; } } } let forAlts; if(dfn.hasAttribute('data-dfn-for')) { forAlts = dfn.getAttribute('data-dfn-for') .split(",") .map(x=>x.trim()); } else { forAlts = ['']; } let linkingSyntaxes = []; if(!needsFor(type)) { for(const lt of ltAlts) { linkingSyntaxes.push(linkFormatter(lt)); } } if(!refusesFor(type)) { for(const f of forAlts) { linkingSyntaxes.push(linkFormatter(`${f}/${ltAlts[0]}`)) } } return [ mk.b({}, 'Possible linking syntaxes:'), mk.ul({}, ...linkingSyntaxes.map(link => { const copyLink = async () => await navigator.clipboard.writeText(link); return mk.li({}, mk.div({ class: 'link-item' }, mk.button({ class: 'copy-icon', title: 'Copy', type: 'button', _onclick: copyLink, tabindex: 0, }, mk.span({ class: 'icon' }) ), mk.span({}, link) ) ); }) ) ]; } } /* Boilerplate: script-ref-hints */ "use strict"; { let refsData = { "#prerender-candidate": {"displayText":"prerender candidate","export":true,"for_":[],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"prerender candidate","type":"dfn","url":"#prerender-candidate"}, "#prerender-candidate-target-navigable-name-hint": {"displayText":"target navigable name hint","export":true,"for_":["prerender candidate"],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"target navigable name hint","type":"dfn","url":"#prerender-candidate-target-navigable-name-hint"}, "#speculation-rule-set-prerender-rules": {"displayText":"prerender rules","export":true,"for_":["speculation rule set"],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"prerender rules","type":"dfn","url":"#speculation-rule-set-prerender-rules"}, "#speculation-rule-target-navigable-name-hint": {"displayText":"target navigable name hint","export":true,"for_":["speculation rule"],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"target navigable name hint","type":"dfn","url":"#speculation-rule-target-navigable-name-hint"}, "50adabbe_https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set": {"displayText":"parse a speculation rule set string","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"parse a speculation rule set string","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"}, "https://console.spec.whatwg.org/#report-a-warning-to-the-console": {"displayText":"report a warning to the console","export":true,"for_":[],"level":"1","normative":true,"shortname":"console","spec":"console","status":"current","text":"report a warning to the console","type":"dfn","url":"https://console.spec.whatwg.org/#report-a-warning-to-the-console"}, "https://dom.spec.whatwg.org/#concept-element-attributes-change-ext": {"displayText":"attribute change steps","export":true,"for_":[],"level":"1","normative":true,"shortname":"dom","spec":"dom","status":"current","text":"attribute change steps","type":"dfn","url":"https://dom.spec.whatwg.org/#concept-element-attributes-change-ext"}, "https://html.spec.whatwg.org/multipage/document-sequences.html#valid-navigable-target-name-or-keyword": {"displayText":"valid navigable target name or keyword","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"valid navigable target name or keyword","type":"dfn","url":"https://html.spec.whatwg.org/multipage/document-sequences.html#valid-navigable-target-name-or-keyword"}, "https://html.spec.whatwg.org/multipage/image-maps.html#the-area-element": {"displayText":"area","export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"area","type":"element","url":"https://html.spec.whatwg.org/multipage/image-maps.html#the-area-element"}, "https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target": {"displayText":"target","export":true,"for_":["a","area"],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"target","type":"element-attr","url":"https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target"}, "https://html.spec.whatwg.org/multipage/links.html#concept-hyperlink-url": {"displayText":"url","export":true,"for_":["HTMLHyperlinkElementUtils"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"url","type":"dfn","url":"https://html.spec.whatwg.org/multipage/links.html#concept-hyperlink-url"}, "https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element": {"displayText":"a","export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"a","type":"element","url":"https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element"}, "https://infra.spec.whatwg.org/#list": {"displayText":"list","export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"list","type":"dfn","url":"https://infra.spec.whatwg.org/#list"}, "https://infra.spec.whatwg.org/#list-append": {"displayText":"append","export":true,"for_":["list"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"append","type":"dfn","url":"https://infra.spec.whatwg.org/#list-append"}, "https://infra.spec.whatwg.org/#list-iterate": {"displayText":"for each","export":true,"for_":["list","set"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"for each","type":"dfn","url":"https://infra.spec.whatwg.org/#list-iterate"}, "https://infra.spec.whatwg.org/#map-exists": {"displayText":"exist","export":true,"for_":["map"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"exist","type":"dfn","url":"https://infra.spec.whatwg.org/#map-exists"}, "https://infra.spec.whatwg.org/#string": {"displayText":"string","export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"string","type":"dfn","url":"https://infra.spec.whatwg.org/#string"}, "https://infra.spec.whatwg.org/#struct": {"displayText":"struct","export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"struct","type":"dfn","url":"https://infra.spec.whatwg.org/#struct"}, "https://infra.spec.whatwg.org/#struct-item": {"displayText":"item","export":true,"for_":["struct","tuple"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"item","type":"dfn","url":"https://infra.spec.whatwg.org/#struct-item"}, "https://whatpr.org/html/11426/semantics.html#get-an-element's-target": {"displayText":"get an element's target","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"get an element's target","type":"dfn","url":"https://whatpr.org/html/11426/semantics.html#get-an-element's-target"}, "https://whatpr.org/html/11426/speculative-loading.html#collect-tags-from-speculative-load-candidates": {"displayText":"collecting tags from speculative load candidates","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"collecting tags from speculative load candidates","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#collect-tags-from-speculative-load-candidates"}, "https://whatpr.org/html/11426/speculative-loading.html#compute-speculative-load-referrer-policy": {"displayText":"compute a speculative load referrer policy","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"compute a speculative load referrer policy","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#compute-speculative-load-referrer-policy"}, "https://whatpr.org/html/11426/speculative-loading.html#consider-speculative-loads": {"displayText":"consider speculative loads","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"consider speculative loads","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#consider-speculative-loads"}, "https://whatpr.org/html/11426/speculative-loading.html#document-sr-sets": {"displayText":"speculation rule sets","export":true,"for_":["Document"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculation rule sets","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#document-sr-sets"}, "https://whatpr.org/html/11426/speculative-loading.html#finding-matching-links": {"displayText":"finding matching links","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"finding matching links","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#finding-matching-links"}, "https://whatpr.org/html/11426/speculative-loading.html#inner-consider-speculative-loads-steps": {"displayText":"inner consider speculative loads steps","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"inner consider speculative loads steps","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#inner-consider-speculative-loads-steps"}, "https://whatpr.org/html/11426/speculative-loading.html#parse-a-speculation-rule": {"displayText":"parse a speculation rule","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"parse a speculation rule","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#parse-a-speculation-rule"}, "https://whatpr.org/html/11426/speculative-loading.html#prefetch-candidate": {"displayText":"prefetch candidate","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"prefetch candidate","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#prefetch-candidate"}, "https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-anonymization-policy": {"displayText":"anonymization policy","export":true,"for_":["prefetch candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"anonymization policy","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-anonymization-policy"}, "https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-eagerness": {"displayText":"eagerness","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"eagerness","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-eagerness"}, "https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-nvs-hint": {"displayText":"No-Vary-Search hint","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"no-vary-search hint","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-nvs-hint"}, "https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-referrer-policy": {"displayText":"referrer policy","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"referrer policy","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-referrer-policy"}, "https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-tags": {"displayText":"tags","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"tags","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-tags"}, "https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-url": {"displayText":"URL","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"url","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-url"}, "https://whatpr.org/html/11426/speculative-loading.html#speculation-rule": {"displayText":"speculation rule","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculation rule","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule"}, "https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set": {"displayText":"speculation rule set","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculation rule set","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"}, "https://whatpr.org/html/11426/speculative-loading.html#speculative-load-candidate": {"displayText":"speculative load candidate","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculative load candidate","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculative-load-candidate"}, "https://whatpr.org/html/11426/speculative-loading.html#sr-eagerness": {"displayText":"eagerness","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"eagerness","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-eagerness"}, "https://whatpr.org/html/11426/speculative-loading.html#sr-nvs-hint": {"displayText":"No-Vary-Search hint","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"no-vary-search hint","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-nvs-hint"}, "https://whatpr.org/html/11426/speculative-loading.html#sr-predicate": {"displayText":"predicate","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"predicate","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-predicate"}, "https://whatpr.org/html/11426/speculative-loading.html#sr-requirements": {"displayText":"requirements","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"requirements","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-requirements"}, "https://whatpr.org/html/11426/speculative-loading.html#sr-set-prefetch": {"displayText":"prefetch rules","export":true,"for_":["speculation rule set"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"prefetch rules","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-set-prefetch"}, "https://whatpr.org/html/11426/speculative-loading.html#sr-tags": {"displayText":"tags","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"tags","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-tags"}, "https://whatpr.org/html/11426/speculative-loading.html#sr-urls": {"displayText":"URLs","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"urls","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-urls"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record": {"displayText":"prefetch record","export":true,"for_":[],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"prefetch record","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy": {"displayText":"anonymization policy","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"anonymization policy","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint": {"displayText":"No-Vary-Search hint","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"no-vary-search hint","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-target-navigable-name-hint": {"displayText":"prerendering target navigable name hint","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"prerendering target navigable name hint","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-target-navigable-name-hint"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-traversable": {"displayText":"prerendering traversable","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"prerendering traversable","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-traversable"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy": {"displayText":"referrer policy","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"referrer policy","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source": {"displayText":"source","export":true,"for_":["prefetch record"],"level":"","normative":true,"shortname":"prefetch","spec":"prefetch","status":"anchor-block","text":"source","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags": {"displayText":"tags","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"tags","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags"}, "https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url": {"displayText":"URL","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"url","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url"}, "https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch": {"displayText":"start a referrer-initiated navigational prefetch","export":true,"for_":[],"level":"","normative":true,"shortname":"prefetch","spec":"prefetch","status":"anchor-block","text":"start a referrer-initiated navigational prefetch","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch"}, "https://wicg.github.io/nav-speculation/prerendering.html#start-a-referrer-initiated-navigational-prerender": {"displayText":"start a referrer-initiated navigational prerender","export":true,"for_":[],"level":"","normative":true,"shortname":"prerendering-revamped","spec":"prerendering-revamped","status":"anchor-block","text":"start a referrer-initiated navigational prerender","type":"dfn","url":"https://wicg.github.io/nav-speculation/prerendering.html#start-a-referrer-initiated-navigational-prerender"}, }; function mkRefHint(link, ref) { const linkText = link.textContent; let dfnTextElements = ''; if (ref.displayText.toLowerCase() != linkText.toLowerCase()) { // Give the original term if it's being displayed in a different way. // But allow casing differences, they're insignificant. dfnTextElements = mk.li({}, mk.b({}, "Term: "), mk.span({}, ref.displayText) ); } const forList = ref.for_; let forListElements; if(forList.length == 0) { forListElements = []; } else if(forList.length == 1) { forListElements = mk.li({}, mk.b({}, "For: "), mk.span({}, forList[0]), ); } else { forListElements = mk.li({}, mk.b({}, "For: "), mk.ul({}, ...forList.map(forItem => mk.li({}, mk.span({}, forItem) ), ), ), ); } const url = ref.url; const safeUrl = encodeURIComponent(url); const hintPanel = mk.aside({ class: "ref-hint", id: `ref-hint-for-${safeUrl}`, "data-for": url, "aria-labelled-by": `ref-hint-for-${safeUrl}`, }, mk.ul({}, dfnTextElements, mk.li({}, mk.b({}, "URL: "), mk.a({ href: url, class: "ref" }, url), ), mk.li({}, mk.b({}, "Type: "), mk.span({}, `${ref.type}`), ), mk.li({}, mk.b({}, "Spec: "), mk.span({}, `${ref.spec ? ref.spec : ''}`), ), forListElements ), ); hintPanel.forLink = link; setupRefHintEventListeners(link, hintPanel); return hintPanel; } function hideAllRefHints() { queryAll(".ref-hint").forEach(el=>hideRefHint(el)); } function hideRefHint(refHint) { const link = refHint.forLink; link.setAttribute("aria-expanded", "false"); if(refHint.teardownEventListeners) { refHint.teardownEventListeners(); } refHint.remove(); } function showRefHint(link) { if(link.classList.contains("dfn-link")) return; const url = link.getAttribute("href"); const refHintKey = link.getAttribute("data-refhint-key"); let key = url; if(refHintKey) { key = refHintKey + "_" + url; } const ref = refsData[key]; if(!ref) return; hideAllRefHints(); // Only display one at this time. const refHint = mkRefHint(link, ref); append(document.body, refHint); link.setAttribute("aria-expanded", "true"); positionRefHint(refHint); } function setupRefHintEventListeners(link, refHint) { if (refHint.teardownEventListeners) return; // Add event handlers to hide the refHint after the user moves away // from both the link and refHint, if not hovering either within one second. let timeout = null; const startHidingRefHint = (event) => { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(() => { hideRefHint(refHint); }, 1000); } const resetHidingRefHint = (event) => { if (timeout) clearTimeout(timeout); timeout = null; }; link.addEventListener("mouseleave", startHidingRefHint); link.addEventListener("mouseenter", resetHidingRefHint); link.addEventListener("blur", startHidingRefHint); link.addEventListener("focus", resetHidingRefHint); refHint.addEventListener("mouseleave", startHidingRefHint); refHint.addEventListener("mouseenter", resetHidingRefHint); refHint.addEventListener("blur", startHidingRefHint); refHint.addEventListener("focus", resetHidingRefHint); refHint.teardownEventListeners = () => { // remove event listeners resetHidingRefHint(); link.removeEventListener("mouseleave", startHidingRefHint); link.removeEventListener("mouseenter", resetHidingRefHint); link.removeEventListener("blur", startHidingRefHint); link.removeEventListener("focus", resetHidingRefHint); refHint.removeEventListener("mouseleave", startHidingRefHint); refHint.removeEventListener("mouseenter", resetHidingRefHint); refHint.removeEventListener("blur", startHidingRefHint); refHint.removeEventListener("focus", resetHidingRefHint); }; } function positionRefHint(refHint) { const link = refHint.forLink; const linkPos = getBounds(link); refHint.style.top = linkPos.bottom + "px"; refHint.style.left = linkPos.left + "px"; const panelPos = refHint.getBoundingClientRect(); const panelMargin = 8; const maxRight = document.body.parentNode.clientWidth - panelMargin; if (panelPos.right > maxRight) { const overflowAmount = panelPos.right - maxRight; const newLeft = Math.max(panelMargin, linkPos.left - overflowAmount); refHint.style.left = newLeft + "px"; } } // TODO: shared util // Returns the root-level absolute position {left and top} of element. function getBounds(el, relativeTo=document.body) { const relativeRect = relativeTo.getBoundingClientRect(); const elRect = el.getBoundingClientRect(); const top = elRect.top - relativeRect.top; const left = elRect.left - relativeRect.left; return { top, left, bottom: top + elRect.height, right: left + elRect.width, } } function showRefHintListener(e) { // If the target isn't in a link (or is a link), // just ignore it. let link = e.target.closest("a"); if(!link) return; // If the target is in a ref-hint panel // (aka a link in the already-open one), // also just ignore it. if(link.closest(".ref-hint")) return; // Otherwise, show the panel for the link. showRefHint(link); } function hideAllHintsListener(e) { // If the click is inside a ref-hint panel, ignore it. if(e.target.closest(".ref-hint")) return; // Otherwise, close all the current panels. hideAllRefHints(); } document.addEventListener("DOMContentLoaded", () => { document.body.addEventListener("mousedown", showRefHintListener); document.body.addEventListener("focus", showRefHintListener); document.body.addEventListener("click", hideAllHintsListener); }); window.addEventListener("resize", () => { // Hide any open ref hint. hideAllRefHints(); }); } /* Boilerplate: script-var-click-highlighting */ "use strict"; { /* Color-choosing design: * Colors are ordered by goodness. * On clicking a var, give it the earliest color with the lowest usage in the algorithm. * On re-clicking, re-use the var's most recent color if that's not currently being used elsewhere. */ const COLOR_COUNT = 7; document.addEventListener("click", e=>{ if(e.target.nodeName == "VAR") { highlightSameAlgoVars(e.target); } }); function highlightSameAlgoVars(v) { // Find the algorithm container. let algoContainer = findAlgoContainer(v); // Not highlighting document-global vars, // too likely to be unrelated. if(algoContainer == null) return; const varName = nameFromVar(v); if(!v.hasAttribute("data-var-color")) { const newColor = chooseHighlightColor(algoContainer, v); for(const el of algoContainer.querySelectorAll("var")) { if(nameFromVar(el) == varName) { el.setAttribute("data-var-color", newColor); el.setAttribute("data-var-last-color", newColor); } } } else { for(const el of algoContainer.querySelectorAll("var")) { if(nameFromVar(el) == varName) { el.removeAttribute("data-var-color"); } } } } function findAlgoContainer(el) { while(el != document.body) { if(el.hasAttribute("data-algorithm")) return el; el = el.parentNode; } return null; } function nameFromVar(el) { return el.textContent.replace(/(\s|\xa0)+/g, " ").trim(); } function colorCountsFromContainer(container) { const namesFromColor = Array.from({length:COLOR_COUNT}, x=>new Set()); for(let v of container.querySelectorAll("var[data-var-color]")) { let color = +v.getAttribute("data-var-color"); namesFromColor[color].add(nameFromVar(v)); } return namesFromColor.map(x=>x.size); } function leastUsedColor(colors) { // Find the earliest color with the lowest count. let minCount = Infinity; let minColor = null; for(var i = 0; i < colors.length; i++) { if(colors[i] < minCount) { minColor = i; minCount = colors[i]; } } return minColor; } function chooseHighlightColor(container, v) { const colorCounts = colorCountsFromContainer(container); if(v.hasAttribute("data-var-last-color")) { let color = +v.getAttribute("data-var-last-color"); if(colorCounts[color] == 0) return color; } return leastUsedColor(colorCounts); } }