مدیاویکی:Common.js

ویکی‌پدیا، آزادِ دانشنومه، جه

نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.

  • فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلید‌های Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-R)
  • گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانه‌های اپل مکینتاش کلید‌های ⌘-Shift-R)
  • اینترنت اکسپلورر/ Edge: کلید Ctrl را نگه‌دارید و روی دکمهٔ Refresh کلیک کنید، یا کلید‌های Ctrl-F5 را با هم فشار دهید
  • اپرا: Ctrl-F5 را بفشارید.
//<nowiki>

/**
 * @source https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
 * @revision 2020-04-04
 */
mw.loader.using( ['mediawiki.util'], function () {
	var extraCSS = mw.util.getParamValue( 'withCSS' ),
		extraJS = mw.util.getParamValue( 'withJS' );

	if ( extraCSS ) {
		// WARNING: DO NOT REMOVE THIS "IF" - REQUIRED FOR SECURITY (against XSS/CSRF attacks)
		if ( /^MediaWiki:[^&<>=%#]*\.css$/.test( extraCSS ) ) {
			mw.loader.load( '/w/index.php?title=' + encodeURIComponent( extraCSS ) + '&action=raw&ctype=text/css', 'text/css' );
		} else {
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withCSS value' } );
		}
	}

	if ( extraJS ) {
		// WARNING: DO NOT REMOVE THIS "IF" - REQUIRED FOR SECURITY (against XSS/CSRF attacks)
		if ( /^MediaWiki:[^&<>=%#]*\.js$/.test( extraJS ) ) {
			mw.loader.load( '/w/index.php?title=' + encodeURIComponent( extraJS ) + '&action=raw&ctype=text/javascript' );
		} else {
			mw.notify( 'Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' } );
		}
	}
});


/** Collapsible tables *********************************************************
 *
 *  Description: Allows tables to be collapsed, showing only the header. See
 *               [[Wikipedia:NavFrame]].
 *  Maintainers: [[User:R. Koot]]
 */
var autoCollapse = 2;
var collapseCaption = "دَوِستِن";
var expandCaption = "دیار هاکِن";
 
function collapseTable( tableIndex )
{
    var Button = document.getElementById( "collapseButton" + tableIndex );
    var Table = document.getElementById( "collapsibleTable" + tableIndex );
 
    if ( !Table || !Button ) {
        return false;
    }
 
    var Rows = Table.rows;
 
    if ( Button.firstChild.data == collapseCaption ) {
        for ( var i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = "none";
        }
        Button.firstChild.data = expandCaption;
    } else {
        for ( var i = 1; i < Rows.length; i++ ) {
            Rows[i].style.display = Rows[0].style.display;
        }
        Button.firstChild.data = collapseCaption;
    }
}
 
function createCollapseButtons() {
    var tableIndex = 0;
    var NavigationBoxes = {};
    var Tables = document.getElementsByTagName( 'table' );
    var i;

    function handleButtonLink( index, e ) {
        window.collapseTable( index );
        e.preventDefault();
    }

    for ( i = 0; i < Tables.length; i++ ) {
        if ( $( Tables[i] ).hasClass( 'collapsible' ) ) {

            /* only add button and increment count if there is a header row to work with */
            var HeaderRow = Tables[i].getElementsByTagName( 'tr' )[0];
            if ( !HeaderRow ) continue;
            var Header = HeaderRow.getElementsByTagName( 'th' )[0];
            if ( !Header ) continue;

            NavigationBoxes[ tableIndex ] = Tables[i];
            Tables[i].setAttribute( 'id', 'collapsibleTable' + tableIndex );

            var Button     = document.createElement( 'span' );
            var ButtonLink = document.createElement( 'a' );
            var ButtonText = document.createTextNode( collapseCaption );

            Button.className = 'collapseButton';  /* Styles are declared in Common.css */

            ButtonLink.style.color = Header.style.color;
            ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
            ButtonLink.setAttribute( 'href', '#' );
            $( ButtonLink ).on( 'click', $.proxy( handleButtonLink, ButtonLink, tableIndex ) );
            ButtonLink.appendChild( ButtonText );

            Button.appendChild( document.createTextNode( '[' ) );
            Button.appendChild( ButtonLink );
            Button.appendChild( document.createTextNode( ']' ) );

            Header.insertBefore( Button, Header.firstChild );
            tableIndex++;
        }
    }

    for ( i = 0;  i < tableIndex; i++ ) {
        if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) || ( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) ) ) {
            window.collapseTable( i );
        } 
        else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) {
            var element = NavigationBoxes[i];
            while ((element = element.parentNode)) {
                if ( $( element ).hasClass( 'outercollapse' ) ) {
                    window.collapseTable ( i );
                    break;
                }
            }
        }
    }
}

