« MediaWiki:Gadget-Accessibility.js » : différence entre les versions

Contenu supprimé Contenu ajouté
m séparation du code de lancement
m modernisation : traductibilité, mediawiki.storage, rapprochement styles par défaut des portlets, style Wikimedia
Ligne 1 :
/**
* Outils de vérification de l'accessibilité des pages.
* Ajoute une palette de liens, classiquement à gauche.
* Auteurs : Lgd, Ltrlg
* auteur : http://fr.wikipedia.org/wiki/Utilisateur:Lgd
* {{Projet:JavaScript/Script|Accessibility}}
*/
/* eslint-env browser */
/* eslint-disable no-multi-str */
/* global $, mw, OO */
 
var
function runAccessibilityGadget() {
supportedSkins = [ 'vector', 'monobook', 'timeless' ],
var link = $( '<link>' );
portletId = 'p-accessibility',
link.attr( {
storageId = 'gadget-accessibility',
type: 'text/css',
messages;
rel: 'stylesheet',
media: 'screen',
href: '//fr.wikipedia.org/w/index.php?title=MediaWiki:Gadget-Accessibility.css&action=raw&ctype=text/css'
} );
$( 'head' ).append( link );
 
/* ----- Translations ----- */
if ( mw.config.get( 'skin' ) == 'vector' || mw.config.get( 'skin' ) == 'timeless' ) {
$( '#p-navigation' ).after( '<div id="p-accessibility" class="portal"><h3><span>Accessibilité</span></h3><a title="Fixer le Gadget" id="acc_fixed" href="#"><img src="//upload.wikimedia.org/wikipedia/commons/d/d5/Show-handle-10.png" height="16" width="16" alt="Fixer le gadget" /></a><div class="body"><ul><li><a href="#" id="acc_table" title="Vérifier l\'accessibilité des tableaux">Tableaux</a></li><li><a href="#" id="acc_header" title="Vérifier l\'accessibilité des titres de section">Titres</a></li><li><a href="#" id="acc_list" title="Vérifier l\'accessibilité des listes de définition">Listes</a></li><li><a href="#" id="acc_quote" title="Vérifier l\'accessibilité des citations">Citations</a></li><li><a href="#" id="acc_lang" title="Vérifier la présence des changements de langue">Langues</a></li><li><a href="#" id="acc_alt" title="Vérifier la présence des alternatives textuelles">Alternatives</a></li><li><a href="#" id="acc_all">Tout désactiver</a></li><li><a href="//fr.wikipedia.org/wiki/Wikip%C3%A9dia:Atelier_accessibilit%C3%A9/Bonnes_pratiques" id="acc_bp" target="_blank" title="Bonnes pratiques d\'accessibilité (nouvelle fenêtre)">Bonnes pratiques</a></li><li><a href="//fr.wikipedia.org/wiki/Wikip%C3%A9dia:Atelier_accessibilit%C3%A9/Aide_gadget" id="acc_help" target="_blank" title="Aide pour l\'utilisation du gadget (nouvelle fenêtre)">Aide gadget</a></li></ul><p id="acc_disclaimer">Soyez prudent dans vos modifications et n\'hésitez pas à <a href="//fr.wikipedia.org/wiki/Discussion_Wikip%C3%A9dia:Atelier_accessibilit%C3%A9">demander conseil</a>.</p></div></div>' );
 
messages = {
var state = $.cookie( 'vector-nav-p-accessibility' );
fr: {
if ( state == 'true' || state == null ) {
'accessibility-all-disable': 'Tout désactiver',
$( '#p-accessibility' ).addClass( 'expanded' ).find( 'div.body' ).show();
'accessibility-alt-empty': 'ALT VIDE',
} else {
'accessibility-alt-flag': 'L’alternative devrait commencer par « Drapeau… » ou « Pavillon… »',
$( '#p-accessibility' ).addClass( 'collapsed' );
'accessibility-alt-gallery': 'Indiquez l’alternative de chaque image de la galerie.',
}
'accessibility-alt-label': 'Alternatives',
if ( state != null ) {
'accessibility-alt-link': 'Vérifiez si le lien sur l’image peut être désactivé (LINK vide) (ou si l’image peut être transformée en thumb)',
$.cookie( 'vector-nav-p-accessibility', state, { expires: 30, path: '/' } );
'accessibility-alt-long': 'Vérifiez si cette alternative de $1 caractères pourrait être plus concise (environ 120 caractères au plus) et si l’alternative actuelle pourrait être transférée dans la section description de la page de l’image.',
}
'accessibility-alt-missing': 'ALT MANQUANT',
'accessibility-alt-title': 'Vérifier la présence des alternatives textuelles',
'accessibility-alt-usemap': 'Indiquez l’alternative de l’image.',
'accessibility-disclaimer': 'Soyez prudent dans vos modifications et n’hésitez pas à <a href="//fr.wikipedia.org/wiki/Discussion_Wikip%C3%A9dia:Atelier_accessibilit%C3%A9">demander conseil</a>.',
'accessibility-good-practice-label': 'Bonnes pratiques',
'accessibility-good-practice-page': 'Wikipédia:Atelier accessibilité/Bonnes pratiques',
'accessibility-good-practice-title': 'Bonnes pratiques d’accessibilité (nouvelle fenêtre)',
'accessibility-headers-dl': 'Possible élément de liste de définition utilisé à la place d’un titre de section',
'accessibility-headers-h1': 'H1',
'accessibility-headers-h2': 'H2',
'accessibility-headers-h3': 'H3',
'accessibility-headers-h4': 'H4',
'accessibility-headers-h5': 'H5',
'accessibility-headers-h6': 'H6',
'accessibility-headers-label': 'Titres',
'accessibility-headers-title': 'Vérifier l’accessibilité des titres de section',
'accessibility-help-label': 'Aide gadget',
'accessibility-help-page': 'Wikipédia:Atelier accessibilité/Aide gadget',
'accessibility-help-title': 'Aide pour l’utilisation du gadget (nouvelle fenêtre)',
'accessibility-lang-dk': 'Code de langue erroné : utilisez da (danois)',
'accessibility-lang-empty': 'Code de langue erroné:: lang ne doit pas être vide',
'accessibility-lang-foreign-latn': 'Vérifiez que ce qui suit est bien une transcription en caractères latins (et non une traduction) :',
'accessibility-lang-foreign-missing': 'Code de langue manquant pour une citation en langue étrangère',
'accessibility-lang-gr': 'Code de langue erroné : utilisez el (grec moderne) ou grc (grec ancien avant 1453)',
'accessibility-lang-jp': 'Code de langue erroné : utilisez ja (japonais)',
'accessibility-lang-label': 'Langues',
'accessibility-lang-lang': 'Lang : $1',
'accessibility-lang-lat': 'Code de langue erroné : utilisez la (latin)',
'accessibility-lang-lu': 'Code de langue erroné : utilisez lb (luxembourgeois)',
'accessibility-lang-mul': 'Code de langue erroné : ne pas utiliser le code mul (multiple)',
'accessibility-lang-oci': 'Code de langue erroné : utilisez oc (occitan)',
'accessibility-lang-title': 'Vérifier la présence des changements de langue',
'accessibility-lang-und': 'Code de langue erroné : ne pas utiliser le code und (undefined)',
'accessibility-lists-dd': 'Définition : ',
'accessibility-lists-dl': 'Vérifiez le bon usage et la structure de cette liste de définition.',
'accessibility-lists-dt': 'Terme défini : ',
'accessibility-lists-header': 'Possible élément de liste de définition utilisé à la place d’un titre de section',
'accessibility-lists-indent': 'Possible élément de liste de définition utilisé uniquement pour indenter le texte',
'accessibility-lists-label': 'Listes',
'accessibility-lists-orphean': 'Elément de liste potentiellement orphelin : vérifier l’absence de sauts de ligne entre les *',
'accessibility-lists-title': 'Vérifier l’accessibilité des listes de définition',
'accessibility-portlet-fix-title': 'Fixer le gadget',
'accessibility-portlet-title': 'Accessibilité',
'accessibility-portlet-unfix-title': 'Détacher',
'accessibility-quotes-ok': 'Citation bien balisée : ',
'accessibility-quotes-label': 'Citations',
'accessibility-quotes-title': 'Vérifier l’accessibilité des citations',
'accessibility-tables-caption-error': 'Ce tableau ne devrait pas avoir de titre caption (code wiki |+)</caption>',
'accessibility-tables-caption-missing': 'Ce tableau devrait avoir un titre caption (code wiki |+)</caption>',
'accessibility-tables-label': 'Tableaux',
'accessibility-tables-summary': '@summary=$1',
'accessibility-tables-td-headers': 'HEADERS: $1',
'accessibility-tables-td-imbrication': 'Limitez autant que possible l’imbrication de tableaux.',
'accessibility-tables-td-scope': 'ERREUR TD SCOPE $1',
'accessibility-tables-th-id': 'ID: $1',
'accessibility-tables-th-missing-scope': 'Vérifiez s’il faut ajouter un SCOPE ou transformer en TD (code wiki: |)',
'accessibility-tables-th-scope': 'SCOPE $1',
'accessibility-tables-th-scope-headers': 'SCOPE: $1 HEADERS: $2',
'accessibility-tables-th-scope-headers-id': 'SCOPE: $1 HEADERS: $2 ID: $3',
'accessibility-tables-th-scope-id': 'SCOPE $1 ID: $2',
'accessibility-tables-title': 'Vérifier l’accessibilité des tableaux'
}
};
 
function selectApplicableMessages() {
} else if ( mw.config.get( 'skin' ) == 'monobook' ) {
var
$( '#p-search' ).after( '<div id="p-accessibility" class="portlet"><h3>Accessibilité</h3><a title="Fixer le Gadget" id="acc_fixed" href="#"><img src="//upload.wikimedia.org/wikipedia/commons/d/d5/Show-handle-10.png" height="16" width="16" alt="Fixer le gadget" /></a><div class="pBody"><ul><li><a href="#" id="acc_table" title="Vérifier l\'accessibilité des tableaux">Tableaux</a></li><li><a href="#" id="acc_header" title="Vérifier l\'accessibilité des titres de section">Titres</a></li><li><a href="#" id="acc_list" title="Vérifier l\'accessibilité des listes de définition">Listes</a></li><li><a href="#" id="acc_quote" title="Vérifier l\'accessibilité des citations">Citations</a></li><li><a href="#" id="acc_lang" title="Vérifier la présence des changements de langue">Langues</a></li><li><a href="#" id="acc_alt" title="Vérifier la présence des alternatives textuelles">Alternatives</a></li><li><a href="#" id="acc_all">Tout désactiver</a></li><li><a href="//fr.wikipedia.org/wiki/Wikip%C3%A9dia:Atelier_accessibilit%C3%A9/Bonnes_pratiques" id="acc_bp" target="_blank" title="Bonnes pratiques d\'accessibilité (nouvelle fenêtre)">Bonnes pratiques</a></li><li><a href="//fr.wikipedia.org/wiki/Wikip%C3%A9dia:Atelier_accessibilit%C3%A9/Aide_gadget" id="acc_help" target="_blank" title="Aide pour l\'utilisation du gadget (nouvelle fenêtre)">Aide gadget</a></li></ul><p id="acc_disclaimer">Soyez prudent dans vos modifications et n\'hésitez pas à <a href="//fr.wikipedia.org/wiki/Discussion_Wikip%C3%A9dia:Atelier_accessibilit%C3%A9">demander conseil</a>.</p></div></div>' );
defaultLang = 'fr',
currentLang = mw.config.get( 'wgUserLanguage' );
 
mw.messages.set( messages[ defaultLang ] );
 
if ( currentLang && currentLang !== defaultLang && currentLang in messages ) {
mw.messages.set( messages[ currentLang ] );
}
}
 
/* fixed----- Storage ----- */
 
var state = $.cookie( 'wp_acc_fixed' );
function loadOptions() {
if ( state == 'true' ) {
var res;
$( '#p-accessibility' ).addClass( 'acc_fixed' );
 
$( '#p-accessibility #acc_fixed img' ).attr( { alt: 'Détacher', src: '//upload.wikimedia.org/wikipedia/commons/3/3b/Hide-handle-10.png' } );
try {
$( '#p-accessibility #acc_fixed' ).attr( { title: 'Détacher' } );
res = JSON.parse( mw.storage.get( storageId ) );
} catch ( e ) { /* Will fallback */ }
 
return $.isPlainObject( res ) ? res : {};
}
 
function storeOptions( options ) {
mw.storage.set( storageId, JSON.stringify( options ) );
}
 
function storeBooleanState( name, val ) {
var options = loadOptions();
options[ name ] = val;
storeOptions( options );
}
 
function loadBooleanState( name ) {
var options = loadOptions();
return Object.prototype.hasOwnProperty.call( options, name ) ?
options[ name ] :
null;
}
 
/* ----- Fixed or not ----- */
 
/** Add a state control to a portlet.
*
* @param {object} description Options bag with the following properties:
* - `$portlet`: jQuery handler for the portlet;
* - `$controls`: jQuery handler for the controls bar;
* - `id`: storage id, partial state class id;
* - `enableIcon': OOUI icon for enabling;
* - `enableTitle`: hover text for enabling;
* - `disableIcon': OOUI icon for disabling;
* - `disableTitle`: hover text for disabling;
*/
function addStateControlToPortlet( description ) {
var
disabledData = {
title: description.enableTitle,
icon: description.enableIcon
},
enabledData = {
title: description.disableTitle,
icon: description.disableIcon
},
 
enabled = loadBooleanState( description.id ),
currentData = enabled ? enabledData : disabledData,
 
button = new OO.ui.ButtonWidget( {
framed: false,
icon: currentData.icon,
iconTitle: currentData.title
} ),
 
className = 'acc_' + description.id;
 
if ( enabled ) {
$( '#' + portletId ).addClass( className );
}
 
if ( state != null ) {
// Renew cookie storage
$.cookie( 'wp_acc_fixed', state, { expires: 30, path: '/' } );
if ( enabled !== null ) {
storeBooleanState( description.id, enabled );
}
 
$button.on( '#acc_fixedclick' ).click(, function () {
var currentData;
$( '#p-accessibility' ).toggleClass( 'acc_fixed' );
description.$portlet.toggleClass( className );
var state = $( '#p-accessibility' ).is( '.acc_fixed' );
enabled = !enabled;
$.cookie( 'wp_acc_fixed', state, { expires: 30, path: '/' } );
currentData = enabled ? enabledData : disabledData;
if ( !state ) {
storeBooleanState( description.id, enabled );
$( '#p-accessibility #acc_fixed img' ).attr( { alt: 'Fixer le gadget', src: '//upload.wikimedia.org/wikipedia/commons/d/d5/Show-handle-10.png' } );
 
$( '#p-accessibility #acc_fixed' ).attr( { title: 'Fixer le gadget' } );
button.setIconTitle( currentData.title );
} else {
button.setIcon( currentData.icon );
$( '#p-accessibility #acc_fixed img' ).attr( { alt: 'Détacher', src: '//upload.wikimedia.org/wikipedia/commons/3/3b/Hide-handle-10.png' } );
$( '#p-accessibility #acc_fixed' ).attr( { title: 'Détacher' } );
}
return false;
} );
 
description.$controls.append( button.$element );
/* Tout désactiver */
}
$( '#acc_all' ).click( function () {
 
$( '#content' ).removeClass( 'acc_table acc_header acc_list acc_quote acc_lang' );
function addControlsToPortlet( $portlet ) {
$( '#content span.acc_attr_show, #content caption.acc_caption_error' ).remove();
var $controls = $( '<span>' ).attr( 'id', 'acc_controls' );
$( '#p-accessibility li a' ).removeClass( 'acc_on' );
 
$.cookie( 'wp_acc_table', false, { expires: 30, path: '/' } );
addStateControlToPortlet( {
$.cookie( 'wp_acc_header', false, { expires: 30, path: '/' } );
$portlet: $portlet,
$.cookie( 'wp_acc_list', false, { expires: 30, path: '/' } );
$controls: $controls,
$.cookie( 'wp_acc_quote', false, { expires: 30, path: '/' } );
id: 'collapsed',
$.cookie( 'wp_acc_lang', false, { expires: 30, path: '/' } );
enableTitle: mw.msg( 'accessibility-portlet-collapse-title' ),
$.cookie( 'wp_acc_alt', false, { expires: 30, path: '/' } );
enableIcon: 'collapse',
return false;
disableTitle: mw.msg( 'accessibility-portlet-expand-title' ),
disableIcon: 'expand'
} );
 
addStateControlToPortlet( {
/* Tableaux */
$portlet: $portlet,
var state = $.cookie( 'wp_acc_table' );
$controls: $controls,
if ( state == 'true' ) {
id: 'fixed',
acc_table();
enableTitle: mw.msg( 'accessibility-portlet-fix-title' ),
enableIcon: 'window',
disableTitle: mw.msg( 'accessibility-portlet-unfix-title' ),
disableIcon: 'close'
} );
 
$portlet.find( 'h3' ).before( $controls );
}
 
/* ----- Portlet creation ----- */
 
function addDisclaimerToPortlet( $portlet ) {
var $disc = $( '<p>' )
.attr( 'id', 'acc_disclaimer' )
.html( mw.msg( 'accessibility-disclaimer' ) );
$portlet.find( 'ul' ).after( $disc );
}
 
function createPortlet( id, title ) {
var $portlet;
switch ( mw.config.get( 'skin' ) ) {
case 'vector':
case 'timeless':
$portlet = $( '<div>' )
.attr( { id: id, 'class': 'portal' } )
.append( $( '<h3>' ).append( '<span>' ).text( title ) )
.append( $( '<div>' ).attr( 'class', 'body' )
.append( $( '<ul>' ) )
);
$( '#p-navigation' ).after( $portlet );
break;
 
case 'monobook':
$portlet = $( '<div>' )
.attr( { id: id, 'class': 'portlet' } )
.append( $( '<h3>' ).text( title ) )
.append( $( '<div>' ).attr( 'class', 'pBody' )
.append( $( '<ul>' ) )
);
$( '#p-search' ).after( $portlet );
break;
 
default:
throw Error( 'Unsupported skin' );
}
return $portlet;
if ( state != null ) {
}
$.cookie( 'wp_acc_table', state, { expires: 30, path: '/' } );
 
}
/* ----- CSS manipulation ----- */
$( '#acc_table' ).click( function () {
/* We want to keep the code in CSS for now, but make strings translatable…
acc_table();
* Let’s build a tiny CSS superset for that…
return false;
* We will replace `«msg-name, args…»` (because french quotes are so easy for
* french people) with `"msg with " arg "."`
*/
 
function replacesMessagesinCss( extendedCss ) {
return extendedCss.replace( /«([^»]+)»/g, function ( _, cont ) {
var
parts = cont.split( /,\s*/ ),
msgName = parts[ 0 ],
msg = mw.msg( msgName ),
wrappedMessage = '"' + msg + '"', // Obviously, we may need escaping at some point…
finalString = wrappedMessage.replace( /\$(\d)/g, function ( _, sIndex ) {
// Exit the string, then add our value.
return '"' + parts[ Number( sIndex ) ] + '"';
} );
return finalString;
} );
}
function acc_table() {
 
$( '#content' ).toggleClass( 'acc_table' );
/* ----- Individual options ----- */
$( '#acc_table' ).toggleClass( 'acc_on' );
 
$.cookie( 'wp_acc_table', $( '#acc_table' ).is( '.acc_on' ), { expires: 30, path: '/' } );
/** Create a option link in the portlet.
if ( $( '#acc_table' ).attr( 'class' ) == 'acc_on' ) {
*
$( '#content table:has(th[scope])' ).not( '#content table:has(caption)' ).prepend( '<caption class="error acc_caption_error">Ce tableau devrait avoir un titre caption (code wiki |+)</caption>' );
* @param {object} description is an option bag with the following properties:
$( '#content table:has(caption)' ).not( '#content table:has(th[scope])' ).prepend( '<caption class="error acc_caption_error">Ce tableau ne devrait pas avoir de titre caption (code wiki |+)</caption>' );
* - [req] `id`: the storage identifier & link identifier;
} else {
* - [req] `title`: title for the portlet link;
$( '#content caption.acc_caption_error' ).remove();
* - [req] `label`: label for the portlet link;
* - [opt] `activate`: function executed for activating the option;
* - [opt] `deactivate`: function executed for deactivating the option.
* - [opt] `styles`: extended CSS used by this option (see replacesMessagesinCss).
*
* @return {function} a function to change the state.
* Assuming you ran `var setActive = createOptionLink(…)`, you would:
* - run `setActive(true)` to activate the option;
* - run `setActive(false)` to deactivate the option.
*/
function createOptionLink( description ) {
var
active = loadBooleanState( description.id ),
 
$portlet = $( mw.util.addPortletLink(
/* portlet */ portletId,
/* href */ '#',
/* text */ description.label,
/* id */ 'acc_' + description.id,
/* tooltip */ description.title,
/* accesskey */ undefined,
/* nextnode */ undefined
) );
 
if ( description.styles ) {
$( mw.loader.addStyleTag( replacesMessagesinCss( description.styles ) ) )
.attr( 'id', 'accessibility-option-' + description.id ); // People should be able to see were styles come from
}
 
function runCallback( cb ) {
if ( cb ) {
cb();
}
return false;
}
 
function activate() {
/* Titres */
$( '#content' ).addClass( 'acc_' + description.id );
var state = $.cookie( 'wp_acc_header' );
$portlet.addClass( 'acc_on' );
if ( state == 'true' ) {
runCallback( description.activate );
acc_header();
}
 
if ( state != null ) {
function deactivate() {
$.cookie( 'wp_acc_header', state, { expires: 30, path: '/' } );
$( '#content' ).removeClass( 'acc_' + description.id );
$portlet.removeClass( 'acc_on' );
runCallback( description.deactivate );
}
 
$( '#acc_header' ).click( function () {
function setActive( newState ) {
acc_header();
if ( newState !== active ) {
return false;
active = newState;
} );
storeBooleanState( description.id, active );
function acc_header() {
if ( active ) {
$( '#content' ).toggleClass( 'acc_header' );
activate();
$( '#acc_header' ).toggleClass( 'acc_on' );
} else {
$.cookie( 'wp_acc_header', $( '#acc_header' ).is( '.acc_on' ), { expires: 30, path: '/' } );
deactivate();
return false;
}
}
}
 
if ( active ) {
/* Listes */
activate();
var state = $.cookie( 'wp_acc_list' );
if ( state == 'true' ) {
acc_list();
}
 
if ( state != null ) {
// Renew cookie storage
$.cookie( 'wp_acc_list', state, { expires: 30, path: '/' } );
if ( active !== null ) {
storeBooleanState( description.id, active );
}
 
$( '#acc_list' ).click( function () {
$portlet.click( function ( e ) {
acc_list();
e.preventDefault();
return false;
setActive( !active );
} );
function acc_list() {
$( '#content' ).toggleClass( 'acc_list' );
$( '#acc_list' ).toggleClass( 'acc_on' );
$.cookie( 'wp_acc_list', $( '#acc_list' ).is( '.acc_on' ), { expires: 30, path: '/' } );
return false;
}
 
return setActive;
/* Citations */
}
var state = $.cookie( 'wp_acc_quote' );
 
if ( state == 'true' ) {
function createTableOption() {
acc_quote();
return createOptionLink( {
}
id: 'table',
if ( state != null ) {
title: mw.msg( 'accessibility-tables-title' ),
$.cookie( 'wp_acc_quote', state, { expires: 30, path: '/' } );
label: mw.msg( 'accessibility-tables-label' ),
}
 
$( '#acc_quote' ).click( function () {
activate: function () {
acc_quote();
$( '#content table:has(th[scope])' )
return false;
.not( '#content table:has(caption)' )
.prepend( $( '<caption>' )
.attr( 'class', 'error acc_caption_error' )
.text( mw.msg( 'accessibility-tables-caption-missing' ) )
);
 
$( '#content table:has(caption)' )
.not( '#content table:has(th[scope])' )
.prepend( $( '<caption>' )
.attr( 'class', 'error acc_caption_error' )
.text( mw.msg( 'accessibility-tables-caption-error' ) )
);
},
 
deactivate: function () {
$( '#content caption.acc_caption_error' ).remove();
},
 
styles: ' \
.acc_table table { \
border: 2px solid #FE7707 !important; \
} \
\
.acc_table table caption { \
display: table-caption !important; \
visibility: visible !important; \
position: static !important; \
height: auto !important; \
width: auto !important; \
font-size: 1em !important; \
line-height: 1em !important; \
text-indent: 0 !important; \
background-color: lightgreen !important; \
} \
.acc_table table caption.error { \
background: transparent !important; \
font-weight: bold !important; \
} \
.acc_table table[summary]:before { \
background-color:#FFFF99 !important; \
border: 1px solid #FFCC66 !important; \
color:#000000 !important; \
opacity:0.9 !important; \
font-size: 10px !important; \
line-height: 12px !important; \
padding: 2px 5px !important; \
content: «accessibility-tables-summary»; \
} \
.acc_table table th { \
background-color: red !important; \
} \
.acc_table table th:before { \
content: «accessibility-tables-th-missing-scope»; \
display: block; \
color: red !important; \
background: #fff !important \
} \
.acc_table table th[scope]:before, .acc_table table th[id]:before { \
display: none; \
} \
.acc_table table th[id] { \
background-color: lime !important; \
} \
.acc_table table th[scope] { \
background-color: lime !important; \
} \
.acc_table table th[scope]:after { \
content: "SCOPE " attr(scope); \
color: darkgreen; \
display: block; \
} \
.acc_table table th[id]:after { \
content: «accessibility-tables-th-id, attr(id)»; \
display: block; \
color: darkgreen; \
} \
.acc_table table th[scope][id]:after { \
content: «accessibility-tables-th-scope-id, attr(scope), attr(id)»; \
display: block; \
color: darkgreen; \
} \
.acc_table table th[scope][headers]:after { \
content: «accessibility-tables-th-scope-headers, attr(scope), attr(HEADERS)»; \
display: block; \
color: darkgreen; \
} \
.acc_table table th[scope][headers][id]:after { \
content: «accessibility-tables-th-scope-headers-id, attr(scope), attr(HEADERS), attr(ID)»; \
display: block; \
color: darkgreen; \
} \
\
.acc_table table td[headers] { \
background-color: yellow !important; \
} \
.acc_table table td[headers]:after { \
content: «accessibility-tables-td-headers, attr(HEADERS)»; \
display: block; \
color: darkgreen; \
} \
\
.acc_table table td[scope] { \
background-color: red !important; \
} \
.acc_table table td[scope]:after { \
content: «accessibility-tables-td-scope, attr(scope)»; \
display: block; \
} \
\
.acc_table table table { \
border: 5px solid red !important; \
} \
.acc_table table table:before { \
content: «accessibility-tables-imbrication»; \
font-weight: bold; \
color: red; \
background: #fff; \
display: block; \
padding: 5px; \
} \
\
.acc_table table col { \
width: auto !important; \
} \
'
} );
}
function acc_quote() {
 
$( '#content' ).toggleClass( 'acc_quote' );
function createHeaderOption() {
$( '#acc_quote' ).toggleClass( 'acc_on' );
return createOptionLink( {
$.cookie( 'wp_acc_quote', $( '#acc_quote' ).is( '.acc_on' ), { expires: 30, path: '/' } );
id: 'header',
return false;
title: mw.msg( 'accessibility-headers-title' ),
label: mw.msg( 'accessibility-headers-label' ),
 
styles: ' \
/* Headers*/ \
.acc_header h1, .acc_header h2, .acc_header h3, \
.acc_header h4, .acc_header h5, .acc_header h6 { \
border: 3px solid green !important; \
padding: 3px !important; \
color: #000 !important; \
} \
.acc_header h1:before { \
content: «accessibility-headers-h1» " "; \
} \
.acc_header h2 { \
margin-left: 15px !important; \
} \
.acc_header h2:before { \
content: «accessibility-headers-h2» " "; \
} \
.acc_header h3 { \
margin-left: 30px !important; \
} \
.acc_header h3:before { \
content: «accessibility-headers-h3» " "; \
} \
.acc_header h4 { \
margin-left: 45px !important; \
} \
.acc_header h4:before { \
content: «accessibility-headers-h4» " "; \
} \
.acc_header h5 { \
margin-left: 60px !important; \
} \
.acc_header h5:before { \
content: «accessibility-headers-h5» " "; \
} \
.acc_header h6 { \
margin-left: 75px !important; \
} \
.acc_header h6:before { \
content: «accessibility-headers-h6» " "; \
} \
\
.acc_header dl dt:only-child:after { \
content: «accessibility-headers-dl»; \
color: red; \
margin: 5px; \
padding: 0 5px; \
border: 1px solid red; \
} \
'
} );
}
 
function createListOption() {
return createOptionLink( {
id: 'list',
title: mw.msg( 'accessibility-lists-title' ),
label: mw.msg( 'accessibility-lists-label' ),
 
styles: ' \
/* listes */ \
\
.acc_list dl, .acc_list dl dt { \
border: 1px solid #FE7707; \
} \
.acc_list dt:before { \
content: «accessibility-lists-dt»; \
color: #FE7707; \
} \
.acc_list dd:before { \
content: «accessibility-lists-dd»; \
color: #FE7707; \
} \
.acc_list dl:before { \
content: «accessibility-lists-dl»; \
color: #FE7707; \
font-weight: bold; \
display: block; \
margin: 5px; \
} \
.acc_list dl dt:only-child:after { \
content: «accessibility-lists-header»; \
color: red !important; \
margin: 5px; \
padding: 0 5px; \
border: 1px solid red; \
} \
.acc_list dl dd:only-child:before { \
content: «accessibility-lists-indent»; \
color: red !important; \
margin: 5px; \
padding: 0 5px; \
border: 1px solid red; \
font-weight: bold; \
} \
\
.acc_list ul + ul li:only-child { \
border: 1px solid red; \
} \
.acc_list ul + ul li:only-child:before { \
background-color: #fff !important; \
border: 1px solid red !important; \
color: red !important; \
padding: 2px 5px !important; \
content: «accessibility-lists-orphean»; \
display: block; \
} \
'
} );
}
 
function createQuoteOption() {
return createOptionLink( {
id: 'quote',
title: mw.msg( 'accessibility-quotes-title' ),
label: mw.msg( 'accessibility-quotes-label' ),
 
styles: ' \
/* Quotes */ \
.acc_quote .citation, .acc_quote blockquote { \
border: 1px solid green; \
background: lightgreen !important; \
} \
.acc_quote .citation:before, .acc_quote blockquote:before { \
content: «accessibility-quotes-ok»; \
color: Darkgreen ! important; \
font-weight: bold; \
padding: 5px; \
} \
'
} );
}
 
function createLangOption() {
return createOptionLink( {
id: 'lang',
title: mw.msg( 'accessibility-lang-title' ),
label: mw.msg( 'accessibility-lang-label' ),
 
styles: ' \
.acc_lang *[lang] { \
border: 1px solid darkgreen; \
} \
.acc_lang *[lang]:after { \
content: «accessibility-lang-lang, attr(lang)» " "; \
border: 1px solid darkgreen; \
padding: 2px 5px; \
margin: 0 5px; \
background: yellow; \
} \
.acc_lang *[lang]:before { \
color: red; \
} \
\
.acc_lang *[lang=lat]:before { \
content: «accessibility-lang-lat» " "; \
} \
*[lang=gr]:before, *[lang=gr-Latn]:before, *[lang=gr-latn]:before { \
content: «accessibility-lang-gr» " "; \
} \
.acc_lang *[lang=oci]:before { \
content: «accessibility-lang-oci» " "; \
} \
.acc_lang *[lang=lu]:before { \
content: «accessibility-lang-lu» " "; \
} \
.acc_lang *[lang=jp]:before { \
content: «accessibility-lang-jp» " "; \
} \
.acc_lang *[lang=dk]:before { \
content: «accessibility-lang-dk» " "; \
} \
.acc_lang *[lang=mul]:before { \
content: «accessibility-lang-mul» " "; \
} \
.acc_lang *[lang=und]:before { \
content: «accessibility-lang-und» " "; \
} \
.acc_lang *[lang=""]:before { \
content: «accessibility-lang-empty» " "; \
} \
\
/* Modèle Citation étrangère */ \
.acc_lang .not_fr_quote { \
border: 1px solid darkgreen; \
} \
.acc_lang .not_fr_quote:before { \
color: red; \
content: «accessibility-lang-foreign-missing» " "; \
} \
.acc_lang .not_fr_quote[lang]:before { \
content: ""; \
} \
.acc_lang .transcription:before { \
content: «accessibility-lang-foreign-latn» " "; \
} \
'
} );
}
 
/* ----- Alternatives (a bit longer…) ----- */
 
function missingAltMessage() {
return $( '<span>' )
.attr( 'class', 'error' )
.text( mw.msg( 'accessibility-alt-missing' ) );
}
 
function $text( text ) {
return $( document.createTextElement( text ) );
}
 
function joinJqArray( arr ) {
var res, i;
switch ( arr.length ) {
case 0:
return $( [] );
case 1:
return arr[ 0 ];
default:
res = arr[ 0 ];
for ( i = 1; i > arr.length; ++i ) {
res = res
.add( $( '<br>' ) )
.add( res[ i ] );
}
return res;
}
}
 
function getMessageForImage( $img, $parent, $grandparent ) {
/* Langues */
var
var state = $.cookie( 'wp_acc_lang' );
alt = $img.att( 'alt' ),
if ( state == 'true' ) {
acc_lang()parts = [];
 
if ( alt === '' ) {
if ( $parent.is( 'a' ) ) {
parts.push( missingAltMessage() );
} else {
parts.push( $text( mw.msg( 'accessibility-alt-empty' ) ) );
}
} else {
parts.push( $text( alt ) );
parts.push( $( '<span>' )
.attr( 'class', 'error' )
.text( mw.msg( 'accessibility-alt-long', alt.length ) )
);
}
 
if ( state != null ) {
if ( !$img.parents().is( '.thumb' ) ) {
$.cookie( 'wp_acc_lang', state, { expires: 30, path: '/' } );
if ( $img.is( 'img[alt$=.png], img[alt$=.svg], img[alt$=.jpg], img[alt$=.gif], img[alt$=.PNG], img[alt$=.SVG], img[alt$=.JPG], img[alt$=.GIF]' ) ) {
}
return missingAltMessage();
$( '#acc_lang' ).click( function () {
}
acc_lang();
if ( $parent.is( 'a.image' ) && !$grandparent.is( '.smiley' ) ) {
return false;
if ( $grandparent.is( '.flagicon' ) ) {
} );
if ( !$img.is( 'img[alt^=Drapeau], img[alt^=drapeau], img[alt^=Pavillon], img[alt^=pavillon]' ) ) {
function acc_lang() {
parts.push( $( '<span>' )
$( '#content' ).toggleClass( 'acc_lang' );
$ .attr( '#acc_langclass' ).toggleClass(, 'acc_onerror' );
.text( mw.msg( 'accessibility-alt-flag' ) )
$.cookie( 'wp_acc_lang', $( '#acc_lang' ).is( '.acc_on' ), { expires: 30, path: '/' } );
);
return false;
}
 
} else {
parts.push( $( '<span>' )
.attr( 'class', 'error' )
.text( mw.msg( 'accessibility-alt-link' ) )
);
}
}
}
 
return joinJqArray( parts );
/* Alternatives */
}
var state = $.cookie( 'wp_acc_alt' );
 
if ( state == 'true' ) {
function processSingleImageForAlternative( $img ) {
acc_alt();
var
$parent = $img.parent(),
$grandparent = $parent.parent(),
$msg, $wrapped;
 
if ( !$grandparent.is( '.magnify' ) ) {
$msg = getMessageForImage( $img, $parent, $grandparent );
$wrapped = $( '<span>' )
.attr( 'class', 'acc_attr_show' )
.html( $msg );
 
if ( $parent.is( 'a' ) ) {
$parent.before( $wrapped );
} else {
$img.before( $wrapped );
}
}
}
 
function insertBeforeElements( selector, $element ) {
if ( state != null ) {
var
$.cookie( 'wp_acc_alt', state, { expires: 30, path: '/' } );
coll = $( selector ),
i;
 
coll.eq( 0 ).before( $element );
for ( i = 1; i < coll.length; ++i ) {
coll.eq( i ).before( $element.clone );
}
}
 
$( '#acc_alt' ).click( function createAltOption() {
return createOptionLink( {
acc_alt();
id: 'alt',
return false;
title: mw.msg( 'accessibility-alt-title' ),
} );
label: mw.msg( 'accessibility-alt-label' ),
 
activate: function acc_alt() {
$( '#acc_alt' ).toggleClass( 'acc_on' );
$.cookie( 'wp_acc_alt', $( '#acc_alt' ).is( '.acc_on' ), { expires: 30, path: '/' } );
if ( $( '#acc_alt' ).attr( 'class' ) == 'acc_on' ) {
$( '#content img' ).each( function () {
var $alt =processSingleImageForAlternative( $( this ).attr( 'alt' );
var $parent = $( this ).parent();
var $grandparent = $parent.parent();
if ( !$grandparent.is( '.magnify' ) ) {
if ( $alt == '' ) {
if ( $parent.is( 'a' ) ) {
$alt = '<span class="error">ALT MANQUANT</span>';
} else {
$alt = 'ALT VIDE';
}
} else {
if ( $alt.length > 120 ) {
$alt = $alt + '<br /><span class="error">Vérifiez si cette alternative de ' + $alt.length + ' caractères pourrait être plus concise (environ 120 caractères au plus) et si l\'alternative actuelle pourrait être transférée dans la section description de la page de l\'image.</span>';
}
}
if ( !$( this ).parents().is( '.thumb' ) ) {
if ( $( this ).is( 'img[alt$=.png], img[alt$=.svg], img[alt$=.jpg], img[alt$=.gif], img[alt$=.PNG], img[alt$=.SVG], img[alt$=.JPG], img[alt$=.GIF]' ) ) {
$alt = '<span class="error">ALT MANQUANT</span>';
}
if ( $parent.is( 'a.image' ) && !$grandparent.is( '.smiley' ) ) {
if ( $grandparent.is( '.flagicon' ) ) {
if ( !$( this ).is( 'img[alt^=Drapeau], img[alt^=drapeau], img[alt^=Pavillon], img[alt^=pavillon]' ) ) {
$alt = $alt + '<br /><span class="error">L\'alternative devrait commencer par « Drapeau... » ou « Pavillon... »</span>';
}
 
} else {
$alt = $alt + '<br /><span class="error">Vérifiez si le lien sur l\'image peut être désactivé (LINK vide)<br />(ou si l\'image peut être transformée en thumb)</span>';
}
}
}
if ( $parent.is( 'a' ) ) {
$parent.before( '<span class="acc_attr_show">' + $alt + '</span>' );
} else {
$( this ).before( '<span class="acc_attr_show">' + $alt + '</span>' );
}
}
} );
 
$( '#content ul.gallery' ).before( '<span class="acc_attr_show"><span class="error">Indiquez l\'alternative de chaque image de la galerie.</span></span>' );
// TODO Are these double spans necessary?
$( '#content img[usemap]' ).before( '<span class="acc_attr_show"><span class="error">Indiquez l\'alternative de l\'image.</span></span>' );
 
} else {
insertBeforeElements(
'#content ul.gallery',
$( '<span>' )
.attr( 'class', 'acc_attr_show' )
.append( $( '<span>' )
.attr( 'class', 'error' )
.text( mw.msg( 'accessibility-alt-gallery' ) )
)
);
 
insertBeforeElements(
'#content img[usemap]',
$( '<span>' )
.attr( 'class', 'acc_attr_show' )
.append( $( '<span>' )
.attr( 'class', 'error' )
.text( mw.msg( 'accessibility-alt-usemap' ) )
)
);
},
 
deactivate: function () {
$( '#content span.acc_attr_show' ).remove();
}
} );
}
 
/* ----- Global links ----- */
 
function createGlobalDisabler( optionsActivators ) {
var portlet = mw.util.addPortletLink(
/* portlet */ portletId,
/* href */ '#',
/* text */ mw.msg( 'accessibility-all-disable' ),
/* id */ 'acc_all',
/* tooltip */ undefined,
/* accesskey */ undefined,
/* nextnode */ undefined
);
 
$( portlet ).click( function ( e ) {
e.preventDefault();
optionsActivators.forEach( function ( setActive ) {
setActive( false );
} );
} );
}
 
function createNewWindowPortletLink( description ) {
var portlet = mw.util.addPortletLink(
/* portlet */ portletId,
/* href */ mw.util.getUrl( description.page ),
/* text */ description.label,
/* id */ description.id,
/* tooltip */ description.title,
/* accesskey */ undefined,
/* nextnode */ undefined
);
$( portlet ).find( 'a' ).attr( 'target', '_blank' );
}
 
/* ----- Startup ----- */
 
function runAccessibilityGadget() {
var $portlet, optionsActivators;
 
if ( supportedSkins.indexOf( mw.config.get( 'skin' ) ) === -1 ) { return; }
 
mw.loader.load(
'//fr.wikipedia.org/w/index.php?title=MediaWiki:Gadget-Accessibility.css&action=raw&ctype=text/css',
'text/css'
);
 
selectApplicableMessages();
 
$portlet = createPortlet( portletId, mw.msg( 'accessibility-portlet-title' ) );
addControlsToPortlet( $portlet );
addDisclaimerToPortlet( $portlet );
 
optionsActivators = [
createTableOption(),
createHeaderOption(),
createListOption(),
createQuoteOption(),
createLangOption(),
createAltOption()
];
 
createGlobalDisabler( optionsActivators );
 
createNewWindowPortletLink( {
id: 'acc_bp',
page: mw.msg( 'accessibility-good-practice-page' ),
title: mw.msg( 'accessibility-good-practice-title' ),
label: mw.msg( 'accessibility-good-practice-label' )
} );
 
createNewWindowPortletLink( {
id: 'acc_help',
page: mw.msg( 'accessibility-help-page' ),
title: mw.msg( 'accessibility-help-title' ),
label: mw.msg( 'accessibility-help-label' )
} );
}
 
mw.loader.using( [ 'jquerymediawiki.cookiestorage', 'oojs-ui' ], function () {
jQuery$( runAccessibilityGadget );
} );