Aller au contenu

MediaWiki:Gadget-PagesSansBandeauDePortail.js

Une page de Wikipédia, l'encyclopédie libre.
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;

Firefox (sur GNU/Linux) / Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.
/* {{Catégorisation JS|PagesSansBandeauDePortail}} */

// Documentation : [[Projet:Articles sans portail/intro]]

/* eslint-env browser */
/* jshint esversion: 8 */
/* globals mw, $ */
// <syntaxhighlight lang=javascript><pre><nowiki>

const PagesSansBandeauDePortail_GoodPages = 'Projet:Articles_sans_portail/';
const PagesSansBandeauDePortail_BadPages = 'Projet:Articles_sans_portail/intro';


const PagesSansBandeauDePortail_WorkingImage = '/media/wikipedia/commons/d/de/Ajax-loader.gif';

const PagesSansBandeauDePortail_Modeles = [];
const PagesSansBandeauDePortail_Images = [];

PagesSansBandeauDePortail_Modeles.push( '[[File:Yes check.svg|15px|Fait|link=]]' );
PagesSansBandeauDePortail_Images.push( '<img height="15" width="15" src="/media/wikipedia/commons/thumb/f/fb/Yes_check.svg/15px-Yes_check.svg.png" alt="Fait">');

PagesSansBandeauDePortail_Modeles.push( '[[File:Disambig.png|15px|Homonymie|link=]]' );
PagesSansBandeauDePortail_Images.push( '<img height="11" width="15" src="/media/wikipedia/commons/thumb/6/69/Disambig.png/15px-Disambig.png" alt="Disambig.png">' );

const PagesSansBandeauDePortail_Api = new mw.Api( { userAgent: 'PagesSansBandeauDePortail/1.0' } );


function PagesSansBandeauDePortail_AddNavigLinks() {
	let Content = document.getElementById( 'bodyContent' );					// monobook, myskin, chick, simple, vector
	if ( !Content ) Content = document.getElementById( 'article' );			// cologneblue, nostalgia, standard
	if ( !Content ) Content = document.getElementById( 'mw_contentholder' );// modern
	if ( !Content ) return;

	let ThisPage = false;
	const TDs = Content.getElementsByTagName( 'td' );
	for( const TD of TDs ) {
		if ( TD.classList.contains( 'list' ) ) {
			const Strongs = TD.getElementsByTagName( 'strong' );
			for( const strong of Strongs ) {
				if ( strong.classList.contains( 'selflink' ) ) {
					ThisPage = strong;
				}
			}
		}
	}
	if ( !ThisPage ) return;

	let PreviousPage = false;
	let Node = ThisPage.previousSibling;
	while ( Node ) {
		if ( Node.tagName && Node.tagName.toLowerCase() === 'a' ) {
			PreviousPage = Node;
			break;
		}
		Node = Node.previousSibling;
	}

	let NextPage = false;
	Node = ThisPage.nextSibling;
	while ( Node ) {
		if ( Node.tagName && Node.tagName.toLowerCase() === 'a' ) {
			NextPage = Node;
			break;
		}
		Node = Node.nextSibling;
	}
	let PreviousLink = '';
	if ( PreviousPage ) {
		PreviousLink = '<a href="' + PreviousPage.href + '" title="' + PreviousPage.title + '">Page précédente : ' + PreviousPage.innerHTML + '</a>';
	}
	let NextLink = '';
	if ( NextPage ) {
		NextLink = '<a href="' + NextPage.href + '" title="' + NextPage.title + '">Page suivante : ' + NextPage.innerHTML + '</a>';
	}
	const Tables = document.getElementsByTagName( 'table' );
	for ( const table of Tables ) {
		if ( table.classList.contains( 'navbox' ) ) {
			const TitleLinks = table.getElementsByTagName( 'th' )[ 0 ].getElementsByTagName( 'a' );
			const TitleDiv = TitleLinks[ ( TitleLinks.length - 1 ) ].parentNode;
			TitleDiv.innerHTML = '<small>(' + PreviousLink + ')</small>&nbsp;&nbsp;—&nbsp;&nbsp;' + TitleDiv.innerHTML + '&nbsp;&nbsp;—&nbsp;&nbsp;<small>(' + NextLink+')</small>';
		}
	}
}