$(createCollapseButtons);

/** Dynamic Navigation Bars (experimental) *************************************
 *
 *  Description: See [[Wikipedia:NavFrame]].
 *  Maintainers: UNMAINTAINED
 */
 
// set up the words in your language
var NavigationBarHide = '[' + collapseCaption + ']';
var NavigationBarShow = '[' + expandCaption + ']';
 
// shows and hides content and picture (if available) of navigation bars
// Parameters:
//     indexNavigationBar: the index of navigation bar to be toggled
window.toggleNavigationBar = function ( indexNavigationBar, event ) {
    var NavToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
    var NavFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
    var NavChild;
 
    if ( !NavFrame || !NavToggle ) {
        return false;
    }
 
    /* if shown now */
    if ( NavToggle.firstChild.data === NavigationBarHide ) {
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
                NavChild.style.display = 'none';
            }
        }
    NavToggle.firstChild.data = NavigationBarShow;
 
    /* if hidden now */
    } else if ( NavToggle.firstChild.data === NavigationBarShow ) {
        for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
            if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
                NavChild.style.display = 'block';
            }
        }
        NavToggle.firstChild.data = NavigationBarHide;
    }
 
    event.preventDefault();
};
 
/* adds show/hide-button to navigation bars */
function createNavigationBarToggleButton() {
    var indexNavigationBar = 0;
    var NavFrame;
    var NavChild;
    /* iterate over all < div >-elements */
    var divs = document.getElementsByTagName( 'div' );
    for ( var i = 0; (NavFrame = divs[i]); i++ ) {
        /* if found a navigation bar */
        if ( $( NavFrame ).hasClass( 'NavFrame' ) ) {
 
            indexNavigationBar++;
            var NavToggle = document.createElement( 'a' );
            NavToggle.className = 'NavToggle';
            NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
            NavToggle.setAttribute( 'href', '#' );
            $( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );
 
            var isCollapsed = $( NavFrame ).hasClass( 'collapsed' );
            /**
             * Check if any children are already hidden.  This loop is here for backwards compatibility:
             * the old way of making NavFrames start out collapsed was to manually add style="display:none"
             * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
             * the content visible without JavaScript support), the new recommended way is to add the class
             * "collapsed" to the NavFrame itself, just like with collapsible tables.
             */
            for ( NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling ) {
                if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
                    if ( NavChild.style.display === 'none' ) {
                        isCollapsed = true;
                    }
                }
            }
            if ( isCollapsed ) {
                for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
                    if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
                        NavChild.style.display = 'none';
                    }
                }
            }
            var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide );
            NavToggle.appendChild( NavToggleText );
 
            /* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */
            for( var j = 0; j < NavFrame.childNodes.length; j++ ) {
                if ( $( NavFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
                    NavToggle.style.color = NavFrame.childNodes[j].style.color;
                    NavFrame.childNodes[j].appendChild( NavToggle );
                }
            }
            NavFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
        }
    }
}
 
$(createNavigationBarToggleButton);

// ==============================
// Force IP to preview before saving changes.
// Copyright Marc Mongenet, 2006
function forcePreview() {
    if (mw.config.get('wgUserName') != null) return;
    if (document.getElementById('editpage-copywarn')) {
        var saveButton = document.getElementById("wpSave");
        var oldHTML = document.getElementById('editpage-copywarn').innerHTML;
        var newHTML = oldHTML + '<p style="width:100%;background-color:#FFE4E1;border:2px solid #700050; color:#000000; font-size:90%; padding:2px;">&nbsp;با <a href="//mzn.wikipedia.org/w/index.php?title=وپ:نام">کاروری نوم </a>  دله بیین یا فعال بیّن وسّه «جاءدکتن» دکمه ره بزنین، بتونّی اول پیش‌نمایش جه هم استفاده هاکنین.</p>';
        if (!saveButton) return;
        if (location.search.search(/&action=edit/) == -1) return;
        document.getElementById('editpage-copywarn').innerHTML = newHTML;
        saveButton.disabled = true;
        saveButton.style.fontWeight = "normal";
        document.getElementById("wpPreview").style.fontWeight = "bold";
    }
}
$(forcePreview);

