User:Не кочан/global.js

nkch_css_configs = { saveWithCookies: true, useAnimations: true, useLess: true, useSass: true }

importArticles({   type: "script",    articles: [        // 'u:nkch:MediaWiki:nkchCSS.js',        // 'u:nkch:MediaWiki:nkchCSS4.js',        'u:nkch:MediaWiki:ThemeToggler.js',        // 'u:dev:MediaWiki:PortableCSSPad/code.js',        'u:dev:MediaWiki:PurgeButton/code.js',        'u:dev:MediaWiki:QuickDiff/code.js',        'u:nkch:MediaWiki:ProfileBanner.js',        'u:nkch:MediaWiki:WhatLeavesHere.js'    ] });

mw.loader.getScript("https://cdn.jsdelivr.net/gh/Vonavy/nkch-css@latest/dist/index.js");

$(function {    var _config = {        mbNoAutoStart: false,        mbTooltip: ';$1 заблокирован ($2) участником $3: $4 ($5)',        mbTempStyle: 'opacity:0.7; text-decoration:line-through;',        mbIndefStyle: 'opacity:0.4; font-style:italic; text-decoration:line-through;',        mbTipBox: null,        mbTipBoxStyle: 'font-size:85%; background:#FFFFF0; border:1px solid #FEA; padding:0 0.3em; color:#AAA;',        mbLoadingOpacity: 0.85    },        _wasRunned = false,        _api,        _userNS = [],        _userTitleRX,        _articleRX,        _scriptRX,        _$portletLink,        _users = {},        _processedLinks = [];

function parseTS(ts) { var m = ts.replace(/\D/g, '').match(/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/) return new Date(Date.UTC(m[1], m[2] - 1, m[3], m[4], m[5], m[6])) }

function inHours(ms) { var mm = Math.floor(ms / 60000); if (!mm) return Math.floor(ms / 1000) + " с.";

var hh = Math.floor(mm / 60);

mm = mm % 60;

var dd = Math.floor(hh / 24);

hh = hh % 24;

if (dd) return dd + (dd < 10 ? '.' + hh.toString.padStart(2, "0") : '') + " дн.";

return hh + ":" + mm.toString.padStart(2, "0"); }

function markBlocked(container) { var contentLinks, userLinks, users, user, promises, waitingCSS

contentLinks = !_wasRunned || !container ? (mw.util.$content || $(".mw-body")).find("a").add("#ca-nstab-user a") : $(container).find("a");

userLinks = {}; contentLinks.each(function (i, link) {           if (_processedLinks.indexOf(link) !== -1) return;

user = getLinkUser(link);

if (user) { if (!userLinks[user]) userLinks[user] = []; userLinks[user].push(link); _processedLinks.push(link); }       })

users = Object.keys(userLinks).filter(function (user) {           return !_users[user];        })

if (!users || users.length === 0) { markLinks(userLinks); return; }

waitingCSS = mw.util.addCSS("a.userlink {opacity:" + _config.mbLoadingOpacity + "}") promises = []; while (users.length > 0) { promises.push(               request(users.splice(0, 50))            ) }

$.when.apply($, promises).always(function {            markLinks(userLinks);            waitingCSS.disabled = true;            _$portletLink && _$portletLink.remove;        })

if (!_wasRunned) _wasRunned = true; }

function getLinkUser(link) { var ma, pgTitle, user, $link = $(link), url = $link.attr("href");

if (!url || url.charAt(0) !== '/') return;

if ((ma = _articleRX.exec(url)) || (ma = _scriptRX.exec(url))) { pgTitle = ma[1]; } else return;

pgTitle = decodeURIComponent(pgTitle).replace(/_/g, ' '); user = _userTitleRX.exec(pgTitle);

if (!user) return;

user = user[2]; if (user === 'К удалению') return;

$link.addClass('userlink') return user }

function request(users) { var params = { action: "query", list: "blocks", bklimit: 100, bkusers: users, bkprop: ["user", "by", "timestamp", "expiry", "reason", "flags"], format: "json" }       return _api .post(params) .then(response) }

function response(data, xhr) { var list, user, serverTime = new Date(xhr.getResponseHeader("Date"))

if (!data || !data.query || !data.query.blocks) return;

list = data.query.blocks;

list.forEach(function (item, i) {           user = {                name: item.user,                data: item,                partial: ''            }

var diff = (serverTime - new Date(user.data.timestamp));

if (/^in/.test(user.data.expiry)) { user.class = "user-blocked-indef" user.blTime = user.data.expiry } else { user.class = "user-blocked-temp" user.blTime = inHours(parseTS(user.data.expiry) - parseTS(user.data.timestamp)) }

if ("partial" in user.data) { user.class = "user-blocked-partial" user.partial = " partial" }

user.message = _config.mbTooltip .replace("$1", user.partial) .replace("$2", user.blTime) .replace("$3", user.data.by) .replace("$4", user.data.reason) .replace("$5", new Intl.RelativeTimeFormat.format(-(Math.floor(diff / (1000 * 60 * 60 * 24))), "days")); _users[user.name] = user; })   }

function markLinks(userLinks) { var user, $link $.each(userLinks, function (userName, links) {           user = _users[userName]            if (!user) {                return            }            links.forEach(function (link) { $link = $(link).addClass(user.class) if (_config.mbTipBox) { $(' # ')                       .attr('title', user.message) .insertBefore($link) } else { $link.attr('title', $link.attr('title') + user.message) }           })        })    }

function prepare { var wgNamespaceIds

_config = $.extend(_config, {           mbNoAutoStart: window.mbNoAutoStart,            mbTooltip: window.mbTooltip,            mbTempStyle: window.mbTempStyle,            mbIndefStyle: window.mbIndefStyle,            mbTipBox: window.mbTipBox,            mbTipBoxStyle: window.mbTipBoxStyle,            mbLoadingOpacity: window.mbLoadingOpacity        });

_api = new mw.Api; wgNamespaceIds = mw.config.get("wgNamespaceIds");

$.each(wgNamespaceIds, function (ns, id) {           if ([2, 3, 1200].indexOf(id) !== -1) {                _userNS.push(ns.replace(/_/g, " ") + ":")            }        });

// RegExp for all titles that are  User: | User_talk: | Special:Contributions/ (localized) | Special:Contributions/ (for userscripts) _userTitleRX = new RegExp('^'           + '(' + _userNS.join('|') + '|Служебная:Вклад\\/|Special:Contributions\\/' + ')'           + '([^\\/#]+)$', 'i')

//RegExp for links _articleRX = new RegExp(           '^(?:' + mw.config.get('wgServer') + ')?' +            mw.config.get('wgArticlePath').replace('$1', '') + '([^#]+)'        )

_scriptRX = new RegExp(           '^(?:' + mw.config.get('wgServer') + ')?' +            mw.config.get('wgScript') + '\\?title=([^#&]+)'        )

// Add custom css mw.util.addCSS('\			.mediawiki .user-blocked-temp {'  + _config.mbTempStyle + '}\			.mediawiki .user-blocked-indef {'  + _config.mbIndefStyle + '}\			.mediawiki .user-blocked-tipbox {' + _config.mbTipBoxStyle + '}\		' ) }

window.markBlocked = markBlocked;

switch (mw.config.get("wgAction")) { case "edit": case "submit": case "delete": break; case "view": if ([0, 10].indexOf(mw.config.get("wgNamespaceNumber")) !== -1) break; default: // 'history', 'purge' mw.loader.using("mediawiki.util").done(function {                prepare;

if (_config.mbNoAutoStart) { _$portletLink = $(mw.util.addPortletLink("p-cactions", null, "XX", "ca-showblocks")) _$portletLink.on("click", function (e) {                       e.preventDefault                        markBlocked                    }) } else { mw.hook("wikipage.content").add(markBlocked) mw.hook("global.userlinks").add(markBlocked) }           })    } })