MediaWiki:Common.js: различия между версиями

Нет описания правки
Нет описания правки
Строка 273: Строка 273:
// Функция для увеличения яркости цвета
// Функция для увеличения яркости цвета
function brightenColor(color, factor) {
function brightenColor(color, factor) {
    function getBrightness(r, g, b) {
function getBrightness(r, g, b) {
        return 0.2126 * r + 0.7152 * g + 0.0722 * b;
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
    }
}


    function isGray(r, g, b) {
function isGray(r, g, b) {
        const maxDiff = 20;  
const maxDiff = 20;  
        return Math.abs(r - g) < maxDiff
return Math.abs(r - g) < maxDiff
            && Math.abs(g - b) < maxDiff
&& Math.abs(g - b) < maxDiff
            && Math.abs(r - b) < maxDiff;
&& Math.abs(r - b) < maxDiff;
    }
}


    const vals = color.match(/-?\d+(\.\d+)?/g).map(parseFloat);
const vals = color.match(/-?\d+(\.\d+)?/g).map(parseFloat);
    let [r, g, b, a = 1] = vals;
let [r, g, b, a = 1] = vals;


    if (r <= 1 && g <= 1 && b <= 1) {
if (r <= 1 && g <= 1 && b <= 1) {
        r *= 255;
r *= 255;
        g *= 255;
g *= 255;
        b *= 255;
b *= 255;
    }
}


    r = Math.round(r);
r = Math.round(r);
    g = Math.round(g);
g = Math.round(g);
    b = Math.round(b);
b = Math.round(b);


    const brightness = getBrightness(r, g, b);
const brightness = getBrightness(r, g, b);


    if (factor === undefined) {
if (factor === undefined) {
        if (brightness <= 40) {
if (brightness <= 40) {
            factor = 6;
factor = 6;
        } else if (brightness <= 180) {
} else if (brightness <= 180) {
            factor = 4;
factor = 4;
        } else {
} else {
            factor = 0;
factor = 0;
        }
}
    }
}


    if (isGray(r, g, b)) {
if (isGray(r, g, b)) {
        factor = Math.max(1, factor * 0.5);
factor = Math.max(1, factor * 0.5);
    }
}


    r = Math.min(255, r + factor);
r = Math.min(255, r + factor);
    g = Math.min(255, g + factor);
g = Math.min(255, g + factor);
    b = Math.min(255, b + factor);
b = Math.min(255, b + factor);


    if (a < 1) {
if (a < 1) {
        return `rgba(${r}, ${g}, ${b}, ${a})`;
return `rgba(${r}, ${g}, ${b}, ${a})`;
    } else {
} else {
        return `rgb(${r}, ${g}, ${b})`;
return `rgb(${r}, ${g}, ${b})`;
    }
}
}
}