const PagesSansBandeauDePortail_AllLinks = [];

function PagesSansBandeauDePortail_AddLinks() {
	let Content = document.getElementById( 'bodyContent' );					// monobook, myskin, chick, simple, vector
	if ( !Content ) Content = document.getElementById( 'article' );			// cologneblue, nostalgia, standard
	if ( !Content ) Content = document.getElementById( 'mw_contentholder' );// modern
	if ( !Content ) return;
	document.body.classList.add( 'PagesSansBandeauDePortail' );
	let Count = -1;
	const Liste = Content.getElementsByTagName( 'li' );
	for ( const li of Liste) {
		let Lien = li.getElementsByTagName( 'a' )[ 0 ];
		if ( !Lien ) continue;
		if ( decodeURIComponent( Lien.href ).indexOf( mw.config.get( 'wgFormattedNamespaces' )[ 6 ] + ":" ) !== -1 ) Lien = li.getElementsByTagName( 'a' )[ 1 ];   
		if ( !Lien ) continue;
		if ( Lien.href.indexOf( '#' ) === -1 && Lien.className !== 'new' && Lien.parentNode.tagName.toLowerCase() !== 's' && Lien.href.indexOf( 'javascript:' ) === -1) {
			Count++;
			PagesSansBandeauDePortail_AllLinks.push( Lien );
			Lien.id = 'Link_' + Count;
			Lien.classList.add( 'LinkWithButtons' );
			const SpanLinks = document.createElement( 'span' );
			SpanLinks.className = 'SpanLinks';
			Lien.before( SpanLinks, Lien );

			const PreviewButton = document.createElement( 'button' );
			PreviewButton.style.cssText = 'border: none; padding: 0; background: none; cursor: pointer;';
			PreviewButton.title = 'Previsualiser la page';
			PreviewButton.innerHTML = '<img height="15" width="15" src="/media/wikipedia/commons/thumb/6/61/Crystal_Clear_app_kappfinder.png/15px-Crystal_Clear_app_kappfinder.png" alt="Prévisualiser">';
			( function( count ) {
				PreviewButton.addEventListener( 'click', () => PagesSansBandeauDePortail_Preview( count ) );
				PreviewButton.addEventListener( 'keydown', ( event ) => {
					if ( event.key === 'Enter' ) PagesSansBandeauDePortail_Preview( count );
				});
			})( Count );
			SpanLinks.append( PreviewButton );
		}
	}
	const Spans = document.querySelectorAll( 'span.mw-editsection' );
	for ( const span of Spans ) {
		const Section = span.getElementsByTagName( 'a' )[ 0 ].href.split( 'section=' )[ 1 ];
		const UpdateAllLink = '<a href="javascript:PagesSansBandeauDePortail_UpdateAll(' + Section + ');" title="Marquer comme faites les pages de cette section ayant un bandeau de portail">[mettre à jour]</a>';

		span.innerHTML += '&nbsp;' + UpdateAllLink;
		span.id = 'editsection_' + Section;
	}
}


function PagesSansBandeauDePortail_Done( index, modeleIndex ) {
	const Lien = document.getElementById( 'Link_' + index );
	if ( !Lien ) return;
	const Page = PagesSansBandeauDePortail_HTMLDecode( Lien.innerHTML );
	PagesSansBandeauDePortail_Edit( Page, modeleIndex, index );
}

// Détermination de la hauteur de l'écran
 
function PagesSansBandeauDePortail_GetScreenHeight() {
	let ScreenHeight = 0;
	if ( typeof innerHeight === 'number' ) {
		ScreenHeight = parseInt( innerHeight );
	} else if ( document.documentElement && document.documentElement.clientHeight ) {
		ScreenHeight = parseInt( document.documentElement.clientHeight );
	} else if ( document.body && document.body.clientHeight ) {
		ScreenHeight = parseInt( document.body.clientHeight );
	}
	return ScreenHeight;
}
 
// Détermination de la largeur de l'écran
 
