MediaWiki:Common.js

Материал из Викиновостей, свободного источника новостей

Замечание: Возможно, после публикации вам придётся очистить кэш своего браузера, чтобы увидеть изменения.

  • Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl+F5 или Ctrl+R (⌘+R на Mac)
  • Google Chrome: Нажмите Ctrl+Shift+R (⌘+Shift+R на Mac)
  • Internet Explorer / Edge: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl+F5
  • Opera: Нажмите Ctrl+F5.
importScript_ = importScript;
importScript = function ( page, proj ) {
	if (!proj) {
		importScript_(page);
	} else {
		if ( proj.indexOf( '.' ) === -1 ) {
			proj += '.wikinews.org';
		}
		mw.loader.load( '//' + proj + '/w/index.php?title=' + encodeURIComponent( page.replace( / /g, '_' ) ) + '&action=raw&ctype=text/javascript' );
	}
};

importMW = function (name) {
	importScript( 'MediaWiki:' + name + '.js' );
};

var auto_comment = 0;

/**
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные
 * названия классов и идентификаторов.
 */
function runAsEarlyAsPossible( callback, $testElement, func ) {
	func = func || $;
	$testElement = $testElement || $( '#footer' );

	if ( $testElement.length ) {
		callback();
	} else {
		func( callback );
	}
}

// Викификатор
mw.loader.load("//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript");

// Дополнительные кнопки на панели редактирования
if (mw.config.get("wgAction") === "edit" || mw.config.get("wgAction") === "submit") 
 importScript_( 'MediaWiki:Editpage.js' );

/*
// cross-project slidebar from ru.wp
importScript( 'MediaWiki:Sidebar-related.js', 'ru.wikipedia.org' );
*/

// сворачиваемые таблицы и блоки, [[w:ВП:СБ]]
var autoCollapse = 2;
var collapseCaption = 'скрыть';
var expandCaption = 'показать';

var hasClass = ( function (){
	var reCache = {};
	return function ( element, className ) {
		return ( reCache[className] ? reCache[className] : ( reCache[className] = new RegExp( "(?:\\s|^)" + className + "(?:\\s|$)" ) ) ).test( element.className );
	};
} )();

function collapsibleTables() {
	var Table, HRow, THs, Header, btn, a, tblIdx = 0, colTables = [];
	var allTables = document.getElementsByTagName( 'table' );
	for ( var i = 0; Table = allTables[i]; i++ ) {
		if ( !hasClass( Table, 'collapsible' ) ) {
			continue;
		}
		if ( !( HRow = Table.rows[0] ) ) {
			continue;
		}
		THs = HRow.getElementsByTagName( 'th' );
		if ( THs.length === 0 ) {
			continue;
		}
		Header = THs[THs.length-1]; //last TH, not 1st like in en.wp
		Table.id = 'collapsibleTable' + tblIdx;
		btn = document.createElement( 'span' );
		btn.style.styleFloat = btn.style.cssFloat = 'right';
		btn.style.fontWeight = 'normal';
		a = document.createElement( 'a' );
		a.id = 'collapseButton' + tblIdx;
		a.href = 'javascript:collapseTable( ' + tblIdx + ' );';
		a.appendChild( document.createTextNode( collapseCaption ) );
		btn.appendChild( document.createTextNode( '[' ) );
		btn.appendChild( a );
		btn.appendChild( document.createTextNode( ']' ) );
		Header.insertBefore( btn, Header.childNodes[0] );
		colTables[tblIdx++] = Table;
 }
 for ( var i = 0; i < tblIdx; i++ ) {
	 if ( ( tblIdx > autoCollapse && hasClass( colTables[i], 'autocollapse' ) ) || hasClass( colTables[i], 'collapsed' ) ) {
		 collapseTable( i );
	 }
 }
}

function collapseTable ( idx ) {
	var Table = document.getElementById( 'collapsibleTable' + idx );
	var btn = document.getElementById( 'collapseButton' + idx );
	if ( !Table || !btn ) {
		return false;
	}
	var Rows = Table.rows;
	var isShown = ( btn.firstChild.data == collapseCaption );
	btn.firstChild.data = isShown ? expandCaption : collapseCaption;
	var disp = isShown ? 'none' : Rows[0].style.display;
	for ( var i = 1; i < Rows.length; i++ ) {
		Rows[i].style.display = disp;
	}
}

var NavigationBarHide = '[' + collapseCaption + ']';
var NavigationBarShow = '[' + expandCaption + ']';
var NavigationBarShowDefault = autoCollapse;

