From 6a2540dc5c4e57b508af9da567ca86ccc8391aa7 Mon Sep 17 00:00:00 2001 From: Guillaume PERE Date: Thu, 30 May 2024 09:09:01 +0200 Subject: [PATCH 01/20] Web > Tests > Update the right menu "On this page" --- src/assets/test-web.js | 857 +++++++++++++++++++++-------------------- 1 file changed, 436 insertions(+), 421 deletions(-) diff --git a/src/assets/test-web.js b/src/assets/test-web.js index fbc9152a8..1d210c724 100644 --- a/src/assets/test-web.js +++ b/src/assets/test-web.js @@ -1,553 +1,568 @@ -document.addEventListener("DOMContentLoaded", function(event) { - const lang = document.documentElement.getAttribute('lang') - - if (!lang) { - throw new Error('A lang attribute must be set on the tag !') - } - - const locales = { - 'en': { - process : "Process", - check : "To check", - conception: 'Design', - development: 'Development', - results : "Results", - justification : "Justification", - profiles: 'Profiles', - tools: 'Tools', - allTools: 'All tools', - allProfils: 'All profiles', - exceptions: 'Exceptions', - ongoingTests: 'ongoing tests', - noResults: 'No results match your selection', - withCurrentFilters: 'with current filters', - reinitFilters: 'Reinit  filters' - }, - 'fr': { - process : "Procédures", - check : "A vérifier", - conception: 'Conception', - development: 'Développement', - results : "Résultats", - justification : "Justification", - profiles: 'Profils ', - tools: 'Outils ', - allTools: 'Tous les outils', - allProfils: 'Tous les profils', - exceptions: 'Exceptions', - ongoingTests: 'tests en cours', - noResults: 'Aucun résultat ne correspond à votre sélection', - withCurrentFilters: 'dans les filtres en cours', - reinitFilters: 'Réinitialiser  les filtres' +document.addEventListener("DOMContentLoaded", function (event) { + const lang = document.documentElement.getAttribute('lang') + + if (!lang) { + throw new Error('A lang attribute must be set on the tag !') } - } - function translate(key, to) { - const locale = to || lang + const locales = { + 'en': { + process: "Process", + check: "To check", + conception: 'Design', + development: 'Development', + results: "Results", + justification: "Justification", + profiles: 'Profiles', + tools: 'Tools', + allTools: 'All tools', + allProfils: 'All profiles', + exceptions: 'Exceptions', + ongoingTests: 'ongoing tests', + noResults: 'No results match your selection', + withCurrentFilters: 'with current filters', + reinitFilters: 'Reinit  filters' + }, + 'fr': { + process: "Procédures", + check: "A vérifier", + conception: 'Conception', + development: 'Développement', + results: "Résultats", + justification: "Justification", + profiles: 'Profils ', + tools: 'Outils ', + allTools: 'Tous les outils', + allProfils: 'Tous les profils', + exceptions: 'Exceptions', + ongoingTests: 'tests en cours', + noResults: 'Aucun résultat ne correspond à votre sélection', + withCurrentFilters: 'dans les filtres en cours', + reinitFilters: 'Réinitialiser  les filtres' + } + } + + function translate(key, to) { + const locale = to || lang + + if (!locales.hasOwnProperty(locale)) { + throw new Error(`translate(): Translation's locale \`${locale}\` does not exist`) + } + + if (!locales[locale].hasOwnProperty(key)) { + throw new Error(`translate(): Translation's key \`${key}\` does not exist for locale \`${locale}\``) + } - if (!locales.hasOwnProperty(locale)) { - throw new Error(`translate(): Translation's locale \`${locale}\` does not exist`) + return locales[locale][key] } - if (!locales[locale].hasOwnProperty(key)) { - throw new Error(`translate(): Translation's key \`${key}\` does not exist for locale \`${locale}\``) + //requette XMLHttpRequest + function doXHR(url, callback) { + var oReq = new XMLHttpRequest(); + + oReq.onreadystatechange = function (event) { + if (this.readyState === XMLHttpRequest.DONE) { + if (this.status === 200) { + return callback(null, this.responseText); + } else { + return callback({errCode: this.status, errMsg: this.statusText}); + } + } + }; + oReq.open('GET', url, true); + oReq.send(null); } - return locales[locale][key] - } + //appel des Json - //requette XMLHttpRequest - function doXHR(url, callback) { - var oReq = new XMLHttpRequest(); - oReq.onreadystatechange = function(event) { - if (this.readyState === XMLHttpRequest.DONE) { - if (this.status === 200) { - return callback(null, this.responseText); - } else { - return callback({errCode: this.status, errMsg: this.statusText}); + doXHR('/assets/json/checklist/tests-web-' + lang + '.json', function (errFirst, responseFirst) { + if (errFirst) { + reqError(); } - } - }; - oReq.open('GET', url, true); - oReq.send(null); - } - - //appel des Json - - - doXHR('/assets/json/checklist/tests-web-'+lang+'.json', function(errFirst, responseFirst) { - if (errFirst) { - reqError(); - } - return doXHR('/assets/json/checklist/tests-concepteur-'+lang+'.json', function(errSecond, responseSecond) { - if (errSecond) { - reqError(); - } - return reqListener(responseFirst, responseSecond); - }); + return doXHR('/assets/json/checklist/tests-concepteur-' + lang + '.json', function (errSecond, responseSecond) { + if (errSecond) { + reqError(); + } + return reqListener(responseFirst, responseSecond); + }); - }); + }); - function reqError(err) { - let elrefTests = document.getElementById('refTests'); - elrefTests.innerHTML = '
Erreur chargement ressource JSON
'; - } + function reqError(err) { + let elrefTests = document.getElementById('refTests'); + elrefTests.innerHTML = '
Erreur chargement ressource JSON
'; + } - //on concatene les 2 jsons en les réorganisant par tests - function compareReorder(a, b) { + //on concatene les 2 jsons en les réorganisant par tests + function compareReorder(a, b) { - // si les titres sont identiques, on regroupe par titre - for (var i = 0; i < a.length; i++) { + // si les titres sont identiques, on regroupe par titre + for (var i = 0; i < a.length; i++) { - let testA = a[i].title; + let testA = a[i].title; - for (var j = 0; j < b.length; j++) { + for (var j = 0; j < b.length; j++) { - var testB = b[j].title; + var testB = b[j].title; - if (testA==testB){ - a.splice(i++, 0, b[j]); - b.splice(j, 1); + if (testA == testB) { + a.splice(i++, 0, b[j]); + b.splice(j, 1); - } + } - } + } - } + } - //sinon on regroupe les tests par themes - for (var i = 0; i < a.length; i++) { + //sinon on regroupe les tests par themes + for (var i = 0; i < a.length; i++) { - let testC = a[i].themes; + let testC = a[i].themes; - for (var j = 0; j < b.length; j++) { + for (var j = 0; j < b.length; j++) { - var testD = b[j].themes; + var testD = b[j].themes; - if (testC==testD){ - a.splice(i, 0, b[j]); - b.splice(j, 1); + if (testC == testD) { + a.splice(i, 0, b[j]); + b.splice(j, 1); + } + } } - } + return a; } - return a; - } - // function encode(str){ + // function encode(str){ - // str=str.replace(/[\x26\x0A\<>'"^]/gi, function(r){return"&#"+r.charCodeAt(0)+";"}); - // str=str.replace(/\<code\>([\s\S]*?)\<\/code\>/g, '$1'); + // str=str.replace(/[\x26\x0A\<>'"^]/gi, function(r){return"&#"+r.charCodeAt(0)+";"}); + // str=str.replace(/\<code\>([\s\S]*?)\<\/code\>/g, '$1'); - // return str; - // } + // return str; + // } - function formatHeading(str){ - str = str.toLowerCase(); - str = str.replace(/é|è|ê/g,"e"); - str = str.replace(/ /g,"-"); + function formatHeading(str) { + str = str.toLowerCase(); + str = str.replace(/é|è|ê/g, "e"); + str = str.replace(/ /g, "-"); - return str; - } + return str; + } - //supprimer les doublons dans les filtres - function delDoublon(arrCond, inputId){ - for (var i = 0; i < arrCond.length; i++) { - //for (let condition of arrCond) { - let condition = arrCond[i]; - if (condition.name == inputId) { - let arrCondIndex = arrCond.indexOf(condition); - arrCond.splice(arrCondIndex , 1); - } + //supprimer les doublons dans les filtres + function delDoublon(arrCond, inputId) { + for (var i = 0; i < arrCond.length; i++) { + //for (let condition of arrCond) { + let condition = arrCond[i]; + if (condition.name == inputId) { + let arrCondIndex = arrCond.indexOf(condition); + arrCond.splice(arrCondIndex, 1); + } + } + return arrCond; } - return arrCond; - } - function reqListener(responseFirst, responseSecond) { + function reqListener(responseFirst, responseSecond) { + var data = JSON.parse(responseFirst); + var data2 = JSON.parse(responseSecond); + var uniqueTypes = []; + var refTests = compareReorder(data, data2); - var data = JSON.parse(responseFirst); - var data2 = JSON.parse(responseSecond); - var uniqueTypes = []; - var refTests = compareReorder(data, data2); + // Get the right menu + const toc = document.getElementById('toc'); + let ul = toc.querySelector('ul'); + const originalUl = ul.cloneNode(true); - let app = new function() { - // Récupération des données - //this.refTests = refTests; + let app = new function () { + // Récupération des données + //this.refTests = refTests; - this.UpdateTypes = function(allTypes, updatedTypes) { - let elrefTypes = []; + this.UpdateTypes = function (allTypes, updatedTypes) { + let elrefTypes = []; - for (let i in updatedTypes) { - for (let j in updatedTypes[i].type) { - elrefTypes.push(updatedTypes[i].type[j]); - } - } - let uniqueUpdatedTypes = elrefTypes.filter(function(value, index, self) { - return self.indexOf(value) === index; - }); + for (let i in updatedTypes) { + for (let j in updatedTypes[i].type) { + elrefTypes.push(updatedTypes[i].type[j]); + } + } + let uniqueUpdatedTypes = elrefTypes.filter(function (value, index, self) { + return self.indexOf(value) === index; + }); - for (let i in allTypes) { - var elem = document.getElementById('type'+i); - elem.disabled = true; - var elemLabel = document.getElementById('labelType'+i); - elemLabel.classList.add("disabled"); + for (let i in allTypes) { + var elem = document.getElementById('type' + i); + elem.disabled = true; + var elemLabel = document.getElementById('labelType' + i); + elemLabel.classList.add("disabled"); - } - for (let i in allTypes) { - for (let j in uniqueUpdatedTypes) { - if (allTypes[i]==uniqueUpdatedTypes[j]) { - var elem = document.getElementById('type'+i); - elem.disabled = false; - var elemLabel = document.getElementById('labelType'+i); - elemLabel.classList.remove("disabled"); - } - } - } + } + for (let i in allTypes) { + for (let j in uniqueUpdatedTypes) { + if (allTypes[i] == uniqueUpdatedTypes[j]) { + var elem = document.getElementById('type' + i); + elem.disabled = false; + var elemLabel = document.getElementById('labelType' + i); + elemLabel.classList.remove("disabled"); + } + } + } - }; + }; - this.UpdateFeedback = function(activeFilter, nbTests) { - let elBtnReinit = document.getElementById('reinit'); - let elFeedback = document.getElementById('feedback'); - let htmlFeedback = ''; - let test = nbTests > 1 ? 'tests' : 'test' + this.UpdateFeedback = function (activeFilter, nbTests) { + let elBtnReinit = document.getElementById('reinit'); + let elFeedback = document.getElementById('feedback'); + let htmlFeedback = ''; + let test = nbTests > 1 ? 'tests' : 'test' - if (activeFilter) { - elBtnReinit.disabled = false; - htmlFeedback = '

'+nbTests+' ' + test + ' ' + translate('withCurrentFilters') + '
'; + elFilterFooter.innerHTML = htmlFilterFooter; + let elBtnReinit = document.getElementById('reinit'); - // Retourne la liste des checkboxes - this.DisplayFilters = function() { - let elFilterFooter = document.getElementById('filter-footer'); - let htmlFilterFooter = ''; - htmlFilterFooter += ''; - elFilterFooter.innerHTML = htmlFilterFooter; - let elBtnReinit = document.getElementById('reinit'); + elBtnReinit.addEventListener('click', function () { + app.FetchAll(refTests); + app.FilterByType(); + app.UpdateFeedback(false, refTests.length); + }); - elBtnReinit.addEventListener('click', function() { - app.FetchAll(refTests); - app.FilterByType(); - app.UpdateFeedback(false, refTests.length); - }); + // Selection de l'élément + let elTypes = document.getElementById('types'); + let types = []; - // Selection de l'élément - let elTypes = document.getElementById('types'); - let types = []; + // Selection de l'élément + let elProfils = document.getElementById('profils'); + let profils = []; - // Selection de l'élément - let elProfils = document.getElementById('profils'); - let profils = []; + // Chaque ligne (test) + for (let i in refTests) { - // Chaque ligne (test) - for (let i in refTests) { + // Chaque "type" dans chaque ligne (test) + for (let j in refTests[i].type) { - // Chaque "type" dans chaque ligne (test) - for (let j in refTests[i].type) { + (Array.isArray(refTests[i].type[j]) ? types.push(refTests[i].type[j][0]) : types.push(refTests[i].type[j])) - ( Array.isArray(refTests[i].type[j]) ? types.push(refTests[i].type[j][0]) : types.push(refTests[i].type[j])) - - } + } - // Chaque "profil" dans chaque ligne (test) - for (let j in refTests[i].profils) { - profils.push(refTests[i].profils[j]); - } + // Chaque "profil" dans chaque ligne (test) + for (let j in refTests[i].profils) { + profils.push(refTests[i].profils[j]); + } - } + } - //let uniqueTypes = types.filter( (value, index, self) => self.indexOf(value) === index ); - uniqueTypes = types.filter(function(value, index, self) { - if(value!=""){ - return self.indexOf(value) === index; - } - }); + //let uniqueTypes = types.filter( (value, index, self) => self.indexOf(value) === index ); + uniqueTypes = types.filter(function (value, index, self) { + if (value != "") { + return self.indexOf(value) === index; + } + }); - //on tri par ordre alphabétique - uniqueTypes.sort(function (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()); - }); + //on tri par ordre alphabétique + uniqueTypes.sort(function (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); + }); - let htmlTypes = ''; + let htmlTypes = ''; - htmlTypes += '
  • '; + htmlTypes += '
  • '; - for (let i in uniqueTypes) { - htmlTypes += '
  • '; - } + for (let i in uniqueTypes) { + htmlTypes += '
  • '; + } - //let uniqueProfils = profils.filter( (value, index, self) => self.indexOf(value) === index ); - let uniqueProfils = profils.filter(function(value, index, self) { - return self.indexOf(value) === index; - }); + //let uniqueProfils = profils.filter( (value, index, self) => self.indexOf(value) === index ); + let uniqueProfils = profils.filter(function (value, index, self) { + return self.indexOf(value) === index; + }); - let htmlProfils = ''; + let htmlProfils = ''; - htmlProfils += '
  • '; - for (let i in uniqueProfils) { - htmlProfils += '
  • '; - } + htmlProfils += '
  • '; + for (let i in uniqueProfils) { + htmlProfils += '
  • '; + } - elTypes.innerHTML = htmlTypes; - elProfils.innerHTML = htmlProfils; + elTypes.innerHTML = htmlTypes; + elProfils.innerHTML = htmlProfils; - }; + }; - // Retourne les tests filtrés - this.FilterByType = function() { + // Retourne les tests filtrés + this.FilterByType = function () { - // Affiche les checkboxes et boutons radios - this.DisplayFilters(); + // Affiche les checkboxes et boutons radios + this.DisplayFilters(); - let checkboxes = document.querySelectorAll('input'); - let arrType = []; - let arrProfil = []; - let conditions = []; - let self = this; - let runUpdateType = false; + let checkboxes = document.querySelectorAll('input'); + let arrType = []; + let arrProfil = []; + let conditions = []; + let self = this; + let runUpdateType = false; - for (var i = 0; i < checkboxes.length; i++) { + for (var i = 0; i < checkboxes.length; i++) { - let input = checkboxes[i]; + let input = checkboxes[i]; - input.addEventListener('click', function() { + input.addEventListener('click', function () { - if (this.checked && this.id==="profilAll" ){ - arrProfil = []; + if (this.checked && this.id === "profilAll") { + arrProfil = []; - }else if ((this.checked && this.name==="profil")){ - arrProfil = []; - arrProfil.push(input.value); - } + } else if ((this.checked && this.name === "profil")) { + arrProfil = []; + arrProfil.push(input.value); + } - if (this.checked && this.id==="typeAll" ){ - arrType = []; + if (this.checked && this.id === "typeAll") { + arrType = []; - } else if (this.checked && this.name==="types"){ - arrType = []; - arrType.push(input.value); - } + } else if (this.checked && this.name === "types") { + arrType = []; + arrType.push(input.value); + } - let indice = arrType.length + arrProfil.length; + let indice = arrType.length + arrProfil.length; + if (indice > 0) { - if (indice > 0) { + if (indice == 1) { - if (indice == 1) { + //on réinitialise les conditions + //conditions = []; - //on réinitialise les conditions - //conditions = []; + //on ajoute le premier critère + if ((arrProfil.length === 1)) { - //on ajoute le premier critère - if ((arrProfil.length===1)){ + //on supprime les doublons, nécessaire pour les boutons radio + delDoublon(conditions, this.name); - //on supprime les doublons, nécessaire pour les boutons radio - delDoublon(conditions, this.name); + conditions.unshift(function (item) { + //return item.profils === arrProfil[0]; + return item.profils.indexOf(arrProfil[0]) !== -1; + }); + //on nomme la fonction, pour les boutons radio on utilise this.name + Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); - conditions.unshift(function(item) { - //return item.profils === arrProfil[0]; - return item.profils.indexOf(arrProfil[0]) !== -1; - }); - //on nomme la fonction, pour les boutons radio on utilise this.name - Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); + runUpdateType = true; - runUpdateType = true; + } + if ((arrType.length === 1)) { - } - if ((arrType.length===1)){ + //on supprime les doublons, nécessaire pour les boutons radio + delDoublon(conditions, this.name); - //on supprime les doublons, nécessaire pour les boutons radio - delDoublon(conditions, this.name); - - conditions.unshift(function(item) { - return item.type.toString().indexOf(arrType[0]) !== -1; - }); + conditions.unshift(function (item) { + return item.type.toString().indexOf(arrType[0]) !== -1; + }); - //on nomme la fonction, pour les checkboxes on utilise this.id - Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); + //on nomme la fonction, pour les checkboxes on utilise this.id + Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); - runUpdateType = false; - } + runUpdateType = false; + } - } else { + } else { - //on ajoute le nouveau critère - if ((this.checked && this.name==="profil" && this.id!="profilAll")){ + //on ajoute le nouveau critère + if ((this.checked && this.name === "profil" && this.id != "profilAll")) { - //on supprime les doublons, nécessaire pour les boutons radio - delDoublon(conditions, this.name); + //on supprime les doublons, nécessaire pour les boutons radio + delDoublon(conditions, this.name); - conditions.unshift(function(item) { - return item.profils.indexOf(arrProfil[0]) !== -1; - }); + conditions.unshift(function (item) { + return item.profils.indexOf(arrProfil[0]) !== -1; + }); - //on nomme la fonction, pour les boutons radio on utilise this.name - Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); + //on nomme la fonction, pour les boutons radio on utilise this.name + Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); - runUpdateType = true; + runUpdateType = true; - } - if ((this.checked && this.name==="types" && this.id!="allType")){ + } + if ((this.checked && this.name === "types" && this.id != "allType")) { - //on supprime les doublons, nécessaire pour les boutons radio - delDoublon(conditions, this.name); + //on supprime les doublons, nécessaire pour les boutons radio + delDoublon(conditions, this.name); - conditions.unshift(function(item) { - return item.type.indexOf(arrType[0]) !== -1; - }); + conditions.unshift(function (item) { + return item.type.indexOf(arrType[0]) !== -1; + }); - Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); + Object.defineProperty(conditions[0], 'name', {value: this.name, writable: false}); - runUpdateType = false; + runUpdateType = false; - } - } + } + } - //on applique tous les filtres stockés dans conditions - //filteredTest = self.refTests.filter(function(d) { - filteredTest = refTests.filter(function(d) { - return conditions.every(function(c) { - return c(d); - }); - }); + //on applique tous les filtres stockés dans conditions + //filteredTest = self.refTests.filter(function(d) { + filteredTest = refTests.filter(function (d) { + return conditions.every(function (c) { + return c(d); + }); + }); - //on met à jour la page - app.FetchAll(filteredTest); + //on met à jour la page + app.FetchAll(filteredTest); - if (runUpdateType) { - app.UpdateTypes(uniqueTypes, filteredTest); - } - app.UpdateFeedback(true,filteredTest.length); + if (runUpdateType) { + app.UpdateTypes(uniqueTypes, filteredTest); + } + app.UpdateFeedback(true, filteredTest.length); - } else { - //aucun critère de sélectionné, on réinitialise la page - app.FetchAll(refTests); - // Filtrage - app.FilterByType(); - app.UpdateFeedback(true,refTests.length); + } else { + //aucun critère de sélectionné, on réinitialise la page + app.FetchAll(refTests); + // Filtrage + app.FilterByType(); + app.UpdateFeedback(true, refTests.length); - } + } - }); + }); - } + } - }; + }; - } - // Affichage de tous les tests - app.FetchAll(refTests); - // Filtrage - app.FilterByType(); - app.UpdateFeedback(false, refTests.length); + } + // Affichage de tous les tests + app.FetchAll(refTests); + // Filtrage + app.FilterByType(); + app.UpdateFeedback(false, refTests.length); - } + } }); From 32a92f9db3cc356cd19f21ab6143e69d928ba26f Mon Sep 17 00:00:00 2001 From: Guillaume PERE Date: Thu, 30 May 2024 10:50:31 +0200 Subject: [PATCH 02/20] Web > Tests > Hide the two "reinitialize" buttons if needed --- src/assets/style.css | 4 ++++ src/assets/test-web.js | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/assets/style.css b/src/assets/style.css index 4e3850695..49b4fea98 100644 --- a/src/assets/style.css +++ b/src/assets/style.css @@ -530,4 +530,8 @@ pre code { line-height: 1.125; color: #fff; letter-spacing: -.00625rem; +} + +.hidden { + display: none; } \ No newline at end of file diff --git a/src/assets/test-web.js b/src/assets/test-web.js index 1d210c724..d4db93c3a 100644 --- a/src/assets/test-web.js +++ b/src/assets/test-web.js @@ -221,7 +221,7 @@ document.addEventListener("DOMContentLoaded", function (event) { let test = nbTests > 1 ? 'tests' : 'test' if (activeFilter) { - elBtnReinit.disabled = false; + elBtnReinit.classList.remove('hidden'); htmlFeedback = '

    ' + nbTests + ' ' + test + ' ' + translate('withCurrentFilters') + '
    '; + htmlFilterFooter += ''; elFilterFooter.innerHTML = htmlFilterFooter; let elBtnReinit = document.getElementById('reinit'); From f1b0d4de5cd1690d166c8a8a0025ff100e559997 Mon Sep 17 00:00:00 2001 From: Guillaume PERE Date: Thu, 30 May 2024 15:18:03 +0200 Subject: [PATCH 03/20] Web > Tests > Add an avoidance link to filters --- .../components/header/skip-links.njk | 2 +- src/assets/test-web.js | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/_includes/components/header/skip-links.njk b/src/_includes/components/header/skip-links.njk index f944fdd71..b14c3cf9e 100644 --- a/src/_includes/components/header/skip-links.njk +++ b/src/_includes/components/header/skip-links.njk @@ -1,4 +1,4 @@ -
    -![Sur iOS 15 : activer Voice Over à partir du menu Réglages-Accessibilité-Voice Over](../../images/ios-test-VO_iOS15.png) +![Sur iOS 15 : activer Voice Over à partir du menu Réglages-Accessibilité-Voice Over](../../images/ios-test-VO_iOS15.png)
    -![Sur iOS 13 : activer Voice Over à partir du menu Réglages-Accessibilité-Voice Over](../../images/ios-test-VO_iOS13.png) +![Sur iOS 13 : activer Voice Over à partir du menu Réglages-Accessibilité-Voice Over](../../images/ios-test-VO_iOS13.png)
    -![Sur iOS 12 : activer Voice Over à partir du menu Général-Accessibilité-Voice Over](../../images/ios-test-VO_iOS12.png) +![Sur iOS 12 : activer Voice Over à partir du menu Général-Accessibilité-Voice Over](../../images/ios-test-VO_iOS12.png)
    @@ -198,36 +198,36 @@ Remarque : l'activation de cette fonctionnalité se fait elle aussi via les data-bs-toggle="tab" href="#SwitchControl-iOS15" role="tab" - aria-selected="true">iOS 15 + aria-selected="true" lang="en">iOS 15
    -![Sur iOS 15 : activer Contrôle de sélection à partir du menu Réglages-Accessibilité-Contrôle de sélection](../../images/ios-test-SwitchControl_iOS15.png) +![Sur iOS 15 : activer Contrôle de sélection à partir du menu Réglages-Accessibilité-Contrôle de sélection](../../images/ios-test-SwitchControl_iOS15.png)
    -![Sur iOS 13 : activer Contrôle de sélection à partir du menu Réglages-Accessibilité-Contrôle de sélection](../../images/ios-test-SwitchControl_iOS13.png) +![Sur iOS 13 : activer Contrôle de sélection à partir du menu Réglages-Accessibilité-Contrôle de sélection](../../images/ios-test-SwitchControl_iOS13.png)
    -![Sur iOS 12 : activer Contrôle de sélection à partir du menu Général-Accessibilité-Contrôle de sélection](../../images/ios-test-SwitchControl_iOS12.png) +![Sur iOS 12 : activer Contrôle de sélection à partir du menu Général-Accessibilité-Contrôle de sélection](../../images/ios-test-SwitchControl_iOS12.png)

    @@ -245,9 +245,9 @@ L'outil Accessibility Inspector dispose d'une fonctionnal

    ### Inspection de code -L'interface de développement Xcode fournit un outil particulièrement intéressant intitulé **Accessibility Inspector**. +L'interface de développement Xcode fournit un outil particulièrement intéressant intitulé **Accessibility Inspector**. -L'intérêt et l'utilisation de cet outil ne seront pas développés ici car ils sont très bien expliqués dans les vidéos parfaitement détaillées [`Audit` `d'une` `app` `en` `accessibilité`](../wwdc/2016/407/) et [`Découvrir` `Accessibility` `Inspector`](../wwdc/2019/#decouvrir-accessibility-inspector) dont le visionnage est très fortement recommandé. +L'intérêt et l'utilisation de cet outil ne seront pas développés ici car ils sont très bien expliqués dans les vidéos parfaitement détaillées [`Audit` `d'une` `app` `en` `accessibilité`](../wwdc/2016/407/) et [`Découvrir` `Accessibility` `Inspector`](../wwdc/2019/#decouvrir-accessibility-inspector) dont le visionnage est très fortement recommandé.

    ### Tests liés au code diff --git a/src/fr/web/developper/contenu-textuel.md b/src/fr/web/developper/contenu-textuel.md index 06d2582bf..9a93230db 100644 --- a/src/fr/web/developper/contenu-textuel.md +++ b/src/fr/web/developper/contenu-textuel.md @@ -83,7 +83,7 @@ Un titrage de page avec un saut de niveau h2 → h4 : **Outils :** Des extensions à installer dans votre navigateur permettent d'extraire la liste des titres : -- L’extension HeadingsMaps disponible sur Firefox et chrome. +- L’extension HeadingsMaps disponible sur Firefox et chrome. - L'extension Web developer. **Référence WCAG :** From 90145227e7b1631ba06a8e7b4f7a3569cffed847 Mon Sep 17 00:00:00 2001 From: Guillaume PERE Date: Tue, 6 Aug 2024 10:53:23 +0200 Subject: [PATCH 17/20] =?UTF-8?q?Fixes=20#535=20:=20Des=20changements=20de?= =?UTF-8?q?=20langue=20=C3=A0=20indiquer=20dans=20du=20texte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fr/mobile/ios/voiceover/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fr/mobile/ios/voiceover/index.md b/src/fr/mobile/ios/voiceover/index.md index 75a7ccc39..e9da5d65d 100644 --- a/src/fr/mobile/ios/voiceover/index.md +++ b/src/fr/mobile/ios/voiceover/index.md @@ -17,21 +17,21 @@ L'activation de VoiceOver se fait via le menu `Réglages` data-bs-toggle="tab" href="#VoiceOverActivation-iOS15" role="tab" - aria-selected="true">iOS 15 + aria-selected="true" lang="en">iOS 15