function PagesSansBandeauDePortail_GetScreenWidth() {
	let ScreenWidth = 0;
	if ( typeof innerWidth === 'number' ) {
		ScreenWidth = parseInt( innerWidth );
	} else if ( document.documentElement && document.documentElement.clientWidth ) {
		ScreenWidth = parseInt( document.documentElement.clientWidth );
	} else if ( document.body && document.body.clientWidth ) {
		ScreenWidth = parseInt( document.body.clientWidth );
	}
	return ScreenWidth;
}


function PagesSansBandeauDePortail_Preview( index ) {
	const Lien = document.getElementById( 'Link_' + index );
	if ( !Lien ) return;
	const Href = Lien.href;
	let Frame = document.getElementById( 'Frame_' + index );
	if ( !Frame ) { 
		const LargeurEcran = PagesSansBandeauDePortail_GetScreenWidth();
		const HauteurEcran = PagesSansBandeauDePortail_GetScreenHeight();
		const Parent = Lien.parentNode;
		Frame = document.createElement( 'div' );
		Frame.id = 'Frame_' + index;
		Parent.append( Frame );
		Frame.style.position = 'fixed';
		Frame.style.zIndex = 1000;
		Frame.style.width = '75%';
		PositionGauche = parseInt( ( LargeurEcran - Frame.clientWidth ) / 2 ) ;
		PositionHaut = parseInt( ( HauteurEcran - Frame.clientHeight ) / 5 ) ;
		Frame.style.left = PositionGauche + 'px';
		Frame.style.top = PositionHaut + 'px';
		Frame.style.backgroundColor = 'white';
		Frame.style.border = '3px double black';

		const TopBar = document.createElement( 'div' );
		TopBar.className = 'TopBarDiv';
		const CloseButton = document.createElement( 'button' );
		CloseButton.style.cssText = 'border: none; padding: 0; background: none; cursor: pointer; float:right;';
		CloseButton.title = 'Fermer la fenêtre';
		CloseButton.innerHTML = '<img height="30" width="30" src="/media/wikipedia/commons/thumb/2/2e/Crystal_Clear_action_button_cancel.png/30px-Crystal_Clear_action_button_cancel.png" alt="Fermer">';
		CloseButton.addEventListener( 'click', () => PagesSansBandeauDePortail_EndPreview( index ) );
		CloseButton.addEventListener( 'keydown', ( event ) => {
			if ( event.key === 'Enter' ) PagesSansBandeauDePortail_EndPreview( index );
		});
		TopBar.append( CloseButton );

		const CenterTag = document.createElement( 'center' );
		TopBar.append( CenterTag );

		const DoneButton = document.createElement( 'button' );
		DoneButton.style.cssText = 'border: none; padding: 0; background: none; cursor: pointer;';
		DoneButton.title = 'Marquer comme fait';
		DoneButton.innerHTML = '<img height="30" width="30" src="/media/wikipedia/commons/thumb/4/47/Done.png/30px-Done.png" alt="Fait">';
		DoneButton.addEventListener( 'click', () => PagesSansBandeauDePortail_Done( index, 0 ) );
		DoneButton.addEventListener( 'keydown', ( event ) => {
			if ( event.key === 'Enter' ) PagesSansBandeauDePortail_Done( index, 0 );
		});

		const HomonDoneButton = document.createElement( 'button' );
		HomonDoneButton.style.cssText = 'border: none; padding: 0; background: none; cursor: pointer;';
		HomonDoneButton.title = 'Marquer comme page d\'homonymie';
		HomonDoneButton.innerHTML = '<img height="30" width="30" src="/media/wikipedia/commons/thumb/6/69/Disambig.png/30px-Disambig.png" alt="Fait : homonymie">';
		HomonDoneButton.addEventListener( 'click', () => PagesSansBandeauDePortail_Done( index, 1 ) );
		HomonDoneButton.addEventListener( 'keydown', ( event ) => {
			if ( event.key === 'Enter' ) PagesSansBandeauDePortail_Done( index, 1 );
		});
		CenterTag.append( DoneButton, ' - ', HomonDoneButton );
		Frame.append( TopBar );
		TopBar.onmousedown = function( event ) {
			monbody = document.body;
			positionSouris_X = parseInt( event.clientX );
			positionSouris_Y = parseInt( event.clientY );

			Frame.initialX = parseInt( positionSouris_X - Frame.offsetLeft );
			Frame.initialY = parseInt( positionSouris_Y - Frame.offsetTop );
			monbody.onmousemove = function( event ) {
				positionSouris_X = parseInt( event.clientX );
				positionSouris_Y = parseInt( event.clientY );
				PositionGauche = parseInt( positionSouris_X ) - Frame.initialX;
				PositionHaut = parseInt( positionSouris_Y ) - Frame.initialY;
				if ( PositionGauche < 0) {
					PositionGauche = 0;
				}
				if ( PositionHaut < 0) {
					PositionHaut = 0;
				}
				Frame.style.left = PositionGauche + 'px';
				Frame.style.top = PositionHaut + 'px';
				Frame.style.opacity = '.8';
			};

			monbody.onmouseup = function( event ) {
				Frame.style.opacity = '';
				monbody.onmousemove = null;
				monbody.onmouseup = null;
			};
		};

		const FrameContent = document.createElement( 'iframe' );
		FrameContent.src = Href;
		FrameContent.width = '100%';
		FrameContent.height = parseInt( HauteurEcran / 2 ) + 'px';
		Frame.append( FrameContent );
		const BottomBar = document.createElement( 'div' );
		BottomBar.style.height = '30px';
		BottomBar.style.cursor='se-resize';
		BottomBar.onmousedown = function( event ) {
			monbody = document.body;
			positionSouris_X = parseInt( event.clientX );
			positionSouris_Y = parseInt( event.clientY );
			FrameContent.initialWidth = parseInt( positionSouris_X - FrameContent.offsetWidth );
			FrameContent.initialHeight = parseInt( positionSouris_Y - FrameContent.offsetHeight );
			Frame.initialWidth = parseInt( positionSouris_X - Frame.offsetWidth );
			Frame.initialHeight = parseInt( positionSouris_Y - Frame.offsetHeight );
			Frame.style.opacity = '.8';
	  
			monbody.onmousemove = function( event ) {
				positionSouris_X = parseInt( event.clientX );
				positionSouris_Y = parseInt( event.clientY );
				FrameContent.width  = parseInt( positionSouris_X - FrameContent.initialWidth  ) + 'px';
				FrameContent.height = parseInt( positionSouris_Y - FrameContent.initialHeight ) + 'px';
				Frame.style.width  = parseInt( positionSouris_X - Frame.initialWidth  ) + 'px';
				Frame.style.height = parseInt( positionSouris_Y - Frame.initialHeight ) + 'px';

			};
			monbody.onmouseup = function( event ) {
				Frame.style.opacity = '';
				monbody.onmousemove = null;
				monbody.onmouseup = null;
			};
		};
		Frame.append( BottomBar );
		Parent.append( Frame );
	}
}

