_ _    _ _____  ___   __                       
 __      _(_) | _(_)___ / ( _ ) / /_   ___ ___  _ __ ___  
 \ \ /\ / / | |/ / | |_ \ / _ \| '_ \ / __/ _ \| '_ ` _ \ 
  \ V  V /| |   <| |___) | (_) | (_) | (_| (_) | | | | | |
   \_/\_/ |_|_|\_\_|____/ \___/ \___(_)___\___/|_| |_| |_|

MediaWiki:Gadget-WhereWikimediansLive.js

Dans le monde d'aujourd'hui, MediaWiki:Gadget-WhereWikimediansLive.js est devenu un sujet d'une grande pertinence et d'un grand intérêt pour un large éventail de personnes. Qu'il s'agisse d'un phénomène social, d'une avancée technologique, d'un personnage historique ou de tout autre aspect de la vie moderne, MediaWiki:Gadget-WhereWikimediansLive.js a capté l'attention de différents publics et généré d'intenses débats dans divers cercles. Dans cet article, nous explorerons les différents aspects liés à MediaWiki:Gadget-WhereWikimediansLive.js, de son origine à ses implications actuelles, dans le but d'offrir au lecteur une vision globale et contextualisée de ce sujet d'actualité.
/*
* WhereWikimediansLive
*
* Permet de s'ajouter à la ].
*
* Auteur : ]
* {{Projet:JavaScript/Script|WhereWikimediansLive}}
*/
//<nowiki>



var _wwlMessages = {
	'fr': {
		'wwl-button-edit': 'Modifier mon marqueur',
		'wwl-button-remove': 'Supprimer ma position',
		'wwl-button-add': 'Ajouter ma position',
		'wwl-dialog-remove-title': 'Voulez-vous vraiment retirer votre position ?',
		'wwl-dialog-remove-message': 'L\'information restera cependant disponible dans l\'historique. Si vous souhaitez que les informations soient également retirées de l\'historique, contactez un masqueur par e-mail à l\'adresse [email protected].',
		'wwl-dialog-remove-button-cancel': 'Annuler',
		'wwl-dialog-remove-button-delete': 'Supprimer',
		'wwl-form-button-add': 'Ajouter',
		'wwl-form-link-new-translation': 'Ajouter une description dans une autre langue',
		'wwl-form-fieldset-wikis-title': 'Mes wikis',
		'wwl-form-fieldset-descriptions-title': 'Présentation',
		'wwl-form-button-save': 'Enregistrer',
		'wwl-form-fieldset-wikis-text': 'Sélectionnez votre projet Wikimédia principal, choisissez votre langue, puis cliquez sur "Ajouter". Répétez l\'opération pour les autres projets auxquels vous participez.',
		'wwl-form-description-placeholder': 'Présentez-vous en quelques mots.',
		'wwl-notify-success-add': 'Votre position a été ajoutée sur la carte !',
		'wwl-notify-success-edit': 'Vos informations ont correctement été modifiées sur la carte.',
		'wwl-notify-success-remove': 'Votre position a été retirée de la carte.',
		'wwl-notify-wait': 'Enregistrement en cours, veuillez patienter. En fonction de votre configuation, cette étape peut durer jusqu\'à 1 minute.',
		'wwl-notify-error-get': 'Impossible de récupérer les données sur Commons.',
		'wwl-notify-error-save': 'Une erreur est survenue lors de l\'enregistrement des informations sur Commons.',
	},
	'en': {
		'wwl-button-edit': 'Edit my marker',
		'wwl-button-remove': 'Delete my position',
		'wwl-button-add': 'Add my position',
		'wwl-dialog-remove-title': 'Are you sure you want to remove your position? ?',
		'wwl-dialog-remove-message': 'The information will however remain available in the history. If you want the information also to be removed from the history, contact a masker by e-mail at [email protected].',
		'wwl-dialog-remove-button-cancel': 'Cancel',
		'wwl-dialog-remove-button-delete': 'Remove',
		'wwl-form-button-add': 'Add',
		'wwl-form-link-new-translation': 'Add a description in an other language',
		'wwl-form-fieldset-wikis-title': 'My wikis',
		'wwl-form-fieldset-descriptions-title': 'Description',
		'wwl-form-button-save': 'Save',
		'wwl-form-fieldset-wikis-text': 'Select your main Wikimedia project, choose your language and click "Add". Repeat for the other projects you contribute to.',
		'wwl-form-description-placeholder': 'Present yourself in a few words.',
		'wwl-notify-success-add': 'Your position has been successfully added to the map!',
		'wwl-notify-success-edit': 'Your information has been correctly modified on the map.',
		'wwl-notify-success-remove': 'Your position has been removed from the map.',
		'wwl-notify-wait': 'Saving in progress. Please, be patient, it may take up to 1 minute.',
		'wwl-notify-error-get': 'Unable to retrieve data from Commons.',
		'wwl-notify-error-save': 'An error occurred while registering Commons information.',
	}
};


if ( $( '#wwl-map' ).length ) {
	mw.loader.using( , function() {
		// Initialize all neaded vars
		var kartoBox = mw.loader.require( 'ext.kartographer.box' ),
				api = mw.config.get( 'wgWikiID' ) === 'commonswiki' ? new mw.Api() : new mw.ForeignApi( 'https://commons.wikimedia.org/w/api.php' ),
				localApi = new mw.Api(),
				username = mw.config.get( 'wgUserName' ),
				map,
				popup,
				marker,
				userData,
				userLanguage = mw.config.get( 'wgUserLanguage' ),
				allLanguages = {},
				dropdownLanguages = ,
				currentWiki = {
					'dbname': mw.config.get( 'wgDBname' ),
					'langcode': null,
					'sitecode': null,
				},
				siteMatrix = {
					//multilingual wikis
					'wiki': { label: 'Wikipedia', name: 'Wikipedia', data: 'wiki', shortcode: 'w', color: '#ACFA58', sites:  },
					'wiktionary': { label: 'Wiktionary', name: 'Wiktionary', data: 'wiktionary', shortcode: 'wikt', color: '#F4FA58', sites:  },
					'wikibooks': { label: 'Wikibooks', name: 'Wikibooks', data: 'wikibooks', shortcode: 'b', color: '#e2cc8a', sites:  },
					'wikinews': { label: 'Wikinews', name: 'Wikinews', data: 'wikinews', shortcode: 'n', color: '#575ff9', sites:  },
					'wikiquote': { label: 'Wikiquote', name: 'Wikiquote', data: 'wikiquote', shortcode: 'q', color: '#57f9b9', sites:  },
					'wikisource': { label: 'Wikisource', name: 'Wikisource', data: 'wikisource', shortcode: 's', color: '#FAAC58', sites:  },
					'wikiversity': { label: 'Wikiversity', name: 'Wikiversity', data: 'wikiversity', shortcode: 'v', color: '#cecece', sites:  },
					'wikivoyage': { label: 'Wikivoyage', name: 'Wikivoyage', data: 'wikivoyage', shortcode: 'voy', color: '#f957ba', sites:  },
					//monolingual wikis
					'meta': { label: 'Meta', name: 'Meta', data: 'meta', shortcode: 'm', color: '#D358F7' },
					'commons': { label: 'Wikimedia Commons', name: 'Wikimedia Commons', data: 'commons', shortcode: 'c', color: '#58ACFA' },
					'wikidata': { label: 'Wikidata', name: 'Wikidata', data: 'wikidata', shortcode: 'd', color: '#FA5858' },
					'species': { label: 'Wikispecies', name: 'Wikispecies', data: 'species', shortcode: 'species', color: '#339650' },
					'mediawiki': { label: 'MediaWiki', name: 'MediaWiki', data: 'mediawiki', shortcode: 'mw', color: '#ffffc8' },
				};

		// Get initial datas
		function getData() {
			api.get( {
				action: 'query',
				prop: 'revisions',
				rvprop: ,
				titles: 'Data:Wikimedians.map',
				formatversion: '2',
			} ).fail( function( data ) {
				mw.notify( mw.msg( 'wwl-notify-error-get' ) , { autoHide: false, title: 'WhereWikimediansLives', type: 'error' } );
				console.log( 'WhereWikimediansLive: Failed to fetch initial datas from Commons.' );
				console.log( data );
			} ).then( function( data ) {
				content = JSON.parse( data.query.pages.revisions.content );

				$.each( content.data.features, function( key, userInfos ) {
					if ( userInfos.username === username ) {
						var projects = ;
						$.each( userInfos.data, function( project, langs ) {
							$.each( langs, function( _, lang ) {
								projects.push( { project: project, lang:lang } );
							} );
						} );
						userData = {
							lat: userInfos.geometry.coordinates,
							lng: userInfos.geometry.coordinates,
							projects: projects,
							descriptions: userInfos.properties.description,
						};
						return false;
					}
				} );
				return localApi.get( {
					action: "sitematrix",
					format: "json",
					formatversion: 2
				} );
			} ).then( function( data ) {
				$.each( data.sitematrix, function( key, lang ) {
					if ( key !== 'specials' && key !== 'count' ) {
						allLanguages = {
							'name': lang.name,
							'localname': lang.localname,
						};
						$.each( lang.site, function( _, site ) {
							if ( site.private !== true && site.closed !== true && site.fishbowl !== true ) {
								siteMatrix.sites.push( {
									'data': lang.code,
									'dbname': site.dbname,
									'label': lang.localname
								} );
							}
							if ( site.dbname === currentWiki.dbname ) {
								currentWiki.langcode = lang.code;
								currentWiki.sitecode = site.code;
							}
							if ( lang.code === userLanguage ) {
								siteMatrix.label = site.sitename;
							}
						} );
					}
				} );

				if( currentWiki.sitecode === null ) {
					$.each( data.sitematrix.specials, function( _, site ) {
						if ( site.dbname === currentWiki.dbname ) {
							currentWiki.sitecode = site.code;
							return false;
						}
					} )
				}
				if ( currentWiki.langcode === null ) {
					currentWiki.langcode = 'en';
				}

				$.each( siteMatrix, function( _, project ) {

					if ( project.sites !== undefined ) {
						for( var i = 0; i < project.sites.length; i++ ) {
							if ( project.sites.label === undefined ) {
								project.sites.splice( i, 1 );
							}
						}
						project.sites.sort(function(a,b) { return ( a.label.toLowerCase() > b.label.toLowerCase() ) ? 1 : ( ( b.label.toLowerCase() > a.label.toLowerCase() ) ? -1 : 0 ); } );
					}
				} );

				$.each( allLanguages, function( code, langInfos ) {
					if ( langInfos.localname !== undefined ) {
						dropdownLanguages.push( { data: code, label: langInfos.localname } );
					}
				} );
				dropdownLanguages.sort(function(a,b) { return ( a.label.toLowerCase() > b.label.toLowerCase() ) ? 1 : ( ( b.label.toLowerCase() > a.label.toLowerCase() ) ? -1 : 0 ); } );
				addButtons();
			} );
		}

		// Add the buttons at the bottom of the page
		function addButtons() {
			var buttonContainer = $( '#wwl-buttons' );
			if ( buttonContainer.length === 0 ) {
				buttonContainer = $( '<div id="wwl-buttons" class="wwl-default-buttons" >' );
				$( '#wwl-map' ).after( buttonContainer );
			}

			if ( userData !== undefined ) {
				var editButton = new OO.ui.ButtonWidget( {
					label: mw.msg( 'wwl-button-edit' ),
					icon: 'settings',
					title: 'Edit',
					flags: 
				} );
				editButton.on( 'click', function() {
					editButton.setDisabled( true );
					openMap();
				} );
				var removeButton = new OO.ui.ButtonWidget( {
					label: mw.msg( 'wwl-button-remove' ),
					icon: 'remove',
					title: 'Remove',
					flags: 
				} );
				removeButton.on( 'click', function() {
					openRemoveDialog();
				} );
				buttonContainer.append( editButton.$element );
				buttonContainer.append( removeButton.$element );
			} else {
				var addButton = new OO.ui.ButtonWidget( {
					label: mw.msg( 'wwl-button-add' ),
					icon: 'add',
					title: 'Add',
					flags: 
				} );
				addButton.on( 'click', function() {
					addButton.setDisabled( true );
					openMap();
				} );
				buttonContainer.append( addButton.$element );
			}
		}

		function openRemoveDialog() {
			var messageDialog = new OO.ui.MessageDialog();
			var windowManager = new OO.ui.WindowManager();
			$( 'body' ).append( windowManager.$element );
			windowManager.addWindows(  );

			windowManager.openWindow( messageDialog, {
				title: mw.msg( 'wwl-dialog-remove-title' ),
				message: mw.msg( 'wwl-dialog-remove-message' ),
				size: 'medium',
				actions: [ {
					label: mw.msg( 'wwl-dialog-remove-button-cancel' ),
					action: 'cancel'
				},
									{
										label: mw.msg( 'wwl-dialog-remove-button-delete' ),
										action: 'delete',
										flags: 'destructive'
									},
								 ],
			} ).then( function( opened ) {
				opened.then( function( closing, data ) {
					if ( data && data.action == 'delete' ) {
						removeDataFromMap();
					}
				} );
			} );
		}

		function openMap() {
			var lat, lng, zoom;
			if ( userData === undefined ) {
				// Get the coordinates of the map
				lat = $( '#wwl-map .mw-kartographer-map' ).attr( 'data-lat' );
				lng = $( '#wwl-map .mw-kartographer-map' ).attr( 'data-lon' );
				zoom = $( '#wwl-map .mw-kartographer-map' ).attr( 'data-zoom' );
			} else {
				lat = userData.lat;
				lng = userData.lng;
				zoom = 12;
			}

			if ( map === undefined ) {
				// Create the map
				map = kartoBox.map( {
					container: $( '#wwl-map' ).empty().css( {
						height: 500
					} ),
					center: ,
					zoom: zoom,
					alwaysInteractive: true,
					//allowFullScreen: true, //TODO: allow full screen selection-map
				} );

				// Prepare the popup
				preparePopup();
				if ( userData !== undefined ) {
					marker.setLatLng(  ).addTo( map ).openPopup();
				}
			}
		}

		function generateGeoJSON( lat, lng, descriptions, wikis, color ) {
			return {
				"type": "Feature",
				"properties": {
					"marker-size": "small",
					"marker-color": color,
					"marker-symbol": "circle-stroked",
					"title": '<div style="margin-bottom: 5px;">' + username + '</div>',
					"description": descriptions
				},
				"geometry": {
					"type": "Point",
					"coordinates": [
						parseFloat( lng ),
						parseFloat( lat )
					]
				},
				"username": username,
				"data": wikis
			};
		}

		function createForm() {
			// Initialise all widgets and fieldsets
			var projectDropdown = new OO.ui.DropdownInputWidget( { classes: , options: Object.keys( siteMatrix ).map( function ( key ) { return siteMatrix; } ) } ).setValue( currentWiki.sitecode ),
					projectLangDropdown = new OO.ui.DropdownInputWidget( { classes: , options: ( siteMatrix.sites !== undefined ? siteMatrix.sites : siteMatrix.wiki.sites ) } ).setValue( currentWiki.langcode ),
					addWikiButton = new OO.ui.ButtonInputWidget( { label: mw.msg( 'wwl-form-button-add' ), flags:  } ),
					allWikisMultiselect = new OO.ui.TagMultiselectWidget( { allowArbitrary: true, allowEditTags: false, allowDuplicates: false, inputPosition: 'none' } ),
					descriptionLangDropdowns = ,
					descriptionInputs = ,
					addDescriptionLink = new OO.ui.ButtonWidget( { framed: false, flags: , label: mw.msg( 'wwl-form-link-new-translation' ) } ),
					wikisFieldset = new OO.ui.FieldsetLayout( { label: mw.msg( 'wwl-form-fieldset-wikis-title' ), classes:  } ),
					descriptionsFieldset = new OO.ui.FieldsetLayout( { label: mw.msg( 'wwl-form-fieldset-descriptions-title' ), classes:  } ),
					saveButton = new OO.ui.ButtonInputWidget( { label: mw.msg( 'wwl-form-button-save' ), flags:  } );


			// Add the widgets in the fieldsets
			wikisFieldset.addItems( [
				new OO.ui.FieldLayout(
					new OO.ui.Widget( { content: [ new OO.ui.HorizontalLayout( {
						items: 
					} ) ]
														} ),
					{
						label: mw.msg( 'wwl-form-fieldset-wikis-text' ),
						align: 'top'
					}
				),
				allWikisMultiselect
			] );
			descriptionsFieldset.addItems( [
				addDescriptionLink
			] );

			// Managing the addition of new descriptions
			function addDescriptionWidgets( lang, description ) {
				lang = lang || 'en';
				description = description || '';
				var descriptionLangDropdown = new OO.ui.DropdownInputWidget( { options: dropdownLanguages, classes:  } ).setValue( lang );
				var descriptionInput = new OO.ui.TextInputWidget( { placeholder: mw.msg( 'wwl-form-description-placeholder' ), multiline: true, value: '', classes:  } ).setValue( description );
				descriptionsFieldset.addItems( [
					new OO.ui.Widget( {
						content: [ new OO.ui.HorizontalLayout( {
							items: 
						} ) ]
					} ),
				], descriptionsFieldset.getItemCount() - 1 );

				descriptionLangDropdowns.push( descriptionLangDropdown );
				descriptionInputs.push( descriptionInput );
			}

			//Populate
			if ( userData !== undefined ) {
				$.each( userData.descriptions, function( lang, description ) {
					addDescriptionWidgets( lang, description.split( '<div class="wwl-projects">' ).replace( '<br>', '\n' ) );
				} );
				$.each( userData.projects, function( _, wiki ) {
					allWikisMultiselect.addTag( wiki.project + ',' + wiki.lang, wiki.lang + wiki.project );
				} );
			}
			else {
				addDescriptionWidgets();
			}

			// Manage the differents interactions and events with the widgets
			projectDropdown.on( 'change', function( project ) {
				projectLangDropdown.setOptions( ( siteMatrix.sites !== undefined ? siteMatrix.sites : siteMatrix.wiki.sites ) ).setValue( currentWiki.langcode );
			} );
			addWikiButton.on( 'click', function() {
				allWikisMultiselect.addTag( projectDropdown.getValue() + ',' + projectLangDropdown.getValue(), projectLangDropdown.getValue() + projectDropdown.getValue() );
			} );
			addDescriptionLink.on( 'click', addDescriptionWidgets );
			saveButton.on( 'click', function() {
				saveButton.setDisabled( true );
				mw.notify( mw.msg( 'wwl-notify-wait' ) );

				var wikis = {},
						descriptions = {},
						wikisDescription = '',
						color;

				$.each( allWikisMultiselect.getValue(), function( key, wiki ) {
					wiki = wiki.split( ',' );
					if ( key === 0 ) {
						color = siteMatrix ].color;
					}
					if ( wikis ] === undefined ) {
						wikis ] = ;
					}
					wikis ].push( wiki );
				} );
				$.each( wikis, function( project, langs ) {
					if ( siteMatrix.sites !== undefined ) {
						wikisDescription += '<br>\'\'\'' + siteMatrix.name + ':\'\'\' ';
						$.each( langs, function( key, lang ) {
							if ( key !== 0 ) {
								wikisDescription += ', ';
							}
							wikisDescription += '.shortcode + ':' + lang + ':User:' + username + '|' + lang + ']]';
						} );
					}
					else {
						wikisDescription += '<br>.shortcode + ':User:' + username + '|\'\'\'' + siteMatrix.name + '\'\'\']]';
					}
				} );

				$.each( descriptionInputs , function( key, _ ) {
					descriptions.getValue() ] = descriptionInputs.getValue().replace(/(\r\n|\n\r|\r|\n)/g, '<br>' )
				} );
				$.each( descriptions, function( key, _ ) {
					descriptions += '<div class="wwl-projects"><small>' + wikisDescription + '</small></div>';
				} );

				var geojson = generateGeoJSON( marker.getLatLng().lat.toFixed( 6 ), marker.getLatLng().lng.toFixed( 6 ), descriptions, wikis, color )
				if ( userData === undefined ) {
					addDataToMap( geojson );
				}
				else {
					editDataOnMap( geojson );
				}
			} );

			return $( '<div class="wwl-form">' ).append( wikisFieldset.$element ).append( descriptionsFieldset.$element ).append( saveButton.$element );
		}

		function preparePopup() {

			popup = L.popup( {
				minWidth: 465,
				className: ''
			} );

			popup.setContent( createForm() );

			marker = L.marker(, {
				icon: L.icon( {
					iconUrl: 'https://maps.wikimedia.org/v4/marker/pin-l-building+FFD700.png',
					iconSize: ,
					iconAnchor: ,
					popupAnchor: ,
				} )
			} ).bindPopup( popup );

			map.on( 'click', onMapClick );

		}

		function onMapClick( e ) {
			lat = e.latlng.lat;
			lng = e.latlng.lng;
			marker.setLatLng(  ).addTo( map ).openPopup();
		}

		function addDataToMap( geojson ) {
			api.edit( 'Data:Wikimedians.map', function ( revision ) {
				var content = JSON.parse( revision.content );
				content.data.features.push( geojson );
				return {
					text: JSON.stringify( content, null, 4 ),
					summary: 'Adding ' + username + ' to the map.',
					//tag: ''
				};
			} )
				.then( function () {
				mw.notify( mw.msg( 'wwl-notify-success-add' ) );
				onSaved();
			} )
				.fail( onFail );
		}

		function editDataOnMap( geojson ) {
			api.edit( 'Data:Wikimedians.map', function ( revision ) {
				var content = JSON.parse( revision.content );
				$.each( content.data.features, function( key, userContent ) {
					if ( userContent.username === username ) {
						content.data.features = geojson;
						return false;
					}
				} );
				return {
					text: JSON.stringify( content, null, 4 ),
					summary: 'Change informations of ' + username + '.',
					//tag: ''
				};
			} )
				.then( function () {
				mw.notify( mw.msg( 'wwl-notify-success-edit' ) );
				onSaved();
			} )
				.fail( onFail );
		}

		function removeDataFromMap() {
			api.edit( 'Data:Wikimedians.map', function ( revision ) {
				var content = JSON.parse( revision.content );
				$.each( content.data.features, function( key, userContent ) {
					if ( userContent.username === username ) {
						content.data.features.splice(key, 1);
						return false;
					}
				} );
				return {
					text: JSON.stringify( content, null, 4 ),
					summary: 'Removing ' + username + ' from the map.',
					//tag: ''
				};
			} )
				.then( function () {
				mw.notify( mw.msg( 'wwl-notify-success-remove' ) );
				onSaved();
			} )
				.fail( onFail );
		}

		function onSaved() {
			localApi.post( {
				action: 'purge',
				forcelinkupdate: '1',
				titles: mw.config.get( 'wgPageName' )
			} ).done( function( data ) {
				location.reload();
			} );
		}

		function onFail() {
			mw.notify( mw.msg( 'wwl-notify-error-save' ) );
			console.log( 'WhereWikimediansLive: Error while saving datas on commons.' );
			console.log( data );
		}

		if ( typeof wwlMessages !== 'undefined' ) {
			Object.assign( _wwlMessages, wwlMessages );
		}
		mw.messages.set( _wwlMessages );
		if ( userLanguage !== 'en' && userLanguage in _wwlMessages ) {
			mw.messages.set( _wwlMessages );
		}

		$( '#wwl-defaulttext' ).hide();
		$( '#wwl-gadgettext' ).show();
		getData();

	} );
}

//</nowiki>