/** Main Page layout fixes
 *
 *  Description: Adds an additional link to the complete list of languages available.
 *  Maintainers: [[User:AzaToth]], [[User:R. Koot]], [[User:Alex Smotrov]]
 */
if (mw.config.get('wgIsMainPage') || mw.config.get('wgPageName') == 'گپ:گت_صفحه') {
  mw.loader.using(['mediawiki.util']).then(function (){
    $( function () {
      mw.util.addPortletLink('p-lang', '//meta.wikimedia.org/wiki/ویکی‌پدیائون رج', 'ویکی‌پدیائون رج', 'interwiki-completelist', 'ویکی‌پدیائون رج');
    });
  });
}

/**
 * Fill upload with preloadOnEmpty
 **/
$(function () {
	if (mw.config.get('wgPageName') === 'شا:بارگذاری_پرونده' && $('#wpUploadDescription').val() === '') {
		if (location.href.indexOf('wpForReUpload') === -1) {
			$('#wpUploadDescription').val($('#preloadOnEmpty').text());
		}
		$('#mw-upload-permitted p').each(function () {
			this.innerHTML = this.innerHTML.replace(/pdf[,،、] /, '');
		});
	}
});

/**
 * WikiMiniAtlas is a popup click and drag world map.
 * See [[meta:WikiMiniAtlas]] for more information.
 * Maintainers: [[w:User:Dschwen]]
 */
mw.loader.load( '//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript' );

/** 
 * redirect redlinks for not autoconfirmed users
 * and hides "new article wizard" edit buttons for them
 * +
 * redirect new page creation with non-standard on title
 */