Строка 621: Строка 621:
}
}
function layerIndex() {
function layerIndex() {
    var z_index = 1000;
var z_index = 1000;


    document.querySelectorAll('.z-index-position').forEach(function(domEl) {
document.querySelectorAll('.z-index-position').forEach(function(domEl) {
        domEl.style.zIndex = z_index--;
domEl.style.zIndex = z_index--;
    });
});
}
}
// Для "Шаблон:Ajax"
// Для "Шаблон:Ajax"
function initAjaxLoader() {
function initAjaxLoader() {
    var ajaxElements = document.querySelectorAll('.ajax-load-link');
var ajaxElements = document.querySelectorAll('.ajax-load-link');


    var BATCH_SIZE = 1000;
var BATCH_SIZE = 1000;
    var queue = [];
var queue = [];
    var processing = false;
var processing = false;


    function fetchParsedData(wikiText) {
function fetchParsedData(wikiText) {
        var apiUrl = "https://station14.ru/api.php?action=parse&format=json&prop=text&text=" + encodeURIComponent(wikiText) + "&origin=*";
var apiUrl = "https://station14.ru/api.php?action=parse&format=json&prop=text&text=" + encodeURIComponent(wikiText) + "&origin=*";
        return $.ajax({
return $.ajax({
            url: apiUrl,
url: apiUrl,
            method: "GET",
method: "GET",
            dataType: "json"
dataType: "json"
        });
});
    }
}


    function applyParsedHTML(parsedHTML, placeholder) {
function applyParsedHTML(parsedHTML, placeholder) {
        var newContainer = document.createElement("span");
var newContainer = document.createElement("span");
        newContainer.innerHTML = parsedHTML;
newContainer.innerHTML = parsedHTML;
        if (placeholder && placeholder.parentNode) {
if (placeholder && placeholder.parentNode) {
            placeholder.replaceWith(newContainer);
placeholder.replaceWith(newContainer);
        }
}


        var scripts = Array.prototype.slice.call(newContainer.querySelectorAll("script"));
var scripts = Array.prototype.slice.call(newContainer.querySelectorAll("script"));
        scripts.forEach(function (scr) {
scripts.forEach(function (scr) {
            var parent = scr.parentNode;
var parent = scr.parentNode;
            var scriptNode = document.createElement("script");
var scriptNode = document.createElement("script");
            if (scr.src) {
if (scr.src) {
                scriptNode.src = scr.src;
scriptNode.src = scr.src;
                if (scr.defer) scriptNode.defer = true;
if (scr.defer) scriptNode.defer = true;
                if (scr.async) scriptNode.async = true;
if (scr.async) scriptNode.async = true;
                parent.replaceChild(scriptNode, scr);
parent.replaceChild(scriptNode, scr);
            } else {
} else {
                try {
try {
                    $.globalEval(scr.textContent || scr.innerText || "");
$.globalEval(scr.textContent || scr.innerText || "");
                } catch (e) {}
} catch (e) {}
                parent.removeChild(scr);
parent.removeChild(scr);
            }
}
        });
});


        mw.loader.using(['jquery.tablesorter', 'jquery.makeCollapsible'], function () {
mw.loader.using(['jquery.tablesorter', 'jquery.makeCollapsible'], function () {
            $(newContainer).find('table.sortable').tablesorter();
$(newContainer).find('table.sortable').tablesorter();
            $(newContainer).find('.mw-collapsible').makeCollapsible();
$(newContainer).find('.mw-collapsible').makeCollapsible();
        });
});


        mw.hook('wikipage.content').fire(newContainer);
mw.hook('wikipage.content').fire(newContainer);
        mw.loader.load('//station14.ru/w/index.php?title=MediaWiki:Common.js&action=raw&ctype=text/javascript');
mw.loader.load('//station14.ru/w/index.php?title=MediaWiki:Common.js&action=raw&ctype=text/javascript');
    }
}


    function processQueue() {
function processQueue() {
        if (processing) return;
if (processing) return;
        processing = true;
processing = true;


        function nextBatch() {
function nextBatch() {
            if (queue.length === 0) {
if (queue.length === 0) {
                processing = false;
processing = false;
                return;
return;
            }
}


            var batch = queue.splice(0, BATCH_SIZE);
var batch = queue.splice(0, BATCH_SIZE);
            var remaining = batch.length;
var remaining = batch.length;


            batch.forEach(function (job) {
batch.forEach(function (job) {
                fetchParsedData(job.wikiText)
fetchParsedData(job.wikiText)
                    .done(function (data) {
.done(function (data) {
                        if (data.parse && data.parse.text) {
if (data.parse && data.parse.text) {
                            var parsedHTML = data.parse.text["*"] || "";
var parsedHTML = data.parse.text["*"] || "";
                            applyParsedHTML(parsedHTML, job.placeholder);
applyParsedHTML(parsedHTML, job.placeholder);
                        } else {
} else {
                            if (job.placeholder) job.placeholder.textContent = "API не вернул ожидаемых данных.";
if (job.placeholder) job.placeholder.textContent = "API не вернул ожидаемых данных.";
                        }
}
                    })
})
                    .fail(function () {
.fail(function () {
                        if (job.placeholder) job.placeholder.textContent = "Ошибка при выполнении запроса к API.";
if (job.placeholder) job.placeholder.textContent = "Ошибка при выполнении запроса к API.";
                    })
})
                    .always(function () {
.always(function () {
                        remaining--;
remaining--;
                        if (remaining === 0) {
if (remaining === 0) {
                            nextBatch();
nextBatch();
                        }
}
                    });
});
            });
});
        }
}


        nextBatch();
nextBatch();
    }
}


    var standaloneContents = document.querySelectorAll('.ajax-load-content');
var standaloneContents = document.querySelectorAll('.ajax-load-content');
    standaloneContents.forEach(function (content) {
standaloneContents.forEach(function (content) {
        if (!content.closest('.ajax-load-link')) {
if (!content.closest('.ajax-load-link')) {
            var wikiText = content ? (content.textContent || content.innerText) : null;
var wikiText = content ? (content.textContent || content.innerText) : null;
            if (!wikiText) return;
if (!wikiText) return;


            var placeholder = document.createElement("span");
var placeholder = document.createElement("span");
            placeholder.textContent = "Пожалуйста, подождите, содержимое загружается...";
placeholder.textContent = "Пожалуйста, подождите, содержимое загружается...";
            content.replaceWith(placeholder);
content.replaceWith(placeholder);


            queue.push({ wikiText: wikiText, placeholder: placeholder });
queue.push({ wikiText: wikiText, placeholder: placeholder });
        }
}
    });
});


    ajaxElements.forEach(function (element) {
ajaxElements.forEach(function (element) {
        element.addEventListener('click', function () {
element.addEventListener('click', function () {
            var content = element.querySelector('.ajax-load-content');
var content = element.querySelector('.ajax-load-content');
            var wikiText = content ? (content.textContent || content.innerText) : null;
var wikiText = content ? (content.textContent || content.innerText) : null;
            if (!wikiText) return;
if (!wikiText) return;


            var placeholder = document.createElement("span");
var placeholder = document.createElement("span");
            placeholder.textContent = "Пожалуйста, подождите, содержимое загружается...";
placeholder.textContent = "Пожалуйста, подождите, содержимое загружается...";
            element.replaceWith(placeholder);
element.replaceWith(placeholder);


            queue.push({ wikiText: wikiText, placeholder: placeholder });
queue.push({ wikiText: wikiText, placeholder: placeholder });
            processQueue();
processQueue();
        });
});
    });
});


    if (queue.length > 0) processQueue();
if (queue.length > 0) processQueue();
}
}
// Для "Шаблон:CheckboxCreator"
// Для "Шаблон:CheckboxCreator"
( function () {
function initCheckboxCreator() {
    if ( window.checkboxGeneratorInit ) return;
var containers = document.querySelectorAll('.checkbox-generator');
    window.checkboxGeneratorInit = true;


    function parseBool(v) {
function parseBool(v) {
        if (!v && v !== 0) return false;
if (v === undefined || v === null) return false;
        v = String(v).trim().toLowerCase();
v = String(v).trim().toLowerCase();
        return v === '1' || v === 'true' || v === 'yes' || v === 'checked';
return v === '1' || v === 'true' || v === 'yes' || v === 'checked';
    }
}


    function makeSingle(container, spec) {
function makeCheckbox(container, spec) {
        var input = document.createElement('input');
var input = document.createElement('input');
        input.type = 'checkbox';
input.type = 'checkbox';
        if (spec.cls) input.className = spec.cls;
        if (spec.name) input.name = spec.name;
        input.checked = !!spec.checked;
        if (spec.id) input.id = spec.id;
        else input.id = 'chk-' + Math.random().toString(36).slice(2,9);
        if (spec.disabled) input.disabled = true;


        var label = document.createElement('label');
if (spec.cls) input.className = spec.cls;
        label.htmlFor = input.id;
if (spec.name) input.name = spec.name;
        label.textContent = spec.label || '';
if (spec.id) input.id = spec.id;
if (spec.checked) input.checked = true;
if (spec.disabled) input.disabled = true;


        var wrapper = document.createElement('span');
var label = document.createElement('label');
        wrapper.className = 'js-checkbox-gen-item';
if (spec.id) label.htmlFor = spec.id;
        wrapper.appendChild(input);
label.textContent = spec.label || '';
        wrapper.appendChild(label);


        container.appendChild(wrapper);
var wrapper = document.createElement('span');
    }
wrapper.className = 'checkbox-gen-item';


    function buildFromContainer(container) {
wrapper.appendChild(input);
        var itemsRaw = container.dataset.cboxItems;
wrapper.appendChild(label);
        if (itemsRaw) {
            try {
                var arr = JSON.parse(itemsRaw);
                if (Array.isArray(arr)) {
                    arr.forEach(function (it, idx) {
                        if (typeof it === 'string') {
                            makeSingle(container, { label: it });
                        } else if (typeof it === 'object' && it !== null) {
                            makeSingle(container, {
                                label: it.label || '',
                                cls: it["class"] || it.cls || container.dataset.cboxClass || '',
                                checked: parseBool(it.checked) || false,
                                name: it.name || '',
                                id: it.id || '',
                                disabled: parseBool(it.disabled) || false
                            });
                        }
                    });
                    return;
                }
            } catch (e) {
            }
        }


        var spec = {
container.appendChild(wrapper);
            label: container.dataset.cboxLabel || '',
}
            cls: container.dataset.cboxClass || '',
            checked: parseBool(container.dataset.cboxChecked),
            name: container.dataset.cboxName || '',
            id: container.dataset.cboxId || '',
            disabled: parseBool(container.dataset.cboxDisabled)
        };


        makeSingle(container, spec);
containers.forEach(function(container) {
    }
if (container.dataset.checkboxInitialized === '1') return;


    function init() {
var itemsRaw = container.dataset.cboxItems;
        var nodes = document.querySelectorAll('.js-checkbox-generator');
        nodes.forEach(function (node) {
            if (node.dataset.checkboxInitialized) return;
            node.innerHTML = '';
            buildFromContainer(node);
            node.dataset.checkboxInitialized = '1';
        });
    }


    if (document.readyState === 'loading') {
if (itemsRaw) {
        document.addEventListener('DOMContentLoaded', init);
try {
    } else {
var arr = JSON.parse(itemsRaw);
        init();
if (Array.isArray(arr)) {
    }
arr.forEach(function(it) {
}() );
if (typeof it === 'string') {
makeCheckbox(container, {
label: it,
cls: container.dataset.cboxClass || ''
});
} else if (typeof it === 'object') {
makeCheckbox(container, {
label: it.label || '',
cls: it["class"] || container.dataset.cboxClass || '',
checked: parseBool(it.checked),
name: it.name || '',
id: it.id || '',
disabled: parseBool(it.disabled)
});
}
});
}
} catch (e) {}
} else {
makeCheckbox(container, {
label: container.dataset.cboxLabel || '',
cls: container.dataset.cboxClass || '',
checked: parseBool(container.dataset.cboxChecked),
name: container.dataset.cboxName || '',
id: container.dataset.cboxId || '',
disabled: parseBool(container.dataset.cboxDisabled)
});
}
 
container.dataset.checkboxInitialized = '1';
});
}
const currentPageTitle = document.title;
const currentPageTitle = document.title;
$(document).ready(function() {
$(document).ready(function() {
Строка 924: Строка 912:
var layerIndexLoad = document.querySelectorAll('.z-index-position');
var layerIndexLoad = document.querySelectorAll('.z-index-position');
if (layerIndexLoad.length > 0) {
if (layerIndexLoad.length > 0) {
    layerIndex();  
layerIndex();  
}
}
if (document.querySelectorAll('.ajax-load-content').length > 0) {
if (document.querySelectorAll('.ajax-load-content').length > 0) {
    initAjaxLoader();
initAjaxLoader();
}
var checkboxExist = document.querySelectorAll('.checkbox-generator');
if (checkboxExist.length > 0) {
initCheckboxCreator();
}
}
});
});
Строка 981: Строка 973:
/* Добавляет кнопку «Вверх» слева */
/* Добавляет кнопку «Вверх» слева */
function scrollTop(){
function scrollTop(){
    $(window).scroll(function(e) {
$(window).scroll(function(e) {
    if($(window).scrollTop()>0) {
if($(window).scrollTop()>0) {
    $("#scroll-top").fadeIn(300);
$("#scroll-top").fadeIn(300);
    } else{  
} else{  
    $("#scroll-top").fadeOut(300);
$("#scroll-top").fadeOut(300);
    }
}
    });
});
}
}


