انتقل إلى المحتوى

ميدياويكي:Gadget-AncreTitres.js

من ويكي مصدر، المكتبة الحرة

ملاحظة: بعد النشر، أنت قد تحتاج إلى إفراغ الكاش الخاص بمتصفحك لرؤية التغييرات.

  • فايرفوكس / سافاري: أمسك Shift أثناء ضغط Reload، أو اضغط على إما Ctrl-F5 أو Ctrl-R (⌘-R على ماك)
  • جوجل كروم: اضغط Ctrl-Shift-R (⌘-Shift-R على ماك)
  • إنترنت إكسبلورر/إيدج: أمسك Ctrl أثناء ضغط Refresh، أو اضغط Ctrl-F5
  • أوبرا: اضغط Ctrl-F5.
/**
 * AncreTitres
 * @source [[fr:Mediawiki:Gadget-AncreTitres.js]], [[fa:مدیاویکی:Gadget-AncreTitres.js]]
 * [[:ar:مستخدم:حبيشان]]
 * Cette fonction fournit un lien vers une section de page en cliquant
 * sur le lien [URL] ou [[lien]] à droite du titre de section.
 *
 * Auteurs : Pabix, Phe, Bayo, Chphe, Arkanosis, Mah3110, Ash_Crow
 * {{Projet:JavaScript/Script|AncreTitres}}
 */
