MediaWiki:Gadget-edit2.js
Замечание: Чтобы после сохранения вступили в силу изменения стилей, перезагрузите файл //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=vector&*, если используете скин Vector, или //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=common&*, если используете скин Common.
Чтобы вступили в силу изменения скриптов, перезагрузите файл //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=vector&*, если используете скин Vector, или //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=common&*, если используете скин Common.
Гаджеты и импортируемые скрипты загружаются отдельными файлами.
/*
* Инструменты редактирования. Версия 0.92
* Александр Машин.
* Отдельные изменения — Mithgol the Webmaster.
* Для обновления очистить кэш для сайта.
* Гаджеты, добавляющие кнопки, должны вносить их в массивы mw.tools_above и mw.tools_below
* внутри одной из функций массива mw.edit_gadget_extensions.
*
*/
// Значки развёртывания и свёртывания субменю:
var extender = '<img src="/files/c/cf/Etool_extender.png" width="5" height="16" alt="→" />';
var collapser = '<img src="/files/d/d4/Etool_collapser.png" width="5" height="16" alt="↓" />';
// Для отложенного разбора:
var lastPostponed = 0;
var immediate_limit = 64;
// Счётчик инструментов:
var tool_no = 0;
// Признак того, что кнопка мыши нажата:
var mouse_is_down = false;
// id счётчика времени, включившегося при наведении мыши на инструмент:
var delay_id;
// Задержка показа подменю при наведении указателя мыши, мс:
var popup_delay = 500;
// Кэш для хранения обёрток, заполнителей и подменю, загрузка которых отложена:
var cache = {};
// Массив функций-расширений, которые будут выполены после заполнения
// массивов стандартного меню, но до их вывода:
if (!mw.edit_gadget_extensions) {
mw.edit_gadget_extensions = [];
}
/*
* Автогенерация нового меню
*/
function newMenuHTML (tools) {
return '' +
'<menu>\n' +
'<ul>\n' +
'<li></li>\n' +
'</ul>\n' +
'<menu>\n';
} // -- function newMenuHTML (tools)
function newMenuCSS (tools) {
return '' +
'menu {\n' +
' margin: 100px 0;\n' +
' background-color: #E64A19;\n' +
'}\n' +
'\n' +
'/* убираем отступы и поля, а также list-style для "ul", \n' +
' * и добавляем "position:relative" */\n' +
'menu ul {\n' +
' padding:0;\n' +
' margin:0;\n' +
' list-style: none;\n' +
' position: relative;\n' +
' }\n' +
'\n' +
'/* применяем inline-block позиционирование к элементам навигации */\n' +
'menu ul li {\n' +
' margin: 0px -7px 0 0;\n' +
' display:inline-block;\n' +
' background-color: #E64A19;\n' +
' }\n' +
'\n' +
'/* стилизуем ссылки */\n' +
'menu a {\n' +
' display:block;\n' +
' padding:0 10px;\n' +
' color:#FFF;\n' +
' font-size:20px;\n' +
' line-height: 60px;\n' +
' text-decoration:none;\n' +
'}\n' +
'\n' +
'/* изменяем цвет фона при наведении курсора */\n' +
'menu a:hover {\n' +
' background-color: #000000;\n' +
' }\n' +
' \n' +
' /* скрываем выпадающие списки по умолчанию\n' +
' * и задаем абсолютное позиционирование */\n' +
'menu ul ul {\n' +
' display: none;\n' +
' position: absolute;\n' +
' top: 100%;\n' +
'}\n' +
'\n' +
'/* отображаем выпадающий список при наведении */\n' +
'menu ul li:hover > ul {\n' +
' display:inherit;\n' +
'}\n' +
'\n' +
'/* первый уровень выпадающего списка */\n' +
'menu ul ul li {\n' +
' min-width:170px;\n' +
' float:none;\n' +
' display:list-item;\n' +
' position: relative;\n' +
'}\n' +
'\n' +
'/* второй, третий и последующие уровни \n' +
' * смещаем 2 и 3 уровни влево \n' +
' * на значение длины первого уровня.\n' +
'*/\n' +
'menu ul ul ul {\n' +
' position: absolute;\n' +
' top:0;\n' +
' left:100%;\n' +
' }\n' +
' \n' +
' /* измените ' +' на любой другой символ, если нужно\n' +
' */\n' +
'li > a:after { content: ' +'; }\n' +
" li > a:only-child:after { content: ''; }\n";
} // -- function newMenuCSS (tools)
/* Заготовки для меню.
* Объявления — глобальные.
* Создаются функцией createStubs().
*/
var $li_stub, $button_stub, $a_stub, $full_stub, $ul0_stub, $ul1_stub, $li0_stub,
$li1_stub, $postponed_stub;
function createStubs() {
/* употребляются в eButton(): */
// Пункт меню:
$li_stub = $('<li></li>');
// Кнопка:
$button_stub = $('<button type="button"></button>').mouseup(function(){
// Срабатывание функции кнопки:
insertTag ($(this).attr ('forbox')
, cache [makeCacheKey (this.title) + '_wrapper']
, cache [makeCacheKey (this.title) + '_filler']
, $(this).attr ('process_all')
);
$(this).makeLeader();
}).mouseover(function(){
// Вывод вставляемого кнопкой вики-кода в строку состояния:
var wrapper = cache [makeCacheKey (this.title) + '_wrapper'];
if (wrapper && !$.isFunction (wrapper)) {
window.status = this.title;
if ( this.title != $.trim (stripHTML(wrapper)).replace (/_/g, ' ') ){
window.status += ': ' + wrapper;
}
}
return false;
}).mouseleave(function(){
// Очистка строки состояния:
window.status = '';
});
// + для IE, который не понимает :hover в CSS:
/* if ($.browser.msie) {
$button_stub.hover (
function () {$(this).addClass ('hover');}
, function () {$(this).removeClass ('hover');}
);
} */
// Ссылка:
$a_stub = $('<a target="_blank"></a>');
// + для IE, который не понимает :hover в CSS:
/* if ($.browser.msie) {
$a_stub.hover (
function(){ $(this).addClass ('hover'); }
, function(){ $(this).removeClass('hover'); }
);
} */
// Текст к кнопке:
$full_stub = $('<span></span>').addClass('full');
/* употребляются в eMenu(): */
// Заготовка меню верхнего уровня:
$ul0_stub = $('<ul></ul>').addClass('eMenu');
// Подменю:
$ul1_stub = $ul0_stub.clone().mouseleave(function(){
// Свёртывание при съезде мыши:
$('.eMenu .eMenu').not('.fixed').slideUp('fast');
// Сброс счётчика времени для показа подменю по наведению и задержке мыши:
clearInterval(delay_id);
});
// + для IE, который не может нормально установить ширину абсолютно позиционированных блоков:
/* if ($.browser.msie) {
// Установить ширину подменю:
$ul1_stub.width('35em');
} */
// Заготовка кнопки верхнего меню:
$li0_stub = $('<li></li>').append( // Последний инструмент:
$('<button></button>').text ('?').addClass ('last')
).append( // Кнопка развёртывания:
$('<button type="button"></button>').html(extender).addClass('extender').mousedown(
function(){
fixedToggle($(this).parent()); // -- развёртывание.
return false;
}
)
).mousedown(function(){
// Показ подменю при нажатии кнопки мыши:
var $this = $(this);
var $toolbar = $this.parents ('.eMenu');
if ($toolbar.find('.eMenu.fixed').length === 0){
$this.find ('.eMenu').loadAndShow ('instant');
mouse_is_down = true;
}
// Сброс счётчика времени для показа подменю по наведению и задержке мыши:
clearInterval (delay_id);
}).mouseover(function(){
// Сброс счётчика времени для показа подменю по наведению и задержке мыши:
clearInterval (delay_id);
var $this = $(this);
var $toolbar = $this.parents ('.eMenu');
if ($toolbar.find('.eMenu.fixed').length === 0) {
// Показ подменю при наезде, при условии, что:
if (mouse_is_down) { // кнопка мыши нажата:
$this.find('.eMenu').loadAndShow('instant');
} else {
// или мышь задерживается на popupdelay мс (по умолчанию, 0,5 с):
delay_id = setTimeout(function(){
$this.find('.eMenu').loadAndShow('fast');
}, popup_delay);
}
}
}).mouseup(function(){
// Снятие признака нажатия кнопки мыши:
mouse_is_down = false;
// Сброс счётчика времени для показа подменю по наведению и задержке мыши:
clearInterval (delay_id);
}).mouseleave(function(){
// Сброс счётчика времени для показа подменю по наведению и задержке мыши:
clearInterval (delay_id);
// Свёртывание при съезде мыши:
$('.eMenu .eMenu').not ('.fixed').slideUp ('fast');
});
// + для IE: разрыв над подменю, чтобы оно показывалось ниже, а не справа:
/* if ($.browser.msie) {
$li0_stub.append( '<br />' );
} */
// Заготовка кнопки подменю:
$li1_stub = $('<li></li>');
// Заготовка отметки отложенной загрузки:
/*
$postponed_stub = eButton({
b: '<img src="/files/Etool_AJAX-loader-T16.gif" width="16" height="16" alt="loading…" />',
t: 'Загрузка…'
});
*/
}
// Вертикальный разделитель и перевод строки для субменю:
var separator = {h: '<li><img src="/files/7/77/Etool_vrule.png" width="3" style="height: 2.5ex" alt="|" /></li>'};
var inline_separator = ' <<_•_>> ';
var br = {h: '<br clear="all" />'};
// Строка шаблонов лицензий для страницы загрузки изображений:
var licenses = '';
if (mw.config.get ('wgTitle') === 'Upload' || mw.config.get ('wgTitle') === 'Загрузка') {
$('#wpLicense option').each (function () {
if (this.disabled) {
// Группа лицензий:
licenses += 'br <<' + $(this).text ().replace (/\s/g, '_').replace (/[[\]]/g, '') + '>> ';
} else {
// Лицензия:
licenses += $(this).val () ? '{{' + $.trim ($(this).val ().split ('|', 2) [0].replace (/\s/g, '_')) + '}} ' : '';
}
});
}
// Настройка панелей инструментов над и под текстовыми окнами.
// Вложенные массивы обозначают подменю.
// Объекты описывают кнопки, метки, ссылки или произвольный HTML.
// Строки -- ряды простых инструментов, разделённых пробелом.
// Верхняя панель:
mw.tools_above = [
[
{t: 'Обработка выделенного текста', nl: true}
// Место для подключения викификатора:
, {w: function (s) {return s.toLowerCase ();}, t: 'Нижний регистр', b: 'аб', all: true}, br
// Инструмент поиска и замены:
, {h: '<hr />'}
, {w: function (s) {
return s.replace ($('#tregex').val () == 'on'
? new RegExp ($('#tsearch').val ()
, ($('#tglobal').val () == 'on' ? 'g' : '')
+ ($('#tmulti').val () == 'on' ? 'm' : '')
+ ($('#ticase').val () == 'on' ? 'i' : ''))
: $('#tsearch').val ()
, $('#treplace').val ());
},
b: '<img src="/files/b/b8/Etool_replace.png" alt="→" />',
t: 'Поиск и замена',
all: true, nl: true}
, {h: '<span>(</span><input type="checkbox" id="tregex" /><label for="tregex">как <a href="/Регулярные_выражения" target="_blank" title="страница о регулярных выражениях (в новой вкладке)">regex</a></label>): '
+ '/<input id="tsearch" size="30" title="Что заменить">/<input id="treplace" size="30" title="Чем заменить">/'
+ '<input type="checkbox" id="tglobal" checked title="Заменить всё" /><label for="tglobal" title="Заменить всё">g</label>'
+ '<input type="checkbox" id="tmulti" title="Много строк" /><label for="multi" title="Много строк">m</label>'
+ '<input type="checkbox" id="ticase" checked title="Игнорировать регистр" /><label for="ticase" title="Игнорировать регистр">i</label>/',
nl: true}
] , separator, [
{t: 'Пунктуация', nl: true}
, {w: '+—', b: '—', t: 'Тире'}
, {w: '+–', b: '–', t: 'Минус'}
, {w: '+…', b: '…', t: 'Многоточие'}
, {w: ' ', b: '∙', t: 'Неразрывный пробел'}, br
, {t: 'Кавычки:'}
, {w: '<q>+</q>', b: '«<span class="plus_sign">a</span>»', t: 'Универсальные', f: 'Текст в кавычках'}
, {w: '«+»', b: '«<span class="plus_sign">a</span>»', t: 'Обычные', f: 'Текст в кавычках'}
, {w: '„+“', b: '„<span class="plus_sign">a</span>“', t: 'Вложенные', f: 'Текст в кавычках второго уровня'}, br
, {w: '“+”', b: '“<span class="plus_sign">a</span>”', t: 'Английские', f: 'Текст в кавычках внутри английского текста'}
, {w: '»+«', b: '»<span class="plus_sign">a</span>«', t: 'Немецкие', f: 'Текст в кавычках внутри немецкого текста'}, br
, '§+ №+ ~ ¡+ ¿+ +† +‡ {{•}}_ ¶ #+ &+'
, {w: function (s) {return s + '|';}, b: '|', t: 'Вертикальная черта'}
, ' {{!}} ` \''
, {t: 'Диакритика', nl: true}
, {w: '+́', b: '<b><span style="color:black">a</span>́</b>', t: 'Знак ударения', f: 'Подударная гласная'}, br
, {w: '+́', b: '<b><span class="plus_sign">a</span>́</b>', t: 'Акут', f: 'Буква под акутом'}
, {w: '+̀', b: '<b><span class="plus_sign">a</span>̀</b>', t: 'Гравис', f: 'Буква под грависом'}
, {w: '+̂', b: '<b><span class="plus_sign">a</span>̂</b>', t: 'Циркумфлекс', f: 'Буква под циркумфлексом'}
, {w: '+̈', b: '<b><span class="plus_sign">a</span>̈</b>', t: 'Диарезис', f: 'Буква под диарезисом'}
, {w: '+̃', b: '<b><span class="plus_sign">a</span>̃</b>', t: 'Тильда', f: 'Буква под тильдой'}
, {w: '+̌', b: '<b><span class="plus_sign">e</span>̌</b>', t: 'Гачек', f: 'Буква под гачеком'}, br
, {w: '+̆', b: '<b><span class="plus_sign">a</span>̆</b>', t: 'Кратка', f: 'Краткая буква'}
, {w: '+̄', b: '<b><span class="plus_sign">a</span>̄</b>', t: 'Макрон', f: 'Долгая буква'}
, {url: mw.util.getUrl ('Традиция:Типографика'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Типографика', nl: true}
], [
{t: 'Шрифт', nl: true}
, {w: "''+''", b: '<img src="/files/e/e8/Etool_italic.png" width="14" height="16" alt="К" />', t: '<em>Курсив</em>'}
, {w: "'''+'''", b: '<img src="/files/1/15/Etool_bold.png" width="20" height="16" alt="Ж" />', t: '<strong>Полужирный шрифт</strong>'}, br
, {w: '<sup>+</sup>', b: '<img src="/files/9/9b/Etool_font_superscript.png" height="16" width="16" alt="sup">', t: 'Верхний индекс'}
, {w: '<sub>+</sub>', b: '<img src="/files/6/68/Etool_font_subscript.png" height="16" width="16" alt="sub">', t: 'Нижний индекс'}
, {w: '<s>+</s>', b: '<strike style="color:blue"><span style="color:black"> a </span></strike>', t: 'Зачеркнуть', f: 'Зачёркнутый текст'} , br
, {w: '<code>+</code>', b: 'К', t: '<code>Код</code>'}
, {w: '<kbd>+</kbd>', b: '<img src="/files/c/ce/Etool_keyboard.png" height="16" width="16" alt="kbd">', t: '<kbd>Ввод пользователя</kbd>'}
, {w: '<abbr title="(полностью)">+</abbr>', b: 'А', t: 'Сокращение'}
, {w: '<acronym title="(полностью)">+</acronym>', b: 'Y', t: 'Акроним'}
], [
{t: 'Заголовки', nl: true}
, {w: '\n== + ==\n', b: '<h2 style="font-size: 130%; margin: 0">З2</h2>', t: '<h2>Заголовок 2</h2>', nl: true}
, {w: '\n=== + ===\n', b: '<h3 style="font-size: 120%; margin: 0">З3</h3>', t: '<h3 style="margin-left: 16px;">Заголовок 3</h3>', nl: true}
, {w: '\n==== + ====\n', b: '<h4 style="font-size: 100%; margin: 0">З4</h4>', t: '<h4 style="margin-left: 32px;">Заголовок 4</h4>', nl: true}
, {w: '\n===== + =====\n', b: '<h5 style="font-size: 90%; margin: 0">З5</h5>', t: '<h5 style="margin-left: 48px;">Заголовок 5</h5>', nl: true}
, {w: '\n====== + ======\n', b: '<h6 style="font-size: 80%; margin: 0">З6</h6>', t: '<h6 style="margin-left: 64px;">Заголовок 6</h6>', nl: true}
, {t: 'Содержание', nl: true}
, {w: '+\n{{TOC}}\n', b: '<img src="/files/8/85/Etool_toc.png" height="16" width="16" alt="Ξ">', t: 'Содержание здесь'}, br
, {w: '+\n{{TOCRight}}\n', b: '<img src="/files/f/fd/Etool_toc_right.png" height="16" width="16" alt="Ξ→">', t: 'Содержание справа'}, br
, {w: '+\n__NOTOC__\n', b: '<img src="/files/0/00/Etool_no_toc.png" height="16" width="16" alt="Ξ→">', t: 'Подавить содержание'}
], [
{t: 'Абзац', nl: true}
, {w: '\n\n+', b: '<img src="/files/e/e9/Etool_red_line.png" width="16" height="16" alt="↵" />', t: 'Новый абзац'}, br
, {w: makeUL, b: '<img src="/files/0/0d/Etool_text_list_bullets.png" width="16" height="16" alt="*" />', t: 'Маркированный список', f: '\nодин пункт,\nдругой пункт,\n…,\nпоследний пункт'}
, {w: makeOL, b: '<img src="/files/3/36/Etool_text_list_numbers.png" width="16" height="16" alt="#" />', t: 'Нумерованный список', f: '\nпервый пункт,\nвторой пункт,\n…,\nпоследний пункт'}
, {w: makeGlossary, b: '<img src="/files/4/42/Etool_glossary.png" width="16" height="16" alt="= ==" />', t: 'Глоссарий', f: '\nпервый термин:определение,\nвторой термин:определение,\n…,\nпоследний термин:определение'}, br
, {w: '\n{{цитата|+|источник}}', b: '<img src="/files/4/43/Etool_text_indent.png" width="16" height="16" alt="→text" />', t: 'Цитата', f: 'Цитируемый текст'}
, {w: makeTable
, b: '<img src="/files/b/ba/Etool_table.png" width="16" height="16" alt="table" />'
, t: 'Таблица'
, f: '\nзаголовок\n(1, nl:1)\n(2,1)'}
, {url: mw.util.getUrl ('Традиция:Как делать таблицы'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Таблицы'}, br
, {w: '<poem>+</poem>\n', b: '<img src="/files/3/3b/Etool_poem.png" width="16" height="16" alt="Стихи" />', t: 'Стихи'}
, {w: '<source lang=(язык)">+</source>\n', b: '<img src="/files/a/ad/Etool_source_code.png" width="16" height="16" alt="<>" />', t: '<code>Исходный код</code>'}
, {w: '<pre>+</pre>\n', b: '<img src="/files/2/2e/Etool_pre.png" width="16" height="16" alt="$>_" />', t: '<code>Преформатированный текст</code>'}, br
, {w: '<nowiki>+</nowiki>', b: '<img src="/files/c/cb/Etool_nowiki.png" width="16" height="16" alt="</>" />', t: 'Невикифицированный текст', f: 'Сырой викитест'}
, {w: '\n<!--\n+\n--' + '>\n', b: '<img src="/files/5/5f/Etool_comment.png" height="16" width="16" alt="books">', t: 'Комментарий HTML', f: 'Комментарий HTML (не обрабатывается парсером)'}, br
, {w: '<br />', b: '<img src="/files/e/e3/Etool_br.png" width="11" height="16" alt="↵" />', t: 'Перевод строки'}
, {url: mw.util.getUrl ('Традиция:Вики-разметка'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Вики-разметка', nl: true}
], [
{t: 'Ссылки', nl: true}
, {w: '[[+]]', b: '<img src="/files/4/41/Etool_link.png" height="16" width="16" alt="[[]]">', t: 'Вставить викиссылку', f: 'Статья «Традиции»'}, br
, {w: '[+ (описание ссылки)]', b: '<img src="/files/3/3b/Etool_world_link.png" height="16" width="16" alt="→www">', t: 'Внешняя ссылка', f: '(url)'}
, {w: '<span class="plainlinks">[+ (описание ссылки)]</span>', b: '<img src="/files/e/e6/Etool_www_page.png" height="16" width="16" alt="→www">', t: 'Внешняя ссылка без значка', f: '(url)'}
, {t: 'Сноски', nl: true}
, {w: '<ref>+</ref>', b: '<img src="/files/0/02/Etool_bookmark.png" width="16" height="16" alt="Сноска" />', t: 'Сноска', f: 'Текст сноски'}
, {w: '{{тчк}}<ref>+</ref>', b: '<span style="margin-right: -0.21em">.</span><sup class="reference">[1]</sup>', t: 'Точка и сноска', f: 'Текст сноски'}
, {w: '{{,}}<ref>+</ref>', b: '<span style="margin-right: -0.21em">,</span><sup class="reference">[1]</sup>', t: 'Запятая и сноска', f: 'Текст сноски'}
, {t: 'Источники', nl: true}
, {w: '{{статья|автор=|заглавие=|оригинал=|ссылка=+|издание=|тип=|место={{М.}}|год=[[]]|том=|номер=|страницы=}}', b: '<img src="/files/d/d6/Etool_newspaper_link.png" height="16" width="16" alt="→[P]">', t: 'Статья', f: '(url)'}
, {w: '{{книга|автор=|часть=|заглавие=|оригинал=|язык_оригинала=|язык_оригинала_сокращённо=|переводчик=|ссылка=+|издание=|место={{М.}}|издательство=|год=[[]]|страницы=|isbn=}}', b: '<img src="/files/c/cd/Etool_book_link.png" height="16" width="16" alt="→[B]">', t: 'Книга', f: '(url)'}
, {w: '{{cite_news|first=|last=|authorlink=|author=|coauthors=|title=|url=+|format=|work=|publisher=|location=|id=|pages=|page=|date=|accessdate=|language=|quote=|archiveurl=|archivedate=}}', b: '<img src="/files/d/d6/Etool_newspaper_link.png" height="16" width="16" alt="→[P]">', t: 'Новость', f: '(url)'}
, {w: '{{cite_web|first=|last=|authorlink=|author=|coauthors=|title=|url=+|format=|work=|publisher=|location=|id=|pages=|page=|date=|accessdate=|language=|quote=|archiveurl=|archivedate=}}', b: '<img src="/files/5/58/Etool_page_link.png" width="16" height="16" alt="→text" />', t: 'WWW', f: '(url)'}
, {t: 'Блоги и форумы', nl: true}
, {w: '{{lj user|+}}', b: '<img src="/files/c/cd/Etool_user.png" width="16" height="16" alt="ЖЖuser" />', t: 'Пользователь ЖЖ', f: '(ник)'}
, {w: '{{lj comm|+}}', b: '<img src="/files/4/4b/Etool_group_link.png" height="16" width="16" alt="ЖЖС">', t: 'Сообщество ЖЖ', f: '(ник)'}
, {w: '{{lj post|ник=+|№=|название=|автор=|дата=}}', b: '<img src="/files/d/d6/Etool_livejournal.png" height="16" width="16" alt="ЖЖ">', t: 'Запись ЖЖ', f: '(ник автора)'}, br
, {w: '{{ljr user|+}}', b: '<img src="/files/d/d4/Etool_user_red.png" width="16" height="16" alt="ЖЖР user" />', t: 'Пользователь ЖЖР', f: '(ник)'}
, {w: '{{ljr comm|+}}', b: '<img src="/files/4/4b/Etool_group_link.png" height="16" width="16" alt="ЖЖРС">', t: 'Сообщество ЖЖР', f: '(ник)'}, br
, {w: '{{ФИГШ:пост|№_поста|+}}', b: 'Пост ФИГШ', t: null, f: '(название)'}
, {w: '{{ФИГШ:тема|№_темы|+}}', b: 'Тема ФИГШ', t: null, f: '(название)'}
, {t: 'См. также в', nl: true}
, {w: '{{См. также в|tsdne=+}}\n', b: 'ТСДНЭ', t: null, f: '(название)'}
, {w: '{{См. также в|nmp=+}}\n', b: 'НМП', t: null, f: '(название)'}
, {t: 'Запросы источников', nl: true}
, '{{Источник}} {{Кто?}} {{Когда?}}'
, {t: 'Разделы сносок и источников', nl: true}
, {w: '\n== Ссылки ==\n* ', b: '<img src="/files/9/91/Etool_books.png" height="16" width="16" alt="books">', t: 'Ссылки'}
, {t: 'Автосписки: ', nl: true}
, {w: '{{автобиблиография}}\n', b: 'библиография'}
, {w: '{{список текстов по теме}}\n', b: 'тексты по теме'}
, {w: '{{тексты автора}}\n', b: 'тексты автора'}
, {w: '\n== Примечания ==\n{{примечания}}\n', b: '<img src="/files/3/38/Etool_column_one.png" height="16" width="16" alt="books">', t: 'Примечания'}
, {w: '\n== Примечания ==\n{{примечания|2}}\n', b: '<img src="/files/7/7d/Etool_column_two.png" height="16" width="16" alt="books">', t: 'Примечания в 2 столбца'}
, {t: 'Цитирование', nl: true}
, {w: '\n{{цитата|+|источник}}', b: '<img src="/files/0/05/Etool_document_quote.png" height="16" width="16" alt="books">', t: 'Цитата', f: 'Цитируемый текст'}, br
, {t: 'Кавычки:'}
, {w: '<q>+</q>', b: '«<span class="plus_sign">a</span>»', t: 'Универсальные', f: 'Текст в кавычках'}
, {w: '«+»', b: '«<span class="plus_sign">a</span>»', t: 'Обычные', f: 'Текст в кавычках'}
, {w: '„+“', b: '„<span class="plus_sign">a</span>“', t: 'Вложенные', f: 'Текст в кавычках второго уровня'}, br
, {w: '“+”', b: '“<span class="plus_sign">a</span>”', t: 'Английские', f: 'Текст в кавычках внутри английского текста'}
, {w: '»+«', b: '»<span class="plus_sign">a</span>«', t: 'Немецкие', f: 'Текст в кавычках внутри немецкого текста'}, br
, {w: '{{current}}', b: '<img src="/files/0/02/Current_event_marker.png" alt="!" height="16" width="21" />', t: 'Текущие события'}
, {url: mw.util.getUrl ('Справка:Примечания и сноски'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Примечания и сноски', nl: true}
], separator, [
{b: '<img src="/files/c/c7/Etool_image.png" width="16" height="16" alt="Файл" />', t: 'Изображения', nl: true}
, {w: '{{Файл|+|ширина|right}}', b: '<img src="/files/c/c7/Etool_image.png" width="16" height="16" alt="-[]-" />', t: 'Универсальное изображение', f: 'Имя файла'}
, {w: '[[Файл:+|thumb|(размер)px|(описание)]]', b: '<img src="/files/d/d7/Etool_image_right.png" width="16" height="16" alt="-[]-" />', t: 'Изображение справа', f: 'Имя файла'}
, {w: '[[Файл:+|thumb|center|(размер)px|(описание)]]', b: '<img src="/files/8/88/Etool_image_center.png" width="16" height="16" alt="-[]-" />', t: 'Изображение в центре', f: 'Имя файла'}
, {w: '[[Файл:+|(размер)px]]', b: '<img src="/files/a/aa/Etool_inline_image.png" height="16" width="17" alt="=[]=">', t: 'Внутристрочное изображение', f: 'Имя файла'}, br
, {w: '{{Строчный блок|[[Файл:+|thumb|center|(размер)px|(описание)]]}}', b: '<img src="/files/8/83/Etool_inline_block_image.png" height="16" width="17" alt="[][][]">', t: 'Изображение в строчном блоке', f: 'Имя файла'}, br
, {w: '\n<gallery>+</gallery>\n', b: '<img src="/files/d/d6/Etool_images.png" height="16" width="16" alt="[][][]">', t: 'Галерея', f: 'Список файлов'}
, {w: '{{изображения}}', b: '<img src="/files/d/d6/Etool_images.png" height="16" width="16" alt="↓[][][]">', t: 'Автоматическая галерея'}
, {url: mw.util.getUrl ('Справка:Изображения'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Изображения', nl: true}
], [
{b: '<img src="/files/0/0f/Etool_youtube.png" height="16" width="16" alt="YouTube">', t: 'Видео YouTube', nl: true}
, {w: '{{YouTube|+|ширина=(ширина)|(описание)}}', b: '<img src="/files/5/51/Etool_youtube_right.png" height="16" width="19" alt="film→">', t: 'YouTube справа', f: 'Номер ролика'}
, {w: '{{YouTube|+|ширина=(ширина)|(описание)|центр=да}}', b: '<img src="/files/5/5c/Etool_youtube_centered.png" height="15" width="16" alt="film">', t: 'YouTube в центре', f: 'Номер ролика'}
, {w: '{{Строчный блок|{{YouTube|+|ширина=(ширина)|(описание)|центр=да}}}}', b: '<img src="/files/b/bf/Etool_youtube_inline.png" height="16" width="32" alt="film">', t: 'YouTube в строчном блоке', f: 'Номер ролика'}, br
, {w: '{{VKontakte|+|id|hash|подпись|ширина=}}', b: '<img src="/files/d/d0/VK_video_icon.png" height="16" width="29" alt="film→">', t: 'VKontakte справа', f: 'id ролика'}
, {url: mw.util.getUrl ('Справка:Видео'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Видео', nl: true}
, {b: '<img src="/files/b/bf/Music-beam-16.png" height="16" width="16" alt="Ноты">', t: 'Ноты', nl: true}
, {b: '<img src="/files/b/bf/Music-beam-16.png" height="16" width="16" alt="Ноты">', w: '<score lang="lilypond" raw="" midi="" vorbis="">+</score>', t: 'Ноты lilypond', f: 'Ноты lilypond'}
, {b: '<img src="/files/b/bf/Music-beam-16.png" height="16" width="16" alt="Ноты">', w: '<score lang="ABC" raw="" midi="" vorbis="">+</score>', t: 'Ноты ABC', f: 'Ноты ABC'}
, {url: mw.util.getUrl ('Справка:Ноты'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Ноты', nl: true}
], [
{b: '<img src="/files/f/fe/Etool_globe_model.png" height="16" width="16" alt="[M]">', t: 'Карта WikiLeaflet', nl: true}
, {w: '{{wl|\n+\n}}', b: '<img src="/files/1/15/Etool_map.png" height="16" width="16" alt="[M]">', t: 'Вставить карту', f: 'Содержимое карты — дополнительные вызовы {{wl}}.'}, br
, {w: '{{wl|точка|+|долгота|текст|тип|надпись=надпись}}', b: '<img src="/files/3/32/Etool_location_pin.png" height="16" width="16" alt="P">', t: 'Поставить значок', f: 'широта'}
, {w: '{{wl|значок|+|файл|ширина|высота|тень|ширина тени|высота тени|сдвиг значка x|сдвиг значка y|сдвиг тени от пузыря x|сдвиг тени от пузыря y|надпись=надпись}}L', b: '<img src="/files/b/b4/Etool_legend.png" height="16" width="16" alt="...">', t: 'Определить значок', f: 'идентификатор значка'}, br
, {w: '{{wl|центр|+|долгота|увеличение}}', b: '<img src="/files/b/be/Etool_compass.png" height="16" width="16" alt="compass">', t: 'Центр и масштаб', f: 'широта'}
, {w: '{{wl|высота|+}}', b: '<img src="/files/7/77/Etool_vrule.png" width="16" height="16" alt="Файл" />', t: 'Высота', f: 'целая высота карты в пикселах'}
, {w: '{{wl|редактор}}', b: '<img src="/files/e/e1/Etool_map_edit.png" height="16" width="16" alt="[M]/">', t: 'Возможность редактировать', f: '-'}, br
, {t: 'Тайлы от:'}
, {w: '{{wl|тайлы|osm}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'osm'}
/*, {w: '{{wl|тайлы|local}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'сервер «Традиции»'}*/
, {w: '{{wl|тайлы|osmarender}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'osmarender'}
, {w: '{{wl|тайлы|cycle}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'cycle'}
, {w: '{{wl|тайлы|mapquest}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'mapquest'}
, {w: '{{wl|тайлы|openaerial}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'openaerial'}
, {w: '{{wl|тайлы|osmosnimki}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'osmosnimki'}
, {w: '{{wl|тайлы|kosmosnimki}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'kosmosnimki'}
, {w: '{{wl|тайлы|openmapsurfer}}', b: '<img src="/files/b/b8/Etool_server_database.png" height="16" width="16" alt="←S">', t: 'openmapsurfer'}
, br
, '{{wl|меню|+}} {{wl|фильтры|+}} {{wl|пункт|+}} {{wl|GeoJSON|<nowiki>+</nowiki>}}'
, {url: mw.util.getUrl ('Справка:Карты'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Карты', nl: true}
], separator, [
{b: '', t: 'Вики', nl: true}
, {w: '#перенаправление [[+]]', b: '<img src="/files/4/40/Etool_document_redirect.png" height="16" width="16" alt="↵">', t: 'Перенаправление', f: 'На какую статью перенаправить'}, br
, {w: '{{другие значения|+}}', b: 'Др. зн.', t: 'Есть другие значения'}
, {w: '{{неоднозначность}}', b: '<img src="/files/thumb/5/5f/Disambig_gray.svg/16px-Disambig_gray.svg.png" height="16" width="16" alt="E">', t: 'Неоднозначность'}, br,
, {w: '{{main|+}}', b: '<img src="/files/3/32/Icons-mini-icon_2main.png" height="16" width="16" alt="→">', t: 'Основная статья'},
, {w: '{{обзор|+}}', b: '<img src="/files/a/a9/Icons-mini-icon_2brief.png" height="16" width="16" alt="↑">', t: 'Обзор'}, br
, {w: '{{+}}', b: '<img src="/files/2/21/Etool_template.png" height="16" width="41" alt="{{*}}">', t: 'Вызвать шаблон', f: 'Шаблон'}
, {w: '{{!}}', t: '| для передачи в шаблон', f: '-'}, br
, {w: '\n[[Категория:+]]', b: '<img src="/files/3/32/Etool_bookshelf.png" width="16" height="16" alt="Добавить категорию" />', t: 'Добавить категорию', f: 'Категория'}, br
, {w: '\n{{DISPLAYTITLE:+}}', b: '<img src="/files/7/78/Etool_displaytitle.png" height="16" width="16" alt="<>">', t: 'Отображаемое название'}
, {w: '\n{{DEFAULTSORT:+}}', b: '<img src="/files/a/a2/Etool_page_key.png" height="16" width="16" alt="↑↓">', t: 'Ключ сортировки'}, br
, {b: '', t: 'Заготовки и черновики', nl: true}
, {w: '{{заготовка}}', b: '<img src="/files/thumb/9/9d/Blank_template.gif/16px-Blank_template.gif" height="16" width="16" alt="<!>">', t: 'Заготовка'}
, {w: '{{черновик}}', b: '<img src="/files/7/73/Etool_construction.png" height="16" width="16" alt="<!>">', t: 'Черновик'}
, {w: '{{сборник ссылок}}', b: '<img src="/files/thumb/Asymmetrical_symbol_of_Chaos.ant.svg/16px-Asymmetrical_symbol_of_Chaos.ant.svg.png" height="16" width="16" alt="<!>">', t: 'Сборник ссылок'}
, {w: '{{Написал|+}}', b: '<img src="/files/3/3d/Etool_document_signature.png" height="16" width="16" alt="~">', t: 'Написал', f: '(автор)'}
],
mw.config.get ('wgTitle') && mw.config.get ('wgTitle').indexOf (':') > -1 ? [
{b: '<img src="/files/6/66/Etool_infobox.png" alt="К" width="14" height="16" />', t: 'Карточка текста', w: '{{Текст\n'
+ ' | название = (название всего текста, по умолчанию часть названия страницы после двоеточия)\n'
+ ' | оригинал названия = (название на языке, с которого переведён текст)\n'
+ ' | подзаголовок = (подзаголовок)\n'
+ ' | жанр = (жанр текста)\n'
+ ' | категория = (категория, по умолчанию, Традиция:Авторские статьи; -, если категория не должна добавляться)\n'
+ ' | автор = (автор, по умолчанию часть названия страницы перед двоеточием)\n'
+ ' | оригинал автора = (имя автора на языке, с которого переведён текст)\n'
+ ' | переводчик = (имя переводчика иностранного текста) \n'
+ ' | язык оригинала = (язык, на котором первоначально написан переведённый текст)\n'
+ ' | язык перевода = (язык, на который переведён текст, по умолчанию — русский)\n'
+ ' | переведено = (дата перевода)\n'
+ ' | раздел = (название раздела текста на странице)\n'
+ ' | № раздела = (номер раздела текста, который содержит эта страница)\n'
+ ' | без содержания = (задать любое непустое значение, чтобы подавить вывод содержания)\n'
+ ' | написано = (дата написания)\n'
+ ' | публикация = (ссылка на первую публикацию)\n'
+ ' | предыдущая = (предыдущая книга или текст в серии или сборнике)\n'
+ ' | следующая = (следующая книга или текст в серии или сборнике)\n'
+ ' | источник = (откуда текст попал на «Традицию»)\n'
+ ' | дата = (дата первой публикации)\n'
+ ' | раздел0 = (ссылка на введение к большому тексту)\n'
+ ' | раздел1 = (ссылка на первый раздел большого текста)\n'
+ ' | раздел2 = (ссылка на второй раздел большого текста)\n'
+ ' …\n'
+ ' | раздел20 = (ссылка на двадцатый раздел большого текста)\n'
+ ' | текст эпиграфа = (текст эпиграфа)\n'
+ ' | автор эпиграфа = (автор эпиграфа)\n'
+ ' | источник эпиграфа = (источник эпиграфа)\n'
+ ' | обложка = (название файла, содержащего изображение обложки)\n'
+ ' | предмет = Предмет текста\n'
+ ' | примечание = (примечание об истории текста и т.п.)\n'
+ ' | описание = (ссылка на статью «Традиции» с описанием текста)\n'
+ ' | ББК = (ББК)\n'
+ ' | УДК = (УДК)\n'
+ ' | аудио = (ссылка на звуковой файл с чтением текста)\n'
+ '}}\n'}
, {url: mw.util.getUrl ('Справка:Тексты'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Тексты', nl: true}
] : null
, mw.config.get ('wgNamespaceNumber') === 10 || mw.config.get ('wgNamespaceNumber') === 156 ? [
{t: 'Шаблоны', nl: true}
, '{{{+}}} {{!}}', br
, {w: '<includeonly>+</includeonly>', b: '<includeonly>'}
, {w: '<noinclude>+</noinclude>', b: '<noinclude>'}, br
, '\n[[Категория:Традиция:Шаблоны|+]] {{doc}}', br
, '{{PAGENAME}} {{FULLPAGENAME}} {{#if:|+|}} {{#ifeq:||+|}} {{#switch:|1=+|2=|default=}}', br
, '{{#vardefine:a=+}} {{#var:+}} {{#forargs:префикс|параметр|значение|+}}'
, '{{#invoke:Модуль|функция|параметры}}'
, {url: mw.util.getUrl ('Традиция:Шаблоны'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Шаблоны', nl: true}
] : null
, mw.config.get ('wgNamespaceNumber') === 14 ? [
{t: 'Категория', nl: true}
, '{{Категория|+|форма}} {{catmain|+}}'
] : null
, mw.config.get ('wgNamespaceNumber') === 152 ? [
{t: 'SMW', nl: true}
, '{{Свойство|+|тип|опис|общ}} [[Имеет_тип:+]] {{Отношение|+|опис|общ}}'
] : null
, mw.config.get ('wgNamespaceNumber') === 6 || mw.config.get ('wgTitle') === 'Upload' || mw.config.get ('wgTitle') === 'Загрузка' ? [
{b: '<img src="/files/a/a3/Etool_image_desc.png" height="16" width="16" alt="Ξ">'
, t: 'Описание', w: '{{Изображение'
+ '\n| Название = {{PAGENAME}}'
+ '\n| Объект ='
+ '\n| Тип ='
+ '\n| Описание ='
+ '\n| Автор ='
+ '\n| Время создания ='
+ '\n| Источник ='
+ '\n| Лицензия ='
+ '\n}}'
}
, {t: 'Лицензии', nl: true}
, licenses
] : null, [
{w: function (s) {
return 'Above:\n'
+ 'HTML:\n' + newMenuHTML (mw.tools_above) + '\n'
+ 'CSS:\n' + newMenuCSS (mw.tools_above) + '\n'
+ 'Below:\n'
+ 'HTML:\n' + newMenuHTML (mw.tool_below) + '\n'
+ 'CSS:\n' + newMenuCSS (mw.tools_below) + '\n';
}, t: 'Код панелей', b: 'Код!', all: true}
],
[
{url: mw.util.getUrl ('Справка:Справка'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Содержание', nl: true}
, {url: mw.util.getUrl ('Традиция:Правила и указания'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Правила и указания'}, br
, {url: mw.util.getUrl ('Традиция:Вики-разметка'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Вики-разметка'}, br
, {url: mw.util.getUrl ('Традиция:Типографика'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Типографика'}, br
, {url: mw.util.getUrl ('Традиция:Шаблоны'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Шаблоны'}, br
, {url: mw.util.getUrl ('Традиция:Как делать таблицы'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Таблицы'}, br
, {url: mw.util.getUrl ('Справка:Примечания и сноски'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Примечания и сноски'}, br
, {url: mw.util.getUrl ('Справка:Изображения'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Изображения'}, br
, {url: mw.util.getUrl ('Справка:Видео'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Видео'}, br
, {url: mw.util.getUrl ('Справка:Карты'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Карты'}, br
, {url: mw.util.getUrl ('Справка:Графы'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Графы'}, br
, {url: mw.util.getUrl ('Справка:Формулы'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Формулы'}, br
, {url: mw.util.getUrl ('Справка:Тексты'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Тексты'}
]
];
// Нижняя панель:
mw.tools_below = [
[
{b: 'Яя', t: 'Кириллица', nl: true, leader: true}
, '<<Основные:>> А а Б б В в Г г Д д Е е Ё ё Ж ж З з И и Й й К к Л л М м Н н О о П п Р р С с Т т У у Ф ф Х х Ц ц Ч ч Ш ш Щ щ Ъ ъ Ы ы Ь ь Э э Ю ю Я я br '
+ '<<Старорусские:>> Ѳ ѳ І і Ѣ ѣ Ѵ ѵ <<Древнерусские:>> Ѕ ѕ Ѥ ѥ Ѯ ѯ Ѹ ѹ Ѱ ѱ Ѡ ѡ Ѻ ѻ Ѽ ѽ Ѿ ѿ Ѧ ѧ Ѩ ѩ Ѫ ѫ Ѭ ѭ Ѷ ѷ ҂ а҃ б҄ а҅ а҆ ́а {{подст:у́}} br '
+ '<<Другие_славянские:>> Ґ ґ Ѓ ѓ Ђ ђ Є є І і Ї ї Й й Ј ј Ќ ќ Љ љ Њ њ Ћ ћ Ў ў Џ џ br '
+ '<<Неславянские:>> Ә ә Ө ө Ғ ғ Җ җ Қ қ Ҝ ҝ Ң ң Ү ү Ұ ұ Ҳ ҳ Ҹ ҹ Һ һ Ҕ ҕ Ӣ ӣ Ӯ ӯ Ҙ ҙ Ҡ ҡ Ҥ ҥ Ҫ ҫ Ӑ ӑ Ӓ ӓ Ӕ ӕ Ӗ ӗ Ӱ ӱ Ӳ ӳ Ӹ ӹ Ӏ br '
+ 'Ҟ ҟ Ҧ ҧ Ҩ ҩ Ҭ ҭ Ҵ ҵ Ҷ ҷ Ҽ ҽ Ҿ ҿ Ӂ ӂ Ӄ ӄ Ӈ ӈ Ӌ ӌ Ӛ ӛ Ӝ ӝ Ӟ ӟ Ӡ ӡ Ӥ ӥ Ӧ ӧ Ӫ ӫ Ӵ ӵ '
], [
{b: 'Ωω', t: 'Греческие', nl: true, leader: true}
, '<<Основные:>> Α α Β β Γ γ Δ δ Ε ε Ζ ζ Η η Θ θ Ι ι Κ κ Λ λ Μ μ Ν ν Ξ ξ Ο ο Π π Ρ ρ Σ σ ς Τ τ Υ υ Φ φ Χ χ Ψ ψ Ω ω br '
+ '<<Шаблоны:>> {{lang-el|+}} {{lang-el2|+}} {{Polytonic|+}} br '
+ '<<С_тонами:>> Ά ά Έ έ Ή ή Ί ί Ό ό Ύ ύ Ώ ώ ᾼ ᾳ ᾴ Ὰ ὰ ᾲ ᾶ ᾷ Ἀ ἀ ᾈ ᾀ Ἁ ἁ ᾉ ᾁ Ἄ ἄ ᾌ ᾄ Ἂ ἂ ᾊ ᾂ Ἆ ἆ ᾎ ᾆ Ἅ ἅ ᾍ ᾅ Ἃ ἃ ᾋ ᾃ Ἇ ἇ ᾏ ᾇ br '
+ 'Ὲ ὲ Ἐ ἐ Ἑ ἑ Ἔ ἔ Ἒ ἒ Ἕ ἕ Ἓ ἓ ῌ ῃ ῄ Ὴ ὴ ῂ ῆ ῇ Ἠ ἠ ᾘ ᾐ Ἡ ἡ ᾙ ᾑ Ἤ ἤ ᾜ ᾔ Ἢ ἢ ᾚ ᾒ Ἦ ἦ ᾞ ᾖ Ἥ ἥ ᾝ ᾕ Ἣ ἣ ᾛ ᾓ Ἧ ἧ ᾟ ᾗ br '
+ 'Ὶ ὶ ῖ Ἰ ἰ Ἱ ἱ Ἴ ἴ Ἲ ἲ Ἶ ἶ Ἵ ἵ Ἳ ἳ Ἷ ἷ Ὸ ὸ Ὀ ὀ Ὁ ὁ Ὄ ὄ Ὂ ὂ Ὅ ὅ Ὃ ὃ ῤ Ῥ ῥ Ὺ ὺ ῦ ὐ Ὑ ὑ ὔ ὒ ὖ Ὕ ὕ Ὓ ὓ Ὗ ὗ br '
+ 'ῼ ῳ ῴ Ὼ ὼ ῲ ῶ ῷ Ὠ ὠ ᾨ ᾠ Ὡ ὡ ᾩ ᾡ Ὤ ὤ ᾬ ᾤ Ὢ ὢ ᾪ ᾢ Ὦ ὦ ᾮ ᾦ Ὥ ὥ ᾭ ᾥ Ὣ ὣ ᾫ ᾣ Ὧ ὧ ᾯ ᾧ br '
+ '<<Архаичные:>> Ϝ ϝ Ϙ ϙ Ϛ ϛ Ϻ ϻ Ϡ ϡ <<Варианты:>> ϐ ϑ ϳ ϰ ϱ ϲ ϕ ϖ <<Коптские:>> Ϣ ϣ Ϥ Ϧ ϧ Ϩ ϩ Ϫ ϫ Ϭ ϭ Ϯ ϯ br '
+ '<<Пунктуация:>> ʹ ͵ ͺ ;'
], [
{b: 'Zz', t: 'Латинские', nl: true, leader: true}
, '<<Основные:>> A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p R r S s T t U u V v W w X x Y y Z z br '
+ '<<Шаблоны:>> {{Unicode|+}} br '
+ '<<Дополнительные:>> A a Á á À à Â â Ä ä Ǎ ǎ Ă ă Ā ā Ã ã Å å Ą ą Æ æ Ǣ ǣ B b C c Ć ć Ċ ċ Ĉ ĉ Č č Ç ç D d Ď ď Đ đ Ḍ ḍ Ð ð br '
+ 'E e É é È è Ė ė Ê ê Ë ë Ě ě Ĕ ĕ Ē ē Ẽ ẽ Ę ę Ə ə F f G g Ġ ġ Ĝ ĝ Ğ ğ Ģ ģ H h Ĥ ĥ Ħ ħ Ḥ ḥ I i İ ı Í í Ì ì Î î Ï ï Ǐ ǐ Ĭ ĭ Ī ī Ĩ ĩ Į į J j Ĵ ĵ br '
+ 'K k Ķ ķ L l Ĺ ĺ Ŀ ŀ Ľ ľ Ļ ļ Ł ł Ḷ ḷ Ḹ ḹ M m Ṃ ṃ N n Ń ń Ň ň Ñ ñ Ņ ņ Ṇ ṇ O o Ó ó Ò ò Ô ô Ö ö Ǒ ǒ Ŏ ŏ Ō ō Õ õ Ǫ ǫ Ő ő Ø ø Œ œ br '
+ 'P p Q q R r Ŕ ŕ Ř ř Ŗ ŗ Ṛ ṛ Ṝ ṝ S s Ś ś Ŝ ŝ Š š Ş ş Ṣ ṣ ß T t Ť ť Ţ ţ Ṭ ṭ Þ þ U u Ú ú Ù ù Û û Ü ü Ǔ ǔ Ŭ ŭ Ū ū Ũ ũ Ů ů Ų ų Ű ű Ǘ ǘ Ǜ ǜ Ǚ ǚ Ǖ ǖ br '
+ 'V v W w Ŵ ŵ X x Y y Ý ý Ŷ ŷ Ÿ ÿ Ỹ ỹ Ȳ ȳ Z z Ź ź Ż ż Ž ž ß Ð ð Þ þ Ə ə'
], [
{b: 'א', t: 'Еврейские', nl: true, leader: true}
, '<<Шаблоны:>> {{lang-he|+}} {{lang-he2|+}} br '
+ '<<Основные:>> א ב ג ד ה ו ז ח ט י ך כ ל ם מ ן נ ס ע ף פ ץ צ ק ר ש ת br '
+ '<<Дополнительные:>> ׳ ״ װ ױ ײ '
], [
{b: 'ار', t: 'Арабские', nl: true, leader: true}
, '<<Шаблоны:>> {{lang-ar|+}} {{lang-ar2|+}} br '
+ '<<Основные:>> ا ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي br '
+ '<<Дополнительные:>> ﺁ ﺓ ﻻ ﷲ ء '
, {w: 'ى', b: 'ى', t: 'алиф максура'}
, {w: 'ي', b: 'ي', t: 'йе'} , br
, '<<Пунктуация:>> ، ؛ ؟ br '
+ '<<Цифры:>> ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ٪ ٫ ٬'
], [
{b: '[ɑ]', t: 'IPA для английского языка', nl: true, leader: true}
, '<<Шаблоны:>> {{IPA-en|+}} {{IPA|/+/}} ‹+› br '
+ 'ˈ ˌ ŋ ɡ tʃ dʒ ʃ ʒ θ ð ʔ iː ɪ uː ʊ ʌ ɜr eɪ ɛ æ oʊ ɒ ɔː ɔɪ ɔr ɑː ɑr aɪ aʊ ə ər ɨ ɵ ʉ'
, {b: '[ʔ]', t: 'IPA для других языков', nl: true}
, '<<Шаблон:>> {{IPA|+}} br '
+ 'ʈ ɖ ɟ ɡ ɢ ʡ ʔ ɸ β θ ð ʃ ʒ ɕ ʑ ʂ ʐ ç ʝ ɣ χ ʁ ħ ʕ ʜ ʢ ɦ ɱ ɳ ɲ ŋ ɴ ʋ ɹ ɻ ɰ ʙ ⱱ ʀ ɾ ɽ ɬ ɮ ɺ ɭ ʎ ʟ ʍ ɥ ɧ ʼ ɓ ɗ ʄ ɠ ʛ br '
+ 'ʘ ǀ ǃ ǂ ǁ ɨ ʉ ɯ ɪ ʏ ʊ ø ɘ ɵ ɤ ə ɛ œ ɜ ɞ ʌ ɔ æ ɐ ɶ ɑ ɒ br '
+ 'ʰ ʱ ʷ ʲ ˠ ˤ ˀ ᵊ k̚ ⁿˡ ˈ ˌ ː ˑ t̪ d̪ s̺ s̻ θ̼ s̬ n̥ ŋ̊ a̤ a̰ β̞ ˕ r̝ ˔ o˞ ɚ ɝ e̘ e̙ u̟ i̠ ɪ̈ e̽ ɔ̹ ɔ̜ n̩ ə̆ ə̯ ə̃ ȷ̃ ɫ z̴ ə̋ ə́ ə̄ ə̀ ə̏ ə̌ ə̂ ə᷄ ə᷅ ə᷇ ə᷆ ə᷈ ə᷉ t͡ʃ d͡ʒ t͜ɬ ‿ br '
+ '˥ ˦ ˧ ˨ ˩ ꜛ ꜜ | ‖ ↗ ↘ k͈ s͎'
], separator, [
{t: 'Формулы TEX', nl: true},
{w: '<math>+</math>', b: '<img src="/files/9/96/Etool_pi_math.png" height="16" width="16" alt="π">', t: 'Вставить внутристрочную формулу', f: 'Формула'}, br,
{w: '\n: <math>+</math>\n', b: '<img src="/files/c/ce/Etool_pi_math_centered.png" height="16" width="16" alt="π">', t: 'Вставить выносную формулу', f: 'Формула'}, br,
{url: mw.util.getUrl ('Справка:Формулы'), b: '<img src="/files/d/d5/Etool_help.png" height="16" width="16" alt="?">', t: 'Справка: Формулы'}
], separator
// Символы:
, [ // Математические:
{b: '<img src="/files/3/37/Etool_sum.png" width="16" height="16" alt="Σ" />', t: 'Математические знаки', nl: true, leader: true}
, '− × ÷ ⋅ ° +² +³ ∗ ∘ ± ∓ ≤ ≥ ≠ ≡ ≅ ≜ ≝ ≐ ≃ ≈ ⊕ ⊗ ∞ br '
+ '≪ ≫ ∝ √ ∤ ≀ ◅ ▻ ⋉ ⋊ ⋈ ∴ ∵ ∙ ∷ ⋮ ⋯ ⋰ ⋱ br '
+ '¬ ∧ ∨ ⊻ ∀ ∃ ∄ ∅ ∈ ∉ ∋ ⊆ ⊈ ⊊ ⊂ ⊄ ⊇ ⊉ ⊋ ⊃ ⊅ ∪ ∩ br '
+ '∑ ∏ ∐ ′ ∫ ∬ ∭ ∮ ∇ ∂ ∆ ∅ ℂ ℍ ℕ ℙ ℚ ℝ ℤ ℵ br '
+ '⌊ ⌋ ⌈ ⌉ ⊤ ⊥ ⊢ ⊣ ⊧ □ ∠ ⟨ ⟩ − br '
+ ' ⃛ ⃜ ∁ ‵ ∂ ∞ ∟ ∠ ∡ ∢ ⊾ ⦜ ⊤ * ¹ ² ³ _ | ‖ br '
+ '√ ⊹ ⋔ ⌕ ⎰ ⎱ Ⓢ ╱ ▭ ⧴ ⩮ ⊶ ⊷ ⊸ ⋈ ⌢ ⌣ □ ▪ ♢ ◊ ⧫'
], [
{b: '♔', t: 'Разные символы', nl: true, leader: true}
, '<<Шахматы:>> ♔ ♕ ♖ ♗ ♘ ♙ ♚ ♛ ♜ ♝ ♞ ♟ br '
+ '<<Масти:>> ♠ ♣ ♥ ♦ ♡ ♢ ♤ ♧ br '
+ '<<Триграммы:>> ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷ br '
+ '<<Планеты:>> ☼ ☽ ☾ ☿ ♀ ♁ ♂ ♃ ♄ ♅ ♆ ♇ br '
+ '<<Созвездия:>> ♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓ br '
+ '<<Узлы:>> ☉ ☊ ☋ ☌ ☍ br '
+ '<<Ноты:>> ♩ ♪ ♫ ♬ ♬ ♭ ♮ ♯ br '
+ '<<Разные:>> ® © ™ ♀ ♂ ℅ ℓ ℗ µ Ω ℮ ☠ ☡ ☢ ☣ br '
+ '☤ ☥ ☦ ☧ ☨ ☩ ☪ ☫ ☬ ✡ ☭ ☮ ☯ '
], [
{b: '₽', t: 'Валюты и дроби', nl: true, leader: true}
, '<<Валюты:>> ¤ ₽ ₳ ฿ ₵ ¢ ₡ ₢ $ ₫ ₯ € ₠ ₣ ƒ br '
+ ' ₴ ₭ ₤ ℳ ₥ ₦ ₧ ₰ £ ៛ ₨ ₪ ৳ ₮ ₩ ¥ br '
+ '<<Дроби:>> ½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞ '
], [
{b: '⇆', t: 'Стрелки', nl: true, leader: true}
, '↺ ↻ ↑ → ← ↓ ↔ ↕ ↖ ↗ ↘ ↙ ↚ ↛ ↜ ↝ ↞↠ ↢ ↣ ↦ ↩ ↪ ↫ ↬ ↭ ↮ br '
+ ' ⇍ ⇎ ⇏ ⇐ ⇑ ⇒ ⇓ ⇔ ⇕ ⇚ ⇛ ⇝ ☚ ☛ ☜ ☝ ☞ ☟ ➔ ➘ ➙ ➚ ➛ ➜ ➝ ➟ ➠ ➡ br '
+ ' ➢ ➣ ➤ ➥ ➦ ➧ ➨ ➨ ➪ ➫ ➬ ➭ ➮ ➯ ➱ ➲ ➳ ➴ ➵ ➶ ➷ ➸ ➹ ➺ ➻ ➼ ➽ ➾ br '
+ '⇵ ⟵ ⟶ ⟷ ⟸ ⟹ ⟺ ⟼ ⤒ ⤓ ⥎ ⥏ ⥐ ⥑ ⥒ ⥓ ⥔ ⥕ ⥖ ⥗ ⥘ ⥙ ⥚ ⥛ ⥜ ⥝ ⥞ ⥟ ⥠ ⥡ br '
+ '↰ ↱ ↶ ↷ ↼ ↽ ↾ ↿ ⇀ ⇁ ⇂ ⇃ ⇄ ⇅ ⇆ ⇇ ⇈ ⇉ ⇊ ⇋ ⇌ △ ▴ ▵ ▸ ▹ ▽ ▾ ▿ ◂ ◃ br '
+ '⇄ ⇅ ⇆ ⇇ ⇈ ⇉ ⇊ ⇋ ⇌ △ ▴ ▵ ▸ ▹ ▽ ▾ ▿ ◂ ◃'
], // Подписи и обсуждения:
mw.config.get ('wgNamespaceNumber') % 2 === 1 || mw.config.get('wgNamespaceNumber') === 4 ? separator : null,
mw.config.get ('wgNamespaceNumber') % 2 === 1 || mw.config.get('wgNamespaceNumber') === 4 ? [
{t: 'Подписи', nl: true}
, {w: '<br />~~~~', b: '<img src="/files/c/c1/Etool_text_signature.png" width="16" height="16" alt="~~" />', t: 'С новой строки'}, br
, '<<В_той_же_строке:>> --~~~~ ~~~~ —_~~~~ ~~~', br
, {w: '{{unsigned|+}}'}
, {t: 'Голосования и обсуждения', nl: true}
, {w: '{{За}}', b: '<img src="/files/thumb/9/94/Symbol_support_vote.svg/15px-Symbol_support_vote.svg.png" alt="+" height="15" width="15" />', t: 'За'}
, {w: '{{Против}}', b: '<img src="/files/thumb/7/7f/Symbol_oppose_vote.svg/15px-Symbol_oppose_vote.svg.png" alt="-" height="15" width="15" />', t: 'Против'}
, {w: '{{Воздерживаюсь}}', b: '<img src="/files/thumb/5/5f/Symbol_neutral_vote.png/15px-Symbol_neutral_vote.png" alt="~" height="15" width="15" />', t: 'Воздерживаюсь'}, br
, {w: '{{Оставить}}', b: '<img src="/files/thumb/5/5a/BallotCheckMark.png/15px-BallotCheckMark.png" alt="Оставить" height="15" width="15" />', t: 'Оставить'}
, {w: '{{Удалить}}', b: '<img src="/files/thumb/8/83/BallotX.png/15px-BallotX.png" alt="Удалить" height="15" width="15" />', t: 'Удалить'}, br
, {w: '{{Перенесено в|+}}', f: 'Страница, куда перенесён текст'}
, {w: '{{Перенесено из|+}}', f: 'Страница, откуда перенесён текст'}
, {t: 'Новые страницы', nl: true}
, {t: 'Страница побывала в шаблоне «Новые статьи»', b: '<img src="/files/thumb/b/b9/Internet-news-reader.svg/16px-Internet-news-reader.svg.png" alt="!" height="16" width="16" />', w: '{{Было_в_новых|URL=+}}'}
] : null
];
/*
* Обработчики событий:
*/
// Для упрощения синтаксиса вызова, оформляются в виде метода jQuery:
$.fn.extend ({
// Выбрать ведущую кнопку для подменю:
setLeader: function ($button) {
// Find first active (not submenu) button:
$button = $button ? $button : this.find ('.leader *, button:not(.label), a:not(.label)').first ();
this.parent ().children ('.last').replaceWith ($button.clone (true).addClass ('last'));
return this;
}
// Сделать кнопку ведущей в подменю:
, makeLeader: function () {
this.parents ('.eMenu ul').setLeader (this);
return this;
}
// Клонировать меню/подменю для указанного текстового поля:
, cloneForTextbox: function (id) {
return this.clone (true).find ('button, ul').attr ('forbox', id).end ().attr ('forbox', id);
}
// Активировать панели инструментов для текстового поля:
, activateToolbars: function () {
// Все панели серым:
$('.eMenu').removeClass ('active');
// Относящиеся к окну с фокусом -- не серым:
$('.eMenu[forbox="' + this.attr ('id') + '"]').addClass ('active');
}
// Показать подменю с отложенной загрузкой:
, loadAndShow: function (speed) {
clearInterval (delay_id);
var $ret = this.hasClass ('postponed')
// Подменю с отложенной загрузкой. Перезагрузить:
? eMenu (
cache [this.attr('id')]
, 1, true
).cloneForTextbox (this.attr('forbox')).replaceAll (this)
// Подменю полностью загружено:
: this;
return speed == 'instant' ? $ret.show () : $ret.slideDown (speed);
}
});
// Развёртывание и свёртывание субменю не наездом, а щелчком по треугольнику.
// Так развёрнутое подменю свёртывается только другим щелчком:
function fixedToggle ($tool) {
var $toolbar = $tool.parents ('.eMenu');
// Снять класс fixed со всех развёрнутых подменю данной панели,
// всё равно, наездом или щелчком, кроме щёлкнутого:
$toolbar.find ('li').not ($tool [0]).find ('.eMenu').removeClass ('fixed');
// Переключить класс fixed щёлкнутого меню:
$tool.find ('.eMenu').toggleClass ('fixed');
// Скрыть все подменю данной панели:
$toolbar.find ('li .eMenu').hide ();
// Показать подменю, развёрнутые щелчком (с классом fixed):
$('.fixed').loadAndShow ();
// Установить значки на основании класса fixed:
$('.extender').each (function () {
$(this).html ($(this).parent ('li').find ('.eMenu.fixed').length ? collapser : extender);
});
}
/*
* Функции-обработчики настроек:
*/
// Экранирование HTML для title, onclick и т.п.:
function escape4htmlEvents (s) {
return s.replace (/</g, '<').replace (/>/g, '>').replace (/"/g, '"').replace (/\\/g, '\\\\').replace (/'/g, '\\\'');
}
// Удаляет из аргумента теги HTML:
function stripHTML (s) {
return s ? s.replace (/(<.+?>|\n)/g, '') : null;
}
// Удаление из строки символов, недопустимых в имени переменной Javascript
// для использования в кэше HTML:
function makeCacheKey (s) {
return s.replace (/[:'"&+*\-\/|[\]{}(),\s\.#;]/g, 'S').replace (/\?/g, 'qu');
}
// Возвращает имя функции. Нужна только из-за IE:
function functionName (func) {
var name = func && (typeof (func) == 'function' || typeof (func) == 'object')
? func.name
: null;
if (!name) {
var matches = ('' + func).match (/function\s*([\w\$\d_]*)\s*\(/);
name = matches ? matches [1] : '';
}
return name;
}
// Отладочная функция:
function showObj (obj, depth) {
var out = '';
if (!depth) {
depth = 2;
}
if (typeof (obj) == 'object' && obj !== null && depth > 1) {
out += 'object (' + obj.constructor.name + ') : [\n';
$.each (obj, function (key, val) {
// window.alert (key + ' = ' + val + ' (' + typeof (val) + ')\n');
out += key + ' = ' + showObj (val, depth - 1) + '\n';
});
out += ']';
} else if (typeof (obj) == 'object' && obj !== null && depth <= 1) {
out = '[object]\n';
} else if (obj !== null) {
out = typeof (obj) + ': ' + obj.toString ();
} else {
out = 'null';
}
return out;
}
/*
* Точка входа:
*/
// Добавление панелей инструментов над и под каждым текстовым полем после загрузки документа:
$(function () {
// Компиляция панелей инструментов. Проводится только после загрузки формы редактирования,
// чтобы не задерживать её показ:
if (!mw.config.exists ('wgCodeEditorCurrentLanguage')
&& !(mw.config.exists ('wgWikiEditorEnabledModules') && mw.config.get ('wgWikiEditorEnabledModules').toc)
&& mw.user.options.get ('gadget-edit2')
) {
// Только если не включено содержание и CodeEditor:
// Создание заготовок:
createStubs ();
// Подключение расширений:
$.each (mw.edit_gadget_extensions, function (i, func) {
func ();
});
// Обход текстовых полей:
$('textarea').not ('.g-recaptcha-response').each (function () {
// Запись id текстового поля:
var id = this.id;
// Добавление панелей:
$(this).before ( // -- верхняя панель:
eMenu (mw.tools_above).addClass ('above').cloneForTextbox (id)
).after ( // -- нижняя панель:
eMenu (mw.tools_below).addClass ('below').cloneForTextbox (id)
).focus (function () { // -- событие фокуса: активация своих и деактивация чужих панелей:
$(this).activateToolbars ();
});
});
// Удаление стандартных инструментов:
$('#toolbar').remove ();
// Удаление инструментов WikiEditor:
$('#wikiEditor-ui-toolbar').remove (); // -- MW 1.22-
$('.wikiEditor-ui-top').remove (); // -- MW 1.23+
//mw.toolbar = null; //mwEditButtons = null;
// Подключение кнопки CodeMirror:
$('a#mw-editbutton-codemirror').insertBefore ($('.eMenu.above > li:last-child')).width ('1.4em').wrapAll ('<li></li>');
// Активация первого текстового поля:
$('textarea').first ().focus ();
// window.alert ('Число инструментов -- ' + tool_no);
}
});
/*
* Функции, создающие меню из массива:
*/
// Получает в качестве аргумента объект со свойствами
// w[rapper], f[iller], url, h[tml], b[utton], t[itle]:
function eButton (arg) {
if (!arg) return null;
// Установить неопределённые свойства в null для упрощения дальнейшего кода:
var wrapper = typeof arg.w == 'undefined' ? null : arg.w;
var button = typeof arg.b == 'undefined' ? null : arg.b;
var title = typeof arg.t == 'undefined' ? null : arg.t;
var filler = typeof arg.f == 'undefined' ? null : arg.f;
var all = typeof arg.all == 'undefined' ? false : arg.all;
var nl = typeof arg.nl == 'undefined' ? null : arg.nl;
var leader = typeof arg.leader == 'undefined' ? null : arg.leader;
var url = typeof arg.url == 'undefined' ? null : arg.url;
var html = typeof arg.h == 'undefined' ? null : arg.h;
if (!wrapper && !button && !title && !url && !html) return null;
// Только если явно задано название инструмента, разворачивать его в подменю:
var expand = arg.t ? true : false;
tool_no++; // -- счётчик инструментов.
var $ret = $li_stub.clone ();
// Вывести инструмент в новой строке?
if (nl) $ret.addClass ('nl');
// Сделать его ведущим по умолчанию вне очереди?
if (leader) $ret.addClass ('leader');
// Допустить обработку всего поля?
var wrapper_name = $.isFunction (wrapper)
? functionName (wrapper)
: wrapper;
// TODO: stripHTML () -> mw.html.escape ();
// Создание отсутствующего заполнителя из заданного названия:
filler = filler == '-' ? ''
: filler ? filler
/* : t && w && wrapper_name.indexOf ('+') > -1
? stripHTML (title)*/
: '';
// Всплывающая подсказка для инструмента:
title = title ? title // Если надо, создать название из кнопки:
: button ? escape4htmlEvents (stripHTML (button)) // или даже из обёртки:
: $.trim (stripHTML (wrapper_name)).replace (/_/g, ' ');
// Если надо, создать кнопку из обёртки:
if (!button && wrapper) {
var split = wrapper_name.split ('+', 2);
button = split [0]
+ (split [0] && split [1] ? '<span class="plus_sign">+</span>' : '')
+ (split [1] ? split [1] : '');
}
// Кэширование обёртки и заполнителя:
if (title) {
var cache_key = makeCacheKey (stripHTML (title));
cache [cache_key + '_wrapper'] = wrapper;
cache [cache_key + '_filler'] = filler;
}
if (!wrapper && !url && !html && title) {
// Если обёртки, URL и HTML нет, то создаётся метка:
if (nl) $ret.addClass ('header');
$ret.attr ('title', stripHTML (title)).append (
// Кнопка без событий, чтобы при протаскивании мыши не началось выделение текста:
$('<button type="button" class="label"></button>').append (button).append (
expand ? $('<span></span>').addClass ('full').html (title) : ''
)
);
} else if (url) {
// Есть URL. Создаётся ссылка:
$ret.attr ('title', title ? stripHTML (title) : '').append (
$a_stub.clone ().attr ('href', url).append (button).append (
expand ? $full_stub.clone ().html (title) : null
)
);
if (nl) $ret.addClass ('header');
} else if (html) {
// Произвольный HTML:
if (nl) $ret.addClass ('header');
$ret = $(html);
} else {
// Создаётся настоящая кнопка:
$ret.append (
$button_stub.clone (true).attr ('title', stripHTML (title)).attr ('process_all', all).html (button).append (
// Название инструмента для подменю:
expand ? $full_stub.clone ().html (title) : null
)
);
}
return $ret;
}
// Создаёт подменю или подменю из массива объектов, описывающих кнопки
// массивов, описывающих подменю и строк, описывающих ряды кнопок.
// Если level = 0, нужно меню, иначе -- подменю.
// Если now = true, отложенная загрузка запрещена.
// Возвращает объект jQuery:
function eMenu (arg, level, now) {
if (!level) level = 0;
// Нужно из-за изменения значения this в зависимости от контекста:
var $li_stub = level == 0 ? $li0_stub : $li1_stub;
var $ret = level == 0 ? $ul0_stub.clone () : $ul1_stub.clone ();
// Если подменю слишком длинное для немедленного показа, показать отложенно:
var left = now || level == 0 ? 10000000 : immediate_limit;
var postponed = false;
// Развёртывание рядов кнопок, заданных с помощью разделённых пробелами строк:
var parsed = [];
// Обход всего переданного массива:
$.each (arg, function () {
if (this) {
if (this.split && this.length) {
// Разделённая пробелами строка. Заменить на массив объектов:
var estimated_length = this.match (/\S+/ig).length;
// Массив, полученный разбивкой строки, добавляется к накопленному массиву объектов:
parsed = $.merge (parsed, $.map (this.split (' ', left), function (s) {
// Обёртка подстрок в объекты:
return !s ? null
: s == 'br' ? {h : '<br clear="all" />'} // -- перевод строки.
: s.match (/^<<.+>>$/) // Метка:
? {t: s.replace (/(^<<|>>$)/g, '').replace (/_/g, ' ')}
: {w: s.replace (/_/g, ' ').replace (/-uline-/ig, '_')};
}));
// Отдельная оценка необходима, т.к. ограничение в .split () работает неправильно:
left -= estimated_length;
} else {
// Кнопка или подменю. Возвратить как есть:
parsed.push (this);
left--;
}
}
// При превышении лимита завершить цикл:
if (left <= 0) {
postponed = true;
return false;
}
});
// Обход массива:
$.each (parsed, function () {
if (this) {
if ($.isArray (this)) {
// Подменю:
eMenu (this, level + 1, now).appendTo ( // -- создание подменю рекурсивным вызовом.
$li_stub.clone (true).appendTo ($ret) // -- создание пункта меню.
).setLeader (); // -- задание ведущей кнопки.
} else {
// Предположительно, объект, описывающий кнопку:
// Создание пункта меню с кнопкой и добавление к возврату:
var button = eButton (this);
if (button) {
button.appendTo ($ret);
}
}
}
});
// Добавление признаков отложенной загрузки и запись её параметров в кэш:
if (postponed) {
// Запись в кэш:
cache ['postponed_' + lastPostponed] = arg;
// Класс отложенной записи, id записи в кэше, заглушка:
$ret.addClass ('postponed').attr ('id', 'postponed_' + lastPostponed++)/*.append (
$postponed_stub
)*/;
}
// Установка класса, заменяющего first-child и last-child, для IE:
/* if ($.browser.msie) {
$ret.children ().first ().addClass ('firstChild');
$ret.children ().last ().addClass ('lastChild');
} */
// Возврат:
return $ret;
}
/*
* Функции, обработки текста, вызываемые кнопками:
*/
// Вставка тега вокруг выделенного текста или вызов функции-обработчика
// в результате нажатия кнопки
// (ID окна, обёртка или обработчик, текст-образец (если нет выделения)):
function insertTag (textbox_id, wrapper, filler, all) {
var callback;
if ($.isFunction (wrapper)) {
// Передана функция-обработчик:
callback = wrapper;
callback.filler = filler;
} else {
// Передана строка-обёртка:
// Превращение обёртки в открывающий и закрывающий тэги:
var tag_open, tag_close;
if (wrapper && wrapper.indexOf ('+') > -1) {
// Если в обёрке есть плюс, по нему её и разрезать на открывающий и закрывающий теги:
var tags = wrapper.split (/\+(?!\+)/, 2);
tag_open = tags [0];
tag_close = tags [1];
callback = function (s) {
// Окружить старое выделение символами '\x01' и '\x02':
return tag_open + '\x01' + (s ? s : filler ? filler : '') + '\x02' + tag_close;
}
} else {
// Если в обёртке нет плюса, вставлять её после выделения.
// Выделить после этого вставленный символ:
callback = function (s) {
// Подумать, имеет ли смысл в этом контексте f:
return (s ? s : filler ? filler : '') + '\x01' + wrapper + '\x02';
}
}
}
// ID -> объект DOM:
var textbox = document.getElementById (textbox_id);
processSelection (textbox, callback, eval (all));
} // -- конец insertTag ();
// Превратить многострочный текст в маркированный список:
function makeUL (s) {
return '\n' + (s ? s : makeUL.filler).replace (/^\s*(?:\d*[.)]|-)?\s*(.)/gm, '* $1');
}
// Превратить многострочный текст в нумерованный список:
function makeOL (s) {
return '\n' + (s ? s : makeOL.filler).replace (/^\s*(?:\d*[.)]|-)?\s*(.)/gm, '# $1');
}
// Превратить многострочный текст в глоссарий:
function makeGlossary (s) {
return '\n' + (s ? s : makeGlossary.filler).replace (/^\s*(?:\d*[.)]|-)?\s*(.)/gm, '; $1').replace (/[\-—:]/gm, ' : ');
}
// Превратить многострочный текст в строки таблицы (в один столбец):
function makeTable (s) {
return '\n{| class="wikitable"\n'
+ (s ? s : makeTable.filler).replace (/^./gm, '|-\n| $&').replace (/\t/g, ' || ')
+ '\n|}\n';
}
// Функция, викифицирующая выделение:
function wikifySelection (txtarea_id) {
processSelection (document.getElementById (txtarea_id)
, wikifyText
, true);
// Скорее всего, так просто не заработает:
if (window.insertSummary) {
insertSummary ('викификация');
}
}
// Функция, выполняющая поиск и замену в выделении:
function regexSelection (txtarea_id, search, replace) {
processSelection (document.getElementById (txtarea_id)
, function (s) {return s.replace (search, replace);}
, true);
}
// Обработать выделение в textbox с помощью funct.
// Если ничего не выбрано и установлен all, обработать всё:
function processSelection (textbox, funct, all) {
var inserted;
var full_text = 'Будет обработан ВЕСЬ редактируемый текст. Продолжить?';
var win_scroll = document.documentElement.scrollTop;
textbox.focus ();
if (typeof (textbox.selectionStart) != 'undefined' /*
&& (navigator ['productSub'] > 20031000
|| $.browser.safari
|| $.browser.webkit
|| $.browser.opera
|| $.browser.mozilla) */ ) {
// Mozilla/Opera/Safari3:
var textScroll = textbox.scrollTop; // -- сохранить положение промотки.
// Определить выделение в виде позиций начала и конца:
var start_pos = textbox.selectionStart;
var end_pos = textbox.selectionEnd;
if (start_pos == end_pos && all && confirm (full_text)) {
// Ничего не выделено, но в таком случае позволено обработать весь текст:
start_pos = 0;
end_pos = textbox.value.length;
}
// Получение и обработка выделения:
inserted = funct (textbox.value.substring (start_pos, end_pos));
// Получение старого выделения:
var sel_offset = inserted.indexOf ('\x01') > -1 ? inserted.indexOf ('\x01') : 0;
var sel_length = (inserted.indexOf ('\x02') > -1 ? inserted.indexOf ('\x02') : 0) - sel_offset - 1;
sel_length = sel_length >= 0 ? sel_length : 0;
// Удаление символов выделения:
inserted = inserted.replace ('\x01', '').replace ('\x02', '');
// Перезапись значения поля:
textbox.value = textbox.value.substring (0, start_pos)
+ inserted
+ textbox.value.substring (end_pos);
// Выделить обработанное. Использовать для выделения нестандартные свойства
// selOffset и selLength, если возвращены funct:
var correction = Math.floor ((/* $.browser.opera && */ inserted.substr (0, start_pos + sel_offset).match (/\n/g)
? inserted.substr (0, start_pos + sel_offset).match (/\n/g).length
: 0) / 2);
textbox.selectionStart
= start_pos
+ sel_offset
+ correction;
textbox.selectionEnd
= start_pos + sel_offset
+ sel_length
- correction;
// -- всё ещё неверно в Опере.
textbox.scrollTop = textScroll; // -- восстановить положение промотки.
} else if (document.selection && document.selection.createRange) {
// IE:
// Определить выделение в виде объекта range:
var range = document.selection.createRange();
if (range.text.length == 0 && all && confirm (full_text)) {
// Ничего не выделено, но в таком случае позволено обработать весь текст:
textbox.value = funct (textbox.value);
} else {
// Есть выделение, или обработка всего текста не предусмотрена:
// Обработать выделение:
inserted = funct (range.text);
// Получение старого выделения:
var sel_offset = inserted.indexOf ('\x01') > -1 ? inserted.indexOf ('\x01') : 0;
var sel_length = (inserted.indexOf ('\x02') > -1 ? inserted.indexOf ('\x02') : 0) - sel_offset - 1;
sel_length = sel_length >= 0 ? sel_length : 0;
// Удаление символов выделения:
inserted = inserted.replace ('\x01', '').replace ('\x02', '');
// Заменить выделение на обработанное:
range.text = inserted;
// Перевыделить вставленное:
if (range.moveStart) {
range.moveStart ('character', - inserted.length + sel_offset);
range.moveEnd ('character', - inserted.length + sel_offset + sel_length);
}
range.select();
}
} else {
// Другие браузеры. Выделения не получить; обрабатывать всё или ничего:
if (all && confirm (full_text)) {
textbox.value = funct (textbox.value).replace ('\x01', '').replace ('\x02', '');
}
}
document.documentElement.scrollTop = win_scroll; // -- восстановить позицию промотки в IE/Opera.
} // -- конец processSelection ().