MediaWiki:Mobile.js
Замечание: Возможно, после публикации вам придётся очистить кэш своего браузера, чтобы увидеть изменения.
- Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl+F5 или Ctrl+R (⌘+R на Mac)
- Google Chrome: Нажмите Ctrl+Shift+R (⌘+Shift+R на Mac)
- Internet Explorer / Edge: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl+F5
- Opera: Нажмите Ctrl+F5.
/*
* База знаний Эскорт — MediaWiki:Mobile.js (копия Common.js для мобильной версии)
*
* 1. Фильтр каталога на заглавной странице: категории + поиск по модели.
* Плитки создаёт шаблон «Плитка продукта» (атрибуты data-cat и data-search).
* 2. Номера разделов в оглавлении «01, 02 …» на страницах с «Карточкой датчика»,
* чтобы они совпадали с нумерацией в тексте (её задаёт Common.css).
* 3. Мобильная версия: блок «Далее» выносится из последнего сворачиваемого
* раздела в конец статьи, чтобы переход к соседней модели был виден всегда.
*
* Синтаксис — ES5: так скрипт проходит проверку ResourceLoader в MediaWiki 1.41.
*/
( function () {
'use strict';
/*
* Подписи интерфейса. Для EN/ES вики tools/build-lang.py подставляет переводы
* (собранные файлы — в MediaWiki/en и MediaWiki/es).
* Порядок категорий = порядок кнопок; коды совпадают с параметром «категория» шаблона.
*/
var TEXT = {
cats: [
[ 'all', 'Все' ],
[ 'fuel', 'Уровень топлива' ],
[ 'angle', 'Угол наклона' ],
[ 'level', 'Уровень воды и сыпучих' ],
[ 'ble', 'BLE-инфраструктура' ],
[ 'other', 'Прочие датчики' ],
[ 'meteo', 'Сокол Метео' ]
],
filter: 'Фильтр каталога',
search: 'Поиск по каталогу',
placeholder: 'Модель или тип: TD-BLE, угол…',
empty: 'Ничего не найдено. Проверьте написание модели или напишите в поддержку: help@escortsensors.com'
};
var CATS = TEXT.cats;
function el( tag, attrs, text ) {
var node = document.createElement( tag );
var key;
for ( key in attrs ) {
if ( Object.prototype.hasOwnProperty.call( attrs, key ) ) {
node.setAttribute( key, attrs[ key ] );
}
}
if ( text !== undefined ) {
node.appendChild( document.createTextNode( text ) );
}
return node;
}
function initCatalog( catalog ) {
if ( catalog.getAttribute( 'data-es-ready' ) ) {
return;
}
catalog.setAttribute( 'data-es-ready', '1' );
var tiles = Array.prototype.slice.call( catalog.querySelectorAll( '.es-tile' ) );
var state = { cat: 'all', q: '' };
var bar = el( 'div', { 'class': 'es-filter', role: 'group', 'aria-label': TEXT.filter } );
var empty = el( 'div', { 'class': 'es-filter__empty', role: 'status', hidden: 'hidden' },
TEXT.empty );
var chips = el( 'div', { 'class': 'es-filter__chips' } );
var buttons = [];
CATS.forEach( function ( c ) {
var used = c[ 0 ] === 'all' || tiles.some( function ( t ) {
return t.getAttribute( 'data-cat' ) === c[ 0 ];
} );
if ( !used ) {
return;
}
var btn = el( 'button', { type: 'button', 'class': 'es-chip', 'aria-pressed': c[ 0 ] === 'all' ? 'true' : 'false', 'data-cat': c[ 0 ] }, c[ 1 ] );
var count = el( 'span', { 'class': 'es-chip__count' } );
btn.appendChild( count );
btn.addEventListener( 'click', function () {
state.cat = c[ 0 ];
apply();
} );
buttons.push( { btn: btn, count: count, cat: c[ 0 ] } );
chips.appendChild( btn );
} );
bar.appendChild( chips );
var search = el( 'input', {
type: 'search',
'class': 'es-filter__search',
placeholder: TEXT.placeholder,
'aria-label': TEXT.search
} );
search.addEventListener( 'input', function () {
state.q = search.value.trim().toLowerCase();
apply();
} );
bar.appendChild( search );
/* Поиск идёт по модели, типу, тегам и названию категории («угол» → «Угол наклона») */
var labels = {};
CATS.forEach( function ( c ) {
labels[ c[ 0 ] ] = c[ 1 ].toLowerCase();
} );
tiles.forEach( function ( t ) {
t.esSearch = ( t.getAttribute( 'data-search' ) || '' ) + ' ' + ( labels[ t.getAttribute( 'data-cat' ) ] || '' );
} );
function matchesQuery( t ) {
return !state.q || t.esSearch.indexOf( state.q ) !== -1;
}
function apply() {
var shown = 0;
tiles.forEach( function ( t ) {
var ok = matchesQuery( t ) && ( state.cat === 'all' || t.getAttribute( 'data-cat' ) === state.cat );
if ( ok ) {
t.removeAttribute( 'hidden' );
shown++;
} else {
t.setAttribute( 'hidden', 'hidden' );
}
} );
buttons.forEach( function ( b ) {
var n = tiles.filter( function ( t ) {
return matchesQuery( t ) && ( b.cat === 'all' || t.getAttribute( 'data-cat' ) === b.cat );
} ).length;
b.count.textContent = String( n );
b.btn.setAttribute( 'aria-pressed', b.cat === state.cat ? 'true' : 'false' );
} );
if ( shown ) {
empty.setAttribute( 'hidden', 'hidden' );
} else {
empty.removeAttribute( 'hidden' );
}
}
catalog.parentNode.insertBefore( bar, catalog );
catalog.parentNode.insertBefore( empty, catalog.nextSibling );
apply();
}
function padTocNumbers() {
if ( !document.querySelector( '.mw-parser-output .es-card' ) ) {
return;
}
var nums = document.querySelectorAll( '.vector-toc-level-1 > .vector-toc-link .vector-toc-numb' );
Array.prototype.forEach.call( nums, function ( n ) {
if ( /^\d$/.test( n.textContent ) ) {
n.textContent = '0' + n.textContent;
}
} );
}
function liftNext( root ) {
Array.prototype.forEach.call( root.querySelectorAll( '.es-next' ), function ( next ) {
var section = next.parentNode;
while ( section && !( section.tagName === 'SECTION' && /\bcollapsible-block\b/.test( section.className ) ) ) {
section = section.parentNode;
}
if ( section && section.parentNode ) {
section.parentNode.appendChild( next );
}
} );
}
mw.hook( 'wikipage.content' ).add( function ( $content ) {
var root = $content && $content[ 0 ] ? $content[ 0 ] : document;
Array.prototype.forEach.call( root.querySelectorAll( '.es-catalog' ), initCatalog );
liftNext( root );
} );
$( padTocNumbers );
}() );