function PagesSansBandeauDePortail_EndPreview( index ) {
	const Frame = document.getElementById( 'Frame_' + index );
	if ( Frame ) Frame.remove();
}

function PagesSansBandeauDePortail_HTMLDecode( text ) {
	const DecodedCharacters = {
		'&amp;': '&',
		'&#039;': "'",
		'&quot;': '"',
		'&nbsp;': ' '
	};

	for ( const [ encodedCharacter, decodedCharacter ] of Object.entries( DecodedCharacters ) ) {
		text = text.replaceAll( encodedCharacter, decodedCharacter );
	}
	return text;
}

async function PagesSansBandeauDePortail_Edit( Page, ModeleIndex, index ) {
	PagesSansBandeauDePortail_EndPreview( index );
	const Image = document.createElement( 'img' );
	Image.id = 'Working_Image' + index;
	Image.src = PagesSansBandeauDePortail_WorkingImage;
	Image.width = 50;
	Image.heigth = 50;
	Image.style.position = 'fixed';
	Image.style.zIndex = 10000;
	Image.style.top = 0;
	Image.style.right = 0;
	document.body.prepend( Image );

	await PagesSansBandeauDePortail_Api.edit( mw.config.get( 'wgPageName' ), function ( revision ) {
		const ContenuPage = revision.content;
		const AncienLien = '[[' + Page + ']]';
		const NouvelleLigne = '<li>' + PagesSansBandeauDePortail_Modeles[ ModeleIndex ] + '&nbsp;<s>[[' + Page + ']]</s></li>';
		const Lines = ContenuPage.split( '\n' );
		for ( let a = 0; a < Lines.length; a++ ) {
			const ThisLine = Lines[ a ];
			if ( ThisLine.indexOf( AncienLien ) !== -1 ) {
				for ( let b = 0; b < PagesSansBandeauDePortail_Modeles.length; b++ ) {
					if ( ThisLine.indexOf( PagesSansBandeauDePortail_Modeles[ b ] ) !== -1 ) {
						ModeleIndex = b;
						PagesSansBandeauDePortail_EditOK( index, ModeleIndex );
						return;
					}
				}
				Lines[ a ] = NouvelleLigne;
			}
		}
		const NouveauContenuPage = Lines.join( '\n' );
		const NouveauSommaire = 'Mise à jour : - [[' + Page + ']]';
		return {
			text: NouveauContenuPage,
			summary: NouveauSommaire,
			minor: true,
			watchlist: 'nochange'
		};
	});
	PagesSansBandeauDePortail_EditOK(index, ModeleIndex);
}

