« MediaWiki:Carte-osm.js » : différence entre les versions
Cartes : outil Deplacer pour les utilisateurs connectes (fiche du lieu, clic sur la carte, enregistrement dans le wikicode) |
Cartes : cartes d ensemble (parametre sources), pictogramme par theme, points dans les tableaux, Deplacer corrige l article source |
||
| Ligne 1 : | Ligne 1 : | ||
/* Cartes OpenStreetMap de WikiColombes. | /* Cartes OpenStreetMap de WikiColombes. | ||
* | * | ||
* | * Côté wikicode : | ||
* - {{Carte OSM}} place | * - {{Carte OSM}} place une carte dans la page ; | ||
* - {{Point carte|latitude|longitude| | * - {{Point carte|latitude|longitude|…}}, posé à côté d'un nom, dans une liste | ||
* d'un | * ou dans la première colonne d'un tableau, y ajoute ce lieu. | ||
* | * | ||
* | * Deux sortes de cartes : | ||
* - la carte d'un article montre les points de cet article ; sa légende reprend | |||
* | * les titres de section (niveau 3, à défaut 2) qui les précèdent ; | ||
* | * - une carte d'ensemble ({{Carte OSM|sources=Article 1; Article 2}}) ne contient | ||
* aucun point : elle lit ceux des articles cités, à chaque affichage. Rien n'est | |||
* recopié, donc rien n'est à synchroniser ; sa légende propose un thème par | |||
* article, nommé par le paramètre « thème » de la carte de cet article. | |||
* | |||
* Pastilles : pour un établissement scolaire (niveau=…), une lettre par niveau — | |||
* M maternelle, É élémentaire, P primaire en bleu, C collège en orange, L lycée en | |||
* vert ; pour tout autre lieu, le pictogramme du lieu (symbole=…) ou, à défaut, | |||
* celui de son thème. Carré : établissement privé ou lieu associatif. | |||
* | |||
* Les utilisateurs connectés peuvent déplacer un lieu depuis sa fiche (bouton | |||
* « Déplacer ») : le script réécrit alors les coordonnées de son {{Point carte}} | |||
* dans l'article où il est défini, même depuis une carte d'ensemble. | |||
* | * | ||
* Bibliothèque : Leaflet 1.9.4, hébergée sur le serveur du wiki | * Bibliothèque : Leaflet 1.9.4, hébergée sur le serveur du wiki | ||
| Ligne 18 : | Ligne 27 : | ||
* Fond de carte : tuiles OpenStreetMap standard, attribution obligatoire. | * Fond de carte : tuiles OpenStreetMap standard, attribution obligatoire. | ||
* Styles : bloc « Cartes OpenStreetMap » de MediaWiki:Common.css. | * Styles : bloc « Cartes OpenStreetMap » de MediaWiki:Common.css. | ||
*/ | */ | ||
( function () { | ( function () { | ||
| Ligne 39 : | Ligne 45 : | ||
P: { nom: 'École primaire', famille: 'ecole' }, | P: { nom: 'École primaire', famille: 'ecole' }, | ||
C: { nom: 'Collège', famille: 'college' }, | C: { nom: 'Collège', famille: 'college' }, | ||
L: { nom: 'Lycée', famille: 'lycee' } | L: { nom: 'Lycée', famille: 'lycee' } | ||
}; | }; | ||
var ORDRE = [ 'M', 'É', 'P', 'C', 'L | var ORDRE = [ 'M', 'É', 'P', 'C', 'L' ]; | ||
var HAUTEUR_PX = 26; // hauteur d'un marqueur (pastille de 22 px + liseré) | var HAUTEUR_PX = 26; // hauteur d'un marqueur (pastille de 22 px + liseré) | ||
var MARGE_PX = 3; // écart minimal entre deux marqueurs voisins | var MARGE_PX = 3; // écart minimal entre deux marqueurs voisins | ||
var reduit = window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches; | var reduit = window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches; | ||
var compteur = 0; // identifiant unique de chaque point, toutes cartes confondues | |||
/* ---------- utilitaires ---------- */ | /* ---------- utilitaires ---------- */ | ||
| Ligne 53 : | Ligne 59 : | ||
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[ c ]; | return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[ c ]; | ||
} ); | } ); | ||
} | |||
function simplifier( s ) { | |||
return String( s ).toLowerCase().normalize( 'NFD' ).replace( /[̀-ͯ]/g, '' ).replace( /[^a-z0-9]+/g, ' ' ).trim(); | |||
} | } | ||
| Ligne 65 : | Ligne 75 : | ||
} | } | ||
} ); | } ); | ||
vus.sort( function ( a, b ) { | return vus.sort( function ( a, b ) { | ||
return ORDRE.indexOf( a ) - ORDRE.indexOf( b ); | return ORDRE.indexOf( a ) - ORDRE.indexOf( b ); | ||
} ); | } ); | ||
} | } | ||
function | /* Les pastilles d'un point : lettres de niveau pour une école, sinon un pictogramme. */ | ||
return '<span class="carte-osm-pastille | function pucesDe( p ) { | ||
var carre = p.statut !== 'public'; | |||
if ( p.niveaux.length ) { | |||
return p.niveaux.map( function ( n ) { | |||
return { texte: n, classe: 'carte-osm-' + NIVEAUX[ n ].famille, carre: carre, rang: ORDRE.indexOf( n ) }; | |||
} ); | |||
} | |||
return [ { texte: p.symbole || '•', classe: 'carte-osm-symbole', carre: carre, rang: 10 } ]; | |||
} | |||
function htmlPuce( u ) { | |||
return '<span class="carte-osm-pastille ' + u.classe + ( u.carre ? ' carte-osm-prive' : '' ) + | |||
'" aria-hidden="true">' + echapper( u.texte ) + '</span>'; | |||
} | |||
/* Réunit des pastilles sans doublon, dans un ordre stable. */ | |||
function fusionnerPuces( listes, ignorerForme ) { | |||
var vues = {}, res = []; | |||
listes.forEach( function ( liste ) { | |||
liste.forEach( function ( u ) { | |||
var cle = u.texte + '|' + u.classe + ( ignorerForme ? '' : '|' + u.carre ); | |||
if ( !vues[ cle ] ) { | |||
vues[ cle ] = true; | |||
res.push( u ); | |||
} | |||
} ); | |||
} ); | |||
return res.sort( function ( a, b ) { | |||
return a.rang - b.rang || ( a.carre === b.carre ? 0 : a.carre ? 1 : -1 ); | |||
} ); | |||
} | } | ||
function pastillesDe( p ) { | function pastillesDe( p ) { | ||
return p | return pucesDe( p ).map( htmlPuce ).join( '' ); | ||
} | } | ||
| Ligne 87 : | Ligne 122 : | ||
} | } | ||
/* Le nom d'un lieu : la page | function lienValable( a ) { | ||
function lireNom( | return !a.closest( '.reference, .point-carte-voir, .mw-cite-backlink, sup' ) && | ||
var | !a.classList.contains( 'external' ) && !a.classList.contains( 'mw-file-description' ); | ||
lien = null | } | ||
if ( | /* Le nom d'un lieu : le lien le plus proche qui le précède dans la même cellule | ||
lien = | (ou le même élément de liste) ; à défaut, le premier lien de la ligne ; à défaut, | ||
le texte. Du lien, on garde le titre de la page quand il contient le texte | |||
affiché (« Ambroise Paré » → « École maternelle Ambroise Paré »), sinon le texte | |||
(« Médiathèque de la Marine », lien vers « Médiathèques de Colombes »). */ | |||
function lireNom( el ) { | |||
var force = ( el.getAttribute( 'data-nom' ) || '' ).trim(), | |||
cellule = el.closest( 'td, th, li' ) || el.parentNode, | |||
ligne = el.closest( 'tr, li' ) || cellule, | |||
lien = null; | |||
Array.prototype.forEach.call( cellule.querySelectorAll( 'a' ), function ( a ) { | |||
if ( lienValable( a ) && ( a.compareDocumentPosition( el ) & Node.DOCUMENT_POSITION_FOLLOWING ) ) { | |||
lien = a; | |||
} | } | ||
} ); | |||
if ( !lien ) { | |||
lien = Array.prototype.filter.call( ligne.querySelectorAll( 'a' ), lienValable )[ 0 ] || null; | |||
} | } | ||
if ( lien ) { | if ( lien ) { | ||
var texte = lien.textContent.trim(), | |||
titre = ( lien.getAttribute( 'title' ) || texte ).replace( /\s*\(page inexistante\)$/, '' ).trim(); | |||
return { | return { | ||
complet: force || ( simplifier( titre ).indexOf( simplifier( texte ) ) !== -1 ? titre : texte ), | |||
complet: ( | |||
lien: lien.getAttribute( 'href' ), | lien: lien.getAttribute( 'href' ), | ||
rouge: lien.classList.contains( 'new' ) | rouge: lien.classList.contains( 'new' ), | ||
force: !!force | |||
}; | }; | ||
} | } | ||
var copie = | var copie = cellule.cloneNode( true ); | ||
copie.querySelectorAll( 'sup, ul, ol, .point-carte-voir' ).forEach( function ( x ) { | copie.querySelectorAll( 'sup, ul, ol, .point-carte-voir' ).forEach( function ( x ) { | ||
x.remove(); | x.remove(); | ||
} ); | } ); | ||
var | var brut = copie.textContent.replace( /\s*\(.*$/, '' ).trim(); | ||
return { | return { complet: force || brut, lien: null, rouge: false, force: !!force }; | ||
} | } | ||
/* Sans lien, « Guy de Maupassant » devient « Lycée Guy de Maupassant ». */ | /* Sans lien, « Guy de Maupassant » devient « Lycée Guy de Maupassant ». */ | ||
function nomComplet( p ) { | function nomComplet( p ) { | ||
if ( p.nom.lien || p.niveaux | if ( p.nom.lien || p.nom.force || !p.niveaux.length || | ||
/^(École|Ecole|Collège|Lycée|Groupe|Institut|Cité)\b/i.test( p.nom.complet ) ) { | /^(École|Ecole|Collège|Lycée|Groupe|Institut|Cité)\b/i.test( p.nom.complet ) ) { | ||
return p.nom.complet; | return p.nom.complet; | ||
| Ligne 123 : | Ligne 172 : | ||
} | } | ||
function detail( p, ensemble ) { | |||
var morceaux = []; | |||
if ( ensemble && p.theme ) { | |||
morceaux.push( p.theme.nom ); | |||
} | |||
if ( p.niveaux.length ) { | |||
morceaux.push( 'Enseignement ' + p.statut ); | |||
} else if ( p.statut === 'associatif' ) { | |||
morceaux.push( 'Lieu associatif' ); | |||
} else if ( p.statut === 'privé' ) { | |||
morceaux.push( 'Lieu privé' ); | |||
} | |||
if ( p.adresse ) { | |||
morceaux.push( p.adresse ); | |||
} | |||
return morceaux.map( echapper ).join( ' · ' ); | |||
} | |||
function lirePoints( racine ) { | /* ---------- lecture des points d'une page ---------- */ | ||
var points = [], sections = [], index = {}, courante = null, | |||
/* racine : le contenu d'une page (celle qu'on lit, ou une page source chargée par | |||
l'API) ; source : son titre, ou null pour la page affichée. Le rang d'un point | |||
est son numéro d'ordre parmi les {{Point carte}} de sa page : c'est lui qui | |||
désigne le modèle à réécrire quand on déplace le lieu. */ | |||
function lirePoints( racine, source, theme ) { | |||
var points = [], sections = [], index = {}, courante = null, rang = 0; | |||
racine.querySelectorAll( 'h2, h3, .point-carte' ).forEach( function ( el ) { | racine.querySelectorAll( 'h2, h3, .point-carte' ).forEach( function ( el ) { | ||
if ( !el.classList.contains( 'point-carte' ) ) { | if ( !el.classList.contains( 'point-carte' ) ) { | ||
| Ligne 132 : | Ligne 203 : | ||
return; | return; | ||
} | } | ||
var rangIci = | var rangIci = rang++, | ||
lat = parseFloat( el.getAttribute( 'data-lat' ) ), | lat = parseFloat( el.getAttribute( 'data-lat' ) ), | ||
lon = parseFloat( el.getAttribute( 'data-lon' ) ); | lon = parseFloat( el.getAttribute( 'data-lon' ) ); | ||
| Ligne 138 : | Ligne 209 : | ||
return; | return; | ||
} | } | ||
var | var statut = ( el.getAttribute( 'data-statut' ) || '' ).toLowerCase(), | ||
cle = courante || 'Autres lieux'; | |||
if ( !index[ cle ] ) { | if ( !index[ cle ] ) { | ||
index[ cle ] = { nom: cle, points: [], actif: true }; | index[ cle ] = { nom: cle, points: [], actif: true }; | ||
| Ligne 145 : | Ligne 216 : | ||
} | } | ||
var p = { | var p = { | ||
id: compteur++, | |||
lat: lat, | lat: lat, | ||
lon: lon, | lon: lon, | ||
niveaux: lireNiveaux( el.getAttribute( 'data-niveau' ) ), | niveaux: lireNiveaux( el.getAttribute( 'data-niveau' ) ), | ||
statut: /priv/ | statut: /priv/.test( statut ) ? 'privé' : /assoc/.test( statut ) ? 'associatif' : 'public', | ||
adresse: el.getAttribute( 'data-adresse' ) || '', | adresse: el.getAttribute( 'data-adresse' ) || '', | ||
symbole: el.getAttribute( 'data-symbole' ) || ( theme && theme.symbole ) || '', | |||
section: index[ cle ], | section: index[ cle ], | ||
theme: theme, | |||
source: source, | |||
el: el, | el: el, | ||
rang: rangIci | rang: rangIci | ||
}; | }; | ||
p.nom = lireNom( | p.nom = lireNom( el ); | ||
index[ cle ].points.push( p ); | index[ cle ].points.push( p ); | ||
points.push( p ); | points.push( p ); | ||
} ); | } ); | ||
return { points: points, sections: sections }; | return { points: points, sections: sections }; | ||
} | |||
function themeDe( racine, titre ) { | |||
var c = racine.querySelector( '.carte-osm' ); | |||
return { | |||
nom: ( c && c.getAttribute( 'data-theme' ) ) || titre, | |||
symbole: ( c && c.getAttribute( 'data-symbole' ) ) || '', | |||
page: titre, | |||
points: [], | |||
actif: true | |||
}; | |||
} | |||
/* Charge une page source par l'API et en lit les points. */ | |||
function chargerSource( titre ) { | |||
return mw.loader.using( 'mediawiki.api' ).then( function () { | |||
return new mw.Api().get( { | |||
action: 'parse', | |||
page: titre, | |||
prop: 'text', | |||
redirects: 1, | |||
disableeditsection: 1, | |||
disablelimitreport: 1, | |||
formatversion: 2 | |||
} ); | |||
} ).then( function ( r ) { | |||
var doc = new DOMParser().parseFromString( r.parse.text, 'text/html' ), | |||
theme = themeDe( doc, r.parse.title ), | |||
lus = lirePoints( doc, r.parse.title, theme ); | |||
theme.points = lus.points; | |||
return theme; | |||
}, function () { | |||
return { nom: titre, page: titre, points: [], actif: true, erreur: true }; | |||
} ); | |||
} | } | ||
| Ligne 164 : | Ligne 273 : | ||
function construire( conteneur, racine ) { | function construire( conteneur, racine ) { | ||
var | var sources = ( conteneur.getAttribute( 'data-sources' ) || '' ).split( /\s*;\s*/ ).map( function ( s ) { | ||
return s.trim(); | |||
} ).filter( Boolean ); | |||
if ( !sources.length ) { | |||
var themeLocal = themeDe( racine, mw.config.get( 'wgTitle' ) ), | |||
lus = lirePoints( racine, null, themeLocal ); | |||
if ( lus.points.length ) { | |||
dessinerCarte( conteneur, lus.points, lus.sections, false, [] ); | |||
} | |||
return; | return; | ||
} | } | ||
conteneur.classList.add( 'carte-osm-prete' ); | |||
$.when.apply( $, sources.map( chargerSource ) ).then( function () { | |||
var themes = Array.prototype.slice.call( arguments ), | |||
points = [], manquants = []; | |||
themes.forEach( function ( t ) { | |||
if ( t.erreur || !t.points.length ) { | |||
manquants.push( t.page ); | |||
} | |||
points = points.concat( t.points ); | |||
t.points.forEach( function ( p ) { | |||
p.section = t; // dans une carte d'ensemble, la légende filtre par thème | |||
} ); | |||
} ); | |||
themes = themes.filter( function ( t ) { | |||
return t.points.length; | |||
} ); | |||
if ( points.length ) { | |||
dessinerCarte( conteneur, points, themes, true, manquants ); | |||
} else { | |||
var repli = conteneur.querySelector( '.carte-osm-repli' ); | |||
if ( repli ) { | |||
repli.textContent = 'Aucun lieu trouvé dans les articles sources.'; | |||
} | |||
} | |||
} ); | |||
} | |||
/* points : les lieux ; filtres : les entrées de la légende (sections d'un article, | |||
ou thèmes d'une carte d'ensemble) ; ensemble : vrai pour une carte d'ensemble. */ | |||
function dessinerCarte( conteneur, points, filtres, ensemble, manquants ) { | |||
conteneur.classList.add( 'carte-osm-prete' ); | conteneur.classList.add( 'carte-osm-prete' ); | ||
conteneur.innerHTML = ''; | conteneur.innerHTML = ''; | ||
| Ligne 180 : | Ligne 327 : | ||
legende.setAttribute( 'role', 'group' ); | legende.setAttribute( 'role', 'group' ); | ||
legende.setAttribute( 'aria-label', 'Lieux affichés sur la carte' ); | legende.setAttribute( 'aria-label', 'Lieux affichés sur la carte' ); | ||
filtres.forEach( function ( s ) { | |||
var etiquette = document.createElement( 'label' ), | var etiquette = document.createElement( 'label' ), | ||
caseACocher = document.createElement( 'input' ); | caseACocher = document.createElement( 'input' ), | ||
echantillon = ensemble ? | |||
fusionnerPuces( s.points.map( pucesDe ), true ).slice( 0, 5 ) : | |||
pucesDe( s.points[ 0 ] ); | |||
caseACocher.type = 'checkbox'; | caseACocher.type = 'checkbox'; | ||
caseACocher.checked = true; | caseACocher.checked = true; | ||
| Ligne 193 : | Ligne 343 : | ||
etiquette.appendChild( caseACocher ); | etiquette.appendChild( caseACocher ); | ||
etiquette.insertAdjacentHTML( 'beforeend', | etiquette.insertAdjacentHTML( 'beforeend', | ||
'<span class="carte-osm-puces">' + | '<span class="carte-osm-puces">' + echantillon.map( htmlPuce ).join( '' ) + '</span>' + | ||
'<span>' + echapper( s.nom ) + '</span>' + | '<span>' + echapper( s.nom ) + '</span>' + | ||
'<span class="carte-osm-compte">' + s.points.length + '</span>' ); | '<span class="carte-osm-compte">' + s.points.length + '</span>' ); | ||
legende.appendChild( etiquette ); | legende.appendChild( etiquette ); | ||
} ); | } ); | ||
if ( ensemble && points.some( function ( p ) { | |||
return p.statut !== 'public'; | |||
} ) ) { | |||
legende.insertAdjacentHTML( 'beforeend', '<span class="carte-osm-note">' + | |||
'<span class="carte-osm-pastille carte-osm-symbole carte-osm-prive" aria-hidden="true"></span>' + | |||
'carré : privé ou associatif</span>' ); | |||
} | |||
if ( manquants.length ) { | |||
legende.insertAdjacentHTML( 'beforeend', '<span class="carte-osm-note">Sans lieu ou introuvable : ' + | |||
manquants.map( echapper ).join( ', ' ) + '</span>' ); | |||
} | |||
var fond = document.createElement( 'div' ); | var fond = document.createElement( 'div' ); | ||
| Ligne 218 : | Ligne 379 : | ||
L.control.zoom( { zoomInTitle: 'Zoom avant', zoomOutTitle: 'Zoom arrière' } ).addTo( carte ); | L.control.zoom( { zoomInTitle: 'Zoom avant', zoomOutTitle: 'Zoom arrière' } ).addTo( carte ); | ||
var limites = L.latLngBounds( | var limites; | ||
function calculerLimites() { | |||
} | limites = L.latLngBounds( points.map( function ( q ) { | ||
return [ q.lat, q.lon ]; | |||
} ) ); | |||
} | |||
calculerLimites(); | |||
function cadrer() { | function cadrer() { | ||
carte.fitBounds( limites, { padding: [ 24, 24 ] } ); | carte.fitBounds( limites, { padding: [ 24, 24 ] } ); | ||
| Ligne 251 : | Ligne 416 : | ||
groupes = []; | groupes = []; | ||
function | function ordre( p ) { | ||
return ORDRE.indexOf( p.niveaux[ 0 ] ) * 2 + ( p.statut === ' | return ( p.niveaux.length ? ORDRE.indexOf( p.niveaux[ 0 ] ) : 10 ) * 2 + ( p.statut === 'public' ? 0 : 1 ); | ||
} | } | ||
| Ligne 258 : | Ligne 423 : | ||
var html = '<div class="carte-osm-bulle"><ul>'; | var html = '<div class="carte-osm-bulle"><ul>'; | ||
g.membres.slice().sort( function ( a, b ) { | g.membres.slice().sort( function ( a, b ) { | ||
return | return ordre( a ) - ordre( b ) || nomComplet( a ).localeCompare( nomComplet( b ), 'fr' ); | ||
} ).forEach( function ( p ) { | } ).forEach( function ( p ) { | ||
var nom = echapper( nomComplet( p ) ); | var nom = echapper( nomComplet( p ) ), ligne = detail( p, ensemble ); | ||
if ( p.nom.lien ) { | if ( p.nom.lien ) { | ||
nom = '<a href="' + echapper( p.nom.lien ) + '"' + ( p.nom.rouge ? ' class="new"' : '' ) + '>' + nom + '</a>'; | nom = '<a href="' + echapper( p.nom.lien ) + '"' + ( p.nom.rouge ? ' class="new"' : '' ) + '>' + nom + '</a>'; | ||
| Ligne 266 : | Ligne 431 : | ||
html += '<li><span class="carte-osm-puces">' + pastillesDe( p ) + '</span><span>' + | html += '<li><span class="carte-osm-puces">' + pastillesDe( p ) + '</span><span>' + | ||
'<span class="carte-osm-nom">' + nom + '</span>' + | '<span class="carte-osm-nom">' + nom + '</span>' + | ||
'<span class="carte-osm-detail"> | ( ligne ? '<span class="carte-osm-detail">' + ligne + '</span>' : '' ) + | ||
( peutDeplacer ? '<button type="button" class="carte-osm-deplacer" data-id="' + p.id + '">Déplacer</button>' : '' ) + | |||
( peutDeplacer ? '<button type="button" class="carte-osm-deplacer" data- | |||
'</span></li>'; | '</span></li>'; | ||
} ); | } ); | ||
| Ligne 279 : | Ligne 443 : | ||
/* Un groupe = les lieux qui se chevaucheraient à l'écran. Son marqueur aligne | /* Un groupe = les lieux qui se chevaucheraient à l'écran. Son marqueur aligne | ||
leurs pastilles, d'où une largeur variable : on compare donc les boîtes | |||
réelles des marqueurs, pas seulement leurs centres, et on fusionne tant | |||
qu'il reste un chevauchement. */ | |||
function majGroupe( g ) { | function majGroupe( g ) { | ||
var x = 0, y = 0 | var x = 0, y = 0; | ||
g.membres.forEach( function ( p ) { | g.membres.forEach( function ( p ) { | ||
x += p.px.x / g.membres.length; | x += p.px.x / g.membres.length; | ||
| Ligne 289 : | Ligne 453 : | ||
} ); | } ); | ||
g.px = L.point( x, y ); | g.px = L.point( x, y ); | ||
g.puces = | g.puces = fusionnerPuces( g.membres.map( pucesDe ), false ); | ||
g.largeur = g.puces.length * 24 + 2; | g.largeur = g.puces.length * 24 + 2; | ||
} | } | ||
| Ligne 310 : | Ligne 464 : | ||
function dessiner() { | function dessiner() { | ||
calque.clearLayers(); | calque.clearLayers(); | ||
groupes = | groupes = points.filter( function ( p ) { | ||
return p.section.actif; | return p.section.actif; | ||
} ).map( function ( p ) { | } ).map( function ( p ) { | ||
| Ligne 340 : | Ligne 494 : | ||
g.etendu = g.membres.length > 1 && | g.etendu = g.membres.length > 1 && | ||
carte.distance( g.limites.getSouthWest(), g.limites.getNorthEast() ) > 5; | carte.distance( g.limites.getSouthWest(), g.limites.getNorthEast() ) > 5; | ||
var | var noms = g.membres.map( nomComplet ).join( ', ' ), | ||
html = '<span class="carte-osm-marque">' + g.puces.map( htmlPuce ).join( '' ) + | |||
html = '<span class="carte-osm-marque">' + puces.join( '' ) + | ( g.membres.length > g.puces.length ? '<span class="carte-osm-nombre">' + g.membres.length + '</span>' : '' ) + | ||
( g.membres.length > puces.length ? '<span class="carte-osm-nombre">' + g.membres.length + '</span>' : '' ) + | |||
'</span>'; | '</span>'; | ||
g.marque = L.marker( carte.layerPointToLatLng( g.px ), { | g.marque = L.marker( carte.layerPointToLatLng( g.px ), { | ||
| Ligne 356 : | Ligne 509 : | ||
} | } | ||
g.marque.on( 'popupopen', function ( e ) { | g.marque.on( 'popupopen', function ( e ) { | ||
var | var element = e.popup.getElement(), | ||
bouton = | fermer = element.querySelector( '.leaflet-popup-close-button' ), | ||
bouton = element.querySelector( '.carte-osm-zoom' ); | |||
if ( fermer ) { | if ( fermer ) { | ||
fermer.setAttribute( 'aria-label', 'Fermer' ); | fermer.setAttribute( 'aria-label', 'Fermer' ); | ||
| Ligne 368 : | Ligne 522 : | ||
} ); | } ); | ||
} | } | ||
element.querySelectorAll( '.carte-osm-deplacer' ).forEach( function ( b ) { | |||
b.addEventListener( 'click', function () { | b.addEventListener( 'click', function () { | ||
var vise = Number( b.getAttribute( 'data- | var vise = Number( b.getAttribute( 'data-id' ) ); | ||
g.membres.forEach( function ( p ) { | g.membres.forEach( function ( p ) { | ||
if ( p. | if ( p.id === vise ) { | ||
commencerDeplacement( p ); | commencerDeplacement( p ); | ||
} | } | ||
| Ligne 387 : | Ligne 541 : | ||
« Déplacer » dans la fiche d'un lieu, puis un clic sur la carte à l'endroit | « Déplacer » dans la fiche d'un lieu, puis un clic sur la carte à l'endroit | ||
voulu ; le repère provisoire s'ajuste à la souris avant d'enregistrer. | voulu ; le repère provisoire s'ajuste à la souris avant d'enregistrer. | ||
L'enregistrement réécrit les coordonnées du n-ième {{Point carte}} | L'enregistrement réécrit les coordonnées du n-ième {{Point carte}} de | ||
l'article où le lieu est défini — la page affichée, ou l'article source | |||
d'une carte d'ensemble : c'est une modification ordinaire de cet article | |||
(historique, résumé, annulation possible). Si l'article a changé depuis son | |||
affichage, rien n'est écrit. */ | |||
var bandeau = null, enCours = null; | var bandeau = null, enCours = null; | ||
| Ligne 469 : | Ligne 624 : | ||
function enregistrer() { | function enregistrer() { | ||
var p = enCours.p, | var p = enCours.p, | ||
page = p.source || cfg.wgPageName, | |||
ll = enCours.repere.getLatLng(), | ll = enCours.repere.getLatLng(), | ||
lat = ll.lat.toFixed( 6 ), | lat = ll.lat.toFixed( 6 ), | ||
| Ligne 477 : | Ligne 633 : | ||
afficherBandeau( 'Enregistrement…' ); | afficherBandeau( 'Enregistrement…' ); | ||
mw.loader.using( 'mediawiki.api' ).then( function () { | mw.loader.using( 'mediawiki.api' ).then( function () { | ||
return new mw.Api().edit( | return new mw.Api().edit( page, function ( revision ) { | ||
var n = 0, ok = false; | var n = 0, ok = false; | ||
var texte = revision.content.replace( /(\{\{\s*[Pp]oint[ _]carte\s*\|)([^|}]*)\|([^|}]*)/g, | var texte = revision.content.replace( /(\{\{\s*[Pp]oint[ _]carte\s*\|)([^|}]*)\|([^|}]*)/g, | ||
| Ligne 505 : | Ligne 661 : | ||
p.el.setAttribute( 'data-lat', lat ); | p.el.setAttribute( 'data-lat', lat ); | ||
p.el.setAttribute( 'data-lon', lon ); | p.el.setAttribute( 'data-lon', lon ); | ||
calculerLimites(); | |||
arreterDeplacement(); | arreterDeplacement(); | ||
dessiner(); | dessiner(); | ||
afficherBandeau( '✓ Position de <b>' + echapper( nomComplet( p ) ) + '</b> enregistrée. ' + | afficherBandeau( '✓ Position de <b>' + echapper( nomComplet( p ) ) + '</b> enregistrée' + | ||
'<a href="' + echapper( cfg.wgScript + '?title=' + encodeURIComponent( | ( p.source ? ' dans « ' + echapper( p.source ) + ' »' : '' ) + '. ' + | ||
'<a href="' + echapper( cfg.wgScript + '?title=' + encodeURIComponent( page ) + '&action=history' ) + '">Historique</a> ' + | |||
'<button type="button" class="carte-osm-annuler">Fermer</button>' ); | '<button type="button" class="carte-osm-annuler">Fermer</button>' ); | ||
}, function ( code ) { | }, function ( code ) { | ||
var message = code === 'carte-decalee' ? | var message = code === 'carte-decalee' ? | ||
' | 'L’article a changé depuis son affichage : rechargez la page, puis recommencez.' : | ||
'L’enregistrement a échoué (' + echapper( code ) + '). Les coordonnées peuvent aussi se corriger dans le wikicode.'; | 'L’enregistrement a échoué (' + echapper( code ) + '). Les coordonnées peuvent aussi se corriger dans le wikicode.'; | ||
if ( enCours && enCours.repere ) { | if ( enCours && enCours.repere ) { | ||
| Ligne 532 : | Ligne 687 : | ||
} | } | ||
/* ---------- « situer sur la carte » depuis la | /* ---------- « situer sur la carte » depuis la page (points de la page seulement) ---------- */ | ||
points.forEach( function ( p ) { | |||
if ( p.el.nextElementSibling && p.el.nextElementSibling.classList.contains( 'point-carte-voir' ) ) { | if ( p.source || ( p.el.nextElementSibling && p.el.nextElementSibling.classList.contains( 'point-carte-voir' ) ) ) { | ||
return; | return; | ||
} | } | ||