function collapsibleDivs(){
	var navIdx = 0, colNavs = [], i, NavFrame;
	var divs = document.getElementById( 'content' ).getElementsByTagName( 'div' );
	for (i = 0; NavFrame = divs[i]; i++) {
		if (!hasClass( NavFrame, 'NavFrame' ) ) {
			continue;
		}
		NavFrame.id = 'NavFrame' + navIdx;
		var a = document.createElement( 'a' );
		a.className = 'NavToggle';
		a.id = 'NavToggle' + navIdx;
		a.href = 'javascript:collapseDiv( ' + navIdx + ' );';
		a.appendChild( document.createTextNode( NavigationBarHide ) );
		// 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 ( hasClass( NavFrame.childNodes[j], 'NavHead' ) ) {
				NavFrame.childNodes[j].appendChild( a );
			}
		}
		colNavs[navIdx++] = NavFrame;
	}
	for ( i = 0; i < navIdx; i++ ) {
		if ( ( navIdx > NavigationBarShowDefault && !hasClass( colNavs[i], 'expanded' ) ) || hasClass( colNavs[i], 'collapsed' ) ) {
			collapseDiv( i );
		}
	}
}

function collapseDiv(idx) {
	var div = document.getElementById( 'NavFrame' + idx );
	var btn = document.getElementById( 'NavToggle' + idx );
	if ( !div || !btn ) {
		return false;
	}
	var isShown = ( btn.firstChild.data == NavigationBarHide );
	btn.firstChild.data = isShown ? NavigationBarShow : NavigationBarHide;
	var disp = isShown ? 'none' : 'block';
	for ( var child = div.firstChild;  child != null;  child = child.nextSibling ) {
		if ( hasClass( child, 'NavPic' ) || hasClass( child, 'NavContent' ) ) {
			child.style.display = disp;
		}
	}
}

$( collapsibleDivs );
$( collapsibleTables );

// for backwards compatibility
var addLoadEvent = function ( func ) {
	$( function(){ func(); } );
};

//{Modifynewsectionlink}
function newSectionLink(){
	var plus = document.getElementById( 'ca-addsection' );
	if ( !plus ) {
		return;
	}
	var custom = document.getElementById( 'add-custom-section' );
	if ( !custom ) {
		return;
	}
	plus.firstChild.setAttribute( 'href', custom.getElementsByTagName( 'A' )[0].href );
}



// ссылка [править] для нулевой секции
function editZeroSection(){
	var body = document.getElementById( 'bodyContent' );
	if ( !body || window.disable_zero_section ) {
		return;
	}
	var h2s = body.getElementsByTagName( 'H2' );
	var h2 = h2s[0];
	if ( !h2 ) {
		return;
	}
	if ( h2.parentNode.id == 'toctitle' ) {
		h2 = h2s[1];
	}
	if ( !h2 ) {
		return;
	}
	var span = h2.firstChild;
	if ( !span || span.className != 'editsection' ) {
		return;
	}
	var zero = span.cloneNode( true );
	body.insertBefore( zero, body.firstChild );
	var a = zero.getElementsByTagName( 'a' )[0];
	a.title = a.title.replace( /:.*$/,': 0' );
	a.setAttribute( 'href', a.href.replace( /&section=1/,'&section=0' ) );
}


var load_extratabs = true;

// добавление RSS-ленты последних статей
$( 'head' ).append( '<link type="application/rss+xml" href="http://feeds.feedburner.com/RuWikinewsLatestNews?format=xml" rel="alternate" title="(подписывайтесь здесь!) Главный новостной RSS-канал русских Викиновостей" \/>' );


/******************
Begin editintro stuff
This makes a custom editintro for people editing old pages, or coming directly from 'pedia
maintainer: User:bawolff
*****************/

function addEditIntro(template) {
	//This function assumes that all edit links are in proper order (as in the title arg is first argument), and proper case
	//This function appends &editintro=template to any link that edits the CURRENT page.
	//template parameter should already be escaped

	//var as = document.getElementsByTagName( 'a' );
	var bodyContent = document.getElementById( 'bodyContent' );
	var list = getElementsByClassName( ( bodyContent ? bodyContent : document ), 'span', 'editsection' );
	list[list.length] = document.getElementById( 'ca-edit' );

	for ( var i = 0; i < list.length; i++ ) {
		var a = list[i].getElementsByTagName( 'a' )[0];
		if ( !a ) {
			continue; //just in case
		}
		if ( a.href.indexOf( '&action=edit' ) === -1 ) { //if not an edit link
			continue;
		}
		if ( a.href.indexOf( '?title=' + mw.config.get( 'wgPageName' ) ) === -1 ) { //not a link to this page
			continue;
		}
		if ( a.href.indexOf( '&editintro' ) !== -1 ) { //if it already has an editintro don't add another
			continue;
		}
		a.href = a.href + '&editintro=' + template;
	}
}