function PagesSansBandeauDePortail_EditOK( index, ModeleIndex ) {
	const EditDiv = document.getElementById( 'EditPage_' + index );
	if ( EditDiv ) EditDiv.remove();
	const WorkingImage = document.getElementById( 'Working_Image' + index );
	if ( WorkingImage ) WorkingImage.remove();

	const Link = document.getElementById( 'Link_' + index );
	if ( Link ) {
		const Modele = PagesSansBandeauDePortail_Images[ ModeleIndex ];
		const Li = Link.parentNode;
		const Span = Li.getElementsByTagName( 'span' )[ 0 ];
		Link.remove();
		const Barre = document.createElement( 's' );
		Barre.append( Link );
		Li.innerHTML = Modele + '&nbsp;';
		Li.append( Barre );
	}
}




let PagesSansBandeauDePortail_UpdateIsRunning = false;

async function PagesSansBandeauDePortail_UpdateAll( Section ) {
	if ( PagesSansBandeauDePortail_UpdateIsRunning ) return;
	const PagesSansBandeauDePortail_AllLinksTitle = [];
	const SousTitre = document.getElementById( 'editsection_' + Section ).parentNode;
	let Node = SousTitre.nextSibling;
	let FoundNode = false;
	while( Node && !FoundNode ) {
		if ( Node.tagName ) {
			if ( Node.tagName.toLowerCase().indexOf( 'h') !== -1 ) break;
			if ( Node.tagName.toLowerCase().indexOf( 'ol' ) !== -1 && !FoundNode ) {
				FoundNode = Node;
				break;
			}
		}
		Node = Node.nextSibling;
	}
	const AllLinks = Node.getElementsByTagName( 'a' );
	for ( const link of AllLinks) {
		if ( link.classList.contains( 'LinkWithButtons' ) ) {
			if ( link.parentNode.tagName.toLowerCase() !== 's' ) {
				let Title = link.title;
				if ( !Title ) Title = PagesSansBandeauDePortail_HTMLDecode( link.innerHTML );
				PagesSansBandeauDePortail_AllLinksTitle.push( Title );
			}
		}
	}
	const Conf = confirm( 'Nombre de pages à vérifier : ' + PagesSansBandeauDePortail_AllLinksTitle.length );
	if ( PagesSansBandeauDePortail_AllLinksTitle.length === 0 || !Conf ) return;
	const Image = document.createElement( 'img' );
	Image.id = 'Working_Image';
	Image.src = PagesSansBandeauDePortail_WorkingImage;
	Image.width = 50;
	Image.heigth = 50;
	Image.style.position = 'fixed';
	Image.style.zIndex = 10000;
	Image.style.top = 0;
	Image.style.right = 0;
	document.body.prepend( Image );
	PagesSansBandeauDePortail_UpdateIsRunning = true;

	const TitleList = PagesSansBandeauDePortail_AllLinksTitle;
	if ( TitleList.length === 0 ) return;

	const batches = [];
	for ( let i = 0; i < TitleList.length; i += 50 ) {
		batches.push( TitleList.slice( i, i + 50 ) );
	}

	const TitleChecked = {};
	await Promise.all(
		batches.map( async ( batch, i ) => {
			const data = await PagesSansBandeauDePortail_Api.get({
				action: 'query',
				titles: batch,
				prop: 'templates',
				tltemplates: 'Modèle:Méta lien vers portail',
				tllimit: 500,
				formatversion: 2
			});
			data.query.pages.forEach( page => TitleChecked[ page.title ] = 'templates' in page );
		})
	);

	PagesSansBandeauDePortail_UpdateEdit( Section, TitleChecked );
}