mw.loader.using( [ 'mediawiki.util', 'user' ], function () {
	'use strict';

	var lang = mw.config.get( 'wgUserLanguage' ),
		skin = mw.config.get( 'skin' ),
		ns = mw.config.get( 'wgNamespaceNumber' ),
		nsIsTalk = (ns>-1) && (ns%2===1),
		messages = {
			en: {
				'ancretitres-anchor-name': '[URL]',
				'ancretitres-internal-link-name': '[[Link]]',
				'ancretitres-permanent-link-name': '[[Permalink]]',
				'ancretitres-description': 'Get an URL to this section',
				'ancretitres-int-description': 'Get an internal link to this section',
				'ancretitres-int-description': 'Get a permanent link to this section',
				'ancretitres-notif-title': 'Text copied to clipboard',
				'ancretitres-notif-error': 'Could not copy to clipboard'
			},
			ar: {
				'ancretitres-anchor-name': '[خارجي]',
				'ancretitres-internal-link-name': '[[وصلة]]',
				'ancretitres-permanent-link-name': '[[دائمة]]',
				'ancretitres-description': 'الحصول على رابط خارجي لهذا القسم',
				'ancretitres-int-description': 'الحصول على وصلة داخلية لهذا القسم',
				'ancretitres-permanent-description': 'الحصول على وصلة دائمة لهذا القسم',
				'ancretitres-notif-title': 'نُسِخ النص إلى الحافظة',
				'ancretitres-notif-error': 'تعذر النص إلى الحافظة'
			}
		},
		options = {
			'خارجي': true,
			'وصلة': true,
			'دائمة': true
		};

	mw.messages.set( messages.en );
	if ( lang !== 'en' && lang in messages ) {
		mw.messages.set( messages[ lang ] );
	}

	if ( typeof window['وصلات الأقسام'] !== 'undefined' ) {
		Object.assign( options, window['وصلات الأقسام'] );
	}

	if ( nsIsTalk && typeof window['وصلات الأقسام-نطاق نقاش'] !== 'undefined' ) {
		Object.assign( options, window['وصلات الأقسام-نطاق نقاش'] );
	}

	if ( typeof window['وصلات الأقسام-نطاق:' + ns] !== 'undefined' ) {
		Object.assign( options, window['وصلات الأقسام-نطاق:' + ns]);
	}

	if ( !options['خارجي'] && !options['وصلة'] && !options['دائمة'] ) {
		return;
	}

	mw.loader.addStyleTag( `
		.ancretitres {
			font-size: xx-small;
			font-weight: normal;
			-webkit-user-select: none; /* Safari */
			user-select: none;
		}
		body:not( .skin-minerva ) .ancretitres:not( .mw-editsection + .ancretitres ) {
			margin-inline-start: 0.5em;
		}
	` );

	mw.hook( 'wikipage.content' ).add( function ( $content ) {

		var $pageContent = getPageContent( $content );
		if ( !$pageContent ) {
			return;
		}

		// see: [[mw:Heading HTML changes]] and [[phab:T13555]]

		// regular headings (.mw-heading > hN)
		$pageContent.find( '.mw-heading' ).each( processRegularHeading );

		// raw headings (<hN> tags in wikicode, also in special pages)
		// (reminder: special pages have structure #mw-content-text > hN)
		// (caution: $pageContent.find( 'h2, h3, h4, h5, h6' ) has terrible performances, it seems to analyze all children)
		for ( var i = 2; i <= 6; ++i ) {
			var $rawHeadings = $pageContent
				.find( 'h' + i )
				.not( ( _, elm ) => elm.parentNode.matches( '.mw-heading' ) );

			// we also have to filter out the TOC heading <h2>...
			if ( i === 2 ) {
				$rawHeadings = $rawHeadings.not( '#mw-toc-heading' );
			}

			$rawHeadings.each( processRawHeading );
		}
	} );

	function getPageContent( $content ) {
		/*
		 * Sélection plus précise de l'élément avec le contenu de page,
		 * pour éviter l'interface de diff, l'interface de modification, le print footer...
		 */
		var $parserOutput = $content.find( '.mw-parser-output' );
		if ( $parserOutput.length ) { // élément avec le contenu de page
			return $parserOutput;
		} else if ( $content.hasClass( 'mw-parser-output' ) ) { // [[phab:T349298]]
			return $content;
		} else if ( mw.config.get( 'wgNamespaceNumber' ) === -1 ) { // on utilise #mw-content-text pour les pages spéciales
			return $content;
		} else { // pas de contenu de page (notamment, pages d'historiques)
			return false;
		}
	}

	function copyTextToClipboard( text ) {
		function notifySuccess() {
			mw.notify( text, { title: mw.msg( 'ancretitres-notif-title' ), tag: 'ancretitres', type: 'info', autoHide: true } );
		}

		function notifyError() {
			mw.notify( mw.msg( 'ancretitres-notif-error' ), { tag: 'ancretitres', type: 'error', autoHide: true } );
		}

		if ( navigator.clipboard ) {
			// Clipboard API
			navigator.clipboard.writeText( text ).then( notifySuccess, notifyError );
		} else {
			notifyError();
		}
	}

	function processRegularHeading( _, mwHeading ) {
		var innerHeading = mwHeading.querySelector( 'h2, h3, h4, h5, h6' );
		if ( !innerHeading ) {
			// first-level heading (which should not be used, and that we do not process to improve performance),
			// or unsuitable use of "mw-heading" class in wikicode
			return;
		}

		var sectionId = innerHeading.id;
		if ( !sectionId ) {
			return;
		}

		var gadgetLink = makeLink( sectionId );

		if ( skin !== 'minerva' ) {
			var editLink = mwHeading.querySelector( '.mw-editsection' );
			if ( editLink ) {
				editLink.after( gadgetLink );
				return;
			}
		}

		innerHeading.after( gadgetLink );
	}

	function processRawHeading( _, rawHeading ) {
		var sectionId = rawHeading.id;
		if ( !sectionId ) {
			return;
		}

		var gadgetLink = makeLink( sectionId );

		rawHeading.append( gadgetLink );
	}

	function makeLink( sectionId ) {
		var $span = $( '<span>' )
			.addClass( 'ancretitres noprint' );

		var sectionUrl = 'https://' + mw.config.get( 'wgServerName' ) + decodeURIComponent(mw.util.getUrl()) + '#' + sectionId;

		if ( options['خارجي'] ) {
			var $linkE = $( '<a>' )
				.attr( 'href', sectionUrl )
				.attr( 'title', mw.msg( 'ancretitres-description' ) )
				.text( mw.msg( 'ancretitres-anchor-name' ) )
				.click( function ( e ) {
					e.preventDefault();
					copyTextToClipboard( sectionUrl );
				} );
			$span.append( ' ', $linkE );
		}

		if ( options['وصلة'] ) {
			var $linkI = $( '<a>' )
				.attr( 'href', sectionUrl )
				.attr( 'title', mw.msg( 'ancretitres-int-description' ) )
				.text( mw.msg( 'ancretitres-internal-link-name' ) )
				.click( function ( e ) {
					e.preventDefault();
					var escapedAnchor = sectionId
						// escaping caractères spéciaux HTML
						// (partiel, '"& ne sont pas escapés pour ne pas dégrader inutilement la lisibilité du lien)
						.replaceAll( '<', '&lt;' )
						.replaceAll( '>', '&gt;' )
						// escaping caractères spéciaux MediaWiki
						.replaceAll( '[', '&#91;' )
						.replaceAll( ']', '&#93;' )
						.replaceAll( '{', '&#123;' )
						.replaceAll( '|', '&#124;' )
						.replaceAll( '}', '&#125;' );
					var outputText = '[[' + ( mw.config.get( 'wgPageName' ) + '#' + escapedAnchor ).replaceAll( '_', ' ' ) + ']]';
					copyTextToClipboard( outputText );
				} );
			$span.append( ' ', $linkI );
		}

		if ( options['دائمة'] && mw.config.get( 'wgRevisionId' )> 0) {
			var $linkP = $( '<a>' )
				.attr( 'href', sectionUrl )
				.attr( 'title', mw.msg( 'ancretitres-permanent-description' ) )
				.text( mw.msg( 'ancretitres-permanent-link-name' ) )
				.click( function ( e ) {
					e.preventDefault();
					var escapedAnchor = sectionId
						// escaping caractères spéciaux HTML
						// (partiel, '"& ne sont pas escapés pour ne pas dégrader inutilement la lisibilité du lien)
						.replaceAll( '<', '&lt;' )
						.replaceAll( '>', '&gt;' )
						// escaping caractères spéciaux MediaWiki
						.replaceAll( '[', '&#91;' )
						.replaceAll( ']', '&#93;' )
						.replaceAll( '{', '&#123;' )
						.replaceAll( '|', '&#124;' )
						.replaceAll( '}', '&#125;' );
					var outputText = '[[خاص:وصلة دائمة/' + mw.config.get( 'wgRevisionId' ) + '#' + ( escapedAnchor ).replaceAll( '_', ' ' ) + ']]';
					copyTextToClipboard( outputText );
				} );
			$span.append( ' ', $linkP );
		}
		return $span[ 0 ];
	}
} );