Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 45 additions & 16 deletions css-nav-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ the specification remains the full document.

<input type=checkbox id=api-check> <label for=api-check>Hide JavaScript APIs, including events</label><br>
<input type=checkbox id=cssapi-check> <label for=cssapi-check>Hide CSS properties that enable selecting behavior variants, and related information</label><br>
<input type=checkbox id=verbose-check> <label for=verbose-check>Hide informative sections that explain and summarise normative sections without adding more information</label><br>
<input type=checkbox id=verbose-check> <label for=verbose-check>Hide informative sections that explain and summarize normative sections without adding more information</label><br>

<h2 id="intro" class=non-normative>
Introduction</h2>
Expand Down Expand Up @@ -209,7 +209,7 @@ until it has either moved focus,
scrolled,
or reached the root.

Note: As a consequnce of this processing model,
Note: As a consequence of this processing model,
the elements that are reachable by sequential navigation
and by spatial navigation are almost the same:
elements that are currently outside of the viewport of a scrollable element
Expand Down Expand Up @@ -394,7 +394,7 @@ JavaScript API</h2>
<h3 id=high-level-api>
Triggering Navigation Programmatically</h3>

The {{Window/navigate()}} method enables the author to trigger spatial navigation programatically,
The {{Window/navigate()}} method enables the author to trigger spatial navigation programmatically,
as if the user had done so manually
(for instance, by pressing the arrow keys in a browser where that is the way to trigger spatial navigation).

Expand Down Expand Up @@ -483,14 +483,44 @@ The {{Element/getSpatialNavigationContainer()}} method must follow these steps:

<div algorithm="focusableAreas steps">
The {{Element/focusableAreas()}} method must follow these steps:
1. Let <var>v</var> be <code>false</code>
if the argument's {{FocusableAreasOptions/mode}} attribute if present and equal to <code>"all"</code>,
1. Let <var>visibleOnly</var> be <code>false</code>
if the argument's {{FocusableAreasOptions/mode}} attribute is present and equal to <code>'all'</code>,
or <code>true</code> otherwise.
4. Let <var>areas</var> be the result of <a>finding focusable areas</a> within the element with the visibleOnly argument set to <var>v</var>
2. Let <var>areas</var> be the result of <a>finding focusable areas</a> within the element with the <var>visibleOnly</var> argument.
3. Loop: If there is a <a>spatial navigation container</a> <var>container</var> among <var>areas</var>,
then add the result of <a>finding focusable areas</a> to <var>areas</var> within the <var>container</var>.
5. Let <var>anchors</var> be a <a for=list>clone</a> of <var>areas</var>,
with every <a>focusable area</a> which is not itself a <a>Node</a> replaced with its <a>DOM anchor</a>.
6. Return <var>anchors</var>
</div>

<div class=example id=focusAreas-visible>
The following code shows how to get all the visible focusable elements in the current page using {{Element/focusableAreas()}}.
If the method finds a <a>spatial navigation container</a>, it recursively finds focusable areas inside it.
However, <code>'visible'</code> is given to the {{FocusableAreasOptions/mode}} attribute of this method,
the focusable element which isn’t inside the <a>scrollport</a> is excluded from the result.

<pre><code highlight=markup>
&lt;body>
&lt;button class="box" style="top:100px; left:20px;">&lt;/button>
&lt;div class="container" style="left:110px; width:300px; height:200px; overflow-x: scroll;">
&lt;button class="box" style="top:78px; left:25px;">&lt;/button>
&lt;button class="box" style="top: 80px; left:150px;">&lt;/button>
&lt;button class="box" style="top: 80px; left:350px;">&lt;/button>
&lt;/div>
&lt;/body>
</code></pre>
<pre><code highlight=javascript>
const focusableAreas = document.body.focusableAreas({'mode': 'visible'});
focusableAreas && focusableAreas.forEach(focusable => {
focusable.style.outline = '5px solid red';
});
</code></pre>
The figure below is the result of this code.
<figure>
<img alt="An image about focusableAreas()" src="images/focusableareas-visible-example.png" style="width: 450px;"/>
<figcaption>Find all visible focusable areas inside the document.</figcaption>
</figure>
</div>

<div algorithm="spatialNavigationSearch steps">
Expand Down Expand Up @@ -537,7 +567,7 @@ and the result will be <code>null</code>.</strong>
The following code changes the behavior of spatial navigation
so that when a scroll container would get focused,
if it has at least one visible focusable descendant,
the focus is automatically transfered to it.
the focus is automatically transferred to it.

<pre><code highlight=javascript>
document.addEventListener("navbeforefocus", function(e) {
Expand Down Expand Up @@ -566,14 +596,14 @@ and the result will be <code>null</code>.</strong>
<div class=example id=loop>
The following code changes the behavior of spatial navigation
to trap the focus within a spatial navigation container:
when no further focusable elements can be found in the requested direcition
when no further focusable elements can be found in the requested direction
and the spatial navigation container cannot be scrolled any futher,
we loop back to the other side instead of searching outside of it,
either by focusing or scrolling depending on what is available.

The focus can still be moved outside by sequential navigation,
mouse interaction,
programatic calls to {{focus()}}…
programmatic calls to {{focus()}}…

<pre><code highlight=javascript>
document.addEventListener("navnotarget", function(e) {
Expand Down Expand Up @@ -863,11 +893,11 @@ and it cannot be scrolled at the same time.
For the sake of keeping the description simple,
this example assumes a UA where spatial navigation is triggered using arrow keys.

<figure>
<img alt="An image about navnotarget" src="images/navnotarget-example-1.png" style="width: 200px;"/>
<figcaption>Moving focus when there isn't any candidate in the
<a>scroll container</a>.</figcaption>
</figure>
<figure>
<img alt="An image about navnotarget" src="images/navnotarget-example-1.png" style="width: 200px;"/>
<figcaption>Moving focus when there isn't any candidate in the
<a>scroll container</a>.</figcaption>
</figure>

<table class="complex data">
<thead>
Expand Down Expand Up @@ -983,15 +1013,14 @@ The <a>navigation-override</a> [=policy-controlled feature=]</h2>
We recognize that there exists other mechanisms predating spatial navigation
that malicious authors could use
to interfere with the user's ability to control where the focus goes.
Despite that, it seems worthwile to attempt not to increase this attack surface,
Despite that, it seems worthwhile to attempt not to increase this attack surface,
although it is possible that such attacks are already sufficiently easy to perform
that this is a lost cause.
Further feedback on this topic,
based on experience with implementation or with mitigating such attacks,
is very welcome.



<h2 id=processing-model>
Processing Model</h2>

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.