diff --git a/spec.bs b/spec.bs
index e30ffa49..42aeac02 100644
--- a/spec.bs
+++ b/spec.bs
@@ -30,6 +30,9 @@ spec: prerendering-revamped; urlPrefix: https://wicg.github.io/nav-speculation/p
for: navigable
text: loading mode; url: #navigable-loading-mode
+spec: fetch; urlPrefix: https://fetch.spec.whatwg.org/
+ type: dfn
+ text: queue a cross-origin embedder policy CORP violation report; url: queue-a-cross-origin-embedder-policy-corp-violation-report
spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
type: dfn
urlPrefix: browsers.html
@@ -86,12 +89,36 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
urlPrefix: interaction.html
text: activation notification; url: activation-notification
text: consume user activation; url: consume-user-activation
+ text: activation; url: activation
+ text: click focusable; url: click-focusable
+ text: focusable area; url: focusable-area
+ text: sequential focus navigation; url: sequential-focus-navigation
+ text: focus; url: dom-window-focus
+ text: focus chain; url: focus-chain
+ text: focus update steps; url: focus-update-steps
+ text: focused; url: focused
+ text: gain focus; url: gains-focus
+ text: DOM anchor; url: dom-anchor
+ text: get the focusable area; url: get-the-focusable-area
+ text: currently focused area of a top-level traversable; url: currently-focused-area-of-a-top-level-traversable
+ text: focused area; url: focused-area-of-the-document
+ text: sequential navigation search algorithm; url: sequential-navigation-search-algorithm
+ urlPefix: infrastructure.html
+ text: immediately; url: immediately
urlPrefix: nav-history-apis.html
for: Window
text: navigable; url: window-navigable
-spec: fetch; urlPrefix: https://fetch.spec.whatwg.org/
- type: dfn
- text: queue a cross-origin embedder policy CORP violation report; url: queue-a-cross-origin-embedder-policy-corp-violation-report
+ urlPrefix: interactive-elements.html
+ text: accesskey attribute command; url: using-the-accesskey-attribute-to-define-a-command-on-other-elements
+ text: previously focused element; url: previously-focused-element
+ urlPrefix: popover.html
+ text: hide popover algorithm; url: hide-popover-algorithm
+ urlPrefix: form-control-infrastructure.html
+ text: interactively validate the constraints; url: interactively-validate-the-constraints
+ urlPrefix: custom-elements.html
+ text: face validation anchor; url: face-validation-anchor
+ urlPrefix: webappapis.html
+ text: fire a click event; url: fire-a-click-event
spec: RFC8941; urlPrefix: https://www.rfc-editor.org/rfc/rfc8941.html
type: dfn
text: structured header; url: #section-1
@@ -759,6 +786,185 @@ in the [[#nested-traversables-intro]].
1. Return |navigables|.
+
Modifications to the focusing algorithms
+
+The [[HTML]] standard defines how to handle focusing elements and {{Window}}s, both by user gesture
+and through script-initiated APIs. Since fenced frames are designed to prevent communication across
+a fenced frame boundary, we need to handle focusing carefully. This is because when focus is pulled
+across a fenced frame boundary, contexts on both sides of the boundary can detect that change, which
+can be used to open a communication channel between a <{fencedframe}> and its embedder.
+
+We do this is by not allowing the [=focusing steps=] to move script-initiated focus across a fenced
+frame boundary.
+
+When a user clicks on an element like a <{button}> inside a
+<{fencedframe}> while another element *outside* of the <{fencedframe}> is [=focused=], because this
+is a user-initiated action, the [=focusing steps=] will allow the <{button}> to [=gain focus=].
+Without allowing that, no element inside of a <{fencedframe}> would never be able [=gain
+focus=].
+
+If we were to continue blindly allowing all elements to
+be [=focused=] via the {{HTMLOrSVGElement/focus()}} method as is the status quo before this
+specification, a [=fenced navigable container=] and its [=fenced navigable container/fenced
+navigable=] could use a sequence of {{HTMLOrSVGElement/focus()}} calls to send arbitrary data across
+the fenced frame boundary, which is a privacy leak. To avoid this, we effectively "fence" the
+{{HTMLOrSVGElement/focus()}} method, which sacrifices some functionality for privacy.
+
+
+ Modify the [=focusing steps=] to take a new optional [=boolean=] argument unfenced that defaults to false.
+
+ Add a new step after step 3 of the algorithm (that changes new focus target) that reads:
+
+ 4. If |new focus target| is a [=fenced navigable container=] with non-null
+ [=fenced navigable container/fenced navigable=], then set |new focus target| to the
+ [=fenced navigable container/fenced navigable=]'s [=navigable/active document=].
+
+ Add a new step after the step that defines the |new chain| variable, that reads:
+
+ 9. If [=focus-unfenced|unfenced=] is false, |new chain| [=list/contains=] a {{Document}}
+ |document| whose [=node navigable=]'s [=navigable/traversable navigable=] is a
+ [=fenced navigable container/fenced navigable=], and old chain does not also
+ [=list/contain=] |document|, then return.
+
+ Note: This is how we bail-out early just before calling the [=focus update steps=], in the case
+ where focus is trying to cross the fence.
+
+ Modify the user agent sentence after the algorithm steps in [=focusing steps=] to read:
+
+ User agents must [=immediately=] run the [=focusing steps=] for a [=focusable area=] or
+ [=navigable=] |candidate| with [=focus-unfenced|unfenced=] set to true whenever the user attempts to
+ move the focus to |candidate|.
+
+
+
+ Modify the action of the [=accesskey attribute command=] algorithm to be:
+
+ 1. Run the [=focusing steps=] for the element with [=focus-unfenced|unfenced=] set to true.
+
+ 1.
Fire a `click` event at the element.
+
+
+
+ Modify the behavior when a user [=activation|activates=] a [=click focusable=] [=focusable area=]
+ to be:
+
+ When a user [=activation|activates=] a [=click focusable=] [=focusable area=], the user agent must
+ run the [=focusing steps=] on the [=focusable area=] with focus trigger set
+ to "`click`" and [=focus-unfenced|unfenced=] set to true.
+
+
+
+ Modify step 10 of the [=hide popover algorithm=] to read:
+
+ 10. If |previouslyFocusedElement| is not null, then:
+ 1. Set element's [=previously focused element=] to null.
+ 2. If focusPreviousElement is true, then run the [=focusing steps=] for
+ |previouslyFocusedElement| with [=focus-unfenced|unfenced=] set to true; the viewport
+ should not be scrolled by doing this step.
+
+ Note: Although dismissing a popover manually is a user-initiated gesture, the
+ [=focusing steps=] will be called with [=focus-unfenced|unfenced=] set to false regardless
+ of whether this was called from user gesture or via a script call.
+
+
+
+ Modify the first bullet point of step 3 of the [=interactively validate the constraints=]
+ algorithm to read:
+
+ * User agents may focus one of those elements in the process, by running the
+ [=focusing steps=] for that element, and may change the scrolling position of the
+ document, or perform some other action that brings the element to the user's attention.
+ If these steps were invoked by user gesture, [=focusing steps=] can be called with
+ [=focus-unfenced|unfenced=] set to true. For elements that are
+ [=form-associated custom elements=], user agents should use their [=face validation anchor=]
+ instead, for the purposes of these actions.
+
+
+
+ Add a step after step 2 of the while loop in the [=has focus steps=] algorithm that reads:
+
+ 3. If the [=focused area=] of |candidate| is a [=fenced navigable container=] with a non-null
+ [=fenced navigable container/fenced navigable=], then set |candidate| to the [=navigable/active
+ document=] of that [=fenced navigable container=]'s [=fenced navigable container/fenced
+ navigable=].
+
+
+
+ Modify step 3 of the while loop in the [=focus chain=] algorithm to read:
+ 3. If |currentObject| is a [=focusable area=], then set |currentObject| to |currentObject|'s [=DOM
+ anchor=]'s [=Node/node document=].
+
+ Otherwise, if |currentObject| is a {{Document}} whose [=node navigable=]'s [=navigable/parent=]
+ is non-null, then set |currentObject| to |currentObject|'s [=node navigable=]'s
+ [=navigable/parent=].
+
+ Otherwise, if |currentObject| is a {{Document}} whose [=node navigable=] is a [=traversable
+ navigable=] whose [=traversable navigable/unfenced parent=] is non-null, then set
+ |currentObject| to |currentObject|'s [=node navigable=]'s [=traversable navigable/unfenced
+ parent=].
+
+ Otherwise, [=iteration/break=].
+
+
+
+ Modify the [=get the focusable area=] algorithm. Add a new case to the switch statement:
+
+
+ - If focus target is a [=fenced navigable container=] with a non-null [=fenced navigable container/fenced navigable=]
+
+ Return the [=fenced navigable container=]'s [=fenced navigable container/fenced
+ navigable=]'s [=navigable/active document=].
+
+
+ Note: This algorithm can unconditionally "jump the fence" boundary because its return value always
+ feeds into an algorithm that _does_ carefully consider the fence boundary.
+
+
+
+ Modify step 3 of the [=currently focused area of a top-level traversable=] algorithm to read:
+
+ 3. While |candidate|'s [=focused area=] is either a [=navigable container=] with a non-null
+ [=navigable container/content navigable=] or a [=fenced navigable container=] with a non-null
+ [=fenced navigable container/fenced navigable=]: set |candidate| to the
+ [=navigable/active document=] of either that [=navigable container=]'s
+ [=navigable container/content navigable=] or that [=fenced navigable container=]'s
+ [=fenced navigable container/fenced navigable=], whichever is non-null.
+
+
+
+ Modify step 6 of the [=sequential focus navigation=] algorithm to read:
+
+ 6. If |candidate| is not null, then run the [=focusing steps=] for
+ |candidate| with [=focus-unfenced|unfenced=] set to true and return.
+
+ Modify step 9 of the [=sequential focus navigation=] algorithm to read:
+
+ 9. Otherwise, |starting point| is a [=focusable area=] in a [=child navigable=] or
+ [=fenced navigable container/fenced navigable=]. Set |starting point| to that
+ [=child navigable=] or [=fenced navigable container/fenced navigable=]'s
+ [=traversable navigable/unfenced parent=] and return to the step labeled loop.
+
+
+
+ Modify step 2 of the [=sequential navigation search algorithm=] to read:
+
+ 2. If |candidate| is a [=navigable container=] with a non-null
+ [=navigable container/content navigable=], then let |new candidate| be the result of running the
+ [=sequential navigation search algorithm=] with |candidate|'s
+ [=navigable container/content navigable=] as the first argument, direction as
+ the second, and sequential as the third.
+
+ If |candidate| is a [=fenced navigable container=] with a non-null
+ [=fenced navigable container/fenced navigable=], then let |new candidate| be the result of
+ running the [=sequential navigation search algorithm=] with |candidate|'s
+ [=fenced navigable container/fenced navigable=] as the first argument,
+ direction as the second, and sequential as the third.
+
+ If |new candidate| is null, then let starting point
+ be |candidate|, and return to the top of this algorithm. Otherwise, let
+ |candidate| be |new candidate|.
+
Navigation