$(function () {
	// اجماع &oldid=11798574 گانه زیر ۲۵ دَچی‌یه‌ئون نتونّه وه ره دَچینِن
	if (mw.config.get('wgUserEditCount') < 25) {
		if (mw.config.get('wgNamespaceNumber') === 0) {
			$($('.noarticletext').length !== 0 ? '#ca-edit a' : '.new').each(function() {
				this.href = new mw.Uri(this.href).extend({
					//withJS: "MediaWiki:Intro-Welcome-NewUsers.js",
					preload: "الگو:ایجاد+مقاله/استخوان‌بندی",
					editintro: "الگو:ایجاد+مقاله/ادیت‌نوتیس",
					summary: "ایجاد+یک+مقاله+نو+از+طریق+ایجادگر",
					nosummary: "",
					prefix: "",
					minor: "",
					create: "درست+کردن+مقاله+جدید"
				});
			});
		}
		importScript("MediaWiki:Gadget-signit.js");
	}
	if (mw.config.get('wgNamespaceNumber') === 4 || mw.config.get('wgNamespaceNumber') % 2 === 1) {
		if (['en', 'fr', 'de', 'it', 'es'].indexOf(mw.config.get('wgUserLanguage')) !== -1) {
			$('#wpSummary, #wpTextbox1').attr('dir', 'ltr');
		}
	}
	// این کد با بهبودهایی کوچک عنوان صفحه را اصلاح می‌کند
	var uri = new mw.Uri();
	if ((mw.config.get('wgAction') === "edit") &&
			(mw.config.get('wgNamespaceNumber') === 0) &&
			(uri.query.redirected !== "1") && (uri.query.title !== undefined) &&
			(uri.query.redlink === "1")) {
		
		var oldTitle = uri.query.title.replace(/( |%20)/g, '_');
		var title = oldTitle;
		
		for (var i = 0; i < 10; i++) {
			title = title.replace(new RegExp('[' + '٠١٢٣٤٥٦٧٨٩'[i] + i + ']', 'g'), '۰۱۲۳۴۵۶۷۸۹'[i]); // replaces Arabic and Arabic-indic digits at once
		}
		title = title
			.replace(/[ىۍېي]/g, "ی")
			.replace(/[كﻙﻚڪ]/g, "ک")
			.replace(/[ہەھ]/g, "ه")
			.replace(/:(?=[^ _])/g, ': ')
			.replace(/([^ _])\(/, '$1 (')
			.replace(/([\.،«»\:؛\sزرذدواژؤإأآءةa-zA-Z])\u200c/g, '$1')
			.replace(/\u200c[ _]/g, ' ')
			.replace(/(\u200c*$|^\u200c*)/g, '')
			.replace(/[\u200dـ]/g, '')
			.replace(/\(\s(.*?)\s\)/g, '($1)')
			.replace(/\s{2,}/g, ' ')
			.replace(/(ۀ|هٓ)/g, 'ه')
			.replace(/,/g, '،')
			.replace(/ابهام ?زدایی/g, 'ابهام‌زدایی');
		
		if (title !== oldTitle) {
			uri.query.title = title;
			uri.query.redirected = "1";
			window.location.href = uri.toString();
		}
	}
});

/**
 * قراردادن فرمول‌های ریاضی در سمت چپ مناسب برای ویکی‌های راست به چپ
 */
$(function(){
	$("img.tex, span.texhtml").each(function () {
		if ($(this).parent().text().trim() === $(this).text() && $(this).parent().is("p, dd")) {
			$(this).parent().css({
				direction: 'ltr',
				padding: '1em 0'
			});
		}
	});
});

/**
 * Source codes pages direction and and pre white-space 
 */
if ([2, 4, 8].indexOf(mw.config.get('wgNamespaceNumber')) !== -1) {
	if (/\.(js|css|py)$/.test(mw.config.get('wgPageName'))) {
		mw.util.addCSS('.diff-addedline, .diff-deletedline, .diff-context { direction: ltr; } ' +
			'#wpTextbox1 { direction: ltr; }');
	}
}
/*</pre>
=== ToggleImage ===
<pre>*/ 
// Adapted from French Wikipedia
function toggleImage (group, remindex, shwindex) {
	$("#ImageGroupsGr" + group + "Im" + remindex).hide();
	$("#ImageGroupsGr" + group + "Im" + shwindex).show();
}

function ImageGroup() {
    $('div.ImageGroup').each(function(i, group) {
        var unitnode = $('div.ImageGroupUnits', group).get(0);
        if (unitnode == undefined) {
            return 1;
        }
        var units = jQuery(unitnode).children('.center, .mw-halign-center');
        var count = units.get().length;
        if (count <= 1) {
            return 1;
        }
        units.each(function(j, currentimage) {
            $(currentimage).attr('id', "ImageGroupsGr" + i + "Im" + j);
            var leftlink = jQuery('<a href="#" style="text-decoration:none" />');
            var rightlink = jQuery('<a href="#" style="text-decoration:none" />');
            if (j != 0) {
                leftlink.text('▶').click(function() {
                    toggleImage(i, j, j - 1); return false;
                });
            }
            if (j != count - 1) {
                rightlink.text('◀').click(function() {
                    toggleImage(i, j, j + 1); return false;
                });
            }
            jQuery('<div/>').css({ 'font-size' : '110%', 'font-weight' : 'bold' })
                .append(leftlink)
                .append('<tt>(' + String(j+1).replace(/1/g, "۱").replace(/2/g, "۲").replace(/3/g, "۳").replace(/4/g, "۴").replace(/5/g, "۵").replace(/6/g, "۶").replace(/7/g, "۷").replace(/8/g, "۸").replace(/9/g, "۹").replace(/0/g, "۰") + ' از ' + String(count).replace(/1/g, "۱").replace(/2/g, "۲").replace(/3/g, "۳").replace(/4/g, "۴").replace(/5/g, "۵").replace(/6/g, "۶").replace(/7/g, "۷").replace(/8/g, "۸").replace(/9/g, "۹").replace(/0/g, "۰") +  ')</tt>')
                .append(rightlink)
                .prependTo(jQuery(currentimage));
            if (j != 0) {
                $(currentimage).hide().addClass('noprint');
            }
        });
    });
}

$(ImageGroup);

// Newbies are misusing wikilove instead using talk pages add new section
// hiding WikiLove from not autoconfirmed users or without more than 100 edits
if ($.inArray('autoconfirmed', mw.config.get('wgUserGroups')) === -1 || mw.config.get('wgUserEditCount') < 100) {
	mw.loader.using(['mediawiki.util']).then(function() {
		mw.util.addCSS('#ca-wikilove { display: none; }');
	});
}

//Help Abuse Filter #106 to tag Recreated Pages which have delete log
$(function () {
	if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1 && $('.mw-warning-with-logexcerpt .mw-logline-delete').length !== 0) {
		$('#editform input[type=submit]').click(function () { $('#wpSummary').val($('#wpSummary').val() + "‌‌‌‌"); });
	}
});

// Hiding Sandbox pages in content categories, temp. workaround
if (mw.config.get('wgNamespaceNumber') === 14 && (mw.config.get('wgPageName').search(/ویکی|نامزد_حذف_سریع/i) === -1)) {
    $('ul li > a[title$="/صفحه تمرین"]').parent().hide();
}

// </nowiki>