Участник:Stjn/unformat.js: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Содержимое удалено Содержимое добавлено
fix
более рекурсивная обработка подписей, h/t MBH
Строка 23: Строка 23:
ru: /^(?:Участни(к|ца)|Обсуждение участни(ка|цы)):.*/
ru: /^(?:Участни(к|ца)|Обсуждение участни(ка|цы)):.*/
}
}
// Check for valid parent targets
var inlineTags = [
var inlineTags = [
'font', 'span',
'font', 'span',
Строка 30: Строка 32:
'code', 'samp', 'tt'
'code', 'samp', 'tt'
]
]
function isValidParent( target ) {
return (
inlineTags.indexOf( target.tagName.toLowerCase() ) > -1
&& !target.classList.contains( 'mw-headline' )
);
}
// Pick a method for checking namespace names
// Pick a method for checking namespace names
Строка 76: Строка 84:
// Remove any styling from link itself
// Remove any styling from link itself
item.innerHTML = text;
item.innerHTML = text;
var parent = item.parentNode;
var parent = item.parentNode;
var isInline = ( inlineTags.indexOf( parent.tagName.toLowerCase() ) > -1 );
var ignoreHeadlines = !parent.classList.contains( 'mw-headline' );
// Remove parent of user link (probably) with styles
// Remove parents of user link (probably) with styles
if ( isInline && ignoreHeadlines ) {
while ( isValidParent( parent ) ) {
var parentText = parent.innerText || parent.textContent || parent.innerHTML;
var grandParent = parent.parentNode;
var parentText = ( parent.innerText || parent.textContent || parent.innerHTML ).trim();
if ( parentText.startsWith( text ) ) {
if ( parentText.startsWith( text.trim() ) ) {
// Replace an element with its children
var fr = document.createDocumentFragment();
var fr = document.createDocumentFragment();
while ( parent.firstChild ) {
while ( parent.firstChild ) {
fr.appendChild( parent.firstChild );
fr.appendChild( parent.firstChild );
}
}
parent.parentNode.replaceChild( fr, parent );
grandParent.replaceChild( fr, parent );
} else {
} else {
// Remove styling on elements without class and ID
// Remove styling on an element without class or ID
if ( parent.classList.length === 0 && parent.id === '' ) {
if ( parent.classList.length === 0 && parent.id === '' ) {
parent.removeAttribute( 'style' );
parent.removeAttribute( 'style' );
}
}
}
}
parent = grandParent;
}
}
}
}

Версия от 17:58, 4 октября 2021

/*
 * Unformat all (most) user links
 * 
 * Should not be used without a polyfill for startsWith in Internet Explorer
 * See if you need one:
 * https://polyfill.io/v3/polyfill.min.js?features=String.prototype.startsWith
*/
mw.hook( 'wikipage.content' ).add( function() {
	var mwConfig = mw.config.get( [
		'wgAction',
		'wgNamespaceNumber',
		'wgUserName',
		'wgContentLanguage',
		'wgFormattedNamespaces'
	] );
	if ( mwConfig[ 'wgNamespaceNumber' ] === -1 || mwConfig[ 'wgAction' ] === 'history' ) {
		return false;
	}
	
	// Support for languages with gendered namespaces
	var genderedNamespaceNames = {
		de: /^Benutzer(?:|in)(?: Diskussion):.*/,
		ru: /^(?:Участни(к|ца)|Обсуждение участни(ка|цы)):.*/
	}
	
	// Check for valid parent targets
	var inlineTags = [
		'font', 'span',
		'b', 'strong',
		'em', 'i',
		'small',
		'code', 'samp', 'tt'
	]
	function isValidParent( target ) {
		return (
			inlineTags.indexOf( target.tagName.toLowerCase() ) > -1
			&& !target.classList.contains( 'mw-headline' )
		);
	}
	
	// Pick a method for checking namespace names
	var testMethod = genderedNamespaceNames[ mwConfig.wgContentLanguage ];
	var testMethodContribs = '';
	if ( mwConfig[ 'wgUserName' ] !== null ) {
		// Hacky way to learn how Special:Contributions is called
		testMethodContribs = decodeURIComponent( document.querySelector( '#pt-mycontris > a' ).getAttribute( 'href' ) );
		testMethodContribs = testMethodContribs.replace( '/wiki/', '' )
			.replace( mwConfig[ 'wgUserName' ], '' );
	}
	if ( testMethod === undefined ) {
		testMethod = mwConfig.wgFormattedNamespaces;
	}
	function notUserLink( title ) {
		// Provide some fallback
		var notContribs = !title.startsWith( 'Special:Contributions/' );
		if ( testMethodContribs ) {
			notContribs = ( notContribs && !title.startsWith( testMethodContribs ) )
		}
		
		if ( testMethod[ 2 ] && testMethod[ 3 ] ) {
			var user = testMethod[ 2 ] + ':';
			var userTalk = testMethod[ 3 ] + ':';
			return (
				!title.startsWith( user )
				&& !title.startsWith( userTalk )
				&& notContribs
			);
		}
		
		return !testMethod.exec( title ) && notContribs;
	}
	
	var links = document.querySelectorAll( '.mw-parser-output a' );
	for ( var i = 0; i < links.length; i++ ) {
		var item = links[i];
		var title = item.getAttribute( 'title' );
		if ( !title ) continue;
		var text = item.innerText || item.textContent || item.innerHTML;
		
		if ( notUserLink( title ) ) {
			continue;
		}
		
		// Remove any styling from link itself
		item.innerHTML = text;
		var parent = item.parentNode;
		
		// Remove parents of user link (probably) with styles
		while ( isValidParent( parent ) ) {
			var grandParent = parent.parentNode;
			var parentText = ( parent.innerText || parent.textContent || parent.innerHTML ).trim();
			
			if ( parentText.startsWith( text.trim() ) ) {
				// Replace an element with its children
				var fr = document.createDocumentFragment();
				while ( parent.firstChild ) {
					fr.appendChild( parent.firstChild );
				}
				grandParent.replaceChild( fr, parent );
			} else {
				// Remove styling on an element without class or ID
				if ( parent.classList.length === 0 && parent.id === '' ) {
					parent.removeAttribute( 'style' );
				}
			}
			
			parent = grandParent;
		}
	}	
} );