async function PagesSansBandeauDePortail_UpdateEdit( Section, TitleChecked ) {
	const data = await PagesSansBandeauDePortail_Api.get({
		action: 'query',
		titles: mw.config.get( 'wgPageName' ),
		prop: 'revisions',
		rvprop: 'content',
		rvslots: 'main',
		rvsection: Section,
		formatversion: 2
	});
	const ContenuSection = data.query.pages[ 0 ].revisions[ 0 ].slots.main.content;
	const Lines = ContenuSection.split( '\n' );
	for ( let a = 0; a < Lines.length; a++ ) {
		const ThisLine = Lines[ a ];
		for ( const title of Object.keys( TitleChecked ) ) {
			const OldLink = '[[' + title + ']]';
			if ( ThisLine.indexOf( OldLink ) !== -1 ) {
				const WithPortal = TitleChecked[ title ];
				if ( WithPortal ) {
					Lines[ a ] = '<li>' + PagesSansBandeauDePortail_Modeles[ 0 ] +' <s>[[' + title + ']]</s></li>';
				}
			}
		}
	}
	const NouveauContenuSection = Lines.join( '\n' );
	const Sommaire = 'Mise à jour globale';
	await PagesSansBandeauDePortail_Api.postWithEditToken({
		action: 'edit',
		title: mw.config.get( 'wgPageName' ),
		section: Section,
		text: NouveauContenuSection,
		summary: Sommaire,
		minor: true,
		watchlist: 'nochange'
	});
	PagesSansBandeauDePortail_UpdateFinish( TitleChecked );
}

function PagesSansBandeauDePortail_UpdateFinish( TitleChecked ) {
	for ( const title of Object.keys( TitleChecked ) ) {
		if ( TitleChecked[ title ] ) {
			for ( let b = 0; b < PagesSansBandeauDePortail_AllLinks.length; b++ ) {
				const LinkTitle = PagesSansBandeauDePortail_HTMLDecode( PagesSansBandeauDePortail_AllLinks[ b ].innerHTML );
				if ( LinkTitle === title ) PagesSansBandeauDePortail_EditOK( b, 0 );
			}
		}
	}
	const EditPage = document.getElementById( 'EditPage' );
	if ( EditPage ) EditPage.remove();
	const Working = document.getElementById( 'Working_Image' );
	if ( Working ) Working.remove();
	PagesSansBandeauDePortail_UpdateIsRunning = false;
}


if ( mw.config.get( 'wgPageName' ).indexOf( PagesSansBandeauDePortail_GoodPages ) !== -1 && mw.config.get( 'wgPageName' ).indexOf( PagesSansBandeauDePortail_BadPages ) === -1 && mw.config.get( 'wgAction' ) === 'view' ) {
	mw.loader.load( '//fr.wikipedia.org/w/index.php?title=MediaWiki:Gadget-PagesSansBandeauDePortail.css&action=raw&ctype=text/css', 'text/css' );
	mw.loader.using( [ 'mediawiki.api' ], function () {
		$( PagesSansBandeauDePortail_AddNavigLinks );
		$( PagesSansBandeauDePortail_AddLinks );
	} );
}

//</nowiki></pre></syntaxhighlight>