MediaWiki:Common.js: различия между версиями
Перейти к навигации
Перейти к поиску
Karaby (обсуждение | вклад) мНет описания правки |
Karaby (обсуждение | вклад) мНет описания правки |
||
(не показаны 102 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
/* | /** | ||
* Локальная функция загрузки скриптов с поддержкой указания проекта | |||
*/ | |||
//debug:mw.log.warn("Using of MediaWiki:Common.js (start)"); | |||
importScript_ = importScript | // original from wikipedia.ru: | ||
importScript = function (page, proj){ | //var importScript_ = importScript; | ||
/*importScript = function ( page, proj ) { | |||
if ( !proj ) { | |||
importScript_( page ); | |||
} else { | |||
if ( proj.indexOf( '.' ) === -1 ) { | |||
proj += '.wikipedia.org'; | |||
} | |||
mw.loader.using( 'mediawiki.util' ).done( function () { | |||
mw.loader.load( '//' + proj + '/w/index.php?title=' + mw.util.wikiUrlencode( page ) + | |||
'&action=raw&ctype=text/javascript' ); | |||
} ); | |||
} | |||
}; | |||
*/ | |||
importScript = function ( page ) { | |||
// mw.loader.using( 'mediawiki.util' ).done( function () { | |||
mw.loader.load( '/w/index.php?title=' + mw.util.wikiUrlencode( page ) + '&action=raw&ctype=text/javascript' ); | |||
// } ); | |||
} | } | ||
//mw.log.warn( 'Using of MediaWiki:Common.js (2)' ); | |||
//mw.log.warn( typeof importScript ); | |||
importMW = function ( name ) {importScript( 'MediaWiki:' + name + '.js' );}; | |||
//console.log ('COMMON.JS importscript'); | |||
//mw.log.warn( 'Using of MediaWiki:Common.js (3)' ); | |||
/ | /** | ||
* Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что | |||
* к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит | |||
* слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха | |||
* функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент | |||
* в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть | |||
* уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные | |||
* названия классов и идентификаторов. | |||
*/ | |||
function runAsEarlyAsPossible( callback, $testElement, func ) { | |||
func = func || $; | |||
$testElement = $testElement || $( '#footer' ); | |||
if ( $testElement.length ) { | |||
callback(); | |||
} else { | |||
func( callback ); | |||
} | |||
if( | |||
} | } | ||
mw.config.set( 'tableSorterCollation', { 'Ё': 'Е', 'ё': 'е' } ); | |||
/** | |||
* Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот | |||
* список не стоит. При необходимости добавить много сообщений во много языков можно использовать | |||
* механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы | |||
. | * типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js. | ||
*/ | |||
var expandCaption, collapseCaption, zeroSectionTip; | |||
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) { | |||
expandCaption = 'show'; | |||
collapseCaption = 'hide'; | |||
zeroSectionTip = 'Edit lead section'; | |||
} else { | |||
expandCaption = 'показать'; | |||
collapseCaption = 'скрыть'; | |||
zeroSectionTip = 'Править преамбулу'; | |||
var | |||
} | } | ||
function | function wgImg( img ) { | ||
return '//upload.wikimedia.org/wikipedia/' + img; | |||
} | } | ||
function | function createFuncBtn( id, func, img, tip ) { | ||
$( '<img id="' + id + '" src="' + wgImg( img ) + '" style="cursor:pointer;" ' + | |||
'title="' + tip + '" alt="' + tip.substr( 0, 3 ) + '">' ) | |||
.appendTo( '#gadget-toolbar' ) | |||
.click( func ); | |||
} | } | ||
// Число раскрытых по умолчанию навигационных (и не только) шаблонов, если им задан параметр | |||
// autocollapse. Участники могут переопределять это значение в личных JS. | |||
var NavigationBarShowDefault; | |||
if ( typeof NavigationBarShowDefault === 'undefined' ) { | |||
NavigationBarShowDefault = 1; | |||
} | } | ||
// table.collapsible | |||
function collapsibleTables( $content ) { | |||
var $btn, | |||
$a, | |||
tblIdx = 0, | |||
navboxCount = 0, | |||
notNavboxCount = 0, | |||
colTables = [], | |||
$Tables = $content.find( 'table' ); | |||
$Tables.each( function ( i, table ) { | |||
if ( $( table ).hasClass( 'collapsible' ) ) { | |||
var $table = $( this ), | |||
if ( | $row = $table.find( 'tr' ).first(), | ||
$cell = $row.find( 'th' ).first(); | |||
if ( !$cell.length ) { | |||
return; | |||
} | |||
} | $table.attr( 'id', 'collapsibleTable' + tblIdx ); | ||
$btn = $( '<span>' ).addClass( 'collapseButton' ); | |||
$a = $( '<a>' ) | |||
.attr( 'id', 'collapseButton' + tblIdx ) | |||
.attr( 'href', 'javascript:collapseTable(' + tblIdx + ');' ) | |||
// Изменяем цвет ссылки, только если цвет текста в навбоксе нестандартный | |||
.css( 'color', $cell.css( 'color' ) === $( '.mw-body' ).css( 'color' ) ? 'auto' : | |||
$cell.css( 'color' ) ) | |||
.text( collapseCaption ); | |||
$btn | |||
.append( '[' ) | |||
.append( $a ) | |||
.append( ']' ); | |||
if ( $cell.contents().length ) { | |||
$btn.insertBefore( $cell.contents().first() ); | |||
} else { | |||
$btn.appendTo( $cell ); | |||
} | |||
// hasClass( 'navbox' ) — временное решение для навшаблонов, ещё не переведённых | |||
// на {{Навигационная таблица}} (также ниже) | |||
if ( $table.hasClass( 'navbox-inner' ) || $table.hasClass( 'navbox' ) ) { | |||
navboxCount++; | |||
} else { | |||
notNavboxCount++; | |||
} | |||
colTables[tblIdx++] = $table; | |||
} | |||
} ); | |||
for ( var i = 0; i < tblIdx; i++ ) { | |||
if ( colTables[i].hasClass( 'collapsed' ) || | |||
( colTables[i].hasClass( 'autocollapse' ) && | |||
( ( ( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) && | |||
navboxCount > NavigationBarShowDefault ) || | |||
( !( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) && | |||
notNavboxCount > NavigationBarShowDefault ) ) ) ) | |||
{ | |||
collapseTable( i ); | |||
} | |||
} | |||
} | } | ||
mw.hook( 'wikipage.content' ).add( collapsibleTables ); | |||
function collapseTable( idx ) { | |||
var $table = $( '#collapsibleTable' + idx ), | |||
$rows = $table.children().children( 'tr' ), | |||
$btn = $( '#collapseButton' + idx ); | |||
if ( !$table.length || !$rows.length || !$btn.length ) { | |||
return false; | |||
} | |||
var isExpanded = ( $btn.text() === collapseCaption ), | |||
cssDisplay = isExpanded ? 'none' : $rows.first().css( 'display' ); | |||
$btn.text( isExpanded ? expandCaption : collapseCaption ); | |||
$rows.slice( 1 ).each( function () { | |||
$( this ).css( 'display', cssDisplay ); | |||
} ); | |||
} | } | ||
// | // div.NavFrame | ||
var navFrameExpandCaption = '[' + expandCaption + ']', | |||
navFrameCollapseCaption = '[' + collapseCaption + ']'; | |||
// Изолируем код из глобальной области видимости | |||
( function () { | |||
function collapsibleDivs( $content ) { | |||
var navFrameIndex = 0, | |||
navFrames = [], | |||
i; | |||
$content.find( 'div' ).each( function () { | |||
var $div = $( this ); | |||
if ( $div.hasClass( 'NavFrame' ) ) { | |||
var $div = $( this ); | |||
var $btn = $( '<a>' ) | |||
.addClass( 'NavToggle' ) | |||
.attr( 'href', 'javascript:' ) | |||
.text( navFrameCollapseCaption ) | |||
.click( navToggleClickHandler ); | |||
$div.children( '.NavHead' ).append( $btn ); | |||
navFrames[ navFrameIndex++ ] = $div; | |||
} | |||
} ); | |||
for ( i = 0; i < navFrameIndex; i++ ) { | |||
if ( navFrames[ i ].hasClass( 'collapsed' ) || | |||
( navFrameIndex > NavigationBarShowDefault && | |||
!navFrames[ i ].hasClass( 'expanded' ) | |||
) | |||
) { | |||
toggleDiv( navFrames[ i ] ); | |||
} | |||
} | |||
} | |||
mw.hook( 'wikipage.content' ).add( collapsibleDivs ); | |||
function navToggleClickHandler() { | |||
var $btn = $( this ); | |||
toggleDiv( $btn.closest( '.NavFrame' ), $btn ); | |||
} | |||
function toggleDiv( $div, $btn ) { | |||
$btn = $btn || $div.find( '.NavToggle' ).first(); | |||
if ( !$div.length || !$btn.length ) return false; | |||
var isExpanded = ( $btn.text() === navFrameCollapseCaption ); | |||
$btn.text( isExpanded ? navFrameExpandCaption : navFrameCollapseCaption ); | |||
$div.children( '.NavContent, .NavPic' ).each( function () { | |||
$( this ).css( 'display', isExpanded ? 'none' : 'block' ); | |||
} ); | |||
} | |||
/** | |||
* Загрузка скриптов через систему подгаджетов | |||
*/ | |||
var namespaceNumber = mw.config.get( 'wgNamespaceNumber' ); | |||
var | // Скрипты для служебных страниц | ||
var | if ( namespaceNumber === -1 ) { | ||
var specialGadgets = [ | |||
'Abusefilter', | |||
'Block', | |||
'Log', | |||
'Movepage', | |||
'Newpages', | |||
'Search', | |||
'Upload' | |||
]; | |||
var canonicalSpecialPageName = mw.config.get( 'wgCanonicalSpecialPageName' ); | |||
if ( specialGadgets.indexOf( canonicalSpecialPageName ) > -1 ) { | |||
mw.loader.load( 'ext.gadget.common-special-' + canonicalSpecialPageName.toLowerCase() ); | |||
} | |||
} else { | |||
// Скрипты для действий | |||
var action = mw.config.get( 'wgAction' ); | |||
var actionGadgets = { | |||
'edit': [ 'ext.gadget.common-action-edit', 'ext.gadget.wikificator', 'ext.gadget.summaryButtons' ] | |||
}; | |||
actionGadgets[ 'submit' ] = actionGadgets[ 'edit' ]; | |||
// Удалить после исчезновения ссылки «Редактировать с инструментом переезда на новый парсер» в сайдбаре | |||
actionGadgets[ 'parsermigration-edit' ] = actionGadgets[ 'edit' ]; | |||
if ( actionGadgets[ action ] ) { | |||
if ( | mw.loader.load( actionGadgets[ action ] ); | ||
} | } | ||
// Скрипты для пространств | |||
var namespaceGadgets = { | |||
6: [ 'ext.gadget.common-namespace-file' ] | |||
}; | |||
if ( namespaceGadgets[ namespaceNumber ] ) { | |||
mw.loader.load( namespaceGadgets[ namespaceNumber ] ); | |||
} | } | ||
} | |||
}() ); | |||
/** | |||
* Старые коды | |||
}; | */ | ||
if ( navigator.platform.indexOf( 'Win' ) !== -1 ) { | |||
mw.loader.using( 'mediawiki.util' ).done( function () { | |||
mw.util.addCSS( '.IPA, .Unicode { font-family: "Arial Unicode MS", "Lucida Sans Unicode"; }' ); | |||
} ); | |||
} | } | ||
/* * * * * * * * * * Ajax functions * * * * * * * * * */ | /* * * * * * * * * * Ajax functions * * * * * * * * * */ | ||
var prevReq; | var prevReq; | ||
var pageUrlTpl = wgScript + "?title=$1&action=raw&templates=expand"; | var pageUrlTpl = mw.config.get('wgScript') + "?title=$1&action=raw&templates=expand"; | ||
var pageUrl = ""; | var pageUrl = ""; | ||
var pageToFetch = ""; | var pageToFetch = ""; | ||
/** | |||
* Compatibility wrapper for creating a new XMLHttpRequest object. | |||
*/ | |||
function createXhr() { | |||
// debug( 'sajax_init_object() called..' ); | |||
var a; | |||
try { | |||
// Try the new style before ActiveX so we don't | |||
// unnecessarily trigger warnings in IE 7 when | |||
// set to prompt about ActiveX usage | |||
a = new XMLHttpRequest(); | |||
} catch ( xhrE ) { | |||
try { | |||
a = new window.ActiveXObject( 'Msxml2.XMLHTTP' ); | |||
} catch ( msXmlE ) { | |||
try { | |||
a = new window.ActiveXObject( 'Microsoft.XMLHTTP' ); | |||
} catch ( msXhrE ) { | |||
a = null; | |||
} | |||
} | |||
} | |||
if ( !a ) { | |||
debug( 'Could not create connection object.' ); | |||
} | |||
return a; | |||
} | |||
/** | |||
* Apply tagOpen/tagClose to selection in currently focused textarea. | |||
* | |||
* Uses `sampleText` if selection is empty. | |||
* | |||
* @param {string} tagOpen | |||
* @param {string} tagClose | |||
* @param {string} sampleText | |||
*/ | |||
function insertTags ( tagOpen, tagClose, sampleText ) { | |||
$currentFocused = $( '#wpTextbox1' ); | |||
if ( $currentFocused.length ) { | |||
$currentFocused.textSelection( | |||
'encapsulateSelection', { | |||
pre: tagOpen, | |||
peri: sampleText, | |||
post: tagClose | |||
} | |||
); | |||
} | |||
} | |||
function loadPage(page) { | function loadPage(page) { | ||
prevReq = | //deprecated prevReq = sajax_init_object(); | ||
prevReq = createXhr(); | |||
if ( !prevReq ) return false; | if ( !prevReq ) return false; | ||
pageToFetch = page; | pageToFetch = page; | ||
Строка 368: | Строка 405: | ||
var customizeToolbar = function() { | var customizeToolbar = function() { | ||
$('#wpTextbox1').wikiEditor('addToToolbar', { | |||
section: 'advanced', | |||
group: 'format', | |||
tools: { | |||
"firstupper": { | |||
label: 'С заглавной', | |||
type: 'button', | |||
icon: 'extensions/VisualEditor/lib/ve/lib/oojs-ui/themes/wikimediaui/images/icons/searchCaseSensitive.svg', | |||
action: { | |||
type: 'callback', | |||
execute: function (context) { | |||
var ta = $('#wpTextbox1'); | |||
var sel = ta.textSelection('getSelection'); | |||
if (!sel) return context; | |||
sel = sel[0].toUpperCase() + sel.slice(1).toLowerCase(); | |||
// replace the selected text in the textarea with the new text | |||
ta.textSelection('encapsulateSelection', {pre: sel, replace: true}); | |||
} | } | ||
} | |||
} ); | } | ||
} | |||
}); | |||
$('#wpTextbox1').wikiEditor('addToToolbar', { | $('#wpTextbox1').wikiEditor('addToToolbar', { | ||
section: 'advanced', | section: 'advanced', | ||
Строка 418: | Строка 468: | ||
tools: { | tools: { | ||
"comment": { | "comment": { | ||
label: ' | label: 'Комментарий', | ||
type: 'button', | type: 'button', | ||
icon: '//upload.wikimedia.org/wikipedia/commons/1/11/Toolbaricon_hiddencomment.png', | icon: '//upload.wikimedia.org/wikipedia/commons/1/11/Toolbaricon_hiddencomment.png', | ||
Строка 431: | Строка 481: | ||
} | } | ||
} ); | } ); | ||
/* | |||
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', { | $( '#wpTextbox1' ).wikiEditor( 'addToToolbar', { | ||
section: 'advanced', | section: 'advanced', | ||
Строка 449: | Строка 500: | ||
} | } | ||
} ); | } ); | ||
*/ | |||
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', { | $( '#wpTextbox1' ).wikiEditor( 'addToToolbar', { | ||
'section': 'advanced', | |||
'groups': { | |||
'blanks': { | |||
'label': '' // or use labelMsg for a localized label, see above | |||
} | |||
} | |||
} ); | |||
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', { | |||
'section': 'advanced', | |||
'group': 'blanks', | |||
'tools': { | |||
'blank-page':{ | |||
'label':'Заготовка статьи', | |||
'type':'select', | |||
'list':{ | |||
'blank-page-5':{ | |||
'label':'Газета', | |||
'action':{ | |||
'type':'callback', | |||
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Газета");} | |||
} | |||
}, | |||
'blank-page-4':{ | |||
'label':'Журнал', | |||
'action':{ | |||
'type':'callback', | |||
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Журнал");} | |||
} | |||
}, | |||
'blank-page-3':{ | |||
'label':'Периодическое издание (общее)', | |||
'action':{ | |||
'type':'callback', | |||
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание");} | |||
} | |||
}, | |||
'blank-page-4':{ | |||
'label':'Журнал', | |||
'action':{ | |||
'type':'callback', | |||
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Журнал");} | |||
} | |||
}, | |||
'blank-page-6':{ | |||
'label':'Библиография периодики', | |||
'action':{ | |||
'type':'callback', | |||
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Библиография");} | |||
} | |||
}, | |||
'blank-page-1':{ | |||
'label':'Исполнитель аудиокниг', | |||
'action':{ | |||
'type':'callback', | |||
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Исполнитель");} | |||
} | |||
} | |||
} | } | ||
}, | }, | ||
Строка 486: | Строка 566: | ||
'type':'select', | 'type':'select', | ||
'list':{ | 'list':{ | ||
'blank- | 'blank-card-1':{ | ||
'label':'Персона', | 'label':'Персона', | ||
'action':{ | 'action':{ | ||
Строка 493: | Строка 573: | ||
} | } | ||
}, | }, | ||
'blank- | 'blank-card-2':{ | ||
'label':'Периодич. издание', | 'label':'Периодич. издание', | ||
'action':{ | 'action':{ | ||
Строка 503: | Строка 583: | ||
} | } | ||
}, | }, | ||
'blank-ins': { | |||
'label': 'Доп. форматирование', // or use labelMsg for a localized label, see above | |||
'type': 'select', | |||
'list': { | |||
'blank-ins-1' : { // Вставить новую пустую категорию | |||
'label': ' | 'label': 'Категория', | ||
'action': { | |||
'type': 'encapsulate', | |||
'options': { | |||
'pre': '[[Категория:', | |||
'peri': '', // <== сюда курсор (текущее выделение) | |||
'post': ']]', | |||
} | |||
} | |||
}, | |||
'blank-ins-7' : { // форматирование года издания периодики | |||
'label': 'Год периодики', | |||
'action': { | 'action': { | ||
'type': 'encapsulate', | 'type': 'encapsulate', | ||
'options': { | 'options': { | ||
'pre': ' | 'pre': '\n{{Год периодики|', | ||
' | 'peri': 'Год', | ||
'post': ']]', | 'post': '|f}}', | ||
} | |||
} | |||
}, | |||
'blank-ins-6' : { // форматирование ссылки на изображение | |||
'label': 'Изображение', | |||
'action': { | |||
'type': 'encapsulate', | |||
'options': { | |||
'pre': '', | |||
'peri': 'Файл с изображением', | |||
'post': '', | |||
'regex': /^.*?\[\[:?(File|Файл):(.*?)\]\]$/, | |||
'regexReplace': " [ [[:Файл:$2|Изображение]] ] ", | |||
// : [[Файл:ClipCapIt-171104-215641.PNG]] | |||
// :[[File:ClipCapIt-171105-212715.PNG]] | |||
} | } | ||
} | } | ||
}, | |||
'blank-ins-3' : { // Вставить includeonly | |||
'label': 'includeonly', | 'label': 'includeonly', | ||
'action': { | 'action': { | ||
Строка 528: | Строка 634: | ||
} | } | ||
} | } | ||
}, | |||
'blank-ins-4' : { // Вставить noinclude | |||
'label': 'noinclude', | 'label': 'noinclude', | ||
'action': { | 'action': { | ||
Строка 539: | Строка 645: | ||
} | } | ||
} | } | ||
}, | |||
'blank-ins-5' : { // Вставить ссылку на статью в Web | |||
'label': 'Ссылка на статью в Web', | 'label': 'Ссылка на статью в Web', | ||
'action': { | 'action': { | ||
Строка 550: | Строка 656: | ||
} | } | ||
} | } | ||
}, | |||
'blank-ins-2' : { // шаблон Автор статьи | |||
'label': 'Подпись', | 'label': 'Подпись', | ||
'action': { | 'action': { | ||
Строка 564: | Строка 670: | ||
} | } | ||
} | } | ||
} | |||
} | |||
} | } | ||
} | } | ||
} ); | } ); | ||
}; | }; | ||
//////////////////////////////////////// | //////////////////////////////////////// | ||
/* Check if view is in edit mode and that the required modules are available. Then, customize the toolbar … */ | |||
if ( $.inArray( mw.config.get( 'wgAction' ), ['edit', 'submit'] ) !== -1 ) { | if ( $.inArray( mw.config.get( 'wgAction' ), ['edit', 'submit'] ) !== -1 ) { | ||
mw.loader.using( 'user.options', function () { | |||
if ( mw.user.options.get('usebetatoolbar') ) { | |||
$.when( | |||
mw.loader.using( 'ext.wikiEditor' ), $.ready | |||
).then( customizeToolbar ); | |||
} | |||
} ); | |||
} | } |
Текущая версия от 16:20, 16 февраля 2022
/**
* Локальная функция загрузки скриптов с поддержкой указания проекта
*/
//debug:mw.log.warn("Using of MediaWiki:Common.js (start)");
// original from wikipedia.ru:
//var importScript_ = importScript;
/*importScript = function ( page, proj ) {
if ( !proj ) {
importScript_( page );
} else {
if ( proj.indexOf( '.' ) === -1 ) {
proj += '.wikipedia.org';
}
mw.loader.using( 'mediawiki.util' ).done( function () {
mw.loader.load( '//' + proj + '/w/index.php?title=' + mw.util.wikiUrlencode( page ) +
'&action=raw&ctype=text/javascript' );
} );
}
};
*/
importScript = function ( page ) {
// mw.loader.using( 'mediawiki.util' ).done( function () {
mw.loader.load( '/w/index.php?title=' + mw.util.wikiUrlencode( page ) + '&action=raw&ctype=text/javascript' );
// } );
}
//mw.log.warn( 'Using of MediaWiki:Common.js (2)' );
//mw.log.warn( typeof importScript );
importMW = function ( name ) {importScript( 'MediaWiki:' + name + '.js' );};
//console.log ('COMMON.JS importscript');
//mw.log.warn( 'Using of MediaWiki:Common.js (3)' );
/**
* Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что
* к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит
* слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха
* функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент
* в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть
* уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные
* названия классов и идентификаторов.
*/
function runAsEarlyAsPossible( callback, $testElement, func ) {
func = func || $;
$testElement = $testElement || $( '#footer' );
if ( $testElement.length ) {
callback();
} else {
func( callback );
}
}
mw.config.set( 'tableSorterCollation', { 'Ё': 'Е', 'ё': 'е' } );
/**
* Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот
* список не стоит. При необходимости добавить много сообщений во много языков можно использовать
* механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы
* типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js.
*/
var expandCaption, collapseCaption, zeroSectionTip;
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {
expandCaption = 'show';
collapseCaption = 'hide';
zeroSectionTip = 'Edit lead section';
} else {
expandCaption = 'показать';
collapseCaption = 'скрыть';
zeroSectionTip = 'Править преамбулу';
}
function wgImg( img ) {
return '//upload.wikimedia.org/wikipedia/' + img;
}
function createFuncBtn( id, func, img, tip ) {
$( '<img id="' + id + '" src="' + wgImg( img ) + '" style="cursor:pointer;" ' +
'title="' + tip + '" alt="' + tip.substr( 0, 3 ) + '">' )
.appendTo( '#gadget-toolbar' )
.click( func );
}
// Число раскрытых по умолчанию навигационных (и не только) шаблонов, если им задан параметр
// autocollapse. Участники могут переопределять это значение в личных JS.
var NavigationBarShowDefault;
if ( typeof NavigationBarShowDefault === 'undefined' ) {
NavigationBarShowDefault = 1;
}
// table.collapsible
function collapsibleTables( $content ) {
var $btn,
$a,
tblIdx = 0,
navboxCount = 0,
notNavboxCount = 0,
colTables = [],
$Tables = $content.find( 'table' );
$Tables.each( function ( i, table ) {
if ( $( table ).hasClass( 'collapsible' ) ) {
var $table = $( this ),
$row = $table.find( 'tr' ).first(),
$cell = $row.find( 'th' ).first();
if ( !$cell.length ) {
return;
}
$table.attr( 'id', 'collapsibleTable' + tblIdx );
$btn = $( '<span>' ).addClass( 'collapseButton' );
$a = $( '<a>' )
.attr( 'id', 'collapseButton' + tblIdx )
.attr( 'href', 'javascript:collapseTable(' + tblIdx + ');' )
// Изменяем цвет ссылки, только если цвет текста в навбоксе нестандартный
.css( 'color', $cell.css( 'color' ) === $( '.mw-body' ).css( 'color' ) ? 'auto' :
$cell.css( 'color' ) )
.text( collapseCaption );
$btn
.append( '[' )
.append( $a )
.append( ']' );
if ( $cell.contents().length ) {
$btn.insertBefore( $cell.contents().first() );
} else {
$btn.appendTo( $cell );
}
// hasClass( 'navbox' ) — временное решение для навшаблонов, ещё не переведённых
// на {{Навигационная таблица}} (также ниже)
if ( $table.hasClass( 'navbox-inner' ) || $table.hasClass( 'navbox' ) ) {
navboxCount++;
} else {
notNavboxCount++;
}
colTables[tblIdx++] = $table;
}
} );
for ( var i = 0; i < tblIdx; i++ ) {
if ( colTables[i].hasClass( 'collapsed' ) ||
( colTables[i].hasClass( 'autocollapse' ) &&
( ( ( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &&
navboxCount > NavigationBarShowDefault ) ||
( !( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &&
notNavboxCount > NavigationBarShowDefault ) ) ) )
{
collapseTable( i );
}
}
}
mw.hook( 'wikipage.content' ).add( collapsibleTables );
function collapseTable( idx ) {
var $table = $( '#collapsibleTable' + idx ),
$rows = $table.children().children( 'tr' ),
$btn = $( '#collapseButton' + idx );
if ( !$table.length || !$rows.length || !$btn.length ) {
return false;
}
var isExpanded = ( $btn.text() === collapseCaption ),
cssDisplay = isExpanded ? 'none' : $rows.first().css( 'display' );
$btn.text( isExpanded ? expandCaption : collapseCaption );
$rows.slice( 1 ).each( function () {
$( this ).css( 'display', cssDisplay );
} );
}
// div.NavFrame
var navFrameExpandCaption = '[' + expandCaption + ']',
navFrameCollapseCaption = '[' + collapseCaption + ']';
// Изолируем код из глобальной области видимости
( function () {
function collapsibleDivs( $content ) {
var navFrameIndex = 0,
navFrames = [],
i;
$content.find( 'div' ).each( function () {
var $div = $( this );
if ( $div.hasClass( 'NavFrame' ) ) {
var $div = $( this );
var $btn = $( '<a>' )
.addClass( 'NavToggle' )
.attr( 'href', 'javascript:' )
.text( navFrameCollapseCaption )
.click( navToggleClickHandler );
$div.children( '.NavHead' ).append( $btn );
navFrames[ navFrameIndex++ ] = $div;
}
} );
for ( i = 0; i < navFrameIndex; i++ ) {
if ( navFrames[ i ].hasClass( 'collapsed' ) ||
( navFrameIndex > NavigationBarShowDefault &&
!navFrames[ i ].hasClass( 'expanded' )
)
) {
toggleDiv( navFrames[ i ] );
}
}
}
mw.hook( 'wikipage.content' ).add( collapsibleDivs );
function navToggleClickHandler() {
var $btn = $( this );
toggleDiv( $btn.closest( '.NavFrame' ), $btn );
}
function toggleDiv( $div, $btn ) {
$btn = $btn || $div.find( '.NavToggle' ).first();
if ( !$div.length || !$btn.length ) return false;
var isExpanded = ( $btn.text() === navFrameCollapseCaption );
$btn.text( isExpanded ? navFrameExpandCaption : navFrameCollapseCaption );
$div.children( '.NavContent, .NavPic' ).each( function () {
$( this ).css( 'display', isExpanded ? 'none' : 'block' );
} );
}
/**
* Загрузка скриптов через систему подгаджетов
*/
var namespaceNumber = mw.config.get( 'wgNamespaceNumber' );
// Скрипты для служебных страниц
if ( namespaceNumber === -1 ) {
var specialGadgets = [
'Abusefilter',
'Block',
'Log',
'Movepage',
'Newpages',
'Search',
'Upload'
];
var canonicalSpecialPageName = mw.config.get( 'wgCanonicalSpecialPageName' );
if ( specialGadgets.indexOf( canonicalSpecialPageName ) > -1 ) {
mw.loader.load( 'ext.gadget.common-special-' + canonicalSpecialPageName.toLowerCase() );
}
} else {
// Скрипты для действий
var action = mw.config.get( 'wgAction' );
var actionGadgets = {
'edit': [ 'ext.gadget.common-action-edit', 'ext.gadget.wikificator', 'ext.gadget.summaryButtons' ]
};
actionGadgets[ 'submit' ] = actionGadgets[ 'edit' ];
// Удалить после исчезновения ссылки «Редактировать с инструментом переезда на новый парсер» в сайдбаре
actionGadgets[ 'parsermigration-edit' ] = actionGadgets[ 'edit' ];
if ( actionGadgets[ action ] ) {
mw.loader.load( actionGadgets[ action ] );
}
// Скрипты для пространств
var namespaceGadgets = {
6: [ 'ext.gadget.common-namespace-file' ]
};
if ( namespaceGadgets[ namespaceNumber ] ) {
mw.loader.load( namespaceGadgets[ namespaceNumber ] );
}
}
}() );
/**
* Старые коды
*/
if ( navigator.platform.indexOf( 'Win' ) !== -1 ) {
mw.loader.using( 'mediawiki.util' ).done( function () {
mw.util.addCSS( '.IPA, .Unicode { font-family: "Arial Unicode MS", "Lucida Sans Unicode"; }' );
} );
}
/* * * * * * * * * * Ajax functions * * * * * * * * * */
var prevReq;
var pageUrlTpl = mw.config.get('wgScript') + "?title=$1&action=raw&templates=expand";
var pageUrl = "";
var pageToFetch = "";
/**
* Compatibility wrapper for creating a new XMLHttpRequest object.
*/
function createXhr() {
// debug( 'sajax_init_object() called..' );
var a;
try {
// Try the new style before ActiveX so we don't
// unnecessarily trigger warnings in IE 7 when
// set to prompt about ActiveX usage
a = new XMLHttpRequest();
} catch ( xhrE ) {
try {
a = new window.ActiveXObject( 'Msxml2.XMLHTTP' );
} catch ( msXmlE ) {
try {
a = new window.ActiveXObject( 'Microsoft.XMLHTTP' );
} catch ( msXhrE ) {
a = null;
}
}
}
if ( !a ) {
debug( 'Could not create connection object.' );
}
return a;
}
/**
* Apply tagOpen/tagClose to selection in currently focused textarea.
*
* Uses `sampleText` if selection is empty.
*
* @param {string} tagOpen
* @param {string} tagClose
* @param {string} sampleText
*/
function insertTags ( tagOpen, tagClose, sampleText ) {
$currentFocused = $( '#wpTextbox1' );
if ( $currentFocused.length ) {
$currentFocused.textSelection(
'encapsulateSelection', {
pre: tagOpen,
peri: sampleText,
post: tagClose
}
);
}
}
function loadPage(page) {
//deprecated prevReq = sajax_init_object();
prevReq = createXhr();
if ( !prevReq ) return false;
pageToFetch = page;
pageUrl = pageUrlTpl.replace(/\$1/, encodeURI(page));
showLoadIndicator();
prevReq.onreadystatechange = insertIntoWikiTextFromRequest;
prevReq.open("GET", pageUrl, true);
prevReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
prevReq.send(null);
return true;
}
function insertIntoWikiTextFromRequest() {
if ( prevReq.readyState != 4 ) {
return;
}
hideLoadIndicator();
if ( prevReq.status != 200 ) {
window.alert(/*gLang.msg(*/"et-ajaxerror", prevReq.status, prevReq.statusText,
pageToFetch, pageUrl/*)*/);
return;
}
insertIntoWikiText(prevReq.responseText);
}
function insertIntoWikiText(content) {
// delete text marked for no inclusion + <pre> and <nowiki>
var re = /<!--noinclude-->.*<!--\/noinclude-->|<\/?pre>|<\/?nowiki>/g;
content = content.replace(re, "");
// replace escaped tags
var specials = ["pre", "nowiki"];
for (var i in specials) {
re = new RegExp("\\[(\/?)"+ specials[i] +"\\]", "g");
content = content.replace(re, "<$1"+ specials[i] +">");
}
// we can have >>|sample text|<< or >>|<< or just simple text
var parts = null;
var left, right, def = "";
content = escapeNl(content);
if ( ( parts = content.match(/(.*)>>\|(.*)\|<<(.*)/) ) ) {
left = parts[1];
def = parts[2];
right = parts[3];
} else { // no sample text: split at caret’s position
parts = content.split(">>|<<");
left = parts[0];
delete(parts[0]);
right = parts.join("");
}
insertTags(unescapeNl(left), unescapeNl(right), unescapeNl(def));
}
function escapeNl(s) { return s.replace(/\n/g, "\x01"); }
function unescapeNl(s) { return s.replace(/\x01/g, "\n"); }
var loadIndicator;
function showLoadIndicator() {
if ( loadIndicator ) {
loadIndicator.style.display = "block";
return;
}
loadIndicator = document.createElement("div");
loadIndicator.id = "loadIndicator";
loadIndicator.appendChild( document.createTextNode(/*gLang.msg(*/"et-tplloading"/*)*/) );
document.getElementsByTagName("body")[0].appendChild(loadIndicator);
}
function hideLoadIndicator() {
if (loadIndicator) loadIndicator.style.display = "none";
}
var customizeToolbar = function() {
$('#wpTextbox1').wikiEditor('addToToolbar', {
section: 'advanced',
group: 'format',
tools: {
"firstupper": {
label: 'С заглавной',
type: 'button',
icon: 'extensions/VisualEditor/lib/ve/lib/oojs-ui/themes/wikimediaui/images/icons/searchCaseSensitive.svg',
action: {
type: 'callback',
execute: function (context) {
var ta = $('#wpTextbox1');
var sel = ta.textSelection('getSelection');
if (!sel) return context;
sel = sel[0].toUpperCase() + sel.slice(1).toLowerCase();
// replace the selected text in the textarea with the new text
ta.textSelection('encapsulateSelection', {pre: sel, replace: true});
}
}
}
}
});
$('#wpTextbox1').wikiEditor('addToToolbar', {
section: 'advanced',
group: 'format',
tools: {
"strikethrough": {
label: 'Зачеркнуть',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/f/f9/Toolbaricon_regular_S_stroke.png',
action: {
type: 'encapsulate',
options: {
pre: "<s>",
post: "</s>"
}
}
}
}
});
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
section: 'advanced',
group: 'format',
tools: {
"hline": {
label: 'Горизонт. линия',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/b/b4/Toolbaricon_rule.png',
action: {
type: 'encapsulate',
options: {
pre: "----",
ownline: true
}
}
}
}
} );
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
section: 'advanced',
group: 'format',
tools: {
"comment": {
label: 'Комментарий',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/1/11/Toolbaricon_hiddencomment.png',
action: {
type: 'encapsulate',
options: {
pre: "<!-- ",
post: " -->"
}
}
}
}
} );
/*
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
section: 'advanced',
group: 'format',
tools: {
"math": {
label: 'Математика',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/3/38/Button_Math.png',
action: {
type: 'encapsulate',
options: {
pre: "<math>",
post: "</math>"
}
}
}
}
} );
*/
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
'section': 'advanced',
'groups': {
'blanks': {
'label': '' // or use labelMsg for a localized label, see above
}
}
} );
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
'section': 'advanced',
'group': 'blanks',
'tools': {
'blank-page':{
'label':'Заготовка статьи',
'type':'select',
'list':{
'blank-page-5':{
'label':'Газета',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Газета");}
}
},
'blank-page-4':{
'label':'Журнал',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Журнал");}
}
},
'blank-page-3':{
'label':'Периодическое издание (общее)',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание");}
}
},
'blank-page-4':{
'label':'Журнал',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Журнал");}
}
},
'blank-page-6':{
'label':'Библиография периодики',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодическое_издание/Библиография");}
}
},
'blank-page-1':{
'label':'Исполнитель аудиокниг',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Исполнитель");}
}
}
}
},
'blank-card':{
'label':'Заготовка карточки',
'type':'select',
'list':{
'blank-card-1':{
'label':'Персона',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Персона");}
}
},
'blank-card-2':{
'label':'Периодич. издание',
'action':{
'type':'callback',
execute: function(context){loadPage("MediaWiki:Common.js/Edit_tools_data/Периодика");}
}
}
}
},
'blank-ins': {
'label': 'Доп. форматирование', // or use labelMsg for a localized label, see above
'type': 'select',
'list': {
'blank-ins-1' : { // Вставить новую пустую категорию
'label': 'Категория',
'action': {
'type': 'encapsulate',
'options': {
'pre': '[[Категория:',
'peri': '', // <== сюда курсор (текущее выделение)
'post': ']]',
}
}
},
'blank-ins-7' : { // форматирование года издания периодики
'label': 'Год периодики',
'action': {
'type': 'encapsulate',
'options': {
'pre': '\n{{Год периодики|',
'peri': 'Год',
'post': '|f}}',
}
}
},
'blank-ins-6' : { // форматирование ссылки на изображение
'label': 'Изображение',
'action': {
'type': 'encapsulate',
'options': {
'pre': '',
'peri': 'Файл с изображением',
'post': '',
'regex': /^.*?\[\[:?(File|Файл):(.*?)\]\]$/,
'regexReplace': " [ [[:Файл:$2|Изображение]] ] ",
// : [[Файл:ClipCapIt-171104-215641.PNG]]
// :[[File:ClipCapIt-171105-212715.PNG]]
}
}
},
'blank-ins-3' : { // Вставить includeonly
'label': 'includeonly',
'action': {
'type': 'encapsulate',
'options': {
'pre': '<includeonly>',
'peri': '', // <== сюда курсор (текущее выделение)
'post': '</includeonly>',
}
}
},
'blank-ins-4' : { // Вставить noinclude
'label': 'noinclude',
'action': {
'type': 'encapsulate',
'options': {
'pre': '<noinclude>',
'peri': '', // <== сюда курсор (текущее выделение)
'post': '</noinclude>',
}
}
},
'blank-ins-5' : { // Вставить ссылку на статью в Web
'label': 'Ссылка на статью в Web',
'action': {
'type': 'encapsulate',
'options': {
'pre': '<ref>{{cite web| url =',
'peri': 'url', // <== сюда курсор (текущее выделение)
'post': ' | title = [Заголовок статьи]}}</ref>',
}
}
},
'blank-ins-2' : { // шаблон Автор статьи
'label': 'Подпись',
'action': {
'type': 'encapsulate',
'options': {
'pre': '{{автор статьи|',
'peri': 'Автор и дата',
'post': '}}',
'regex': /^(\s*)(={1,6})(.*?)\2(\s*)$/,
'regexReplace': "$1===$3===$4",
// 'ownline': true // новая строка
}
}
}
}
}
}
} );
};
////////////////////////////////////////
/* Check if view is in edit mode and that the required modules are available. Then, customize the toolbar … */
if ( $.inArray( mw.config.get( 'wgAction' ), ['edit', 'submit'] ) !== -1 ) {
mw.loader.using( 'user.options', function () {
if ( mw.user.options.get('usebetatoolbar') ) {
$.when(
mw.loader.using( 'ext.wikiEditor' ), $.ready
).then( customizeToolbar );
}
} );
}