From 104b82b20e75271476e6d3243a4b75574e6db036 Mon Sep 17 00:00:00 2001
From: "Patrick H. Lauke"
Date: Fri, 22 Nov 2024 18:05:19 +0000
Subject: [PATCH 01/14] Change "NEW" marker to use W3C blue background (#4145)
Instead of the original red - see
https://github.com/w3c/wcag/pull/1481#issuecomment-2447584448
---
guidelines/guidelines.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/guidelines/guidelines.css b/guidelines/guidelines.css
index e7ca78324b..889a6ab499 100644
--- a/guidelines/guidelines.css
+++ b/guidelines/guidelines.css
@@ -5,7 +5,7 @@
.change {
display: inline;
color: #fff;
- background: #B50000;
+ background: #005A9C;
border-radius: 0.25em;
padding: 0.25em 0.4em;
margin: 0 0.25em 0 0;
From aa4315333622dbc61571e7d9fc52a804d4f74e96 Mon Sep 17 00:00:00 2001
From: "Patrick H. Lauke"
Date: Fri, 22 Nov 2024 18:49:19 +0000
Subject: [PATCH 02/14] Add explanation of what "automatic" means in 2.2.2 and
1.4.2, cross-reference (#4012)
Closes https://github.com/w3c/wcag/issues/2863
This is an alternative to https://github.com/w3c/wcag/pull/2906 which
more directly addresses the definition, as well as providing further
explanation/cross-linking for overlapping SCs:
* removes the mention of "audio" from the intent for 2.2.2 Pause, Stop,
Hide, which is clearly aimed at visual content only
* adds a basic explanation of what's meant by "starts automatically" to
2.2.2
* adds relevant cross-references/overlaps to other SCs to 2.2.2
* adds a basic explanation of what's meant by "plays automatically" to
1.4.2 Audio Control
* adds a further clarification to 2.3.3 Animation from Interactions
---------
Co-authored-by: Alastair Campbell
Co-authored-by: Mike Gower
---
understanding/20/audio-control.html | 71 +-------
understanding/20/pause-stop-hide.html | 164 +++++-------------
.../21/animation-from-interactions.html | 54 +++---
3 files changed, 75 insertions(+), 214 deletions(-)
diff --git a/understanding/20/audio-control.html b/understanding/20/audio-control.html
index 5ebd2fc3b4..0009d2697e 100644
--- a/understanding/20/audio-control.html
+++ b/understanding/20/audio-control.html
@@ -1,157 +1,104 @@
-
+
Understanding Audio Control
Understanding Audio Control
-
+
In brief
Goal
A page that plays music or sounds doesn't disrupt people.
What to do
If you play audio content automatically, let people turn it down or off.
-
Why it's important
Sound distracts some people, and also interferes with screen readers.
+
Why it's important
Sound distracts some people, and also interferes with screen readers.
-
+
Intent of Audio Control
-
-
Individuals who use screen reading software can find it hard to hear the speech output
if there is other audio playing at the same time. This difficulty is exacerbated when
the screen reader's speech output is software based (as most are today) and is controlled
via the same volume control as the sound. Therefore, it is important that the user
- be able to turn off the background sound.
+ be able to turn off the background sound.
Having control of the volume includes
being able to reduce its volume to zero. Muting the system volume is not "pausing or stopping" the autoplay audio. Both the "pause or stop" and control of audio volume need to be independent of the overall system volume.
-
-
Playing audio automatically when landing on a page may affect a screen reader user's
ability to find the mechanism to stop it because they navigate by listening and automatically
started sounds might interfere with that navigation. Therefore, we discourage the
practice of automatically starting sounds (especially if they last more than 3 seconds),
- and encourage that the sound be
+ and encourage that the sound be
started by an action initiated by the user after they reach the page, rather than requiring
- that the sound be
+ that the sound be
stopped by an action of the user after they land on the page.
In the context of this Success Criterion, "plays automatically" broadly refers to audio that is not started/played as a direct result of a user's intentional activation. For example, not selecting a link or button.
Benefits of Audio Control
-
-
-
Individuals who use screen reading technologies can hear the screen reader without
other sounds playing. This is especially important for those who are hard of hearing
and for those whose screen readers use the system volume (so they cannot turn sound
down and screen reader up).
-
This Success Criterion also benefits people who have difficulty focusing on visual
content (including text) when audio is playing.
-
-
-
Examples of Audio Control
-
An audio file begins playing automatically when a page is opened. However, the audio
can be stopped by the user by selecting a "silent" link at the top of the page.
Fewer users are distracted by content that updates or moves.
What to do
Let users control content changes that occur in parallel with other content.
-
Why it's important
Some people with cognitive disabilities and attention deficits cannot concentrate with continual movement.
+
Why it's important
Some people with cognitive disabilities and attention deficits are distracted by continuous movement.
-
+
Intent of Pause, Stop, Hide
-
-
+
The intent of this Success Criterion is to avoid distracting users during their interaction
with a Web page.
-
+
+
In the context of this Success Criterion, "starts automatically" broadly refers to animations/updates
+ that are not the direct result of a user's intentional activation, for example, selecting a link or button.
+
"Moving, blinking and scrolling" refers to content in which the visible content conveys
a sense of motion. Common examples include motion pictures, synchronized media presentations,
animations, real-time games, and scrolling stock tickers. "Auto-updating" refers to
content that updates or disappears based on a preset time interval. Common time-based
- content includes audio, automatically updated weather information, news, stock price
+ content includes automatically updated weather information, news, stock price
updates, and auto-advancing presentations and messages. The requirements for moving,
blinking and scrolling content and for auto-updating content are the same except that:
-
+
-
-
authors have the option of providing the user with a means to control the frequency
- of updates when content is auto-updating and
-
-
-
there is no five second exception for auto-updating since it makes little sense to
- auto-update for a few seconds and then stop
-
-
+
authors have the option of providing the user with a means to control the frequency of updates when content is auto-updating and
+
there is no five second exception for auto-updating since it makes little sense to auto-update for a few seconds and then stop
-
+
Content that moves or auto-updates can be a barrier to anyone who has trouble reading
stationary text quickly as well as anyone who has trouble tracking moving objects.
It can also cause problems for screen readers.
-
+
Moving content can also be a severe distraction for some people. Certain groups, particularly
those with attention deficit disorders, find blinking content distracting, making
it difficult for them to concentrate on other parts of the Web page. Five seconds
was chosen because it is long enough to get a user's attention, but not so long that
a user cannot wait out the distraction if necessary to use the page.
-
+
Content that is paused can either resume in real-time or continue playing from the
point in the presentation where the user left off.
-
+
-
-
Pausing and resuming where the user left off is best for users who want to pause to
read content and works best when the content is not associated with a real-time event
or status.
-
-
-
See
- 2.2.1: Timing Adjustable for additional requirements related to time-limits for reading.
-
-
+
See 2.2.1: Timing Adjustable for additional requirements related to time-limits for reading and interactions.
-
-
-
Pausing and jumping to current display (when pause is released) is better for information
that is real-time or "status" in nature. For example, weather radar, a stock ticker,
a traffic camera, or an auction timer, would present misleading information if a pause
caused it to display old information when the content was restarted.
-
-
-
Hiding content would have the same result as pausing and jumping to current display
- (when pause is released).
-
-
+
Hiding content would have the same result as pausing and jumping to current display (when pause is released).
-
-
-
+
For a mechanism to be considered "a mechanism for the user to pause," it must provide
the user with a means to pause that does not tie up the user or the focus so that
the page cannot be used. The word "pause" here is meant in the sense of a "pause
@@ -110,58 +88,58 @@
Intent of Pause, Stop, Hide
moves the focus away) would not be considered a "mechanism for the user to pause"
because it makes the page unusable in the process and would not meet this SC.
-
-
It is important to note that the terms "blinking" and "flashing" can sometimes refer
- to the same content.
-
-
+
+
+
This Success Criterion is specifically concerned with moving, blinking, scrolling, and
+ auto-updating visual content. For audio content that starts automatically, refer to 1.4.2 Audio Control.
+
Moving, blinking, scrolling content that starts automatically because of a general user interaction (such as focusing/hovering over an element,
+ or scrolling the page), rather than as a result of an intentional activation (such as activating a button),
+ and which doesn't provide provide a way to Pause, Stop, or Hide, will fail this Criterion, and potentially
+ 2.3.3 Animation from Interaction.
+
+
+
It is important to note that the terms "blinking" and "flashing" can sometimes refer to the same content.
+
-
"Blinking" refers to content that causes a distraction problem. Blinking can be allowed
for a short time as long as it stops (or can be stopped)
-
"Flashing" refers to content that can trigger a seizure (if it is more than 3 per
second and large and bright enough). This cannot be allowed even for a second or it
could cause a seizure. And turning the flash off is also not an option since the seizure
could occur faster than most users could turn it off.
-
Blinking usually does not occur at speeds of 3 per second or more, but it can. If
blinking occurs faster than 3 per second, it would also be considered a flash.
Providing content that stops blinking after five seconds or providing a mechanism
for users to stop blinking content allows people with certain disabilities to interact
with the Web page.
-
One use of content that blinks is to draw the visitor's attention to that content.
Although this is an effective technique for all users with vision, it can be a problem
for some users if it persists. For certain groups, including people with low literacy,
reading and intellectual disabilities, and people with attention deficit disorders,
content that blinks may make it difficult or even impossible to interact with the
- rest of the Web page.
-
+ rest of the Web page.
-
-
-
Examples of Pause, Stop, Hide
-
An essential animation can be paused without affecting the activity
A Web site helps users understand 'how things work' through animations that demonstrate
@@ -195,127 +173,69 @@
Examples of Pause, Stop, Hide
for all users and because it is not presented in parallel with other content, no mechanism
to pause, stop or hide it needs to be provided.
Support user preferences for motion, and eliminate unnecessary motion effects.
Why it's important
People can get sick from motion effects.
-
-
-
+
+
+
Intent
The intent of this Success Criterion is to allow users to prevent animation from being displayed on Web pages. Some users experience distraction or nausea from animated content. For example, if scrolling a page causes elements to move (other than the essential movement associated with scrolling) it can trigger vestibular disorders. Vestibular (inner ear) disorder reactions include dizziness, nausea and headaches. Another animation that is often non-essential is parallax scrolling. Parallax scrolling occurs when backgrounds move at a different rate to foregrounds. Animation that is essential to the functionality or information of a web page is allowed by this Success Criterion.
-
"Animation from interactions" applies when a user’s interaction initiates non-essential animation. In contrast, 2.2.2 Pause, Stop, Hide applies when the web page initiates animation.
+
"Animation from interactions" applies when a user’s interaction initiates non-essential animation. In contrast, 2.2.2 Pause, Stop, Hide applies when the web page initiates animation "automatically" that is not in response to an intentional user activation. There may be situations where a particular animation may fail both Success Criteria.
The impact of animation on people with vestibular disorders can be quite severe. Triggered reactions include nausea, migraine headaches, and potentially needing bed rest to recover.
How can a website reduce the chances of triggering a vestibular disorder? Choose any one of the following solutions. Avoid using unnecessary animation. Provide a control for users to turn off non-essential animations from user interaction. Take advantage of the reduce motion feature in the user agent or operating system.
-
+
What about movement caused by a user scrolling a page? Moving new content into the viewport is essential for scrolling. The user controls the essential scrolling movement so it is allowed. Only add non-essential animation to the scrolling interaction in a responsible way. Always give users the ability to turn off unnecessary movement.
@@ -44,35 +44,29 @@
Benefits
Examples
-
-
Parallax scrolling with option to turn off unnecessary motion globally:
-
-
A site includes extra animations when the user scrolls. Decorative elements move in and out of view horizontally when the essential page content is scrolled vertically. A control at the top of each page allows the user to turn off unnecessary animations. The ability to turn off non-essential animations is a site-wide setting.
-
-
-
Transitions that support the reduce motion preference:
-
-
A site includes a non-essential transition when loading new content. The transition is a page-flipping animation that respects the reduce-motion CSS media query. When the user enables the reduce motion preference, the page-flipping animation is turned off.
-
-
-
Essential animation:
-
-
A web application provides a feature to author animated sequences. As part of this tool the author needs to preview the animation.
-
-
-
+
+
Parallax scrolling with option to turn off unnecessary motion globally
+
A site includes extra animations when the user scrolls. Decorative elements move in and out of view
+ horizontally when the essential page content is scrolled vertically. A control at the top of each page
+ allows the user to turn off unnecessary animations. The ability to turn off non-essential animations is a site-wide setting.
+
Transitions that support the reduce motion preference
+
A site includes a non-essential transition when loading new content. The transition is a page-flipping
+ animation that respects the reduce-motion CSS media query. When the user enables the reduce motion preference,
+ the page-flipping animation is turned off.
+
Essential animation
+
A web application provides a feature to author animated sequences. As part of this tool the author needs to preview the animation.
From 6ec98a3e4256b40a7ba6a20f01144753a010144b Mon Sep 17 00:00:00 2001
From: "Kenneth G. Franqueiro"
Date: Wed, 27 Nov 2024 17:20:03 -0500
Subject: [PATCH 03/14] Update 11ty-publish workflow to use
git-auto-commit-action (#4154)
This update resolves spurious errors in the publish workflow in cases
where a merge to `main` results in no changes to push to `gh-pages`.
- [Example of the type of error this
addresses](https://github.com/kfranqueiro/wcag/actions/runs/12036136821/job/33556666057)
- [Example of the same type of run succeeding with this
change](https://github.com/kfranqueiro/wcag/actions/runs/12036196134/job/33556861412)
- [Example of a run completing with this change, operating as usual when
there are changes to commit to
`gh-pages`](https://github.com/kfranqueiro/wcag/actions/runs/12036639462/job/33558323786)
---
.github/workflows/11ty-publish.yaml | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/11ty-publish.yaml b/.github/workflows/11ty-publish.yaml
index fd2ec74e6b..198641fc31 100644
--- a/.github/workflows/11ty-publish.yaml
+++ b/.github/workflows/11ty-publish.yaml
@@ -36,10 +36,13 @@ jobs:
curl https://labs.w3.org/spec-generator/?type=respec"&"url=https://raw.githack.com/$GITHUB_REPOSITORY/main/requirements/22/index.html -o _site/requirements/22/index.html -f --retry 3
curl https://labs.w3.org/spec-generator/?type=respec"&"url=https://raw.githack.com/$GITHUB_REPOSITORY/main/conformance-challenges/index.html -o _site/conformance-challenges/index.html -f --retry 3
- name: Push
- working-directory: _site
- run: |
- git config user.email 87540780+w3cgruntbot@users.noreply.github.com
- git config user.name w3cgruntbot
- git add -A .
- git commit -m ":robot: Deploy to GitHub Pages: $GITHUB_SHA from branch $GITHUB_REF"
- git push origin gh-pages
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ repository: _site
+ branch: gh-pages
+ commit_user_name: w3cgruntbot
+ commit_user_email: 87540780+w3cgruntbot@users.noreply.github.com
+ commit_author: "w3cgruntbot <87540780+w3cgruntbot@users.noreply.github.com>"
+ commit_message: ":robot: Deploy to GitHub Pages: ${{ github.sha }} from branch ${{ github.ref }}"
+ skip_fetch: true
+ skip_checkout: true
From 7aad7a702bd17bc23785f7bc8fba1278d6d6dc67 Mon Sep 17 00:00:00 2001
From: "Kenneth G. Franqueiro"
Date: Thu, 28 Nov 2024 06:12:13 -0500
Subject: [PATCH 04/14] Pin definitions when building an older version (#4155)
This is a follow-up to #4007, in which I had neglected to pin
definitions for key terms to the published recommendation when building
for 2.1.
- Moves `termsMap` definition to the Eleventy config (where all other
target-version-dependent assignments are made), to be passed into the
`CustomLiquid` constructor
- Updates `termsMap` references within `CustomLiquid` to use an instance
variable set in the constructor
- Updates `loadRemoteGuidelines` to account for pre-processed terms
content
- Also updates to account for #4124
- Skips entirety of custom `render` processing for pages not being
output for 2.1 (to avoid irrelevant error messages as well as save time)
---
11ty/CustomLiquid.ts | 26 +++++++++++++++++---------
11ty/guidelines.ts | 30 +++++++++++++++++-------------
11ty/types.ts | 2 +-
eleventy.config.ts | 4 ++++
4 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/11ty/CustomLiquid.ts b/11ty/CustomLiquid.ts
index 1a302627c6..948a4847f3 100644
--- a/11ty/CustomLiquid.ts
+++ b/11ty/CustomLiquid.ts
@@ -1,5 +1,5 @@
import { Liquid, type Template } from "liquidjs";
-import type { RenderOptions } from "liquidjs/dist/liquid-options";
+import type { LiquidOptions, RenderOptions } from "liquidjs/dist/liquid-options";
import compact from "lodash-es/compact";
import uniq from "lodash-es/uniq";
@@ -10,7 +10,7 @@ import type { GlobalData } from "eleventy.config";
import { biblioPattern, getBiblio } from "./biblio";
import { flattenDom, load, type CheerioAnyNode } from "./cheerio";
import { generateId } from "./common";
-import { getAcknowledgementsForVersion, getTermsMap } from "./guidelines";
+import { getAcknowledgementsForVersion, type TermsMap } from "./guidelines";
import { resolveTechniqueIdFromHref, understandingToTechniqueLinkSelector } from "./techniques";
import { techniqueToUnderstandingLinkSelector } from "./understanding";
@@ -22,7 +22,6 @@ const techniquesPattern = /\btechniques\//;
const understandingPattern = /\bunderstanding\//;
const biblio = await getBiblio();
-const termsMap = await getTermsMap();
const termLinkSelector = "a:not([href])";
/** Generates {% include "foo.html" %} directives from 1 or more basenames */
@@ -72,6 +71,10 @@ function expandTechniqueLink($el: CheerioAnyNode) {
const stripHtmlComments = (html: string) => html.replace(//g, "");
+interface CustomLiquidOptions extends LiquidOptions {
+ termsMap: TermsMap;
+}
+
// Dev note: Eleventy doesn't expose typings for its template engines for us to neatly extend.
// Fortunately, it passes both the content string and the file path through to Liquid#parse:
// https://github.com/11ty/eleventy/blob/9c3a7619/src/Engines/Liquid.js#L253
@@ -84,6 +87,11 @@ const stripHtmlComments = (html: string) => html.replace(//g, "")
* - generating/expanding sections with auto-generated content
*/
export class CustomLiquid extends Liquid {
+ termsMap: TermsMap;
+ constructor(options: CustomLiquidOptions) {
+ super(options);
+ this.termsMap = options.termsMap;
+ }
public parse(html: string, filepath?: string) {
// Filter out Liquid calls for computed data and includes themselves
if (filepath && !filepath.includes("_includes/") && isHtmlFileContent(html)) {
@@ -300,7 +308,7 @@ export class CustomLiquid extends Liquid {
public async render(templates: Template[], scope: GlobalData, options?: RenderOptions) {
// html contains markup after Liquid tags/includes have been processed
const html = (await super.render(templates, scope, options)).toString();
- if (!isHtmlFileContent(html) || !scope) return html;
+ if (!isHtmlFileContent(html) || !scope || scope.page.url === false) return html;
const $ = load(html);
@@ -414,7 +422,7 @@ export class CustomLiquid extends Liquid {
.toLowerCase()
.trim()
.replace(/\s*\n+\s*/, " ");
- const term = termsMap[name];
+ const term = this.termsMap[name];
if (!term) {
console.warn(`${scope.page.inputPath}: Term not found: ${name}`);
return;
@@ -428,7 +436,7 @@ export class CustomLiquid extends Liquid {
const $el = $(el);
const termName = extractTermName($el);
$el
- .attr("href", `${scope.guidelinesUrl}#${termName ? termsMap[termName].trId : ""}`)
+ .attr("href", `${scope.guidelinesUrl}#${termName ? this.termsMap[termName].trId : ""}`)
.attr("target", "terms");
});
} else if (scope.isUnderstanding) {
@@ -442,7 +450,7 @@ export class CustomLiquid extends Liquid {
// since terms may reference other terms in their own definitions.
// Each iteration may append to termNames.
for (let i = 0; i < termNames.length; i++) {
- const term = termsMap[termNames[i]];
+ const term = this.termsMap[termNames[i]];
if (!term) continue; // This will already warn via extractTermNames
const $definition = load(term.definition);
@@ -459,7 +467,7 @@ export class CustomLiquid extends Liquid {
return 0;
});
for (const name of termNames) {
- const term = termsMap[name]; // Already verified existence in the earlier loop
+ const term = this.termsMap[name]; // Already verified existence in the earlier loop
$termsList.append(
`
${term.name}
` +
`
${term.definition}
`
@@ -469,7 +477,7 @@ export class CustomLiquid extends Liquid {
// Iterate over non-href links once more in now-expanded document to add hrefs
$(termLinkSelector).each((_, el) => {
const name = extractTermName($(el));
- el.attribs.href = `#${name ? termsMap[name].id : ""}`;
+ el.attribs.href = `#${name ? this.termsMap[name].id : ""}`;
});
} else {
// No terms: remove skeleton that was placed in #parse
diff --git a/11ty/guidelines.ts b/11ty/guidelines.ts
index cbdc084bcb..0dc8ace485 100644
--- a/11ty/guidelines.ts
+++ b/11ty/guidelines.ts
@@ -197,14 +197,17 @@ interface Term {
/** id of dfn in TR, which matches original id in terms file */
trId: string;
}
+export type TermsMap = Record;
/**
* Resolves term definitions from guidelines/index.html organized for lookup by name;
* comparable to the term elements in wcag.xml from the guidelines-xml Ant task.
*/
-export async function getTermsMap() {
- const $ = await flattenDomFromFile("guidelines/index.html");
- const terms: Record = {};
+export async function getTermsMap(version?: WcagVersion) {
+ const $ = version
+ ? await loadRemoteGuidelines(version)
+ : await flattenDomFromFile("guidelines/index.html");
+ const terms: TermsMap = {};
$("dfn").each((_, el) => {
const $el = $(el);
@@ -240,24 +243,25 @@ const loadRemoteGuidelines = async (version: WcagVersion) => {
);
// Re-collapse definition links and notes, to be processed by this build system
- $(".guideline a.internalDFN").removeAttr("class data-link-type id href title");
- $(".guideline [role='note'] .marker").remove();
- $(".guideline [role='note']").find("> div, > p").addClass("note").unwrap();
+ $("a.internalDFN").removeAttr("class data-link-type id href title");
+ $("[role='note'] .marker").remove();
+ $("[role='note']").find("> div, > p").addClass("note").unwrap();
- // Bibliography references are not processed in Understanding SC boxes
- $(".guideline cite:has(a.bibref:only-child)").each((_, el) => {
+ // Un-process bibliography references, to be processed by CustomLiquid
+ $("cite:has(a.bibref:only-child)").each((_, el) => {
const $el = $(el);
- const $parent = $el.parent();
- $el.remove();
- // Remove surrounding square brackets (which aren't in a dedicated element)
- $parent.html($parent.html()!.replace(/ \[\]/g, ""));
+ $el.replaceWith(`[${$el.find("a.bibref").html()}]`);
});
+ // Remove generated IDs and markers from examples
+ $(".example[id]").removeAttr("id");
+ $(".example .marker:has(.self-link)").remove();
+
// Remove extra markup from headings so they can be parsed for names
$("bdi").remove();
// Remove abbr elements which exist only in TR, not in informative docs
- $("#acknowledgements li abbr").each((_, abbrEl) => {
+ $("#acknowledgements li abbr, #glossary abbr").each((_, abbrEl) => {
$(abbrEl).replaceWith($(abbrEl).text());
});
diff --git a/11ty/types.ts b/11ty/types.ts
index 9bdd86c9f1..ed89e25178 100644
--- a/11ty/types.ts
+++ b/11ty/types.ts
@@ -9,7 +9,7 @@ interface EleventyPage {
outputPath: string;
rawInput: string;
templateSyntax: string;
- url: string;
+ url: string | false; // (false when permalink is set to false for the page)
}
interface EleventyDirectories {
diff --git a/eleventy.config.ts b/eleventy.config.ts
index 4313c5f2fa..d579a657ff 100644
--- a/eleventy.config.ts
+++ b/eleventy.config.ts
@@ -14,6 +14,7 @@ import {
getFlatGuidelines,
getPrinciples,
getPrinciplesForVersion,
+ getTermsMap,
scSlugOverrides,
type FlatGuidelinesMap,
type Guideline,
@@ -103,6 +104,8 @@ for (const [technology, list] of Object.entries(techniques)) {
const understandingDocs = await getUnderstandingDocs(version);
const understandingNav = await generateUnderstandingNavMap(principles, understandingDocs);
+const termsMap = process.env.WCAG_VERSION ? await getTermsMap(version) : await getTermsMap();
+
// Declare static global data up-front so we can build typings from it
const globalData = {
version,
@@ -274,6 +277,7 @@ export default function (eleventyConfig: any) {
root: ["_includes", "."],
jsTruthy: true,
strictFilters: true,
+ termsMap,
})
);
From 079df5e52d7a2d16b3240c4398d489d53d0c777b Mon Sep 17 00:00:00 2001
From: Kevin White
Date: Fri, 6 Dec 2024 15:54:29 +0000
Subject: [PATCH 05/14] Update for 2.2 publication Dec 2024 (#4163)
---
guidelines/respec-config.js | 56 ++++++-------------------------------
1 file changed, 8 insertions(+), 48 deletions(-)
diff --git a/guidelines/respec-config.js b/guidelines/respec-config.js
index a6189081a5..75d1ff7d1d 100644
--- a/guidelines/respec-config.js
+++ b/guidelines/respec-config.js
@@ -8,10 +8,10 @@ var respecConfig = {
permalinkHide: false,
tocIntroductory: true,
// specification status (e.g., WD, LC, NOTE, etc.). If in doubt use ED.
- specStatus: "ED",
+ specStatus: "REC",
//crEnd: "2012-04-30",
//perEnd: "2013-07-23",
- publishDate: "2023-10-05",
+ publishDate: "2024-12-12",
diffTool: "http://www.aptest.com/standards/htmldiff/htmldiff.pl",
// the specifications short name, as in https://www.w3.org/TR/short-name/
@@ -62,62 +62,22 @@ var respecConfig = {
companyURI: "https://loc.gov/",
w3cid: 90310
},
- {
+ {
name: "Michael Cooper",
url: 'https://www.w3.org/People/cooper',
- //mailto: "cooper@w3.org",
company: "W3C",
companyURI: "https://www.w3.org",
- w3cid: 34017
+ w3cid: 34017,
+ retiredDate: "2023-07-31"
},
{
name: "Andrew Kirkpatrick",
- //url: "http://www.adobe.com/",
- mailto: "akirkpat@adobe.com",
company: "Adobe",
companyURI: "http://www.adobe.com/",
- w3cid: 39770
+ w3cid: 39770,
+ retiredDate: "2020-03-04"
}
- ],
- /*
- formerEditors: [
- {
- name: "Ben Caldwell",
- company: "Trace R&D Center, University of Wisconsin-Madison",
- w3cid: 33602
- },
- {
- name: "Loretta Guarino Reid",
- company: "Google, Inc.",
- w3cid: 35436
- },
- {
- name: "Gregg Vanderheiden",
- company: "Trace R&D Center, University of Wisconsin-Madison",
- w3cid: 3442
- },
- {
- name: "Wendy Chisholm",
- company: "W3C",
- w3cid: 4099
- },
- {
- name: "John Slatin",
- company: "Accessibility Institute, University of Texas at Austin",
- w3cid: 35537
- },
- {
- name: "Jason White",
- company: "University of Melbourne",
- w3cid: 74028
- },
- {
- name: "Joshue O Connor",
- company: "Invited Expert, InterAccess",
- w3cid: 41218
- }
- ],
- */
+ ],
// authors, add as many as you like.
// This is optional, uncomment if you have authors as well as editors.
From fd311595df3639495869b46ad243d7fe398899e7 Mon Sep 17 00:00:00 2001
From: "Kenneth G. Franqueiro"
Date: Fri, 6 Dec 2024 18:12:47 -0500
Subject: [PATCH 06/14] Tolerate specref API failures during local dev (#4167)
Since #4124 was merged, all builds require an HTTP request to
api.specref.org in order to resolve additional bibliographical
references. This may cause issues in local dev in the case of being
offline due to travel or internet hiccups, behind a proxy, etc.
This commit adds a reusable function for cases where a HTTP failure
during local dev is tolerable, and uses it for the bibrefs request.
Running `npm build` will still result in an immediate failure and stack
trace; this is intentional to ensure that nothing slips by during builds
for PR previews, GitHub Pages, or w3.org.
---
11ty/biblio.ts | 14 +++++++++-----
11ty/common.ts | 22 ++++++++++++++++++++++
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/11ty/biblio.ts b/11ty/biblio.ts
index 24a809fdb8..fcf5faca80 100644
--- a/11ty/biblio.ts
+++ b/11ty/biblio.ts
@@ -3,6 +3,8 @@ import { readFile } from "fs/promises";
import { glob } from "glob";
import uniq from "lodash-es/uniq";
+import { wrapAxiosRequest } from "./common";
+
export const biblioPattern = /\[\[\??([\w-]+)\]\]/g;
/** Compiles URLs from local biblio + specref for linking in Understanding documents. */
@@ -12,7 +14,7 @@ export async function getBiblio() {
.replace(/^respecConfig\.localBiblio\s*=\s*/, "(")
.replace("};", "})")
);
-
+
const refs: string[] = [];
for (const path of await glob(["guidelines/**/*.html", "understanding/*/*.html"])) {
const content = await readFile(path, "utf8");
@@ -20,16 +22,18 @@ export async function getBiblio() {
while ((match = biblioPattern.exec(content))) if (!localBiblio[match[1]]) refs.push(match[1]);
}
const uniqueRefs = uniq(refs);
-
- const response = await axios.get(`https://api.specref.org/bibrefs?refs=${uniqueRefs.join(",")}`);
+
+ const response = await wrapAxiosRequest(
+ axios.get(`https://api.specref.org/bibrefs?refs=${uniqueRefs.join(",")}`)
+ );
const fullBiblio = {
...response.data,
...localBiblio,
};
-
+
const resolvedRefs = Object.keys(fullBiblio);
const unresolvedRefs = uniqueRefs.filter((ref) => !resolvedRefs.includes(ref));
if (unresolvedRefs.length) console.warn(`Unresolved biblio refs: ${unresolvedRefs.join(", ")}`);
-
+
return fullBiblio;
}
diff --git a/11ty/common.ts b/11ty/common.ts
index ade5d87f14..bda9ec4618 100644
--- a/11ty/common.ts
+++ b/11ty/common.ts
@@ -1,5 +1,7 @@
/** @fileoverview Common functions used by multiple parts of the build process */
+import { AxiosError, type AxiosResponse } from "axios";
+
import type { Guideline, Principle, SuccessCriterion } from "./guidelines";
/** Generates an ID for heading permalinks. Equivalent to wcag:generate-id in base.xslt. */
@@ -28,3 +30,23 @@ export function wcagSort(
}
return 0;
}
+
+/**
+ * Handles HTTP error responses from Axios requests in local dev;
+ * re-throws error during builds to fail loudly.
+ * This should only be used for non-critical requests that can tolerate null data
+ * without major side effects.
+ */
+export const wrapAxiosRequest = (promise: Promise>) =>
+ promise.catch((error) => {
+ if (!(error instanceof AxiosError) || !error.response || !error.request) throw error;
+ const { response, request } = error;
+ console.warn(
+ `AxiosError: status ${response.status} received from ${
+ request.protocol + "//" + request.host
+ }${request.path || ""}`
+ );
+
+ if (process.env.ELEVENTY_RUN_MODE === "build") throw error;
+ else return { data: null };
+ });
From 23d8ce8cc708508b16d490947f534bbec96506d4 Mon Sep 17 00:00:00 2001
From: "Kenneth G. Franqueiro"
Date: Mon, 9 Dec 2024 11:08:02 -0500
Subject: [PATCH 07/14] Make link to build system readme more prominent in the
main readme (#4168)
---
README.md | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 401e417ef5..66c59c52de 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,11 @@ Content for WCAG 2.1 and later is organized according to the file structure belo
Where `{version}` is "20", content came from WCAG 2.0. "21" is used for content introduced in WCAG 2.1, "22" for WCAG 2.2, etc.
+## Build System
+
+The Techniques and Understanding documents are processed through a build system based on Eleventy and Liquid for templating and Cheerio for transformations.
+More details, including instructions for previewing the output locally, can be found in the [build process README](11ty/README.md).
+
## Editing Draft Success Criteria
[Success Criteria Managers](https://www.w3.org/WAI/GL/wiki/SC_Managers_Phase1) will prepare candidate success criteria, ready for inclusion in the guidelines document. To prepare success criteria, follow these steps:
@@ -158,7 +163,7 @@ Once a technique branch and file is set up, populate the content and request rev
### Formatting Techniques
-Techniques in the repository are plain HTML files with minimal formatting. For publication to the editors' draft and W3C location, techniques are formatted by a build process based on Eleventy for templating and Cheerio for transformations. More details, including instructions for previewing locally, can be found in the [build process README](11ty/README.md).
+Techniques in the repository are plain HTML files with minimal formatting. For publication to the editors' draft and W3C location, techniques are formatted by the Eleventy build process described above in the [Build System section](#build-system).
The generator compiles the techniques together as a suite with formatting and navigation. It enforces certain structures, such as ordering top-level sections described above and standardizing headings. It attempts to process cross reference links to make sure the URIs work upon publication. One of the most substantial roles is to populate the Applicability section with references to the guidelines or success criteria to which the technique relates. The information for this comes from the Understanding documents. Proper use of the technique template is important to enable this functionality, and mal-formed techniques may cause the generator to fail.
From b9cd498c41b8e4acd2460774f514af02cb46c7e1 Mon Sep 17 00:00:00 2001
From: Kevin White
Date: Thu, 12 Dec 2024 12:00:01 +0000
Subject: [PATCH 08/14] 2024 post publication fixes (#4172)
---
guidelines/index.html | 26 +++++++++++++-------------
guidelines/input-purposes.html | 2 +-
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/guidelines/index.html b/guidelines/index.html
index fbfa8a9807..a5a7e668a5 100644
--- a/guidelines/index.html
+++ b/guidelines/index.html
@@ -792,19 +792,19 @@
address-level1 - The broadest administrative level in the address, i.e., the province within which the locality is found; for example, in the US, this would be the state; in Switzerland it would be the canton; in the UK, the post town
country - Country code
country-name - Country name
-
postal-code - Postal code, post code, ZIP code, CEDEX code (if CEDEX, append "CEDEX", and the dissement, if relevant, to the address-level2 field)
+
postal-code - Postal code, post code, ZIP code, CEDEX code (if CEDEX, append "CEDEX", and the arrondissement, if relevant, to the address-level2 field)
cc-name - Full name as given on the payment instrument
cc-given-name - Given name as given on the payment instrument (in some Western cultures, also known as the first name)
cc-additional-name - Additional names given on the payment instrument (in some Western cultures, also known as middle names, forenames other than the first name)
From 3e937868e8d86f5f125d32a379644d4d7635aa24 Mon Sep 17 00:00:00 2001
From: JAWS-test2 <60307417+JAWS-test2@users.noreply.github.com>
Date: Fri, 13 Dec 2024 23:40:44 +0100
Subject: [PATCH 09/14] Update F103 to remove progressbar as it's not an
implicit live region (#1021)
Fixes #892
Co-authored-by: JAWS-test2 <>
Co-authored-by: Kenneth G. Franqueiro
Co-authored-by: Patrick H. Lauke
Co-authored-by: Mike Gower
---
techniques/failures/F103.html | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/techniques/failures/F103.html b/techniques/failures/F103.html
index aabec5461e..4c365aaa64 100644
--- a/techniques/failures/F103.html
+++ b/techniques/failures/F103.html
@@ -35,10 +35,9 @@
Description
the HTML output element
role="status"
role="alert"
-
the use of an aria-live attribute on an element, set to either "polite" or "assertive"
role="log"
-
role="progressbar"
-
+
the use of an aria-live attribute on an element, set to either "polite" or "assertive"
+
The absence of all of these techniques predicts a failure for the status message be announced to the user. Additionally, if the role or property is not set before the dynamic content is added, this also predicts a failure.
Since additional techniques may exist to alert an assistive technology, the final step of this failure technique is confirming whether an assistive technology (such as a screen reader) detects the dynamic content and exposes the information to users. Where a status message exists but is not surfaced by assistive technology, it is confirmation that a failure has taken place.
@@ -73,7 +72,7 @@
Procedure
the existence of errors
-
Check that the element containing the new content does not have a pre-existing aria role of status, alert, log, or progressbar, or an aria-live attribute
+
Check that the element containing the new content does not have a pre-existing aria role of status, alert, or log, or an aria-live attribute
Check that the status message is not surfaced (i.e., announced) by assistive technology
From 6ee72a7770b5d1fc1f565b70ab62382b02341f2b Mon Sep 17 00:00:00 2001
From: Detlev Fischer
Date: Fri, 13 Dec 2024 23:41:29 +0100
Subject: [PATCH 10/14] Update H95.html (#2150)
Adressing suggestions for updated links in
https://github.com/w3c/wcag/issues/2079
Preview of[ amended Technique
H95](https://raw.githack.com/w3c/wcag/cd6d94d7be2837be6a025650343acc652d02caf6/techniques/html/H95.html)
Closes #2079
---------
Co-authored-by: Patrick H. Lauke
Co-authored-by: Kenneth G. Franqueiro
Co-authored-by: Mike Gower
---
techniques/html/H95.html | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/techniques/html/H95.html b/techniques/html/H95.html
index f9218fbac4..f7ebf97040 100644
--- a/techniques/html/H95.html
+++ b/techniques/html/H95.html
@@ -73,18 +73,27 @@