MediaWiki:QuickDiff/code.js

/* QuickDiff - quickly view any diff link */

/*jslint browser, single */ /*global require */

require(['jquery', 'mw', 'wikia.ui.factory', 'wikia.window'], function ($, mw, uiFactory, context) {   'use strict';

// double-run protection if (context.quickDiffLoaded) { return; }   context.quickDiffLoaded = true;

// translations var lang = mw.config.get('wgUserLanguage'); var msg = { en: { error: 'Something went wrong while getting the page at “%url”.', loading: 'Loading…', title: 'Changes: %pagename' },       be: { error: 'Што-то пайшло не так падчас загрузкі старонкі «%url».', loading: 'Загрузка…', title: 'Змены: %pagename' },       es: { error: 'Un error ha occurido mientras se extraia la página en “%url”.', loading: 'Cargando…', title: 'Cambios: %pagename' },       it: { error: 'Qualcosa è andato storto mentre si caricava la pagina da “%url”.', loading: 'Caricamento…', title: 'Modifiche: %pagename' },       nl: { error: 'Er ging iets verkeerd bij het ophalen van de pagina op “%url”.', loading: 'Laden…', title: 'Wijzigingen: %pagename' },       pl: { error: 'Coś się zepsuło podczas ładowania strony „%url”.', loading: 'Ładowanie…', title: 'Zmiany: %pagename' },       ru: { error: 'Что-то пошло не так во время загрузки страницы «%url».', loading: 'Загрузка…', title: 'Изменения: %pagename' },       uk: { error: 'Щось пішло не так під час завантаження сторінки «%url».', loading: 'Завантаження…', title: 'Зміни: %pagename' },       vi: { error: 'Đã có sự cố xảy ra khi tải trang tại đường dẫn “%url”.', loading: 'Đang tải…', title: 'Thay đổi: %pagename' }   };    // use user language, with English as fallback msg = msg[lang] || msg[lang.split('-')['0']] || msg.en;

// used to detect "Special:Diff/12345" links // must be equal to the language's default alias for Special:Diff // as of 2016-09-12, only the en translation seems to be available on Wikia var specialDiff = { en: 'Diff' };   specialDiff = mw.config.get('wgFormattedNamespaces')['-1'] + ':' + (specialDiff[mw.config.get('wgContentLanguage')] || specialDiff.en) + '/';

var currentModal = null; var pendingModal = null; var uiModalFactory = null;

function updateModal(modal) { //initialise if new modal if (!currentModal) { currentModal = modal; modal.$buttons = modal.$element.find('> footer > .buttons'); modal.$content.addClass('WikiaArticle'); // better Oasis styling pendingModal['1'] = pendingModal['1'] || msg.loading; }

// update modal content + clear pending data var shouldFire = pendingModal['2']; if (pendingModal['1']) { modal.setTitle(msg.title.replace('%pagename', pendingModal['1'])); }       modal.setContent(pendingModal['0']); pendingModal = null; modal.$buttons.empty;

// fire event handlers if needed if (shouldFire) { mw.hook('quickdiff.ready').fire(modal); }

modal.show; }

function loadModal { if (uiModalFactory) { uiModalFactory.createComponent({               vars: {                    content: '',                    id: 'quickdiff-modal',                    size: 'large'                },                confirmCloseModal: function  {                    currentModal = null;                    return true;                }            }, updateModal); } else { uiFactory.init(['modal']).then(function (uiModal) {               uiModalFactory = uiModal;                loadModal;            }); }   }

function showModal(content, title, shouldFire) { if (pendingModal) { // modal is pending update - replace previous content with latest pendingModal = [content, title, shouldFire]; return; }

pendingModal = [content, title, shouldFire]; if (currentModal) { // modal is ready - update content updateModal(currentModal); } else { // no modal loaded loadModal; }   }

function loadDiff(url) { showModal(' ');

// add 'action=render' and 'diffonly' params to save some bytes on each request url.extend({           action: 'render',            diffonly: '1'        });

var urlString = url.toString; $.get(urlString).always(function (content) {           var $content = null;            var valid = false;

if (typeof content === 'string') { $content = $(content); }

if ($content && $content.hasClass('diff')) { valid = true; }

// not diff, but instead a complete page - see if a diff can be found // needed for diffs from Special:Diff / Special:Undelete, as they ignore action=render URL parameter if (!valid && $content) { var $contentDiff = $content.find('table.diff'); if ($contentDiff.length) { $content = $contentDiff; content = $contentDiff.prop('outerHTML'); valid = true; }           }

if (valid) { var title = $content.find('#mw-diff-ntitle1 > strong > a').attr('title'); mw.loader.using('mediawiki.action.history.diff', function {                    showModal(content, title, true);                }); } else { showModal(msg.error.replace('%url', urlString)); }       });    }

function init { mw.util.addCSS(           '#quickdiff-modal > section {' +                'box-sizing: border-box;' +  // prevent overflowing in IE 11                'font-size: 13px;' +         // better MonoBook font styling                'line-height: 21px;' +                'overflow: auto;' +          // defaults to visible on .WikiaArticle in message wall / forum namespaces                'position: relative;' +      // prevent throbber showing over title            '}' +            '#blackout_quickdiff-modal ~ .modalWrapper {' +                'position: fixed;' +         // fix modals shown on top of QuickDiff            '}'        );

// attach to body for compatibility with ajax-loaded content // also, one attached event handler is better than hundreds! $(document.body).on('click.quickdiff', 'a', function (event) {           var target = event.currentTarget;            var url = target.href && new mw.Uri(target.href);

// quit early if link is empty or is cross-domain if (!url || url.host !== location.hostname) { return; }

// has diff param + no fragment (prevents triggering by section links on diff pages) var hasDiffParam = url.query.diff !== undefined && !url.fragment; var isSpecialDiffLink = target.title.indexOf(specialDiff) === 0;

if (hasDiffParam || isSpecialDiffLink) { event.preventDefault; loadDiff(url); }       });    }

$(init);

// hook to collect action links (edit, undo, rollback, patrol) and add them to modal footer mw.hook('quickdiff.ready').add(function (modal) {       var $buttons = modal.$content.find('.diff-ntitle')            .find('.mw-rev-head-action, .mw-rollback-link, .patrollink').clone;

// remove text nodes (the brackets around each link) $buttons.contents.filter(function (ignore, element) {           return element.nodeType === 3;        }).remove;

$buttons.find('a').addClass('button');

modal.$buttons.append($buttons); });

});