Строка 1414: Строка 1406:


(function($, mw) {
(function($, mw) {
    mw.loader.using('ext.gadget.theme').then(function() {
mw.loader.using('ext.gadget.theme').then(function() {
        const { loadTheme, initThemeMenu } = mw.themeUtils;
const { loadTheme, initThemeMenu } = mw.themeUtils;


        function createSettingsDropdown(currentTheme) {
function createSettingsDropdown(currentTheme) {
            const $dropdown = $('<div>', { class: 'theme-dropdown' });
const $dropdown = $('<div>', { class: 'theme-dropdown' });
            const $details = $('<details>', { id: 'theme-preferences-details', class: 'theme-dropdown-details' });
const $details = $('<details>', { id: 'theme-preferences-details', class: 'theme-dropdown-details' });
            const $summary = $('<summary>', { class: 'theme-dropdown-summary', 'data-tooltip-initialized': 'true' })
const $summary = $('<summary>', { class: 'theme-dropdown-summary', 'data-tooltip-initialized': 'true' })
                .append($('<span>', { class: 'theme-icon theme-icon-settings' }));
.append($('<span>', { class: 'theme-icon theme-icon-settings' }));
            $details.append($summary);
$details.append($summary);


            const $window = $('<div>', { id: 'theme-preferences', class: 'theme-window' }).hide();
const $window = $('<div>', { id: 'theme-preferences', class: 'theme-window' }).hide();
            const $header = $('<div>', {
const $header = $('<div>', {
                id: 'theme-preferences__header',
id: 'theme-preferences__header',
                class: 'theme-window__header',
class: 'theme-window__header',
                text: 'Параметры'
text: 'Параметры'
            });
});
            $window.append($header);
$window.append($header);


            const $content = $('<div>', {
const $content = $('<div>', {
                id: 'theme-preferences__content',
id: 'theme-preferences__content',
                class: 'theme-window__content'
class: 'theme-window__content'
            });
});
            $window.append($content);
$window.append($content);


            initThemeMenu($content, currentTheme);
initThemeMenu($content, currentTheme);


            $dropdown.append($details, $window);
$dropdown.append($details, $window);


            const $container = $('#user-tools').length ? $('#user-tools') : $('.minerva-search-form');
const $container = $('#user-tools').length ? $('#user-tools') : $('.minerva-search-form');
            $container.append($dropdown);
$container.append($dropdown);


            const $cover = $('#menus-cover');
const $cover = $('#menus-cover');


            $details.on('toggle', function() {
$details.on('toggle', function() {
                const isOpen = $(this).prop('open');
const isOpen = $(this).prop('open');
                $window.toggle(isOpen);
$window.toggle(isOpen);


                if ($cover.length) {
if ($cover.length) {
                    $cover.css('display', isOpen ? 'block' : 'none');
$cover.css('display', isOpen ? 'block' : 'none');
                }
}
            });
});


            $(document).on('click', function(e) {
$(document).on('click', function(e) {
                const isClickInside = $(e.target).closest('.theme-window, .theme-dropdown-summary').length > 0;
const isClickInside = $(e.target).closest('.theme-window, .theme-dropdown-summary').length > 0;
                if (!isClickInside && $details.prop('open')) {
if (!isClickInside && $details.prop('open')) {
                    $details.removeAttr('open');
$details.removeAttr('open');
                    if ($cover.length) {
if ($cover.length) {
                        $cover.css('display', 'none');
$cover.css('display', 'none');
                    }
}
                }
}
            });
});
        }
}


        function init() {
function init() {
            const theme = loadTheme();
const theme = loadTheme();
            createSettingsDropdown(theme);
createSettingsDropdown(theme);
        }
}


        $(function() {
$(function() {
            setTimeout(init, 100);
setTimeout(init, 100);
        });
});
    });
});
}(jQuery, mediaWiki));
}(jQuery, mediaWiki));