MediaWiki:Common.js

Версия от 14:52, 16 сентября 2012; Александр Машин (комментарии | вклад) (Новая страница: «/* Размещённый здесь код JavaScript будет загружен всем читателям * (не обязательно участник…»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)

Замечание: Чтобы после сохранения вступили в силу изменения стилей, перезагрузите файл http://in.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=vector&*, если используете скин Vector, или http://in.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=common&*, если используете скин Common.

Чтобы вступили в силу изменения скриптов, перезагрузите файл http://in.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=vector&*, если используете скин Vector, или http://in.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=common&*, если используете скин Common.

Гаджеты и·импортируемые скрипты загружаются отдельными файлами.

/*  Размещённый здесь код JavaScript будет загружен всем читателям
 *  (не обязательно участникам проекта) при обращении к какой-либо странице.
 *
 *  Импортировать скрипты из [[MediaWiki:jQuery.js]] не нужно:
 *  их подгружает расширение [[jQuery для MediaWiki]].
 *
 *  Когда всё подгрузится, задаём в Традиции плавную прокрутку по ссылкам из оглавлений.
*/
$(function(){
   if (typeof(donotlocalscroll) == 'undefined') {
      $.localScroll({  // плавное проматывание страницы внутренними её гиперссылками
         hash: true,   // багфикс «Back», [[Обсуждение участника:Mithgol the Webmaster]] июнь 2010
         onAfter: function(target){ // багфикс :target, http://habrahabr.ru/blogs/jquery/80434/
            location = '#' + ( target.id || target.name ); // подсветка сносок
         }
      });
   }

   toggleToc = function(){ // плавное сокрытие и открытие оглавления страницы
      var $toc = $('#toc ul:first');
      var $toggleLink = $('#togglelink');

      if (($toc.length != 0) && ($toggleLink.length != 0)) {
         if ($toc.is(':visible')) {
            $toggleLink.text(mediaWiki.msg('showtoc'));
            document.cookie = "hidetoc=1";
            $toc.slideUp(1000);
         } else {
            $toggleLink.text(mediaWiki.msg('hidetoc'));
            document.cookie = "hidetoc=0";
            $toc.slideDown(1000);
         };
      };
   };
});

// Редактирование новыми инструментами:

if( $('textarea').length > 0 ){
   importStylesheet ('MediaWiki:Edit.css');
   importScript ('MediaWiki:Edit.js');
}

/*  Расширенный поиск.
 *  Автор:       [[Участник:Dream]]
 *  jQuery-код:  [[Участник:Mithgol the Webmaster]]
*/
/*
if (wgPageName == "Служебная:Search") { $(function(){
   var $SearchForm = $('#powersearch');
   if ($SearchForm.length === 0) return;

   var $powerSearchText = $('#powerSearchText');
   if ($powerSearchText.length === 0) return;

   var safeSearchValue = $powerSearchText.val().
      replace(/&/g, "&").
      replace(/</g, "&lt;").
      replace(/>/g, "&gt;").
      replace(/"/g, "&quot;");

   var googleSearch =
      '<form action="http://www.google.com/custom" method="get" name="google" target="_blank" id="google" ' +
      'onsubmit="$(\'#google input[name=q]\').val( $(\'#powerSearchText\').val() ); return true;">' +
      '<input type="hidden" name="hl" value="ru" />' +
      '<input type="hidden" name="domains" value="traditio-ru.org" />' +
      '<input type="hidden" name="q" maxlength="2048" value="' + safeSearchValue + '" />' +
      '<input type="hidden" name="sitesearch" value="traditio-ru.org" />' +
      '<input type="submit" value="Поиск Google по «Право — Традиции»" style="width: 20em;" /></form>';
    
   var yandexSearch =
      '<form action="http://www.yandex.ru/yandsearch" method="get" name="yandex" target="_blank" id="yandex" ' +
      'onsubmit="$(\'#yandex input[name=text]\').val( $(\'#powerSearchText\').val() ); return true;">' +
      '<input type="hidden" name="text" maxlength="300" value="' + safeSearchValue + '" />' +
      '<input type="hidden" name="site" value="traditio-ru.org" />' +
      '<input type="hidden" name="ras" value="1" />' +
      '<input type="hidden" name="site_manually" value="true" />' +
      '<input type="hidden" name="server_name" value="[pravo.traditio" />' +
      '<input type="submit" value="Поиск «Яндексом» по «Право — Традиции»" style="width: 20em;" /></form>';

   var ramblerSearch =
      '<form action="http://nova.rambler.ru/search?adult=none" method="get" name="rambler" target="_blank" id="rambler" ' +
      'onsubmit="$(\'#rambler input[name=query]\').val( $(\'#powerSearchText\').val() ); return true;">' +
      '<input type="hidden" name="query" maxlength="300" value="' + safeSearchValue + '" />' +
      '<input type="hidden" name="filter" value="traditio-ru.org" />' +
      '<input type="submit" value="Поиск «Рамблером» по «Право — Традиции»" style="width: 20em;" /></form>';

   $SearchForm.after(
      '<table style="margin-left: 57%; padding-left: 4px;"><tr><td>' +
      yandexSearch + '</td></tr><tr><td>' + googleSearch + '</td></tr><tr><td>' + ramblerSearch +
      '</td></tr></table>'
   );
}); }
*/

/*
 *   Далее следует код, который:
 *
 *   *) показывает значок статуса ICQ в шаблоне {{ICQ}}
 *
 *   *) показывает значок статуса Skype в шаблоне {{Skype}}
 *
 *   *) показывает консоль для отслеживания статуса игры Quake II
 *      на странице [[Quake II Deathmatch]]
*/
$(function(){
   // ICQ status background
   $('span.ICQ').each(function(){
      var ICQURL = 'http://status.icq.com/online.gif?icq=' + this.id + '&img=5';
      $(this).css({
         'padding' :          '0 0 0 20px',
         'background-image':  'url(' + ICQURL + ')',
         'background-repeat': 'no-repeat'
      });
   });

   // Skype status
   $('span.skypeTemplate').each(function(){
      var $this = $(this);
      var username = $this.find('span.skypeUserName').text();

      // А теперь защита от взлома Традиции, совершаемого впрыскиванием левого кода.
      // По адресу https://login.skype.com/account/signup-form сказано:
      // What is my Skype Name?
      // Your Skype Name is your unique username for Skype.
      // It must be between 6-32 characters, start with a letter
      // and contain only letters and numbers (no spaces or special characters).
      if (username.match(/^[a-zA-Z][a-zA-Z01-9-]{5,31}$/) === null) return;

      $this.html(
         '<a href="skype:' + username + '?call" class="val-3"><img ' +
         'src="http://mystatus.skype.com/smallicon/' + username + '" ' +
         'width="16" height="16" alt="[Skype status]" title=""></a> ' +
         '<a href="skype:' + username + '?call"><span class="skypeUserName">' +
         username + '</span></a>'
      );
   });

   // Quake II consoles
   $('span.quake2traditio').each(function(){
      var $this = $(this);
      // проверяем, действительно ли указано имя сервера
      // (защита от взлома «Право — Традиции», совершаемого впрыскиванием левого кода)
      // имя.имя.имя...имя:порт, где имя == [a-zA-Z01-9][a-zA-Z01-9-]*
      //                           а порт не обязателен
      var TheText = $this.text();
      if (TheText.match(/^([a-zA-Z01-9][a-zA-Z01-9-]*\.)+([a-zA-Z01-9][a-zA-Z01-9-]*)(:[1-9][01-9]*)?$/)
                  === null)
      {
         // не сервер:
         $this.html('<b>' + TheText + ' не является сервером Quake&nbsp;II</b>');
      } else {
         // сервер:
         $this.html('<embed style="width: 100%;" height=388 type="application/x-q3plug-plugin" ' +
                    'name="' + TheText + '" color="#ffeedd" color2="#88ff88" game="Q2" ' +
                    'pluginspage="http://members.liwest.at/mb/q3plug" />');
      } // конец проверки того, действительно ли указано имя сервера
   });
});

/******************************************************************************************
 *
 *  Сворачивающиеся блоки для шаблонов {{Навигационная таблица}}, {{Навигационная полоса}}
 *  и для таблиц class="collapsible" (см. на [[Справка:Оформление таблиц]] пример).
 *
 *  Код полностью переписал Mithgol the Webmaster на основе jQuery в начале августа 2009 г.
 *
*/

var autoCollapse = 2;
var collapseCaption = 'скрыть';
var expandCaption = 'показать';

function collapseTable(linkObject){ // accepts both raw and jQuery-wrapped objects
   var TheLink = $(linkObject);
   var TableRows = TheLink.closest('tr').parent().children().filter('tr').not(':first');
   if (TableRows.length == 0) return;

   if (TheLink.text() == collapseCaption) {
      TheLink.text(expandCaption);
   } else {
      TheLink.text(collapseCaption);
   };
   TableRows.fadeToggle(1000);
}

$(function(){
   var allTables = $('#content table.collapsible');

   allTables.each(function(tblIdx){
      var HRow = $('tr:first', this);
      if (HRow.length == 0){
         $(this).addClass('wontCollapse'); // no rows
         return true; // continue next iteration of each()
      }
      if (HRow.parent().children().filter('tr').not(':first').length == 0){
         $(this).addClass('wontCollapse'); // no rows after the first
         return true; // continue next iteration of each()
      }

      var Header = $('th:last', HRow);
      if (Header.length == 0){
         $(this).addClass('wontCollapse'); // no TH in the first row
         return true; // continue next iteration of each()
      }

      $(this).data('collapseIndex', tblIdx);
      Header.prepend(
         '<span style="float: right; font-weight: normal;">'+
         '[<a id="collapseButton' + tblIdx + '" href="#" onClick="collapseTable(this); return false;">'+
         collapseCaption + '</a>]</span>');
   });

   var processedTables = allTables.not('.wontCollapse');
   if (processedTables.length > autoCollapse){
      processedTables.filter('.autocollapse').each(function(i){
         var linkIDX = $(this).data('collapseIndex');
         collapseTable($('a#collapseButton' + linkIDX, this).eq(0));
      });
   }
   processedTables.filter('.collapsed').each(function(i){
      var linkIDX = $(this).data('collapseIndex');
      collapseTable($('a#collapseButton' + linkIDX, this).eq(0));
   });
});

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

function collapseDiv(toggleObject){ // accepts both raw and jQuery-wrapped objects
   var TheToggle = $(toggleObject);
   var TheFrame  = TheToggle.closest('div.NavFrame');
   if (TheFrame.length == 0) return false;

   if (TheToggle.text() == NavigationBarHide){
      TheToggle.text(NavigationBarShow);
      TheFrame.children().filter('.NavPic, .NavContent').slideUp(1000);
   } else {
      TheToggle.text(NavigationBarHide);
      TheFrame.children().filter('.NavPic, .NavContent').slideDown(1700, 'easeOutElastic');
   };
}
 
$(function(){
   var NavFrameList = $('#content div.NavFrame');
   NavFrameList.each(function(navIdx){
      var TheNavHead = $('.NavHead:first', this);
      if (TheNavHead.length == 0) {
         $(this).addClass('wontCollapse'); // no NavHead inside!
         return true;      // continue next iteration of each()
      }
      $(this).data('NavFrameIndex', navIdx);
      TheNavHead.prepend('<a class="NavToggle" '+
         'id="NavToggle' + navIdx + '" href="#" '+
         'onClick="collapseDiv(this); return false;">'+
         NavigationBarHide + '</a>'
      );
   });

   var processedDivs = NavFrameList.not('.wontCollapse');
   if (processedDivs.length > NavigationBarShowDefault){
      processedDivs.not('.expanded').each(function(i){
         var linkIDX = $(this).data('NavFrameIndex');
         collapseDiv($('a#NavToggle' + linkIDX, this).eq(0));
      });
   }
   processedDivs.filter('.collapsed').each(function(i){
      var linkIDX = $(this).data('NavFrameIndex');
      collapseDiv($('a#NavToggle' + linkIDX, this).eq(0));
   });
});

/*  Замена свёртывания и развёртывания метаданных по трём причинам:
 *  1) http://traditio-ru.org/w/skins/common/metadata.js чего-то не действует в Firefox 4
 *  2) уместнее манипулировать DOM только после того, как код страницы весь пришёл
 *  3) эффекты jQuery выглядят круче, чем мгновенное переключение видимости
*/
attachMetadataToggle = function(){}; // старая функция устранена, вот новая:
$(function(){
   var $tbody = $('#mw_metadata tbody');
   $tbody.append(
      '<tr><td colspan="2"><a href="javascript:" id="toggleMetadata">'+
      '<span id="hideMetadata">Скрыть метаданные</span>'+
      '<span id="showMetadata">Показать метаданные</span>'+
      '</a></td></tr>'
   );
   $tbody.children('tr').not(':last').hide();
   $('#hideMetadata').hide();
 
   $('#toggleMetadata').click(function(){
      $(this).blur();
      $('#hideMetadata').toggle();
      $('#showMetadata').toggle();
      $('#mw_metadata tbody tr').not(':last').fadeToggle(1000);
   });
});

/*  Замена гиперссылки на кнопке «+» (например, наверху обсуждений) на другой адрес,
 *  если на странице был поставлен шаблон {{modifynewsectionlink}}.
*/
$(function(){
   var customLink = $('#add-custom-section a:first');
   if (customLink.length !== 0) { // используем customLink:
      $('#ca-addsection a:first').attr('href', customLink.attr('href'));
   }
});

/*** Дополнение сносок всплывающими подсказками ***/
$(function(){
   $('.reference').each(function(){
      var $this = $(this);
      // document.getElementById вместо $, т.к. последний не работает с точками,
      //     появляющимися в закодированном названии якоря на русском:
      var $cite = $( document.getElementById ($this.find('a').attr('href').substring (1)) ).clone();
      var $backlink = $cite.find('a').eq(0);
      if ($backlink.text() == '↑'){ $backlink.remove(); }

      var $bodyContent = $('#bodyContent');
      var parentShift = $bodyContent.children().first().offsetParent().offset();
      $this.qtip({
         content: { text: $cite.html() },
         position: {
            container: $bodyContent,
            adjust: {
               x: -parentShift.left,
               y: -parentShift.top,
               screen: true
            }
         },
         show: {
            delay: 1,
            effect: { length: 500 }
         },
         hide: {
            delay: 200,
            fixed: true,
            effect: {
               length: 1111
            }
         },
         style: {
            name: 'light',
            width: { max: 512 },
            border: {
               width: 1,
               radius: 0,
               color: '#777'
            },
            color: 'inherit'
         }
      });
   }); // завершение each()-цикла
});

/*** Дополнение span'ов с классом tipped всплывающими подсказками из вложенного span'а с классом .tip ***/
$(function(){
    createToolTips($('#bodyContent'));
});

// находит $('.tipped') внутри $cttArea, применяет addHTMLToolTip() по мере нужды
function createToolTips($cttArea){
   $cttArea.find('.tipped').each(function(){
      var $this = $(this);
      $this.css('position', 'relative');
      var $tip = $this.children('.tip').clone();
      addHTMLToolTip($this, $tip.html());
   }); // завершение each()-цикла
}

// функция снабжает элемент $tipped подсказкою с HTML из tip
// вызывает createToolTips() рекурсивно
function addHTMLToolTip($tipped, tip){
   var $bodyContent = $('#bodyContent');
   var parentShift = $bodyContent.children().first().offsetParent().offset();
   $tipped.qtip({
      content: { text: tip },
      position: {
         container: $bodyContent,
         corner: {
            target:  'bottomRight',
            tooltip: 'topRight'
         },
         adjust: {
            x: -parentShift.left,
            y: -parentShift.top,
            screen: true
         }
      },
      show: {
         delay: 1,
         effect: { length: 500 }
      },
      hide: {
         delay: 200,
         fixed: true,
         effect: {
            length: 1111
         }
      },
      style: {
         name: 'light',
         width: { max: 512 },
         border: {
            width: 1,
            radius: 0,
            color: '#777'
         },
         color: 'inherit'
      },
      // Вложенные подсказки:
      api: {
         onRender: function(){
            createToolTips($( this.elements.content ));
         }
      }
   });
}

/* ***  Отрисовка геокарт [[WikiLeaflet]]  *** */

LeafletRoot = '/wiki/js/leaflet/';
$(function(){
   if ($('.wikileaf').length !== 0){
      var WikiLeafletURL = wgScriptPath + '/index.php?title=' +
            escape( 'MediaWiki:WikiLeaflet.js' ) +
            '&action=raw&ctype=text/javascript&dontcountme=s';

      importStylesheetURI(LeafletRoot + 'leaflet.css');
      if ($.browser.msie && ($.browser.version < 9)){
         importStylesheetURI(LeafletRoot + 'leaflet.ie.css');
      }
      $.ajax({
         url: LeafletRoot + 'leaflet.js',
         dataType: 'script',
         cache: true,
         success: function(){
            $.ajax({
               url: WikiLeafletURL,
               dataType: 'script',
               cache: true,
               success: function(){
                  wlRender();
               }
            });
         }
      });
   }
});

// Sharing buttons:
// (Removed).

// A more explicit invitation to participate:
// (Removed).

// настройки ColorBox
$.colorbox.settings.opacity = 0.45;
$.colorbox.settings.current = '{current} из {total}';
// ColorBox миниатюр
$(function(){
   $('div.thumb:has(a.image):not(li.gallerybox div.thumb):not(div.lineBlock div.thumb)').each(function(){
      var $this = $(this);
      var theURL = $this.find('a.image').attr('href');
      var imgURL = theURL + ' #file';

      var $caption = $this.find('div.thumbcaption').clone();
      $caption.find('div.magnify').remove();
      var imgCaption = $caption.html();

      $this.find('a.image').click(function(){
         $.colorbox({
            'href':  imgURL,
            'title': imgCaption,
            'onComplete' : function(){
               var $loaded = $('#cboxLoadedContent');
               if ($loaded.html().indexOf('×') !== -1){
                  $loaded.find('div#file a').attr('title', 'открыть полноразмерную версию');
                  $loaded.append('<div class="fullMedia"></div>');
                  $.get(theURL, function(data){
                     $loaded.find('.fullMedia').html( $(data).find('.fullMedia').html() );
                     $.colorbox.resize();
                  });
               }
            }
         });
         $('#colorbox').easydrag();
         return false;
      });
   });
});
// ColorBox строчных блоков (с поддержкою галерейности)
$(function(){
   $('div.lineBlock:not(div.lineBlock + div.lineBlock)').each(function(idx){
      var gallID = 'lineblocklist' + idx;
      $(this).nextUntil(':not(div.lineBlock)').andSelf().find('div.thumb a.image').colorbox({
         'rel': gallID,
         'href': function(){
            return $(this).attr('href') + ' #file';
         },
         'title': function(){
            var $caption = $(this).closest('div.thumb').find('div.thumbcaption').clone();
            $caption.find('div.magnify').remove();
            return $caption.html();
         },
         'onComplete': function(){
            var theURL = $(this).attr('href');
            var $loaded = $('#cboxLoadedContent');
            if ($loaded.html().indexOf('×') !== -1){
               $loaded.find('div#file a').attr('title', 'открыть полноразмерную версию');
               $loaded.append('<div class="fullMedia"></div>');
               $.get(theURL, function(data){
                  $loaded.find('.fullMedia').html( $(data).find('.fullMedia').html() );
                  $.colorbox.resize();
               });
            }
         },
         'onLoad': function(){
            $('#colorbox').easydrag();
         }
      });
   });
});
// ColorBox галерей (с поддержкою галерейности)
$(function(){
   $('ul.gallery:has(li.gallerybox div.thumb a.image)').each(function(idx){
      var gallID = 'tradigallery' + idx;
      $(this).find('li.gallerybox div.thumb a.image').colorbox({
         'rel': gallID,
         'href': function(){
            return $(this).attr('href') + ' #file';
         },
         'title': function(){
            return $(this).closest('li.gallerybox').find('div.gallerytext').html();
         },
         'onComplete': function(){
            var theURL = $(this).attr('href');
            var $loaded = $('#cboxLoadedContent');
            if ($loaded.html().indexOf('×') !== -1){
               $loaded.find('div#file a').attr('title', 'открыть полноразмерную версию');
               $loaded.append('<div class="fullMedia"></div>');
               $.get(theURL, function(data){
                  $loaded.find('.fullMedia').html( $(data).find('.fullMedia').html() );
                  $.colorbox.resize();
               });
            }
         },
         'onLoad': function(){
            $('#colorbox').easydrag();
         }
      });
   });
});

// Add custom footer icons by Javascript rather than inject them into the HTML on server side.
//     This will reduce apparent page load time:
$(function () {
    if (!_.isUndef('DisableExternalCounters')) return; // [[MediaWiki:Gadget-DisableExternalCounters.js]]
    // Yandex's and Rambler's counters:
    var counters = '<a href="http://yandex.ru/cy?base=0&amp;amp;host=pravo.traditio.ru"><img src="http://www.yandex.ru/cycounter?pravo.traditio.ru" alt="ТИЦ Яндекса" width="88" height="31" /></a>'
/* Register with Rambler first:
                 + '<a href="http://top100.rambler.ru/navi/2513448/"><img src="http://counter.rambler.ru/top100.cnt?2513448" alt="Rambler\'s Top 100" width="88" height="31" /></a>'
*/
/* Register with LiveInternet first:
                 + '<a href="http://www.liveinternet.ru/click" target="_blank"><img src="//counter.yadro.ru/hit?t16.6;r' + escape (document.referrer)
                 + ((typeof (screen) == 'undefined ') ? '' : ';s' + screen.width + '*' + screen.height + '*'
                     + (screen.colorDepth ? screen.colorDepth : screen.pixelDepth)
                   ) + ';u' + escape (document.URL) + ';h' + escape (document.title.substring (0,80)) + ';' + Math.random ()
                 + '" alt="Счётчик LiveInternet" title="LiveInternet: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня" '
                 + 'border="0" width="88" height="31"><\/a>'
*/
;
    // Different ways in Common and Vector skins:
    if (mw.config.get ('skin') == 'vector') {
        $('li#footer-poweredbyico').before ('<li></li><li id="footer-counters">' + counters + '</li>');
    } else {
        $('div#f-poweredbyico').prepend ('&nbsp;&nbsp;' + counters);
    }
});