MediaWiki:Modules/interactive-book.js

Материал из Мракопедии
Перейти к: навигация, поиск

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

  • Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl-F5 или Ctrl-R (⌘-R на Mac)
  • Google Chrome: Нажмите Ctrl-Shift-R (⌘-Shift-R на Mac)
  • Internet Explorer: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl-F5
  • Opera: Выберите очистку кэша в меню Инструменты → Настройки
/********************************************************************************
* Этот модуль занимается интерактивными книгами.
*
* В качестве живого примера такой книги - см. историю "Берегись_лиловой_пасты!"
********************************************************************************/

~function() {

setupInteractiveBook();

function setupInteractiveBook() {
  if (!isInteractiveBook()) {
    return;
  }
  
  importStylesheet('Mediawiki:Modules/interactive-book.css');
  
  $(function() {
    wrapChapters();
    listenPageNavigation();
    navigateToEntry();
    $(window).bind('hashchange', function() {
      navigateToEntry();
    });
    finishLoading('interactiveBook');
  });
}

function wrapChapters() {
  $('#mw-content-text > h2').each(function() {
    var headlineId = $(this).find('.mw-headline').attr('id');
    if (!headlineId) {
      return;
    }

    if ($(this).find('.mw-headline').text().substr(0, 1) === '$') {
      $(this).addClass('interactive-book-service-chapter');
      
      return;
    }
    
    var chapterId = 'chapter-' + headlineId;
    var $wrap = $('<div />');
    $wrap.addClass('interactive-book-chapter');
    $wrap.attr('id', chapterId);
    
    var $chapter = $(this).nextUntil("h2").andSelf();
    $chapter.wrapAll($wrap);
  });
}

function pushState(hash) {
  if ((window.history == null) || (history.pushState == null)) {
    return;
  }
  
  if (window.localStorage && (+localStorage.interactiveBookCheats)) {
    history.pushState(null, '', hash);
  } else {
    history.replaceState(null, '', hash);
  }
}
  
function interactiveBookGoto(hash) {
  pushState(hash);
  
  var id = 'chapter-' + decodeURIComponent(hash.substr(1));
  
  var $chapter = $('#' + escapeId(id));
  
  if ($chapter.length === 0) {
    alert('Ой!\n\nКажется, эта ссылка ведет в никуда, и так явно не должно быть.\n\nПожалуйста, напишите об этом на странице обсуждения истории.\n\nОтсутствующий анкер: ' + id);
    return;
  }
  
  $('.interactive-book-chapter-active').removeClass('interactive-book-chapter-active');
  
  $chapter
    .addClass('interactive-book-chapter-active')
    [0].scrollIntoView({
      behavior: "instant",
      block: "start"
    });
}

function isRelative(link) {
  var loc = window.location;
  
  return ((link.protocol === loc.protocol) && (link.host === loc.host) && (link.pathname === loc.pathname) && (link.search === loc.search));
}

function listenPageNavigation() {
  $('.interactive-book-chapter a[href]').click(function(ev) {
    if (!isRelative(this)) {
      return;
    }
    
    ev.preventDefault();
    ev.stopPropagation();
    
    interactiveBookGoto(this.hash);
  });
}

function navigateToEntry() {
  var id;
  if (window.location.hash) {
    id = window.location.hash;
  } else {
    id = '#' + $('.interactive-book-entry').closest('.interactive-book-chapter').find('.mw-headline').attr('id');
  }
  
  interactiveBookGoto(id);
}

function escapeId(id) {
  return id.replace(/([\/\[\\\]\` !"#$%&'()*+,.:;<=>?@^{|}~])/g, '\\$1');
}

function isInteractiveBook() {
  return $('.interactive-book-entry').length !== 0;
}

}();