function doEditIntro() {
//called onload
	 try {
		if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 || mw.config.get( 'wgPageName' ) === 'Заглавная_страница' ) {
			return;
		}
		var notCurrent = doEditIntro.oldNews();
		var fromPedia = ( document.referrer.indexOf( 'http://ru.wikipedia.org' ) === 0 );
		if ( notCurrent ) {
			addEditIntro( 'Template:Editintro_notcurrent' );
		} else if ( fromPedia ) {
			addEditIntro( 'Template:Editintro_from_wikipedia' );
		}
	}
	catch ( e ) {
		//in case of different skin and can't find cat links or something.
	}

}

doEditIntro.oldNews = function () {
 var cats = document.getElementById( 'catlinks' ).getElementsByTagName( 'a' );
 var pubDate, pubCat, archiveCat, tmp, catName;
 for ( var i = 0; i < cats.length; i++ ) {
	catName = cats[i].title;
	tmp = doEditIntro.parseDate( catName );
	if ( !isNaN( tmp ) ) {
		pubDate = tmp;
	}
	if ( catName === 'Категория:Опубликовано' ) {
		pubCat = true;
	}
	if ( catName === 'Категория:Архивировано' || catName === 'Категория:Автоматически архивировано' ) {
		archiveCat = true;
	}
 } //end getting cats

 if ( !pubDate || !pubCat || archiveCat ) {
 //not in a date category, not published, or already archived.
	return false;
 }
 if ( ( ( new Date() ).getTime() - pubDate ) > 24 * 60 * 60 * 1000 ) { //if more than 24h elasped
	return true;
 }
 else {
	return false;
 }
};

doEditIntro.parseDate = function ( datestring ) {
	// + sign converts to number
	//Returns NaN in even of parse failure.
	var date = datestring.replace( doEditIntro.dateRegex, doEditIntro.dateFunc );
	if ( date === datestring ) {
		return NaN;
	}
	return +date;
};

doEditIntro.dateRegex = /^Категория: (\d\d?) (января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря) (20\d\d)$/;

doEditIntro.dateFunc = function ( str, month, day, year ) {
	//Since JS month starts at month 0

	var months = {'января' : 0, 'февраля': 1, 'марта': 2, 'апреля': 3, 'мая': 4, 'июня': 5, 'июля': 6, 'августа': 7, 'сентября': 8, 'октября': 9,  'ноября': 10,  'декабря': 11};

	return Date.UTC( year, months[month], day );
};
$( doEditIntro );

/**
 * Выполнение скриптов из пространства MediaWiki, указанных в URL
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
 */
var withJS = location.href.match( /[&?]withjs=((mediawiki:)?([^&#]+))/i );
if ( withJS ) {
	importScript_( 'MediaWiki:' + withJS[3] );
}

/**
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible
 * и ниже про wikipage.content).
 */
runAsEarlyAsPossible( function () {
	/**
	 * {{выполнить скрипт}}
	 */
	var $execJS = $( '.executeJS' );
	if ( $execJS.length ) {
		$execJS.each( function () {
			$.each( $( this ).data( 'scriptnames' ).split( ' ' ), function ( i, sc ) {
				sc = $.trim( sc.replace( /[^\w ]/g, '' ) );
				if ( sc ) {
					importScript( 'MediaWiki:Script/' + sc + '.js' );
				}
			} );
		} );
	}

	/**
	 * Чтобы ссылки на очистку кэша не требовали подтверждения (они должны быть помещены в тег с классом
	 * purgelink и именем страницы в параметре data-pagename, например как в шаблоне {{очистить кэш}})
	 */
	$( '.purgelink a' ).click( function ( e ) {
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {
			var pageName = $( this ).parent( '.purgelink' ).data( 'pagename' ) || mw.config.get( 'wgPageName' );
			new mw.Api().post( {
				action: 'purge',
				titles: pageName
			} ).then( function () {
				var url = mw.util.getUrl( pageName );
				if ( e.ctrlKey ) {
					if ( !window.open( url ) ) {
						location.assign( url );
					}
				} else {
					location.assign( url );
				}
			}, function () {
				mw.notify( 'Не удалось очистить кэш.', { type: 'error' } );
			} );
			e.preventDefault();
		} );
	} );
}, $( '#footer' ), mw.hook( 'wikipage.content' ).add );

/* Вкладка 'комментарии' */
if ( mw.config.get( 'wgPageName' ) != 'Заглавная_страница' ) {
	importScript( 'Mediawiki:Comments.js' );
}