ultra11y 4.3.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.opencode/plugins/ultra11y.js +1 -1
- package/README.md +40 -4
- package/package.json +1 -1
- package/scripts/build-standards.mjs +290 -1
- package/scripts/ultra11y.mjs +2675 -274
- package/scripts/vendor/wcag-2.2-fr.json +944 -0
- package/scripts/vendor/wcag-2.2-text.json +749 -0
- package/skills/review-a11y/SKILL.md +1 -1
- package/skills/review-a11y/scripts/ultra11y.mjs +2675 -274
- package/skills/ultra11y/SKILL.md +13 -4
- package/skills/ultra11y/references/guidance.md +33 -7
- package/skills/ultra11y/references/harnesses.md +10 -0
- package/skills/ultra11y/references/mcp.md +215 -0
- package/skills/ultra11y/references/packs.md +8 -0
- package/skills/ultra11y/references/standards.md +18 -0
- package/skills/ultra11y/scripts/ultra11y.mjs +2675 -274
- package/src/adjudicate.ts +9 -15
- package/src/adjudication-data.ts +38 -0
- package/src/check.ts +51 -1
- package/src/cli.ts +6 -2
- package/src/config.ts +27 -4
- package/src/criteria-view.ts +463 -0
- package/src/criteria.ts +14 -11
- package/src/data/guidance/wcag.json +268 -0
- package/src/data/wcag.json +1112 -55
- package/src/guidance/index.ts +11 -0
- package/src/guidance/resolve.ts +71 -0
- package/src/mcp/handlers.ts +160 -15
- package/src/mcp/prompts.ts +13 -2
- package/src/mcp/server.ts +18 -4
- package/src/mcp/standards-resources.ts +174 -0
- package/src/mcp/tools.ts +140 -6
- package/src/method-view.ts +227 -0
- package/src/prd.ts +5 -16
- package/src/standards/coverage.ts +237 -0
- package/src/standards/index.ts +1 -0
- package/src/standards/pack.ts +19 -0
- package/src/standards/registry.ts +115 -9
- package/src/types.ts +24 -1
- package/src/wcag.ts +21 -1
package/scripts/ultra11y.mjs
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { realpathSync as realpathSync6, writeFileSync as writeFileSync19, mkdirSync as mkdirSync17, existsSync as existsSync34, readFileSync as readFileSync32, appendFileSync, copyFileSync as copyFileSync4 } from "fs";
|
|
5
|
-
import { join as join50, relative as relative5, sep as sep7, dirname as dirname14 } from "path";
|
|
5
|
+
import { join as join50, relative as relative5, resolve as resolve15, sep as sep7, dirname as dirname14 } from "path";
|
|
6
6
|
import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL3 } from "url";
|
|
7
7
|
|
|
8
8
|
// src/types.ts
|
|
9
|
-
var VERSION = "4.
|
|
9
|
+
var VERSION = "4.4.0";
|
|
10
10
|
var SCHEMA_VERSION = 2;
|
|
11
11
|
|
|
12
12
|
// src/audit.ts
|
|
@@ -180,7 +180,20 @@ var wcag_default = {
|
|
|
180
180
|
"H80",
|
|
181
181
|
"H81",
|
|
182
182
|
"H86"
|
|
183
|
-
]
|
|
183
|
+
],
|
|
184
|
+
text: "All non-text content that is presented to the user has a text alternative that serves the equivalent purpose, except for the situations listed below.\nControls, Input:\nIf non-text content is a control or accepts user input, then it has a name that describes its purpose. (Refer to Success Criterion 4.1.2 for additional requirements for controls and content that accepts user input.)\nTime-Based Media:\nIf non-text content is time-based media, then text alternatives at least provide descriptive identification of the non-text content. (Refer to Guideline 1.2 for additional requirements for media.)\nTest:\nIf non-text content is a test or exercise that would be invalid if presented in text, then text alternatives at least provide descriptive identification of the non-text content.\nSensory:\nIf non-text content is primarily intended to create a specific sensory experience, then text alternatives at least provide descriptive identification of the non-text content.\nCAPTCHA:\nIf the purpose of non-text content is to confirm that content is being accessed by a person rather than a computer, then text alternatives that identify and describe the purpose of the non-text content are provided, and alternative forms of CAPTCHA using output modes for different types of sensory perception are provided to accommodate different disabilities.\nDecoration, Formatting, Invisible:\nIf non-text content is pure decoration, is used only for visual formatting, or is not presented to users, then it is implemented in a way that it can be ignored by assistive technology.",
|
|
185
|
+
textFr: "Tout contenu non textuel pr\xE9sent\xE9 \xE0 l\u2019utilisateur a un \xE9quivalent textuel qui remplit une fonction \xE9quivalente sauf dans les situations \xE9num\xE9r\xE9es ci-dessous.\nComposant d\u2019interface ou de saisie:\nsi le contenu non textuel est un composant d\u2019interface ou s\u2019il permet la saisie d\u2019informations par l\u2019utilisateur, alors il a un nom qui d\xE9crit sa fonction. (Se r\xE9f\xE9rer au Crit\xE8re de succ\xE8s 4.1.2 pour des exigences suppl\xE9mentaires \xE0 propos des composants d\u2019interfaces utilisateur ou des contenus qui permettent la saisie d\u2019informations par l\u2019utilisateur.)\nM\xE9dia temporel:\nsi le contenu non textuel est un m\xE9dia temporel, alors l\u2019\xE9quivalent textuel fournit au moins une identification descriptive du contenu non textuel. (Se r\xE9f\xE9rer \xE0 la R\xE8gle 1.2 pour des exigences suppl\xE9mentaires concernant les m\xE9dias temporels.)\nTest:\nsi le contenu non textuel est un test ou un exercice qui serait invalide s\u2019il \xE9tait pr\xE9sent\xE9 en texte, alors l\u2019\xE9quivalent textuel fournit au moins une identification descriptive du contenu non textuel.\nContenu sensoriel:\nsi le contenu non textuel vise d\u2019abord \xE0 cr\xE9er une exp\xE9rience sensorielle sp\xE9cifique, l\u2019\xE9quivalent textuel fournit au moins une identification descriptive de ce contenu non textuel.\nCAPTCHA:\nsi ce contenu non textuel vise \xE0 confirmer que le contenu est consult\xE9 par une personne plut\xF4t que par un ordinateur, alors un \xE9quivalent textuel est fourni pour identifier et d\xE9crire la fonction du contenu non textuel, et des formes alternatives du CAPTCHA sont propos\xE9es pour diff\xE9rents types de perception sensorielle afin d\u2019accommoder diff\xE9rents types de limitations fonctionnelles.\nD\xE9coration, formatage, invisibilit\xE9:\nsi le contenu non textuel est purement d\xE9coratif, s\u2019il est utilis\xE9 seulement pour un formatage visuel ou s\u2019il n\u2019est pas pr\xE9sent\xE9 \xE0 l\u2019utilisateur, alors il est impl\xE9ment\xE9 de mani\xE8re \xE0 \xEAtre ignor\xE9 par les technologies d\u2019assistance.",
|
|
186
|
+
termsFr: [
|
|
187
|
+
"non-text-content",
|
|
188
|
+
"text-alternative",
|
|
189
|
+
"name",
|
|
190
|
+
"text",
|
|
191
|
+
"specific-sensory-experience",
|
|
192
|
+
"captcha",
|
|
193
|
+
"pure-decoration",
|
|
194
|
+
"assistive-technologies"
|
|
195
|
+
],
|
|
196
|
+
terms: ["non-text-content", "text-alternative", "name", "text", "specific-sensory-experience", "captcha", "pure-decoration", "assistive-technology"]
|
|
184
197
|
},
|
|
185
198
|
{
|
|
186
199
|
sc: "1.2.1",
|
|
@@ -193,7 +206,11 @@ var wcag_default = {
|
|
|
193
206
|
automatability: "judgment",
|
|
194
207
|
ruleIds: [],
|
|
195
208
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/audio-only-and-video-only-prerecorded.html",
|
|
196
|
-
techniques: ["F30", "F67", "G158", "G159", "G166", "G173", "G58", "G69", "G78", "G8", "H96", "SM6", "SM7"]
|
|
209
|
+
techniques: ["F30", "F67", "G158", "G159", "G166", "G173", "G58", "G69", "G78", "G8", "H96", "SM6", "SM7"],
|
|
210
|
+
text: "For prerecorded audio-only and prerecorded video-only media, the following are true, except when the audio or video is a media alternative for text and is clearly labeled as such:\nPrerecorded Audio-only:\nAn alternative for time-based media is provided that presents equivalent information for prerecorded audio-only content.\nPrerecorded Video-only:\nEither an alternative for time-based media or an audio track is provided that presents equivalent information for prerecorded video-only content.",
|
|
211
|
+
textFr: "Pour des m\xE9dias pr\xE9-enregistr\xE9s seulement audio et pr\xE9-enregistr\xE9s seulement vid\xE9o, sauf si l\u2019audio ou la vid\xE9o sont un m\xE9dia de remplacement pour un texte et qu\u2019ils sont clairement identifi\xE9s comme tels, les points suivants sont vrais :\nContenu pr\xE9-enregistr\xE9 seulement audio:\nfournir une version de remplacement pour un m\xE9dia temporel, pr\xE9sentant une information \xE9quivalente au contenu seulement audio.\nContenu pr\xE9-enregistr\xE9 seulement vid\xE9o:\nfournir, soit une version de remplacement pour un m\xE9dia temporel, soit une piste audio (pr\xE9sentant une information \xE9quivalente) pour un contenu pr\xE9-enregistr\xE9 seulement vid\xE9o.",
|
|
212
|
+
termsFr: ["prerecorded", "audio-only", "video-only", "media-alternative-for-text", "alternative-for-time-based-media"],
|
|
213
|
+
terms: ["prerecorded", "audio-only", "video-only", "media-alternative-for-text", "alternative-for-time-based-media"]
|
|
197
214
|
},
|
|
198
215
|
{
|
|
199
216
|
sc: "1.2.2",
|
|
@@ -206,7 +223,11 @@ var wcag_default = {
|
|
|
206
223
|
automatability: "judgment",
|
|
207
224
|
ruleIds: ["media-no-track"],
|
|
208
225
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/captions-prerecorded.html",
|
|
209
|
-
techniques: ["F74", "F75", "F8", "G58", "G87", "G93", "H95", "SM11", "SM12"]
|
|
226
|
+
techniques: ["F74", "F75", "F8", "G58", "G87", "G93", "H95", "SM11", "SM12"],
|
|
227
|
+
text: "Captions are provided for all prerecorded audio content in synchronized media, except when the media is a media alternative for text and is clearly labeled as such.",
|
|
228
|
+
textFr: "Fournir des sous-titres pour tout contenu audio pr\xE9-enregistr\xE9 dans un m\xE9dia synchronis\xE9, except\xE9 lorsque le m\xE9dia est un m\xE9dia de remplacement pour un texte et qu\u2019il est clairement identifi\xE9 comme tel.",
|
|
229
|
+
termsFr: ["captions", "audio", "prerecorded", "synchronized-media", "media-alternative-for-text"],
|
|
230
|
+
terms: ["captions", "prerecorded", "audio", "synchronized-media", "media-alternative-for-text"]
|
|
210
231
|
},
|
|
211
232
|
{
|
|
212
233
|
sc: "1.2.3",
|
|
@@ -219,7 +240,11 @@ var wcag_default = {
|
|
|
219
240
|
automatability: "judgment",
|
|
220
241
|
ruleIds: [],
|
|
221
242
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/audio-description-or-media-alternative-prerecorded.html",
|
|
222
|
-
techniques: ["F30", "F67", "G158", "G159", "G166", "G173", "G58", "G69", "G78", "G8", "H96", "SM6", "SM7"]
|
|
243
|
+
techniques: ["F30", "F67", "G158", "G159", "G166", "G173", "G58", "G69", "G78", "G8", "H96", "SM6", "SM7"],
|
|
244
|
+
text: "An alternative for time-based media or audio description of the prerecorded video content is provided for synchronized media, except when the media is a media alternative for text and is clearly labeled as such.",
|
|
245
|
+
textFr: "Fournir une version de remplacement pour un m\xE9dia temporel ou une audio-description du contenu vid\xE9o pr\xE9-enregistr\xE9 pour un m\xE9dia synchronis\xE9, except\xE9 quand le m\xE9dia est un m\xE9dia de remplacement pour un texte et qu\u2019il est clairement identifi\xE9 comme tel.",
|
|
246
|
+
termsFr: ["alternative-for-time-based-media", "audio-descriptions", "video", "prerecorded", "synchronized-media", "media-alternative-for-text"],
|
|
247
|
+
terms: ["alternative-for-time-based-media", "audio-description", "prerecorded", "video", "synchronized-media", "media-alternative-for-text"]
|
|
223
248
|
},
|
|
224
249
|
{
|
|
225
250
|
sc: "1.2.4",
|
|
@@ -231,7 +256,11 @@ var wcag_default = {
|
|
|
231
256
|
addedIn: "2.0",
|
|
232
257
|
automatability: "judgment",
|
|
233
258
|
ruleIds: [],
|
|
234
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/captions-live.html"
|
|
259
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/captions-live.html",
|
|
260
|
+
text: "Captions are provided for all live audio content in synchronized media.",
|
|
261
|
+
textFr: "Fournir des sous-titres pour tout contenu audio en direct, sous forme de m\xE9dia synchronis\xE9.",
|
|
262
|
+
termsFr: ["captions", "audio", "live", "synchronized-media"],
|
|
263
|
+
terms: ["captions", "live", "audio", "synchronized-media"]
|
|
235
264
|
},
|
|
236
265
|
{
|
|
237
266
|
sc: "1.2.5",
|
|
@@ -244,7 +273,11 @@ var wcag_default = {
|
|
|
244
273
|
automatability: "judgment",
|
|
245
274
|
ruleIds: [],
|
|
246
275
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/audio-description-prerecorded.html",
|
|
247
|
-
techniques: ["G173", "G58", "G78", "G8", "H96", "SM1", "SM2", "SM6", "SM7"]
|
|
276
|
+
techniques: ["G173", "G58", "G78", "G8", "H96", "SM1", "SM2", "SM6", "SM7"],
|
|
277
|
+
text: "Audio description is provided for all prerecorded video content in synchronized media.",
|
|
278
|
+
textFr: "Fournir une audio-description pour tout contenu vid\xE9o pr\xE9-enregistr\xE9, sous forme de m\xE9dia synchronis\xE9.",
|
|
279
|
+
termsFr: ["audio-descriptions", "video", "prerecorded", "synchronized-media"],
|
|
280
|
+
terms: ["audio-description", "prerecorded", "video", "synchronized-media"]
|
|
248
281
|
},
|
|
249
282
|
{
|
|
250
283
|
sc: "1.3.1",
|
|
@@ -348,7 +381,11 @@ var wcag_default = {
|
|
|
348
381
|
"SCR20",
|
|
349
382
|
"SCR29",
|
|
350
383
|
"SCR35"
|
|
351
|
-
]
|
|
384
|
+
],
|
|
385
|
+
text: "Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.",
|
|
386
|
+
textFr: "L\u2019information, la structure, et les relations v\xE9hicul\xE9es par la pr\xE9sentation peuvent \xEAtre d\xE9termin\xE9es par un programme informatique ou sont disponibles sous forme de texte.",
|
|
387
|
+
termsFr: ["structure", "relationships", "presentation", "programmatically-determinable"],
|
|
388
|
+
terms: ["structure", "relationships", "presentation", "programmatically-determined"]
|
|
352
389
|
},
|
|
353
390
|
{
|
|
354
391
|
sc: "1.3.2",
|
|
@@ -361,7 +398,11 @@ var wcag_default = {
|
|
|
361
398
|
automatability: "judgment",
|
|
362
399
|
ruleIds: [],
|
|
363
400
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/meaningful-sequence.html",
|
|
364
|
-
techniques: ["ARIA4", "C18", "C22", "C6", "C8", "F1", "F15", "F32", "F33", "F34", "F48", "F49", "G10", "G135", "G140", "G57", "G59", "H56"]
|
|
401
|
+
techniques: ["ARIA4", "C18", "C22", "C6", "C8", "F1", "F15", "F32", "F33", "F34", "F48", "F49", "G10", "G135", "G140", "G57", "G59", "H56"],
|
|
402
|
+
text: "When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined.",
|
|
403
|
+
textFr: "Lorsque l\u2019ordre de pr\xE9sentation du contenu affecte sa signification, un ordre de lecture correct peut \xEAtre d\xE9termin\xE9 par un programme informatique.",
|
|
404
|
+
termsFr: ["correct-reading-sequence", "programmatically-determinable"],
|
|
405
|
+
terms: ["correct-reading-sequence", "programmatically-determined"]
|
|
365
406
|
},
|
|
366
407
|
{
|
|
367
408
|
sc: "1.3.3",
|
|
@@ -374,7 +415,9 @@ var wcag_default = {
|
|
|
374
415
|
automatability: "judgment",
|
|
375
416
|
ruleIds: [],
|
|
376
417
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/sensory-characteristics.html",
|
|
377
|
-
techniques: ["F14", "F26", "G140", "G96"]
|
|
418
|
+
techniques: ["F14", "F26", "G140", "G96"],
|
|
419
|
+
text: "Instructions provided for understanding and operating content do not rely solely on sensory characteristics of components such as shape, color, size, visual location, orientation, or sound.\nNote: For requirements related to color, refer to Guideline 1.4.",
|
|
420
|
+
textFr: "Les instructions donn\xE9es pour la compr\xE9hension et l\u2019utilisation du contenu ne doivent pas reposer uniquement sur les caract\xE9ristiques sensorielles des \xE9l\xE9ments comme la forme, la couleur, la taille, l\u2019emplacement visuel, l\u2019orientation ou le son.\nNote : Pour les exigences li\xE9es \xE0 la couleur, se r\xE9f\xE9rer \xE0 la R\xE8gle 1.4."
|
|
378
421
|
},
|
|
379
422
|
{
|
|
380
423
|
sc: "1.3.4",
|
|
@@ -386,7 +429,11 @@ var wcag_default = {
|
|
|
386
429
|
addedIn: "2.1",
|
|
387
430
|
automatability: "needs-rendering",
|
|
388
431
|
ruleIds: ["rendered-orientation-lock"],
|
|
389
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/orientation.html"
|
|
432
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/orientation.html",
|
|
433
|
+
text: "Content does not restrict its view and operation to a single display orientation, such as portrait or landscape, unless a specific display orientation is essential.\nNote: Examples where a particular display orientation may be essential are a bank check, a piano application, slides for a projector or television, or virtual reality content where parts of the image (for instance, a status bar or heads-up display) always remain at a fixed orientation relative to the headset screens (and the user's eyes) regardless of the physical orientation of the headset.",
|
|
434
|
+
textFr: "La consultation et le fonctionnement du contenu ne sont pas limit\xE9s \xE0 une seule orientation de l\u2019affichage, comme le portrait ou le paysage, \xE0 moins qu\u2019une orientation sp\xE9cifique de l\u2019affichage ne soit essentielle.\nNote : On compte parmi les exemples o\xF9 une orientation sp\xE9cifique de l\u2019affichage peut \xEAtre essentielle : un ch\xE8que de banque, une application de piano, des diapositives pour un projecteur ou une t\xE9l\xE9vision, ou un contenu de r\xE9alit\xE9 virtuelle qui n\u2019est pas n\xE9cessairement limit\xE9 \xE0 une orientation d\u2019affichage en mode paysage ou portrait.",
|
|
435
|
+
termsFr: ["essential"],
|
|
436
|
+
terms: ["essential"]
|
|
390
437
|
},
|
|
391
438
|
{
|
|
392
439
|
sc: "1.3.5",
|
|
@@ -399,7 +446,11 @@ var wcag_default = {
|
|
|
399
446
|
automatability: "judgment",
|
|
400
447
|
ruleIds: ["field-purpose-incomplete", "autocomplete-token-invalid"],
|
|
401
448
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/identify-input-purpose.html",
|
|
402
|
-
techniques: ["H98"]
|
|
449
|
+
techniques: ["H98"],
|
|
450
|
+
text: "The purpose of each input field collecting information about the user can be programmatically determined when:\n\u2022 The input field serves a purpose identified in the Input Purposes for user interface components section; and\n\u2022 The content is implemented using technologies with support for identifying the expected meaning for form input data.",
|
|
451
|
+
textFr: "La finalit\xE9 de chaque champ de saisie recueillant des informations sur l\u2019utilisateur peut \xEAtre d\xE9termin\xE9e par un programme informatique lorsque :\n\u2022 Le champ de saisie r\xE9pond \xE0 une finalit\xE9 identifi\xE9e dans la section Finalit\xE9s de saisie des composants d\u2019interface utilisateur ; et\n\u2022 Le contenu est impl\xE9ment\xE9 via des technologies permettant d\u2019identifier la finalit\xE9 de la saisie attendue pour le champ.",
|
|
452
|
+
termsFr: ["programmatically-determinable"],
|
|
453
|
+
terms: ["programmatically-determined"]
|
|
403
454
|
},
|
|
404
455
|
{
|
|
405
456
|
sc: "1.4.1",
|
|
@@ -412,7 +463,9 @@ var wcag_default = {
|
|
|
412
463
|
automatability: "needs-rendering",
|
|
413
464
|
ruleIds: ["rendered-link-colour-only"],
|
|
414
465
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html",
|
|
415
|
-
techniques: ["C15", "F14", "F26", "F73", "F78", "G111", "G117", "G138", "G14", "G140", "G149", "G165", "G182", "G183", "G195", "G205", "G96", "SCR31"]
|
|
466
|
+
techniques: ["C15", "F14", "F26", "F73", "F78", "G111", "G117", "G138", "G14", "G140", "G149", "G165", "G182", "G183", "G195", "G205", "G96", "SCR31"],
|
|
467
|
+
text: "Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.\nNote: This success criterion addresses color perception specifically. Other forms of perception are covered in Guideline 1.3 including programmatic access to color and other visual presentation coding.",
|
|
468
|
+
textFr: "La couleur n\u2019est pas utilis\xE9e comme la seule fa\xE7on de v\xE9hiculer de l\u2019information, d\u2019indiquer une action, de solliciter une r\xE9ponse ou de distinguer un \xE9l\xE9ment visuel.\nNote : Ce crit\xE8re de succ\xE8s traite sp\xE9cifiquement de la perception des couleurs. Les autres formes de perception sont trait\xE9es \xE0 la r\xE8gle 1.3 comme l\u2019acc\xE8s \xE0 la couleur par programme informatique et les autres formes de codage de la pr\xE9sentation visuelle."
|
|
416
469
|
},
|
|
417
470
|
{
|
|
418
471
|
sc: "1.4.2",
|
|
@@ -425,7 +478,11 @@ var wcag_default = {
|
|
|
425
478
|
automatability: "static",
|
|
426
479
|
ruleIds: ["autoplay-media"],
|
|
427
480
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/audio-control.html",
|
|
428
|
-
techniques: ["F23", "F93", "G170", "G171", "G60"]
|
|
481
|
+
techniques: ["F23", "F93", "G170", "G171", "G60"],
|
|
482
|
+
text: "If any audio on a web page plays automatically for more than 3 seconds, either a mechanism is available to pause or stop the audio, or a mechanism is available to control audio volume independently from the overall system volume level.\nNote: Since any content that does not meet this success criterion can interfere with a user's ability to use the whole page, all content on the web page (whether or not it is used to meet other success criteria) must meet this success criterion. See Conformance Requirement 5: Non-Interference.",
|
|
483
|
+
textFr: "Si du son sur une page Web est audible automatiquement pendant plus de 3 secondes, un m\xE9canisme est disponible pour le mettre en pause, l\u2019arr\xEAter ou pour en contr\xF4ler le volume de fa\xE7on ind\xE9pendante du niveau de volume du syst\xE8me g\xE9n\xE9ral.\nNote : Puisque tout contenu ne satisfaisant pas \xE0 ce crit\xE8re de succ\xE8s peut interf\xE9rer avec la capacit\xE9 de l\u2019utilisateur \xE0 exploiter la page enti\xE8re, tout le contenu pr\xE9sent dans la page Web (qu\u2019il soit utilis\xE9 pour satisfaire \xE0 d\u2019autres crit\xE8res de succ\xE8s ou non) doit satisfaire \xE0 ce crit\xE8re de succ\xE8s. Voir l\u2019exigence de conformit\xE9 5 : Non-interf\xE9rence.",
|
|
484
|
+
termsFr: ["mechanism"],
|
|
485
|
+
terms: ["mechanism", "paused"]
|
|
429
486
|
},
|
|
430
487
|
{
|
|
431
488
|
sc: "1.4.3",
|
|
@@ -438,7 +495,11 @@ var wcag_default = {
|
|
|
438
495
|
automatability: "needs-rendering",
|
|
439
496
|
ruleIds: ["contrast-literal", "rendered-contrast", "rendered-contrast-pixel"],
|
|
440
497
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html",
|
|
441
|
-
techniques: ["C29", "F24", "G136", "G145", "G148", "G174", "G18"]
|
|
498
|
+
techniques: ["C29", "F24", "G136", "G145", "G148", "G174", "G18"],
|
|
499
|
+
text: "The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for the following:\nLarge Text:\nLarge-scale text and images of large-scale text have a contrast ratio of at least 3:1;\nIncidental:\nText or images of text that are part of an inactive user interface component, that are pure decoration, that are not visible to anyone, or that are part of a picture that contains significant other visual content, have no contrast requirement.\nLogotypes:\nText that is part of a logo or brand name has no contrast requirement.",
|
|
500
|
+
textFr: "La pr\xE9sentation visuelle du texte et du texte sous forme d\u2019image a un rapport de contraste d\u2019au moins 4,5:1, sauf dans les cas suivants :\nTexte agrandi:\nle texte agrandi et le texte agrandi sous forme d\u2019image ont un rapport de contraste d\u2019au moins 3:1.\nTexte d\xE9coratif:\naucune exigence de contraste pour le texte ou le texte sous forme d\u2019image qui fait partie d\u2019un composant d\u2019interface utilisateur inactif, qui est purement d\xE9coratif, qui est invisible pour tous ou qui est une partie d\u2019une image contenant un autre contenu significatif.\nLogotypes:\naucune exigence de contraste pour le texte faisant partie d\u2019un logo ou d\u2019un nom de marque.",
|
|
501
|
+
termsFr: ["text", "images-of-text", "contrast-ratio", "large-scale", "user-interface-components", "pure-decoration"],
|
|
502
|
+
terms: ["text", "image-of-text", "contrast-ratio", "large-scale", "user-interface-component", "pure-decoration"]
|
|
442
503
|
},
|
|
443
504
|
{
|
|
444
505
|
sc: "1.4.4",
|
|
@@ -451,7 +512,11 @@ var wcag_default = {
|
|
|
451
512
|
automatability: "needs-rendering",
|
|
452
513
|
ruleIds: ["meta-viewport-zoom-block"],
|
|
453
514
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/resize-text.html",
|
|
454
|
-
techniques: ["C12", "C13", "C14", "C17", "C28", "F69", "F80", "G146", "G179", "SCR34"]
|
|
515
|
+
techniques: ["C12", "C13", "C14", "C17", "C28", "F69", "F80", "G146", "G179", "SCR34"],
|
|
516
|
+
text: "Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.",
|
|
517
|
+
textFr: "\xC0 l\u2019exception des sous-titres et du texte sous forme d\u2019image, le texte peut \xEAtre redimensionn\xE9 jusqu\u2019\xE0 200 pour cent sans l\u2019aide d\u2019une technologie d\u2019assistance et sans perte de contenu ou de fonctionnalit\xE9.",
|
|
518
|
+
termsFr: ["captions", "images-of-text", "text", "assistive-technologies"],
|
|
519
|
+
terms: ["captions", "image-of-text", "text", "assistive-technology"]
|
|
455
520
|
},
|
|
456
521
|
{
|
|
457
522
|
sc: "1.4.5",
|
|
@@ -464,7 +529,11 @@ var wcag_default = {
|
|
|
464
529
|
automatability: "needs-rendering",
|
|
465
530
|
ruleIds: [],
|
|
466
531
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/images-of-text.html",
|
|
467
|
-
techniques: ["C22", "C30", "G136", "G140"]
|
|
532
|
+
techniques: ["C22", "C30", "G136", "G140"],
|
|
533
|
+
text: "If the technologies being used can achieve the visual presentation, text is used to convey information rather than images of text except for the following:\nCustomizable:\nThe image of text can be visually customized to the user's requirements;\nEssential:\nA particular presentation of text is essential to the information being conveyed.\nNote: Logotypes (text that is part of a logo or brand name) are considered essential.",
|
|
534
|
+
textFr: "Si les technologies utilis\xE9es peuvent r\xE9aliser la pr\xE9sentation visuelle, du texte est utilis\xE9 pour v\xE9hiculer l\u2019information plut\xF4t que du texte sous forme d\u2019image sauf dans les cas suivants :\nPersonnalisable:\nle texte sous forme d\u2019image peut \xEAtre personnalis\xE9 visuellement selon les exigences de l\u2019utilisateur ;\nEssentielle:\nune pr\xE9sentation sp\xE9cifique du texte est essentielle \xE0 l\u2019information v\xE9hicul\xE9e.\nNote : Les logotypes sont consid\xE9r\xE9s comme essentiels (le texte qui fait partie d\u2019un logo ou d\u2019un nom de marque).",
|
|
535
|
+
termsFr: ["text", "images-of-text", "visually-customized", "essential"],
|
|
536
|
+
terms: ["text", "image-of-text", "visually-customized", "essential"]
|
|
468
537
|
},
|
|
469
538
|
{
|
|
470
539
|
sc: "1.4.10",
|
|
@@ -477,7 +546,11 @@ var wcag_default = {
|
|
|
477
546
|
automatability: "needs-rendering",
|
|
478
547
|
ruleIds: [],
|
|
479
548
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/reflow.html",
|
|
480
|
-
techniques: ["C34", "C37"]
|
|
549
|
+
techniques: ["C34", "C37"],
|
|
550
|
+
text: "Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions for:\n\u2022 Vertical scrolling content at a width equivalent to 320 CSS pixels;\n\u2022 Horizontal scrolling content at a height equivalent to 256 CSS pixels.\nExcept for parts of the content which require two-dimensional layout for usage or meaning.\nNote: 320 CSS pixels is equivalent to a starting viewport width of 1280 CSS pixels wide at 400% zoom. For web content which is designed to scroll horizontally (e.g., with vertical text), 256 CSS pixels is equivalent to a starting viewport height of 1024 CSS pixels at 400% zoom.\nNote: Examples of content which requires two-dimensional layout are images required for understanding (such as maps and diagrams), video, games, presentations, data tables (not individual cells), and interfaces where it is necessary to keep toolbars in view while manipulating content. It is acceptable to provide two-dimensional scrolling for such parts of the content.",
|
|
551
|
+
textFr: "Le contenu peut \xEAtre pr\xE9sent\xE9 sans perte d\u2019information ou de fonctionnalit\xE9 et sans n\xE9cessit\xE9 de d\xE9filement dans les deux dimensions pour :\n\u2022 un contenu \xE0 d\xE9filement vertical avec une largeur \xE9quivalente \xE0 320 pixels CSS ;\n\u2022 un contenu \xE0 d\xE9filement horizontal avec une hauteur \xE9quivalente \xE0 256 pixels CSS.\nSauf pour les parties du contenu dont l\u2019utilisation ou la compr\xE9hension n\xE9cessite une mise en page en deux dimensions.\nNote : 320 pixels CSS \xE9quivaut \xE0 une largeur d\u2019affichage initiale de 1280 pixels CSS avec un zoom de 400 %. Pour un contenu Web con\xE7u pour d\xE9filer horizontalement (par exemple, avec du texte vertical), la valeur de 256 pixels CSS \xE9quivaut \xE0 une hauteur d\u2019affichage initiale de 1024 pixels CSS avec un zoom de 400 %.\nNote : On compte parmi les exemples de contenu n\xE9cessitant une mise en page en deux dimensions les images n\xE9cessaires \xE0 la compr\xE9hension (comme les cartes ou les diagrammes), les vid\xE9os, les jeux, les pr\xE9sentations, les tableaux de donn\xE9es (non pas les cellules individuelles), et les interfaces o\xF9 il est n\xE9cessaire de garder les barres d\u2019outils visibles pendant la manipulation du contenu. Un d\xE9filement bidimensionnel pour ces parties du contenu est acceptable.",
|
|
552
|
+
termsFr: ["css-pixels"],
|
|
553
|
+
terms: ["css-pixel", "viewport"]
|
|
481
554
|
},
|
|
482
555
|
{
|
|
483
556
|
sc: "1.4.11",
|
|
@@ -490,7 +563,11 @@ var wcag_default = {
|
|
|
490
563
|
automatability: "needs-rendering",
|
|
491
564
|
ruleIds: ["rendered-nontext-contrast"],
|
|
492
565
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html",
|
|
493
|
-
techniques: ["F78", "G145", "G174", "G18", "G183", "G195", "G207"]
|
|
566
|
+
techniques: ["F78", "G145", "G174", "G18", "G183", "G195", "G207"],
|
|
567
|
+
text: "The visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s):\nUser Interface Components: Visual information required to identify user interface components and states, except for inactive components or where the appearance of the component is determined by the user agent and not modified by the author;\nGraphical Objects: Parts of graphics required to understand the content, except when a particular presentation of graphics is essential to the information being conveyed.",
|
|
568
|
+
textFr: "La pr\xE9sentation visuelle des \xE9l\xE9ments suivants a un rapport de contraste d\u2019au moins 3:1 avec la ou les couleurs adjacentes :\nComposants d\u2019interface utilisateur: informations visuelles n\xE9cessaires \xE0 l\u2019identification des composants et des \xE9tats de l\u2019interface utilisateur, \xE0 l\u2019exception des composants inactifs ou lorsque l\u2019apparence du composant est d\xE9termin\xE9e par l\u2019agent utilisateur et non modifi\xE9e par l\u2019auteur ;\nObjets graphiques: parties d\u2019\xE9l\xE9ments graphiques n\xE9cessaires \xE0 la compr\xE9hension du contenu, sauf si une pr\xE9sentation sp\xE9cifique de ces \xE9l\xE9ments est essentielle \xE0 l\u2019information transmise.",
|
|
569
|
+
termsFr: ["presentation", "contrast-ratio", "user-interface-components", "states", "essential"],
|
|
570
|
+
terms: ["presentation", "contrast-ratio", "user-interface-component", "state", "user-agent", "essential"]
|
|
494
571
|
},
|
|
495
572
|
{
|
|
496
573
|
sc: "1.4.12",
|
|
@@ -503,7 +580,11 @@ var wcag_default = {
|
|
|
503
580
|
automatability: "needs-rendering",
|
|
504
581
|
ruleIds: [],
|
|
505
582
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/text-spacing.html",
|
|
506
|
-
techniques: ["C21", "C35", "C36", "C8"]
|
|
583
|
+
techniques: ["C21", "C35", "C36", "C8"],
|
|
584
|
+
text: "In content implemented using markup languages that support the following text style properties, no loss of content or functionality occurs by setting all of the following and by changing no other style property:\n\u2022 Line height (line spacing) to at least 1.5 times the font size;\n\u2022 Spacing following paragraphs to at least 2 times the font size;\n\u2022 Letter spacing (tracking) to at least 0.12 times the font size;\n\u2022 Word spacing to at least 0.16 times the font size.\nException: Human languages and scripts that do not make use of one or more of these text style properties in written text can conform using only the properties that exist for that combination of language and script.\nNote: Content is not required to use these text spacing values. The requirement is to ensure that when a user overrides the authored text spacing, content or functionality is not lost.\nNote: Writing systems for some languages use different text spacing settings, such as paragraph start indent. Authors are encouraged to follow locally available guidance for improving readability and legibility of text in their writing system.",
|
|
585
|
+
textFr: "Dans un contenu impl\xE9ment\xE9 via un langage de balisage qui prend en charge les propri\xE9t\xE9s de style de texte suivantes, il n\u2019y a aucune perte de contenu ou de fonctionnalit\xE9 lorsqu\u2019on applique toutes les valeurs ci-dessous sans modifier aucune autre propri\xE9t\xE9 de style :\n\u2022 La hauteur de ligne (interlignage) d\xE9finie \xE0 au moins 1,5 fois la taille de la police ;\n\u2022 L\u2019espacement entre les paragraphes cons\xE9cutifs d\xE9fini \xE0 au moins 2 fois la taille de la police ;\n\u2022 L\u2019espacement des lettres (interlettrage) d\xE9fini \xE0 au moins 0,12 fois la taille de la police ;\n\u2022 L\u2019espacement entre les mots d\xE9fini \xE0 au moins 0,16 fois la taille de la police.\nException : les langues et syst\xE8mes d\u2019\xE9critures qui n\u2019utilisent pas une ou plusieurs de ces propri\xE9t\xE9s de style de texte pour le texte \xE9crit peuvent \xEAtre conformes en utilisant uniquement les propri\xE9t\xE9s qui existent pour cette combinaison de langue et de syst\xE8me d\u2019\xE9criture.\nNote : Il n\u2019est pas obligatoire d\u2019utiliser ces valeurs d\u2019espacement du texte. L\u2019exigence consiste \xE0 s\u2019assurer que, lorsqu\u2019un utilisateur modifie l\u2019espacement du texte d\xE9fini par l\u2019auteur, le contenu ou la fonctionnalit\xE9 ne soient pas perdus.\nNote : Dans certaines langues, les syst\xE8mes d\u2019\xE9criture utilisent des param\xE8tres d\u2019espacement de texte diff\xE9rents, tels que l\u2019indentation au d\xE9but des paragraphes. Les auteurs sont encourag\xE9s \xE0 suivre les recommandations disponibles \xE0 l\u2019\xE9chelle locale pour am\xE9liorer la lisibilit\xE9 et la clart\xE9 du texte dans leur propre syst\xE8me d\u2019\xE9criture.",
|
|
586
|
+
termsFr: ["style-properties", "text"],
|
|
587
|
+
terms: ["text", "style-property", "human-language"]
|
|
507
588
|
},
|
|
508
589
|
{
|
|
509
590
|
sc: "1.4.13",
|
|
@@ -516,7 +597,11 @@ var wcag_default = {
|
|
|
516
597
|
automatability: "needs-rendering",
|
|
517
598
|
ruleIds: [],
|
|
518
599
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/content-on-hover-or-focus.html",
|
|
519
|
-
techniques: ["F95"]
|
|
600
|
+
techniques: ["F95"],
|
|
601
|
+
text: "Where receiving and then removing pointer hover or keyboard focus triggers additional content to become visible and then hidden, all of the following are true:\nDismissible: A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error or does not obscure or replace other content;\nHoverable: If pointer hover can trigger the additional content, then the pointer can be moved over the additional content without the additional content disappearing;\nPersistent: The additional content remains visible until the hover or focus trigger is removed, the user dismisses it, or its information is no longer valid.\nException: The visual presentation of the additional content is controlled by the user agent and is not modified by the author.\nNote: Examples of additional content controlled by the user agent include browser tooltips created through use of the HTML title attribute [[HTML]].\nNote: Custom tooltips, sub-menus, and other nonmodal popups that display on hover and focus are examples of additional content covered by this criterion.\nNote: This criterion applies to content that appears in addition to the triggering component itself. Since hidden components that are made visible on keyboard focus (such as links used to skip to another part of a page) do not present additional content they are not covered by this criterion.",
|
|
602
|
+
textFr: "Lorsque la r\xE9ception puis le retrait du survol du pointeur ou du focus du clavier d\xE9clenche l\u2019affichage puis le masquage d\u2019un contenu additionnel, les \xE9l\xE9ments suivants sont vrais :\nMasquable: il existe un m\xE9canisme permettant de masquer le contenu additionnel sans d\xE9placer le pointeur ou le focus du clavier, \xE0 moins que le contenu additionnel ne communique une erreur de saisie ou ne masque ni ne remplace un autre contenu ;\nSurvolable: si le survol du pointeur peut d\xE9clencher le contenu additionnel, alors le pointeur peut \xEAtre d\xE9plac\xE9 sur le contenu additionnel sans que celui-ci disparaisse ;\nPersistant: le contenu additionnel reste visible jusqu\u2019\xE0 ce que le survol ou le focus soit retir\xE9, que l\u2019utilisateur le masque ou que ses informations ne soient plus valables.\nException : la pr\xE9sentation visuelle du contenu additionnel est contr\xF4l\xE9e par l\u2019agent utilisateur et n\u2019est pas modifi\xE9e par l\u2019auteur.\nNote : Parmi les exemples de contenu additionnel contr\xF4l\xE9 par l\u2019agent utilisateur figurent les infobulles du navigateur cr\xE9\xE9es \xE0 l\u2019aide de l\u2019attribut HTML title [HTML].\nNote : Les infobulles personnalis\xE9es, les sous-menus et autres fen\xEAtres non modales qui s\u2019affichent au survol et \xE0 la prise de focus sont des exemples de contenu additionnel couvert par ce crit\xE8re.\nNote : Ce crit\xE8re s\u2019applique au contenu qui appara\xEEt en plus du composant d\xE9clencheur lui-m\xEAme. \xC9tant donn\xE9 que les composants cach\xE9s qui deviennent visibles au focus du clavier (comme les liens d\u2019acc\xE8s rapide \xE0 une autre partie d\u2019une page) ne pr\xE9sentent pas de contenu additionnel, ils ne sont pas couverts par ce crit\xE8re.",
|
|
603
|
+
termsFr: ["mechanism", "input-error"],
|
|
604
|
+
terms: ["mechanism", "input-error", "user-agent"]
|
|
520
605
|
},
|
|
521
606
|
{
|
|
522
607
|
sc: "2.1.1",
|
|
@@ -529,7 +614,11 @@ var wcag_default = {
|
|
|
529
614
|
automatability: "judgment",
|
|
530
615
|
ruleIds: ["clickable-noninteractive"],
|
|
531
616
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html",
|
|
532
|
-
techniques: ["F10", "F42", "F54", "F55", "G202", "G21", "G4", "G90", "H91", "SCR2", "SCR20", "SCR29", "SCR35"]
|
|
617
|
+
techniques: ["F10", "F42", "F54", "F55", "G202", "G21", "G4", "G90", "H91", "SCR2", "SCR20", "SCR29", "SCR35"],
|
|
618
|
+
text: "All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.\nNote: This exception relates to the underlying function, not the input technique. For example, if using handwriting to enter text, the input technique (handwriting) requires path-dependent input but the underlying function (text input) does not.\nNote: This does not forbid and should not discourage providing mouse input or other input methods in addition to keyboard operation.",
|
|
619
|
+
textFr: "Toutes les fonctionnalit\xE9s du contenu sont utilisables \xE0 l\u2019aide d\u2019une interface clavier sans exiger un rythme de frappe propre \xE0 l\u2019utilisateur, sauf lorsque la fonction sous-jacente n\xE9cessite une saisie qui d\xE9pend du trac\xE9 du mouvement effectu\xE9 par l\u2019utilisateur et pas seulement des points de d\xE9part et d\u2019arriv\xE9e de ce trac\xE9.\nNote : Cette exception ne concerne que la fonction sous-jacente et non la technique de saisie. Par exemple, lorsqu\u2019on utilise l\u2019\xE9criture manuscrite pour saisir du texte, la technique de saisie (l\u2019\xE9criture manuscrite) n\xE9cessite une saisie qui d\xE9pend d\u2019un trac\xE9, mais la fonction sous-jacente (la saisie de texte) ne le requiert pas.\nNote : Cela n\u2019interdit pas et ne devrait pas d\xE9courager l\u2019utilisation de la souris ou de toute autre m\xE9thode de saisie en plus de l\u2019utilisation du clavier.",
|
|
620
|
+
termsFr: ["functionality", "keyboard-interface"],
|
|
621
|
+
terms: ["functionality", "keyboard-interface"]
|
|
533
622
|
},
|
|
534
623
|
{
|
|
535
624
|
sc: "2.1.2",
|
|
@@ -542,7 +631,11 @@ var wcag_default = {
|
|
|
542
631
|
automatability: "needs-rendering",
|
|
543
632
|
ruleIds: [],
|
|
544
633
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/no-keyboard-trap.html",
|
|
545
|
-
techniques: ["F10", "G202", "G21", "G4", "G90", "H91"]
|
|
634
|
+
techniques: ["F10", "G202", "G21", "G4", "G90", "H91"],
|
|
635
|
+
text: "If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface, and, if it requires more than unmodified arrow or tab keys or other standard exit methods, the user is advised of the method for moving focus away.\nNote: Since any content that does not meet this success criterion can interfere with a user's ability to use the whole page, all content on the web page (whether it is used to meet other success criteria or not) must meet this success criterion. See Conformance Requirement 5: Non-Interference.",
|
|
636
|
+
textFr: "Si le focus du clavier peut \xEAtre positionn\xE9 sur un \xE9l\xE9ment de la page \xE0 l\u2019aide d\u2019une interface clavier, r\xE9ciproquement, il peut \xEAtre d\xE9plac\xE9 hors de ce m\xEAme composant simplement \xE0 l\u2019aide d\u2019une interface clavier et, si ce d\xE9placement exige plus que l\u2019utilisation d\u2019une simple touche fl\xE8che ou tabulation ou toute autre m\xE9thode standard de sortie, l\u2019utilisateur est inform\xE9 de la m\xE9thode permettant de d\xE9placer le focus hors de ce composant.\nNote : Puisque tout contenu ne satisfaisant pas \xE0 ce crit\xE8re de succ\xE8s peut interf\xE9rer avec la capacit\xE9 de l\u2019utilisateur \xE0 exploiter la page enti\xE8re, tout le contenu pr\xE9sent dans la page Web (qu\u2019il soit utilis\xE9 pour satisfaire \xE0 d\u2019autres crit\xE8res de succ\xE8s ou non) doit satisfaire \xE0 ce crit\xE8re de succ\xE8s. Voir l\u2019exigence de conformit\xE9 5 : Non-interf\xE9rence.",
|
|
637
|
+
termsFr: ["keyboard-interface"],
|
|
638
|
+
terms: ["keyboard-interface"]
|
|
546
639
|
},
|
|
547
640
|
{
|
|
548
641
|
sc: "2.1.4",
|
|
@@ -555,7 +648,11 @@ var wcag_default = {
|
|
|
555
648
|
automatability: "judgment",
|
|
556
649
|
ruleIds: [],
|
|
557
650
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/character-key-shortcuts.html",
|
|
558
|
-
techniques: ["F99", "G217"]
|
|
651
|
+
techniques: ["F99", "G217"],
|
|
652
|
+
text: "If a keyboard shortcut is implemented in content using only letter (including upper- and lower-case letters), punctuation, number, or symbol characters, then at least one of the following is true:\nTurn off: A mechanism is available to turn the shortcut off;\nRemap: A mechanism is available to remap the shortcut to include one or more non-printable keyboard keys (e.g., Ctrl, Alt);\nActive only on focus: The keyboard shortcut for a user interface component is only active when that component has focus.",
|
|
653
|
+
textFr: "Si un raccourci clavier est impl\xE9ment\xE9 dans du contenu en utilisant uniquement des caract\xE8res de type lettres (y compris les majuscules et les minuscules), des signes de ponctuation, des chiffres ou des symboles, alors au moins l\u2019une des conditions suivantes est vraie :\nD\xE9sactivation: un m\xE9canisme est disponible pour d\xE9sactiver le raccourci ;\nR\xE9assignation: un m\xE9canisme est disponible pour r\xE9assigner le raccourci afin d\u2019inclure une ou plusieurs touches non imprimables du clavier (par exemple, Ctrl, Alt) ;\nActif uniquement au focus: le raccourci clavier pour un composant d\u2019interface utilisateur n\u2019est actif que lorsque ce composant a le focus.",
|
|
654
|
+
termsFr: ["keyboard-shortcuts", "mechanism", "user-interface-components"],
|
|
655
|
+
terms: ["keyboard-shortcut", "mechanism", "user-interface-component"]
|
|
559
656
|
},
|
|
560
657
|
{
|
|
561
658
|
sc: "2.2.1",
|
|
@@ -599,7 +696,11 @@ var wcag_default = {
|
|
|
599
696
|
"SM11",
|
|
600
697
|
"SM12",
|
|
601
698
|
"SVR1"
|
|
602
|
-
]
|
|
699
|
+
],
|
|
700
|
+
text: 'For each time limit that is set by the content, at least one of the following is true:\nTurn off:\nThe user is allowed to turn off the time limit before encountering it; or\nAdjust:\nThe user is allowed to adjust the time limit before encountering it over a wide range that is at least ten times the length of the default setting; or\nExtend:\nThe user is warned before time expires and given at least 20 seconds to extend the time limit with a simple action (for example, "press the space bar"), and the user is allowed to extend the time limit at least ten times; or\nReal-time Exception:\nThe time limit is a required part of a real-time event (for example, an auction), and no alternative to the time limit is possible; or\nEssential Exception:\nThe time limit is essential and extending it would invalidate the activity; or\n20 Hour Exception:\nThe time limit is longer than 20 hours.\nNote: This success criterion helps ensure that users can complete tasks without unexpected changes in content or context that are a result of a time limit. This success criterion should be considered in conjunction with Success Criterion 3.2.1, which puts limits on changes of content or context as a result of user action.',
|
|
701
|
+
textFr: "Pour chaque limite de temps fix\xE9e par le contenu, au moins l\u2019un des points suivants est vrai :\nSuppression:\nl\u2019utilisateur a la possibilit\xE9 de supprimer la limite de temps avant de la rencontrer ; ou\nAjustement:\nl\u2019utilisateur a la possibilit\xE9 d\u2019ajuster la limite de temps avant de la rencontrer dans un intervalle d\u2019au moins dix fois la dur\xE9e param\xE9tr\xE9e par d\xE9faut ; ou\nExtension:\nl\u2019utilisateur est averti avant que la limite de temps n\u2019expire et il lui est accord\xE9 au moins 20 secondes pour \xE9tendre cette limite par une action simple (par exemple, \xAB appuyer sur la barre d\u2019espace \xBB) et l\u2019utilisateur a la possibilit\xE9 d\u2019\xE9tendre la limite de temps au moins dix fois ; ou\nL\u2019exception du temps r\xE9el:\nla limite de temps est une partie constitutive d\u2019un \xE9v\xE9nement en temps r\xE9el (par exemple, une ench\xE8re) et aucune alternative n\u2019est possible ; ou\nL\u2019exception de la limite essentielle:\nla limite de temps est essentielle et l\u2019\xE9tendre invaliderait alors l\u2019activit\xE9 ; ou\nL\u2019exception des 20 heures:\nla limite de temps est sup\xE9rieure \xE0 20 heures.\nNote : Ce crit\xE8re de succ\xE8s permet de s\u2019assurer que les utilisateurs peuvent compl\xE9ter leurs t\xE2ches sans changement inattendu de contenu ou de contexte r\xE9sultant de la limite de temps. Il devrait \xEAtre consid\xE9r\xE9 conjointement avec le crit\xE8re de succ\xE8s 3.2.1, qui pose des limites aux changements de contenu ou de contexte r\xE9sultant d\u2019une action de l\u2019utilisateur.",
|
|
702
|
+
termsFr: ["essential"],
|
|
703
|
+
terms: ["real-time-event", "essential"]
|
|
603
704
|
},
|
|
604
705
|
{
|
|
605
706
|
sc: "2.2.2",
|
|
@@ -643,7 +744,11 @@ var wcag_default = {
|
|
|
643
744
|
"SM11",
|
|
644
745
|
"SM12",
|
|
645
746
|
"SVR1"
|
|
646
|
-
]
|
|
747
|
+
],
|
|
748
|
+
text: "For moving, blinking, scrolling, or auto-updating information, all of the following are true:\nMoving, blinking, scrolling:\nFor any moving, blinking or scrolling information that (1) starts automatically, (2) lasts more than five seconds, and (3) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it unless the movement, blinking, or scrolling is part of an activity where it is essential; and\nAuto-updating:\nFor any auto-updating information that (1) starts automatically and (2) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it or to control the frequency of the update unless the auto-updating is part of an activity where it is essential.\nNote: For requirements related to flickering or flashing content, refer to Guideline 2.3.\nNote: Since any content that does not meet this success criterion can interfere with a user's ability to use the whole page, all content on the web page (whether it is used to meet other success criteria or not) must meet this success criterion. See Conformance Requirement 5: Non-Interference.\nNote: Content that is updated periodically by software or that is streamed to the user agent is not required to preserve or present information that is generated or received between the initiation of the pause and resuming presentation, as this may not be technically possible, and in many situations could be misleading to do so.\nNote: An animation that occurs as part of a preload phase or similar situation can be considered essential if interaction cannot occur during that phase for all users and if not indicating progress could confuse users or cause them to think that content was frozen or broken.",
|
|
749
|
+
textFr: "Pour toute information en mouvement, clignotante, d\xE9filante ou mise \xE0 jour automatiquement, tous les points suivants sont vrais :\nD\xE9placement, clignotement, d\xE9filement:\npour toute information en mouvement, clignotante ou d\xE9filante qui (1) d\xE9marre automatiquement, (2) dure plus de cinq secondes et (3) est pr\xE9sent\xE9e conjointement avec un autre contenu, il y a un m\xE9canisme \xE0 la disposition de l\u2019utilisateur pour la mettre en pause, l\u2019arr\xEAter ou la masquer, \xE0 moins que le mouvement, le clignotement ou le d\xE9filement s\u2019av\xE8re un \xE9l\xE9ment essentiel au bon d\xE9roulement de l\u2019activit\xE9; et\nMise \xE0 jour automatique:\npour toute information mise \xE0 jour automatiquement qui (1) d\xE9marre automatiquement (2) et est pr\xE9sent\xE9e conjointement avec un autre contenu, il y a un m\xE9canisme \xE0 la disposition de l\u2019utilisateur pour la mettre en pause, l\u2019arr\xEAter ou pour en contr\xF4ler la fr\xE9quence des mises \xE0 jour \xE0 moins que la mise \xE0 jour automatique s\u2019av\xE8re essentielle au bon d\xE9roulement de l\u2019activit\xE9.\nNote : Pour les exigences relatives au contenu scintillant ou flashant, se r\xE9f\xE9rer \xE0 la r\xE8gle 2.3.\nNote : Puisque tout contenu ne satisfaisant pas \xE0 ce crit\xE8re de succ\xE8s peut interf\xE9rer avec la capacit\xE9 de l\u2019utilisateur \xE0 exploiter la page enti\xE8re, tout le contenu pr\xE9sent dans la page Web (qu\u2019il soit utilis\xE9 pour satisfaire \xE0 d\u2019autres crit\xE8res de succ\xE8s ou non) doit satisfaire \xE0 ce crit\xE8re de succ\xE8s. Lire Exigence de conformit\xE9 5 : Non-interf\xE9rence.\nNote : Il n\u2019est pas exig\xE9 que le contenu mis \xE0 jour p\xE9riodiquement par logiciel ou diffus\xE9 en flux \xE0 l\u2019agent utilisateur conserve ou pr\xE9sente l\u2019information g\xE9n\xE9r\xE9e ou re\xE7ue entre la mise en pause et la reprise de la pr\xE9sentation, puisque cela peut ne pas \xEAtre techniquement possible et s\u2019av\xE9rer trompeur dans beaucoup de situations.\nNote : Une animation survenant dans une phase de pr\xE9-chargement ou dans une situation similaire peut \xEAtre consid\xE9r\xE9e comme essentielle si aucune interaction n\u2019est permise \xE0 tous les utilisateurs durant cette phase et si l\u2019absence d\u2019indication de progression est susceptible de perturber les utilisateurs ou de leur faire croire que le contenu est fig\xE9 ou d\xE9fectueux.",
|
|
750
|
+
termsFr: ["blinking", "pause", "essential"],
|
|
751
|
+
terms: ["blinking", "mechanism", "paused", "essential"]
|
|
647
752
|
},
|
|
648
753
|
{
|
|
649
754
|
sc: "2.3.1",
|
|
@@ -656,7 +761,11 @@ var wcag_default = {
|
|
|
656
761
|
automatability: "needs-rendering",
|
|
657
762
|
ruleIds: [],
|
|
658
763
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/three-flashes-or-below-threshold.html",
|
|
659
|
-
techniques: ["G15", "G176", "G19"]
|
|
764
|
+
techniques: ["G15", "G176", "G19"],
|
|
765
|
+
text: "Web pages do not contain anything that flashes more than three times in any one second period, or the flash is below the general flash and red flash thresholds.\nNote: Since any content that does not meet this success criterion can interfere with a user's ability to use the whole page, all content on the web page (whether it is used to meet other success criteria or not) must meet this success criterion. See Conformance Requirement 5: Non-Interference.",
|
|
766
|
+
textFr: "Une page Web doit \xEAtre exempte de tout \xE9l\xE9ment qui flashe plus de trois fois dans n\u2019importe quel intervalle d\u2019une seconde ou ce flash doit se situer sous le seuil de flash g\xE9n\xE9rique et le seuil de flash rouge.\nNote : Puisque tout contenu ne satisfaisant pas \xE0 ce crit\xE8re de succ\xE8s peut interf\xE9rer avec la capacit\xE9 de l\u2019utilisateur \xE0 exploiter la page enti\xE8re, tout le contenu pr\xE9sent dans la page Web (qu\u2019il soit utilis\xE9 pour satisfaire \xE0 d\u2019autres crit\xE8res de succ\xE8s ou non) doit satisfaire \xE0 ce crit\xE8re de succ\xE8s. Voir l\u2019exigence de conformit\xE9 5 : Non-interf\xE9rence.",
|
|
767
|
+
termsFr: ["web-page-s", "flashes", "general-flash-and-red-flash-thresholds"],
|
|
768
|
+
terms: ["web-page", "flash", "general-flash-and-red-flash-thresholds"]
|
|
660
769
|
},
|
|
661
770
|
{
|
|
662
771
|
sc: "2.4.1",
|
|
@@ -669,7 +778,11 @@ var wcag_default = {
|
|
|
669
778
|
automatability: "judgment",
|
|
670
779
|
ruleIds: ["skip-link-target-missing"],
|
|
671
780
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/bypass-blocks.html",
|
|
672
|
-
techniques: ["ARIA11", "ARIA12", "ARIA4", "F15", "F66", "G1", "G10", "G115", "G123", "G124", "G130", "G135", "G141", "G59", "H42", "H69", "SCR28"]
|
|
781
|
+
techniques: ["ARIA11", "ARIA12", "ARIA4", "F15", "F66", "G1", "G10", "G115", "G123", "G124", "G130", "G135", "G141", "G59", "H42", "H69", "SCR28"],
|
|
782
|
+
text: "A mechanism is available to bypass blocks of content that are repeated on multiple web pages.",
|
|
783
|
+
textFr: "Un m\xE9canisme permet de contourner les blocs de contenu qui sont r\xE9p\xE9t\xE9s sur plusieurs pages Web.",
|
|
784
|
+
termsFr: ["mechanism", "web-page-s"],
|
|
785
|
+
terms: ["mechanism", "web-page"]
|
|
673
786
|
},
|
|
674
787
|
{
|
|
675
788
|
sc: "2.4.2",
|
|
@@ -682,7 +795,11 @@ var wcag_default = {
|
|
|
682
795
|
automatability: "static",
|
|
683
796
|
ruleIds: ["title-missing-empty"],
|
|
684
797
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/page-titled.html",
|
|
685
|
-
techniques: ["G127", "G88", "H25"]
|
|
798
|
+
techniques: ["G127", "G88", "H25"],
|
|
799
|
+
text: "Web pages have titles that describe topic or purpose.",
|
|
800
|
+
textFr: "Les pages Web pr\xE9sentent un titre qui d\xE9crit leur sujet ou leur but.",
|
|
801
|
+
termsFr: ["web-page-s"],
|
|
802
|
+
terms: ["web-page"]
|
|
686
803
|
},
|
|
687
804
|
{
|
|
688
805
|
sc: "2.4.3",
|
|
@@ -695,7 +812,11 @@ var wcag_default = {
|
|
|
695
812
|
automatability: "judgment",
|
|
696
813
|
ruleIds: ["positive-tabindex"],
|
|
697
814
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html",
|
|
698
|
-
techniques: ["C27", "F1", "F15", "F44", "F66", "F85", "G1", "G10", "G123", "G124", "G135", "G140", "G59", "H4", "SCR26", "SCR27", "SCR28", "SCR37"]
|
|
815
|
+
techniques: ["C27", "F1", "F15", "F44", "F66", "F85", "G1", "G10", "G123", "G124", "G135", "G140", "G59", "H4", "SCR26", "SCR27", "SCR28", "SCR37"],
|
|
816
|
+
text: "If a web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability.",
|
|
817
|
+
textFr: "Si une page Web peut \xEAtre parcourue de fa\xE7on s\xE9quentielle et que les s\xE9quences de navigation affectent la signification ou l\u2019action, les \xE9l\xE9ments re\xE7oivent le focus dans un ordre qui pr\xE9serve la signification et l\u2019op\xE9rabilit\xE9.",
|
|
818
|
+
termsFr: ["web-page-s", "navigated-sequentially"],
|
|
819
|
+
terms: ["web-page", "navigated-sequentially"]
|
|
699
820
|
},
|
|
700
821
|
{
|
|
701
822
|
sc: "2.4.4",
|
|
@@ -708,7 +829,11 @@ var wcag_default = {
|
|
|
708
829
|
automatability: "judgment",
|
|
709
830
|
ruleIds: ["link-empty-name", "icon-only-control-unnamed"],
|
|
710
831
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html",
|
|
711
|
-
techniques: ["ARIA7", "ARIA8", "F63", "F89", "G53", "G91", "H30", "H78", "H79", "H80", "H81"]
|
|
832
|
+
techniques: ["ARIA7", "ARIA8", "F63", "F89", "G53", "G91", "H30", "H78", "H79", "H80", "H81"],
|
|
833
|
+
text: "The purpose of each link can be determined from the link text alone or from the link text together with its programmatically determined link context, except where the purpose of the link would be ambiguous to users in general.",
|
|
834
|
+
textFr: "La fonction de chaque lien est d\xE9termin\xE9e par le texte du lien seul ou par le texte du lien associ\xE9 \xE0 un contexte du lien d\xE9termin\xE9 par un programme informatique, sauf si la fonction du lien est ambigu\xEB pour tout utilisateur.",
|
|
835
|
+
termsFr: ["purpose-of-each-link", "programmatically-determined-link-context", "ambiguous-to-users-in-general"],
|
|
836
|
+
terms: ["link-purpose", "programmatically-determined-link-context", "ambiguous-to-users-in-general"]
|
|
712
837
|
},
|
|
713
838
|
{
|
|
714
839
|
sc: "2.4.5",
|
|
@@ -721,7 +846,11 @@ var wcag_default = {
|
|
|
721
846
|
automatability: "judgment",
|
|
722
847
|
ruleIds: [],
|
|
723
848
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/multiple-ways.html",
|
|
724
|
-
techniques: ["G161", "G61", "G63", "G64"]
|
|
849
|
+
techniques: ["G161", "G61", "G63", "G64"],
|
|
850
|
+
text: "More than one way is available to locate a web page within a set of web pages except where the web page is the result of, or a step in, a process.",
|
|
851
|
+
textFr: "Une page Web peut \xEAtre situ\xE9e par plus d\u2019un moyen dans un ensemble de pages Web sauf si cette page est le r\xE9sultat ou une \xE9tape d\u2019un processus.",
|
|
852
|
+
termsFr: ["web-page-s", "set-of-web-pages", "processes"],
|
|
853
|
+
terms: ["web-page", "set-of-web-pages", "process"]
|
|
725
854
|
},
|
|
726
855
|
{
|
|
727
856
|
sc: "2.4.6",
|
|
@@ -734,7 +863,11 @@ var wcag_default = {
|
|
|
734
863
|
automatability: "judgment",
|
|
735
864
|
ruleIds: [],
|
|
736
865
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/headings-and-labels.html",
|
|
737
|
-
techniques: ["ARIA12", "ARIA14", "ARIA16", "ARIA4", "ARIA6", "ARIA9", "F68", "F82", "F86", "G115", "G130", "G131", "G141", "G82", "H42", "H44", "H65"]
|
|
866
|
+
techniques: ["ARIA12", "ARIA14", "ARIA16", "ARIA4", "ARIA6", "ARIA9", "F68", "F82", "F86", "G115", "G130", "G131", "G141", "G82", "H42", "H44", "H65"],
|
|
867
|
+
text: "Headings and labels describe topic or purpose.",
|
|
868
|
+
textFr: "Les en-t\xEAtes et les \xE9tiquettes d\xE9crivent le sujet ou le but.",
|
|
869
|
+
termsFr: ["labels"],
|
|
870
|
+
terms: ["label"]
|
|
738
871
|
},
|
|
739
872
|
{
|
|
740
873
|
sc: "2.4.7",
|
|
@@ -747,7 +880,10 @@ var wcag_default = {
|
|
|
747
880
|
automatability: "needs-rendering",
|
|
748
881
|
ruleIds: ["rendered-focus-not-visible"],
|
|
749
882
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html",
|
|
750
|
-
techniques: ["C15", "F42", "F54", "F55", "F73", "F78", "G149", "G165", "G183", "G195", "G202", "G90", "SCR2", "SCR20", "SCR29", "SCR31", "SCR35"]
|
|
883
|
+
techniques: ["C15", "F42", "F54", "F55", "F73", "F78", "G149", "G165", "G183", "G195", "G202", "G90", "SCR2", "SCR20", "SCR29", "SCR31", "SCR35"],
|
|
884
|
+
text: "Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.",
|
|
885
|
+
textFr: "Toute interface utilisable au clavier comporte un mode de fonctionnement o\xF9 le focus est visible.",
|
|
886
|
+
terms: ["focus-indicator"]
|
|
751
887
|
},
|
|
752
888
|
{
|
|
753
889
|
sc: "2.4.11",
|
|
@@ -759,7 +895,11 @@ var wcag_default = {
|
|
|
759
895
|
addedIn: "2.2",
|
|
760
896
|
automatability: "needs-rendering",
|
|
761
897
|
ruleIds: [],
|
|
762
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html"
|
|
898
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html",
|
|
899
|
+
text: "When a user interface component receives keyboard focus, the component is not entirely hidden due to author-created content.\nNote: Where content in a configurable interface can be repositioned by the user, then only the initial positions of user-movable content are considered for testing and conformance of this success criterion.\nNote: Content opened by the user may obscure the component receiving focus. If the user can reveal the focused component without advancing the keyboard focus, the component with focus is not considered visually hidden due to author-created content.",
|
|
900
|
+
textFr: "Lorsqu\u2019un composant d\u2019interface utilisateur re\xE7oit le focus du clavier, ce composant n\u2019est pas enti\xE8rement masqu\xE9 par du contenu cr\xE9\xE9 par l\u2019auteur.\nNote : Lorsqu\u2019un contenu d\u2019une interface configurable peut \xEAtre repositionn\xE9 par l\u2019utilisateur, alors seules les positions initiales du contenu d\xE9pla\xE7able sont prises en compte pour les tests et la conformit\xE9 \xE0 ce crit\xE8re de succ\xE8s.\nNote : Il arrive que du contenu ouvert par l\u2019utilisateur masque le composant qui re\xE7oit le focus. Si l\u2019utilisateur peut r\xE9v\xE9ler le composant ayant le focus sans d\xE9placer le focus du clavier, alors le composant ayant le focus n\u2019est pas consid\xE9r\xE9 comme masqu\xE9 par du contenu cr\xE9\xE9 par l\u2019auteur.",
|
|
901
|
+
termsFr: ["user-interface-components"],
|
|
902
|
+
terms: ["user-interface-component"]
|
|
763
903
|
},
|
|
764
904
|
{
|
|
765
905
|
sc: "2.5.1",
|
|
@@ -772,7 +912,11 @@ var wcag_default = {
|
|
|
772
912
|
automatability: "judgment",
|
|
773
913
|
ruleIds: [],
|
|
774
914
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/pointer-gestures.html",
|
|
775
|
-
techniques: ["G215", "G216"]
|
|
915
|
+
techniques: ["G215", "G216"],
|
|
916
|
+
text: "All functionality that uses multipoint or path-based gestures for operation can be operated with a single pointer without a path-based gesture, unless a multipoint or path-based gesture is essential.\nNote: This requirement applies to web content that interprets pointer actions (i.e., this does not apply to actions that are required to operate the user agent or assistive technology).",
|
|
917
|
+
textFr: "Toutes les fonctionnalit\xE9s qui utilisent des gestes multipoints ou bas\xE9s sur un trac\xE9 peuvent \xEAtre utilis\xE9es avec un pointage \xE0 contact unique sans geste bas\xE9 sur un trac\xE9, \xE0 moins qu\u2019un geste multipoint ou bas\xE9 sur un trac\xE9 ne soit essentiel.\nNote : Cette exigence s\u2019applique aux contenus Web qui interpr\xE8tent les actions du pointeur (elle ne s\u2019applique donc pas aux actions n\xE9cessaires \xE0 l\u2019utilisation d\u2019un agent utilisateur ou d\u2019une technologie d\u2019assistance).",
|
|
918
|
+
termsFr: ["functionality", "single-pointer", "essential"],
|
|
919
|
+
terms: ["functionality", "single-pointer", "essential"]
|
|
776
920
|
},
|
|
777
921
|
{
|
|
778
922
|
sc: "2.5.2",
|
|
@@ -784,7 +928,11 @@ var wcag_default = {
|
|
|
784
928
|
addedIn: "2.1",
|
|
785
929
|
automatability: "judgment",
|
|
786
930
|
ruleIds: [],
|
|
787
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/pointer-cancellation.html"
|
|
931
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/pointer-cancellation.html",
|
|
932
|
+
text: "For functionality that can be operated using a single pointer, at least one of the following is true:\nNo Down-Event: The down-event of the pointer is not used to execute any part of the function;\nAbort or Undo: Completion of the function is on the up-event, and a mechanism is available to abort the function before completion or to undo the function after completion;\nUp Reversal: The up-event reverses any outcome of the preceding down-event;\nEssential: Completing the function on the down-event is essential.\nNote: Functions that emulate a keyboard or numeric keypad key press are considered essential.\nNote: This requirement applies to web content that interprets pointer actions (i.e., this does not apply to actions that are required to operate the user agent or assistive technology).",
|
|
933
|
+
textFr: "Pour une fonctionnalit\xE9 qui peut \xEAtre activ\xE9e avec un dispositif de pointage \xE0 contact unique, au moins une des conditions suivantes est vraie :\nAucun \xE9v\xE9nement descendant: l\u2019\xE9v\xE9nement descendant (down-event) du pointeur n\u2019est pas utilis\xE9 pour ex\xE9cuter une partie ou la totalit\xE9 de la fonction ;\nAbandon ou annulation: l\u2019ach\xE8vement de la fonction se fait sur l\u2019\xE9v\xE9nement ascendant (up-event), et un m\xE9canisme est disponible pour interrompre la fonction avant l\u2019ach\xE8vement ou pour annuler la fonction apr\xE8s l\u2019ach\xE8vement ;\nInversion sur l\u2019\xE9v\xE9nement ascendant: l\u2019\xE9v\xE9nement ascendant inverse tout r\xE9sultat de l\u2019\xE9v\xE9nement descendant pr\xE9c\xE9dent ;\nEssentiel: l\u2019ach\xE8vement de la fonction lors de l\u2019\xE9v\xE9nement descendant est essentiel.\nNote : Les fonctions qui \xE9mulent l\u2019appui d\u2019une touche du clavier ou du pav\xE9 num\xE9rique sont consid\xE9r\xE9es comme essentielles.\nNote : Cette exigence s\u2019applique aux contenus Web qui interpr\xE8tent les actions du pointeur (elle ne s\u2019applique donc pas aux actions n\xE9cessaires \xE0 l\u2019utilisation d\u2019un agent utilisateur ou d\u2019une technologie d\u2019assistance).",
|
|
934
|
+
termsFr: ["functionality", "single-pointer", "down-event", "up-event", "mechanism", "essential"],
|
|
935
|
+
terms: ["functionality", "single-pointer", "down-event", "up-event", "mechanism", "essential"]
|
|
788
936
|
},
|
|
789
937
|
{
|
|
790
938
|
sc: "2.5.3",
|
|
@@ -833,7 +981,11 @@ var wcag_default = {
|
|
|
833
981
|
"H81",
|
|
834
982
|
"H91",
|
|
835
983
|
"SCR21"
|
|
836
|
-
]
|
|
984
|
+
],
|
|
985
|
+
text: "For user interface components with labels that include text or images of text, the name contains the text that is presented visually.\nNote: A best practice is to have the text of the label at the start of the name.",
|
|
986
|
+
textFr: "Pour les composants d\u2019interface utilisateur dont les \xE9tiquettes contiennent du texte ou du texte sous forme d\u2019image, le nom contient le texte qui est pr\xE9sent\xE9 visuellement.\nNote : Une bonne pratique consiste \xE0 placer le texte de l\u2019\xE9tiquette au d\xE9but du nom.",
|
|
987
|
+
termsFr: ["user-interface-components", "labels", "text", "images-of-text", "name"],
|
|
988
|
+
terms: ["user-interface-component", "label", "text", "image-of-text", "name"]
|
|
837
989
|
},
|
|
838
990
|
{
|
|
839
991
|
sc: "2.5.4",
|
|
@@ -845,7 +997,11 @@ var wcag_default = {
|
|
|
845
997
|
addedIn: "2.1",
|
|
846
998
|
automatability: "judgment",
|
|
847
999
|
ruleIds: [],
|
|
848
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/motion-actuation.html"
|
|
1000
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/motion-actuation.html",
|
|
1001
|
+
text: "Functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when:\nSupported Interface: The motion is used to operate functionality through an accessibility supported interface;\nEssential: The motion is essential for the function and doing so would invalidate the activity.",
|
|
1002
|
+
textFr: "Les fonctionnalit\xE9s qui peuvent \xEAtre activ\xE9es par un mouvement de l\u2019appareil ou un mouvement de l\u2019utilisateur peuvent \xE9galement \xEAtre activ\xE9es par des composants d\u2019interface utilisateur et la r\xE9ponse au mouvement peut \xEAtre d\xE9sactiv\xE9e pour \xE9viter une activation accidentelle, sauf dans les cas suivants :\nInterface compatible : le mouvement est utilis\xE9 pour activer la fonctionnalit\xE9 par l\u2019interm\xE9diaire d\u2019une interface compatible avec l\u2019accessibilit\xE9 ;\nEssentiel : le mouvement est essentiel \xE0 la fonction et le d\xE9sactiver invaliderait l\u2019activit\xE9.",
|
|
1003
|
+
termsFr: ["functionality", "user-interface-components", "accessibility-supported", "essential"],
|
|
1004
|
+
terms: ["functionality", "user-interface-component", "accessibility-supported", "essential"]
|
|
849
1005
|
},
|
|
850
1006
|
{
|
|
851
1007
|
sc: "2.5.7",
|
|
@@ -857,7 +1013,11 @@ var wcag_default = {
|
|
|
857
1013
|
addedIn: "2.2",
|
|
858
1014
|
automatability: "judgment",
|
|
859
1015
|
ruleIds: [],
|
|
860
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html"
|
|
1016
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html",
|
|
1017
|
+
text: "All functionality that uses a dragging movement for operation can be achieved by a single pointer without dragging, unless dragging is essential or the functionality is determined by the user agent and not modified by the author.\nNote: This requirement applies to web content that interprets pointer actions (i.e., this does not apply to actions that are required to operate the user agent or assistive technology).",
|
|
1018
|
+
textFr: "Toutes les fonctionnalit\xE9s qui utilisent un mouvement de glissement peuvent \xEAtre r\xE9alis\xE9es par un pointage \xE0 contact unique sans glissement, sauf si le glissement est essentiel ou que la fonctionnalit\xE9 est d\xE9termin\xE9e par l\u2019agent utilisateur et non modifi\xE9e par l\u2019auteur.\nNote : Cette exigence s\u2019applique aux contenus Web qui interpr\xE8tent les actions du pointeur (c\u2019est-\xE0-dire qu\u2019elle ne s\u2019applique pas aux actions n\xE9cessaires pour faire fonctionner l\u2019agent utilisateur ou la technologie d\u2019assistance).",
|
|
1019
|
+
termsFr: ["functionality", "dragging-movements", "single-pointer", "essential", "user-agents"],
|
|
1020
|
+
terms: ["functionality", "dragging-movement", "single-pointer", "essential", "user-agent"]
|
|
861
1021
|
},
|
|
862
1022
|
{
|
|
863
1023
|
sc: "2.5.8",
|
|
@@ -869,7 +1029,11 @@ var wcag_default = {
|
|
|
869
1029
|
addedIn: "2.2",
|
|
870
1030
|
automatability: "needs-rendering",
|
|
871
1031
|
ruleIds: [],
|
|
872
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html"
|
|
1032
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html",
|
|
1033
|
+
text: "The size of the target for pointer inputs is at least 24 by 24 CSS pixels, except when:\nSpacing: Undersized targets (those less than 24 by 24 CSS pixels) are positioned so that if a 24 CSS pixel diameter circle is centered on the bounding box of each, the circles do not intersect another target or the circle for another undersized target;\nEquivalent: The function can be achieved through a different control on the same page that meets this criterion;\nInline: The target is in a sentence or its size is otherwise constrained by the line-height of non-target text;\nUser Agent Control: The size of the target is determined by the user agent and is not modified by the author;\nEssential: A particular presentation of the target is essential or is legally required for the information being conveyed.\nNote: Targets that allow for values to be selected spatially based on position within the target are considered one target for the purpose of the success criterion. Examples include sliders, color pickers displaying a gradient of colors, or editable areas where you position the cursor.\nNote: For inline targets the line-height should be interpreted as perpendicular to the flow of text. For example, in a language displayed vertically, the line-height would be horizontal.",
|
|
1034
|
+
textFr: "La taille de la cible pour les entr\xE9es de pointeur est d\u2019au moins 24 par 24 pixels CSS, sauf dans les cas suivants :\n\u2022 Espacement : les cibles de taille r\xE9duite (de moins de 24 par 24 pixels CSS) sont positionn\xE9es de telle sorte que si un cercle de 24 pixels CSS de diam\xE8tre est centr\xE9 sur la bo\xEEte de d\xE9limitation de chacune d\u2019elles, les cercles ne croisent pas d\u2019autre cible ni le cercle d\u2019une autre cible de taille r\xE9duite ;\n\u2022 \xC9quivalence : la fonction peut \xEAtre r\xE9alis\xE9e gr\xE2ce \xE0 un \xE9l\xE9ment de contr\xF4le diff\xE9rent sur la m\xEAme page, et qui satisfait \xE0 ce crit\xE8re ;\n\u2022 En ligne : la cible se trouve dans une phrase, ou bien sa taille est limit\xE9e par la hauteur de ligne du texte non cibl\xE9 ;\n\u2022 Contr\xF4le par l\u2019agent utilisateur : la taille de la cible est d\xE9termin\xE9e par l\u2019agent utilisateur et n\u2019est pas modifi\xE9e par l\u2019auteur ;\n\u2022 Essentiel : une pr\xE9sentation sp\xE9cifique de la cible est essentielle ou est l\xE9galement requise pour transmettre l\u2019information.\nNote : Pour ce crit\xE8re de succ\xE8s, les cibles qui permettent de s\xE9lectionner des valeurs en fonction de leur position dans la cible sont consid\xE9r\xE9es comme une seule cible. Cela inclut par exemple les curseurs (slider), les s\xE9lecteurs de couleurs affichant un d\xE9grad\xE9 de couleurs, ou les zones \xE9ditables o\xF9 l\u2019on positionne le curseur.\nNote : Pour les cibles en ligne, la hauteur de ligne doit \xEAtre interpr\xE9t\xE9e comme \xE9tant perpendiculaire au flux de texte. Par exemple, dans une langue affich\xE9e verticalement, la hauteur de ligne serait horizontale.",
|
|
1035
|
+
termsFr: ["targets", "pointer-inputs", "css-pixels", "bounding-boxes", "user-agents", "presentation", "essential"],
|
|
1036
|
+
terms: ["target", "pointer-input", "css-pixel", "minimum-bounding-box", "user-agent", "presentation", "essential"]
|
|
873
1037
|
},
|
|
874
1038
|
{
|
|
875
1039
|
sc: "3.1.1",
|
|
@@ -882,7 +1046,11 @@ var wcag_default = {
|
|
|
882
1046
|
automatability: "static",
|
|
883
1047
|
ruleIds: ["html-lang-missing", "lang-invalid"],
|
|
884
1048
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/language-of-page.html",
|
|
885
|
-
techniques: ["F15", "G10", "G135", "H57"]
|
|
1049
|
+
techniques: ["F15", "G10", "G135", "H57"],
|
|
1050
|
+
text: "The default human language of each web page can be programmatically determined.",
|
|
1051
|
+
textFr: "La langue par d\xE9faut de chaque page Web peut \xEAtre d\xE9termin\xE9e par un programme informatique.",
|
|
1052
|
+
termsFr: ["human-language-s", "web-page-s", "programmatically-determinable"],
|
|
1053
|
+
terms: ["human-language", "web-page", "programmatically-determined"]
|
|
886
1054
|
},
|
|
887
1055
|
{
|
|
888
1056
|
sc: "3.1.2",
|
|
@@ -895,7 +1063,11 @@ var wcag_default = {
|
|
|
895
1063
|
automatability: "judgment",
|
|
896
1064
|
ruleIds: ["inline-lang-change-missing", "lang-invalid"],
|
|
897
1065
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/language-of-parts.html",
|
|
898
|
-
techniques: ["H58"]
|
|
1066
|
+
techniques: ["H58"],
|
|
1067
|
+
text: "The human language of each passage or phrase in the content can be programmatically determined except for proper names, technical terms, words of indeterminate language, and words or phrases that have become part of the vernacular of the immediately surrounding text.",
|
|
1068
|
+
textFr: "La langue de chaque passage ou expression du contenu peut \xEAtre d\xE9termin\xE9e par un programme informatique sauf pour un nom propre, pour un terme technique, pour un mot dont la langue est ind\xE9termin\xE9e ou pour un mot ou une expression faisant partie du langage courant de la langue utilis\xE9e dans le contexte imm\xE9diat.",
|
|
1069
|
+
termsFr: ["human-language-s", "programmatically-determinable"],
|
|
1070
|
+
terms: ["human-language", "programmatically-determined", "text"]
|
|
899
1071
|
},
|
|
900
1072
|
{
|
|
901
1073
|
sc: "3.2.1",
|
|
@@ -908,7 +1080,11 @@ var wcag_default = {
|
|
|
908
1080
|
automatability: "judgment",
|
|
909
1081
|
ruleIds: [],
|
|
910
1082
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/on-focus.html",
|
|
911
|
-
techniques: ["F22", "F36", "F37", "F41", "F55", "F9", "G107", "G13", "G76", "G80", "H32", "H84", "SCR19"]
|
|
1083
|
+
techniques: ["F22", "F36", "F37", "F41", "F55", "F9", "G107", "G13", "G76", "G80", "H32", "H84", "SCR19"],
|
|
1084
|
+
text: "When any user interface component receives focus, it does not initiate a change of context.",
|
|
1085
|
+
textFr: "Quand un composant d\u2019interface utilisateur re\xE7oit le focus, il ne doit pas initier de changement de contexte.",
|
|
1086
|
+
termsFr: ["user-interface-components", "change-of-context"],
|
|
1087
|
+
terms: ["user-interface-component", "changes-of-context"]
|
|
912
1088
|
},
|
|
913
1089
|
{
|
|
914
1090
|
sc: "3.2.2",
|
|
@@ -921,7 +1097,11 @@ var wcag_default = {
|
|
|
921
1097
|
automatability: "judgment",
|
|
922
1098
|
ruleIds: ["on-input-context-change"],
|
|
923
1099
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/on-input.html",
|
|
924
|
-
techniques: ["F22", "F36", "F37", "F41", "F9", "G107", "G13", "G76", "G80", "H32", "H84", "SCR19"]
|
|
1100
|
+
techniques: ["F22", "F36", "F37", "F41", "F9", "G107", "G13", "G76", "G80", "H32", "H84", "SCR19"],
|
|
1101
|
+
text: "Changing the setting of any user interface component does not automatically cause a change of context unless the user has been advised of the behavior before using the component.",
|
|
1102
|
+
textFr: "Le changement de param\xE8tre d\u2019un composant d\u2019interface utilisateur ne doit pas initier de changement de contexte \xE0 moins que l\u2019utilisateur n\u2019ait \xE9t\xE9 avis\xE9 de ce comportement avant d\u2019utiliser le composant.",
|
|
1103
|
+
termsFr: ["user-interface-components", "change-of-context"],
|
|
1104
|
+
terms: ["user-interface-component", "changes-of-context"]
|
|
925
1105
|
},
|
|
926
1106
|
{
|
|
927
1107
|
sc: "3.2.3",
|
|
@@ -934,7 +1114,11 @@ var wcag_default = {
|
|
|
934
1114
|
automatability: "judgment",
|
|
935
1115
|
ruleIds: [],
|
|
936
1116
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/consistent-navigation.html",
|
|
937
|
-
techniques: ["F66", "G1", "G123", "G124", "G59", "G61", "G63", "SCR28"]
|
|
1117
|
+
techniques: ["F66", "G1", "G123", "G124", "G59", "G61", "G63", "SCR28"],
|
|
1118
|
+
text: "Navigational mechanisms that are repeated on multiple web pages within a set of web pages occur in the same relative order each time they are repeated, unless a change is initiated by the user.",
|
|
1119
|
+
textFr: "Dans un ensemble de pages, les m\xE9canismes de navigation qui se r\xE9p\xE8tent sur plusieurs pages Web se pr\xE9sentent dans le m\xEAme ordre relatif chaque fois qu\u2019ils sont r\xE9p\xE9t\xE9s, \xE0 moins qu\u2019un changement soit initi\xE9 par l\u2019utilisateur.",
|
|
1120
|
+
termsFr: ["set-of-web-pages", "web-page-s", "same-relative-order"],
|
|
1121
|
+
terms: ["web-page", "set-of-web-pages", "same-relative-order"]
|
|
938
1122
|
},
|
|
939
1123
|
{
|
|
940
1124
|
sc: "3.2.4",
|
|
@@ -947,7 +1131,11 @@ var wcag_default = {
|
|
|
947
1131
|
automatability: "judgment",
|
|
948
1132
|
ruleIds: [],
|
|
949
1133
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/consistent-identification.html",
|
|
950
|
-
techniques: ["F31"]
|
|
1134
|
+
techniques: ["F31"],
|
|
1135
|
+
text: "Components that have the same functionality within a set of web pages are identified consistently.",
|
|
1136
|
+
textFr: "Dans un ensemble de pages les composants qui ont la m\xEAme fonctionnalit\xE9 sont identifi\xE9s de la m\xEAme fa\xE7on.",
|
|
1137
|
+
termsFr: ["set-of-web-pages", "same-functionality"],
|
|
1138
|
+
terms: ["same-functionality", "set-of-web-pages"]
|
|
951
1139
|
},
|
|
952
1140
|
{
|
|
953
1141
|
sc: "3.2.6",
|
|
@@ -959,7 +1147,17 @@ var wcag_default = {
|
|
|
959
1147
|
addedIn: "2.2",
|
|
960
1148
|
automatability: "judgment",
|
|
961
1149
|
ruleIds: [],
|
|
962
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/consistent-help.html"
|
|
1150
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/consistent-help.html",
|
|
1151
|
+
text: `If a web page contains any of the following help mechanisms, and those mechanisms are repeated on multiple web pages within a set of web pages, they occur in the same order relative to other page content, unless a change is initiated by the user:
|
|
1152
|
+
\u2022 Human contact details;
|
|
1153
|
+
\u2022 Human contact mechanism;
|
|
1154
|
+
\u2022 Self-help option;
|
|
1155
|
+
\u2022 A fully automated contact mechanism.
|
|
1156
|
+
Note: Help mechanisms may be provided directly on the page, or may be provided via a direct link to a different page containing the information.
|
|
1157
|
+
Note: For this success criterion, "the same order relative to other page content" can be thought of as how the content is ordered when the page is serialized. The visual position of a help mechanism is likely to be consistent across pages for the same page variation (e.g., CSS breakpoint). The user can initiate a change, such as changing the page's zoom or orientation, which may trigger a different page variation. This criterion is concerned with relative order across pages displayed in the same page variation (e.g., same zoom level and orientation).`,
|
|
1158
|
+
textFr: "Si une page Web contient l\u2019un des m\xE9canismes d\u2019aide suivants et que ces m\xE9canismes sont r\xE9p\xE9t\xE9s sur plusieurs pages d\u2019un ensemble de pages, alors ils se pr\xE9sentent dans le m\xEAme ordre relativement aux autres contenus de la page ; \xE0 moins qu\u2019un changement soit initi\xE9 par l\u2019utilisateur :\n\u2022 des coordonn\xE9es de personnes ;\n\u2022 un m\xE9canisme pour contacter une personne ;\n\u2022 une option d\u2019auto-assistance ;\n\u2022 un m\xE9canisme de contact enti\xE8rement automatis\xE9.\nNote : Les m\xE9canismes d\u2019aide peuvent \xEAtre fournis directement sur la page, ou \xEAtre fournis gr\xE2ce \xE0 un lien direct vers une page distincte contenant les informations.\nNote : Pour ce crit\xE8re de succ\xE8s, \xAB le m\xEAme ordre relativement aux autres contenus de la page \xBB peut \xEAtre consid\xE9r\xE9 comme la mani\xE8re dont le contenu est ordonn\xE9 lorsque la page est lin\xE9aris\xE9e. La position visuelle d\u2019un m\xE9canisme d\u2019aide sera probablement coh\xE9rente d\u2019une page \xE0 l\u2019autre pour la m\xEAme variante de page (par exemple, un point de rupture CSS). L\u2019utilisateur peut initier un changement, comme modifier le zoom de la page ou son orientation, ce qui peut d\xE9clencher l\u2019affichage d\u2019une variante diff\xE9rente de la page. Ce crit\xE8re s\u2019int\xE9resse \xE0 l\u2019ordre relatif dans des pages affich\xE9es avec la m\xEAme variante de page (par exemple, le m\xEAme niveau de zoom et la m\xEAme orientation).",
|
|
1159
|
+
termsFr: ["web-page-s", "mechanism", "set-of-web-pages"],
|
|
1160
|
+
terms: ["web-page", "mechanism", "set-of-web-pages"]
|
|
963
1161
|
},
|
|
964
1162
|
{
|
|
965
1163
|
sc: "3.3.1",
|
|
@@ -991,7 +1189,11 @@ var wcag_default = {
|
|
|
991
1189
|
"H90",
|
|
992
1190
|
"SCR18",
|
|
993
1191
|
"SCR32"
|
|
994
|
-
]
|
|
1192
|
+
],
|
|
1193
|
+
text: "If an input error is automatically detected, the item that is in error is identified and the error is described to the user in text.",
|
|
1194
|
+
textFr: "Si une erreur de saisie est d\xE9tect\xE9e automatiquement, l\u2019\xE9l\xE9ment en erreur est identifi\xE9 et l\u2019erreur est d\xE9crite \xE0 l\u2019utilisateur sous forme de texte.",
|
|
1195
|
+
termsFr: ["input-error"],
|
|
1196
|
+
terms: ["input-error"]
|
|
995
1197
|
},
|
|
996
1198
|
{
|
|
997
1199
|
sc: "3.3.2",
|
|
@@ -1033,7 +1235,11 @@ var wcag_default = {
|
|
|
1033
1235
|
"H90",
|
|
1034
1236
|
"SCR18",
|
|
1035
1237
|
"SCR32"
|
|
1036
|
-
]
|
|
1238
|
+
],
|
|
1239
|
+
text: "Labels or instructions are provided when content requires user input.",
|
|
1240
|
+
textFr: "Des \xE9tiquettes sont pr\xE9sent\xE9es ou des instructions sont fournies quand un contenu requiert une saisie utilisateur.",
|
|
1241
|
+
termsFr: ["labels"],
|
|
1242
|
+
terms: ["label"]
|
|
1037
1243
|
},
|
|
1038
1244
|
{
|
|
1039
1245
|
sc: "3.3.3",
|
|
@@ -1046,7 +1252,11 @@ var wcag_default = {
|
|
|
1046
1252
|
automatability: "judgment",
|
|
1047
1253
|
ruleIds: [],
|
|
1048
1254
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/error-suggestion.html",
|
|
1049
|
-
techniques: ["G177", "G84", "G85", "G89", "H89"]
|
|
1255
|
+
techniques: ["G177", "G84", "G85", "G89", "H89"],
|
|
1256
|
+
text: "If an input error is automatically detected and suggestions for correction are known, then the suggestions are provided to the user, unless it would jeopardize the security or purpose of the content.",
|
|
1257
|
+
textFr: "Si une erreur de saisie est automatiquement d\xE9tect\xE9e et que des suggestions de corrections sont connues, ces suggestions sont alors propos\xE9es \xE0 l\u2019utilisateur \xE0 moins que cela puisse compromettre la s\xE9curit\xE9 ou la finalit\xE9 du contenu.",
|
|
1258
|
+
termsFr: ["input-error"],
|
|
1259
|
+
terms: ["input-error"]
|
|
1050
1260
|
},
|
|
1051
1261
|
{
|
|
1052
1262
|
sc: "3.3.4",
|
|
@@ -1059,7 +1269,11 @@ var wcag_default = {
|
|
|
1059
1269
|
automatability: "judgment",
|
|
1060
1270
|
ruleIds: [],
|
|
1061
1271
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/error-prevention-legal-financial-data.html",
|
|
1062
|
-
techniques: ["G155", "G164", "G168", "G98", "G99"]
|
|
1272
|
+
techniques: ["G155", "G164", "G168", "G98", "G99"],
|
|
1273
|
+
text: "For web pages that cause legal commitments or financial transactions for the user to occur, that modify or delete user-controllable data in data storage systems, or that submit user test responses, at least one of the following is true:\nReversible: Submissions are reversible.\nChecked: Data entered by the user is checked for input errors and the user is provided an opportunity to correct them.\nConfirmed: A mechanism is available for reviewing, confirming, and correcting information before finalizing the submission.",
|
|
1274
|
+
textFr: "Pour les pages Web qui entra\xEEnent des engagements juridiques ou des transactions financi\xE8res de la part de l\u2019utilisateur, qui modifient ou effacent des donn\xE9es contr\xF4lables par l\u2019utilisateur dans des syst\xE8mes de stockages de donn\xE9es, qui enregistrent les r\xE9ponses de l\u2019utilisateur \xE0 un test ou un examen, au moins l\u2019une des conditions suivantes est vraie :\nR\xE9versible: les actions d\u2019envoi sont r\xE9versibles.\nV\xE9rifi\xE9e: les donn\xE9es saisies par l\u2019utilisateur sont v\xE9rifi\xE9es au niveau des erreurs de saisie et la possibilit\xE9 est donn\xE9e \xE0 l\u2019utilisateur de les corriger.\nConfirm\xE9e: un m\xE9canisme est disponible pour revoir, confirmer et corriger les informations avant leur soumission finale.",
|
|
1275
|
+
termsFr: ["web-page-s", "legal-commitments", "user-controllable"],
|
|
1276
|
+
terms: ["web-page", "legal-commitments", "user-controllable", "input-error", "mechanism"]
|
|
1063
1277
|
},
|
|
1064
1278
|
{
|
|
1065
1279
|
sc: "3.3.7",
|
|
@@ -1071,7 +1285,11 @@ var wcag_default = {
|
|
|
1071
1285
|
addedIn: "2.2",
|
|
1072
1286
|
automatability: "judgment",
|
|
1073
1287
|
ruleIds: [],
|
|
1074
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry.html"
|
|
1288
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry.html",
|
|
1289
|
+
text: "Information previously entered by or provided to the user that is required to be entered again in the same process is either:\n\u2022 auto-populated, or\n\u2022 available for the user to select.\nExcept when:\n\u2022 re-entering the information is essential,\n\u2022 the information is required to ensure the security of the content, or\n\u2022 previously entered information is no longer valid.",
|
|
1290
|
+
textFr: "Les informations pr\xE9c\xE9demment saisies par l\u2019utilisateur ou fournies \xE0 l\u2019utilisateur, et qui doivent \xEAtre \xE0 nouveau saisies dans le m\xEAme processus sont soit :\n\u2022 pr\xE9remplies, ou\n\u2022 disponibles pour \xEAtre s\xE9lectionn\xE9es par l\u2019utilisateur.\nSauf dans les cas suivants :\n\u2022 il est essentiel de ressaisir les informations soi-m\xEAme,\n\u2022 les informations sont requises pour assurer la s\xE9curit\xE9 du contenu, ou\n\u2022 les informations pr\xE9c\xE9demment saisies ne sont plus valides.",
|
|
1291
|
+
termsFr: ["processes", "essential"],
|
|
1292
|
+
terms: ["process", "essential"]
|
|
1075
1293
|
},
|
|
1076
1294
|
{
|
|
1077
1295
|
sc: "3.3.8",
|
|
@@ -1083,7 +1301,11 @@ var wcag_default = {
|
|
|
1083
1301
|
addedIn: "2.2",
|
|
1084
1302
|
automatability: "judgment",
|
|
1085
1303
|
ruleIds: ["credential-entry-blocked"],
|
|
1086
|
-
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum.html"
|
|
1304
|
+
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum.html",
|
|
1305
|
+
text: 'A cognitive function test (such as remembering a password or solving a puzzle) is not required for any step in an authentication process unless that step provides at least one of the following:\nAlternative: Another authentication method that does not rely on a cognitive function test.\nMechanism: A mechanism is available to assist the user in completing the cognitive function test.\nObject Recognition: The cognitive function test is to recognize objects.\nPersonal Content: The cognitive function test is to identify non-text content the user provided to the website.\nNote: "Object recognition" and "Personal content" may be represented by images, video, or audio.\nExamples of mechanisms that satisfy this criterion include:\n\u2022 support for password entry by password managers to reduce memory need, and\n\u2022 copy and paste to reduce the cognitive burden of re-typing.',
|
|
1306
|
+
textFr: "Aucune \xE9tape d\u2019un processus d\u2019authentification ne requiert de test cognitif (comme la m\xE9morisation d\u2019un mot de passe ou la r\xE9solution d\u2019une \xE9nigme), \xE0 moins que cette \xE9tape ne fournisse au moins l\u2019un des \xE9l\xE9ments suivants :\nAlternative: une autre m\xE9thode d\u2019authentification, qui ne repose pas sur un test cognitif.\nM\xE9canisme: un m\xE9canisme est disponible pour aider l\u2019utilisateur \xE0 compl\xE9ter le test cognitif.\nReconnaissance d\u2019objets: le test cognitif consiste \xE0 reconna\xEEtre des objets.\nContenu personnel: le test cognitif consiste \xE0 identifier un contenu non textuel que l\u2019utilisateur a fourni au site web.\nNote : La \xAB reconnaissance d\u2019objets \xBB et le \xAB contenu personnel \xBB peuvent \xEAtre repr\xE9sent\xE9s par des images, des vid\xE9os ou de l\u2019audio.\nNote :\nDes exemples de m\xE9canismes qui satisfont \xE0 ce crit\xE8re comprennent :\n\u2022 la possibilit\xE9 de saisir un mot de passe par l\u2019interm\xE9diaire d\u2019un gestionnaire de mots de passe afin de r\xE9duire l\u2019effort de m\xE9morisation, et\n\u2022 la fonction copier-coller pour r\xE9duire la charge cognitive due \xE0 une saisie r\xE9p\xE9titive.",
|
|
1307
|
+
termsFr: ["processes", "cognitive-function-test", "mechanism", "non-text-content"],
|
|
1308
|
+
terms: ["cognitive-function-test", "process", "mechanism", "non-text-content"]
|
|
1087
1309
|
},
|
|
1088
1310
|
{
|
|
1089
1311
|
sc: "4.1.2",
|
|
@@ -1174,6 +1396,27 @@ var wcag_default = {
|
|
|
1174
1396
|
"H93",
|
|
1175
1397
|
"H94",
|
|
1176
1398
|
"SCR21"
|
|
1399
|
+
],
|
|
1400
|
+
text: "For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.\nNote: This success criterion is primarily for web authors who develop or script their own user interface components. For example, standard HTML controls already meet this success criterion when used according to specification.",
|
|
1401
|
+
textFr: "Pour tout composant d\u2019interface utilisateur (comprenant mais n\u2019\xE9tant pas limit\xE9 aux \xE9l\xE9ments de formulaire, liens et composants g\xE9n\xE9r\xE9s par des scripts), le nom et le r\xF4le peuvent \xEAtre d\xE9termin\xE9s par un programme informatique ; les \xE9tats, les propri\xE9t\xE9s et les valeurs qui peuvent \xEAtre param\xE9tr\xE9s par l\u2019utilisateur peuvent \xEAtre d\xE9finis par programmation; et la notification des changements de ces \xE9l\xE9ments est disponible aux agents utilisateurs, incluant les technologies d\u2019assistance.\nNote : Ce crit\xE8re de succ\xE8s s\u2019adresse d\u2019abord aux auteurs qui d\xE9veloppent ou programment leurs propres composants d\u2019interface utilisateur. Toutefois, les contr\xF4les HTML standards se conforment d\xE9j\xE0 \xE0 ce crit\xE8re de succ\xE8s lorsqu\u2019ils sont utilis\xE9s conform\xE9ment \xE0 la sp\xE9cification.",
|
|
1402
|
+
termsFr: [
|
|
1403
|
+
"user-interface-components",
|
|
1404
|
+
"name",
|
|
1405
|
+
"role",
|
|
1406
|
+
"programmatically-determinable",
|
|
1407
|
+
"programmatically-set",
|
|
1408
|
+
"user-agents",
|
|
1409
|
+
"assistive-technologies"
|
|
1410
|
+
],
|
|
1411
|
+
terms: [
|
|
1412
|
+
"user-interface-component",
|
|
1413
|
+
"name",
|
|
1414
|
+
"role",
|
|
1415
|
+
"programmatically-determined",
|
|
1416
|
+
"state",
|
|
1417
|
+
"programmatically-set",
|
|
1418
|
+
"user-agent",
|
|
1419
|
+
"assistive-technology"
|
|
1177
1420
|
]
|
|
1178
1421
|
},
|
|
1179
1422
|
{
|
|
@@ -1187,9 +1430,858 @@ var wcag_default = {
|
|
|
1187
1430
|
automatability: "judgment",
|
|
1188
1431
|
ruleIds: ["live-region-conflict", "status-message-not-assertive"],
|
|
1189
1432
|
understanding: "https://www.w3.org/WAI/WCAG22/Understanding/status-messages.html",
|
|
1190
|
-
techniques: ["ARIA19", "ARIA22", "ARIA23"]
|
|
1433
|
+
techniques: ["ARIA19", "ARIA22", "ARIA23"],
|
|
1434
|
+
text: "In content implemented using markup languages, status messages can be programmatically determined through role or properties such that they can be presented to the user by assistive technologies without receiving focus.",
|
|
1435
|
+
textFr: "Dans un contenu impl\xE9ment\xE9 via un langage de balisage, les messages d\u2019\xE9tat peuvent \xEAtre d\xE9termin\xE9s par un programme informatique gr\xE2ce \xE0 un r\xF4le ou des propri\xE9t\xE9s afin qu\u2019ils puissent \xEAtre pr\xE9sent\xE9s \xE0 l\u2019utilisateur par des technologies d\u2019assistance sans recevoir le focus.",
|
|
1436
|
+
termsFr: ["status-messages", "programmatically-determinable", "role", "assistive-technologies"],
|
|
1437
|
+
terms: ["status-message", "programmatically-determined", "role", "assistive-technology"]
|
|
1191
1438
|
}
|
|
1192
|
-
]
|
|
1439
|
+
],
|
|
1440
|
+
glossary: {
|
|
1441
|
+
abbreviation: {
|
|
1442
|
+
title: "abbreviation",
|
|
1443
|
+
body: "shortened form of a word, phrase, or name where the abbreviation has not become part of the language\nThis includes initialisms and acronyms where:\n\u2022\ninitialisms are shortened forms of a name or phrase made from the initial letters of words or syllables contained in that name or phrase\nNote: Not defined in all languages.\nExample:\nSNCF is a French initialism that contains the initial letters of the Soci\xE9t\xE9 Nationale des Chemins de Fer, the French national railroad.\nExample:\nESP is an initialism for extrasensory perception.\n\u2022\nacronyms are abbreviated forms made from the initial letters or parts of other words (in a name or phrase) which may be pronounced as a word\nExample:\nNOAA is an acronym made from the initial letters of the National Oceanic and Atmospheric Administration in the United States.\nNote: Some companies have adopted what used to be an initialism as their company name. In these cases, the new name of the company is the letters (for example, Ecma) and the word is no longer considered an abbreviation."
|
|
1444
|
+
},
|
|
1445
|
+
"accessibility-supported": {
|
|
1446
|
+
title: "accessibility supported",
|
|
1447
|
+
body: `supported by users' assistive technologies as well as the accessibility features in browsers and other user agents
|
|
1448
|
+
To qualify as an accessibility-supported use of a web content technology (or feature of a technology), both 1 and 2 must be satisfied for a web content technology (or feature):
|
|
1449
|
+
\u2022
|
|
1450
|
+
The way that the web content technology is used must be supported by users' assistive technology (AT). This means that the way that the technology is used has been tested for interoperability with users' assistive technology in the human language(s) of the content,
|
|
1451
|
+
AND
|
|
1452
|
+
\u2022
|
|
1453
|
+
The web content technology must have accessibility-supported user agents that are available to users. This means that at least one of the following four statements is true:
|
|
1454
|
+
\u2022
|
|
1455
|
+
The technology is supported natively in widely-distributed user agents that are also accessibility supported (such as HTML and CSS);
|
|
1456
|
+
OR
|
|
1457
|
+
\u2022
|
|
1458
|
+
The technology is supported in a widely-distributed plug-in that is also accessibility supported;
|
|
1459
|
+
OR
|
|
1460
|
+
\u2022
|
|
1461
|
+
The content is available in a closed environment, such as a university or corporate network, where the user agent required by the technology and used by the organization is also accessibility supported;
|
|
1462
|
+
OR
|
|
1463
|
+
\u2022
|
|
1464
|
+
The user agent(s) that support the technology are accessibility supported and are available for download or purchase in a way that:
|
|
1465
|
+
\u2022 does not cost a person with a disability any more than a person without a disability and
|
|
1466
|
+
\u2022 is as easy to find and obtain for a person with a disability as it is for a person without disabilities.
|
|
1467
|
+
Note: The Accessibility Guidelines Working Group and the W3C do not specify which or how much support by assistive technologies there must be for a particular use of a web technology in order for it to be classified as accessibility supported. (See Level of Assistive Technology Support Needed for "Accessibility Support".)
|
|
1468
|
+
Note: Web technologies can be used in ways that are not accessibility supported as long as they are not relied upon and the page as a whole meets the conformance requirements, including Conformance Requirement 4 and Conformance Requirement 5.
|
|
1469
|
+
Note: When a web technology is used in a way that is "accessibility supported," it does not imply that the entire technology or all uses of the technology are supported. Most technologies, including HTML, lack support for at least one feature or use. Pages conform to WCAG only if the uses of the technology that are accessibility supported can be relied upon to meet WCAG requirements.
|
|
1470
|
+
Note: When citing web content technologies that have multiple versions, the version(s) supported should be specified.
|
|
1471
|
+
Note: One way for authors to locate uses of a technology that are accessibility supported would be to consult compilations of uses that are documented to be accessibility supported. (See Understanding Accessibility-Supported Web Technology Uses.) Authors, companies, technology vendors, or others may document accessibility-supported ways of using web content technologies. However, all ways of using technologies in the documentation would need to meet the definition of accessibility-supported web content technologies above.`
|
|
1472
|
+
},
|
|
1473
|
+
"alternative-for-time-based-media": {
|
|
1474
|
+
title: "alternative for time-based media",
|
|
1475
|
+
body: "document including correctly sequenced text descriptions of time-based visual and auditory information and providing a means for achieving the outcomes of any time-based interaction\nNote: A screenplay used to create the synchronized media content would meet this definition only if it was corrected to accurately represent the final synchronized media after editing."
|
|
1476
|
+
},
|
|
1477
|
+
"ambiguous-to-users-in-general": {
|
|
1478
|
+
title: "ambiguous to users in general",
|
|
1479
|
+
body: 'the purpose cannot be determined from the link and all information of the web page presented to the user simultaneously with the link (i.e., readers without disabilities would not know what a link would do until they activated it)\nExample:\nThe word guava in the following sentence "One of the notable exports is guava" is a link. The link could lead to a definition of guava, a chart listing the quantity of guava exported or a photograph of people harvesting guava. Until the link is activated, all readers are unsure and the person with a disability is not at any disadvantage.'
|
|
1480
|
+
},
|
|
1481
|
+
"ascii-art": {
|
|
1482
|
+
title: "ASCII art",
|
|
1483
|
+
body: "picture created by a spatial arrangement of characters or glyphs (typically from the 95 printable characters defined by ASCII)"
|
|
1484
|
+
},
|
|
1485
|
+
"assistive-technology": {
|
|
1486
|
+
title: "assistive technology",
|
|
1487
|
+
body: "hardware and/or software that acts as a user agent, or along with a mainstream user agent, to provide functionality to meet the requirements of users with disabilities that go beyond those offered by mainstream user agents\nNote: Functionality provided by assistive technology includes alternative presentations (e.g., as synthesized speech or magnified content), alternative input methods (e.g., voice), additional navigation or orientation mechanisms, and content transformations (e.g., to make tables more accessible).\nNote: Assistive technologies often communicate data and messages with mainstream user agents by using and monitoring APIs.\nNote: The distinction between mainstream user agents and assistive technologies is not absolute. Many mainstream user agents provide some features to assist individuals with disabilities. The basic difference is that mainstream user agents target broad and diverse audiences that usually include people with and without disabilities. Assistive technologies target narrowly defined populations of users with specific disabilities. The assistance provided by an assistive technology is more specific and appropriate to the needs of its target users. The mainstream user agent may provide important functionality to assistive technologies like retrieving web content from program objects or parsing markup into identifiable bundles.\nExample:\nAssistive technologies that are important in the context of this document include the following:\n\u2022 screen magnifiers, and other visual reading assistants, which are used by people with visual, perceptual and physical print disabilities to change text font, size, spacing, color, synchronization with speech, etc. in order to improve the visual readability of rendered text and images;\n\u2022 screen readers, which are used by people who are blind to read textual information through synthesized speech or braille;\n\u2022 text-to-speech software, which is used by some people with cognitive, language, and learning disabilities to convert text into synthetic speech;\n\u2022 speech recognition software, which may be used by people who have some physical disabilities;\n\u2022 alternative keyboards, which are used by people with certain physical disabilities to simulate the keyboard (including alternate keyboards that use head pointers, single switches, sip/puff and other special input devices.);\n\u2022 alternative pointing devices, which are used by people with certain physical disabilities to simulate mouse pointing and button activations."
|
|
1488
|
+
},
|
|
1489
|
+
"audio-description": {
|
|
1490
|
+
title: "audio description",
|
|
1491
|
+
body: 'narration added to the soundtrack to describe important visual details that cannot be understood from the main soundtrack alone\nNote: Audio description of video provides information about actions, characters, scene changes, on-screen text, and other visual content.\nNote: In standard audio description, narration is added during existing pauses in dialogue. (See also extended audio description.)\nNote: Where all of the important video information is already provided in existing audio, no additional audio description is necessary.\nNote: Also called "video description" and "descriptive narration."'
|
|
1492
|
+
},
|
|
1493
|
+
"audio-only": {
|
|
1494
|
+
title: "audio-only",
|
|
1495
|
+
body: "a time-based presentation that contains only audio (no video and no interaction)"
|
|
1496
|
+
},
|
|
1497
|
+
audio: {
|
|
1498
|
+
title: "audio",
|
|
1499
|
+
body: "the technology of sound reproduction\nNote: Audio can be created synthetically (including speech synthesis), recorded from real world sounds, or both."
|
|
1500
|
+
},
|
|
1501
|
+
blinking: {
|
|
1502
|
+
title: "blinking",
|
|
1503
|
+
body: "switch back and forth between two visual states in a way that is meant to draw attention\nNote: See also flash. It is possible for something to be large enough and blink brightly enough at the right frequency to be also classified as a flash."
|
|
1504
|
+
},
|
|
1505
|
+
"blocks-of-text": {
|
|
1506
|
+
title: "blocks of text",
|
|
1507
|
+
body: "more than one sentence of text"
|
|
1508
|
+
},
|
|
1509
|
+
captcha: {
|
|
1510
|
+
title: "CAPTCHA",
|
|
1511
|
+
body: 'initialism for "Completely Automated Public Turing test to tell Computers and Humans Apart"\nNote: CAPTCHA tests often involve asking the user to type in text that is displayed in an obscured image or audio file.\nNote: A Turing test is any system of tests designed to differentiate a human from a computer. It is named after famed computer scientist Alan Turing. The term was coined by researchers at Carnegie Mellon University.'
|
|
1512
|
+
},
|
|
1513
|
+
captions: {
|
|
1514
|
+
title: "captions",
|
|
1515
|
+
body: "synchronized visual and/or text alternative for both speech and non-speech audio information needed to understand the media content\nNote: Captions are similar to dialogue-only subtitles except captions convey not only the content of spoken dialogue, but also equivalents for non-dialogue audio information needed to understand the program content, including sound effects, music, laughter, speaker identification and location.\nNote: Closed Captions are equivalents that can be turned on and off with some players.\nNote: Open Captions are any captions that cannot be turned off. For example, if the captions are visual equivalent images of text embedded in video.\nNote: Captions should not obscure or obstruct relevant information in the video.\nNote: In some countries, captions are called subtitles.\nNote: Audio descriptions can be, but do not need to be, captioned since they are descriptions of information that is already presented visually."
|
|
1516
|
+
},
|
|
1517
|
+
"changes-of-context": {
|
|
1518
|
+
title: "changes of context",
|
|
1519
|
+
body: "major changes that, if made without user awareness, can disorient users who are not able to view the entire page simultaneously\nChanges in context include changes of:\n\u2022 user agent;\n\u2022 viewport;\n\u2022 focus;\n\u2022 content that changes the meaning of the web page\nNote: A change of content is not always a change of context. Changes in content, such as an expanding outline, dynamic menu, or a tab control do not necessarily change the context, unless they also change one of the above (e.g., focus).\nExample:\nOpening a new window, moving focus to a different component, going to a new page (including anything that would look to a user as if they had moved to a new page) or significantly re-arranging the content of a page are examples of changes of context."
|
|
1520
|
+
},
|
|
1521
|
+
conformance: {
|
|
1522
|
+
title: "conformance",
|
|
1523
|
+
body: "satisfying all the requirements of a given standard, guideline or specification"
|
|
1524
|
+
},
|
|
1525
|
+
"conforming-alternate-version": {
|
|
1526
|
+
title: "conforming alternate version",
|
|
1527
|
+
body: 'version that\n\u2022 conforms at the designated level, and\n\u2022 provides all of the same information and functionality in the same human language, and\n\u2022 is as up to date as the non-conforming content, and\n\u2022\nfor which at least one of the following is true:\n\u2022 the conforming version can be reached from the non-conforming page via an accessibility-supported mechanism, or\n\u2022 the non-conforming version can only be reached from the conforming version, or\n\u2022 the non-conforming version can only be reached from a conforming page that also provides a mechanism to reach the conforming version\nNote: In this definition, "can only be reached" means that there is some mechanism, such as a conditional redirect, that prevents a user from "reaching" (loading) the non-conforming page unless the user had just come from the conforming version.\nNote: The alternate version does not need to be matched page for page with the original (e.g., the conforming alternate version may consist of multiple pages).\nNote: If multiple language versions are available, then conforming alternate versions are required for each language offered.\nNote: Alternate versions may be provided to accommodate different technology environments or user groups. Each version should be as conformant as possible. One version would need to be fully conformant in order to meet conformance requirement 1.\nNote: The conforming alternative version does not need to reside within the scope of conformance, or even on the same website, as long as it is as freely available as the non-conforming version.\nNote: Alternate versions should not be confused with supplementary content, which support the original page and enhance comprehension.\nNote: Setting user preferences within the content to produce a conforming version is an acceptable mechanism for reaching another version as long as the method used to set the preferences is accessibility supported.\nSee Understanding Conforming Alternate Versions'
|
|
1528
|
+
},
|
|
1529
|
+
content: {
|
|
1530
|
+
title: "content",
|
|
1531
|
+
body: "information and sensory experience to be communicated to the user by means of a user agent, including code or markup that defines the content's structure, presentation, and interactions"
|
|
1532
|
+
},
|
|
1533
|
+
"context-sensitive-help": {
|
|
1534
|
+
title: "context-sensitive help",
|
|
1535
|
+
body: "help text that provides information related to the function currently being performed\nNote: Clear labels can act as context-sensitive help."
|
|
1536
|
+
},
|
|
1537
|
+
"contrast-ratio": {
|
|
1538
|
+
title: "contrast ratio",
|
|
1539
|
+
body: "(L1 + 0.05) / (L2 + 0.05), where\n\u2022 L1 is the relative luminance of the lighter of the colors, and\n\u2022 L2 is the relative luminance of the darker of the colors.\nNote: Contrast ratios can range from 1 to 21 (commonly written 1:1 to 21:1).\nNote: Because authors do not have control over user settings as to how text is rendered (for example font smoothing or anti-aliasing), the contrast ratio for text can be evaluated with anti-aliasing turned off.\nNote: For the purpose of Success Criteria 1.4.3 and 1.4.6, contrast is measured with respect to the specified background over which the text is rendered in normal usage. If no background color is specified, then white is assumed.\nNote: Background color is the specified color of content over which the text is to be rendered in normal usage. It is a failure if no background color is specified when the text color is specified, because the user's default background color is unknown and cannot be evaluated for sufficient contrast. For the same reason, it is a failure if no text color is specified when a background color is specified.\nNote: When there is a border around the letter, the border can add contrast and would be used in calculating the contrast between the letter and its background. A narrow border around the letter would be used as the letter. A wide border around the letter that fills in the inner details of the letters acts as a halo and would be considered background.\nNote: WCAG conformance should be evaluated for color pairs specified in the content that an author would expect to appear adjacent in typical presentation. Authors need not consider unusual presentations, such as color changes made by the user agent, except where caused by authors' code."
|
|
1540
|
+
},
|
|
1541
|
+
"correct-reading-sequence": {
|
|
1542
|
+
title: "correct reading sequence",
|
|
1543
|
+
body: "any sequence where words and paragraphs are presented in an order that does not change the meaning of the content"
|
|
1544
|
+
},
|
|
1545
|
+
emergency: {
|
|
1546
|
+
title: "emergency",
|
|
1547
|
+
body: "a sudden, unexpected situation or occurrence that requires immediate action to preserve health, safety, or property"
|
|
1548
|
+
},
|
|
1549
|
+
essential: {
|
|
1550
|
+
title: "essential",
|
|
1551
|
+
body: "if removed, would fundamentally change the information or functionality of the content, and information and functionality cannot be achieved in another way that would conform"
|
|
1552
|
+
},
|
|
1553
|
+
"extended-audio-description": {
|
|
1554
|
+
title: "extended audio description",
|
|
1555
|
+
body: "audio description that is added to an audiovisual presentation by pausing the video so that there is time to add additional description\nNote: This technique is only used when the sense of the video would be lost without the additional audio description and the pauses between dialogue/narration are too short."
|
|
1556
|
+
},
|
|
1557
|
+
flash: {
|
|
1558
|
+
title: "flash",
|
|
1559
|
+
body: "a pair of opposing changes in relative luminance that can cause seizures in some people if it is large enough and in the right frequency range\nNote: See general flash and red flash thresholds for information about types of flash that are not allowed.\nNote: See also blinking."
|
|
1560
|
+
},
|
|
1561
|
+
functionality: {
|
|
1562
|
+
title: "functionality",
|
|
1563
|
+
body: "processes and outcomes achievable through user action"
|
|
1564
|
+
},
|
|
1565
|
+
"general-flash-and-red-flash-thresholds": {
|
|
1566
|
+
title: "general flash and red flash thresholds",
|
|
1567
|
+
body: 'a flash or rapidly changing image sequence is below the threshold (i.e., content passes) if any of the following are true:\n\u2022 there are no more than three general flashes and / or no more than three red flashes within any one-second period; or\n\u2022 the combined area of flashes occurring concurrently occupies no more than a total of .006 steradians within any 10 degree visual field on the screen (25% of any 10 degree visual field on the screen) at typical viewing distance\nwhere:\n\u2022 A general flash is defined as a pair of opposing changes in relative luminance of 10% or more of the maximum relative luminance (1.0) where the relative luminance of the darker image is below 0.80; and where "a pair of opposing changes" is an increase followed by a decrease, or a decrease followed by an increase, and\n\u2022 A red flash is defined as any pair of opposing transitions involving a saturated red\nException: Flashing that is a fine, balanced, pattern such as white noise or an alternating checkerboard pattern with "squares" smaller than 0.1 degree (of visual field at typical viewing distance) on a side does not violate the thresholds.\nNote: For general software or web content, using a 341 x 256 pixel rectangle anywhere on the displayed screen area when the content is viewed at 1024 x 768 pixels will provide a good estimate of a 10 degree visual field for standard screen sizes and viewing distances (e.g., 15-17 inch screen at 22-26 inches). This resolution of 75 - 85 ppi is known to be lower, and thus more conservative than the nominal CSS pixel resolution of 96 ppi in CSS specifications. Higher resolutions displays showing the same rendering of the content yield smaller and safer images so it is lower resolutions that are used to define the thresholds.\nNote: A transition is the change in relative luminance (or relative luminance/color for red flashing) between adjacent peaks and valleys in a plot of relative luminance (or relative luminance/color for red flashing) measurement against time. A flash consists of two opposing transitions.\nNote: The new working definition in the field for "pair of opposing transitions involving a saturated red" (from WCAG 2.2) is a pair of opposing transitions where, one transition is either to or from a state with a value R/(R + G + B) that is greater than or equal to 0.8, and the difference between states is more than 0.2 (unitless) in the CIE 1976 UCS chromaticity diagram. [[ISO_9241-391]]\nNote: Tools are available that will carry out analysis from video screen capture. However, no tool is necessary to evaluate for this condition if flashing is less than or equal to 3 flashes in any one second. Content automatically passes (see #1 and #2 above).'
|
|
1568
|
+
},
|
|
1569
|
+
"human-language": {
|
|
1570
|
+
title: "human language",
|
|
1571
|
+
body: "language that is spoken, written or signed (through visual or tactile means) to communicate with humans\nNote: See also sign language."
|
|
1572
|
+
},
|
|
1573
|
+
idiom: {
|
|
1574
|
+
title: "idiom",
|
|
1575
|
+
body: 'phrase whose meaning cannot be deduced from the meaning of the individual words and the specific words cannot be changed without losing the meaning\nNote: Idioms cannot be translated directly, word for word, without losing their (cultural or language-dependent) meaning.\nExample:\nIn English, "spilling the beans" means "revealing a secret." However, "knocking over the beans" or "spilling the vegetables" does not mean the same thing.\nExample:\nIn Japanese, the phrase "\u3055\u3058\u3092\u6295\u3052\u308B" literally translates into "he throws a spoon," but it means that there is nothing he can do and finally he gives up.\nExample:\nIn Dutch, "Hij ging met de kippen op stok" literally translates into "He went to roost with the chickens," but it means that he went to bed early.'
|
|
1576
|
+
},
|
|
1577
|
+
"image-of-text": {
|
|
1578
|
+
title: "image of text",
|
|
1579
|
+
body: "text that has been rendered in a non-text form (e.g., an image) in order to achieve a particular visual effect\nNote: This does not include text that is part of a picture that contains significant other visual content.\nExample:\nA person's name on a nametag in a photograph."
|
|
1580
|
+
},
|
|
1581
|
+
informative: {
|
|
1582
|
+
title: "informative",
|
|
1583
|
+
body: 'for information purposes and not required for conformance\nNote: Content required for conformance is referred to as "normative."'
|
|
1584
|
+
},
|
|
1585
|
+
"input-error": {
|
|
1586
|
+
title: "input error",
|
|
1587
|
+
body: "information provided by the user that is not accepted\nThis includes:\n\u2022 Information that is required by the web page but omitted by the user\n\u2022 Information that is provided by the user but that falls outside the required data format or values"
|
|
1588
|
+
},
|
|
1589
|
+
jargon: {
|
|
1590
|
+
title: "jargon",
|
|
1591
|
+
body: "words used in a particular way by people in a particular field\nExample:\nThe word StickyKeys is jargon from the field of assistive technology/accessibility."
|
|
1592
|
+
},
|
|
1593
|
+
"keyboard-interface": {
|
|
1594
|
+
title: "keyboard interface",
|
|
1595
|
+
body: 'interface used by software to obtain keystroke input\nA keyboard interface allows users to provide keystroke input to programs even if the native technology does not contain a keyboard.\nExample:\nA touchscreen PDA has a keyboard interface built into its operating system as well as a connector for external keyboards. Applications on the PDA can use the interface to obtain keyboard input either from an external keyboard or from other applications that provide simulated keyboard output, such as handwriting interpreters or speech-to-text applications with "keyboard emulation" functionality.\nNote: Operation of the application (or parts of the application) through a keyboard-operated mouse emulator, such as MouseKeys, does not qualify as operation through a keyboard interface because operation of the program is through its pointing device interface, not through its keyboard interface.'
|
|
1596
|
+
},
|
|
1597
|
+
label: {
|
|
1598
|
+
title: "label",
|
|
1599
|
+
body: "text or other component with a text alternative that is presented to a user to identify a component within web content\nNote: A label is presented to all users whereas the name may be hidden and only exposed by assistive technology. In many (but not all) cases the name and the label are the same.\nNote: The term label is not limited to the label element in HTML."
|
|
1600
|
+
},
|
|
1601
|
+
"large-scale": {
|
|
1602
|
+
title: "large scale",
|
|
1603
|
+
body: `with at least 18 point or 14 point bold or font size that would yield equivalent size for Chinese, Japanese and Korean (CJK) fonts
|
|
1604
|
+
Note: Fonts with extraordinarily thin strokes or unusual features and characteristics that reduce the familiarity of their letter forms are harder to read, especially at lower contrast levels.
|
|
1605
|
+
Note: Font size is the size when the content is delivered. It does not include resizing that may be done by a user.
|
|
1606
|
+
Note: The actual size of the character that a user sees is dependent both on the author-defined size and the user's display or user agent settings. For many mainstream body text fonts, 14 and 18 point is roughly equivalent to 1.2 and 1.5 em or to 120% or 150% of the default size for body text (assuming that the body font is 100%), but authors would need to check this for the particular fonts in use. When fonts are defined in relative units, the actual point size is calculated by the user agent for display. The point size should be obtained from the user agent, or calculated based on font metrics as the user agent does, when evaluating this success criterion. Users who have low vision would be responsible for choosing appropriate settings.
|
|
1607
|
+
Note: When using text without specifying the font size, the smallest font size used on major browsers for unspecified text would be a reasonable size to assume for the font. If a level 1 heading is rendered in 14pt bold or higher on major browsers, then it would be reasonable to assume it is large text. Relative scaling can be calculated from the default sizes in a similar fashion.
|
|
1608
|
+
Note: The 18 and 14 point sizes for roman texts are taken from the minimum size for large print (14pt) and the larger standard font size (18pt). For other fonts such as CJK languages, the "equivalent" sizes would be the minimum large print size used for those languages and the next larger standard large print size.`
|
|
1609
|
+
},
|
|
1610
|
+
"legal-commitments": {
|
|
1611
|
+
title: "legal commitments",
|
|
1612
|
+
body: "transactions where the person incurs a legally binding obligation or benefit\nExample:\nA marriage license, a stock trade (financial and legal), a will, a loan, adoption, signing up for the army, a contract of any type, etc."
|
|
1613
|
+
},
|
|
1614
|
+
"link-purpose": {
|
|
1615
|
+
title: "link purpose",
|
|
1616
|
+
body: "nature of the result obtained by activating a hyperlink"
|
|
1617
|
+
},
|
|
1618
|
+
live: {
|
|
1619
|
+
title: "live",
|
|
1620
|
+
body: "information captured from a real-world event and transmitted to the receiver with no more than a broadcast delay\nNote: A broadcast delay is a short (usually automated) delay, for example used in order to give the broadcaster time to cue or censor the audio (or video) feed, but not sufficient to allow significant editing.\nNote: If information is completely computer generated, it is not live."
|
|
1621
|
+
},
|
|
1622
|
+
"lower-secondary-education-level": {
|
|
1623
|
+
title: "lower secondary education level",
|
|
1624
|
+
body: "the two or three year period of education that begins after completion of six years of school and ends nine years after the beginning of primary education\nNote: This definition is based on the International Standard Classification of Education [[UNESCO]]."
|
|
1625
|
+
},
|
|
1626
|
+
mechanism: {
|
|
1627
|
+
title: "mechanism",
|
|
1628
|
+
body: "process or technique for achieving a result\nNote: The mechanism may be explicitly provided in the content, or may be relied upon to be provided by either the platform or by user agents, including assistive technologies.\nNote: The mechanism needs to meet all success criteria for the conformance level claimed."
|
|
1629
|
+
},
|
|
1630
|
+
"media-alternative-for-text": {
|
|
1631
|
+
title: "media alternative for text",
|
|
1632
|
+
body: "media that presents no more information than is already presented in text (directly or via text alternatives)\nNote: A media alternative for text is provided for those who benefit from alternate representations of text. Media alternatives for text may be audio-only, video-only (including sign-language video), or audio-video."
|
|
1633
|
+
},
|
|
1634
|
+
name: {
|
|
1635
|
+
title: "name",
|
|
1636
|
+
body: "text by which software can identify a component within web content to the user\nNote: The name may be hidden and only exposed by assistive technology, whereas a label is presented to all users. In many (but not all) cases, the label and the name are the same.\nNote: This is unrelated to the name attribute in HTML."
|
|
1637
|
+
},
|
|
1638
|
+
"navigated-sequentially": {
|
|
1639
|
+
title: "navigated sequentially",
|
|
1640
|
+
body: "navigated in the order defined for advancing focus (from one element to the next) using a keyboard interface"
|
|
1641
|
+
},
|
|
1642
|
+
"non-text-content": {
|
|
1643
|
+
title: "non-text content",
|
|
1644
|
+
body: "any content that is not a sequence of characters that can be programmatically determined or where the sequence is not expressing something in human language\nNote: This includes ASCII art (which is a pattern of characters), emoticons, leetspeak (which uses character substitution), and images representing text"
|
|
1645
|
+
},
|
|
1646
|
+
normative: {
|
|
1647
|
+
title: "normative",
|
|
1648
|
+
body: 'required for conformance\nNote: One may conform in a variety of well-defined ways to this document.\nNote: Content identified as "informative" or "non-normative" is never required for conformance.'
|
|
1649
|
+
},
|
|
1650
|
+
"on-a-full-screen-window": {
|
|
1651
|
+
title: "on a full-screen window",
|
|
1652
|
+
body: "on the most common sized desktop/laptop display with the viewport maximized\nNote: Since people generally keep their computers for several years, it is best not to rely on the latest desktop/laptop display resolutions but to consider the common desktop/laptop display resolutions over the course of several years when making this evaluation."
|
|
1653
|
+
},
|
|
1654
|
+
paused: {
|
|
1655
|
+
title: "paused",
|
|
1656
|
+
body: "stopped by user request and not resumed until requested by user"
|
|
1657
|
+
},
|
|
1658
|
+
prerecorded: {
|
|
1659
|
+
title: "prerecorded",
|
|
1660
|
+
body: "information that is not live"
|
|
1661
|
+
},
|
|
1662
|
+
presentation: {
|
|
1663
|
+
title: "presentation",
|
|
1664
|
+
body: "rendering of the content in a form to be perceived by users"
|
|
1665
|
+
},
|
|
1666
|
+
"primary-education-level": {
|
|
1667
|
+
title: "primary education level",
|
|
1668
|
+
body: "six year time period that begins between the ages of five and seven, possibly without any previous education\nNote: This definition is based on the International Standard Classification of Education [[UNESCO]]."
|
|
1669
|
+
},
|
|
1670
|
+
process: {
|
|
1671
|
+
title: "process",
|
|
1672
|
+
body: "series of user actions where each action is required in order to complete an activity\nExample:\nSuccessful use of a series of web pages on a shopping site requires users to view alternative products, prices and offers, select products, submit an order, provide shipping information and provide payment information.\nExample:\nAn account registration page requires successful completion of a Turing test before the registration form can be accessed."
|
|
1673
|
+
},
|
|
1674
|
+
"programmatically-determined-link-context": {
|
|
1675
|
+
title: "programmatically determined link context",
|
|
1676
|
+
body: "additional information that can be programmatically determined from relationships with a link, combined with the link text, and presented to users in different modalities\nExample:\nIn HTML, information that is programmatically determinable from a link in English includes text that is in the same paragraph, list item, or table cell as the link or in a table header cell that is associated with the table cell that contains the link.\nNote: Since screen readers interpret punctuation, they can also provide the context from the current sentence, when the focus is on a link in that sentence."
|
|
1677
|
+
},
|
|
1678
|
+
"programmatically-determined": {
|
|
1679
|
+
title: "programmatically determined",
|
|
1680
|
+
body: "determined by software from author-supplied data provided in a way that different user agents, including assistive technologies, can extract and present this information to users in different modalities\nExample:\nDetermined in a markup language from elements and attributes that are accessed directly by commonly available assistive technology.\nExample:\nDetermined from technology-specific data structures in a non-markup language and exposed to assistive technology via an accessibility API that is supported by commonly available assistive technology."
|
|
1681
|
+
},
|
|
1682
|
+
"programmatically-set": {
|
|
1683
|
+
title: "programmatically set",
|
|
1684
|
+
body: "set by software using methods that are supported by user agents, including assistive technologies"
|
|
1685
|
+
},
|
|
1686
|
+
"pure-decoration": {
|
|
1687
|
+
title: "pure decoration",
|
|
1688
|
+
body: "serving only an aesthetic purpose, providing no information, and having no functionality\nNote: Text is only purely decorative if the words can be rearranged or substituted without changing their purpose.\nExample:\nThe cover page of a dictionary has random words in very light text in the background."
|
|
1689
|
+
},
|
|
1690
|
+
"real-time-event": {
|
|
1691
|
+
title: "real-time event",
|
|
1692
|
+
body: "event that a) occurs at the same time as the viewing and b) is not completely generated by the content\nExample:\nA Webcast of a live performance (occurs at the same time as the viewing and is not prerecorded).\nExample:\nAn on-line auction with people bidding (occurs at the same time as the viewing).\nExample:\nLive humans interacting in a virtual world using avatars (is not completely generated by the content and occurs at the same time as the viewing)."
|
|
1693
|
+
},
|
|
1694
|
+
relationships: {
|
|
1695
|
+
title: "relationships",
|
|
1696
|
+
body: "meaningful associations between distinct pieces of content"
|
|
1697
|
+
},
|
|
1698
|
+
"relative-luminance": {
|
|
1699
|
+
title: "relative luminance",
|
|
1700
|
+
body: 'the relative brightness of any point in a colorspace, normalized to 0 for darkest black and 1 for lightest white\nFor the sRGB colorspace, the relative luminance of a color is defined as L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G and B are defined as:\n\u2022 if RsRGB <= 0.04045 then R = RsRGB/12.92 else R = ((RsRGB+0.055)/1.055) ^ 2.4\n\u2022 if GsRGB <= 0.04045 then G = GsRGB/12.92 else G = ((GsRGB+0.055)/1.055) ^ 2.4\n\u2022 if BsRGB <= 0.04045 then B = BsRGB/12.92 else B = ((BsRGB+0.055)/1.055) ^ 2.4\nand RsRGB, GsRGB, and BsRGB are defined as:\n\u2022 RsRGB = R8bit/255\n\u2022 GsRGB = G8bit/255\n\u2022 BsRGB = B8bit/255\nThe "^" character is the exponentiation operator. (Formula taken from [[SRGB]].)\nNote: Before May 2021 the value of 0.04045 in the definition was different (0.03928). It was taken from an older version of the specification and has been updated. It has no practical effect on the calculations in the context of these guidelines.\nNote: Almost all systems used today to view web content assume sRGB encoding. Unless it is known that another color space will be used to process and display the content, authors should evaluate using sRGB colorspace. If using other color spaces, see Understanding Success Criterion 1.4.3.\nNote: If dithering occurs after delivery, then the source color value is used. For colors that are dithered at the source, the average values of the colors that are dithered should be used (average R, average G, and average B).\nNote: Tools are available that automatically do the calculations when testing contrast and flash.\nNote: A separate page giving the relative luminance definition using MathML to display the formulas is available.'
|
|
1701
|
+
},
|
|
1702
|
+
"relied-upon": {
|
|
1703
|
+
title: "relied upon",
|
|
1704
|
+
body: "the content would not conform if that technology is turned off or is not supported"
|
|
1705
|
+
},
|
|
1706
|
+
role: {
|
|
1707
|
+
title: "role",
|
|
1708
|
+
body: "text or number by which software can identify the function of a component within web content\nExample:\nA number that indicates whether an image functions as a hyperlink, command button, or check box."
|
|
1709
|
+
},
|
|
1710
|
+
"same-functionality": {
|
|
1711
|
+
title: "same functionality",
|
|
1712
|
+
body: 'same result when used\nExample:\nA submit "search" button on one web page and a "find" button on another web page may both have a field to enter a term and list topics in the website related to the term submitted. In this case, they would have the same functionality but would not be labeled consistently.'
|
|
1713
|
+
},
|
|
1714
|
+
"same-relative-order": {
|
|
1715
|
+
title: "same relative order",
|
|
1716
|
+
body: "same position relative to other items\nNote: Items are considered to be in the same relative order even if other items are inserted or removed from the original order. For example, expanding navigation menus may insert an additional level of detail or a secondary navigation section may be inserted into the reading order."
|
|
1717
|
+
},
|
|
1718
|
+
"satisfies-a-success-criterion": {
|
|
1719
|
+
title: "satisfies a success criterion",
|
|
1720
|
+
body: "the success criterion does not evaluate to 'false' when applied to the page"
|
|
1721
|
+
},
|
|
1722
|
+
section: {
|
|
1723
|
+
title: "section",
|
|
1724
|
+
body: "a self-contained portion of written content that deals with one or more related topics or thoughts\nNote: A section may consist of one or more paragraphs and include graphics, tables, lists and sub-sections."
|
|
1725
|
+
},
|
|
1726
|
+
"set-of-web-pages": {
|
|
1727
|
+
title: "set of web pages",
|
|
1728
|
+
body: "collection of web pages that share a common purpose and that are created by the same author, group or organization\nExample:\nExamples include:\n\u2022 a publication which is split across multiple web pages, where each page contains one chapter or other significant section of the work. The publication is logically a single contiguous unit, and contains navigation features that enable access to the full set of pages.\n\u2022 an e-commerce website shows products in a set of web pages that all share the same navigation and identification. However, when progressing to the checkout process, the template changes; the navigation and other elements are removed, so the pages in that process are functionally and visually different. The checkout pages are not part of the set of product pages.\n\u2022 a blog on a sub-domain (e.g. blog.example.com) which has a different navigation and is authored by a distinct set of people from the pages on the primary domain (example.com).\nNote: Different language versions would be considered different sets of web pages."
|
|
1729
|
+
},
|
|
1730
|
+
"sign-language-interpretation": {
|
|
1731
|
+
title: "sign language interpretation",
|
|
1732
|
+
body: "translation of one language, generally a spoken language, into a sign language\nNote: True sign languages are independent languages that are unrelated to the spoken language(s) of the same country or region."
|
|
1733
|
+
},
|
|
1734
|
+
"sign-language": {
|
|
1735
|
+
title: "sign language",
|
|
1736
|
+
body: "a language using combinations of movements of the hands and arms, facial expressions, or body positions to convey meaning"
|
|
1737
|
+
},
|
|
1738
|
+
"specific-sensory-experience": {
|
|
1739
|
+
title: "specific sensory experience",
|
|
1740
|
+
body: "a sensory experience that is not purely decorative and does not primarily convey important information or perform a function\nExample:\nExamples include a performance of a flute solo, works of visual art etc."
|
|
1741
|
+
},
|
|
1742
|
+
structure: {
|
|
1743
|
+
title: "structure",
|
|
1744
|
+
body: "\u2022 The way the parts of a web page are organized in relation to each other; and\n\u2022 The way a collection of web pages is organized"
|
|
1745
|
+
},
|
|
1746
|
+
"supplemental-content": {
|
|
1747
|
+
title: "supplemental content",
|
|
1748
|
+
body: "additional content that illustrates or clarifies the primary content\nExample:\nAn audio version of a web page.\nExample:\nAn illustration of a complex process.\nExample:\nA paragraph summarizing the major outcomes and recommendations made in a research study."
|
|
1749
|
+
},
|
|
1750
|
+
"synchronized-media": {
|
|
1751
|
+
title: "synchronized media",
|
|
1752
|
+
body: "audio or video synchronized with another format for presenting information and/or with time-based interactive components, unless the media is a media alternative for text that is clearly labeled as such"
|
|
1753
|
+
},
|
|
1754
|
+
technology: {
|
|
1755
|
+
title: "technology",
|
|
1756
|
+
body: 'mechanism for encoding instructions to be rendered, played or executed by user agents\nNote: As used in these guidelines "web technology" and the word "technology" (when used alone) both refer to web content technologies.\nNote: Web content technologies may include markup languages, data formats, or programming languages that authors may use alone or in combination to create end-user experiences that range from static web pages to synchronized media presentations to dynamic web applications.\nExample:\nSome common examples of web content technologies include HTML, CSS, SVG, PNG, PDF, Flash, and JavaScript.'
|
|
1757
|
+
},
|
|
1758
|
+
"text-alternative": {
|
|
1759
|
+
title: "text alternative",
|
|
1760
|
+
body: "Text that is programmatically associated with non-text content or referred to from text that is programmatically associated with non-text content. Programmatically associated text is text whose location can be programmatically determined from the non-text content.\nExample:\nAn image of a chart is described in text in the paragraph after the chart. The short text alternative for the chart indicates that a description follows.\nNote: Refer to Understanding Text Alternatives for more information."
|
|
1761
|
+
},
|
|
1762
|
+
text: {
|
|
1763
|
+
title: "text",
|
|
1764
|
+
body: "sequence of characters that can be programmatically determined, where the sequence is expressing something in human language"
|
|
1765
|
+
},
|
|
1766
|
+
"used-in-an-unusual-or-restricted-way": {
|
|
1767
|
+
title: "used in an unusual or restricted way",
|
|
1768
|
+
body: 'words used in such a way that requires users to know exactly which definition to apply in order to understand the content correctly\nExample:\nThe term "gig" means something different if it occurs in a discussion of music concerts than it does in article about computer hard drive space, but the appropriate definition can be determined from context. By contrast, the word "text" is used in a very specific way in WCAG 2, so a definition is supplied in the glossary.'
|
|
1769
|
+
},
|
|
1770
|
+
"user-agent": {
|
|
1771
|
+
title: "user agent",
|
|
1772
|
+
body: "any software that retrieves and presents web content for users\nExample:\nWeb browsers, media players, plug-ins, and other programs \u2014 including assistive technologies \u2014 that help in retrieving, rendering, and interacting with web content."
|
|
1773
|
+
},
|
|
1774
|
+
"user-controllable": {
|
|
1775
|
+
title: "user-controllable",
|
|
1776
|
+
body: "data that is intended to be accessed by users\nNote: This does not refer to such things as Internet logs and search engine monitoring data.\nExample:\nName and address fields for a user's account."
|
|
1777
|
+
},
|
|
1778
|
+
"user-interface-component": {
|
|
1779
|
+
title: "user interface component",
|
|
1780
|
+
body: 'a part of the content that is perceived by users as a single control for a distinct function\nNote: Multiple user interface components may be implemented as a single programmatic element. "Components" here is not tied to programming techniques, but rather to what the user perceives as separate controls.\nNote: User interface components include form elements and links as well as components generated by scripts.\nNote: What is meant by "component" or "user interface component" here is also sometimes called "user interface element".\nExample:\nAn applet has a "control" that can be used to move through content by line or page or random access. Since each of these would need to have a name and be settable independently, they would each be a "user interface component."'
|
|
1781
|
+
},
|
|
1782
|
+
"video-only": {
|
|
1783
|
+
title: "video-only",
|
|
1784
|
+
body: "a time-based presentation that contains only video (no audio and no interaction)"
|
|
1785
|
+
},
|
|
1786
|
+
video: {
|
|
1787
|
+
title: "video",
|
|
1788
|
+
body: "the technology of moving or sequenced pictures or images\nNote: Video can be made up of animated or photographic images, or both."
|
|
1789
|
+
},
|
|
1790
|
+
viewport: {
|
|
1791
|
+
title: "viewport",
|
|
1792
|
+
body: "object in which the user agent presents content\nNote: The user agent presents content through one or more viewports. Viewports include windows, frames, loudspeakers, and virtual magnifying glasses. A viewport may contain another viewport (e.g., nested frames). Interface components created by the user agent such as prompts, menus, and alerts are not viewports.\nNote: This definition is based on User Agent Accessibility Guidelines 1.0 Glossary [[UAAG10]]."
|
|
1793
|
+
},
|
|
1794
|
+
"visually-customized": {
|
|
1795
|
+
title: "visually customized",
|
|
1796
|
+
body: "the font, size, color, and background can be set"
|
|
1797
|
+
},
|
|
1798
|
+
"web-page": {
|
|
1799
|
+
title: "web page",
|
|
1800
|
+
body: 'a non-embedded resource obtained from a single URI using HTTP plus any other resources that are used in the rendering or intended to be rendered together with it by a user agent\nNote: Although any "other resources" would be rendered together with the primary resource, they would not necessarily be rendered simultaneously with each other.\nNote: For the purposes of conformance with these guidelines, a resource must be "non-embedded" within the scope of conformance to be considered a web page.\nExample:\nA web resource including all embedded images and media.\nExample:\nA web mail program built using Asynchronous JavaScript and XML (AJAX). The program lives entirely at http://example.com/mail, but includes an inbox, a contacts area and a calendar. Links or buttons are provided that cause the inbox, contacts, or calendar to display, but do not change the URI of the page as a whole.\nExample:\nA customizable portal site, where users can choose content to display from a set of different content modules.\nExample:\nWhen you enter "http://shopping.example.com/" in your browser, you enter a movie-like interactive shopping environment where you visually move around in a store dragging products off of the shelves around you and into a visual shopping cart in front of you. Clicking on a product causes it to be demonstrated with a specification sheet floating alongside. This might be a single-page website or just one page within a website.'
|
|
1801
|
+
},
|
|
1802
|
+
"css-pixel": {
|
|
1803
|
+
title: "CSS pixel",
|
|
1804
|
+
body: "visual angle of about 0.0213 degrees\nA CSS pixel is the canonical unit of measure for all lengths and measurements in CSS. This unit is density-independent, and distinct from actual hardware pixels present in a display. User agents and operating systems should ensure that a CSS pixel is set as closely as possible to the CSS Values and Units Module Level 3 reference pixel [[css3-values]], which takes into account the physical dimensions of the display and the assumed viewing distance (factors that cannot be determined by content authors)."
|
|
1805
|
+
},
|
|
1806
|
+
"down-event": {
|
|
1807
|
+
title: "down-event",
|
|
1808
|
+
body: 'platform event that occurs when the trigger stimulus of a pointer is depressed\nThe down-event may have different names on different platforms, such as "touchstart" or "mousedown".'
|
|
1809
|
+
},
|
|
1810
|
+
"keyboard-shortcut": {
|
|
1811
|
+
title: "keyboard shortcut",
|
|
1812
|
+
body: "alternative means of triggering an action by the pressing of one or more keys"
|
|
1813
|
+
},
|
|
1814
|
+
"motion-animation": {
|
|
1815
|
+
title: "motion animation",
|
|
1816
|
+
body: "addition of steps between conditions to create the illusion of movement or to give a sense of a smooth transition\nExample:\nFor example, an element which moves into place or changes size while appearing is considered to be animated. An element which appears or changes instantly, without transition/animation steps, is not using animation.\nMotion animation does not include changes \u2013 such as changes of color or opacity \u2013 that do not alter the perceived size, shape, position, or distance/depth of the element to the viewer."
|
|
1817
|
+
},
|
|
1818
|
+
"pointer-input": {
|
|
1819
|
+
title: "pointer input",
|
|
1820
|
+
body: 'input from a device that can target a specific coordinate (or set of coordinates) on a screen, such as a mouse, pen, or touch contact\nNote: See the Pointer Events definition for "pointer" [[pointerevents]].'
|
|
1821
|
+
},
|
|
1822
|
+
region: {
|
|
1823
|
+
title: "region",
|
|
1824
|
+
body: "perceivable, programmatically determined section of content\nNote: In HTML, any area designated with a landmark role would be a region."
|
|
1825
|
+
},
|
|
1826
|
+
"single-pointer": {
|
|
1827
|
+
title: "single pointer",
|
|
1828
|
+
body: "an input modality that only targets a single point on the page/screen at a time \u2013 such as a mouse, single finger on a touch screen, or stylus\nNote: Single pointer interactions include clicks, double clicks, taps, dragging motions, and single-finger swipe gestures. In contrast, multipoint interactions involve the use of two or more pointers at the same time, such as two-finger interactions on a touchscreen, or the simultaneous use of a mouse and stylus."
|
|
1829
|
+
},
|
|
1830
|
+
state: {
|
|
1831
|
+
title: "state",
|
|
1832
|
+
body: "dynamic property expressing characteristics of a user interface component that may change in response to user action or automated processes\nStates do not affect the nature of the component, but represent data associated with the component or user interaction possibilities. Examples include focus, hover, select, press, check, visited/unvisited, and expand/collapse."
|
|
1833
|
+
},
|
|
1834
|
+
"status-message": {
|
|
1835
|
+
title: "status message",
|
|
1836
|
+
body: "change in content that is not a change of context, and that provides information to the user on the success or results of an action, on the waiting state of an application, on the progress of a process, or on the existence of errors"
|
|
1837
|
+
},
|
|
1838
|
+
"style-property": {
|
|
1839
|
+
title: "style property",
|
|
1840
|
+
body: "property whose value determines the presentation (e.g. font, color, size, location, padding, volume, synthesized speech prosody) of content elements as they are rendered (e.g. onscreen, via loudspeaker, via braille display) by user agents\nStyle properties can have several origins:\n\u2022 User agent default styles: The default style property values applied in the absence of any author or user styles. Some web content technologies specify a default rendering, others do not;\n\u2022 Author styles: Style property values that are set by the author as part of the content (e.g. in-line styles, author style sheets);\n\u2022 User styles: Style property values that are set by the user (e.g. via user agent interface settings, user style sheets)"
|
|
1841
|
+
},
|
|
1842
|
+
target: {
|
|
1843
|
+
title: "target",
|
|
1844
|
+
body: "region of the display that will accept a pointer action, such as the interactive area of a user interface component\nNote: If two or more targets are overlapping, the overlapping area should not be included in the measurement of the target size, except when the overlapping targets perform the same action or open the same page."
|
|
1845
|
+
},
|
|
1846
|
+
"up-event": {
|
|
1847
|
+
title: "up-event",
|
|
1848
|
+
body: 'platform event that occurs when the trigger stimulus of a pointer is released\nThe up-event may have different names on different platforms, such as "touchend" or "mouseup".'
|
|
1849
|
+
},
|
|
1850
|
+
"user-inactivity": {
|
|
1851
|
+
title: "user inactivity",
|
|
1852
|
+
body: "any continuous period of time where no user actions occur\nThe method of tracking will be determined by the website or application."
|
|
1853
|
+
},
|
|
1854
|
+
"cognitive-function-test": {
|
|
1855
|
+
title: "cognitive function test",
|
|
1856
|
+
body: "cognitive function test\nA task that requires the user to remember, manipulate, or transcribe information. Examples include, but are not limited to:\n\u2022 memorization, such as remembering a username, password, set of characters, images, or patterns. The common identifiers name, email, and phone number are not considered cognitive function tests as they are personal to the user and consistent across websites;\n\u2022 transcription, such as typing in characters;\n\u2022 use of correct spelling;\n\u2022 performance of calculations;\n\u2022 solving of puzzles."
|
|
1857
|
+
},
|
|
1858
|
+
"dragging-movement": {
|
|
1859
|
+
title: "dragging movement",
|
|
1860
|
+
body: "dragging movement\nan operation where the pointer engages with an element on the down-event and the element (or a representation of its position) follows the pointer until an up-event\nNote: Examples of draggable elements include list items, text elements, and images."
|
|
1861
|
+
},
|
|
1862
|
+
"focus-indicator": {
|
|
1863
|
+
title: "focus indicator",
|
|
1864
|
+
body: "focus indicator\npixels that are changed to visually indicate when a user interface component is in a focused state"
|
|
1865
|
+
},
|
|
1866
|
+
"minimum-bounding-box": {
|
|
1867
|
+
title: "minimum bounding box",
|
|
1868
|
+
body: "minimum bounding box\nthe smallest enclosing rectangle aligned to the horizontal axis within which all the points of a shape lie. For components which wrap onto multiple lines as part of a sentence or block of text (such as hypertext links), the bounding box is based on how the component would appear on a single line."
|
|
1869
|
+
},
|
|
1870
|
+
perimeter: {
|
|
1871
|
+
title: "perimeter",
|
|
1872
|
+
body: "perimeter\ncontinuous line forming the boundary of a shape not including shared pixels, or the minimum bounding box, whichever is shortest\nExample:\nThe perimeter calculation for a 2 CSS pixel perimeter around a rectangle is 4h+4w, where h is the height and w is the width. For a 2 CSS pixel perimeter around a circle it is 4\u{1D70B}r."
|
|
1873
|
+
}
|
|
1874
|
+
},
|
|
1875
|
+
glossaryFr: {
|
|
1876
|
+
abbreviations: {
|
|
1877
|
+
title: "abr\xE9viation",
|
|
1878
|
+
body: "forme abr\xE9g\xE9e d\u2019un mot, d\u2019une expression ou d\u2019un nom lorsque l\u2019abr\xE9viation ne fait pas encore partie de la langue courante\nNote : Ceci comprend les sigles et les acronymes form\xE9s \xE0 partir des initiales des mots o\xF9 :\n\u2022\nles sigles sont une forme abr\xE9g\xE9e d\u2019un nom ou d\u2019une expression constitu\xE9e des lettres initiales des mots ou des syllabes contenues dans ce nom ou cette expression.\nNote : Ne sont pas d\xE9finies dans toutes les langues.\nExemple 1\nSNCF est le sigle de la Soci\xE9t\xE9 nationale des chemins de fer fran\xE7ais.\nExemple 2\nESP est le sigle, en anglais, de extrasensory perception, la perception extrasensorielle.\n\u2022\nles acronymes sont des abr\xE9viations form\xE9es \xE0 partir des premi\xE8res lettres ou des parties d\u2019autres mots (dans un nom ou une expression) et qui peuvent \xEAtre prononc\xE9s comme un mot.\nExemple 3\nONU est un acronyme constitu\xE9 des premi\xE8res lettres de Organisation des Nations unies.\nNote : Quelques soci\xE9t\xE9s ont adopt\xE9 ce qui constituait un sigle ou un acronyme comme nom de leur soci\xE9t\xE9. Dans un tel cas, le nouveau nom de la soci\xE9t\xE9 est constitu\xE9 des lettres (par exemple, Ecma) et le mot n\u2019est plus alors consid\xE9r\xE9 comme une abr\xE9viation."
|
|
1879
|
+
},
|
|
1880
|
+
"user-agents": {
|
|
1881
|
+
title: "agent utilisateur",
|
|
1882
|
+
body: "tout logiciel qui r\xE9cup\xE8re et pr\xE9sente le contenu Web aux utilisateurs\nExemple\nLes navigateurs Web, les lecteurs de m\xE9dia, les modules d\u2019extensions et les autres programmes \u2014 dont les technologies d\u2019assistance \u2014 qui aident \xE0 r\xE9cup\xE9rer, restituer et interagir avec le contenu Web."
|
|
1883
|
+
},
|
|
1884
|
+
"large-scale": {
|
|
1885
|
+
title: "(texte) agrandi",
|
|
1886
|
+
body: "avec au minimum 18 points ou 14 points gras ou une taille de caract\xE8re \xE9quivalente pour les polices chinoises, japonaises ou cor\xE9ennes (CJK)\nNote : Les polices avec des traits extraordinairement fins ou des aspects et des caract\xE9ristiques inhabituels qui r\xE9duisent la reconnaissance de la forme des lettres sont plus difficiles \xE0 lire, sp\xE9cialement \xE0 des niveaux de contrastes bas.\nNote : La taille de caract\xE8re est la taille lorsque le contenu est affich\xE9. Cela n\u2019inclut pas le redimensionnement qui pourrait \xEAtre fait par l\u2019utilisateur.\nNote : La taille r\xE9elle des caract\xE8res qu\u2019un utilisateur voit est d\xE9pendante \xE0 la fois de la d\xE9finition de la taille faite par l\u2019auteur, du p\xE9riph\xE9rique de restitution de l\u2019utilisateur ou du param\xE9trage de l\u2019agent utilisateur. Pour la majorit\xE9 des polices de corps de texte, 14 et 18 points est sensiblement \xE9quivalent \xE0 1,2 et 1,5 em ou \xE0 120% et 150% de la taille par d\xE9faut du corps de texte (en consid\xE9rant que la police de corps est \xE0 100%), mais les auteurs seraient tenus de v\xE9rifier cela pour les polices particuli\xE8res qui seraient utilis\xE9es. Quand les polices sont d\xE9finies en unit\xE9s relatives, la taille r\xE9elle du point est mesur\xE9e par l\u2019agent utilisateur pour l\u2019affichage. La taille d\u2019un point doit \xEAtre obtenue aupr\xE8s de l\u2019agent utilisateur ou calcul\xE9e sur la m\xEAme base de mesure que celle de l\u2019agent utilisateur, lors de l\u2019\xE9valuation de ce crit\xE8re de succ\xE8s. Les utilisateurs qui ont une basse vision auront \xE0 choisir les param\xE8tres appropri\xE9s.\nNote : Lors de l\u2019utilisation de texte sans sp\xE9cification de taille de caract\xE8re, la taille la plus petite utilis\xE9e dans les principaux navigateurs pour le texte dont la taille n\u2019est pas sp\xE9cifi\xE9e serait consid\xE9r\xE9e comme une taille raisonnable pour la police. Si un titre de niveau 1 est restitu\xE9 en 14pt gras ou plus sur les principaux navigateurs, alors il est raisonnable de consid\xE9rer qu\u2019il s\u2019agit de texte agrandi. Le redimensionnement relatif peut \xEAtre calcul\xE9 de mani\xE8re identique \xE0 partir de la taille par d\xE9faut.\nNote : La taille 18 ou 14 points pour les textes en alphabet latin est d\xE9finie \xE0 partir de la taille minimum pour les grands caract\xE8res (14pt) et de la taille standard plus grande (18pt). Pour les autres polices telles que les langues CJK, les tailles \xAB \xE9quivalentes \xBB seraient la taille de grand caract\xE8re minimum utilis\xE9e pour ces langues et la taille de grands caract\xE8res plus grande suivante."
|
|
1887
|
+
},
|
|
1888
|
+
"context-sensitive-help": {
|
|
1889
|
+
title: "aide contextuelle",
|
|
1890
|
+
body: "texte d\u2019aide qui fournit des informations relatives \xE0 la fonction actuellement utilis\xE9e\nNote : Des \xE9tiquettes claires peuvent jouer le r\xF4le d\u2019aide contextuelle."
|
|
1891
|
+
},
|
|
1892
|
+
"ambiguous-to-users-in-general": {
|
|
1893
|
+
title: "ambigu pour tout utilisateur",
|
|
1894
|
+
body: "l\u2019intention ne peut \xEAtre d\xE9termin\xE9e \xE0 partir du lien et de toute l\u2019information de la page Web pr\xE9sent\xE9e \xE0 l\u2019utilisateur en m\xEAme temps que ce lien (c\u2019est-\xE0-dire qu\u2019un lecteur sans limitations fonctionnelles ne conna\xEEtrait pas la fonction d\u2019un lien avant de l\u2019activer)\nExemple\nLe mot goyave dans la phrase suivante utilis\xE9 comme lien : \xAB L\u2019une des exportations importantes est la goyave \xBB. Ce lien pourrait conduire \xE0 une d\xE9finition de la goyave, \xE0 un graphe pr\xE9sentant une liste des quantit\xE9s de goyave export\xE9es ou \xE0 une photo de gens r\xE9coltant la goyave. Jusqu\u2019\xE0 ce que le lien soit activ\xE9, tout utilisateur est dans l\u2019incertitude et une personne handicap\xE9e n\u2019est donc pas d\xE9savantag\xE9e."
|
|
1895
|
+
},
|
|
1896
|
+
"motion-animation": {
|
|
1897
|
+
title: "animation bas\xE9e sur le mouvement",
|
|
1898
|
+
body: "ajout d\u2019\xE9tapes entre des \xE9tats pour cr\xE9er l\u2019illusion de mouvement ou pour donner l\u2019impression d\u2019une transition fluide\nExemple\nPar exemple, un \xE9l\xE9ment qui se d\xE9place ou change de taille lors de son apparition est consid\xE9r\xE9 comme anim\xE9. Un \xE9l\xE9ment qui appara\xEEt instantan\xE9ment sans transition n\u2019est pas consid\xE9r\xE9 comme anim\xE9. L\u2019animation bas\xE9e sur le mouvement ne comprend pas les changements de couleur, d\u2019effet de flou ou d\u2019opacit\xE9 qui ne modifient pas la taille, la forme ou la position per\xE7ues de l\u2019\xE9l\xE9ment."
|
|
1899
|
+
},
|
|
1900
|
+
"ascii-art": {
|
|
1901
|
+
title: "art ASCII",
|
|
1902
|
+
body: "dessin cr\xE9\xE9 par une disposition spatiale de caract\xE8res ou glyphes (habituellement \xE0 partir des 95 caract\xE8res imprimables d\xE9finis en ASCII)"
|
|
1903
|
+
},
|
|
1904
|
+
audio: {
|
|
1905
|
+
title: "audio",
|
|
1906
|
+
body: "la technologie de reproduction des sons\nNote : Le son peut \xEAtre cr\xE9\xE9 de fa\xE7on synth\xE9tique (y compris la synth\xE8se vocale), \xEAtre enregistr\xE9 \xE0 partir de sons r\xE9els ou les deux."
|
|
1907
|
+
},
|
|
1908
|
+
"audio-descriptions": {
|
|
1909
|
+
title: "audio-description",
|
|
1910
|
+
body: "narration ajout\xE9e \xE0 une piste sonore pour d\xE9crire les d\xE9tails visuels importants qui ne peuvent \xEAtre compris \xE0 partir de la piste sonore principale seulement\nNote : L\u2019audio-description d\u2019une vid\xE9o fournit de l\u2019information \xE0 propos des actions, des personnages, des changements de sc\xE8nes, du texte apparaissant \xE0 l\u2019\xE9cran et d\u2019autres contenus visuels.\nNote : Dans une audio-description standard, la narration est ajout\xE9e durant les pauses qui existent dans le dialogue. (Voir aussi audio-description \xE9tendue.)\nNote : Lorsque toute l\u2019information de la vid\xE9o est d\xE9j\xE0 donn\xE9e dans la piste audio, aucune audio-description suppl\xE9mentaire n\u2019est requise.\nNote : Aussi nomm\xE9e \xAB vid\xE9o-description \xBB et \xAB narration descriptive \xBB."
|
|
1911
|
+
},
|
|
1912
|
+
"extended-audio-description": {
|
|
1913
|
+
title: "audio-description \xE9tendue",
|
|
1914
|
+
body: "audio-description ajout\xE9e \xE0 une pr\xE9sentation audiovisuelle en mettant en pause la vid\xE9o de mani\xE8re \xE0 avoir le temps d\u2019ajouter des descriptions suppl\xE9mentaires\nNote : cette technique est \xE0 utiliser seulement si le sens de la vid\xE9o est perdu sans audio-description suppl\xE9mentaire et que les pauses entre les dialogues ou la narration sont trop courtes."
|
|
1915
|
+
},
|
|
1916
|
+
"blocks-of-text": {
|
|
1917
|
+
title: "blocs de texte",
|
|
1918
|
+
body: "plus d\u2019une phrase de texte"
|
|
1919
|
+
},
|
|
1920
|
+
"bounding-boxes": {
|
|
1921
|
+
title: "bo\xEEte de d\xE9limitation minimale",
|
|
1922
|
+
body: "le plus petit rectangle englobant align\xE9 sur l\u2019axe horizontal \xE0 l\u2019int\xE9rieur duquel se trouvent tous les points d\u2019une forme. Pour les composants qui s\u2019\xE9tendent sur plusieurs lignes dans le cadre d\u2019une phrase ou d\u2019un bloc de texte (comme les liens hypertextes), la bo\xEEte de d\xE9limitation est d\xE9termin\xE9e par la fa\xE7on dont le composant appara\xEEtrait sur une seule ligne."
|
|
1923
|
+
},
|
|
1924
|
+
captcha: {
|
|
1925
|
+
title: "CAPTCHA",
|
|
1926
|
+
body: "sigle de \xAB Completely Automated Public Turing test to tell Computers and Humans Apart \xBB (test public de Turing enti\xE8rement automatique ayant pour but de distinguer les humains des ordinateurs)\nNote : Les tests de type CAPTCHA demandent souvent \xE0 l\u2019utilisateur de taper un texte pr\xE9sent\xE9 dans une image ou un extrait audio d\xE9form\xE9s.\nNote : Un test de Turing est tout syst\xE8me de tests con\xE7u pour distinguer un humain d\u2019un ordinateur. Il est nomm\xE9 en l\u2019honneur du c\xE9l\xE8bre informaticien Alan Turing. Ce terme a \xE9t\xE9 popularis\xE9 par les chercheurs de l\u2019Universit\xE9 Carnegie Mellon."
|
|
1927
|
+
},
|
|
1928
|
+
"change-of-context": {
|
|
1929
|
+
title: "changements de contexte",
|
|
1930
|
+
body: "changements majeurs qui, s\u2019ils sont faits sans que l\u2019utilisateur en soit conscient, peuvent d\xE9sorienter les utilisateurs qui ne peuvent voir l\u2019ensemble de la page en m\xEAme temps\nLes changements de contexte comprennent les changements de :\n\u2022 agent utilisateur ;\n\u2022 espace de restitution ;\n\u2022 focus ;\n\u2022 contenu qui modifie la signification de la page Web.\nNote : Un changement de contenu n\u2019est pas toujours un changement de contexte. Un changement dans le contenu comme le d\xE9ploiement d\u2019une arborescence, un menu dynamique ou un d\xE9placement de tabulation ne change pas n\xE9cessairement le contexte \xE0 moins qu\u2019il ne change aussi l\u2019un des \xE9l\xE9ments \xE9num\xE9r\xE9s ci-dessus (par exemple le focus).\nExemple\nL\u2019ouverture d\u2019une nouvelle fen\xEAtre, le d\xE9placement du focus sur un composant diff\xE9rent, le d\xE9placement vers une nouvelle page (y compris tout ce qui, pour l\u2019utilisateur, aurait l\u2019air d\u2019un d\xE9placement vers une autre page) ou la r\xE9organisation significative du contenu d\u2019une page sont autant d\u2019exemples d\u2019un changement de contexte."
|
|
1931
|
+
},
|
|
1932
|
+
targets: {
|
|
1933
|
+
title: "cible",
|
|
1934
|
+
body: "zone du dispositif d\u2019affichage qui re\xE7oit l\u2019action d\u2019un pointeur, telle que la zone interactive d\u2019un composant d\u2019interface utilisateur\nNote : Si deux cibles ou plus se chevauchent, la zone de chevauchement ne devrait pas \xEAtre incluse dans la mesure de la taille de la cible, sauf si les cibles qui se chevauchent ex\xE9cutent la m\xEAme action ou ouvrent la m\xEAme page."
|
|
1935
|
+
},
|
|
1936
|
+
blinking: {
|
|
1937
|
+
title: "clignotement",
|
|
1938
|
+
body: "alternance entre deux \xE9tats visuels d\u2019une fa\xE7on qui veut attirer l\u2019attention\nNote : Voir aussi flash. Il est possible que quelque chose soit suffisamment gros et clignote de fa\xE7on suffisamment lumineuse \xE0 la fr\xE9quence appropri\xE9e pour \xEAtre aussi consid\xE9r\xE9 comme un flash."
|
|
1939
|
+
},
|
|
1940
|
+
"accessibility-supported": {
|
|
1941
|
+
title: "compatible avec l\u2019accessibilit\xE9",
|
|
1942
|
+
body: "compatible avec les technologies d\u2019assistance des utilisateurs ainsi qu\u2019avec les fonctions d\u2019accessibilit\xE9 des navigateurs et des autres agents utilisateurs\nPour que l\u2019utilisation d\u2019une technologie Web (ou d\u2019une fonctionnalit\xE9 d\u2019une technologie) soit consid\xE9r\xE9e comme compatible avec l\u2019accessibilit\xE9, les conditions 1 et 2 doivent toutes deux \xEAtre respect\xE9es pour une technologie Web (ou pour une fonctionnalit\xE9 d\u2019une technologie) :\n\u2022\nLa fa\xE7on dont la technologie Web est utilis\xE9e doit \xEAtre compatible avec les technologies d\u2019assistance des utilisateurs. Cela signifie que la fa\xE7on dont la technologie est utilis\xE9e a \xE9t\xE9 test\xE9e dans une perspective d\u2019interop\xE9rabilit\xE9 avec des utilisateurs des technologies d\u2019assistance dans la ou les langues du contenu ;\nET\n\u2022\nLa technologie Web doit fonctionner avec des agents utilisateurs qui sont compatibles avec l\u2019accessibilit\xE9 et qui sont \xE0 la disposition des utilisateurs. Cela signifie qu\u2019au moins une des quatre affirmations suivantes est vraie :\n\u2022\nLa technologie fonctionne de fa\xE7on native dans des agents utilisateurs largement distribu\xE9s qui sont eux-m\xEAmes compatibles avec l\u2019accessibilit\xE9 (comme HTML et CSS) ;\nOU\n\u2022\nLa technologie fonctionne avec un module d\u2019extension largement distribu\xE9 et qui est lui-m\xEAme compatible avec l\u2019accessibilit\xE9 ;\nOU\n\u2022\nLe contenu est disponible dans un environnement ferm\xE9 comme le r\xE9seau d\u2019une universit\xE9 ou d\u2019une entreprise o\xF9 l\u2019agent utilisateur requis par la technologie et utilis\xE9 par l\u2019organisation est lui-m\xEAme compatible avec l\u2019accessibilit\xE9 ;\nOU\n\u2022\nLes agents utilisateurs avec lesquels fonctionne la technologie sont compatibles avec l\u2019accessibilit\xE9 et sont disponibles en t\xE9l\xE9chargement ou \xE0 l\u2019achat d\u2019une fa\xE7on qui :\n\u2022 ne co\xFBte pas plus cher \xE0 une personne handicap\xE9e qu\u2019\xE0 une personne sans limitations fonctionnelles et\n\u2022 est aussi facile \xE0 trouver et \xE0 obtenir par une personne handicap\xE9e qu\u2019elle l\u2019est pour une personne sans limitations fonctionnelles.\nNote : Le groupe de travail sur les r\xE8gles d\u2019accessibilit\xE9 (AG WG) et le W3C ne pr\xE9cisent pas quel niveau de compatibilit\xE9 avec les technologies d\u2019assistance une technologie Web particuli\xE8re doit avoir pour \xEAtre consid\xE9r\xE9e comme compatible avec l\u2019accessibilit\xE9. Voir le niveau de compatibilit\xE9 avec les technologies d\u2019assistance n\xE9cessaire \xE0 la \xAB compatibilit\xE9 avec l\u2019accessibilit\xE9 \xBB (en anglais).\nNote : Les technologies Web peuvent \xEAtre utilis\xE9es d\u2019une mani\xE8re qui n\u2019est pas compatible avec l\u2019accessibilit\xE9 tant que l\u2019utilisation du contenu n\u2019en d\xE9pend pas et que la page dans son ensemble satisfait aux exigences de conformit\xE9, incluant l\u2019exigence de conformit\xE9 4 et l\u2019exigence de conformit\xE9 5.\nNote : Quand une technologie Web est utilis\xE9e d\u2019une mani\xE8re qui est \xAB compatible avec l\u2019accessibilit\xE9 \xBB, cela n\u2019implique pas que toute la technologie ou que tous les usages de cette technologie sont compatibles. La plupart des technologies, y compris HTML, comportent une fonction ou un usage qui n\u2019est pas compatible. Les pages sont conformes aux WCAG seulement si les usages de la technologie qui sont compatibles avec l\u2019accessibilit\xE9 sont les seuls dont d\xE9pend l\u2019utilisation du contenu et que ces usages permettent de satisfaire aux exigences des WCAG.\nNote : Lorsqu\u2019une technologie Web est cit\xE9e et qu\u2019elle se pr\xE9sente en plusieurs versions, la ou les versions compatibles devraient \xEAtre sp\xE9cifi\xE9es.\nNote : Pour les auteurs, une fa\xE7on de rep\xE9rer les usages d\u2019une technologie qui sont compatibles avec l\u2019accessibilit\xE9 consisterait \xE0 consulter la compilation des usages qui sont document\xE9s comme compatibles avec l\u2019accessibilit\xE9. Voir Comprendre les usages des technologies compatibles avec l\u2019accessibilit\xE9 (en anglais). Les auteurs, les soci\xE9t\xE9s, les vendeurs de technologies ou n\u2019importe qui d\u2019autre peuvent documenter les usages des technologies qui sont compatibles avec l\u2019accessibilit\xE9. Toutefois, tous les usages des technologies document\xE9s devraient satisfaire \xE0 la d\xE9finition des technologies Web compatibles avec l\u2019accessibilit\xE9 telle qu\u2019elle est \xE9nonc\xE9e ci-dessus."
|
|
1943
|
+
},
|
|
1944
|
+
"user-interface-components": {
|
|
1945
|
+
title: "composant d\u2019interface utilisateur",
|
|
1946
|
+
body: "partie du contenu qui est per\xE7ue par les utilisateurs comme un \xE9l\xE9ment de contr\xF4le unique pour une fonction distincte\nNote : Plusieurs composants d\u2019interface utilisateur peuvent \xEAtre impl\xE9ment\xE9s au sein d\u2019un seul programme. La notion de composant n\u2019est pas li\xE9e ici aux techniques de programmation, mais plut\xF4t \xE0 ce que les utilisateurs per\xE7oivent comme des \xE9l\xE9ments de contr\xF4le distincts.\nNote : Les composants d\u2019interface utilisateur incluent les \xE9l\xE9ments de formulaire et les liens aussi bien que des composants g\xE9n\xE9r\xE9s par scripts.\nNote : Les termes \xAB composant \xBB ou \xAB composant d\u2019interface utilisateur \xBB sont aussi parfois d\xE9sign\xE9s par \xAB \xE9l\xE9ment d\u2019interface utilisateur \xBB.\nExemple\nUn microprogramme (applet) dispose d\u2019un \xAB \xE9l\xE9ment de contr\xF4le \xBB permettant de se d\xE9placer dans le contenu ligne par ligne, page par page ou au hasard. Puisque chacune de ces fonctions devrait avoir un nom et fonctionner ind\xE9pendamment, elles constitueraient chacune un \xAB composant d\u2019interface utilisateur \xBB."
|
|
1947
|
+
},
|
|
1948
|
+
conform: {
|
|
1949
|
+
title: "conformit\xE9",
|
|
1950
|
+
body: "satisfaire \xE0 toutes les exigences d\u2019une norme ou d\u2019un standard donn\xE9, d\u2019une r\xE8gle ou d\u2019une sp\xE9cification"
|
|
1951
|
+
},
|
|
1952
|
+
"supplementary-content": {
|
|
1953
|
+
title: "contenu additionnel",
|
|
1954
|
+
body: "contenu suppl\xE9mentaire illustrant ou clarifiant le contenu primaire\nExemple 1\nLa version audio d\u2019une page Web.\nExemple 2\nL\u2019illustration d\u2019un processus complexe.\nExemple 3\nUn paragraphe r\xE9sumant les principales conclusions et recommandations d\u2019un rapport de recherche."
|
|
1955
|
+
},
|
|
1956
|
+
"non-text-content": {
|
|
1957
|
+
title: "contenu non textuel",
|
|
1958
|
+
body: "tout contenu qui n\u2019est pas une suite de caract\xE8res d\xE9termin\xE9e par un programme informatique ou suite de caract\xE8res sans signification dans aucune langue\nNote : Ceci inclut l\u2019art ASCII (qui est un dessin \xE0 base de caract\xE8res), les \xE9motic\xF4nes, l\u2019\xE9criture \xAB leetspeak \xBB (qui utilise la substitution de caract\xE8res) et les images repr\xE9sentant du texte."
|
|
1959
|
+
},
|
|
1960
|
+
content: {
|
|
1961
|
+
title: "contenu (contenu Web)",
|
|
1962
|
+
body: "information et exp\xE9rience sensorielle \xE0 communiquer \xE0 l\u2019utilisateur au moyen d\u2019un agent utilisateur, y compris le code ou le balisage qui d\xE9finit la structure, la pr\xE9sentation et les interactions du contenu"
|
|
1963
|
+
},
|
|
1964
|
+
"programmatically-determined-link-context": {
|
|
1965
|
+
title: "contexte du lien d\xE9termin\xE9 par un programme informatique",
|
|
1966
|
+
body: "information suppl\xE9mentaire qui peut \xEAtre d\xE9termin\xE9e par un programme informatique \xE0 partir des relations avec un lien, combin\xE9e avec le texte du lien et pr\xE9sent\xE9e aux utilisateurs sous diff\xE9rentes formes\nExemple\nEn HTML, l\u2019information qui est d\xE9termin\xE9e par un programme informatique \xE0 partir d\u2019un lien en fran\xE7ais, y compris le texte qui est dans le m\xEAme paragraphe, la m\xEAme liste ou la m\xEAme cellule de tableau que le lien, ou une cellule d\u2019en-t\xEAte de tableau associ\xE9e avec la cellule contenant le lien.\nNote :\nPuisque les lecteurs d\u2019\xE9cran interpr\xE8tent la ponctuation, ils peuvent aussi fournir le contexte de la phrase en cours, lorsque le focus est sur le lien contenu dans cette phrase."
|
|
1967
|
+
},
|
|
1968
|
+
"user-controllable": {
|
|
1969
|
+
title: "contr\xF4lable par l\u2019utilisateur",
|
|
1970
|
+
body: "donn\xE9es auxquelles les utilisateurs ont acc\xE8s\nNote : Ceci ne concerne pas les journaux de connexions (logs) Internet et les donn\xE9es de supervision des moteurs de recherche.\nExemple\nLes champs nom et adresse d\u2019un compte utilisateur."
|
|
1971
|
+
},
|
|
1972
|
+
"on-a-full-screen-window": {
|
|
1973
|
+
title: "dans une fen\xEAtre plein \xE9cran",
|
|
1974
|
+
body: "sur les \xE9crans d\u2019ordinateur de bureau ou portable de taille courante dont l\u2019espace de restitution est maximis\xE9\nNote : Du fait que les gens gardent leurs ordinateurs pendant plusieurs ann\xE9es, il est conseill\xE9 de ne pas se baser sur les derni\xE8res r\xE9solutions d\u2019\xE9crans des ordinateurs de bureau ou portable, mais de prendre en consid\xE9ration la plus repr\xE9sentative des r\xE9solutions d\u2019\xE9crans durant une p\xE9riode de plusieurs ann\xE9es pr\xE9c\xE9dant cette \xE9valuation."
|
|
1975
|
+
},
|
|
1976
|
+
"programmatically-set": {
|
|
1977
|
+
title: "d\xE9fini par programmation",
|
|
1978
|
+
body: "d\xE9fini par un logiciel utilisant des m\xE9thodes qui fonctionnent avec les agents utilisateurs, y compris les technologies d\u2019assistance"
|
|
1979
|
+
},
|
|
1980
|
+
"relied-upon": {
|
|
1981
|
+
title: "d\xE9pendre",
|
|
1982
|
+
body: "(technologies)\nle contenu ne serait pas conforme si cette technologie est inactiv\xE9e ou si elle n\u2019est pas compatible"
|
|
1983
|
+
},
|
|
1984
|
+
"programmatically-determinable": {
|
|
1985
|
+
title: "d\xE9termin\xE9 (d\xE9terminable) par un programme informatique",
|
|
1986
|
+
body: "d\xE9termin\xE9 par un programme \xE0 partir de donn\xE9es fournies par l\u2019auteur d\u2019une mani\xE8re qui permet aux agents utilisateurs, y compris les technologies d\u2019assistance, d\u2019extraire et de pr\xE9senter cette information aux utilisateurs sous diff\xE9rentes formes\nExemple 1\nD\xE9termin\xE9 dans un langage de balisage \xE0 partir d\u2019\xE9l\xE9ments et d\u2019attributs auxquels on acc\xE8de gr\xE2ce aux technologies d\u2019assistance couramment disponibles.\nExemple 2\nD\xE9termin\xE9 gr\xE2ce \xE0 des structures de donn\xE9es sp\xE9cifiques d\u2019une technologie pour un langage non-balis\xE9 et expos\xE9e aux technologies d\u2019assistance via une API d\u2019accessibilit\xE9 aux technologies d\u2019assistance couramment disponibles."
|
|
1987
|
+
},
|
|
1988
|
+
live: {
|
|
1989
|
+
title: "en direct",
|
|
1990
|
+
body: "information capt\xE9e depuis un \xE9v\xE9nement du monde r\xE9el et transmise \xE0 un r\xE9cepteur sans autre d\xE9lai que celui de la diffusion\nNote : Le d\xE9lai de diffusion est un court d\xE9lai souvent automatis\xE9, utilis\xE9 par exemple pour permettre aux diffuseurs de mettre en liste d\u2019attente ou de censurer le flux sonore (ou vid\xE9o), mais insuffisant pour permettre un montage significatif.\nNote : Si l\u2019information est totalement g\xE9n\xE9r\xE9e par ordinateur il ne s\u2019agit pas d\u2019information en direct."
|
|
1991
|
+
},
|
|
1992
|
+
"legal-commitments": {
|
|
1993
|
+
title: "engagements juridiques",
|
|
1994
|
+
body: "transactions par lesquelles la personne contracte une obligation ou re\xE7oit un b\xE9n\xE9fice de nature juridique\nExemple\nUn contrat de mariage, un \xE9change d\u2019actions (financier et juridique), un legs, un pr\xEAt, une adoption, un enr\xF4lement dans l\u2019arm\xE9e, un contrat de tout type, etc."
|
|
1995
|
+
},
|
|
1996
|
+
enclose: {
|
|
1997
|
+
title: "englobe",
|
|
1998
|
+
body: "d\xE9limite ou entoure compl\xE8tement"
|
|
1999
|
+
},
|
|
2000
|
+
"primary-education": {
|
|
2001
|
+
title: "enseignement primaire",
|
|
2002
|
+
body: "p\xE9riode de six ans qui commence entre l\u2019\xE2ge de 5 et 7 ans, sans forc\xE9ment d\u2019ant\xE9c\xE9dents d\u2019\xE9ducation\nNote : Cette d\xE9finition se fonde sur la norme de Classification internationale type de l\u2019\xE9ducation de l\u2019[UNESCO]."
|
|
2003
|
+
},
|
|
2004
|
+
"set-of-web-pages": {
|
|
2005
|
+
title: "ensemble de pages Web",
|
|
2006
|
+
body: "groupe de pages Web partageant un objectif commun et cr\xE9\xE9es par le m\xEAme auteur, groupe ou organisation\nExemple\nCela inclut, par exemple :\n\u2022 une publication r\xE9partie sur plusieurs pages Web et dans laquelle chaque page contient un chapitre ou une autre section importante de l\u2019ouvrage. La publication constitue une seule unit\xE9 logique, contigu\xEB, et contient des \xE9l\xE9ments de navigation qui permettent d\u2019acc\xE9der \xE0 l\u2019ensemble des pages.\n\u2022 un site web de commerce \xE9lectronique pr\xE9sente des produits dans un ensemble de pages Web qui partagent toutes la m\xEAme navigation et la m\xEAme identification. Toutefois, lors du processus de paiement, le mod\xE8le change ; la navigation et d\u2019autres \xE9l\xE9ments sont retir\xE9s, de sorte que les pages de ce processus sont fonctionnellement et visuellement diff\xE9rentes. Les pages de paiement ne font pas partie de l\u2019ensemble des pages de produits.\n\u2022 un blog sur un sous-domaine (par exemple blog.example.com) dont la navigation est diff\xE9rente et dont les contenus sont produits par des auteurs distincts des pages du domaine principal (example.com).\nNote : Diff\xE9rentes versions linguistiques seraient consid\xE9r\xE9es comme des ensembles de pages Web distincts."
|
|
2007
|
+
},
|
|
2008
|
+
"pointer-inputs": {
|
|
2009
|
+
title: "entr\xE9e de pointeur",
|
|
2010
|
+
body: "entr\xE9e effectu\xE9e par un dispositif pouvant cibler une coordonn\xE9e sp\xE9cifique (ou un ensemble de coordonn\xE9es) sur un \xE9cran, tel qu\u2019une souris, un stylet ou un contact tactile\nNote : Voir la d\xE9finition de \xAB pointeur \xBB dans Pointer Events (en anglais) [pointerevents]."
|
|
2011
|
+
},
|
|
2012
|
+
"text-alternative": {
|
|
2013
|
+
title: "\xE9quivalent textuel",
|
|
2014
|
+
body: "texte associ\xE9 par programmation \xE0 un contenu non textuel ou dont il est fait mention depuis un texte associ\xE9 par programmation \xE0 un contenu non textuel. Un texte associ\xE9 par programmation est un texte dont l\u2019emplacement peut \xEAtre d\xE9termin\xE9 par programmation depuis le contenu non textuel.\nExemple\nL\u2019image d\u2019un graphique est d\xE9crite textuellement dans le paragraphe suivant le graphique. Le bref \xE9quivalent textuel du graphique indique que la description suit celui-ci.\nNote : Se r\xE9f\xE9rer \xE0 Comprendre les \xE9quivalents textuels (en anglais) pour plus d\u2019informations."
|
|
2015
|
+
},
|
|
2016
|
+
"input-error": {
|
|
2017
|
+
title: "erreur de saisie",
|
|
2018
|
+
body: "information fournie par l\u2019utilisateur qui n\u2019est pas accept\xE9e\nNote :\nCela inclut :\n\u2022 L\u2019information qui est demand\xE9e par la page Web mais oubli\xE9e par l\u2019utilisateur.\n\u2022 L\u2019information qui est fournie par l\u2019utilisateur mais qui ne correspond pas au format ou aux valeurs des donn\xE9es attendus."
|
|
2019
|
+
},
|
|
2020
|
+
viewport: {
|
|
2021
|
+
title: "espace de restitution",
|
|
2022
|
+
body: "objet au sein duquel l\u2019agent utilisateur pr\xE9sente du contenu\nNote : L\u2019agent utilisateur pr\xE9sente le contenu au travers d\u2019un ou plusieurs espaces de restitution. Les espaces de restitution peuvent \xEAtre des fen\xEAtres, des cadres, des haut-parleurs et des loupes virtuelles. Un espace de restitution peut contenir lui-m\xEAme un autre espace de restitution (par exemple, des cadres imbriqu\xE9s). Les composants d\u2019interface cr\xE9\xE9s par l\u2019agent utilisateur, tels que des invites de commandes, des menus et des alertes ne sont pas des espaces de restitution.\nNote : Cette d\xE9finition est fond\xE9e sur le Glossaire des r\xE8gles pour l\u2019accessibilit\xE9 des agents utilisateurs 1.0 (en anglais) [UAAG10]."
|
|
2023
|
+
},
|
|
2024
|
+
essential: {
|
|
2025
|
+
title: "essentiel",
|
|
2026
|
+
body: "(essentielle)\n\xE9l\xE9ment qui changerait fondamentalement les informations ou les fonctionnalit\xE9s du contenu s\u2019il \xE9tait supprim\xE9 et informations et fonctionnalit\xE9s qui ne pourraient \xEAtre restitu\xE9es autrement d\u2019une mani\xE8re conforme"
|
|
2027
|
+
},
|
|
2028
|
+
states: {
|
|
2029
|
+
title: "\xE9tat",
|
|
2030
|
+
body: "propri\xE9t\xE9 dynamique repr\xE9sentant les caract\xE9ristiques d\u2019un composant d\u2019interface utilisateur qui peut changer en r\xE9ponse \xE0 une action de l\u2019utilisateur ou \xE0 des processus automatis\xE9s\nLes \xE9tats n\u2019affectent pas la nature du composant, mais repr\xE9sentent des donn\xE9es associ\xE9es au composant ou aux possibilit\xE9s d\u2019interaction par l\u2019utilisateur. Il s\u2019agit par exemple des \xE9tats focus, survol\xE9, s\xE9lectionn\xE9, press\xE9, coch\xE9, visit\xE9/non visit\xE9, et d\xE9velopp\xE9/r\xE9duit."
|
|
2031
|
+
},
|
|
2032
|
+
labels: {
|
|
2033
|
+
title: "\xE9tiquette",
|
|
2034
|
+
body: "texte ou autre composant avec un \xE9quivalent textuel qui est restitu\xE9 \xE0 l\u2019utilisateur pour permettre d\u2019identifier un composant dans un contenu Web.\nNote : Une \xE9tiquette est pr\xE9sent\xE9e \xE0 tous les utilisateurs alors que le nom peut \xEAtre masqu\xE9 et seulement restitu\xE9 par une technologie d\u2019assistance. Dans de nombreux cas (mais pas tous) le nom et l\u2019\xE9tiquette sont identiques.\nNote : Le terme \xE9tiquette n\u2019est pas limit\xE9 \xE0 l\u2019\xE9l\xE9ment label en HTML."
|
|
2035
|
+
},
|
|
2036
|
+
"up-event": {
|
|
2037
|
+
title: "\xE9v\xE9nement ascendant (up-event)",
|
|
2038
|
+
body: "\xE9v\xE9nement de la plateforme qui se produit lorsque le m\xE9canisme de d\xE9clenchement d\u2019un pointeur est rel\xE2ch\xE9\nL\u2019\xE9v\xE9nement ascendant peut avoir des noms diff\xE9rents selon les plateformes, comme \xAB touchend \xBB ou \xAB mouseup \xBB."
|
|
2039
|
+
},
|
|
2040
|
+
"down-event": {
|
|
2041
|
+
title: "\xE9v\xE9nement descendant (down-event)",
|
|
2042
|
+
body: "\xE9v\xE9nement de la plateforme qui se produit lorsque le m\xE9canisme de d\xE9clenchement d\u2019un pointeur est enfonc\xE9\nL\u2019\xE9v\xE9nement descendant peut avoir des noms diff\xE9rents selon les plateformes, comme \xAB touchstart \xBB ou \xAB mousedown \xBB."
|
|
2043
|
+
},
|
|
2044
|
+
"real-time-events": {
|
|
2045
|
+
title: "\xE9v\xE9nement en temps r\xE9el",
|
|
2046
|
+
body: "\xE9v\xE9nement qui a) se produit en m\xEAme temps que la visualisation et b) n\u2019est pas enti\xE8rement g\xE9n\xE9r\xE9 par le contenu\nExemple 1\nUne diffusion Web d\u2019une repr\xE9sentation en direct (qui se produit en m\xEAme temps que la visualisation et qui n\u2019est pas pr\xE9-enregistr\xE9e).\nExemple 2\nDes ench\xE8res en ligne avec des gens qui ench\xE9rissent (avec une visualisation en direct).\nExemple 3\nDes humains interagissant dans un monde virtuel gr\xE2ce \xE0 des avatars (qui ne sont pas enti\xE8rement g\xE9n\xE9r\xE9s par le contenu et qui se produisent en m\xEAme temps que la visualisation)."
|
|
2047
|
+
},
|
|
2048
|
+
"specific-sensory-experience": {
|
|
2049
|
+
title: "exp\xE9rience sensorielle sp\xE9cifique",
|
|
2050
|
+
body: "une exp\xE9rience sensorielle qui n\u2019est pas purement d\xE9corative et dont l\u2019objectif premier n\u2019est pas de transmettre une information importante ou d\u2019accomplir une fonction\nExemple\nOn compte parmi les exemples un morceau de fl\xFBte solo, des \u0153uvres d\u2019art visuel, etc."
|
|
2051
|
+
},
|
|
2052
|
+
idioms: {
|
|
2053
|
+
title: "expression idiomatique",
|
|
2054
|
+
body: "phrase dont le sens ne peut \xEAtre d\xE9duit du sens des mots qui la composent et dont les mots sp\xE9cifiques ne peuvent \xEAtre chang\xE9s sans en perdre le sens\nNote : Les expressions idiomatiques ne peuvent \xEAtre traduites litt\xE9ralement sans perdre leur sens (culturel ou linguistique).\nExemple 1\nEn anglais, \xAB spilling the beans \xBB signifie \xAB r\xE9v\xE9ler un secret \xBB. Cependant, \xAB knocking over the beans \xBB ou \xAB spilling the vegetable \xBB ne signifie pas la m\xEAme chose.\nExemple 2\nEn japonais, la phrase \xAB \u3055\u3058\u3092\u6295\u3052\u308B \xBB se traduit litt\xE9ralement par \xAB il jette une cuill\xE8re \xBB mais cela signifie qu\u2019il n\u2019y a rien qu\u2019il puisse faire et que finalement il abandonne.\nExemple 3\nEn n\xE9erlandais, \xAB Hij ging met de kippen op stok \xBB se traduit litt\xE9ralement par \xAB il est all\xE9 r\xF4tir avec les poulets \xBB mais cela signifie qu\u2019il est all\xE9 au lit t\xF4t."
|
|
2055
|
+
},
|
|
2056
|
+
flashes: {
|
|
2057
|
+
title: "flash",
|
|
2058
|
+
body: "alternance de luminance relative qui peut causer des crises chez certaines personnes si leur taille est suffisamment importante dans une gamme de fr\xE9quences sp\xE9cifiques\nNote : Voir seuil de flash g\xE9n\xE9rique et seuil de flash rouge pour plus d\u2019informations sur les types de flashs qui ne sont pas autoris\xE9s.\nNote : Voir aussi clignotement."
|
|
2059
|
+
},
|
|
2060
|
+
"purpose-of-each-link": {
|
|
2061
|
+
title: "fonction du lien",
|
|
2062
|
+
body: "nature d\u2019un r\xE9sultat obtenu par l\u2019activation d\u2019un lien"
|
|
2063
|
+
},
|
|
2064
|
+
functionality: {
|
|
2065
|
+
title: "fonctionnalit\xE9",
|
|
2066
|
+
body: "processus et r\xE9sultats atteignables par une action de l\u2019utilisateur"
|
|
2067
|
+
},
|
|
2068
|
+
"same-functionality": {
|
|
2069
|
+
title: "fonctionnalit\xE9 similaire",
|
|
2070
|
+
body: "produit le m\xEAme r\xE9sultat \xE0 l\u2019utilisation\nExemple\nUn bouton \xAB rechercher \xBB sur une page Web et un bouton \xAB trouver \xBB sur une autre peuvent tous les deux proposer un champ pour saisir un terme et lister les sujets pr\xE9sents dans le site et pertinents par rapport au terme soumis. Dans ce cas, ils offrent la m\xEAme fonctionnalit\xE9 mais ne sont pas nomm\xE9s \xE0 l\u2019identique."
|
|
2071
|
+
},
|
|
2072
|
+
"user-inactivity": {
|
|
2073
|
+
title: "inactivit\xE9 de l\u2019utilisateur",
|
|
2074
|
+
body: "intervalle de temps continu pendant lequel l\u2019utilisateur n\u2019effectue aucune action\nLa m\xE9thode de d\xE9tection sera d\xE9termin\xE9e par le site Web ou l\u2019application."
|
|
2075
|
+
},
|
|
2076
|
+
"focus-indicator": {
|
|
2077
|
+
title: "indicateur de focus",
|
|
2078
|
+
body: "pixels qui sont modifi\xE9s pour indiquer visuellement qu\u2019un composant d\u2019interface utilisateur est dans un \xE9tat focalis\xE9"
|
|
2079
|
+
},
|
|
2080
|
+
informative: {
|
|
2081
|
+
title: "informatif, informative",
|
|
2082
|
+
body: "dans un but d\u2019informations compl\xE9mentaires et non exig\xE9 pour la conformit\xE9\nNote : Le contenu exig\xE9 pour la conformit\xE9 est indiqu\xE9 comme \xAB normatif \xBB."
|
|
2083
|
+
},
|
|
2084
|
+
"keyboard-interface": {
|
|
2085
|
+
title: "interface clavier",
|
|
2086
|
+
body: "interface utilis\xE9e par un logiciel pour obtenir une saisie au clavier\nNote :\nUne interface clavier permet aux utilisateurs de fournir aux programmes une saisie au clavier m\xEAme si la technologie native ne comporte pas de clavier.\nExemple\nUn assistant num\xE9rique personnel (PDA) \xE0 \xE9cran tactile poss\xE8de une interface clavier int\xE9gr\xE9e \xE0 son syst\xE8me d\u2019exploitation et un connecteur pour des claviers externes. Les applications dans le PDA peuvent utiliser l\u2019interface pour obtenir une saisie au clavier externe ou par d\u2019autres applications qui simulent une sortie clavier comme les interpr\xE9teurs d\u2019\xE9criture manuscrite ou les applications de transcription vocale en texte avec des fonctionnalit\xE9s \xAB d\u2019\xE9mulation clavier \xBB.\nNote :\nL\u2019utilisation d\u2019une application (ou de parties d\u2019une application) \xE0 travers un pointeur souris dirig\xE9 au clavier, comme MouseKeys, ne constitue pas une op\xE9ration r\xE9alis\xE9e au travers d\u2019une interface clavier car l\u2019utilisation du programme passe par l\u2019interface de pointage et non pas par l\u2019interface clavier."
|
|
2087
|
+
},
|
|
2088
|
+
"sign-language-interpretation": {
|
|
2089
|
+
title: "interpr\xE9tation en langue des signes",
|
|
2090
|
+
body: "traduction d\u2019une langue, g\xE9n\xE9ralement parl\xE9e, en langue des signes\nNote : Les v\xE9ritables langues des signes sont des langues ind\xE9pendantes qui ne sont pas attach\xE9es \xE0 la langue parl\xE9e de la m\xEAme r\xE9gion ou du m\xEAme pays."
|
|
2091
|
+
},
|
|
2092
|
+
jargon: {
|
|
2093
|
+
title: "jargon",
|
|
2094
|
+
body: "termes utilis\xE9s par les personnes d\u2019une fa\xE7on particuli\xE8re dans un domaine particulier\nExemple\nLes termes \xAB touches r\xE9manentes \xBB sont du jargon du domaine des technologies d\u2019assistance."
|
|
2095
|
+
},
|
|
2096
|
+
"human-language-s": {
|
|
2097
|
+
title: "langue",
|
|
2098
|
+
body: "langue qui est parl\xE9e, \xE9crite ou sign\xE9e (\xE0 l\u2019aide des signes visuels ou tactiles) pour communiquer avec les humains\nNote : Voir aussi langue des signes."
|
|
2099
|
+
},
|
|
2100
|
+
"sign-language": {
|
|
2101
|
+
title: "langue des signes",
|
|
2102
|
+
body: "un langage employant des combinaisons de mouvements des mains et des bras, des expressions faciales ou des positions corporelles pour transmettre du sens"
|
|
2103
|
+
},
|
|
2104
|
+
"relative-luminance": {
|
|
2105
|
+
title: "luminance relative",
|
|
2106
|
+
body: 'luminance relative d\u2019un quelconque point de l\u2019espace colorim\xE9trique normalis\xE9 \xE0 0 pour le noir le plus fonc\xE9 et \xE0 1 pour le blanc le plus clair\nNote :\nPour l\u2019espace colorim\xE9trique de couleur sRGB, la luminance relative d\u2019une couleur est d\xE9finie par L = 0,2126 * R + 0,7152 * G + 0,0722 * B o\xF9 R, G et B sont d\xE9finis par :\n\u2022 si RsRGB <= 0,04045 alors R = RsRGB/12,92 sinon R = ((RsRGB+0,055)/1,055) ^ 2,4\n\u2022 si GsRGB <= 0,04045 alors G = GsRGB/12,92 sinon G = ((GsRGB+0,055)/1,055) ^ 2,4\n\u2022 si BsRGB <= 0,04045 alors B = BsRGB/12,92 sinon B = ((BsRGB+0,055)/1,055) ^ 2,4\net RsRGB, GsRGB, et BsRGB sont d\xE9finis par :\n\u2022 RsRGB = R8bit/255\n\u2022 GsRGB = G8bit/255\n\u2022 BsRGB = B8bit/255\nLe caract\xE8re "^" est l\u2019op\xE9rateur exponentiel. (formule tir\xE9e de [SRGB]).\nNote : Avant mai 2021, la valeur de 0,04045 dans la d\xE9finition \xE9tait diff\xE9rente (0,03928). Elle provenait d\u2019une version pr\xE9c\xE9dente de la sp\xE9cification et a \xE9t\xE9 mise \xE0 jour. Cela n\u2019a aucun effet pratique sur les calculs dans le contexte de ces r\xE8gles.\nNote : La plupart des syst\xE8mes utilis\xE9s aujourd\u2019hui pour afficher le contenu Web adoptent l\u2019encodage sRGB. \xC0 moins que l\u2019on sache qu\u2019un autre espace colorim\xE9trique va \xEAtre utilis\xE9 pour traiter et afficher le contenu, les auteurs devraient l\u2019\xE9valuer en utilisant l\u2019espace colorim\xE9trique sRGB. Si l\u2019on utilise d\u2019autres espaces colorim\xE9triques, voir Comprendre le crit\xE8re de succ\xE8s 1.4.3 (en anglais).\nNote : Si un tramage est effectu\xE9 apr\xE8s l\u2019affichage, alors la valeur source de la couleur est utilis\xE9e. Pour les couleurs tram\xE9es \xE0 la source, les valeurs moyennes des couleurs qui sont tram\xE9es devraient \xEAtre utilis\xE9es (R moyen, G moyen, B moyen).\nNote : Il existe des outils qui effectuent automatiquement les calculs lors des tests de contraste et de flash.\nNote : Une page distincte donnant la d\xE9finition de la luminance relative en utilisant MathML pour afficher les formules est disponible.'
|
|
2107
|
+
},
|
|
2108
|
+
mechanism: {
|
|
2109
|
+
title: "m\xE9canisme",
|
|
2110
|
+
body: "processus ou technique pour obtenir un r\xE9sultat\nNote : Le m\xE9canisme peut \xEAtre explicitement fourni par le contenu ou d\xE9pendre de la plateforme ou de l\u2019agent utilisateur, y compris les technologies d\u2019assistance.\nNote : Le m\xE9canisme doit satisfaire \xE0 tous les crit\xE8res de succ\xE8s (d\u2019un niveau donn\xE9) pour d\xE9clarer un niveau de conformit\xE9."
|
|
2111
|
+
},
|
|
2112
|
+
"media-alternative-for-text": {
|
|
2113
|
+
title: "m\xE9dia de remplacement pour un texte",
|
|
2114
|
+
body: "m\xE9dia qui ne donne pas plus d\u2019information que ce que donne le texte (directement ou via un \xE9quivalent textuel)\nNote : Une version de remplacement pour un texte est fournie \xE0 ceux qui b\xE9n\xE9ficient de repr\xE9sentations \xE9quivalentes du texte. Les versions de remplacement de texte peuvent n\u2019\xEAtre que seulement audio, que seulement vid\xE9o (y compris la vid\xE9o en langue des signes) ou audio-vid\xE9o."
|
|
2115
|
+
},
|
|
2116
|
+
"synchronized-media": {
|
|
2117
|
+
title: "m\xE9dia synchronis\xE9",
|
|
2118
|
+
body: "flux audio ou vid\xE9o synchronis\xE9 avec un autre format pour pr\xE9senter de l\u2019information et/ou comportant des composants temporels interactifs, \xE0 moins que le m\xE9dia soit un m\xE9dia de remplacement pour un texte clairement identifi\xE9 comme tel"
|
|
2119
|
+
},
|
|
2120
|
+
"same-relative-order": {
|
|
2121
|
+
title: "m\xEAme ordre relatif",
|
|
2122
|
+
body: "m\xEAme position relativement aux autres \xE9l\xE9ments\nNote : Plusieurs \xE9l\xE9ments sont consid\xE9r\xE9s \xEAtre dans le m\xEAme ordre relatif m\xEAme si d\u2019autres \xE9l\xE9ments sont ins\xE9r\xE9s ou retir\xE9s de l\u2019ordre original. Par exemple, des menus de navigation extensibles peuvent int\xE9grer un niveau de d\xE9tail additionnel, une section de navigation secondaire peut \xEAtre ins\xE9r\xE9e dans l\u2019ordre de lecture."
|
|
2123
|
+
},
|
|
2124
|
+
"status-messages": {
|
|
2125
|
+
title: "message d\u2019\xE9tat",
|
|
2126
|
+
body: "changement dans le contenu qui n\u2019est pas un changement de contexte et qui fournit des informations \xE0 l\u2019utilisateur sur le succ\xE8s ou les r\xE9sultats d\u2019une action, sur l\u2019\xE9tat d\u2019attente d\u2019une application, sur la progression d\u2019un processus ou sur l\u2019existence d\u2019erreurs"
|
|
2127
|
+
},
|
|
2128
|
+
pause: {
|
|
2129
|
+
title: "mis en pause",
|
|
2130
|
+
body: "arr\xEAt\xE9 par une action de l\u2019utilisateur et relanc\xE9 seulement sur demande de l\u2019utilisateur"
|
|
2131
|
+
},
|
|
2132
|
+
"dragging-movements": {
|
|
2133
|
+
title: "mouvement de glissement",
|
|
2134
|
+
body: "une action o\xF9 un \xE9l\xE9ment est saisi par le pointeur lors de l\u2019\xE9v\xE9nement descendant (down-event) et pendant laquelle l\u2019\xE9l\xE9ment (ou une repr\xE9sentation de sa position) suit le pointeur jusqu\u2019\xE0 l\u2019\xE9v\xE9nement ascendant (up-event).\nNote : Les \xE9l\xE9ments de liste, de texte et les images sont des exemples d\u2019\xE9l\xE9ments pouvant \xEAtre d\xE9plac\xE9s par glissement."
|
|
2135
|
+
},
|
|
2136
|
+
name: {
|
|
2137
|
+
title: "nom",
|
|
2138
|
+
body: "texte gr\xE2ce auquel un logiciel peut identifier pour l\u2019utilisateur un composant du contenu Web\nNote : Le nom peut \xEAtre cach\xE9 et pr\xE9sent\xE9 seulement aux technologies d\u2019assistance, alors qu\u2019une \xE9tiquette est pr\xE9sent\xE9e \xE0 tous les utilisateurs. Dans de nombreux cas (mais pas dans tous), l\u2019\xE9tiquette et le nom sont identiques.\nNote : Celui-ci n\u2019a pas de lien avec l\u2019attribut HTML name."
|
|
2139
|
+
},
|
|
2140
|
+
normative: {
|
|
2141
|
+
title: "normatif",
|
|
2142
|
+
body: "exig\xE9 pour la conformit\xE9\nNote : Il est possible d\u2019\xEAtre en conformit\xE9 stricte avec ce document de nombreuses mani\xE8res bien d\xE9finies.\nNote : Le contenu identifi\xE9 comme \xAB informatif \xBB ou \xAB non normatif \xBB n\u2019est jamais exig\xE9 pour la conformit\xE9."
|
|
2143
|
+
},
|
|
2144
|
+
"correct-reading-sequence": {
|
|
2145
|
+
title: "ordre de lecture correct",
|
|
2146
|
+
body: "tout ordre s\xE9quentiel o\xF9 les mots et les paragraphes sont pr\xE9sent\xE9s dans un ordre qui ne modifie pas la signification du contenu"
|
|
2147
|
+
},
|
|
2148
|
+
"web-page-s": {
|
|
2149
|
+
title: "page Web",
|
|
2150
|
+
body: "une ressource autonome obtenue depuis un URI unique gr\xE2ce au protocole HTTP, accompagn\xE9e de toutes les autres ressources utilis\xE9es dans la restitution ou con\xE7ues pour \xEAtre restitu\xE9es simultan\xE9ment par un agent utilisateur\nNote : Bien que toutes les \xAB autres ressources \xBB seraient restitu\xE9es avec la ressource primaire, elles ne sont pas n\xE9cessairement restitu\xE9es simultan\xE9ment.\nNote : \xC0 des fins de conformit\xE9 avec ces r\xE8gles, une ressource doit \xEAtre autonome \xE0 l\u2019int\xE9rieur du p\xE9rim\xE8tre de conformit\xE9 pour \xEAtre consid\xE9r\xE9e comme une page Web.\nExemple 1\nUne ressource Web incluant toutes les images et m\xE9dias li\xE9s.\nExemple 2\nUn programme Web de courrier \xE9lectronique (Webmail) d\xE9velopp\xE9 \xE0 l\u2019aide d\u2019AJAX (Asynchronous JavaScript and XML, JavaScript asynchrone et XML). Le programme r\xE9side int\xE9gralement \xE0 l\u2019adresse http://exemple.com/mail, mais comprend une bo\xEEte de r\xE9ception, un carnet d\u2019adresses et un calendrier. Des liens et des boutons permettent d\u2019afficher la bo\xEEte de r\xE9ception, les contacts ou le calendrier, mais ne changent pas globalement l\u2019URI de la page.\nExemple 3\nUn site portail personnalisable, dans lequel les utilisateurs peuvent choisir le contenu \xE0 afficher \xE0 partir d\u2019un ensemble de modules de contenu.\nExemple 4\nQuand on saisit \xAB http://shopping.exemple.com/ \xBB dans son navigateur, on entre dans un environnement commercial anim\xE9 et interactif dans lequel on se d\xE9place visuellement dans une boutique, retirant les produits directement depuis les rayons pour les placer dans un panier d\u2019achat face \xE0 soi. Cliquer sur un produit d\xE9clenche une d\xE9monstration avec la fiche technique juste \xE0 c\xF4t\xE9. Cela peut \xEAtre un site Web \xE0 page unique ou simplement une page \xE0 l\u2019int\xE9rieur d\u2019un site Web."
|
|
2151
|
+
},
|
|
2152
|
+
"navigated-sequentially": {
|
|
2153
|
+
title: "parcouru de fa\xE7on s\xE9quentielle",
|
|
2154
|
+
body: "parcouru dans l\u2019ordre d\xE9fini par le d\xE9placement du focus (d\u2019un \xE9l\xE9ment \xE0 l\u2019autre) en utilisant une interface clavier"
|
|
2155
|
+
},
|
|
2156
|
+
perimeter: {
|
|
2157
|
+
title: "p\xE9rim\xE8tre",
|
|
2158
|
+
body: "ligne la plus courte entre la ligne continue d\xE9limitant une forme, en excluant les pixels partag\xE9s, et la ligne continue d\xE9limitant sa bo\xEEte de d\xE9limitation minimale\nExemple\nLe calcul de l\u2019aire d\u2019un p\xE9rim\xE8tre de 2 pixels CSS autour d\u2019un rectangle est 4h+4l, o\xF9 h est la hauteur et l est la largeur. Pour un p\xE9rim\xE8tre de 2 pixels CSS autour d\u2019un cercle, il s\u2019agit de 4\u{1D70B}r."
|
|
2159
|
+
},
|
|
2160
|
+
"visually-customized": {
|
|
2161
|
+
title: "personnalis\xE9 visuellement",
|
|
2162
|
+
body: "la police, la taille, la couleur et le fond sont param\xE9trables"
|
|
2163
|
+
},
|
|
2164
|
+
"css-pixels": {
|
|
2165
|
+
title: "pixel CSS",
|
|
2166
|
+
body: "angle visuel d\u2019environ 0,0213 degr\xE9\nUn pixel CSS est l\u2019unit\xE9 de mesure canonique pour toutes les longueurs et mesures en CSS. Cette unit\xE9 est ind\xE9pendante de la densit\xE9 et diff\xE9rente des pixels mat\xE9riels r\xE9els pr\xE9sents sur un \xE9cran. Les agents utilisateurs et les syst\xE8mes d\u2019exploitation devraient garantir qu\u2019un pixel CSS repr\xE9sente la meilleure approximation du pixel de r\xE9f\xE9rence d\xE9fini dans le module CSS Values and Units de niveau 3 (en anglais) [css3-values], qui tient compte des dimensions physiques de l\u2019\xE9cran et de la distance de visualisation suppos\xE9e (facteurs qui ne peuvent \xEAtre d\xE9termin\xE9s par les auteurs de contenu)."
|
|
2167
|
+
},
|
|
2168
|
+
"single-pointer": {
|
|
2169
|
+
title: "pointage \xE0 contact unique",
|
|
2170
|
+
body: "action de pointage qui fonctionne au moyen d\u2019un seul point de contact avec l\u2019\xE9cran, y compris les appuis courts et les simples clics, les doubles appuis et les doubles clics, les appuis longs et les gestes bas\xE9s sur un trac\xE9."
|
|
2171
|
+
},
|
|
2172
|
+
prerecorded: {
|
|
2173
|
+
title: "pr\xE9-enregistr\xE9",
|
|
2174
|
+
body: "information qui n\u2019est pas diffus\xE9e en direct"
|
|
2175
|
+
},
|
|
2176
|
+
"lower-secondary-education-level": {
|
|
2177
|
+
title: "premier cycle de l\u2019enseignement secondaire",
|
|
2178
|
+
body: "les deux ou trois ann\xE9es de scolarit\xE9 qui commencent apr\xE8s six ans environ d\u2019enseignement primaire et qui se terminent apr\xE8s neuf ans environ de scolarisation depuis le d\xE9but de l\u2019enseignement primaire\nNote : Cette d\xE9finition se fonde sur la norme de Classification internationale type de l\u2019\xE9ducation de l\u2019[UNESCO]."
|
|
2179
|
+
},
|
|
2180
|
+
presentation: {
|
|
2181
|
+
title: "pr\xE9sentation",
|
|
2182
|
+
body: "rendu du contenu sous une forme perceptible par l\u2019utilisateur"
|
|
2183
|
+
},
|
|
2184
|
+
processes: {
|
|
2185
|
+
title: "processus",
|
|
2186
|
+
body: "s\xE9rie d\u2019actions de l\u2019utilisateur dont l\u2019encha\xEEnement est n\xE9cessaire \xE0 l\u2019accomplissement d\u2019une t\xE2che\nExemple 1\nUtilisation r\xE9ussie par l\u2019utilisateur, sur un site de vente, d\u2019un encha\xEEnement de pages Web permettant de voir diff\xE9rents produits, des prix et des offres, de s\xE9lectionner des produits, de soumettre une commande, de fournir les informations d\u2019envoi et de paiement.\nExemple 2\nUne page permettant de cr\xE9er un compte utilisateur n\xE9cessitant l\u2019accomplissement d\u2019un test de Turing avant de pouvoir acc\xE9der \xE0 cette page de formulaire de cr\xE9ation de compte."
|
|
2187
|
+
},
|
|
2188
|
+
"style-properties": {
|
|
2189
|
+
title: "propri\xE9t\xE9 de style",
|
|
2190
|
+
body: "propri\xE9t\xE9 dont la valeur d\xE9termine la pr\xE9sentation (par exemple, la police, la couleur, la taille, l\u2019emplacement, les marges int\xE9rieures (padding), le volume, la prosodie de la synth\xE8se vocale) des \xE9l\xE9ments de contenu lorsqu\u2019ils sont restitu\xE9s (par exemple, \xE0 l\u2019\xE9cran, par un haut-parleur, sur une plage braille) par les agents utilisateurs.\nLes propri\xE9t\xE9s de style peuvent avoir plusieurs origines :\n\u2022 Les styles par d\xE9faut de l\u2019agent utilisateur : les valeurs des propri\xE9t\xE9s de style par d\xE9faut appliqu\xE9es en l\u2019absence de tout style d\u2019auteur ou d\u2019utilisateur. Certaines technologies Web sp\xE9cifient un rendu par d\xE9faut, d\u2019autres non ;\n\u2022 Styles d\u2019auteur : les valeurs des propri\xE9t\xE9s de style qui sont d\xE9finies par l\u2019auteur dans le cadre du contenu (par exemple, les styles en ligne, les feuilles de style de l\u2019auteur) ;\n\u2022 Styles de l\u2019utilisateur : les valeurs des propri\xE9t\xE9s de style qui sont d\xE9finies par l\u2019utilisateur (par exemple, via les param\xE8tres de l\u2019interface de l\u2019agent utilisateur, les feuilles de style de l\u2019utilisateur)."
|
|
2191
|
+
},
|
|
2192
|
+
"pure-decoration": {
|
|
2193
|
+
title: "purement d\xE9coratif",
|
|
2194
|
+
body: "utilis\xE9 seulement dans un but esth\xE9tique, ne fournissant aucune information et n\u2019ayant aucune fonctionnalit\xE9\nNote : Un texte est purement d\xE9coratif si les mots peuvent \xEAtre r\xE9arrang\xE9s ou remplac\xE9s sans changer leur raison d\u2019\xEAtre.\nExemple\nLa page de couverture d\u2019un dictionnaire pr\xE9sente un arri\xE8re-plan estomp\xE9 et constitu\xE9 de mots choisis au hasard."
|
|
2195
|
+
},
|
|
2196
|
+
"keyboard-shortcuts": {
|
|
2197
|
+
title: "raccourci clavier",
|
|
2198
|
+
body: "moyen alternatif pour d\xE9clencher une action par l\u2019appui d\u2019une ou plusieurs touches"
|
|
2199
|
+
},
|
|
2200
|
+
"contrast-ratio": {
|
|
2201
|
+
title: "rapport de contraste",
|
|
2202
|
+
body: "(L1 + 0,05) / (L2 + 0,05), o\xF9\n\u2022 L1 est la luminance relative de la couleur la plus claire et\n\u2022 L2 est la luminance relative de la couleur la plus sombre.\nNote : Le rapport de contraste peut varier de 1 \xE0 21 (commun\xE9ment \xE9crit 1:1, 1 pour 1, \xE0 21:1, 21 pour 1).\nNote : \xC9tant donn\xE9 que les auteurs ne contr\xF4lent pas la configuration de l\u2019utilisateur concernant le rendu du texte (par exemple le lissage de police ou l\u2019anti-cr\xE9nelage), le rapport de contraste du texte peut \xEAtre \xE9valu\xE9 en d\xE9sactivant l\u2019anti-cr\xE9nelage.\nNote : En ce qui concerne les crit\xE8res de succ\xE8s 1.4.3 et 1.4.6, le contraste est mesur\xE9 en tenant compte de l\u2019arri\xE8re-plan sur lequel le texte est normalement affich\xE9. Si aucune couleur d\u2019arri\xE8re-plan n\u2019est sp\xE9cifi\xE9e, il est consid\xE9r\xE9 comme blanc.\nNote : La couleur d\u2019arri\xE8re-plan est la couleur sp\xE9cifi\xE9e du contenu sur lequel le texte est normalement affich\xE9. Il est consid\xE9r\xE9 comme une erreur de ne pas d\xE9finir une couleur d\u2019arri\xE8re-plan lorsque la couleur du texte est sp\xE9cifi\xE9e, parce que la couleur d\u2019arri\xE8re-plan de l\u2019utilisateur est inconnue et ne peut donc pas \xEAtre \xE9valu\xE9e pour v\xE9rifier si le contraste est suffisant. Pour la m\xEAme raison, il est aussi consid\xE9r\xE9 comme une erreur de ne pas d\xE9finir la couleur du texte lorsqu\u2019une couleur d\u2019arri\xE8re-plan est sp\xE9cifi\xE9e.\nNote : Lorsqu\u2019il y a une bordure autour de la lettre, la bordure peut augmenter le contraste et serait utilis\xE9e dans le calcul du contraste entre la lettre et son arri\xE8re-plan. La couleur d\u2019une bordure \xE9troite autour de la lettre serait utilis\xE9e \xE0 la place de la lettre. Une bordure large autour de la lettre qui remplit l\u2019espace dans lequel se d\xE9coupe le d\xE9tail de la lettre agit comme un halo et serait consid\xE9r\xE9e comme un arri\xE8re-plan.\nNote : La conformit\xE9 aux WCAG devrait \xEAtre \xE9valu\xE9e pour les paires de couleurs sp\xE9cifi\xE9es dans le contenu qu\u2019un auteur s\u2019attendrait \xE0 voir appara\xEEtre de fa\xE7on adjacente dans une pr\xE9sentation habituelle. Les auteurs n\u2019ont pas besoin de prendre en consid\xE9ration les pr\xE9sentations inhabituelles comme les changements de couleurs faits par l\u2019agent utilisateur sauf si ces changements sont provoqu\xE9s par le code de l\u2019auteur."
|
|
2203
|
+
},
|
|
2204
|
+
regions: {
|
|
2205
|
+
title: "r\xE9gion",
|
|
2206
|
+
body: "section de contenu perceptible, d\xE9termin\xE9e par un programme informatique\nNote : En HTML, toute zone identifi\xE9e avec un r\xF4le de rep\xE8re (landmark) serait consid\xE9r\xE9e comme une r\xE9gion."
|
|
2207
|
+
},
|
|
2208
|
+
relationships: {
|
|
2209
|
+
title: "relations",
|
|
2210
|
+
body: "associations significatives entre des parties distinctes du contenu"
|
|
2211
|
+
},
|
|
2212
|
+
role: {
|
|
2213
|
+
title: "r\xF4le",
|
|
2214
|
+
body: "texte ou nombre par lequel un logiciel peut identifier la fonction d\u2019un composant dans du contenu Web\nExemple\nUn nombre qui indique si une image sert d\u2019hyperlien, de bouton de commande ou de case \xE0 cocher."
|
|
2215
|
+
},
|
|
2216
|
+
satisfies: {
|
|
2217
|
+
title: "satisfait \xE0 un crit\xE8re de succ\xE8s",
|
|
2218
|
+
body: "le crit\xE8re de succ\xE8s ne se r\xE9v\xE8le pas \xAB faux \xBB lors de l\u2019\xE9valuation de la page"
|
|
2219
|
+
},
|
|
2220
|
+
section: {
|
|
2221
|
+
title: "section",
|
|
2222
|
+
body: "une portion autonome de contenu \xE9crit qui traite d\u2019un ou plusieurs sujets ou id\xE9es li\xE9s entre eux\nNote : Une section peut consister en un ou plusieurs paragraphes et inclure des graphiques, des tableaux, des listes et des sous-sections."
|
|
2223
|
+
},
|
|
2224
|
+
"general-flash-and-red-flash-thresholds": {
|
|
2225
|
+
title: "seuil de flash g\xE9n\xE9rique et seuil de flash rouge",
|
|
2226
|
+
body: "un flash ou une s\xE9quence d\u2019images changeant rapidement est en dessous du seuil de flash (c\u2019est-\xE0-dire que le contenu est conforme) si l\u2019une des conditions suivantes est satisfaite :\n\u2022 il n\u2019y a pas plus de trois flashs g\xE9n\xE9riques et pas plus de trois flashs rouges par seconde ; ou\n\u2022 la surface d\u2019affichage combin\xE9e des flashs simultan\xE9s ne repr\xE9sente pas plus de 0,006 st\xE9radian dans chaque champ visuel de 10 degr\xE9s sur l\u2019\xE9cran (soit 25% de chaque champ visuel de 10 degr\xE9s sur l\u2019\xE9cran) \xE0 une distance habituelle de visualisation\no\xF9 :\n\u2022 un flash g\xE9n\xE9rique est d\xE9fini comme une alternance de luminance relative de 10% ou plus par rapport \xE0 la luminance relative maximum (1.0), o\xF9 la luminance relative de l\u2019image la plus sombre est en dessous de 0,80 et o\xF9 \xAB une alternance \xBB est d\xE9finie comme \xE9tant une augmentation suivie d\u2019une diminution ou une diminution suivie d\u2019une augmentation, et\n\u2022 un flash rouge est d\xE9fini comme toute alternance de transition impliquant un rouge satur\xE9.\nException : Le flash qui suit un mod\xE8le pr\xE9cis et \xE9quilibr\xE9 comme du bruit blanc ou un mod\xE8le de damier altern\xE9 avec des \xAB carr\xE9s \xBB dont les c\xF4t\xE9s font moins de 0,1 degr\xE9 (du champ visuel \xE0 une distance habituelle de visualisation) ne d\xE9passe pas le seuil de flash.\nNote : Pour les logiciels ou le contenu Web, un rectangle de 341 x 256 pixels n\u2019importe o\xF9 sur la surface d\u2019affichage de l\u2019\xE9cran, quand la r\xE9solution est \xE0 1024 x 768 pixels, fournit une bonne estimation de ce que repr\xE9sente 10 degr\xE9s du champ visuel sur l\u2019\xE9cran pour un \xE9cran et une distance habituelle de visualisation. Par exemple des \xE9crans de 38 \xE0 43 centim\xE8tres (15 \xE0 17 pouces) \xE0 une distance de 55 \xE0 65 centim\xE8tres (22-26 pouces). Cette r\xE9solution de 75 \xE0 85 ppp est connue pour \xEAtre plus basse, et donc plus conservatrice que la r\xE9solution nominale du pixel CSS de 96 ppp dans les sp\xE9cifications CSS. Un affichage \xE0 une r\xE9solution sup\xE9rieure du m\xEAme contenu produirait des images plus petites et plus s\xFBres, c\u2019est pourquoi des r\xE9solutions inf\xE9rieures sont utilis\xE9es pour d\xE9finir le seuil.\nNote : Une transition est le changement, dans un temps donn\xE9, de luminance relative (ou de luminance relative ou de couleur pour le flash rouge) entre les pics et les creux adjacents dans un ensemble de mesures de luminance relative (ou de luminance relative ou de couleur pour le flash rouge). Un flash est constitu\xE9 de deux transitions oppos\xE9es.\nNote : La nouvelle d\xE9finition utilis\xE9e dans le domaine pour \xAB deux transitions oppos\xE9es de rouge satur\xE9 \xBB (provenant des WCAG 2.2) est : une paire de transitions oppos\xE9es o\xF9 une transition depuis ou vers un \xE9tat avec une valeur R/(R + G + B) qui est sup\xE9rieure ou \xE9gale \xE0 0,8, et la diff\xE9rence entre les \xE9tats est de plus de 0,2 (sans unit\xE9) sur le diagramme de chromaticit\xE9 CIE 1976 UCS. [ISO_9241-391]\nNote : Des outils sont disponibles pour effectuer l\u2019analyse depuis des captures vid\xE9os. Cependant, aucun outil n\u2019est n\xE9cessaire pour \xE9valuer cette condition si le flash est inf\xE9rieur ou \xE9gal \xE0 3 flashs par seconde. Le contenu est automatiquement conforme (voir #1 et #2 ci-dessus)."
|
|
2227
|
+
},
|
|
2228
|
+
"audio-only": {
|
|
2229
|
+
title: "seulement audio",
|
|
2230
|
+
body: "une pr\xE9sentation temporelle qui contient seulement de l\u2019audio (sans vid\xE9o ni interaction)"
|
|
2231
|
+
},
|
|
2232
|
+
"video-only": {
|
|
2233
|
+
title: "seulement vid\xE9o",
|
|
2234
|
+
body: "une pr\xE9sentation temporelle qui ne contient que de la vid\xE9o (aucun flux audio ni aucune interaction)"
|
|
2235
|
+
},
|
|
2236
|
+
captions: {
|
|
2237
|
+
title: "sous-titres",
|
|
2238
|
+
body: "visuel synchronis\xE9 ou \xE9quivalent textuel pour l\u2019information audio avec ou sans parole n\xE9cessaire \xE0 la compr\xE9hension du contenu d\u2019un m\xE9dia\nNote : Les sous-titres (en anglais captions) sont similaires \xE0 ceux qui sont utilis\xE9s seulement pour les dialogues (en anglais subtitles) sauf que les sous-titres ne communiquent pas seulement le contenu des dialogues parl\xE9s mais aussi des \xE9quivalents pour les informations audio autres que le dialogue et n\xE9cessaires \xE0 la compr\xE9hension du contenu du programme, y compris les effets sonores, la musique, les rires, l\u2019identification et le positionnement des interlocuteurs.\nNote : Les sous-titres cod\xE9s sont de la m\xEAme esp\xE8ce mais peuvent \xEAtre activ\xE9s ou d\xE9sactiv\xE9s dans certains lecteurs multim\xE9dia.\nNote : Les sous-titres visibles sont des sous-titres qui ne peuvent \xEAtre d\xE9sactiv\xE9s. Par exemple, si les sous-titres sont un \xE9quivalent visuel en texte sous forme d\u2019image int\xE9gr\xE9 \xE0 la vid\xE9o.\nNote : Les sous-titres ne devraient pas masquer l\u2019information pertinente de la vid\xE9o, m\xEAme partiellement.\nNote : Dans certaines langues comme l\u2019anglais on distingue entre caption et subtitles, le terme caption \xE9tant parfois traduit en fran\xE7ais par sous-titres pour malentendants.\nNote : L\u2019audio-description peut aussi \xEAtre sous-titr\xE9e, mais n\u2019a pas besoin de l\u2019\xEAtre, \xE9tant donn\xE9 qu\u2019il s\u2019agit d\u2019une description d\u2019information qui est d\xE9j\xE0 pr\xE9sent\xE9e visuellement."
|
|
2239
|
+
},
|
|
2240
|
+
structure: {
|
|
2241
|
+
title: "structure",
|
|
2242
|
+
body: "\u2022 La mani\xE8re dont les parties d\u2019une page Web sont organis\xE9es entre elles ; et\n\u2022 La mani\xE8re dont un groupe de pages Web est organis\xE9"
|
|
2243
|
+
},
|
|
2244
|
+
"assistive-technologies": {
|
|
2245
|
+
title: "technologie d\u2019assistance",
|
|
2246
|
+
body: "(tel qu\u2019utilis\xE9 dans ce document)\nmat\xE9riel ou logiciel qui agit comme agent utilisateur ou simultan\xE9ment avec un agent utilisateur usuel afin de fournir des fonctionnalit\xE9s r\xE9pondant aux besoins des utilisateurs ayant des limitations fonctionnelles, fonctionnalit\xE9s qui vont au-del\xE0 de celles qui sont offertes par les agents utilisateurs usuels\nNote : Les fonctionnalit\xE9s fournies par les technologies d\u2019assistance comprennent des pr\xE9sentations de remplacement (par exemple de la synth\xE8se vocale ou du contenu agrandi), des m\xE9thodes de saisie alternatives (par exemple la voix), des m\xE9canismes de navigation ou d\u2019orientation suppl\xE9mentaires et des transformations de contenu (par exemple pour rendre un tableau plus accessible).\nNote : Les technologies d\u2019assistance communiquent souvent les donn\xE9es et les messages aux agents utilisateurs usuels en utilisant et en surveillant le fonctionnement d\u2019une API (interface de programmation).\nNote : La distinction entre agents utilisateurs usuels et technologies d\u2019assistance n\u2019est pas absolue. Plusieurs agents utilisateurs usuels comportent des fonctions d\u2019assistance aux utilisateurs ayant des limitations fonctionnelles. La principale diff\xE9rence est que ces agents utilisateurs usuels visent un public large et diversifi\xE9 qui comprend des personnes avec et sans limitations fonctionnelles. Les technologies d\u2019assistance visent des populations plus restreintes d\u2019utilisateurs ayant des limitations fonctionnelles particuli\xE8res. L\u2019assistance fournie par une technologie d\u2019assistance est plus sp\xE9cifique et appropri\xE9e aux besoins des utilisateurs vis\xE9s. Un agent utilisateur usuel peut comporter des fonctionnalit\xE9s importantes pour les technologies d\u2019assistance comme l\u2019extraction du contenu Web \xE0 partir d\u2019objets de programmation ou l\u2019analyse syntaxique du balisage par paquets identifiables.\nExemple\nLes technologies d\u2019assistance qui sont importantes dans le contexte du pr\xE9sent document comprennent les technologies suivantes :\n\u2022 les agrandisseurs d\u2019\xE9cran et les autres assistants de lecture visuelle qui sont utilis\xE9s par les personnes ayant des limitations de la vision, de la perception ou d\u2019acc\xE8s physique \xE0 l\u2019imprim\xE9 pour modifier la police de caract\xE8res, la taille, l\u2019espacement, la couleur, la synchronisation avec la synth\xE8se vocale, etc. dans le but d\u2019am\xE9liorer la lisibilit\xE9 visuelle du rendu des textes et des images ;\n\u2022 les lecteurs d\u2019\xE9cran qui sont utilis\xE9s par les personnes aveugles pour lire l\u2019information textuelle en synth\xE8se vocale ou en braille ;\n\u2022 les logiciels de conversion du texte en parole qui sont utilis\xE9s par certaines personnes ayant des limitations cognitives, des limitations du langage et des difficult\xE9s d\u2019apprentissage pour convertir le texte en synth\xE8se vocale ;\n\u2022 les logiciels de reconnaissance vocale qui peuvent \xEAtre utilis\xE9s par les personnes ayant certaines limitations motrices ;\n\u2022 des claviers de remplacement qui sont utilis\xE9s par des personnes ayant certaines limitations motrices pour simuler le clavier (y compris des claviers de remplacement qui utilisent des pointeurs de t\xEAte, des commutateurs simples, des dispositifs d\u2019aspiration/expiration et d\u2019autres dispositifs sp\xE9ciaux d\u2019aide \xE0 la saisie.) ;\n\u2022 des dispositifs de pointage adapt\xE9s qui sont utilis\xE9s par des personnes ayant certaines limitations motrices pour simuler le pointeur de la souris et l\u2019activation des boutons."
|
|
2247
|
+
},
|
|
2248
|
+
technologies: {
|
|
2249
|
+
title: "technologie Web",
|
|
2250
|
+
body: "m\xE9canisme pour encoder les instructions devant \xEAtre restitu\xE9es, jou\xE9es ou ex\xE9cut\xE9es par les agents utilisateurs\nNote : Tels qu\u2019employ\xE9s dans ces r\xE8gles, l\u2019expression \xAB technologie Web \xBB et le mot \xAB technologie \xBB (utilis\xE9 seul) d\xE9signent les technologies relatives aux contenus Web.\nNote : Les technologies relatives aux contenus Web comprennent les langages de balisage, les formats de donn\xE9es ou les langages de programmation que les auteurs sont amen\xE9s \xE0 utiliser seuls ou combin\xE9s pour cr\xE9er des exp\xE9riences pour l\u2019utilisateur final qui vont de pages Web statiques jusqu\u2019\xE0 des pr\xE9sentations multim\xE9dia synchronis\xE9es, en passant par des applications Web dynamiques.\nExemple\nOn compte parmi les exemples les plus fr\xE9quents de technologies Web : HTML, CSS, SVG, PNG, PDF, Flash et JavaScript."
|
|
2251
|
+
},
|
|
2252
|
+
"cognitive-function-test": {
|
|
2253
|
+
title: "test cognitif",
|
|
2254
|
+
body: "Une t\xE2che qui demande \xE0 l\u2019utilisateur de m\xE9moriser, manipuler ou retranscrire une information. Des exemples comprennent, mais ne se limitent pas \xE0 :\n\u2022 la m\xE9morisation, par exemple se souvenir d\u2019un identifiant, d\u2019un mot de passe, d\u2019un ensemble de caract\xE8res, d\u2019images ou de motifs. Les identifiants courants tels que le nom, l\u2019adresse de courrier \xE9lectronique et le num\xE9ro de t\xE9l\xE9phone ne sont pas consid\xE9r\xE9s comme des tests cognitifs, car ils sont propres \xE0 l\u2019utilisateur et constants d\u2019un site Web \xE0 l\u2019autre ;\n\u2022 la transcription, comme la saisie de caract\xE8res ;\n\u2022 l\u2019utilisation d\u2019une orthographe correcte ;\n\u2022 l\u2019ex\xE9cution de calculs ;\n\u2022 la r\xE9solution d\u2019\xE9nigmes."
|
|
2255
|
+
},
|
|
2256
|
+
text: {
|
|
2257
|
+
title: "texte",
|
|
2258
|
+
body: "s\xE9quence de caract\xE8res pouvant \xEAtre d\xE9termin\xE9e par un programme informatique et exprimant quelque chose dans une langue donn\xE9e."
|
|
2259
|
+
},
|
|
2260
|
+
"images-of-text": {
|
|
2261
|
+
title: "texte sous forme d\u2019image",
|
|
2262
|
+
body: "texte qui est restitu\xE9 sous une forme non textuelle (par exemple une image) dans le but de permettre un effet visuel particulier\nNote : Cela n\u2019inclut pas le texte qui est une partie d\u2019une image qui contient d\u2019autres contenus visuels signifiants.\nExemple\nLe nom d\u2019une personne sur un badge dans une photographie."
|
|
2263
|
+
},
|
|
2264
|
+
emergency: {
|
|
2265
|
+
title: "urgence",
|
|
2266
|
+
body: "un \xE9v\xE9nement ou une situation soudaine et impr\xE9vue qui exige une action imm\xE9diate afin de pr\xE9server la sant\xE9, la s\xE9curit\xE9 ou la propri\xE9t\xE9"
|
|
2267
|
+
},
|
|
2268
|
+
"used-in-an-unusual-or-restricted-way": {
|
|
2269
|
+
title: "utilis\xE9 de mani\xE8re inhabituelle ou de fa\xE7on limit\xE9e",
|
|
2270
|
+
body: "mots employ\xE9s de telle mani\xE8re qu\u2019ils obligent les utilisateurs \xE0 savoir exactement quelle d\xE9finition appliquer afin de comprendre correctement le contenu\nExemple\nLe terme \xAB m\xE9moire \xBB poss\xE8de une signification diff\xE9rente dans une conversation universitaire de celle qu\u2019il peut avoir dans un article consacr\xE9 au stockage informatique, mais la d\xE9finition pertinente peut \xEAtre d\xE9duite du contexte. \xC0 l\u2019inverse, le mot \xAB texte \xBB est utilis\xE9 de mani\xE8re tr\xE8s sp\xE9cifique dans les WCAG 2.1, \xE0 tel point qu\u2019une d\xE9finition figure dans le glossaire."
|
|
2271
|
+
},
|
|
2272
|
+
"conforming-alternate-versions": {
|
|
2273
|
+
title: "version de remplacement conforme",
|
|
2274
|
+
body: "version qui\n\u2022 se conforme au niveau d\xE9termin\xE9 et\n\u2022 fournit toutes les informations similaires et les m\xEAmes fonctionnalit\xE9s dans la m\xEAme langue et\n\u2022 est aussi \xE0 jour que le contenu non conforme et\n\u2022\npour laquelle au moins l\u2019une des affirmations suivantes est vraie :\n\u2022 la version conforme peut \xEAtre atteinte \xE0 partir de la page non conforme via un m\xE9canisme compatible avec l\u2019accessibilit\xE9 ou\n\u2022 la version non conforme peut \xEAtre atteinte seulement \xE0 partir de la version conforme ou\n\u2022 la version non conforme peut \xEAtre atteinte seulement \xE0 partir d\u2019une page conforme qui fournit aussi un m\xE9canisme pour atteindre la version conforme.\nNote : Dans cette d\xE9finition, \xAB peut \xEAtre atteinte seulement \xBB signifie qu\u2019il y a un m\xE9canisme comme une redirection conditionnelle, qui emp\xEAche un utilisateur \xAB d\u2019atteindre \xBB (de charger) la page non conforme \xE0 moins que l\u2019utilisateur ne vienne justement de la version conforme de cette m\xEAme page.\nNote : La version de remplacement n\u2019a pas besoin d\u2019\xEAtre appari\xE9e page par page avec la version originale (par exemple la version de remplacement conforme peut se pr\xE9senter en plusieurs pages).\nNote : Si des versions sont propos\xE9es dans plusieurs langues, une version de remplacement conforme est donc requise pour chacune de ces langues.\nNote : Des versions de remplacement peuvent aussi \xEAtre fournies afin d\u2019accommoder diff\xE9rents environnements technologiques ou diff\xE9rents groupes d\u2019utilisateurs. Chaque version devrait \xEAtre aussi conforme que possible. Une version devrait \xEAtre enti\xE8rement conforme afin de satisfaire \xE0 l\u2019exigence de conformit\xE9 1.\nNote : La version de remplacement conforme n\u2019a pas besoin d\u2019\xEAtre situ\xE9e dans le p\xE9rim\xE8tre de conformit\xE9 ni m\xEAme sur le m\xEAme site Web tant qu\u2019elle est aussi librement disponible que la version non conforme.\nNote : Une version de remplacement ne devrait pas \xEAtre confondue avec un contenu additionnel qui s\u2019ajoute \xE0 la page originale pour en am\xE9liorer la compr\xE9hension.\nNote : Permettre la configuration des pr\xE9f\xE9rences de l\u2019utilisateur \xE0 l\u2019int\xE9rieur du contenu afin de produire une version conforme est un m\xE9canisme acceptable pour atteindre une autre version tant que la m\xE9thode utilis\xE9e pour configurer les pr\xE9f\xE9rences est compatible avec l\u2019accessibilit\xE9.\nVoir Comprendre Version de remplacement conforme (en anglais)"
|
|
2275
|
+
},
|
|
2276
|
+
"alternative-for-time-based-media": {
|
|
2277
|
+
title: "version de remplacement pour un m\xE9dia temporel",
|
|
2278
|
+
body: "document renfermant dans un ordre correct une description des contenus visuels et sonores d\u2019un m\xE9dia temporel et fournissant un moyen de r\xE9aliser les effets de toute interaction temporelle\nNote : Un sc\xE9nario utilis\xE9 pour cr\xE9er le contenu d\u2019un m\xE9dia synchronis\xE9 serait conforme \xE0 cette d\xE9finition seulement s\u2019il a \xE9t\xE9 corrig\xE9 afin de repr\xE9senter fid\xE8lement la version finale du m\xE9dia synchronis\xE9 apr\xE8s \xE9dition."
|
|
2279
|
+
},
|
|
2280
|
+
video: {
|
|
2281
|
+
title: "vid\xE9o",
|
|
2282
|
+
body: "vid\xE9o la technologie des images ou photos en mouvement ou en s\xE9quence\nNote : Une vid\xE9o peut \xEAtre constitu\xE9e d\u2019images fixes ou anim\xE9es ou des deux."
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
1193
2285
|
};
|
|
1194
2286
|
|
|
1195
2287
|
// src/data/wcag-universe.json
|
|
@@ -1741,6 +2833,10 @@ function hasSC(id) {
|
|
|
1741
2833
|
function knownScStatus(id) {
|
|
1742
2834
|
return universeById.get(id)?.status;
|
|
1743
2835
|
}
|
|
2836
|
+
function coreGlossary(lang = "en") {
|
|
2837
|
+
const fr = data.glossaryFr;
|
|
2838
|
+
return (lang === "fr" && fr && Object.keys(fr).length ? fr : data.glossary) ?? {};
|
|
2839
|
+
}
|
|
1744
2840
|
function allPrinciples() {
|
|
1745
2841
|
return data.principles;
|
|
1746
2842
|
}
|
|
@@ -1757,6 +2853,11 @@ function guidelineTitle(n, lang = "en") {
|
|
|
1757
2853
|
if (!g) return void 0;
|
|
1758
2854
|
return lang === "fr" ? g.titleFr ?? g.title : g.title;
|
|
1759
2855
|
}
|
|
2856
|
+
function scText(id, lang = "en") {
|
|
2857
|
+
const sc = byId.get(id);
|
|
2858
|
+
if (!sc) return void 0;
|
|
2859
|
+
return lang === "fr" ? sc.textFr ?? sc.text : sc.text;
|
|
2860
|
+
}
|
|
1760
2861
|
function scTitle(id, lang = "en") {
|
|
1761
2862
|
const sc = byId.get(id);
|
|
1762
2863
|
if (!sc) return void 0;
|
|
@@ -6240,7 +7341,7 @@ var flow = (superClass) => class FlowParserMixin extends superClass {
|
|
|
6240
7341
|
node.id = this.parseIdentifier();
|
|
6241
7342
|
}
|
|
6242
7343
|
const bodyNode = this.startNode();
|
|
6243
|
-
const
|
|
7344
|
+
const body3 = bodyNode.body = [];
|
|
6244
7345
|
this.expect(2);
|
|
6245
7346
|
while (!this.match(4)) {
|
|
6246
7347
|
const bodyNode2 = this.startNode();
|
|
@@ -6249,10 +7350,10 @@ var flow = (superClass) => class FlowParserMixin extends superClass {
|
|
|
6249
7350
|
if (!this.isContextual(126) && !this.match(83)) {
|
|
6250
7351
|
this.raise(FlowErrors.InvalidNonTypeImportInDeclareModule, this.state.lastTokStartLoc);
|
|
6251
7352
|
}
|
|
6252
|
-
|
|
7353
|
+
body3.push(super.parseImport(bodyNode2));
|
|
6253
7354
|
} else {
|
|
6254
7355
|
this.expectContextual(121, FlowErrors.UnsupportedStatementInDeclareModule);
|
|
6255
|
-
|
|
7356
|
+
body3.push(this.flowParseDeclare(bodyNode2, true));
|
|
6256
7357
|
}
|
|
6257
7358
|
}
|
|
6258
7359
|
this.scope.exit();
|
|
@@ -6260,7 +7361,7 @@ var flow = (superClass) => class FlowParserMixin extends superClass {
|
|
|
6260
7361
|
node.body = this.finishNode(bodyNode, "BlockStatement");
|
|
6261
7362
|
let kind = null;
|
|
6262
7363
|
let hasModuleExport = false;
|
|
6263
|
-
|
|
7364
|
+
body3.forEach((bodyElement) => {
|
|
6264
7365
|
if (isEsModuleType(bodyElement)) {
|
|
6265
7366
|
if (kind === "CommonJS") {
|
|
6266
7367
|
this.raise(FlowErrors.AmbiguousDeclareModuleKind, bodyElement);
|
|
@@ -12088,17 +13189,17 @@ var ExpressionParser = class extends LValParser {
|
|
|
12088
13189
|
const {
|
|
12089
13190
|
startLoc
|
|
12090
13191
|
} = this.state;
|
|
12091
|
-
const
|
|
12092
|
-
const requiredParentheses = UnparenthesizedPipeBodyDescriptions.has(
|
|
12093
|
-
if (requiredParentheses && !
|
|
13192
|
+
const body3 = this.parseMaybeAssign();
|
|
13193
|
+
const requiredParentheses = UnparenthesizedPipeBodyDescriptions.has(body3.type);
|
|
13194
|
+
if (requiredParentheses && !body3.extra?.parenthesized) {
|
|
12094
13195
|
this.raise(Errors.PipeUnparenthesizedBody, startLoc, {
|
|
12095
|
-
type:
|
|
13196
|
+
type: body3.type
|
|
12096
13197
|
});
|
|
12097
13198
|
}
|
|
12098
13199
|
if (!this.topicReferenceWasUsedInCurrentContext()) {
|
|
12099
13200
|
this.raise(Errors.PipeTopicUnused, startLoc);
|
|
12100
13201
|
}
|
|
12101
|
-
return
|
|
13202
|
+
return body3;
|
|
12102
13203
|
}
|
|
12103
13204
|
checkExponentialAfterUnary(node) {
|
|
12104
13205
|
if (this.match(53)) {
|
|
@@ -14172,11 +15273,11 @@ var StatementParser = class extends ExpressionParser {
|
|
|
14172
15273
|
return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized;
|
|
14173
15274
|
}
|
|
14174
15275
|
parseBlockBody(node, allowDirectives, topLevel, end, afterBlockParse) {
|
|
14175
|
-
const
|
|
15276
|
+
const body3 = node.body = [];
|
|
14176
15277
|
const directives = node.directives = [];
|
|
14177
|
-
this.parseBlockOrModuleBlockBody(
|
|
15278
|
+
this.parseBlockOrModuleBlockBody(body3, allowDirectives ? directives : void 0, topLevel, end, afterBlockParse);
|
|
14178
15279
|
}
|
|
14179
|
-
parseBlockOrModuleBlockBody(
|
|
15280
|
+
parseBlockOrModuleBlockBody(body3, directives, topLevel, end, afterBlockParse) {
|
|
14180
15281
|
const oldStrict = this.state.strict;
|
|
14181
15282
|
let hasStrictModeDirective = false;
|
|
14182
15283
|
let parsedNonDirective = false;
|
|
@@ -14195,7 +15296,7 @@ var StatementParser = class extends ExpressionParser {
|
|
|
14195
15296
|
parsedNonDirective = true;
|
|
14196
15297
|
this.state.strictErrors.clear();
|
|
14197
15298
|
}
|
|
14198
|
-
|
|
15299
|
+
body3.push(stmt);
|
|
14199
15300
|
}
|
|
14200
15301
|
afterBlockParse?.call(this, hasStrictModeDirective);
|
|
14201
15302
|
if (!oldStrict) {
|
|
@@ -14552,8 +15653,8 @@ var StatementParser = class extends ExpressionParser {
|
|
|
14552
15653
|
const oldLabels = this.state.labels;
|
|
14553
15654
|
this.state.labels = [];
|
|
14554
15655
|
this.prodParam.enter(0);
|
|
14555
|
-
const
|
|
14556
|
-
this.parseBlockOrModuleBlockBody(
|
|
15656
|
+
const body3 = member.body = [];
|
|
15657
|
+
this.parseBlockOrModuleBlockBody(body3, void 0, false, 4);
|
|
14557
15658
|
this.prodParam.exit();
|
|
14558
15659
|
this.scope.exit();
|
|
14559
15660
|
this.state.labels = oldLabels;
|
|
@@ -16398,9 +17499,9 @@ var typescript = (superClass) => class TypeScriptParserMixin extends superClass
|
|
|
16398
17499
|
if (this.eat(77)) {
|
|
16399
17500
|
node.extends = this.tsParseHeritageClause("extends");
|
|
16400
17501
|
}
|
|
16401
|
-
const
|
|
16402
|
-
|
|
16403
|
-
node.body = this.finishNode(
|
|
17502
|
+
const body3 = this.startNode();
|
|
17503
|
+
body3.body = this.tsInType(this.tsParseObjectTypeMembers.bind(this));
|
|
17504
|
+
node.body = this.finishNode(body3, "TSInterfaceBody");
|
|
16404
17505
|
return this.finishNode(node, "TSInterfaceDeclaration");
|
|
16405
17506
|
}
|
|
16406
17507
|
tsParseTypeAliasDeclaration(node) {
|
|
@@ -18772,8 +19873,8 @@ function isLibrarySpecifier(spec) {
|
|
|
18772
19873
|
}
|
|
18773
19874
|
function opaqueLibrarySpecifiers(ast, elements) {
|
|
18774
19875
|
const importSrc = /* @__PURE__ */ new Map();
|
|
18775
|
-
const
|
|
18776
|
-
for (const stmt of
|
|
19876
|
+
const body3 = asNodes2((asNode2(ast.program) ?? ast).body);
|
|
19877
|
+
for (const stmt of body3) {
|
|
18777
19878
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
18778
19879
|
const source = asNode2(stmt.source);
|
|
18779
19880
|
const spec = source && typeof source.value === "string" ? source.value : "";
|
|
@@ -19157,22 +20258,22 @@ function patternToRegExpSource(pattern) {
|
|
|
19157
20258
|
re += "[^/]";
|
|
19158
20259
|
} else if (c2 === "[") {
|
|
19159
20260
|
let j = i2 + 1;
|
|
19160
|
-
let
|
|
20261
|
+
let body22 = "";
|
|
19161
20262
|
if (pattern[j] === "!") {
|
|
19162
|
-
|
|
20263
|
+
body22 += "^";
|
|
19163
20264
|
j++;
|
|
19164
20265
|
}
|
|
19165
20266
|
if (pattern[j] === "]") {
|
|
19166
|
-
|
|
20267
|
+
body22 += "\\]";
|
|
19167
20268
|
j++;
|
|
19168
20269
|
}
|
|
19169
20270
|
while (j < pattern.length && pattern[j] !== "]") {
|
|
19170
20271
|
const ch = pattern[j];
|
|
19171
|
-
|
|
20272
|
+
body22 += ch === "\\" || ch === "^" ? "\\" + ch : ch;
|
|
19172
20273
|
j++;
|
|
19173
20274
|
}
|
|
19174
|
-
if (j < pattern.length &&
|
|
19175
|
-
re += `[${
|
|
20275
|
+
if (j < pattern.length && body22 !== "" && body22 !== "^") {
|
|
20276
|
+
re += `[${body22}]`;
|
|
19176
20277
|
i2 = j;
|
|
19177
20278
|
} else {
|
|
19178
20279
|
re += "\\[";
|
|
@@ -19202,8 +20303,8 @@ function parseGitignore(content, baseRel) {
|
|
|
19202
20303
|
if (!line) continue;
|
|
19203
20304
|
const anchored = line.includes("/");
|
|
19204
20305
|
if (line.startsWith("/")) line = line.slice(1);
|
|
19205
|
-
const
|
|
19206
|
-
const source = anchored ? `^${prefix2}${
|
|
20306
|
+
const body22 = patternToRegExpSource(line);
|
|
20307
|
+
const source = anchored ? `^${prefix2}${body22}$` : `^${prefix2}(?:[^/]+/)*${body22}$`;
|
|
19207
20308
|
try {
|
|
19208
20309
|
rules.push({ re: new RegExp(source), negated, dirOnly });
|
|
19209
20310
|
} catch {
|
|
@@ -20520,15 +21621,15 @@ function isBoilerplate(s) {
|
|
|
20520
21621
|
return /^(all notable changes to this project|in the interest of fostering|this project adheres to|we as members and leaders|table of contents)\b/i.test(s);
|
|
20521
21622
|
}
|
|
20522
21623
|
function extractMarkdown(content) {
|
|
20523
|
-
let
|
|
21624
|
+
let body22 = content;
|
|
20524
21625
|
let frontTitle;
|
|
20525
|
-
const fm = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(
|
|
21626
|
+
const fm = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(body22);
|
|
20526
21627
|
if (fm) {
|
|
20527
21628
|
const t2 = /(^|\n)title:\s*["']?(.+?)["']?\s*(\n|$)/i.exec(fm[1]);
|
|
20528
21629
|
if (t2) frontTitle = t2[2].trim();
|
|
20529
|
-
|
|
21630
|
+
body22 = body22.slice(fm[0].length);
|
|
20530
21631
|
}
|
|
20531
|
-
const scan2 = stripFences(
|
|
21632
|
+
const scan2 = stripFences(body22);
|
|
20532
21633
|
const lines = scan2.split(/\r?\n/);
|
|
20533
21634
|
const headings2 = [];
|
|
20534
21635
|
let title2 = frontTitle;
|
|
@@ -23938,10 +25039,10 @@ var init_web_tree_sitter = __esm({
|
|
|
23938
25039
|
} else {
|
|
23939
25040
|
const response = await fetch(input);
|
|
23940
25041
|
if (!response.ok) {
|
|
23941
|
-
const
|
|
25042
|
+
const body22 = await response.text();
|
|
23942
25043
|
throw new Error(`Language.load failed with status ${response.status}.
|
|
23943
25044
|
|
|
23944
|
-
${
|
|
25045
|
+
${body22}`);
|
|
23945
25046
|
}
|
|
23946
25047
|
const retryResp = response.clone();
|
|
23947
25048
|
try {
|
|
@@ -26018,8 +27119,8 @@ function docCommentFor(node) {
|
|
|
26018
27119
|
return void 0;
|
|
26019
27120
|
}
|
|
26020
27121
|
function docstringFor(node) {
|
|
26021
|
-
const
|
|
26022
|
-
const first =
|
|
27122
|
+
const body22 = node.childForFieldName("body");
|
|
27123
|
+
const first = body22?.namedChildren[0];
|
|
26023
27124
|
if (!first) return void 0;
|
|
26024
27125
|
const str22 = first.type === "string" ? first : first.type === "expression_statement" ? first.namedChildren[0] : void 0;
|
|
26025
27126
|
if (!str22 || str22.type !== "string") return void 0;
|
|
@@ -26830,8 +27931,8 @@ function collectTermsRegex(content) {
|
|
|
26830
27931
|
line = line.slice(0, lineComment.index);
|
|
26831
27932
|
}
|
|
26832
27933
|
for (const m of line.matchAll(/(['"`])((?:\\.|(?!\1)[^\\])*)\1/g)) {
|
|
26833
|
-
const
|
|
26834
|
-
if (
|
|
27934
|
+
const body22 = m[2];
|
|
27935
|
+
if (body22.length && body22.length <= MAX_LITERAL_LEN3) add2(body22);
|
|
26835
27936
|
}
|
|
26836
27937
|
}
|
|
26837
27938
|
return [...found].sort();
|
|
@@ -29165,8 +30266,8 @@ function symbolComplexity(scan2, rel2, top = 50) {
|
|
|
29165
30266
|
for (const s of f.symbols) {
|
|
29166
30267
|
if (s.kind === "reexport" || s.kind === "reexport-all") continue;
|
|
29167
30268
|
const end = s.endLine ?? s.line;
|
|
29168
|
-
const
|
|
29169
|
-
const entry = { file: f.rel, name: s.name, line: s.line, complexity: complexityOfSource(
|
|
30269
|
+
const body22 = lines.slice(s.line - 1, end).join("\n");
|
|
30270
|
+
const entry = { file: f.rel, name: s.name, line: s.line, complexity: complexityOfSource(body22) };
|
|
29170
30271
|
if (s.endLine !== void 0) entry.endLine = s.endLine;
|
|
29171
30272
|
out2.push(entry);
|
|
29172
30273
|
}
|
|
@@ -29598,21 +30699,21 @@ function resolveUniqueSymbol(scan2, namePath, file) {
|
|
|
29598
30699
|
function readLines(abs) {
|
|
29599
30700
|
return readFileSync6(abs, "utf8").split("\n");
|
|
29600
30701
|
}
|
|
29601
|
-
function replaceSymbolBody(scan2, namePath,
|
|
30702
|
+
function replaceSymbolBody(scan2, namePath, body22, file) {
|
|
29602
30703
|
const sym = resolveUniqueSymbol(scan2, namePath, file);
|
|
29603
30704
|
const end = sym.endLine ?? sym.line;
|
|
29604
30705
|
const abs = join12(scan2.root, sym.file);
|
|
29605
30706
|
const lines = readLines(abs);
|
|
29606
|
-
const newLines =
|
|
30707
|
+
const newLines = body22.replace(/^\n+|\n+$/g, "").split("\n");
|
|
29607
30708
|
lines.splice(sym.line - 1, end - sym.line + 1, ...newLines);
|
|
29608
30709
|
writeFileSync2(abs, lines.join("\n"));
|
|
29609
30710
|
return { file: sym.file, startLine: sym.line, endLine: sym.line + newLines.length - 1, lines: newLines.length };
|
|
29610
30711
|
}
|
|
29611
|
-
function insertAt(scan2, sym,
|
|
30712
|
+
function insertAt(scan2, sym, body22, index, blankBefore, blankAfter) {
|
|
29612
30713
|
const abs = join12(scan2.root, sym.file);
|
|
29613
30714
|
const lines = readLines(abs);
|
|
29614
30715
|
const minGap = SEPARATED_KINDS.has(sym.kind) ? 1 : 0;
|
|
29615
|
-
const newLines =
|
|
30716
|
+
const newLines = body22.replace(/^\n+|\n+$/g, "").split("\n");
|
|
29616
30717
|
const block = [];
|
|
29617
30718
|
if (blankBefore && minGap && lines[index - 1]?.trim() !== "") block.push("");
|
|
29618
30719
|
block.push(...newLines);
|
|
@@ -29621,14 +30722,14 @@ function insertAt(scan2, sym, body2, index, blankBefore, blankAfter) {
|
|
|
29621
30722
|
writeFileSync2(abs, lines.join("\n"));
|
|
29622
30723
|
return { file: sym.file, startLine: index + 1, endLine: index + block.length, lines: block.length };
|
|
29623
30724
|
}
|
|
29624
|
-
function insertAfterSymbol(scan2, namePath,
|
|
30725
|
+
function insertAfterSymbol(scan2, namePath, body22, file) {
|
|
29625
30726
|
const sym = resolveUniqueSymbol(scan2, namePath, file);
|
|
29626
30727
|
const end = sym.endLine ?? sym.line;
|
|
29627
|
-
return insertAt(scan2, sym,
|
|
30728
|
+
return insertAt(scan2, sym, body22, end, true, true);
|
|
29628
30729
|
}
|
|
29629
|
-
function insertBeforeSymbol(scan2, namePath,
|
|
30730
|
+
function insertBeforeSymbol(scan2, namePath, body22, file) {
|
|
29630
30731
|
const sym = resolveUniqueSymbol(scan2, namePath, file);
|
|
29631
|
-
return insertAt(scan2, sym,
|
|
30732
|
+
return insertAt(scan2, sym, body22, sym.line - 1, true, true);
|
|
29632
30733
|
}
|
|
29633
30734
|
var SEPARATED_KINDS;
|
|
29634
30735
|
var init_edit = __esm({
|
|
@@ -29722,13 +30823,13 @@ function tomlSectionBody(toml, section) {
|
|
|
29722
30823
|
const m = toml.match(re);
|
|
29723
30824
|
return m ? m[1] : null;
|
|
29724
30825
|
}
|
|
29725
|
-
function tomlStringArray(
|
|
29726
|
-
const m =
|
|
30826
|
+
function tomlStringArray(body22, key) {
|
|
30827
|
+
const m = body22.match(new RegExp(`${escapeRegExp(key)}\\s*=\\s*\\[([^\\]]*)\\]`));
|
|
29727
30828
|
if (!m) return [];
|
|
29728
30829
|
return m[1].split(/\r?\n/).map((line) => line.replace(/#.*$/, "")).join("\n").split(",").map((s) => s.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
29729
30830
|
}
|
|
29730
|
-
function tomlString(
|
|
29731
|
-
return
|
|
30831
|
+
function tomlString(body22, key) {
|
|
30832
|
+
return body22?.match(new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*["']([^"']+)["']`, "m"))?.[1];
|
|
29732
30833
|
}
|
|
29733
30834
|
function wsGlobToRegExp(pat) {
|
|
29734
30835
|
let re = "";
|
|
@@ -29767,14 +30868,14 @@ function probeNodePkg(root, dir, kind, warnings) {
|
|
|
29767
30868
|
function probeCargo(root, dir) {
|
|
29768
30869
|
const path = join14(root, dir, "Cargo.toml");
|
|
29769
30870
|
if (!existsSync5(path)) return void 0;
|
|
29770
|
-
const
|
|
30871
|
+
const body22 = tomlSectionBody(readText2(path), "package");
|
|
29771
30872
|
const out2 = {
|
|
29772
|
-
name: tomlString(
|
|
30873
|
+
name: tomlString(body22, "name") ?? dir,
|
|
29773
30874
|
dir,
|
|
29774
30875
|
kind: "cargo",
|
|
29775
30876
|
manifest: `${dir}/Cargo.toml`
|
|
29776
30877
|
};
|
|
29777
|
-
const description = tomlString(
|
|
30878
|
+
const description = tomlString(body22, "description");
|
|
29778
30879
|
if (description) out2.description = description;
|
|
29779
30880
|
return out2;
|
|
29780
30881
|
}
|
|
@@ -29975,11 +31076,11 @@ function fallbackNpmPatterns(root, warnings) {
|
|
|
29975
31076
|
function detectCargoMembers(root, found, warnings) {
|
|
29976
31077
|
const toml = readText2(join14(root, "Cargo.toml"));
|
|
29977
31078
|
if (!toml) return;
|
|
29978
|
-
const
|
|
29979
|
-
if (!
|
|
29980
|
-
const members = tomlStringArray(
|
|
31079
|
+
const body22 = tomlSectionBody(toml, "workspace");
|
|
31080
|
+
if (!body22) return;
|
|
31081
|
+
const members = tomlStringArray(body22, "members");
|
|
29981
31082
|
if (!members.length) return;
|
|
29982
|
-
const excludes = tomlStringArray(
|
|
31083
|
+
const excludes = tomlStringArray(body22, "exclude").map(wsGlobToRegExp);
|
|
29983
31084
|
const candidates2 = /* @__PURE__ */ new Map();
|
|
29984
31085
|
for (const pat of members) expandPattern(root, pat, candidates2, "cargo", warnings);
|
|
29985
31086
|
for (const [dir, pkg] of candidates2) {
|
|
@@ -30015,11 +31116,11 @@ function detectMavenModules(root, found, warnings) {
|
|
|
30015
31116
|
function detectUvMembers(root, found, warnings) {
|
|
30016
31117
|
const toml = readText2(join14(root, "pyproject.toml"));
|
|
30017
31118
|
if (!toml) return;
|
|
30018
|
-
const
|
|
30019
|
-
if (!
|
|
30020
|
-
const members = tomlStringArray(
|
|
31119
|
+
const body22 = tomlSectionBody(toml, "tool.uv.workspace");
|
|
31120
|
+
if (!body22) return;
|
|
31121
|
+
const members = tomlStringArray(body22, "members");
|
|
30021
31122
|
if (!members.length) return;
|
|
30022
|
-
const excludes = tomlStringArray(
|
|
31123
|
+
const excludes = tomlStringArray(body22, "exclude").map(wsGlobToRegExp);
|
|
30023
31124
|
const candidates2 = /* @__PURE__ */ new Map();
|
|
30024
31125
|
for (const pat of members) expandPattern(root, pat, candidates2, "uv", warnings);
|
|
30025
31126
|
for (const [dir, pkg] of candidates2) {
|
|
@@ -30078,9 +31179,9 @@ function cargoEdges(root, pkg, byName, byDir) {
|
|
|
30078
31179
|
if (!toml) return [];
|
|
30079
31180
|
const edges = /* @__PURE__ */ new Set();
|
|
30080
31181
|
for (const section of ["dependencies", "dev-dependencies", "build-dependencies"]) {
|
|
30081
|
-
const
|
|
30082
|
-
if (!
|
|
30083
|
-
for (const line of
|
|
31182
|
+
const body22 = tomlSectionBody(toml, section);
|
|
31183
|
+
if (!body22) continue;
|
|
31184
|
+
for (const line of body22.split(/\r?\n/)) {
|
|
30084
31185
|
const kv = line.match(/^\s*([A-Za-z0-9_-]+)\s*=\s*(.+)$/);
|
|
30085
31186
|
if (!kv) continue;
|
|
30086
31187
|
const dep = kv[1];
|
|
@@ -30669,10 +31770,10 @@ function groupFamilies(dups) {
|
|
|
30669
31770
|
return families;
|
|
30670
31771
|
}
|
|
30671
31772
|
function pathPrefix(value) {
|
|
30672
|
-
const
|
|
30673
|
-
const cut =
|
|
31773
|
+
const body22 = value.startsWith("/") ? value.slice(1) : value;
|
|
31774
|
+
const cut = body22.search(/[/:]/);
|
|
30674
31775
|
if (cut <= 0) return void 0;
|
|
30675
|
-
const prefix2 = (value.startsWith("/") ? "/" : "") +
|
|
31776
|
+
const prefix2 = (value.startsWith("/") ? "/" : "") + body22.slice(0, cut);
|
|
30676
31777
|
return prefix2.length >= FAMILY_MIN_PREFIX ? prefix2 : void 0;
|
|
30677
31778
|
}
|
|
30678
31779
|
var LITERAL_DUPLICATION_CAP;
|
|
@@ -30876,14 +31977,14 @@ function resolveEmbedPullUrl() {
|
|
|
30876
31977
|
async function fetchEmbedModel(url, expectedSha256) {
|
|
30877
31978
|
const res = await fetch(url);
|
|
30878
31979
|
if (!res.ok) throw new Error(`HTTP ${res.status} from ${url}`);
|
|
30879
|
-
const
|
|
31980
|
+
const body22 = await res.text();
|
|
30880
31981
|
if (expectedSha256) {
|
|
30881
|
-
const got = createHash3("sha256").update(
|
|
31982
|
+
const got = createHash3("sha256").update(body22).digest("hex");
|
|
30882
31983
|
if (got !== expectedSha256) {
|
|
30883
31984
|
throw new Error(`sha256 mismatch: expected ${expectedSha256}, got ${got}`);
|
|
30884
31985
|
}
|
|
30885
31986
|
}
|
|
30886
|
-
return
|
|
31987
|
+
return body22;
|
|
30887
31988
|
}
|
|
30888
31989
|
var EMBED_VERSION;
|
|
30889
31990
|
var DEFAULT_EMBED_DIRNAME;
|
|
@@ -31027,16 +32128,16 @@ function serializeEmbeddings(index) {
|
|
|
31027
32128
|
records: index.records.map((r) => ({ file: r.file, symbol: r.symbol ?? "", line: r.line ?? 0 }))
|
|
31028
32129
|
});
|
|
31029
32130
|
const headerBuf = Buffer.from(header4, "utf8");
|
|
31030
|
-
const
|
|
32131
|
+
const body22 = Buffer.alloc(index.records.length * index.dim);
|
|
31031
32132
|
let off = 0;
|
|
31032
32133
|
for (const r of index.records) {
|
|
31033
|
-
for (let d = 0; d < index.dim; d++)
|
|
32134
|
+
for (let d = 0; d < index.dim; d++) body22.writeInt8(r.vec[d] ?? 0, off++);
|
|
31034
32135
|
}
|
|
31035
|
-
const out2 = Buffer.alloc(8 + headerBuf.length +
|
|
32136
|
+
const out2 = Buffer.alloc(8 + headerBuf.length + body22.length);
|
|
31036
32137
|
out2.write(MAGIC, 0, "ascii");
|
|
31037
32138
|
out2.writeUInt32LE(headerBuf.length, 4);
|
|
31038
32139
|
headerBuf.copy(out2, 8);
|
|
31039
|
-
|
|
32140
|
+
body22.copy(out2, 8 + headerBuf.length);
|
|
31040
32141
|
return out2;
|
|
31041
32142
|
}
|
|
31042
32143
|
function deserializeEmbeddings(bytes) {
|
|
@@ -31364,8 +32465,8 @@ var init_onboard = __esm({
|
|
|
31364
32465
|
}
|
|
31365
32466
|
});
|
|
31366
32467
|
function encodeMessage(msg) {
|
|
31367
|
-
const
|
|
31368
|
-
return `Content-Length: ${byteLength(
|
|
32468
|
+
const body22 = JSON.stringify(msg);
|
|
32469
|
+
return `Content-Length: ${byteLength(body22)}${HEADER_END}${body22}`;
|
|
31369
32470
|
}
|
|
31370
32471
|
function byteLength(s) {
|
|
31371
32472
|
return new TextEncoder().encode(s).byteLength;
|
|
@@ -31406,10 +32507,10 @@ function createFramer() {
|
|
|
31406
32507
|
}
|
|
31407
32508
|
const start2 = end + 4;
|
|
31408
32509
|
if (buffer.length < start2 + length) return out2;
|
|
31409
|
-
const
|
|
32510
|
+
const body22 = decoder.decode(buffer.subarray(start2, start2 + length));
|
|
31410
32511
|
buffer = buffer.subarray(start2 + length);
|
|
31411
32512
|
try {
|
|
31412
|
-
out2.push(JSON.parse(
|
|
32513
|
+
out2.push(JSON.parse(body22));
|
|
31413
32514
|
} catch {
|
|
31414
32515
|
}
|
|
31415
32516
|
}
|
|
@@ -33169,19 +34270,19 @@ async function callTool(name2, args2, defaultRepo) {
|
|
|
33169
34270
|
}
|
|
33170
34271
|
if (name2 === "symbols") {
|
|
33171
34272
|
const { symbols } = getArtifacts(repo, scanOpts, walked);
|
|
33172
|
-
const
|
|
33173
|
-
if (
|
|
33174
|
-
return JSON.stringify({ name:
|
|
34273
|
+
const lookup2 = str(args2.name);
|
|
34274
|
+
if (lookup2) {
|
|
34275
|
+
return JSON.stringify({ name: lookup2, defs: symbols.defs[lookup2] ?? [], refs: symbols.refs[lookup2] ?? [] }, null, 2);
|
|
33175
34276
|
}
|
|
33176
34277
|
return JSON.stringify(symbols, null, 2);
|
|
33177
34278
|
}
|
|
33178
34279
|
if (name2 === "callers") {
|
|
33179
34280
|
const scan2 = getScan(repo, scanOpts, walked);
|
|
33180
34281
|
const index = args2.recall === true ? buildCallerIndex(scan2, void 0, { recall: true }) : callerIndexFor(scan2);
|
|
33181
|
-
const
|
|
33182
|
-
if (
|
|
33183
|
-
const entry = index.get(
|
|
33184
|
-
return JSON.stringify(entry ?? { error: `no tracked callers for "${
|
|
34282
|
+
const lookup2 = str(args2.name);
|
|
34283
|
+
if (lookup2) {
|
|
34284
|
+
const entry = index.get(lookup2);
|
|
34285
|
+
return JSON.stringify(entry ?? { error: `no tracked callers for "${lookup2}"` }, null, 2);
|
|
33185
34286
|
}
|
|
33186
34287
|
const obj = {};
|
|
33187
34288
|
for (const [k, v] of index) obj[k] = v;
|
|
@@ -33226,11 +34327,11 @@ async function callTool(name2, args2, defaultRepo) {
|
|
|
33226
34327
|
}
|
|
33227
34328
|
if (name2 === "replace_symbol_body" || name2 === "insert_after_symbol" || name2 === "insert_before_symbol") {
|
|
33228
34329
|
const namePath = str(args2.namePath);
|
|
33229
|
-
const
|
|
33230
|
-
if (!namePath ||
|
|
34330
|
+
const body22 = typeof args2.body === "string" ? args2.body : void 0;
|
|
34331
|
+
if (!namePath || body22 === void 0) throw new Error("`namePath` and `body` are required");
|
|
33231
34332
|
const scan2 = getScan(repo, scanOpts, walked);
|
|
33232
34333
|
const fn = name2 === "replace_symbol_body" ? replaceSymbolBody : name2 === "insert_after_symbol" ? insertAfterSymbol : insertBeforeSymbol;
|
|
33233
|
-
const result = fn(scan2, namePath,
|
|
34334
|
+
const result = fn(scan2, namePath, body22, str(args2.file));
|
|
33234
34335
|
sessionClear();
|
|
33235
34336
|
return JSON.stringify(result, null, 2);
|
|
33236
34337
|
}
|
|
@@ -35607,9 +36708,9 @@ async function runCli(rawArgv) {
|
|
|
35607
36708
|
mkdirSync3(destDir, { recursive: true });
|
|
35608
36709
|
process.stderr.write(`codeindex: fetching model from ${url} \u2192 ${join23(destDir, "model.json")}
|
|
35609
36710
|
`);
|
|
35610
|
-
let
|
|
36711
|
+
let body22;
|
|
35611
36712
|
try {
|
|
35612
|
-
|
|
36713
|
+
body22 = await fetchEmbedModel(url, sha256);
|
|
35613
36714
|
} catch (e) {
|
|
35614
36715
|
process.stderr.write(`codeindex: pull failed \u2014 ${e instanceof Error ? e.message : String(e)} (nothing written)
|
|
35615
36716
|
`);
|
|
@@ -35617,7 +36718,7 @@ async function runCli(rawArgv) {
|
|
|
35617
36718
|
return;
|
|
35618
36719
|
}
|
|
35619
36720
|
try {
|
|
35620
|
-
parseEmbedModel(JSON.parse(
|
|
36721
|
+
parseEmbedModel(JSON.parse(body22), url);
|
|
35621
36722
|
} catch (e) {
|
|
35622
36723
|
process.stderr.write(
|
|
35623
36724
|
`codeindex: pull failed \u2014 response is not a valid model.json (${e instanceof Error ? e.message : String(e)}) (nothing written)
|
|
@@ -35626,7 +36727,7 @@ async function runCli(rawArgv) {
|
|
|
35626
36727
|
process.exitCode = 1;
|
|
35627
36728
|
return;
|
|
35628
36729
|
}
|
|
35629
|
-
writeFileSync4(join23(destDir, "model.json"),
|
|
36730
|
+
writeFileSync4(join23(destDir, "model.json"), body22);
|
|
35630
36731
|
process.stderr.write(`codeindex: model written to ${join23(destDir, "model.json")}
|
|
35631
36732
|
`);
|
|
35632
36733
|
} else {
|
|
@@ -35904,10 +37005,10 @@ function parseCaptureProvenance(source) {
|
|
|
35904
37005
|
const head = source.length > SCAN_LIMIT ? source.slice(0, SCAN_LIMIT) : source;
|
|
35905
37006
|
const m = MARKER.exec(head);
|
|
35906
37007
|
if (!m) return void 0;
|
|
35907
|
-
const
|
|
37008
|
+
const body3 = m[1] ?? "";
|
|
35908
37009
|
const kv = /* @__PURE__ */ new Map();
|
|
35909
37010
|
PAIR.lastIndex = 0;
|
|
35910
|
-
for (let p = PAIR.exec(
|
|
37011
|
+
for (let p = PAIR.exec(body3); p; p = PAIR.exec(body3)) {
|
|
35911
37012
|
kv.set(p[1], unescapeCommentValue(p[2]));
|
|
35912
37013
|
}
|
|
35913
37014
|
const vRaw = kv.get("v");
|
|
@@ -39078,18 +40179,18 @@ var labelInNameMismatch = {
|
|
|
39078
40179
|
const ariaLabel = (attr(el, "aria-label") ?? "").trim();
|
|
39079
40180
|
if (!ariaLabel || ariaLabel.includes("{")) continue;
|
|
39080
40181
|
if (hasAttr(el, "aria-labelledby")) continue;
|
|
39081
|
-
const
|
|
39082
|
-
if (!
|
|
39083
|
-
if (
|
|
40182
|
+
const visible2 = visibleText(el).trim();
|
|
40183
|
+
if (!visible2 || visible2.includes("{")) continue;
|
|
40184
|
+
if (visible2.length < 3) continue;
|
|
39084
40185
|
if (mayInjectContent(el)) continue;
|
|
39085
40186
|
const name2 = normalizeName(ariaLabel);
|
|
39086
|
-
const label = normalizeName(
|
|
40187
|
+
const label = normalizeName(visible2);
|
|
39087
40188
|
if (!label || !name2 || name2.includes(label)) continue;
|
|
39088
40189
|
out2.push({
|
|
39089
40190
|
criteriaId: "2.5.3",
|
|
39090
40191
|
el,
|
|
39091
40192
|
msgId: "label-in-name-mismatch",
|
|
39092
|
-
params: { visible, name: ariaLabel }
|
|
40193
|
+
params: { visible: visible2, name: ariaLabel }
|
|
39093
40194
|
});
|
|
39094
40195
|
}
|
|
39095
40196
|
return out2;
|
|
@@ -40259,10 +41360,10 @@ function crc32(buf) {
|
|
|
40259
41360
|
function chunk(type, data2) {
|
|
40260
41361
|
const len = Buffer.alloc(4);
|
|
40261
41362
|
len.writeUInt32BE(data2.length);
|
|
40262
|
-
const
|
|
41363
|
+
const body3 = Buffer.concat([Buffer.from(type, "latin1"), data2]);
|
|
40263
41364
|
const crc = Buffer.alloc(4);
|
|
40264
|
-
crc.writeUInt32BE(crc32(
|
|
40265
|
-
return Buffer.concat([len,
|
|
41365
|
+
crc.writeUInt32BE(crc32(body3));
|
|
41366
|
+
return Buffer.concat([len, body3, crc]);
|
|
40266
41367
|
}
|
|
40267
41368
|
function encodePng(r) {
|
|
40268
41369
|
const expected = r.width * r.height * 4;
|
|
@@ -41169,6 +42270,9 @@ function runCrossRules(doc, graph) {
|
|
|
41169
42270
|
return { findings, suppress };
|
|
41170
42271
|
}
|
|
41171
42272
|
|
|
42273
|
+
// src/standards/registry.ts
|
|
42274
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
42275
|
+
|
|
41172
42276
|
// src/data/standards/rgaa.json
|
|
41173
42277
|
var rgaa_default = {
|
|
41174
42278
|
key: "rgaa",
|
|
@@ -45652,6 +46756,57 @@ function formatIssues(issues) {
|
|
|
45652
46756
|
// src/standards/registry.ts
|
|
45653
46757
|
var CORE_KEY = "wcag";
|
|
45654
46758
|
var registry = /* @__PURE__ */ new Map();
|
|
46759
|
+
var overlays = /* @__PURE__ */ new Map();
|
|
46760
|
+
var scopeStore = new AsyncLocalStorage();
|
|
46761
|
+
function currentOverlay() {
|
|
46762
|
+
const scope = scopeStore.getStore();
|
|
46763
|
+
return scope === void 0 ? void 0 : overlays.get(scope);
|
|
46764
|
+
}
|
|
46765
|
+
function lookup(key) {
|
|
46766
|
+
return currentOverlay()?.get(key) ?? registry.get(key);
|
|
46767
|
+
}
|
|
46768
|
+
function visible() {
|
|
46769
|
+
const overlay = currentOverlay();
|
|
46770
|
+
if (!overlay?.size) return registry;
|
|
46771
|
+
const merged = new Map(registry);
|
|
46772
|
+
for (const [key, entry] of overlay) merged.set(key, entry);
|
|
46773
|
+
return merged;
|
|
46774
|
+
}
|
|
46775
|
+
function withScope(scope, fn) {
|
|
46776
|
+
return scope === void 0 ? fn() : scopeStore.run(scope, fn);
|
|
46777
|
+
}
|
|
46778
|
+
function registerScoped(scope, raw, glossary = {}, opts = {}) {
|
|
46779
|
+
const overlay = ensureScope(scope);
|
|
46780
|
+
const known = /* @__PURE__ */ new Set([CORE_KEY, ...registry.keys(), ...overlay.keys()]);
|
|
46781
|
+
const v = validatePack(raw, { knownKeys: known, allowOverride: opts.override });
|
|
46782
|
+
if (v.ok && v.pack) overlay.set(v.pack.key, { pack: v.pack, glossary });
|
|
46783
|
+
return v;
|
|
46784
|
+
}
|
|
46785
|
+
function packForMutation(key) {
|
|
46786
|
+
const overlay = currentOverlay();
|
|
46787
|
+
if (!overlay) return loadPack(key);
|
|
46788
|
+
const own = overlay.get(key);
|
|
46789
|
+
if (own) return own.pack;
|
|
46790
|
+
const shared = registry.get(key);
|
|
46791
|
+
if (!shared) return loadPack(key);
|
|
46792
|
+
const copy = { pack: structuredClone(shared.pack), glossary: shared.glossary };
|
|
46793
|
+
overlay.set(key, copy);
|
|
46794
|
+
return copy.pack;
|
|
46795
|
+
}
|
|
46796
|
+
function ensureScope(scope) {
|
|
46797
|
+
let overlay = overlays.get(scope);
|
|
46798
|
+
if (!overlay) {
|
|
46799
|
+
overlay = /* @__PURE__ */ new Map();
|
|
46800
|
+
overlays.set(scope, overlay);
|
|
46801
|
+
}
|
|
46802
|
+
return overlay;
|
|
46803
|
+
}
|
|
46804
|
+
function scopeLoaded(scope) {
|
|
46805
|
+
return overlays.has(scope);
|
|
46806
|
+
}
|
|
46807
|
+
function dropScope(scope) {
|
|
46808
|
+
overlays.delete(scope);
|
|
46809
|
+
}
|
|
45655
46810
|
function register(pack, glossary) {
|
|
45656
46811
|
if (pack.key === CORE_KEY) throw new Error(`pack key "${CORE_KEY}" is reserved for the WCAG core`);
|
|
45657
46812
|
registry.set(pack.key, { pack, glossary });
|
|
@@ -45663,7 +46818,7 @@ function registerRuntimePack(raw, glossary = {}, opts = {}) {
|
|
|
45663
46818
|
return v;
|
|
45664
46819
|
}
|
|
45665
46820
|
function enableSecondaryMapping(packKey, m) {
|
|
45666
|
-
const pack =
|
|
46821
|
+
const pack = packForMutation(packKey);
|
|
45667
46822
|
const list = pack.secondaryMappings ??= [];
|
|
45668
46823
|
const existing = list.find((x) => x.ruleId === m.ruleId && x.criterion === m.criterion);
|
|
45669
46824
|
if (existing) {
|
|
@@ -45677,28 +46832,28 @@ function isCore(key) {
|
|
|
45677
46832
|
return key === CORE_KEY;
|
|
45678
46833
|
}
|
|
45679
46834
|
function hasStandard(key) {
|
|
45680
|
-
return key === CORE_KEY ||
|
|
46835
|
+
return key === CORE_KEY || lookup(key) !== void 0;
|
|
45681
46836
|
}
|
|
45682
46837
|
function loadPack(key) {
|
|
45683
|
-
const r =
|
|
45684
|
-
if (!r) throw new Error(`unknown standards pack "${key}" (known packs: ${[...
|
|
46838
|
+
const r = lookup(key);
|
|
46839
|
+
if (!r) throw new Error(`unknown standards pack "${key}" (known packs: ${[...visible().keys()].join(", ") || "none"})`);
|
|
45685
46840
|
return r.pack;
|
|
45686
46841
|
}
|
|
45687
46842
|
function getPack(key) {
|
|
45688
|
-
return
|
|
46843
|
+
return lookup(key)?.pack;
|
|
45689
46844
|
}
|
|
45690
46845
|
function packGlossary(key) {
|
|
45691
|
-
return
|
|
46846
|
+
return lookup(key)?.glossary;
|
|
45692
46847
|
}
|
|
45693
46848
|
function listStandards() {
|
|
45694
|
-
return [CORE_KEY, ...
|
|
46849
|
+
return [CORE_KEY, ...visible().keys()];
|
|
45695
46850
|
}
|
|
45696
46851
|
function listPacks() {
|
|
45697
|
-
return [...
|
|
46852
|
+
return [...visible().values()].map((r) => r.pack);
|
|
45698
46853
|
}
|
|
45699
46854
|
function packsForSc(sc) {
|
|
45700
46855
|
const out2 = [];
|
|
45701
|
-
for (const { pack } of
|
|
46856
|
+
for (const { pack } of visible().values()) {
|
|
45702
46857
|
const ids = pack.criteria.filter((c2) => c2.wcag.includes(sc)).map((c2) => c2.id);
|
|
45703
46858
|
if (ids.length) out2.push({ key: pack.key, ids });
|
|
45704
46859
|
}
|
|
@@ -45974,11 +47129,11 @@ function extractGraphNode(ast, doc, file, opts = {}) {
|
|
|
45974
47129
|
return { file: posix3, imports, components, definesIds, providesHtmlLang, starReexports, opaqueComponents };
|
|
45975
47130
|
};
|
|
45976
47131
|
if (!ast) return finish();
|
|
45977
|
-
const
|
|
47132
|
+
const body3 = asNodes((asNode(ast.program) ?? ast).body);
|
|
45978
47133
|
const register2 = (def) => {
|
|
45979
47134
|
if (!components.has(def.name)) components.set(def.name, def);
|
|
45980
47135
|
};
|
|
45981
|
-
for (const stmt of
|
|
47136
|
+
for (const stmt of body3) {
|
|
45982
47137
|
if (stmt.type === "ImportDeclaration") {
|
|
45983
47138
|
const source = asNode(stmt.source);
|
|
45984
47139
|
const spec = source && typeof source.value === "string" ? source.value : "";
|
|
@@ -46530,6 +47685,9 @@ function localize(pack, s, lang) {
|
|
|
46530
47685
|
if (!s) return "";
|
|
46531
47686
|
return s[lang] ?? s[pack.defaultLocale] ?? s.en ?? Object.values(s)[0] ?? "";
|
|
46532
47687
|
}
|
|
47688
|
+
function allCriteria(pack) {
|
|
47689
|
+
return pack.criteria;
|
|
47690
|
+
}
|
|
46533
47691
|
function getCriterion(pack, id) {
|
|
46534
47692
|
return pack.criteria.find((c2) => c2.id === id);
|
|
46535
47693
|
}
|
|
@@ -46556,6 +47714,17 @@ function packTestIds(pack, id) {
|
|
|
46556
47714
|
function resolveGlossary(packKey, anchor) {
|
|
46557
47715
|
return packGlossary(packKey)?.[anchor];
|
|
46558
47716
|
}
|
|
47717
|
+
var GLOSSARY_REF = /\[[^\]]+\]\(#([^)]+)\)/g;
|
|
47718
|
+
function glossaryAnchorsOf(crit) {
|
|
47719
|
+
if (!crit) return [];
|
|
47720
|
+
const texts = [...Object.values(crit.tests ?? {}).flat(), ...crit.technicalNote ?? [], ...crit.particularCases ?? []];
|
|
47721
|
+
const seen = /* @__PURE__ */ new Set();
|
|
47722
|
+
for (const t2 of texts) {
|
|
47723
|
+
GLOSSARY_REF.lastIndex = 0;
|
|
47724
|
+
for (let m = GLOSSARY_REF.exec(t2); m; m = GLOSSARY_REF.exec(t2)) if (m[1]) seen.add(m[1]);
|
|
47725
|
+
}
|
|
47726
|
+
return [...seen];
|
|
47727
|
+
}
|
|
46559
47728
|
function neutralizeCaptureGroups(pattern) {
|
|
46560
47729
|
let out2 = "";
|
|
46561
47730
|
for (let i2 = 0; i2 < pattern.length; i2++) {
|
|
@@ -49162,11 +50331,282 @@ var rgaa_default2 = {
|
|
|
49162
50331
|
]
|
|
49163
50332
|
};
|
|
49164
50333
|
|
|
50334
|
+
// src/data/guidance/wcag.json
|
|
50335
|
+
var wcag_default2 = {
|
|
50336
|
+
pack: "wcag",
|
|
50337
|
+
source: "https://www.w3.org/WAI/WCAG22/Understanding/",
|
|
50338
|
+
license: "W3C Document License",
|
|
50339
|
+
attribution: "Derived from the W3C Understanding WCAG 2.2 documents. WCAG 2.2 \xA9 W3C. Short derived summaries and minimal illustrative examples only, not verbatim prose \u2014 see NOTICE.",
|
|
50340
|
+
entries: [
|
|
50341
|
+
{
|
|
50342
|
+
id: "media-live-captions",
|
|
50343
|
+
criterionId: "1.2.4",
|
|
50344
|
+
wcag: ["1.2.4"],
|
|
50345
|
+
title: {
|
|
50346
|
+
en: "Live synchronized media is captioned",
|
|
50347
|
+
fr: "Le m\xE9dia synchronis\xE9 en direct est sous-titr\xE9"
|
|
50348
|
+
},
|
|
50349
|
+
summary: {
|
|
50350
|
+
en: "Live audio in synchronized media needs real-time captions. A player with no caption track leaves deaf and hard-of-hearing users with nothing, and a pre-recorded transcript published afterwards does not satisfy a live criterion.",
|
|
50351
|
+
fr: "L'audio en direct d'un m\xE9dia synchronis\xE9 exige des sous-titres en temps r\xE9el. Un lecteur sans piste de sous-titres ne laisse rien aux personnes sourdes ou malentendantes, et une transcription publi\xE9e apr\xE8s coup ne satisfait pas un crit\xE8re \xAB en direct \xBB."
|
|
50352
|
+
},
|
|
50353
|
+
impact: "high",
|
|
50354
|
+
examples: [
|
|
50355
|
+
{
|
|
50356
|
+
lang: "html",
|
|
50357
|
+
bad: '<video src="/live/stream.m3u8" controls></video>',
|
|
50358
|
+
good: '<video src="/live/stream.m3u8" controls>\n <track kind="captions" srclang="en" label="English (live)" src="/live/captions.vtt" default>\n</video>',
|
|
50359
|
+
note: {
|
|
50360
|
+
en: "The caption track must be fed in real time (a live captioner or a live ASR service). Publishing a transcript after the broadcast is a different criterion.",
|
|
50361
|
+
fr: "La piste doit \xEAtre aliment\xE9e en temps r\xE9el (sous-titrage humain ou reconnaissance vocale en direct). Publier une transcription apr\xE8s la diffusion rel\xE8ve d'un autre crit\xE8re."
|
|
50362
|
+
}
|
|
50363
|
+
}
|
|
50364
|
+
],
|
|
50365
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/captions-live.html"
|
|
50366
|
+
},
|
|
50367
|
+
{
|
|
50368
|
+
id: "motion-three-flashes",
|
|
50369
|
+
criterionId: "2.3.1",
|
|
50370
|
+
wcag: ["2.3.1"],
|
|
50371
|
+
title: {
|
|
50372
|
+
en: "Nothing flashes more than three times a second",
|
|
50373
|
+
fr: "Rien ne clignote plus de trois fois par seconde"
|
|
50374
|
+
},
|
|
50375
|
+
summary: {
|
|
50376
|
+
en: "Content that flashes more than three times in any one second can trigger a seizure. This is the one accessibility failure that can cause physical harm, so it is not a matter of preference: slow the flash below the threshold, or remove it.",
|
|
50377
|
+
fr: "Un contenu qui clignote plus de trois fois par seconde peut d\xE9clencher une crise d'\xE9pilepsie. C'est le seul d\xE9faut d'accessibilit\xE9 qui peut causer un dommage physique : il faut ralentir le clignotement sous le seuil, ou le supprimer."
|
|
50378
|
+
},
|
|
50379
|
+
impact: "high",
|
|
50380
|
+
examples: [
|
|
50381
|
+
{
|
|
50382
|
+
lang: "css",
|
|
50383
|
+
bad: ".alert {\n animation: flash 0.15s steps(1) infinite;\n}",
|
|
50384
|
+
good: ".alert {\n animation: flash 1s steps(1) infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .alert {\n animation: none;\n }\n}",
|
|
50385
|
+
note: {
|
|
50386
|
+
en: "A 0.15s cycle flashes about seven times a second. Honouring prefers-reduced-motion is good practice but does not by itself satisfy this criterion \u2014 the default must already be safe.",
|
|
50387
|
+
fr: "Un cycle de 0,15 s clignote environ sept fois par seconde. Respecter prefers-reduced-motion est une bonne pratique mais ne suffit pas : le comportement par d\xE9faut doit d\xE9j\xE0 \xEAtre s\xFBr."
|
|
50388
|
+
}
|
|
50389
|
+
}
|
|
50390
|
+
],
|
|
50391
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/three-flashes-or-below-threshold.html"
|
|
50392
|
+
},
|
|
50393
|
+
{
|
|
50394
|
+
id: "navigation-multiple-ways",
|
|
50395
|
+
criterionId: "2.4.5",
|
|
50396
|
+
wcag: ["2.4.5"],
|
|
50397
|
+
title: {
|
|
50398
|
+
en: "More than one way to reach a page",
|
|
50399
|
+
fr: "Plus d'un moyen d'atteindre une page"
|
|
50400
|
+
},
|
|
50401
|
+
summary: {
|
|
50402
|
+
en: "A site offers at least two ways to locate a page \u2014 for example a menu plus a search, or a sitemap. Users who find hierarchical menus hard to navigate need another route; the exception is a page that is a step in a process.",
|
|
50403
|
+
fr: "Un site propose au moins deux moyens d'atteindre une page \u2014 par exemple un menu et une recherche, ou un plan du site. Les personnes pour qui la navigation hi\xE9rarchique est difficile ont besoin d'une autre voie ; l'exception est une page qui constitue une \xE9tape d'un processus."
|
|
50404
|
+
},
|
|
50405
|
+
impact: "medium",
|
|
50406
|
+
examples: [
|
|
50407
|
+
{
|
|
50408
|
+
lang: "html",
|
|
50409
|
+
bad: '<nav aria-label="Main">\n <a href="/products">Products</a>\n <a href="/support">Support</a>\n</nav>',
|
|
50410
|
+
good: '<nav aria-label="Main">\n <a href="/products">Products</a>\n <a href="/support">Support</a>\n</nav>\n<form role="search" action="/search">\n <label for="q">Search the site</label>\n <input id="q" name="q" type="search">\n <button type="submit">Search</button>\n</form>\n<a href="/sitemap">Sitemap</a>',
|
|
50411
|
+
note: {
|
|
50412
|
+
en: "Two mechanisms, not two links to the same menu. A search and a sitemap are each a second way; a duplicated navigation bar is not.",
|
|
50413
|
+
fr: "Deux m\xE9canismes, pas deux liens vers le m\xEAme menu. Une recherche et un plan du site sont chacun un second moyen ; une barre de navigation dupliqu\xE9e non."
|
|
50414
|
+
}
|
|
50415
|
+
}
|
|
50416
|
+
],
|
|
50417
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/multiple-ways.html"
|
|
50418
|
+
},
|
|
50419
|
+
{
|
|
50420
|
+
id: "focus-not-obscured",
|
|
50421
|
+
criterionId: "2.4.11",
|
|
50422
|
+
wcag: ["2.4.11"],
|
|
50423
|
+
title: {
|
|
50424
|
+
en: "The focused element is not hidden behind sticky content",
|
|
50425
|
+
fr: "L'\xE9l\xE9ment qui a le focus n'est pas masqu\xE9 par un contenu collant"
|
|
50426
|
+
},
|
|
50427
|
+
summary: {
|
|
50428
|
+
en: "When a component takes keyboard focus it must not be entirely covered by author content such as a sticky header, footer or cookie banner. A keyboard user who cannot see where focus went has lost the page.",
|
|
50429
|
+
fr: "Quand un composant re\xE7oit le focus clavier, il ne doit pas \xEAtre enti\xE8rement recouvert par un contenu de l'auteur : en-t\xEAte ou pied de page collant, bandeau cookies. Une personne naviguant au clavier qui ne voit plus o\xF9 est le focus a perdu la page."
|
|
50430
|
+
},
|
|
50431
|
+
impact: "high",
|
|
50432
|
+
examples: [
|
|
50433
|
+
{
|
|
50434
|
+
lang: "css",
|
|
50435
|
+
bad: ".site-footer {\n position: fixed;\n bottom: 0;\n height: 5rem;\n}",
|
|
50436
|
+
good: ".site-footer {\n position: fixed;\n bottom: 0;\n height: 5rem;\n}\n\n:target,\n:focus {\n scroll-margin-bottom: 6rem;\n}",
|
|
50437
|
+
note: {
|
|
50438
|
+
en: "scroll-margin keeps the browser from scrolling the focused element flush against the sticky bar. Verify it by tabbing through the page, not by reading the stylesheet \u2014 this criterion is decided on the render.",
|
|
50439
|
+
fr: "scroll-margin emp\xEAche le navigateur de coller l'\xE9l\xE9ment focalis\xE9 contre la barre fixe. \xC0 v\xE9rifier en tabulant r\xE9ellement dans la page, pas en lisant la feuille de styles : ce crit\xE8re se tranche au rendu."
|
|
50440
|
+
}
|
|
50441
|
+
}
|
|
50442
|
+
],
|
|
50443
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html"
|
|
50444
|
+
},
|
|
50445
|
+
{
|
|
50446
|
+
id: "pointer-dragging-alternative",
|
|
50447
|
+
criterionId: "2.5.7",
|
|
50448
|
+
wcag: ["2.5.7"],
|
|
50449
|
+
title: {
|
|
50450
|
+
en: "Anything you can drag, you can also do without dragging",
|
|
50451
|
+
fr: "Tout ce qui se fait par glissement se fait aussi autrement"
|
|
50452
|
+
},
|
|
50453
|
+
summary: {
|
|
50454
|
+
en: "A function operated by a dragging movement also works with a single pointer action \u2014 a button, a menu, a form field. Dragging needs sustained precision that users with tremor, limited dexterity or a head pointer may not have.",
|
|
50455
|
+
fr: "Une fonctionnalit\xE9 actionn\xE9e par glissement doit aussi fonctionner par une action de pointeur simple : un bouton, un menu, un champ. Le glissement exige une pr\xE9cision continue dont ne disposent pas les personnes avec tremblements, dext\xE9rit\xE9 r\xE9duite ou pointeur de t\xEAte."
|
|
50456
|
+
},
|
|
50457
|
+
impact: "high",
|
|
50458
|
+
examples: [
|
|
50459
|
+
{
|
|
50460
|
+
lang: "html",
|
|
50461
|
+
bad: '<ul id="queue" data-sortable="drag">\n <li draggable="true">First task</li>\n <li draggable="true">Second task</li>\n</ul>',
|
|
50462
|
+
good: '<ul id="queue" data-sortable="drag">\n <li draggable="true">\n First task\n <button type="button" data-move="up">Move up</button>\n <button type="button" data-move="down">Move down</button>\n </li>\n</ul>',
|
|
50463
|
+
note: {
|
|
50464
|
+
en: "The drag stays; a single-pointer path is added beside it. The exception is when dragging is essential to the function, such as freehand drawing.",
|
|
50465
|
+
fr: "Le glissement reste ; un chemin en pointeur simple est ajout\xE9 \xE0 c\xF4t\xE9. L'exception est le cas o\xF9 le glissement est essentiel \xE0 la fonction, comme le dessin \xE0 main lev\xE9e."
|
|
50466
|
+
}
|
|
50467
|
+
}
|
|
50468
|
+
],
|
|
50469
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html"
|
|
50470
|
+
},
|
|
50471
|
+
{
|
|
50472
|
+
id: "pointer-target-size",
|
|
50473
|
+
criterionId: "2.5.8",
|
|
50474
|
+
wcag: ["2.5.8"],
|
|
50475
|
+
title: {
|
|
50476
|
+
en: "Pointer targets are at least 24 by 24 CSS pixels",
|
|
50477
|
+
fr: "Les cibles de pointeur mesurent au moins 24 sur 24 pixels CSS"
|
|
50478
|
+
},
|
|
50479
|
+
summary: {
|
|
50480
|
+
en: "A target smaller than 24\xD724 CSS pixels needs enough spacing that a 24-pixel circle centred on it touches no other target. Small, tightly packed controls are hard to hit for anyone with a tremor or using a touchscreen one-handed.",
|
|
50481
|
+
fr: "Une cible de moins de 24\xD724 pixels CSS doit \xEAtre assez espac\xE9e pour qu'un cercle de 24 pixels centr\xE9 dessus ne touche aucune autre cible. Des contr\xF4les petits et serr\xE9s sont difficiles \xE0 atteindre en cas de tremblement ou d'usage \xE0 une main sur \xE9cran tactile."
|
|
50482
|
+
},
|
|
50483
|
+
impact: "medium",
|
|
50484
|
+
examples: [
|
|
50485
|
+
{
|
|
50486
|
+
lang: "css",
|
|
50487
|
+
bad: ".icon-button {\n width: 16px;\n height: 16px;\n padding: 0;\n}",
|
|
50488
|
+
good: ".icon-button {\n min-width: 24px;\n min-height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}",
|
|
50489
|
+
note: {
|
|
50490
|
+
en: "The 24px is the target, not the icon: padding counts. Inline links in a sentence are excepted, as are targets whose size is set by the user agent.",
|
|
50491
|
+
fr: "Les 24 px concernent la cible, pas l'ic\xF4ne : le padding compte. Les liens en ligne dans une phrase sont except\xE9s, comme les cibles dimensionn\xE9es par le navigateur."
|
|
50492
|
+
}
|
|
50493
|
+
}
|
|
50494
|
+
],
|
|
50495
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html"
|
|
50496
|
+
},
|
|
50497
|
+
{
|
|
50498
|
+
id: "navigation-consistent-help",
|
|
50499
|
+
criterionId: "3.2.6",
|
|
50500
|
+
wcag: ["3.2.6"],
|
|
50501
|
+
title: {
|
|
50502
|
+
en: "Help is in the same place on every page",
|
|
50503
|
+
fr: "L'aide se trouve au m\xEAme endroit sur chaque page"
|
|
50504
|
+
},
|
|
50505
|
+
summary: {
|
|
50506
|
+
en: "If a set of pages offers help \u2014 a contact link, a phone number, a chat widget \u2014 it appears in the same relative order on each of them. Users who rely on spatial memory should not have to re-find it page by page.",
|
|
50507
|
+
fr: "Si un ensemble de pages propose une aide \u2014 lien de contact, num\xE9ro de t\xE9l\xE9phone, widget de discussion \u2014 elle appara\xEEt dans le m\xEAme ordre relatif sur chacune. Les personnes qui s'appuient sur la m\xE9moire spatiale ne devraient pas avoir \xE0 la rechercher page par page."
|
|
50508
|
+
},
|
|
50509
|
+
impact: "low",
|
|
50510
|
+
examples: [
|
|
50511
|
+
{
|
|
50512
|
+
lang: "html",
|
|
50513
|
+
bad: '<header>\n <a href="/contact">Contact us</a>\n <nav>...</nav>\n</header>',
|
|
50514
|
+
good: '<header>\n <nav>...</nav>\n <a href="/contact">Contact us</a>\n</header>',
|
|
50515
|
+
note: {
|
|
50516
|
+
en: "Same relative order, not identical pixels \u2014 a responsive layout may move it. The criterion is about where it falls in the page, consistently.",
|
|
50517
|
+
fr: "M\xEAme ordre relatif, pas les m\xEAmes pixels : une mise en page responsive peut le d\xE9placer. Le crit\xE8re porte sur sa position dans la page, de fa\xE7on constante."
|
|
50518
|
+
}
|
|
50519
|
+
}
|
|
50520
|
+
],
|
|
50521
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/consistent-help.html"
|
|
50522
|
+
},
|
|
50523
|
+
{
|
|
50524
|
+
id: "forms-error-suggestion",
|
|
50525
|
+
criterionId: "3.3.3",
|
|
50526
|
+
wcag: ["3.3.3"],
|
|
50527
|
+
title: {
|
|
50528
|
+
en: "An error message says how to fix it",
|
|
50529
|
+
fr: "Un message d'erreur indique comment corriger"
|
|
50530
|
+
},
|
|
50531
|
+
summary: {
|
|
50532
|
+
en: 'When input is rejected and a correction is known, the message names it. "Invalid" tells the user only that they failed; the expected format, or the nearest valid value, tells them what to do next.',
|
|
50533
|
+
fr: "Quand une saisie est refus\xE9e et qu'une correction est connue, le message l'indique. \xAB Invalide \xBB n'apprend \xE0 l'utilisateur que son \xE9chec ; le format attendu, ou la valeur valide la plus proche, lui dit quoi faire."
|
|
50534
|
+
},
|
|
50535
|
+
impact: "high",
|
|
50536
|
+
examples: [
|
|
50537
|
+
{
|
|
50538
|
+
lang: "html",
|
|
50539
|
+
bad: '<input id="born" name="born" aria-describedby="born-err">\n<p id="born-err">Invalid input.</p>',
|
|
50540
|
+
good: '<label for="born">Date of birth</label>\n<input id="born" name="born" aria-describedby="born-err" aria-invalid="true">\n<p id="born-err">Enter the date as DD/MM/YYYY, for example 21/03/1994.</p>',
|
|
50541
|
+
note: {
|
|
50542
|
+
en: "The suggestion must be programmatically associated with the field, not merely nearby \u2014 aria-describedby is what makes a screen reader announce it with the input.",
|
|
50543
|
+
fr: "La suggestion doit \xEAtre associ\xE9e programmatiquement au champ, pas seulement plac\xE9e \xE0 c\xF4t\xE9 : c'est aria-describedby qui la fait annoncer avec la saisie."
|
|
50544
|
+
}
|
|
50545
|
+
}
|
|
50546
|
+
],
|
|
50547
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/error-suggestion.html"
|
|
50548
|
+
},
|
|
50549
|
+
{
|
|
50550
|
+
id: "forms-redundant-entry",
|
|
50551
|
+
criterionId: "3.3.7",
|
|
50552
|
+
wcag: ["3.3.7"],
|
|
50553
|
+
title: {
|
|
50554
|
+
en: "Information already entered is not asked for again",
|
|
50555
|
+
fr: "Une information d\xE9j\xE0 saisie n'est pas redemand\xE9e"
|
|
50556
|
+
},
|
|
50557
|
+
summary: {
|
|
50558
|
+
en: "Within a process, information the user already gave is auto-populated or offered for selection rather than retyped. Re-entry is a real barrier for users with memory impairments and for anyone typing with difficulty.",
|
|
50559
|
+
fr: "Au sein d'un processus, une information d\xE9j\xE0 fournie est pr\xE9-remplie ou propos\xE9e \xE0 la s\xE9lection plut\xF4t que ressaisie. La ressaisie est un obstacle r\xE9el en cas de troubles de la m\xE9moire et pour toute personne dont la saisie est difficile."
|
|
50560
|
+
},
|
|
50561
|
+
impact: "medium",
|
|
50562
|
+
examples: [
|
|
50563
|
+
{
|
|
50564
|
+
lang: "html",
|
|
50565
|
+
bad: '<fieldset>\n <legend>Delivery address</legend>\n <label for="d-street">Street</label>\n <input id="d-street" name="d-street">\n</fieldset>',
|
|
50566
|
+
good: '<fieldset>\n <legend>Delivery address</legend>\n <label for="same">\n <input type="checkbox" id="same" name="same" checked>\n Same as my billing address\n </label>\n <label for="d-street">Street</label>\n <input id="d-street" name="d-street" value="12 Rue de Rivoli">\n</fieldset>',
|
|
50567
|
+
note: {
|
|
50568
|
+
en: "Exceptions exist where re-entry is essential \u2014 confirming a password, or a memory test. Convenience is not one of them.",
|
|
50569
|
+
fr: "Des exceptions existent quand la ressaisie est essentielle : confirmation de mot de passe, test de m\xE9moire. La commodit\xE9 n'en fait pas partie."
|
|
50570
|
+
}
|
|
50571
|
+
}
|
|
50572
|
+
],
|
|
50573
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry.html"
|
|
50574
|
+
},
|
|
50575
|
+
{
|
|
50576
|
+
id: "forms-accessible-authentication",
|
|
50577
|
+
criterionId: "3.3.8",
|
|
50578
|
+
wcag: ["3.3.8"],
|
|
50579
|
+
title: {
|
|
50580
|
+
en: "Signing in does not require a cognitive test",
|
|
50581
|
+
fr: "La connexion n'exige pas un test cognitif"
|
|
50582
|
+
},
|
|
50583
|
+
summary: {
|
|
50584
|
+
en: "No step of authentication may depend on remembering, transcribing or solving a puzzle unless an alternative exists. Blocking paste into a password field is the most common way sites fail this: it breaks every password manager.",
|
|
50585
|
+
fr: "Aucune \xE9tape d'authentification ne doit reposer sur la m\xE9morisation, la transcription ou la r\xE9solution d'une \xE9nigme, sauf alternative. Bloquer le collage dans un champ de mot de passe est l'\xE9chec le plus courant : cela casse tous les gestionnaires de mots de passe."
|
|
50586
|
+
},
|
|
50587
|
+
impact: "high",
|
|
50588
|
+
examples: [
|
|
50589
|
+
{
|
|
50590
|
+
lang: "html",
|
|
50591
|
+
bad: '<input type="password" id="pw" name="pw" onpaste="return false" autocomplete="off">',
|
|
50592
|
+
good: '<label for="pw">Password</label>\n<input type="password" id="pw" name="pw" autocomplete="current-password">',
|
|
50593
|
+
note: {
|
|
50594
|
+
en: 'autocomplete="current-password" lets a password manager fill the field, which is the documented way to satisfy this criterion. A puzzle CAPTCHA needs a non-cognitive alternative beside it.',
|
|
50595
|
+
fr: 'autocomplete="current-password" permet \xE0 un gestionnaire de remplir le champ, ce qui est la fa\xE7on document\xE9e de satisfaire ce crit\xE8re. Un CAPTCHA \xE0 \xE9nigme exige une alternative non cognitive \xE0 c\xF4t\xE9.'
|
|
50596
|
+
}
|
|
50597
|
+
}
|
|
50598
|
+
],
|
|
50599
|
+
reference: "https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum.html"
|
|
50600
|
+
}
|
|
50601
|
+
]
|
|
50602
|
+
};
|
|
50603
|
+
|
|
49165
50604
|
// src/guidance/index.ts
|
|
49166
50605
|
var datasets = /* @__PURE__ */ new Map();
|
|
49167
50606
|
function add(ds) {
|
|
49168
50607
|
datasets.set(ds.pack, ds);
|
|
49169
50608
|
}
|
|
50609
|
+
add(wcag_default2);
|
|
49170
50610
|
add(rgaa_default2);
|
|
49171
50611
|
function registerRuntimeGuidance(ds) {
|
|
49172
50612
|
add(ds);
|
|
@@ -49182,6 +50622,9 @@ function guidanceForCriterion(packKey, criterionId) {
|
|
|
49182
50622
|
function hasGuidance(packKey) {
|
|
49183
50623
|
return datasets.has(packKey);
|
|
49184
50624
|
}
|
|
50625
|
+
function getDataset(packKey) {
|
|
50626
|
+
return datasets.get(packKey);
|
|
50627
|
+
}
|
|
49185
50628
|
|
|
49186
50629
|
// src/config.ts
|
|
49187
50630
|
var CONFIG_FILE = ".ultra11yrc.json";
|
|
@@ -49214,7 +50657,11 @@ function packPaths(path) {
|
|
|
49214
50657
|
}
|
|
49215
50658
|
return { pack: path };
|
|
49216
50659
|
}
|
|
49217
|
-
function loadRuntimeStandards(cwd, packFlags, onWarn, override = false) {
|
|
50660
|
+
function loadRuntimeStandards(cwd, packFlags, onWarn, override = false, opts = {}) {
|
|
50661
|
+
return withScope(opts.scope, () => loadStandardsInto(cwd, packFlags, onWarn, override, opts));
|
|
50662
|
+
}
|
|
50663
|
+
function loadStandardsInto(cwd, packFlags, onWarn, override, opts) {
|
|
50664
|
+
if (opts.scope) ensureScope(opts.scope);
|
|
49218
50665
|
const result = { errors: [], loadedPacks: [], loadedGuidance: [] };
|
|
49219
50666
|
let config = null;
|
|
49220
50667
|
try {
|
|
@@ -49245,7 +50692,7 @@ function loadRuntimeStandards(cwd, packFlags, onWarn, override = false) {
|
|
|
49245
50692
|
onWarn(`ultra11y: ${paths.glossary} is not valid JSON \u2014 ignoring glossary.`);
|
|
49246
50693
|
}
|
|
49247
50694
|
}
|
|
49248
|
-
const v = registerRuntimePack(packObj, glossary, { override });
|
|
50695
|
+
const v = opts.scope ? registerScoped(opts.scope, packObj, glossary, { override }) : registerRuntimePack(packObj, glossary, { override });
|
|
49249
50696
|
for (const issue of v.issues) if (issue.severity === "warn") onWarn(`ultra11y: ${raw}: ${issue.path ? `${issue.path}: ` : ""}${issue.message}`);
|
|
49250
50697
|
if (!v.ok || !v.pack) {
|
|
49251
50698
|
result.errors.push(`--pack ${paths.pack}: invalid pack
|
|
@@ -49624,6 +51071,153 @@ function vocabularyFor(standard, lang) {
|
|
|
49624
51071
|
};
|
|
49625
51072
|
}
|
|
49626
51073
|
|
|
51074
|
+
// src/standards/coverage.ts
|
|
51075
|
+
var TIER_ORDER = ["source", "cross-file", "rendered-page", "browser"];
|
|
51076
|
+
var STATIC_RULE_IDS = new Set(ALL_RULES.map((r) => r.id));
|
|
51077
|
+
var CROSS_RULE_IDS = new Set(CROSS_RULES.map((r) => r.id));
|
|
51078
|
+
function ruleTier(ruleId, pack) {
|
|
51079
|
+
if (ruleId.startsWith("pack:")) return "source";
|
|
51080
|
+
if (ruleId.startsWith("agent:")) return "judgment";
|
|
51081
|
+
if (ruleId.startsWith("axe:") || ruleId.startsWith("dyn-")) return "browser";
|
|
51082
|
+
if (ruleId.startsWith("rendered-")) return "rendered-page";
|
|
51083
|
+
if (CROSS_RULE_IDS.has(ruleId)) return "cross-file";
|
|
51084
|
+
if (STATIC_RULE_IDS.has(ruleId)) return "source";
|
|
51085
|
+
if (pack && ruleId.endsWith("*")) return "source";
|
|
51086
|
+
return "source";
|
|
51087
|
+
}
|
|
51088
|
+
function cheapest(tiers) {
|
|
51089
|
+
for (const t2 of TIER_ORDER) if (tiers.includes(t2)) return t2;
|
|
51090
|
+
return void 0;
|
|
51091
|
+
}
|
|
51092
|
+
function dedupe(tiers) {
|
|
51093
|
+
return TIER_ORDER.filter((t2) => tiers.includes(t2));
|
|
51094
|
+
}
|
|
51095
|
+
function coreCoverage(sc) {
|
|
51096
|
+
const c2 = getSC(sc);
|
|
51097
|
+
if (!c2) return void 0;
|
|
51098
|
+
const engineRules = [...c2.ruleIds];
|
|
51099
|
+
const tiers = engineRules.map((r) => ruleTier(r));
|
|
51100
|
+
if (c2.automatability === "judgment") {
|
|
51101
|
+
return {
|
|
51102
|
+
tier: "judgment",
|
|
51103
|
+
sourceIsEnough: false,
|
|
51104
|
+
canFailFrom: dedupe(tiers),
|
|
51105
|
+
alsoNeeds: [],
|
|
51106
|
+
engineRules,
|
|
51107
|
+
applicabilityDeclared: true,
|
|
51108
|
+
why: "WCAG automatability class `judgment`: the evidence can be gathered, but the verdict is a reading of meaning."
|
|
51109
|
+
};
|
|
51110
|
+
}
|
|
51111
|
+
if (c2.automatability === "needs-rendering") {
|
|
51112
|
+
const tier2 = tiers.includes("rendered-page") ? "rendered-page" : "browser";
|
|
51113
|
+
return {
|
|
51114
|
+
tier: tier2,
|
|
51115
|
+
sourceIsEnough: false,
|
|
51116
|
+
canFailFrom: dedupe(tiers),
|
|
51117
|
+
alsoNeeds: dedupe(tiers).filter((t2) => t2 !== tier2),
|
|
51118
|
+
engineRules,
|
|
51119
|
+
applicabilityDeclared: true,
|
|
51120
|
+
why: tier2 === "rendered-page" ? "WCAG automatability class `needs-rendering`, and a rendered-* rule covers it: a captured page snapshot is enough, no live browser." : "WCAG automatability class `needs-rendering`: only a real browser produces this evidence."
|
|
51121
|
+
};
|
|
51122
|
+
}
|
|
51123
|
+
const tier = cheapest(tiers) ?? "source";
|
|
51124
|
+
return {
|
|
51125
|
+
tier,
|
|
51126
|
+
sourceIsEnough: tier === "source",
|
|
51127
|
+
canFailFrom: dedupe(tiers),
|
|
51128
|
+
alsoNeeds: dedupe(tiers).filter((t2) => t2 !== tier),
|
|
51129
|
+
engineRules,
|
|
51130
|
+
applicabilityDeclared: true,
|
|
51131
|
+
why: "WCAG automatability class `static`: an engine rule decides it from the source tree."
|
|
51132
|
+
};
|
|
51133
|
+
}
|
|
51134
|
+
function outOfCore(pc) {
|
|
51135
|
+
return pc.wcag.every((sc) => {
|
|
51136
|
+
const s = knownScStatus(sc);
|
|
51137
|
+
return s === "out-of-core" || s === "removed";
|
|
51138
|
+
});
|
|
51139
|
+
}
|
|
51140
|
+
function packCoverage(pack, pc) {
|
|
51141
|
+
if (outOfCore(pc)) {
|
|
51142
|
+
return {
|
|
51143
|
+
tier: "out-of-scope",
|
|
51144
|
+
sourceIsEnough: false,
|
|
51145
|
+
canFailFrom: [],
|
|
51146
|
+
alsoNeeds: [],
|
|
51147
|
+
engineRules: [],
|
|
51148
|
+
applicabilityDeclared: true,
|
|
51149
|
+
why: `every WCAG success criterion this maps to (${pc.wcag.join(", ")}) is outside the engine's 2.2 AA core \u2014 AAA or removed. Declare it out of scope; never claim conformity.`
|
|
51150
|
+
};
|
|
51151
|
+
}
|
|
51152
|
+
const declared = pc.appliesTo?.ruleIds;
|
|
51153
|
+
if (declared === void 0) {
|
|
51154
|
+
const tiers2 = pc.wcag.map((sc) => coreCoverage(sc)?.tier).filter((t2) => t2 !== void 0);
|
|
51155
|
+
const tier2 = tiers2.includes("judgment") ? "judgment" : cheapest(tiers2) ?? "judgment";
|
|
51156
|
+
return {
|
|
51157
|
+
tier: tier2,
|
|
51158
|
+
sourceIsEnough: tier2 === "source",
|
|
51159
|
+
canFailFrom: dedupe(tiers2),
|
|
51160
|
+
alsoNeeds: dedupe(tiers2).filter((t2) => t2 !== tier2),
|
|
51161
|
+
engineRules: [],
|
|
51162
|
+
applicabilityDeclared: false,
|
|
51163
|
+
why: "the pack declares no rule applicability, so this is inferred from the WCAG success criteria it maps to."
|
|
51164
|
+
};
|
|
51165
|
+
}
|
|
51166
|
+
const engineRules = [...declared];
|
|
51167
|
+
const tiers = engineRules.map((r) => ruleTier(r, pack));
|
|
51168
|
+
if (pc.judgment) {
|
|
51169
|
+
return {
|
|
51170
|
+
tier: "judgment",
|
|
51171
|
+
sourceIsEnough: false,
|
|
51172
|
+
canFailFrom: dedupe(tiers),
|
|
51173
|
+
alsoNeeds: [],
|
|
51174
|
+
engineRules,
|
|
51175
|
+
applicabilityDeclared: true,
|
|
51176
|
+
why: "the standard flags this criterion as judgment: it asks more than its mapped success criteria, so it never inherits a Conforming verdict \u2014 though an engine rule can still fail it."
|
|
51177
|
+
};
|
|
51178
|
+
}
|
|
51179
|
+
if (!engineRules.length) {
|
|
51180
|
+
return {
|
|
51181
|
+
tier: "judgment",
|
|
51182
|
+
sourceIsEnough: false,
|
|
51183
|
+
canFailFrom: [],
|
|
51184
|
+
alsoNeeds: [],
|
|
51185
|
+
engineRules,
|
|
51186
|
+
applicabilityDeclared: true,
|
|
51187
|
+
why: "the standard declares that no engine rule can evidence this criterion \u2014 it is yours to rule on."
|
|
51188
|
+
};
|
|
51189
|
+
}
|
|
51190
|
+
const tier = cheapest(tiers) ?? "judgment";
|
|
51191
|
+
return {
|
|
51192
|
+
tier,
|
|
51193
|
+
sourceIsEnough: tier === "source",
|
|
51194
|
+
canFailFrom: dedupe(tiers),
|
|
51195
|
+
alsoNeeds: dedupe(tiers).filter((t2) => t2 !== tier),
|
|
51196
|
+
engineRules,
|
|
51197
|
+
applicabilityDeclared: true,
|
|
51198
|
+
why: `the standard declares ${engineRules.length} applicable engine rule${engineRules.length === 1 ? "" : "s"}; the cheapest evidence tier among them is \`${tier}\`.`
|
|
51199
|
+
};
|
|
51200
|
+
}
|
|
51201
|
+
function criterionCoverage(standard, id) {
|
|
51202
|
+
if (isCore(standard)) return coreCoverage(id);
|
|
51203
|
+
const pack = loadPack(standard);
|
|
51204
|
+
const pc = getCriterion(pack, id);
|
|
51205
|
+
return pc ? packCoverage(pack, pc) : void 0;
|
|
51206
|
+
}
|
|
51207
|
+
function standardCoverage(standard) {
|
|
51208
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
51209
|
+
if (isCore(standard)) {
|
|
51210
|
+
for (const c2 of allSC()) {
|
|
51211
|
+
const cov = coreCoverage(c2.sc);
|
|
51212
|
+
if (cov) out2.set(c2.sc, cov);
|
|
51213
|
+
}
|
|
51214
|
+
return out2;
|
|
51215
|
+
}
|
|
51216
|
+
const pack = loadPack(standard);
|
|
51217
|
+
for (const pc of allCriteria(pack)) out2.set(pc.id, packCoverage(pack, pc));
|
|
51218
|
+
return out2;
|
|
51219
|
+
}
|
|
51220
|
+
|
|
49627
51221
|
// src/standards/index.ts
|
|
49628
51222
|
var CORE2 = CORE_KEY;
|
|
49629
51223
|
function resolveStandard(flag) {
|
|
@@ -49640,6 +51234,34 @@ function standardLabel(standard) {
|
|
|
49640
51234
|
return `${p.name} ${p.baseVersion}`;
|
|
49641
51235
|
}
|
|
49642
51236
|
|
|
51237
|
+
// src/guidance/resolve.ts
|
|
51238
|
+
var LANGS = ["en", "fr"];
|
|
51239
|
+
function languagesOf(e) {
|
|
51240
|
+
return LANGS.filter((l) => e.title?.[l] || e.summary?.[l]);
|
|
51241
|
+
}
|
|
51242
|
+
function resolveGuidance(standard, criterionId, wcagRefs) {
|
|
51243
|
+
const seen = /* @__PURE__ */ new Set();
|
|
51244
|
+
const out2 = [];
|
|
51245
|
+
const push = (entries, via, inherited) => {
|
|
51246
|
+
for (const entry of entries) {
|
|
51247
|
+
if (seen.has(entry.id)) continue;
|
|
51248
|
+
seen.add(entry.id);
|
|
51249
|
+
out2.push({ entry, via, inherited, languagesAvailable: languagesOf(entry) });
|
|
51250
|
+
}
|
|
51251
|
+
};
|
|
51252
|
+
if (isCore(standard)) {
|
|
51253
|
+
push(guidanceForWcag(criterionId), `wcag:${criterionId}`, false);
|
|
51254
|
+
return out2;
|
|
51255
|
+
}
|
|
51256
|
+
push(guidanceForCriterion(standard, criterionId), "pack", false);
|
|
51257
|
+
const refs = wcagRefs ?? getCriterion(getPack(standard), criterionId)?.wcag ?? [];
|
|
51258
|
+
for (const sc of refs) push(guidanceForWcag(sc), `wcag:${sc}`, true);
|
|
51259
|
+
return out2;
|
|
51260
|
+
}
|
|
51261
|
+
function guidanceEntriesFor(standard, criterionId, wcagRefs) {
|
|
51262
|
+
return resolveGuidance(standard, criterionId, wcagRefs).map((r) => r.entry);
|
|
51263
|
+
}
|
|
51264
|
+
|
|
49643
51265
|
// src/auditor.ts
|
|
49644
51266
|
var SEV_ORDER = ["bloquant", "majeur", "mineur"];
|
|
49645
51267
|
var ICON = { bloquant: "\u{1F534}", majeur: "\u{1F7E0}", mineur: "\u{1F7E1}" };
|
|
@@ -50083,21 +51705,7 @@ function effortOf(unit) {
|
|
|
50083
51705
|
return { bucket: points <= 4 ? "S" : points <= 12 ? "M" : "L", points };
|
|
50084
51706
|
}
|
|
50085
51707
|
function guidanceFor(unit, standard) {
|
|
50086
|
-
|
|
50087
|
-
const out2 = [];
|
|
50088
|
-
const push = (es) => {
|
|
50089
|
-
for (const e of es) {
|
|
50090
|
-
if (seen.has(e.id)) continue;
|
|
50091
|
-
seen.add(e.id);
|
|
50092
|
-
out2.push(e);
|
|
50093
|
-
}
|
|
50094
|
-
};
|
|
50095
|
-
if (isCore(standard)) push(guidanceForWcag(unit.criteriaId));
|
|
50096
|
-
else {
|
|
50097
|
-
push(guidanceForCriterion(standard, unit.criteriaId));
|
|
50098
|
-
for (const sc of unit.refs) push(guidanceForWcag(sc));
|
|
50099
|
-
}
|
|
50100
|
-
return out2;
|
|
51708
|
+
return guidanceEntriesFor(standard, unit.criteriaId, unit.refs);
|
|
50101
51709
|
}
|
|
50102
51710
|
function guidanceExampleBlock(entries, lang) {
|
|
50103
51711
|
const s = L2[lang];
|
|
@@ -50879,7 +52487,7 @@ function pushPrComment(markdown, standard = "wcag") {
|
|
|
50879
52487
|
const pr = prNumberFromEnv();
|
|
50880
52488
|
if (pr === void 0) return { ok: true, action: "skipped", reason: "not a pull-request run" };
|
|
50881
52489
|
const marker = COMMENT_MARKER(standard);
|
|
50882
|
-
const
|
|
52490
|
+
const body3 = stickyBody(markdown, standard);
|
|
50883
52491
|
try {
|
|
50884
52492
|
const repo = ghExec(["repo", "view", "--json", "nameWithOwner", "-q", ".nameWithOwner"]).trim();
|
|
50885
52493
|
let existing;
|
|
@@ -50889,10 +52497,10 @@ function pushPrComment(markdown, standard = "wcag") {
|
|
|
50889
52497
|
} catch {
|
|
50890
52498
|
}
|
|
50891
52499
|
if (existing) {
|
|
50892
|
-
ghExec(["api", "--method", "PATCH", `repos/${repo}/issues/comments/${existing.id}`, "-f", `body=${
|
|
52500
|
+
ghExec(["api", "--method", "PATCH", `repos/${repo}/issues/comments/${existing.id}`, "-f", `body=${body3}`]);
|
|
50893
52501
|
return { ok: true, action: "updated" };
|
|
50894
52502
|
}
|
|
50895
|
-
ghExec(["api", "--method", "POST", `repos/${repo}/issues/${pr}/comments`, "-f", `body=${
|
|
52503
|
+
ghExec(["api", "--method", "POST", `repos/${repo}/issues/${pr}/comments`, "-f", `body=${body3}`]);
|
|
50896
52504
|
return { ok: true, action: "created" };
|
|
50897
52505
|
} catch (e) {
|
|
50898
52506
|
return { ok: false, action: "skipped", reason: ghErrorReason(e) };
|
|
@@ -50991,13 +52599,13 @@ function filePreamble(file, lang) {
|
|
|
50991
52599
|
const t2 = L5[lang];
|
|
50992
52600
|
return [`**${t2.file}** : \`${file}\``, "", `> ${t2.fileNote}`, ""];
|
|
50993
52601
|
}
|
|
50994
|
-
function clampBody(
|
|
50995
|
-
if (
|
|
52602
|
+
function clampBody(body3, limit, lang) {
|
|
52603
|
+
if (body3.length <= limit) return body3;
|
|
50996
52604
|
const notice = `
|
|
50997
52605
|
|
|
50998
52606
|
${L5[lang].truncated(L5[lang].prdPath)}`;
|
|
50999
52607
|
const budget = limit - notice.length;
|
|
51000
|
-
const head =
|
|
52608
|
+
const head = body3.slice(0, Math.max(0, budget));
|
|
51001
52609
|
const cut = head.lastIndexOf("\n## ");
|
|
51002
52610
|
return `${(cut > 0 ? head.slice(0, cut) : head).trimEnd()}${notice}`;
|
|
51003
52611
|
}
|
|
@@ -51031,7 +52639,7 @@ function buildTickets(result, opts) {
|
|
|
51031
52639
|
};
|
|
51032
52640
|
const backlogOpts = opts.technical !== void 0 ? { technical: opts.technical } : {};
|
|
51033
52641
|
const baseDir = opts.baseDir ?? "";
|
|
51034
|
-
const clamp2 = (
|
|
52642
|
+
const clamp2 = (body3) => clampBody(body3, limit, lang);
|
|
51035
52643
|
const ticketFromUnit = (unit, title2, scope2) => ({
|
|
51036
52644
|
title: title2,
|
|
51037
52645
|
body: clamp2(renderCriterionBody(unit, standard, lang, bodyOpts)),
|
|
@@ -51897,6 +53505,8 @@ function formatSC(c2, lang = "en") {
|
|
|
51897
53505
|
out2.push(
|
|
51898
53506
|
`${lang === "fr" ? "R\xE8gle" : "Guideline"} ${c2.guideline} (${gl}) \xB7 ${lang === "fr" ? "principe" : "principle"} ${c2.principle} (${pr}) \xB7 ${lang === "fr" ? "automatisabilit\xE9" : "automatability"} : ${auto}${c2.ruleIds.length ? ` \xB7 ${lang === "fr" ? "r\xE8gles" : "rules"} : ${c2.ruleIds.join(", ")}` : ""}`
|
|
51899
53507
|
);
|
|
53508
|
+
const body3 = scText(c2.sc, lang);
|
|
53509
|
+
if (body3) out2.push("", body3, "");
|
|
51900
53510
|
out2.push(`${lang === "fr" ? "Comprendre" : "Understanding"} : ${c2.understanding}`);
|
|
51901
53511
|
if (c2.techniques?.length) out2.push(`Techniques : ${c2.techniques.join(", ")}`);
|
|
51902
53512
|
const packs = packsForSc(c2.sc);
|
|
@@ -51964,11 +53574,11 @@ function runWcag(opts) {
|
|
|
51964
53574
|
}
|
|
51965
53575
|
var foldTerm = (s) => s.normalize("NFD").replace(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51966
53576
|
function runGlossary(opts) {
|
|
51967
|
-
const
|
|
51968
|
-
const glossary = packGlossary(opts.standard) ?? {};
|
|
53577
|
+
const label = isCore(opts.standard) ? "WCAG 2.2" : loadPack(opts.standard).name;
|
|
53578
|
+
const glossary = isCore(opts.standard) ? coreGlossary(opts.lang) : packGlossary(opts.standard) ?? {};
|
|
51969
53579
|
const anchors = Object.keys(glossary);
|
|
51970
53580
|
if (!anchors.length) {
|
|
51971
|
-
console.error(`ultra11y criteria: ${
|
|
53581
|
+
console.error(`ultra11y criteria: ${label} ships no glossary in this build.`);
|
|
51972
53582
|
return 2;
|
|
51973
53583
|
}
|
|
51974
53584
|
const term = typeof opts.glossary === "string" ? opts.glossary.trim() : "";
|
|
@@ -51981,13 +53591,13 @@ function runGlossary(opts) {
|
|
|
51981
53591
|
const hit = anchors.find((a) => a === term) ?? anchors.find((a) => foldTerm(a) === want) ?? anchors.find((a) => foldTerm(glossary[a]?.title ?? "") === want) ?? anchors.find((a) => foldTerm(a).startsWith(want));
|
|
51982
53592
|
if (!hit) {
|
|
51983
53593
|
const near = anchors.filter((a) => foldTerm(a).includes(want) || foldTerm(glossary[a]?.title ?? "").includes(want)).slice(0, 8);
|
|
51984
|
-
console.error(`ultra11y criteria: no ${
|
|
53594
|
+
console.error(`ultra11y criteria: no ${label} glossary term matching "${term}".${near.length ? ` Did you mean: ${near.join(", ")}?` : ""}`);
|
|
51985
53595
|
return 2;
|
|
51986
53596
|
}
|
|
51987
53597
|
const entry = glossary[hit];
|
|
51988
53598
|
if (opts.json) console.log(JSON.stringify({ anchor: hit, ...entry }, null, 2));
|
|
51989
53599
|
else {
|
|
51990
|
-
console.log(`${
|
|
53600
|
+
console.log(`${label} \u2014 ${entry.title} (#${hit})`);
|
|
51991
53601
|
console.log("");
|
|
51992
53602
|
console.log(entry.body);
|
|
51993
53603
|
}
|
|
@@ -51995,7 +53605,6 @@ function runGlossary(opts) {
|
|
|
51995
53605
|
}
|
|
51996
53606
|
function runPack(opts) {
|
|
51997
53607
|
const pack = loadPack(opts.standard);
|
|
51998
|
-
if (opts.glossary !== void 0 && opts.glossary !== false) return runGlossary(opts);
|
|
51999
53608
|
if (opts.id) {
|
|
52000
53609
|
const c2 = getCriterion(pack, opts.id);
|
|
52001
53610
|
if (!c2) {
|
|
@@ -52019,10 +53628,7 @@ function runPack(opts) {
|
|
|
52019
53628
|
return 0;
|
|
52020
53629
|
}
|
|
52021
53630
|
function runCriteria(opts) {
|
|
52022
|
-
if (opts.glossary !== void 0 && opts.glossary !== false
|
|
52023
|
-
console.error("ultra11y criteria: --glossary needs a country standard (e.g. --standard rgaa); WCAG ships no glossary here.");
|
|
52024
|
-
return 2;
|
|
52025
|
-
}
|
|
53631
|
+
if (opts.glossary !== void 0 && opts.glossary !== false) return runGlossary(opts);
|
|
52026
53632
|
return isCore(opts.standard) ? runWcag(opts) : runPack(opts);
|
|
52027
53633
|
}
|
|
52028
53634
|
function renderCriteriaReference() {
|
|
@@ -52560,7 +54166,8 @@ var M = {
|
|
|
52560
54166
|
semanticMissing: (p) => `Gate s\xE9mantique : aucun artefact de verdicts trouv\xE9 (${p}). G\xE9n\xE9rez la worklist (\`verify --report <md>\`), statuez, puis relancez \u2014 ou passez \`--verdicts <fichier>\`.`,
|
|
52561
54167
|
semanticUnreadable: (p) => `Gate s\xE9mantique : artefact de verdicts illisible ou JSON invalide : ${p}.`,
|
|
52562
54168
|
semanticGate: (failed2, total) => `Gate s\xE9mantique : ${failed2}/${total} verdict(s) en \xE9chec (non statu\xE9, r\xE9fut\xE9, non \xE9tay\xE9 ou non couvert).`,
|
|
52563
|
-
semanticGround: (issue) => `Gate s\xE9mantique : ${issue}
|
|
54169
|
+
semanticGround: (issue) => `Gate s\xE9mantique : ${issue}`,
|
|
54170
|
+
unevidenced: (id, tier, tool) => `Conformit\xE9 non \xE9tay\xE9e : ${id} est d\xE9clar\xE9 conforme, mais ce crit\xE8re se tranche au ${tier} et cet audit n'a produit aucune preuve de ce type. Lancez ${tool}, puis r\xE9-auditez \u2014 ou laissez le crit\xE8re \xAB \xE0 \xE9valuer \xBB.`
|
|
52564
54171
|
},
|
|
52565
54172
|
en: {
|
|
52566
54173
|
section: (n) => `Section ${n} missing from the report.`,
|
|
@@ -52574,7 +54181,8 @@ var M = {
|
|
|
52574
54181
|
semanticMissing: (p) => `Semantic gate: no verdicts artifact found (${p}). Generate the worklist (\`verify --report <md>\`), adjudicate it, then re-run \u2014 or pass \`--verdicts <file>\`.`,
|
|
52575
54182
|
semanticUnreadable: (p) => `Semantic gate: verdicts artifact unreadable or invalid JSON: ${p}.`,
|
|
52576
54183
|
semanticGate: (failed2, total) => `Semantic gate: ${failed2}/${total} verdict(s) failing (unadjudicated, refuted, unsupported or uncovered).`,
|
|
52577
|
-
semanticGround: (issue) => `Semantic gate: ${issue}
|
|
54184
|
+
semanticGround: (issue) => `Semantic gate: ${issue}`,
|
|
54185
|
+
unevidenced: (id, tier, tool) => `Unevidenced conformity: ${id} is declared conformant, but this criterion is decided on the ${tier} and this audit produced no evidence of that kind. Run ${tool}, then re-audit \u2014 or leave the criterion "to assess".`
|
|
52578
54186
|
}
|
|
52579
54187
|
};
|
|
52580
54188
|
function checkReport(md, standard = "wcag", lang = "en", opts = {}) {
|
|
@@ -52639,14 +54247,39 @@ function checkReport(md, standard = "wcag", lang = "en", opts = {}) {
|
|
|
52639
54247
|
for (const id of reportNc) if (!derivedNc.has(id)) issues.push(s.overProject(id));
|
|
52640
54248
|
for (const id of derivedNc) if (!reportNc.has(id)) issues.push(s.underProject(id));
|
|
52641
54249
|
}
|
|
54250
|
+
if (opts.audit) {
|
|
54251
|
+
const engineC = sectionBody(md, 3).split(/^###\s/m)[0] ?? "";
|
|
54252
|
+
const cItem = new RegExp(`^-\\s+(?:[A-Za-z]+\\s+)?(${idGrammar})\\s*\u2014`, "gm");
|
|
54253
|
+
const scanned = hasScanEvidence(opts.audit);
|
|
54254
|
+
const rendered = hasRenderedEvidence(opts.audit);
|
|
54255
|
+
const claimed = /* @__PURE__ */ new Set();
|
|
54256
|
+
let m;
|
|
54257
|
+
while (m = cItem.exec(engineC)) claimed.add(m[1]);
|
|
54258
|
+
for (const id of claimed) {
|
|
54259
|
+
const tier = criterionCoverage(standard, id)?.tier;
|
|
54260
|
+
if (tier === "browser" && !scanned) issues.push(s.unevidenced(id, core ? "browser" : "navigateur", "`ultra11y scan <target> --merge`"));
|
|
54261
|
+
else if (tier === "rendered-page" && rendered === false && !scanned) {
|
|
54262
|
+
issues.push(s.unevidenced(id, core ? "rendered page" : "rendu de page", "`ultra11y render` (or an E2E capture)"));
|
|
54263
|
+
}
|
|
54264
|
+
}
|
|
54265
|
+
}
|
|
52642
54266
|
return { ok: issues.length === 0, issues };
|
|
52643
54267
|
}
|
|
54268
|
+
function hasScanEvidence(r) {
|
|
54269
|
+
if ((r.scope.scan?.testedScs ?? []).length > 0) return true;
|
|
54270
|
+
return r.findings.some((f) => f.ruleId.startsWith("dyn-") || f.ruleId.startsWith("axe:"));
|
|
54271
|
+
}
|
|
54272
|
+
function hasRenderedEvidence(r) {
|
|
54273
|
+
if (r.findings.some((f) => f.ruleId.startsWith("rendered-"))) return true;
|
|
54274
|
+
const audited = r.scope.pagesAudited;
|
|
54275
|
+
return audited === void 0 ? void 0 : audited.length > 0;
|
|
54276
|
+
}
|
|
52644
54277
|
function packReportNcIds(md, idGrammar) {
|
|
52645
|
-
const
|
|
54278
|
+
const body3 = sectionBody(md, 2);
|
|
52646
54279
|
const re = new RegExp(`^\\*\\*[^*\\n]+\\*\\*\\s*:\\s*(${idGrammar})\\s*\u2014`, "gm");
|
|
52647
54280
|
const ids = /* @__PURE__ */ new Set();
|
|
52648
54281
|
let m;
|
|
52649
|
-
while (m = re.exec(
|
|
54282
|
+
while (m = re.exec(body3)) ids.add(m[1]);
|
|
52650
54283
|
return ids;
|
|
52651
54284
|
}
|
|
52652
54285
|
function checkSemantic(md, opts) {
|
|
@@ -53465,6 +55098,18 @@ var adjudication_default = {
|
|
|
53465
55098
|
}
|
|
53466
55099
|
};
|
|
53467
55100
|
|
|
55101
|
+
// src/adjudication-data.ts
|
|
55102
|
+
var ADJUDICATION = adjudication_default;
|
|
55103
|
+
function adjudicationText(sc, lang) {
|
|
55104
|
+
const p = ADJUDICATION[sc];
|
|
55105
|
+
if (!p) return void 0;
|
|
55106
|
+
return {
|
|
55107
|
+
decide: p.decide[lang],
|
|
55108
|
+
...p.na ? { na: p.na[lang] } : {},
|
|
55109
|
+
questions: p.questions.map((q) => q[lang])
|
|
55110
|
+
};
|
|
55111
|
+
}
|
|
55112
|
+
|
|
53468
55113
|
// src/adjudicate.ts
|
|
53469
55114
|
var ADJUDICATE_MAX_EVIDENCE = 30;
|
|
53470
55115
|
function adjudicationContract() {
|
|
@@ -53950,21 +55595,9 @@ var T2 = {
|
|
|
53950
55595
|
glossary: "Terms the standard defines"
|
|
53951
55596
|
}
|
|
53952
55597
|
};
|
|
53953
|
-
var ADJUDICATION = adjudication_default;
|
|
53954
55598
|
var MAX_REFS = 12;
|
|
53955
|
-
var GLOSSARY_REF = /\[[^\]]+\]\(#([^)]+)\)/g;
|
|
53956
55599
|
var MAX_GLOSSARY_TERMS = 8;
|
|
53957
55600
|
var MAX_GLOSSARY_CHARS = 600;
|
|
53958
|
-
function glossaryAnchorsOf(crit) {
|
|
53959
|
-
if (!crit) return [];
|
|
53960
|
-
const texts = [...Object.values(crit.tests ?? {}).flat(), ...crit.technicalNote ?? [], ...crit.particularCases ?? []];
|
|
53961
|
-
const seen = /* @__PURE__ */ new Set();
|
|
53962
|
-
for (const t2 of texts) {
|
|
53963
|
-
GLOSSARY_REF.lastIndex = 0;
|
|
53964
|
-
for (let m = GLOSSARY_REF.exec(t2); m; m = GLOSSARY_REF.exec(t2)) if (m[1]) seen.add(m[1]);
|
|
53965
|
-
}
|
|
53966
|
-
return [...seen];
|
|
53967
|
-
}
|
|
53968
55601
|
function glossaryBlock(pack, crit, lang) {
|
|
53969
55602
|
const anchors = glossaryAnchorsOf(crit).slice(0, MAX_GLOSSARY_TERMS);
|
|
53970
55603
|
if (!anchors.length) return [];
|
|
@@ -53975,8 +55608,8 @@ function glossaryBlock(pack, crit, lang) {
|
|
|
53975
55608
|
const entry = resolveGlossary(pack.key, a);
|
|
53976
55609
|
if (!entry) continue;
|
|
53977
55610
|
any = true;
|
|
53978
|
-
const
|
|
53979
|
-
out2.push(`- **${entry.title}** \u2014 ${
|
|
55611
|
+
const body3 = entry.body.replace(/\s+/g, " ").trim();
|
|
55612
|
+
out2.push(`- **${entry.title}** \u2014 ${body3.length > MAX_GLOSSARY_CHARS ? `${body3.slice(0, MAX_GLOSSARY_CHARS)}\u2026` : body3}`);
|
|
53980
55613
|
}
|
|
53981
55614
|
out2.push("");
|
|
53982
55615
|
return any ? out2 : [];
|
|
@@ -54158,7 +55791,7 @@ Rules, in order of importance:
|
|
|
54158
55791
|
5. Rule only on the criteria presented. Never introduce another.`;
|
|
54159
55792
|
var sleep = (ms) => ms <= 0 ? Promise.resolve() : new Promise((r) => setTimeout(r, ms));
|
|
54160
55793
|
var backoff = (opts, attempt) => opts.backoffMs?.(attempt) ?? 2 ** attempt * 500;
|
|
54161
|
-
async function callOnce(
|
|
55794
|
+
async function callOnce(body3, opts) {
|
|
54162
55795
|
const f = opts.fetchImpl ?? fetch;
|
|
54163
55796
|
const url = `${opts.baseUrl ?? process.env.ANTHROPIC_BASE_URL ?? DEFAULT_BASE_URL}/v1/messages`;
|
|
54164
55797
|
let lastError = "";
|
|
@@ -54168,7 +55801,7 @@ async function callOnce(body2, opts) {
|
|
|
54168
55801
|
res = await f(url, {
|
|
54169
55802
|
method: "POST",
|
|
54170
55803
|
headers: { "content-type": "application/json", "x-api-key": opts.apiKey, "anthropic-version": API_VERSION },
|
|
54171
|
-
body: JSON.stringify(
|
|
55804
|
+
body: JSON.stringify(body3)
|
|
54172
55805
|
});
|
|
54173
55806
|
} catch (e) {
|
|
54174
55807
|
lastError = e instanceof Error ? e.message : String(e);
|
|
@@ -56520,9 +58153,9 @@ var blockRe = () => new RegExp(`${escapeRe2(BLOCK_BEGIN)}[\\s\\S]*?${escapeRe2(B
|
|
|
56520
58153
|
function escapeRe2(s) {
|
|
56521
58154
|
return s.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
56522
58155
|
}
|
|
56523
|
-
function upsertManagedBlock(path,
|
|
58156
|
+
function upsertManagedBlock(path, body3) {
|
|
56524
58157
|
const block = `${BLOCK_BEGIN}
|
|
56525
|
-
${
|
|
58158
|
+
${body3.trim()}
|
|
56526
58159
|
${BLOCK_END}
|
|
56527
58160
|
`;
|
|
56528
58161
|
if (!existsSync25(path)) return writeTextWithBackup(path, block);
|
|
@@ -56699,9 +58332,9 @@ function withoutOurs2(groups) {
|
|
|
56699
58332
|
}
|
|
56700
58333
|
function enableHooksFeature(content) {
|
|
56701
58334
|
if (HOOKS_ON.test(featuresBody(content))) return { content, changed: false };
|
|
56702
|
-
const
|
|
56703
|
-
if (HOOKS_ANY.test(
|
|
56704
|
-
return { content: content.replace(
|
|
58335
|
+
const body3 = featuresBody(content);
|
|
58336
|
+
if (HOOKS_ANY.test(body3)) {
|
|
58337
|
+
return { content: content.replace(body3, body3.replace(HOOKS_ANY, "hooks = true")), changed: true };
|
|
56705
58338
|
}
|
|
56706
58339
|
if (FEATURES_HEADER.test(content)) {
|
|
56707
58340
|
return { content: content.replace(FEATURES_HEADER, "$&\nhooks = true"), changed: true };
|
|
@@ -57187,9 +58820,9 @@ function annotations(result, opts = {}) {
|
|
|
57187
58820
|
const level = f.advisory ? "notice" : LEVEL2[f.severity];
|
|
57188
58821
|
const file = repoRelative(f.file, baseDir);
|
|
57189
58822
|
const title2 = `${criterionLabel2(f, standard)} \xB7 ${f.ruleId}`;
|
|
57190
|
-
const
|
|
58823
|
+
const body3 = `${resolveMessage(f, lang)}
|
|
57191
58824
|
${resolveRemediation(f, lang)}`;
|
|
57192
|
-
out2.push(`::${level} file=${escProp(file)},line=${Math.max(1, f.line)},col=${Math.max(1, f.col)},title=${escProp(title2)}::${esc(
|
|
58825
|
+
out2.push(`::${level} file=${escProp(file)},line=${Math.max(1, f.line)},col=${Math.max(1, f.col)},title=${escProp(title2)}::${esc(body3)}`);
|
|
57193
58826
|
}
|
|
57194
58827
|
return out2;
|
|
57195
58828
|
}
|
|
@@ -57355,14 +58988,14 @@ function prComment(result, opts = {}) {
|
|
|
57355
58988
|
if (opts.artifactName) tail.push(s.artifact(opts.artifactName), "");
|
|
57356
58989
|
if (opts.runUrl) tail.push(s.runLink(opts.runUrl), "");
|
|
57357
58990
|
const assemble = (rows2) => {
|
|
57358
|
-
const
|
|
58991
|
+
const body3 = [];
|
|
57359
58992
|
if (grouped.length) {
|
|
57360
|
-
|
|
57361
|
-
|
|
58993
|
+
body3.push(s.grouped(grouped.length, all.length), "");
|
|
58994
|
+
body3.push(...groupTable(grouped.slice(0, rows2), s), "");
|
|
57362
58995
|
const omitted = grouped.length - rows2;
|
|
57363
|
-
if (omitted > 0)
|
|
58996
|
+
if (omitted > 0) body3.push(rows2 < COMMENT_ROWS ? s.clamped(omitted) : s.moreGroups(omitted), "");
|
|
57364
58997
|
}
|
|
57365
|
-
return [...head, ...
|
|
58998
|
+
return [...head, ...body3, ...tail].join("\n").trimEnd();
|
|
57366
58999
|
};
|
|
57367
59000
|
let rows = Math.min(COMMENT_ROWS, grouped.length);
|
|
57368
59001
|
while (rows > 0 && assemble(rows).length > COMMENT_LIMIT) rows--;
|
|
@@ -58697,8 +60330,8 @@ function startDevServer(opts) {
|
|
|
58697
60330
|
if (url.pathname === "/snapshot" && req.method === "POST") {
|
|
58698
60331
|
void (async () => {
|
|
58699
60332
|
try {
|
|
58700
|
-
const
|
|
58701
|
-
const payload = JSON.parse(
|
|
60333
|
+
const body3 = await readBody(req);
|
|
60334
|
+
const payload = JSON.parse(body3);
|
|
58702
60335
|
const r = auditCollected(opts.root, payload);
|
|
58703
60336
|
if (!r.ok) {
|
|
58704
60337
|
res.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: r.error }));
|
|
@@ -58789,10 +60422,10 @@ function startDevServer(opts) {
|
|
|
58789
60422
|
}
|
|
58790
60423
|
res.writeHead(404, { "content-type": "text/plain" }).end("not found");
|
|
58791
60424
|
});
|
|
58792
|
-
return new Promise((
|
|
60425
|
+
return new Promise((resolve16, reject) => {
|
|
58793
60426
|
server.once("error", reject);
|
|
58794
60427
|
server.listen(opts.port, "127.0.0.1", () => {
|
|
58795
|
-
|
|
60428
|
+
resolve16({
|
|
58796
60429
|
port: server.address().port,
|
|
58797
60430
|
close: () => new Promise((r) => server.close(() => r()))
|
|
58798
60431
|
});
|
|
@@ -59410,6 +61043,435 @@ import { createInterface as createInterface2 } from "readline";
|
|
|
59410
61043
|
import { existsSync as existsSync32, readFileSync as readFileSync30, realpathSync as realpathSync4, statSync as statSync12 } from "fs";
|
|
59411
61044
|
import { isAbsolute as isAbsolute3, join as join48, resolve as resolve13, sep as sep5 } from "path";
|
|
59412
61045
|
|
|
61046
|
+
// src/criteria-view.ts
|
|
61047
|
+
var CriteriaLookupError = class extends Error {
|
|
61048
|
+
suggestions;
|
|
61049
|
+
constructor(message, suggestions = []) {
|
|
61050
|
+
super(message);
|
|
61051
|
+
this.suggestions = suggestions;
|
|
61052
|
+
}
|
|
61053
|
+
};
|
|
61054
|
+
function guidanceView(r, lang) {
|
|
61055
|
+
const e = r.entry;
|
|
61056
|
+
return {
|
|
61057
|
+
id: e.id,
|
|
61058
|
+
...e.title?.[lang] ? { title: e.title[lang] } : {},
|
|
61059
|
+
...e.summary?.[lang] ? { summary: e.summary[lang] } : {},
|
|
61060
|
+
...e.impact ? { impact: e.impact } : {},
|
|
61061
|
+
reference: e.reference,
|
|
61062
|
+
wcag: e.wcag,
|
|
61063
|
+
via: r.via,
|
|
61064
|
+
inherited: r.inherited,
|
|
61065
|
+
languagesAvailable: r.languagesAvailable,
|
|
61066
|
+
examples: (e.examples ?? []).map((x) => ({
|
|
61067
|
+
lang: x.lang,
|
|
61068
|
+
...x.bad ? { bad: x.bad } : {},
|
|
61069
|
+
...x.good ? { good: x.good } : {},
|
|
61070
|
+
...x.note?.[lang] ? { note: x.note[lang] } : {}
|
|
61071
|
+
}))
|
|
61072
|
+
};
|
|
61073
|
+
}
|
|
61074
|
+
function glossaryViews(pack, c2) {
|
|
61075
|
+
const out2 = [];
|
|
61076
|
+
for (const anchor of glossaryAnchorsOf(c2)) {
|
|
61077
|
+
const entry = resolveGlossary(pack.key, anchor);
|
|
61078
|
+
if (entry) out2.push({ anchor, title: entry.title, body: entry.body });
|
|
61079
|
+
}
|
|
61080
|
+
return out2;
|
|
61081
|
+
}
|
|
61082
|
+
function scView(id, lang, includeGuidance) {
|
|
61083
|
+
const c2 = getSC(id);
|
|
61084
|
+
if (!c2) return void 0;
|
|
61085
|
+
const localized = scTitle(c2.sc, lang);
|
|
61086
|
+
return {
|
|
61087
|
+
kind: "wcag",
|
|
61088
|
+
sc: c2.sc,
|
|
61089
|
+
title: c2.title,
|
|
61090
|
+
...localized && localized !== c2.title ? { titleLocalized: localized } : {},
|
|
61091
|
+
...scText(c2.sc, lang) ? { text: scText(c2.sc, lang) } : {},
|
|
61092
|
+
// The terms the wording links to. WCAG's definitions are normative in exactly the way
|
|
61093
|
+
// a pack's are: "large scale" and "pure decoration" mean what the glossary says.
|
|
61094
|
+
glossary: ((lang === "fr" ? c2.termsFr : c2.terms) ?? []).flatMap((slug) => {
|
|
61095
|
+
const entry = coreGlossary(lang)[slug];
|
|
61096
|
+
return entry ? [{ anchor: slug, title: entry.title, body: entry.body }] : [];
|
|
61097
|
+
}),
|
|
61098
|
+
level: c2.level,
|
|
61099
|
+
addedIn: c2.addedIn,
|
|
61100
|
+
principle: { number: c2.principle, ...principleTitle(c2.principle, lang) ? { title: principleTitle(c2.principle, lang) } : {} },
|
|
61101
|
+
guideline: { number: c2.guideline, ...guidelineTitle(c2.guideline, lang) ? { title: guidelineTitle(c2.guideline, lang) } : {} },
|
|
61102
|
+
automatability: c2.automatability,
|
|
61103
|
+
coverage: criterionCoverage("wcag", c2.sc),
|
|
61104
|
+
techniques: techniquesFor(c2.sc),
|
|
61105
|
+
understanding: c2.understanding,
|
|
61106
|
+
// The decision protocol stands in for the Understanding prose this repo deliberately
|
|
61107
|
+
// does not vendor: what makes it Conforming, when NA is legitimate, what to ask.
|
|
61108
|
+
...adjudicationText(c2.sc, lang) ? { adjudication: adjudicationText(c2.sc, lang) } : {},
|
|
61109
|
+
mappedBy: packsForSc(c2.sc).map((p) => ({ standard: p.key, criteria: p.ids })),
|
|
61110
|
+
guidance: includeGuidance ? resolveGuidance("wcag", c2.sc).map((r) => guidanceView(r, lang)) : []
|
|
61111
|
+
};
|
|
61112
|
+
}
|
|
61113
|
+
function packCriterionView(pack, c2, lang, includeGuidance) {
|
|
61114
|
+
const plain2 = titlePlain(pack, c2, lang);
|
|
61115
|
+
const raw = c2.title?.[lang] ?? c2.title?.[pack.defaultLocale];
|
|
61116
|
+
const adjudication = [];
|
|
61117
|
+
for (const sc of c2.wcag) {
|
|
61118
|
+
const p = adjudicationText(sc, lang);
|
|
61119
|
+
if (p) adjudication.push({ sc, ...p });
|
|
61120
|
+
}
|
|
61121
|
+
return {
|
|
61122
|
+
kind: "pack",
|
|
61123
|
+
id: c2.id,
|
|
61124
|
+
theme: { number: c2.theme, ...themeName(pack, c2.theme, lang) ? { name: themeName(pack, c2.theme, lang) } : {} },
|
|
61125
|
+
title: plain2,
|
|
61126
|
+
// The markup is kept, not stripped: `[terme](#ancre)` is what points at the normative
|
|
61127
|
+
// glossary definitions attached below.
|
|
61128
|
+
...raw && raw !== plain2 ? { titleRaw: raw } : {},
|
|
61129
|
+
tests: Object.entries(c2.tests ?? {}).map(([k, lines]) => ({ id: `${c2.id}.${k}`, lines })),
|
|
61130
|
+
techniques: c2.techniques ?? [],
|
|
61131
|
+
wcag: c2.wcag.map((sc) => {
|
|
61132
|
+
const core = getSC(sc);
|
|
61133
|
+
return {
|
|
61134
|
+
sc,
|
|
61135
|
+
...core ? { title: scTitle(sc, lang) ?? core.title, level: core.level, automatability: core.automatability } : {},
|
|
61136
|
+
inCore: core !== void 0
|
|
61137
|
+
};
|
|
61138
|
+
}),
|
|
61139
|
+
technicalNote: c2.technicalNote ?? [],
|
|
61140
|
+
particularCases: c2.particularCases ?? [],
|
|
61141
|
+
judgment: c2.judgment === true,
|
|
61142
|
+
appliesTo: c2.appliesTo?.ruleIds ?? [],
|
|
61143
|
+
coverage: criterionCoverage(pack.key, c2.id),
|
|
61144
|
+
glossary: glossaryViews(pack, c2),
|
|
61145
|
+
adjudication,
|
|
61146
|
+
guidance: includeGuidance ? resolveGuidance(pack.key, c2.id).map((r) => guidanceView(r, lang)) : []
|
|
61147
|
+
};
|
|
61148
|
+
}
|
|
61149
|
+
function criterionView(standard, id, lang, includeGuidance = false) {
|
|
61150
|
+
const base = { standard, standardLabel: standardLabel(standard), lang, kind: "criterion", id };
|
|
61151
|
+
if (isCore(standard)) {
|
|
61152
|
+
const view = scView(id, lang, includeGuidance);
|
|
61153
|
+
if (!view) throw new CriteriaLookupError(`no such success criterion: ${id}. List them all by omitting \`sc\`.`);
|
|
61154
|
+
return { ...base, criterion: view, text: formatSC(getSC(id), lang) };
|
|
61155
|
+
}
|
|
61156
|
+
const pack = loadPack(standard);
|
|
61157
|
+
const c2 = getCriterion(pack, id);
|
|
61158
|
+
if (!c2) throw new CriteriaLookupError(`no such ${pack.name} criterion: ${id}. List them all by omitting \`sc\`.`);
|
|
61159
|
+
return { ...base, criterion: packCriterionView(pack, c2, lang, includeGuidance), text: formatPackCriterion(pack, c2, lang) };
|
|
61160
|
+
}
|
|
61161
|
+
function tierCensus(standard, ids) {
|
|
61162
|
+
const by = {};
|
|
61163
|
+
for (const id of ids) {
|
|
61164
|
+
const t2 = criterionCoverage(standard, id)?.tier;
|
|
61165
|
+
if (t2) by[t2] = (by[t2] ?? 0) + 1;
|
|
61166
|
+
}
|
|
61167
|
+
return by;
|
|
61168
|
+
}
|
|
61169
|
+
function criteriaIndex(standard, lang) {
|
|
61170
|
+
const base = { standard, standardLabel: standardLabel(standard), lang, kind: "index" };
|
|
61171
|
+
if (isCore(standard)) {
|
|
61172
|
+
const scs = allSC();
|
|
61173
|
+
const byGuideline = scsByGuideline();
|
|
61174
|
+
const byAuto = {};
|
|
61175
|
+
for (const c2 of scs) byAuto[c2.automatability] = (byAuto[c2.automatability] ?? 0) + 1;
|
|
61176
|
+
return {
|
|
61177
|
+
...base,
|
|
61178
|
+
meta: { ...meta() },
|
|
61179
|
+
counts: { criteria: scs.length, ...byAuto },
|
|
61180
|
+
byTier: tierCensus(
|
|
61181
|
+
"wcag",
|
|
61182
|
+
scs.map((c2) => c2.sc)
|
|
61183
|
+
),
|
|
61184
|
+
groups: allGuidelines().map((g) => ({
|
|
61185
|
+
number: g.number,
|
|
61186
|
+
...guidelineTitle(g.number, lang) ? { name: guidelineTitle(g.number, lang) } : {},
|
|
61187
|
+
count: byGuideline.get(g.number)?.length ?? 0
|
|
61188
|
+
})),
|
|
61189
|
+
criteria: scs.map((c2) => {
|
|
61190
|
+
const cov = criterionCoverage("wcag", c2.sc);
|
|
61191
|
+
return {
|
|
61192
|
+
id: c2.sc,
|
|
61193
|
+
title: scTitle(c2.sc, lang) ?? c2.title,
|
|
61194
|
+
group: c2.guideline,
|
|
61195
|
+
level: c2.level,
|
|
61196
|
+
tier: cov.tier,
|
|
61197
|
+
sourceIsEnough: cov.sourceIsEnough
|
|
61198
|
+
};
|
|
61199
|
+
})
|
|
61200
|
+
};
|
|
61201
|
+
}
|
|
61202
|
+
const pack = loadPack(standard);
|
|
61203
|
+
const criteria = allCriteria(pack);
|
|
61204
|
+
const tests = criteria.reduce((n, c2) => n + Object.keys(c2.tests ?? {}).length, 0);
|
|
61205
|
+
return {
|
|
61206
|
+
...base,
|
|
61207
|
+
pack: {
|
|
61208
|
+
key: pack.key,
|
|
61209
|
+
name: pack.name,
|
|
61210
|
+
fullName: pack.fullName,
|
|
61211
|
+
org: pack.org,
|
|
61212
|
+
country: pack.country,
|
|
61213
|
+
baseVersion: pack.baseVersion,
|
|
61214
|
+
wcagVersion: pack.wcagVersion,
|
|
61215
|
+
locales: pack.locales,
|
|
61216
|
+
defaultLocale: pack.defaultLocale,
|
|
61217
|
+
license: pack.license,
|
|
61218
|
+
source: pack.source,
|
|
61219
|
+
attribution: pack.attribution
|
|
61220
|
+
},
|
|
61221
|
+
counts: {
|
|
61222
|
+
themes: pack.themes.length,
|
|
61223
|
+
criteria: criteria.length,
|
|
61224
|
+
tests,
|
|
61225
|
+
judgment: criteria.filter((c2) => c2.judgment).length,
|
|
61226
|
+
noEngineRule: criteria.filter((c2) => c2.appliesTo?.ruleIds?.length === 0).length
|
|
61227
|
+
},
|
|
61228
|
+
byTier: tierCensus(
|
|
61229
|
+
pack.key,
|
|
61230
|
+
criteria.map((c2) => c2.id)
|
|
61231
|
+
),
|
|
61232
|
+
groups: pack.themes.map((t2) => ({
|
|
61233
|
+
number: String(t2.number),
|
|
61234
|
+
...themeName(pack, t2.number, lang) ? { name: themeName(pack, t2.number, lang) } : {},
|
|
61235
|
+
count: t2.count
|
|
61236
|
+
})),
|
|
61237
|
+
criteria: criteria.map((c2) => {
|
|
61238
|
+
const cov = criterionCoverage(pack.key, c2.id);
|
|
61239
|
+
return {
|
|
61240
|
+
id: c2.id,
|
|
61241
|
+
title: titlePlain(pack, c2, lang),
|
|
61242
|
+
group: String(c2.theme),
|
|
61243
|
+
wcag: c2.wcag,
|
|
61244
|
+
tier: cov.tier,
|
|
61245
|
+
sourceIsEnough: cov.sourceIsEnough,
|
|
61246
|
+
judgment: c2.judgment === true
|
|
61247
|
+
};
|
|
61248
|
+
})
|
|
61249
|
+
};
|
|
61250
|
+
}
|
|
61251
|
+
function themeView(standard, n, lang) {
|
|
61252
|
+
if (isCore(standard)) {
|
|
61253
|
+
throw new CriteriaLookupError("WCAG has no themes \u2014 it groups criteria by guideline. Omit `theme`, or pass a country standard.");
|
|
61254
|
+
}
|
|
61255
|
+
const pack = loadPack(standard);
|
|
61256
|
+
const criteria = listTheme(pack, n);
|
|
61257
|
+
if (!criteria.length) throw new CriteriaLookupError(`no such ${pack.name} theme: ${n}.`);
|
|
61258
|
+
return {
|
|
61259
|
+
standard,
|
|
61260
|
+
standardLabel: standardLabel(standard),
|
|
61261
|
+
lang,
|
|
61262
|
+
kind: "theme",
|
|
61263
|
+
theme: { number: n, ...themeName(pack, n, lang) ? { name: themeName(pack, n, lang) } : {}, count: criteria.length },
|
|
61264
|
+
criteria: criteria.map((c2) => {
|
|
61265
|
+
const cov = criterionCoverage(pack.key, c2.id);
|
|
61266
|
+
return {
|
|
61267
|
+
id: c2.id,
|
|
61268
|
+
title: titlePlain(pack, c2, lang),
|
|
61269
|
+
wcag: c2.wcag,
|
|
61270
|
+
tier: cov.tier,
|
|
61271
|
+
sourceIsEnough: cov.sourceIsEnough,
|
|
61272
|
+
judgment: c2.judgment === true
|
|
61273
|
+
};
|
|
61274
|
+
})
|
|
61275
|
+
};
|
|
61276
|
+
}
|
|
61277
|
+
function foldTerm2(s) {
|
|
61278
|
+
return s.normalize("NFD").replace(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
61279
|
+
}
|
|
61280
|
+
function citedBy(pack, anchor) {
|
|
61281
|
+
return allCriteria(pack).filter((c2) => glossaryAnchorsOf(c2).includes(anchor)).map((c2) => c2.id);
|
|
61282
|
+
}
|
|
61283
|
+
function glossaryOf(standard, lang) {
|
|
61284
|
+
if (isCore(standard)) return { glossary: coreGlossary(lang), label: standardLabel(standard) };
|
|
61285
|
+
return { glossary: packGlossary(standard) ?? {}, label: loadPack(standard).name };
|
|
61286
|
+
}
|
|
61287
|
+
function glossaryView(standard, term, lang = "en") {
|
|
61288
|
+
const { glossary, label } = glossaryOf(standard, lang);
|
|
61289
|
+
const anchors = Object.keys(glossary).sort();
|
|
61290
|
+
if (!anchors.length) throw new CriteriaLookupError(`${label} ships no glossary in this build.`);
|
|
61291
|
+
const wanted = term?.trim();
|
|
61292
|
+
if (!wanted) {
|
|
61293
|
+
return {
|
|
61294
|
+
standard,
|
|
61295
|
+
standardLabel: standardLabel(standard),
|
|
61296
|
+
kind: "glossary-index",
|
|
61297
|
+
count: anchors.length,
|
|
61298
|
+
terms: anchors.map((a) => ({ anchor: a, title: glossary[a]?.title ?? "" }))
|
|
61299
|
+
};
|
|
61300
|
+
}
|
|
61301
|
+
const want = foldTerm2(wanted);
|
|
61302
|
+
const hit = anchors.find((a) => a === wanted) ?? anchors.find((a) => foldTerm2(a) === want) ?? anchors.find((a) => foldTerm2(glossary[a]?.title ?? "") === want) ?? anchors.find((a) => foldTerm2(a).startsWith(want));
|
|
61303
|
+
if (!hit) {
|
|
61304
|
+
const near = anchors.filter((a) => foldTerm2(a).includes(want) || foldTerm2(glossary[a]?.title ?? "").includes(want)).slice(0, 8);
|
|
61305
|
+
throw new CriteriaLookupError(`no ${label} glossary term matching "${wanted}".`, near);
|
|
61306
|
+
}
|
|
61307
|
+
const entry = glossary[hit];
|
|
61308
|
+
return {
|
|
61309
|
+
standard,
|
|
61310
|
+
standardLabel: standardLabel(standard),
|
|
61311
|
+
kind: "glossary-term",
|
|
61312
|
+
anchor: hit,
|
|
61313
|
+
title: entry.title,
|
|
61314
|
+
body: entry.body,
|
|
61315
|
+
// Which criteria this definition actually governs — the reason it is normative.
|
|
61316
|
+
citedBy: isCore(standard) ? [] : citedBy(loadPack(standard), hit)
|
|
61317
|
+
};
|
|
61318
|
+
}
|
|
61319
|
+
|
|
61320
|
+
// src/method-view.ts
|
|
61321
|
+
function tierCensus2(standard, ids) {
|
|
61322
|
+
const by = {};
|
|
61323
|
+
for (const id of ids) {
|
|
61324
|
+
const t2 = criterionCoverage(standard, id)?.tier;
|
|
61325
|
+
if (t2) by[t2] = (by[t2] ?? 0) + 1;
|
|
61326
|
+
}
|
|
61327
|
+
return by;
|
|
61328
|
+
}
|
|
61329
|
+
function summarize(key) {
|
|
61330
|
+
if (isCore(key)) {
|
|
61331
|
+
const scs = allSC();
|
|
61332
|
+
const byAuto = {};
|
|
61333
|
+
for (const c2 of scs) byAuto[c2.automatability] = (byAuto[c2.automatability] ?? 0) + 1;
|
|
61334
|
+
return {
|
|
61335
|
+
key,
|
|
61336
|
+
core: true,
|
|
61337
|
+
label: standardLabel(key),
|
|
61338
|
+
...meta(),
|
|
61339
|
+
counts: { criteria: scs.length, ...byAuto },
|
|
61340
|
+
byTier: tierCensus2(
|
|
61341
|
+
key,
|
|
61342
|
+
scs.map((c2) => c2.sc)
|
|
61343
|
+
),
|
|
61344
|
+
// The core keeps its terms in wcag.json, not in a pack glossary — it defines "large
|
|
61345
|
+
// scale" and "pure decoration" itself, and those definitions decide its verdicts.
|
|
61346
|
+
glossary: Object.keys(coreGlossary()).length,
|
|
61347
|
+
guidance: getDataset(key)?.entries.length ?? 0
|
|
61348
|
+
};
|
|
61349
|
+
}
|
|
61350
|
+
const pack = loadPack(key);
|
|
61351
|
+
const criteria = allCriteria(pack);
|
|
61352
|
+
return {
|
|
61353
|
+
key,
|
|
61354
|
+
core: false,
|
|
61355
|
+
label: standardLabel(key),
|
|
61356
|
+
name: pack.name,
|
|
61357
|
+
fullName: pack.fullName,
|
|
61358
|
+
org: pack.org,
|
|
61359
|
+
country: pack.country,
|
|
61360
|
+
baseVersion: pack.baseVersion,
|
|
61361
|
+
wcagVersion: pack.wcagVersion,
|
|
61362
|
+
locales: pack.locales,
|
|
61363
|
+
defaultLocale: pack.defaultLocale,
|
|
61364
|
+
license: pack.license,
|
|
61365
|
+
source: pack.source,
|
|
61366
|
+
attribution: pack.attribution,
|
|
61367
|
+
counts: {
|
|
61368
|
+
themes: pack.themes.length,
|
|
61369
|
+
criteria: criteria.length,
|
|
61370
|
+
tests: criteria.reduce((n, c2) => n + Object.keys(c2.tests ?? {}).length, 0),
|
|
61371
|
+
judgment: criteria.filter((c2) => c2.judgment).length,
|
|
61372
|
+
noEngineRule: criteria.filter((c2) => c2.appliesTo?.ruleIds?.length === 0).length,
|
|
61373
|
+
declarativeRules: pack.rules?.length ?? 0
|
|
61374
|
+
},
|
|
61375
|
+
byTier: tierCensus2(
|
|
61376
|
+
key,
|
|
61377
|
+
criteria.map((c2) => c2.id)
|
|
61378
|
+
),
|
|
61379
|
+
glossary: Object.keys(packGlossary(key) ?? {}).length,
|
|
61380
|
+
guidance: hasGuidance(key) ? getDataset(key)?.entries.length ?? 0 : 0,
|
|
61381
|
+
...pack.sampleMethodology ? { sampleKinds: pack.sampleMethodology.requiredKinds.length } : {}
|
|
61382
|
+
};
|
|
61383
|
+
}
|
|
61384
|
+
function standardsInventory() {
|
|
61385
|
+
const keys = listStandards();
|
|
61386
|
+
return {
|
|
61387
|
+
default: "wcag",
|
|
61388
|
+
count: keys.length,
|
|
61389
|
+
standards: keys.map(summarize),
|
|
61390
|
+
// Nothing here is a claim about the project's conformance — it is what the project
|
|
61391
|
+
// COULD be audited against.
|
|
61392
|
+
next: "ultra11y_method for the work plan of one of these; ultra11y_criteria to read a criterion.",
|
|
61393
|
+
builtIn: listPacks().map((p) => p.key)
|
|
61394
|
+
};
|
|
61395
|
+
}
|
|
61396
|
+
var TIER_GUIDE = {
|
|
61397
|
+
source: {
|
|
61398
|
+
tool: "ultra11y_audit",
|
|
61399
|
+
how: "Run ultra11y_audit over the project's markup. An engine rule decides these: on a file that WAS audited, the absence of a finding is a real pass."
|
|
61400
|
+
},
|
|
61401
|
+
"cross-file": {
|
|
61402
|
+
tool: "ultra11y_audit (graph: true)",
|
|
61403
|
+
how: "Statically decidable, but only across the dependency graph \u2014 a label defined in another file. Re-run the audit with graph: true."
|
|
61404
|
+
},
|
|
61405
|
+
"rendered-page": {
|
|
61406
|
+
tool: "ultra11y render / dev / the Playwright or Cypress plugin",
|
|
61407
|
+
how: "Capture a page snapshot into .ultra11y/pages first, then audit again. These rules read computed styles, laid-out boxes and the screenshot \u2014 a captured page, but no live browser."
|
|
61408
|
+
},
|
|
61409
|
+
browser: {
|
|
61410
|
+
tool: "ultra11y scan (CLI)",
|
|
61411
|
+
how: "Needs a live rendered DOM. This server does not drive a browser: run `ultra11y scan <target> --merge` from the CLI, then audit again."
|
|
61412
|
+
},
|
|
61413
|
+
judgment: {
|
|
61414
|
+
tool: "ultra11y_adjudicate",
|
|
61415
|
+
how: "The evidence can be gathered but the verdict is a reading of meaning \u2014 is this alt text relevant, is this link's purpose clear in context. ultra11y_adjudicate hands you the evidence and the decision rule; you rule, citing the criterion's own numbered test."
|
|
61416
|
+
},
|
|
61417
|
+
"out-of-scope": {
|
|
61418
|
+
tool: "\u2014",
|
|
61419
|
+
how: "Every WCAG success criterion this maps to is outside the engine's 2.2 AA core (AAA, or removed). Declare it out of scope. Never claim conformity."
|
|
61420
|
+
}
|
|
61421
|
+
};
|
|
61422
|
+
var TIERS = ["source", "cross-file", "rendered-page", "browser", "judgment", "out-of-scope"];
|
|
61423
|
+
function titleOf(standard, id, lang) {
|
|
61424
|
+
if (isCore(standard)) {
|
|
61425
|
+
const t2 = scTitle(id, lang);
|
|
61426
|
+
return t2 ?? id;
|
|
61427
|
+
}
|
|
61428
|
+
const pack = loadPack(standard);
|
|
61429
|
+
const c2 = allCriteria(pack).find((x) => x.id === id);
|
|
61430
|
+
return c2 ? titlePlain(pack, c2, lang) : id;
|
|
61431
|
+
}
|
|
61432
|
+
function methodView(standard, lang, opts = {}) {
|
|
61433
|
+
const coverage = standardCoverage(standard);
|
|
61434
|
+
const detail = opts.detail ?? "summary";
|
|
61435
|
+
const buckets = TIERS.map((tier) => {
|
|
61436
|
+
const entries = [...coverage].filter(([, c2]) => c2.tier === tier);
|
|
61437
|
+
return {
|
|
61438
|
+
tier,
|
|
61439
|
+
count: entries.length,
|
|
61440
|
+
sourceIsEnough: tier === "source",
|
|
61441
|
+
...TIER_GUIDE[tier],
|
|
61442
|
+
criteria: entries.map(
|
|
61443
|
+
([id, c2]) => detail === "full" ? { id, title: titleOf(standard, id, lang), rules: c2.engineRules, alsoNeeds: c2.alsoNeeds, canFailFrom: c2.canFailFrom, why: c2.why } : { id }
|
|
61444
|
+
)
|
|
61445
|
+
};
|
|
61446
|
+
}).filter((b) => opts.tier ? b.tier === opts.tier : b.count > 0);
|
|
61447
|
+
const sourceIds = [...coverage].filter(([, c2]) => c2.sourceIsEnough).map(([id]) => id);
|
|
61448
|
+
const failableFromSource = [...coverage].filter(([, c2]) => !c2.sourceIsEnough && c2.canFailFrom.includes("source")).map(([id]) => id);
|
|
61449
|
+
const pack = isCore(standard) ? void 0 : getPack(standard);
|
|
61450
|
+
return {
|
|
61451
|
+
standard,
|
|
61452
|
+
standardLabel: standardLabel(standard),
|
|
61453
|
+
lang,
|
|
61454
|
+
total: coverage.size,
|
|
61455
|
+
detail,
|
|
61456
|
+
buckets,
|
|
61457
|
+
sourceIsEnough: { count: sourceIds.length, ids: sourceIds },
|
|
61458
|
+
needsMore: { count: coverage.size - sourceIds.length },
|
|
61459
|
+
canFailFromSource: {
|
|
61460
|
+
count: failableFromSource.length,
|
|
61461
|
+
ids: failableFromSource,
|
|
61462
|
+
note: "These cannot be PROVEN conformant from source, but an engine rule can still fail them outright."
|
|
61463
|
+
},
|
|
61464
|
+
...pack?.sampleMethodology ? {
|
|
61465
|
+
sample: {
|
|
61466
|
+
requiredKinds: pack.sampleMethodology.requiredKinds.map((k) => ({ id: k.id, label: k.label[lang] ?? k.label[pack.defaultLocale] })),
|
|
61467
|
+
note: "This standard is a PER-PAGE norm: the plan above applies to each page of the declared sample. Lint the sample with ultra11y_sample_check."
|
|
61468
|
+
}
|
|
61469
|
+
} : {},
|
|
61470
|
+
coverageNote: "A criterion nobody tested is untested, never conformant. Every count above is derived from this engine's own rule applicability and the WCAG automatability classes \u2014 not from reading the wording of a test.",
|
|
61471
|
+
next: "ultra11y_audit to settle the `source` tier, then ultra11y_adjudicate for the judgment ones."
|
|
61472
|
+
};
|
|
61473
|
+
}
|
|
61474
|
+
|
|
59413
61475
|
// src/project-lock.ts
|
|
59414
61476
|
var chains = /* @__PURE__ */ new Map();
|
|
59415
61477
|
function withProjectLock(dir, fn) {
|
|
@@ -59432,6 +61494,7 @@ var MAX_READ_LINES = 2e3;
|
|
|
59432
61494
|
var MAX_READ_BYTES = 8 * 1024 * 1024;
|
|
59433
61495
|
var DEFAULT_GLOBS = ["**/*.html", "**/*.htm", "**/*.jsx", "**/*.tsx", "**/*.vue", "**/*.svelte"];
|
|
59434
61496
|
var WRITE_TOOL_NAMES = /* @__PURE__ */ new Set(["ultra11y_fix", "ultra11y_scan", "ultra11y_init"]);
|
|
61497
|
+
var REFERENCE_TOOL_NAMES = /* @__PURE__ */ new Set(["ultra11y_criteria", "ultra11y_standards", "ultra11y_glossary", "ultra11y_guidance", "ultra11y_method"]);
|
|
59435
61498
|
function str2(v) {
|
|
59436
61499
|
return typeof v === "string" && v.trim() !== "" ? v : void 0;
|
|
59437
61500
|
}
|
|
@@ -59460,10 +61523,18 @@ function requiredCwd(args2, defaults) {
|
|
|
59460
61523
|
if (!statSync12(abs).isDirectory()) throw new ToolError(`\`cwd\` is not a directory: ${abs}`);
|
|
59461
61524
|
return abs;
|
|
59462
61525
|
}
|
|
61526
|
+
function optionalCwd(args2, defaults) {
|
|
61527
|
+
if (str2(args2.cwd) === void 0 && defaults.defaultCwd === void 0) return void 0;
|
|
61528
|
+
return requiredCwd(args2, defaults);
|
|
61529
|
+
}
|
|
59463
61530
|
function standardOf(args2) {
|
|
59464
|
-
const s = str2(args2.standard)
|
|
59465
|
-
if (s
|
|
59466
|
-
|
|
61531
|
+
const s = str2(args2.standard);
|
|
61532
|
+
if (s === void 0) return CORE2;
|
|
61533
|
+
try {
|
|
61534
|
+
return resolveStandard(s);
|
|
61535
|
+
} catch (e) {
|
|
61536
|
+
throw new ToolError(e instanceof Error ? e.message : String(e));
|
|
61537
|
+
}
|
|
59467
61538
|
}
|
|
59468
61539
|
function langOf(args2) {
|
|
59469
61540
|
const l = str2(args2.lang) ?? "en";
|
|
@@ -59474,9 +61545,46 @@ async function callTool2(name2, args2, defaults = {}) {
|
|
|
59474
61545
|
if (WRITE_TOOL_NAMES.has(name2) && !defaults.allowWrite) {
|
|
59475
61546
|
throw new ToolError(`${name2} changes files in your project and is disabled \u2014 start the server with --allow-write to enable it.`);
|
|
59476
61547
|
}
|
|
59477
|
-
if (name2
|
|
61548
|
+
if (REFERENCE_TOOL_NAMES.has(name2)) {
|
|
61549
|
+
const scope = optionalCwd(args2, defaults);
|
|
61550
|
+
return withStandards(scope, () => outcome(handleReference(name2, args2)));
|
|
61551
|
+
}
|
|
59478
61552
|
const cwd = requiredCwd(args2, defaults);
|
|
59479
|
-
return await withProjectLock(cwd, async () => outcome(await dispatch(name2, args2, cwd)));
|
|
61553
|
+
return await withProjectLock(cwd, async () => withStandards(cwd, async () => outcome(await dispatch(name2, args2, cwd))));
|
|
61554
|
+
}
|
|
61555
|
+
function withStandards(scope, fn) {
|
|
61556
|
+
if (scope === void 0) return fn();
|
|
61557
|
+
if (!scopeLoaded(scope)) {
|
|
61558
|
+
const warnings = [];
|
|
61559
|
+
let errors;
|
|
61560
|
+
try {
|
|
61561
|
+
errors = loadRuntimeStandards(scope, [], (m) => warnings.push(m), false, { scope }).errors;
|
|
61562
|
+
} catch (e) {
|
|
61563
|
+
dropScope(scope);
|
|
61564
|
+
throw new ToolError(`${scope}: ${e instanceof Error ? e.message : String(e)}`);
|
|
61565
|
+
}
|
|
61566
|
+
if (errors.length) {
|
|
61567
|
+
dropScope(scope);
|
|
61568
|
+
throw new ToolError(`${scope}: ${errors.join("\n")}`);
|
|
61569
|
+
}
|
|
61570
|
+
}
|
|
61571
|
+
return withScope(scope, fn);
|
|
61572
|
+
}
|
|
61573
|
+
function handleReference(name2, args2) {
|
|
61574
|
+
switch (name2) {
|
|
61575
|
+
case "ultra11y_criteria":
|
|
61576
|
+
return handleCriteria(args2);
|
|
61577
|
+
case "ultra11y_standards":
|
|
61578
|
+
return handleStandards(args2);
|
|
61579
|
+
case "ultra11y_glossary":
|
|
61580
|
+
return handleGlossary(args2);
|
|
61581
|
+
case "ultra11y_guidance":
|
|
61582
|
+
return handleGuidance(args2);
|
|
61583
|
+
case "ultra11y_method":
|
|
61584
|
+
return handleMethod(args2);
|
|
61585
|
+
default:
|
|
61586
|
+
throw new ToolError(`unknown tool: ${name2}`);
|
|
61587
|
+
}
|
|
59480
61588
|
}
|
|
59481
61589
|
async function dispatch(name2, args2, cwd) {
|
|
59482
61590
|
switch (name2) {
|
|
@@ -59766,13 +61874,65 @@ function reportText(args2, tool) {
|
|
|
59766
61874
|
}
|
|
59767
61875
|
function handleCriteria(args2) {
|
|
59768
61876
|
const lang = langOf(args2);
|
|
59769
|
-
const
|
|
59770
|
-
|
|
59771
|
-
|
|
61877
|
+
const standard = standardOf(args2);
|
|
61878
|
+
const includeGuidance = bool(args2.include_guidance);
|
|
61879
|
+
const id = str2(args2.criterion) ?? str2(args2.sc);
|
|
61880
|
+
const glossary = args2.glossary;
|
|
61881
|
+
const theme = num2(args2.theme);
|
|
61882
|
+
try {
|
|
61883
|
+
if (glossary !== void 0 && glossary !== false) {
|
|
61884
|
+
return glossaryView(standard, typeof glossary === "string" ? glossary : void 0, lang);
|
|
61885
|
+
}
|
|
61886
|
+
if (id) {
|
|
61887
|
+
const view = criterionView(standard, id, lang, includeGuidance);
|
|
61888
|
+
return isCore(standard) ? { ...view, sc: id } : view;
|
|
61889
|
+
}
|
|
61890
|
+
if (theme !== void 0) return themeView(standard, theme, lang);
|
|
61891
|
+
return criteriaIndex(standard, lang);
|
|
61892
|
+
} catch (e) {
|
|
61893
|
+
if (e instanceof CriteriaLookupError) {
|
|
61894
|
+
throw new ToolError(e.suggestions.length ? `${e.message} Did you mean: ${e.suggestions.join(", ")}?` : e.message);
|
|
61895
|
+
}
|
|
61896
|
+
throw e;
|
|
59772
61897
|
}
|
|
59773
|
-
|
|
59774
|
-
|
|
59775
|
-
return
|
|
61898
|
+
}
|
|
61899
|
+
function handleStandards(_args) {
|
|
61900
|
+
return standardsInventory();
|
|
61901
|
+
}
|
|
61902
|
+
function handleGlossary(args2) {
|
|
61903
|
+
const standard = standardOf(args2);
|
|
61904
|
+
try {
|
|
61905
|
+
return glossaryView(standard, str2(args2.term), langOf(args2));
|
|
61906
|
+
} catch (e) {
|
|
61907
|
+
if (e instanceof CriteriaLookupError) {
|
|
61908
|
+
throw new ToolError(e.suggestions.length ? `${e.message} Did you mean: ${e.suggestions.join(", ")}?` : e.message);
|
|
61909
|
+
}
|
|
61910
|
+
throw e;
|
|
61911
|
+
}
|
|
61912
|
+
}
|
|
61913
|
+
function handleGuidance(args2) {
|
|
61914
|
+
const standard = standardOf(args2);
|
|
61915
|
+
const lang = langOf(args2);
|
|
61916
|
+
const id = str2(args2.criterion) ?? str2(args2.sc);
|
|
61917
|
+
if (!id) throw new ToolError("`criterion` is required: the criterion id to fetch guidance for.");
|
|
61918
|
+
const view = criterionView(standard, id, lang, true);
|
|
61919
|
+
const guidance = view.criterion.guidance;
|
|
61920
|
+
return {
|
|
61921
|
+
standard,
|
|
61922
|
+
standardLabel: view.standardLabel,
|
|
61923
|
+
criterion: id,
|
|
61924
|
+
lang,
|
|
61925
|
+
count: guidance.length,
|
|
61926
|
+
entries: guidance,
|
|
61927
|
+
note: guidance.length ? "Guidance illustrates how to implement a criterion. It never decides a verdict, and an entry marked `inherited` comes from the WCAG mapping, not from this standard's own doctrine." : "No guidance is registered for this criterion, in this standard or through its WCAG mapping. That is not a pass \u2014 it means no example was written."
|
|
61928
|
+
};
|
|
61929
|
+
}
|
|
61930
|
+
function handleMethod(args2) {
|
|
61931
|
+
const standard = standardOf(args2);
|
|
61932
|
+
const lang = langOf(args2);
|
|
61933
|
+
const tier = str2(args2.tier);
|
|
61934
|
+
const detail = str2(args2.detail) === "full" ? "full" : "summary";
|
|
61935
|
+
return methodView(standard, lang, { ...tier ? { tier } : {}, detail });
|
|
59776
61936
|
}
|
|
59777
61937
|
function handleRead(args2, cwd) {
|
|
59778
61938
|
const raw = str2(args2.path);
|
|
@@ -59909,7 +62069,6 @@ var globsProp = {
|
|
|
59909
62069
|
};
|
|
59910
62070
|
var standardProp = {
|
|
59911
62071
|
type: "string",
|
|
59912
|
-
enum: ["wcag", "rgaa"],
|
|
59913
62072
|
description: "Which standard to report against. Default: wcag (WCAG 2.2 AA)."
|
|
59914
62073
|
};
|
|
59915
62074
|
var langProp = { type: "string", enum: ["en", "fr"], description: "Language for the rendered prose. Default: en." };
|
|
@@ -59989,11 +62148,25 @@ var TOOLS2 = [
|
|
|
59989
62148
|
{
|
|
59990
62149
|
name: "ultra11y_criteria",
|
|
59991
62150
|
title: "The offline standards reference",
|
|
59992
|
-
description: "Look up what a
|
|
62151
|
+
description: "Look up what a criterion actually requires \u2014 its exact wording, its numbered tests, the terms the standard defines for it, and what it takes to decide it. Works for WCAG success criteria AND for any country standard's own criteria (RGAA 8.3, and whatever packs this project loads). Offline and authoritative; use it instead of recalling a criterion from memory, which is how invented non-conformities get written.",
|
|
59993
62152
|
inputSchema: {
|
|
59994
62153
|
type: "object",
|
|
59995
62154
|
properties: {
|
|
59996
|
-
|
|
62155
|
+
cwd: {
|
|
62156
|
+
type: "string",
|
|
62157
|
+
description: "Absolute path to the project root. Optional \u2014 it decides which standards packs are loaded, not which files are read."
|
|
62158
|
+
},
|
|
62159
|
+
sc: { type: "string", description: "A criterion id: a WCAG success criterion ('1.1.1') or a pack criterion ('8.3'). Omit to list them all." },
|
|
62160
|
+
criterion: { type: "string", description: "Alias for `sc`, for a standard whose criteria are not WCAG success criteria." },
|
|
62161
|
+
theme: { type: "number", description: "List one theme of a country standard (e.g. 8). Not applicable to WCAG, which groups by guideline." },
|
|
62162
|
+
glossary: {
|
|
62163
|
+
type: "string",
|
|
62164
|
+
description: "Look up a term the standard normatively DEFINES. Pass a term, or an empty string to list every term."
|
|
62165
|
+
},
|
|
62166
|
+
include_guidance: {
|
|
62167
|
+
type: "boolean",
|
|
62168
|
+
description: "Also attach before/after implementation examples for the criterion. Default false \u2014 they are large."
|
|
62169
|
+
},
|
|
59997
62170
|
standard: standardProp,
|
|
59998
62171
|
lang: langProp
|
|
59999
62172
|
},
|
|
@@ -60161,6 +62334,77 @@ var WRITE_TOOLS = [
|
|
|
60161
62334
|
}
|
|
60162
62335
|
}
|
|
60163
62336
|
];
|
|
62337
|
+
var referenceCwdProp = {
|
|
62338
|
+
type: "string",
|
|
62339
|
+
description: "Absolute path to the project root. Optional \u2014 it decides which standards packs are loaded, not which files are read."
|
|
62340
|
+
};
|
|
62341
|
+
var REFERENCE_TOOLS = [
|
|
62342
|
+
{
|
|
62343
|
+
name: "ultra11y_standards",
|
|
62344
|
+
title: "The standards this project can be audited against",
|
|
62345
|
+
description: "List every standard available here: the WCAG 2.2 AA core, the country packs built into this build, and any pack the project's .ultra11yrc.json or --pack loaded. Each carries its own coverage arithmetic \u2014 how many criteria it has, and how many of them any engine could ever decide. Standards are per-project: a pack another project declares is not yours. Call this before assuming a standard exists.",
|
|
62346
|
+
inputSchema: {
|
|
62347
|
+
type: "object",
|
|
62348
|
+
properties: { cwd: referenceCwdProp, lang: langProp },
|
|
62349
|
+
required: []
|
|
62350
|
+
}
|
|
62351
|
+
},
|
|
62352
|
+
{
|
|
62353
|
+
name: "ultra11y_glossary",
|
|
62354
|
+
title: "The terms a standard normatively defines",
|
|
62355
|
+
description: "A standard's tests lean constantly on terms it defines itself \u2014 'informative image', 'relevant', 'if necessary'. Those definitions are normative: they decide the verdict, and the everyday meaning of the word is not what is being asked. Look one up rather than assuming, and see which criteria it governs.",
|
|
62356
|
+
inputSchema: {
|
|
62357
|
+
type: "object",
|
|
62358
|
+
properties: {
|
|
62359
|
+
standard: standardProp,
|
|
62360
|
+
term: { type: "string", description: "A term or its anchor. Omit to list every term the standard defines." },
|
|
62361
|
+
cwd: referenceCwdProp,
|
|
62362
|
+
lang: langProp
|
|
62363
|
+
},
|
|
62364
|
+
required: ["standard"]
|
|
62365
|
+
}
|
|
62366
|
+
},
|
|
62367
|
+
{
|
|
62368
|
+
name: "ultra11y_guidance",
|
|
62369
|
+
title: "Before/after implementation guidance for a criterion",
|
|
62370
|
+
description: "The concrete how-to-implement rule for a criterion: a non-compliant snippet, the compliant fix, and the note explaining the difference. A country criterion with no guidance of its own inherits what is keyed to the WCAG success criteria it maps to, marked as inherited. Guidance ILLUSTRATES \u2014 it never decides a verdict and never turns into a non-conformity.",
|
|
62371
|
+
inputSchema: {
|
|
62372
|
+
type: "object",
|
|
62373
|
+
properties: {
|
|
62374
|
+
standard: standardProp,
|
|
62375
|
+
criterion: { type: "string", description: "The criterion id to fetch guidance for (a WCAG SC, or a pack criterion like '1.2')." },
|
|
62376
|
+
sc: { type: "string", description: "Alias for `criterion`." },
|
|
62377
|
+
cwd: referenceCwdProp,
|
|
62378
|
+
lang: langProp
|
|
62379
|
+
},
|
|
62380
|
+
required: []
|
|
62381
|
+
}
|
|
62382
|
+
},
|
|
62383
|
+
{
|
|
62384
|
+
name: "ultra11y_method",
|
|
62385
|
+
title: "The audit work plan for a standard",
|
|
62386
|
+
description: "Get the plan before auditing anything: which of this standard's criteria the static engine decides from source alone, which need a captured page or a real browser, and which are judgment calls only you can make \u2014 each with the evidence to gather and the tool that produces it. Derived from this engine's own per-criterion rule applicability and WCAG automatability data, not from guessing at the wording of a test. A criterion nobody tested is untested, never conformant.",
|
|
62387
|
+
inputSchema: {
|
|
62388
|
+
type: "object",
|
|
62389
|
+
properties: {
|
|
62390
|
+
standard: standardProp,
|
|
62391
|
+
cwd: referenceCwdProp,
|
|
62392
|
+
lang: langProp,
|
|
62393
|
+
tier: {
|
|
62394
|
+
type: "string",
|
|
62395
|
+
enum: ["source", "cross-file", "rendered-page", "browser", "judgment", "out-of-scope"],
|
|
62396
|
+
description: "Return only the criteria in this evidence tier."
|
|
62397
|
+
},
|
|
62398
|
+
detail: {
|
|
62399
|
+
type: "string",
|
|
62400
|
+
enum: ["summary", "full"],
|
|
62401
|
+
description: "'summary' (default) is counts plus criterion ids; 'full' adds each criterion's title, rules and reason."
|
|
62402
|
+
}
|
|
62403
|
+
},
|
|
62404
|
+
required: []
|
|
62405
|
+
}
|
|
62406
|
+
}
|
|
62407
|
+
];
|
|
60164
62408
|
var TOOL_META2 = {
|
|
60165
62409
|
ultra11y_audit: { openWorld: false },
|
|
60166
62410
|
ultra11y_report: { openWorld: false },
|
|
@@ -60171,6 +62415,11 @@ var TOOL_META2 = {
|
|
|
60171
62415
|
// somebody's tracker off the back of a prompt injection.
|
|
60172
62416
|
ultra11y_tickets: { openWorld: false },
|
|
60173
62417
|
ultra11y_criteria: { openWorld: false },
|
|
62418
|
+
// The reference block: they read the vendored standard and nothing else.
|
|
62419
|
+
ultra11y_standards: { openWorld: false },
|
|
62420
|
+
ultra11y_glossary: { openWorld: false },
|
|
62421
|
+
ultra11y_guidance: { openWorld: false },
|
|
62422
|
+
ultra11y_method: { openWorld: false },
|
|
60174
62423
|
ultra11y_check: { openWorld: false },
|
|
60175
62424
|
ultra11y_verify: { openWorld: false },
|
|
60176
62425
|
ultra11y_adjudicate: { openWorld: false },
|
|
@@ -60195,14 +62444,14 @@ function annotationsFor2(name2) {
|
|
|
60195
62444
|
};
|
|
60196
62445
|
}
|
|
60197
62446
|
function toolsFor2(protocolVersion, opts = {}) {
|
|
60198
|
-
const base = opts.allowWrite ? [...TOOLS2, ...WRITE_TOOLS] : TOOLS2;
|
|
62447
|
+
const base = opts.allowWrite ? [...TOOLS2, ...REFERENCE_TOOLS, ...WRITE_TOOLS] : [...TOOLS2, ...REFERENCE_TOOLS];
|
|
60199
62448
|
const withAnnotations = protocolVersion >= ANNOTATIONS_SINCE2;
|
|
60200
62449
|
const withRich = protocolVersion >= RICH_TOOLS_SINCE2;
|
|
60201
62450
|
return base.map((t2) => {
|
|
60202
62451
|
const decl = {
|
|
60203
62452
|
name: t2.name,
|
|
60204
62453
|
description: t2.description,
|
|
60205
|
-
inputSchema: applyDefaultCwd(t2.inputSchema, opts.defaultCwd)
|
|
62454
|
+
inputSchema: applyStandards(applyDefaultCwd(t2.inputSchema, opts.defaultCwd), opts.standards)
|
|
60206
62455
|
};
|
|
60207
62456
|
if (withRich && t2.title) decl.title = t2.title;
|
|
60208
62457
|
if (withRich && t2.outputSchema) decl.outputSchema = t2.outputSchema;
|
|
@@ -60213,6 +62462,15 @@ function toolsFor2(protocolVersion, opts = {}) {
|
|
|
60213
62462
|
return decl;
|
|
60214
62463
|
});
|
|
60215
62464
|
}
|
|
62465
|
+
function applyStandards(schema, standards) {
|
|
62466
|
+
const existing = schema.properties.standard;
|
|
62467
|
+
if (!existing?.description || !standards?.length) return schema;
|
|
62468
|
+
const standard = {
|
|
62469
|
+
...existing,
|
|
62470
|
+
description: `${existing.description} Loaded here: ${standards.join(", ")}. A project's own packs load with it \u2014 call ultra11y_standards to list them.`
|
|
62471
|
+
};
|
|
62472
|
+
return { ...schema, properties: { ...schema.properties, standard } };
|
|
62473
|
+
}
|
|
60216
62474
|
function applyDefaultCwd(schema, defaultCwd) {
|
|
60217
62475
|
const existing = schema.properties.cwd;
|
|
60218
62476
|
if (!defaultCwd || !existing) return schema;
|
|
@@ -60238,14 +62496,25 @@ var PROMPTS = [
|
|
|
60238
62496
|
arguments: [
|
|
60239
62497
|
cwdArg,
|
|
60240
62498
|
{ name: "globs", description: "What to audit, comma-separated (default: the project's markup).", required: false },
|
|
60241
|
-
{
|
|
62499
|
+
{
|
|
62500
|
+
name: "standard",
|
|
62501
|
+
description: "The standard key to report against \u2014 `ultra11y_standards` lists what this project has. Default: wcag.",
|
|
62502
|
+
required: false
|
|
62503
|
+
}
|
|
60242
62504
|
]
|
|
60243
62505
|
},
|
|
60244
62506
|
{
|
|
60245
62507
|
name: "adjudicate_criteria",
|
|
60246
62508
|
title: "Decide the criteria the engine cannot",
|
|
60247
62509
|
description: "The judgment workflow: work the adjudication queue \u2014 alt-text relevance, link purpose in context, heading structure, reading order \u2014 by reading the real markup, not by pattern-matching the element.",
|
|
60248
|
-
arguments: [
|
|
62510
|
+
arguments: [
|
|
62511
|
+
cwdArg,
|
|
62512
|
+
{
|
|
62513
|
+
name: "standard",
|
|
62514
|
+
description: "The standard key to adjudicate against \u2014 `ultra11y_standards` lists what this project has. Default: wcag.",
|
|
62515
|
+
required: false
|
|
62516
|
+
}
|
|
62517
|
+
]
|
|
60249
62518
|
},
|
|
60250
62519
|
{
|
|
60251
62520
|
name: "review_diff_a11y",
|
|
@@ -60401,8 +62670,8 @@ function firstProse(file) {
|
|
|
60401
62670
|
} catch {
|
|
60402
62671
|
return void 0;
|
|
60403
62672
|
}
|
|
60404
|
-
const
|
|
60405
|
-
for (const block of
|
|
62673
|
+
const body3 = text.startsWith("---\n") ? text.slice(text.indexOf("\n---", 3) + 4) : text;
|
|
62674
|
+
for (const block of body3.split(/\n\s*\n/)) {
|
|
60406
62675
|
const line = block.trim();
|
|
60407
62676
|
if (!line || line.startsWith("#") || line.startsWith(">") || line.startsWith("|") || line.startsWith("```")) continue;
|
|
60408
62677
|
const flat = line.replace(/\s+/g, " ").replace(/[*`]/g, "");
|
|
@@ -60411,6 +62680,133 @@ function firstProse(file) {
|
|
|
60411
62680
|
return void 0;
|
|
60412
62681
|
}
|
|
60413
62682
|
|
|
62683
|
+
// src/mcp/standards-resources.ts
|
|
62684
|
+
var SCHEME = "std://";
|
|
62685
|
+
var MIME = "application/json";
|
|
62686
|
+
function hasGlossary(key) {
|
|
62687
|
+
return Object.keys(isCore(key) ? coreGlossary() : packGlossary(key) ?? {}).length > 0;
|
|
62688
|
+
}
|
|
62689
|
+
function listStandardResources() {
|
|
62690
|
+
const out2 = [];
|
|
62691
|
+
for (const key of listStandards()) {
|
|
62692
|
+
const label = standardLabel(key);
|
|
62693
|
+
out2.push({
|
|
62694
|
+
uri: `${SCHEME}${key}/criteria`,
|
|
62695
|
+
name: `${key}/criteria`,
|
|
62696
|
+
title: `${label}: every criterion`,
|
|
62697
|
+
description: `The full criterion index for ${label}, with the evidence tier each one needs.`,
|
|
62698
|
+
mimeType: MIME
|
|
62699
|
+
});
|
|
62700
|
+
out2.push({
|
|
62701
|
+
uri: `${SCHEME}${key}/method`,
|
|
62702
|
+
name: `${key}/method`,
|
|
62703
|
+
title: `${label}: the audit work plan`,
|
|
62704
|
+
description: `Which ${label} criteria the engine decides from source, which need a rendered page or a browser, and which are judgment calls.`,
|
|
62705
|
+
mimeType: MIME
|
|
62706
|
+
});
|
|
62707
|
+
if (hasGlossary(key)) {
|
|
62708
|
+
out2.push({
|
|
62709
|
+
uri: `${SCHEME}${key}/glossary`,
|
|
62710
|
+
name: `${key}/glossary`,
|
|
62711
|
+
title: `${label}: the terms it defines`,
|
|
62712
|
+
description: `The terms ${label} defines normatively \u2014 the definitions that decide its verdicts.`,
|
|
62713
|
+
mimeType: MIME
|
|
62714
|
+
});
|
|
62715
|
+
}
|
|
62716
|
+
if (!isCore(key)) {
|
|
62717
|
+
out2.push({
|
|
62718
|
+
uri: `${SCHEME}${key}/pack.json`,
|
|
62719
|
+
name: `${key}/pack.json`,
|
|
62720
|
+
title: `${label}: the standards pack`,
|
|
62721
|
+
description: `The whole ${label} pack as ultra11y loads it, including its licence and attribution.`,
|
|
62722
|
+
mimeType: MIME
|
|
62723
|
+
});
|
|
62724
|
+
}
|
|
62725
|
+
}
|
|
62726
|
+
return out2;
|
|
62727
|
+
}
|
|
62728
|
+
function listStandardResourceTemplates() {
|
|
62729
|
+
return [
|
|
62730
|
+
{
|
|
62731
|
+
uriTemplate: `${SCHEME}{standard}/criteria/{id}`,
|
|
62732
|
+
name: "criterion",
|
|
62733
|
+
title: "One criterion of one standard",
|
|
62734
|
+
description: "A criterion in full: its wording, its numbered tests, the terms it leans on, and what it takes to decide it.",
|
|
62735
|
+
mimeType: MIME
|
|
62736
|
+
},
|
|
62737
|
+
{
|
|
62738
|
+
uriTemplate: `${SCHEME}{standard}/themes/{number}`,
|
|
62739
|
+
name: "theme",
|
|
62740
|
+
title: "One theme of a country standard",
|
|
62741
|
+
description: "The criteria grouped under one theme of a country standard. WCAG groups by guideline instead.",
|
|
62742
|
+
mimeType: MIME
|
|
62743
|
+
},
|
|
62744
|
+
{
|
|
62745
|
+
uriTemplate: `${SCHEME}{standard}/glossary/{term}`,
|
|
62746
|
+
name: "glossary-term",
|
|
62747
|
+
title: "A term a standard normatively defines",
|
|
62748
|
+
description: "The normative definition of a term, and the criteria it governs.",
|
|
62749
|
+
mimeType: MIME
|
|
62750
|
+
},
|
|
62751
|
+
{
|
|
62752
|
+
uriTemplate: `${SCHEME}{standard}/guidance/{criterion}`,
|
|
62753
|
+
name: "guidance",
|
|
62754
|
+
title: "Implementation guidance for a criterion",
|
|
62755
|
+
description: "Before/after examples for a criterion, including those inherited through its WCAG mapping.",
|
|
62756
|
+
mimeType: MIME
|
|
62757
|
+
}
|
|
62758
|
+
];
|
|
62759
|
+
}
|
|
62760
|
+
function isStandardUri(uri) {
|
|
62761
|
+
return uri.startsWith(SCHEME);
|
|
62762
|
+
}
|
|
62763
|
+
function body2(value) {
|
|
62764
|
+
return JSON.stringify(value, null, 2);
|
|
62765
|
+
}
|
|
62766
|
+
function readStandardResource(uri, lang = "en") {
|
|
62767
|
+
const rest = uri.slice(SCHEME.length);
|
|
62768
|
+
const parts2 = rest.split("/").filter(Boolean);
|
|
62769
|
+
const standard = parts2[0];
|
|
62770
|
+
if (!standard) throw new ResourceError(`no standard named in "${uri}" (expected ${SCHEME}<standard>/\u2026)`);
|
|
62771
|
+
if (!listStandards().includes(standard)) {
|
|
62772
|
+
throw new ResourceError(`unknown standard "${standard}" (known: ${listStandards().join(", ")})`);
|
|
62773
|
+
}
|
|
62774
|
+
const decode = (s) => {
|
|
62775
|
+
try {
|
|
62776
|
+
return decodeURIComponent(s);
|
|
62777
|
+
} catch {
|
|
62778
|
+
return s;
|
|
62779
|
+
}
|
|
62780
|
+
};
|
|
62781
|
+
try {
|
|
62782
|
+
const [, section, ...tail] = parts2;
|
|
62783
|
+
const key = tail.length ? decode(tail.join("/")) : void 0;
|
|
62784
|
+
if (section === void 0) return { uri, mimeType: MIME, text: body2(criteriaIndex(standard, lang)) };
|
|
62785
|
+
if (section === "criteria") {
|
|
62786
|
+
return { uri, mimeType: MIME, text: body2(key ? criterionView(standard, key, lang, true) : criteriaIndex(standard, lang)) };
|
|
62787
|
+
}
|
|
62788
|
+
if (section === "themes") {
|
|
62789
|
+
if (!key) throw new ResourceError(`no theme named in "${uri}"`);
|
|
62790
|
+
return { uri, mimeType: MIME, text: body2(themeView(standard, Number(key), lang)) };
|
|
62791
|
+
}
|
|
62792
|
+
if (section === "glossary") return { uri, mimeType: MIME, text: body2(glossaryView(standard, key, lang)) };
|
|
62793
|
+
if (section === "guidance") {
|
|
62794
|
+
if (!key) throw new ResourceError(`no criterion named in "${uri}"`);
|
|
62795
|
+
const view = criterionView(standard, key, lang, true);
|
|
62796
|
+
return { uri, mimeType: MIME, text: body2({ standard, criterion: key, entries: view.criterion.guidance }) };
|
|
62797
|
+
}
|
|
62798
|
+
if (section === "method") return { uri, mimeType: MIME, text: body2(methodView(standard, lang)) };
|
|
62799
|
+
if (section === "pack.json") {
|
|
62800
|
+
if (isCore(standard)) throw new ResourceError("the WCAG core is not a standards pack \u2014 read std://wcag/criteria instead");
|
|
62801
|
+
return { uri, mimeType: MIME, text: body2(loadPack(standard)) };
|
|
62802
|
+
}
|
|
62803
|
+
throw new ResourceError(`unknown standards resource: ${uri}`);
|
|
62804
|
+
} catch (e) {
|
|
62805
|
+
if (e instanceof CriteriaLookupError) throw new ResourceError(e.message);
|
|
62806
|
+
throw e;
|
|
62807
|
+
}
|
|
62808
|
+
}
|
|
62809
|
+
|
|
60414
62810
|
// src/mcp/server.ts
|
|
60415
62811
|
var ERR_INVALID_REQUEST = -32600;
|
|
60416
62812
|
var ERR_METHOD_NOT_FOUND = -32601;
|
|
@@ -60422,7 +62818,7 @@ function createServer2(opts = {}) {
|
|
|
60422
62818
|
let protocol = LATEST_PROTOCOL2;
|
|
60423
62819
|
const cancelled = /* @__PURE__ */ new Set();
|
|
60424
62820
|
const CANCELLED_MAX = 1024;
|
|
60425
|
-
const listTools = () => toolsFor2(protocol, { defaultCwd: opts.defaultCwd, allowWrite: opts.allowWrite });
|
|
62821
|
+
const listTools = () => toolsFor2(protocol, { defaultCwd: opts.defaultCwd, allowWrite: opts.allowWrite, standards: listStandards() });
|
|
60426
62822
|
async function handle2(msg, send) {
|
|
60427
62823
|
if (msg === null || typeof msg !== "object" || Array.isArray(msg)) {
|
|
60428
62824
|
send({ jsonrpc: "2.0", id: null, error: { code: ERR_INVALID_REQUEST, message: "invalid request: expected a JSON-RPC object" } });
|
|
@@ -60474,7 +62870,10 @@ function createServer2(opts = {}) {
|
|
|
60474
62870
|
await handleToolCall(msg, reply);
|
|
60475
62871
|
return;
|
|
60476
62872
|
case "resources/list":
|
|
60477
|
-
reply({ result: { resources: listResources(opts.skillDir) } });
|
|
62873
|
+
reply({ result: { resources: withStandards(opts.defaultCwd, () => [...listResources(opts.skillDir), ...listStandardResources()]) } });
|
|
62874
|
+
return;
|
|
62875
|
+
case "resources/templates/list":
|
|
62876
|
+
reply({ result: { resourceTemplates: listStandardResourceTemplates() } });
|
|
60478
62877
|
return;
|
|
60479
62878
|
case "resources/read": {
|
|
60480
62879
|
const uri = typeof msg.params?.uri === "string" ? msg.params.uri : "";
|
|
@@ -60483,7 +62882,8 @@ function createServer2(opts = {}) {
|
|
|
60483
62882
|
return;
|
|
60484
62883
|
}
|
|
60485
62884
|
try {
|
|
60486
|
-
|
|
62885
|
+
const contents = isStandardUri(uri) ? withStandards(opts.defaultCwd, () => readStandardResource(uri)) : readResource(uri, opts.skillDir);
|
|
62886
|
+
reply({ result: { contents: [contents] } });
|
|
60487
62887
|
} catch (e) {
|
|
60488
62888
|
if (e instanceof ResourceError) reply({ error: { code: ERR_INVALID_PARAMS, message: e.message } });
|
|
60489
62889
|
else reply({ error: { code: ERR_INTERNAL, message: errMessage2(e) } });
|
|
@@ -60648,14 +63048,14 @@ function startHttpServer(opts = {}) {
|
|
|
60648
63048
|
server.requestTimeout = 0;
|
|
60649
63049
|
server.headersTimeout = 6e4;
|
|
60650
63050
|
server.keepAliveTimeout = 12e4;
|
|
60651
|
-
return new Promise((
|
|
63051
|
+
return new Promise((resolve16, reject) => {
|
|
60652
63052
|
server.once("error", reject);
|
|
60653
63053
|
server.listen(opts.port ?? 0, bind, () => {
|
|
60654
63054
|
server.removeListener("error", reject);
|
|
60655
63055
|
const addr2 = server.address();
|
|
60656
63056
|
const port = typeof addr2 === "object" && addr2 ? addr2.port : opts.port ?? 0;
|
|
60657
63057
|
const host = bind.includes(":") ? `[${bind}]` : bind;
|
|
60658
|
-
|
|
63058
|
+
resolve16({
|
|
60659
63059
|
server,
|
|
60660
63060
|
port,
|
|
60661
63061
|
url: `http://${host}:${port}${MCP_PATH}`,
|
|
@@ -60752,8 +63152,8 @@ function header3(req, name2) {
|
|
|
60752
63152
|
function corsHeaders(origin) {
|
|
60753
63153
|
return origin ? { "access-control-allow-origin": origin, vary: "origin" } : {};
|
|
60754
63154
|
}
|
|
60755
|
-
function sendJson(res, status,
|
|
60756
|
-
const text = JSON.stringify(
|
|
63155
|
+
function sendJson(res, status, body3, origin, extra = {}) {
|
|
63156
|
+
const text = JSON.stringify(body3);
|
|
60757
63157
|
res.writeHead(status, {
|
|
60758
63158
|
"content-type": "application/json",
|
|
60759
63159
|
"content-length": String(Buffer.byteLength(text, "utf8")),
|
|
@@ -60764,7 +63164,7 @@ function sendJson(res, status, body2, origin, extra = {}) {
|
|
|
60764
63164
|
}
|
|
60765
63165
|
var DRAIN_LIMIT = MAX_BODY_BYTES * 8;
|
|
60766
63166
|
function readBody2(req) {
|
|
60767
|
-
return new Promise((
|
|
63167
|
+
return new Promise((resolve16, reject) => {
|
|
60768
63168
|
const chunks = [];
|
|
60769
63169
|
let size = 0;
|
|
60770
63170
|
let over = false;
|
|
@@ -60788,7 +63188,7 @@ function readBody2(req) {
|
|
|
60788
63188
|
});
|
|
60789
63189
|
req.on("end", () => {
|
|
60790
63190
|
if (over) reject(new Error("too large"));
|
|
60791
|
-
else
|
|
63191
|
+
else resolve16(Buffer.concat(chunks).toString("utf8"));
|
|
60792
63192
|
});
|
|
60793
63193
|
req.on("error", reject);
|
|
60794
63194
|
req.on("aborted", () => reject(new Error("client aborted the request")));
|
|
@@ -61674,9 +64074,9 @@ async function cmdDev(p) {
|
|
|
61674
64074
|
}
|
|
61675
64075
|
console.error(fr ? `ultra11y dev : tableau de bord sur http://127.0.0.1:${server.port}` : `ultra11y dev: dashboard on http://127.0.0.1:${server.port}`);
|
|
61676
64076
|
console.error(fr ? "Boucle locale uniquement (l'outil \xE9crit des fichiers). Ctrl-C pour arr\xEAter." : "Loopback only (the tool writes files). Ctrl-C to stop.");
|
|
61677
|
-
await new Promise((
|
|
64077
|
+
await new Promise((resolve16) => {
|
|
61678
64078
|
const stop2 = () => {
|
|
61679
|
-
void server.close().then(
|
|
64079
|
+
void server.close().then(resolve16);
|
|
61680
64080
|
};
|
|
61681
64081
|
process.once("SIGINT", stop2);
|
|
61682
64082
|
process.once("SIGTERM", stop2);
|
|
@@ -63635,7 +66035,8 @@ async function main(argv) {
|
|
|
63635
66035
|
if (typeof v === "string" && v && !allowed.includes(v)) console.error(`ultra11y: --${flag} "${v}" is not one of ${allowed.join("|")} \u2014 using the default.`);
|
|
63636
66036
|
}
|
|
63637
66037
|
const packList = typeof p.flags.pack === "string" ? p.flags.pack.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
63638
|
-
const
|
|
66038
|
+
const configRoot = p.command === "mcp" && typeof p.flags.cwd === "string" && p.flags.cwd ? resolve15(p.flags.cwd) : process.cwd();
|
|
66039
|
+
const loaded2 = loadRuntimeStandards(configRoot, packList, (m) => console.error(m), p.flags.override === true);
|
|
63639
66040
|
if (loaded2.errors.length) {
|
|
63640
66041
|
for (const e of loaded2.errors) console.error(`ultra11y: ${e}`);
|
|
63641
66042
|
return 2;
|