MediaWiki:Common.js: различия между версиями
Pok (обсуждение | вклад) Нет описания правки |
Pok (обсуждение | вклад) Нет описания правки |
||
| Строка 273: | Строка 273: | ||
// Функция для увеличения яркости цвета | // Функция для увеличения яркости цвета | ||
function brightenColor(color, factor) { | function brightenColor(color, factor) { | ||
function getBrightness(r, g, b) { | |||
return 0.2126 * r + 0.7152 * g + 0.0722 * b; | |||
} | |||
function isGray(r, g, b) { | |||
const maxDiff = 20; | |||
return Math.abs(r - g) < maxDiff | |||
&& Math.abs(g - b) < maxDiff | |||
&& Math.abs(r - b) < maxDiff; | |||
} | |||
const vals = color.match(/-?\d+(\.\d+)?/g).map(parseFloat); | |||
let [r, g, b, a = 1] = vals; | |||
if (r <= 1 && g <= 1 && b <= 1) { | |||
r *= 255; | |||
g *= 255; | |||
b *= 255; | |||
} | |||
r = Math.round(r); | |||
g = Math.round(g); | |||
b = Math.round(b); | |||
const brightness = getBrightness(r, g, b); | |||
if (factor === undefined) { | |||
if (brightness <= 40) { | |||
factor = 6; | |||
} else if (brightness <= 180) { | |||
factor = 4; | |||
} else { | |||
factor = 0; | |||
} | |||
} | |||
if (isGray(r, g, b)) { | |||
factor = Math.max(1, factor * 0.5); | |||
} | |||
r = Math.min(255, r + factor); | |||
g = Math.min(255, g + factor); | |||
b = Math.min(255, b + factor); | |||
if (a < 1) { | |||
return `rgba(${r}, ${g}, ${b}, ${a})`; | |||
} else { | |||
return `rgb(${r}, ${g}, ${b})`; | |||
} | |||
} | } | ||
| Строка 621: | Строка 621: | ||
} | } | ||
function layerIndex() { | function layerIndex() { | ||
var z_index = 1000; | |||
document.querySelectorAll('.z-index-position').forEach(function(domEl) { | |||
domEl.style.zIndex = z_index--; | |||
}); | |||
} | } | ||
// Для "Шаблон:Ajax" | // Для "Шаблон:Ajax" | ||
function initAjaxLoader() { | function initAjaxLoader() { | ||
var ajaxElements = document.querySelectorAll('.ajax-load-link'); | |||
var BATCH_SIZE = 1000; | |||
var queue = []; | |||
var processing = false; | |||
function fetchParsedData(wikiText) { | |||
var apiUrl = "https://station14.ru/api.php?action=parse&format=json&prop=text&text=" + encodeURIComponent(wikiText) + "&origin=*"; | |||
return $.ajax({ | |||
url: apiUrl, | |||
method: "GET", | |||
dataType: "json" | |||
}); | |||
} | |||
function applyParsedHTML(parsedHTML, placeholder) { | |||
var newContainer = document.createElement("span"); | |||
newContainer.innerHTML = parsedHTML; | |||
if (placeholder && placeholder.parentNode) { | |||
placeholder.replaceWith(newContainer); | |||
} | |||
var scripts = Array.prototype.slice.call(newContainer.querySelectorAll("script")); | |||
scripts.forEach(function (scr) { | |||
var parent = scr.parentNode; | |||
var scriptNode = document.createElement("script"); | |||
if (scr.src) { | |||
scriptNode.src = scr.src; | |||
if (scr.defer) scriptNode.defer = true; | |||
if (scr.async) scriptNode.async = true; | |||
parent.replaceChild(scriptNode, scr); | |||
} else { | |||
try { | |||
$.globalEval(scr.textContent || scr.innerText || ""); | |||
} catch (e) {} | |||
parent.removeChild(scr); | |||
} | |||
}); | |||
mw.loader.using(['jquery.tablesorter', 'jquery.makeCollapsible'], function () { | |||
$(newContainer).find('table.sortable').tablesorter(); | |||
$(newContainer).find('.mw-collapsible').makeCollapsible(); | |||
}); | |||
mw.hook('wikipage.content').fire(newContainer); | |||
mw.loader.load('//station14.ru/w/index.php?title=MediaWiki:Common.js&action=raw&ctype=text/javascript'); | |||
} | |||
function processQueue() { | |||
if (processing) return; | |||
processing = true; | |||
function nextBatch() { | |||
if (queue.length === 0) { | |||
processing = false; | |||
return; | |||
} | |||
var batch = queue.splice(0, BATCH_SIZE); | |||
var remaining = batch.length; | |||
batch.forEach(function (job) { | |||
fetchParsedData(job.wikiText) | |||
.done(function (data) { | |||
if (data.parse && data.parse.text) { | |||
var parsedHTML = data.parse.text["*"] || ""; | |||
applyParsedHTML(parsedHTML, job.placeholder); | |||
} else { | |||
if (job.placeholder) job.placeholder.textContent = "API не вернул ожидаемых данных."; | |||
} | |||
}) | |||
.fail(function () { | |||
if (job.placeholder) job.placeholder.textContent = "Ошибка при выполнении запроса к API."; | |||
}) | |||
.always(function () { | |||
remaining--; | |||
if (remaining === 0) { | |||
nextBatch(); | |||
} | |||
}); | |||
}); | |||
} | |||
nextBatch(); | |||
} | |||
var standaloneContents = document.querySelectorAll('.ajax-load-content'); | |||
standaloneContents.forEach(function (content) { | |||
if (!content.closest('.ajax-load-link')) { | |||
var wikiText = content ? (content.textContent || content.innerText) : null; | |||
if (!wikiText) return; | |||
var placeholder = document.createElement("span"); | |||
placeholder.textContent = "Пожалуйста, подождите, содержимое загружается..."; | |||
content.replaceWith(placeholder); | |||
queue.push({ wikiText: wikiText, placeholder: placeholder }); | |||
} | |||
}); | |||
ajaxElements.forEach(function (element) { | |||
element.addEventListener('click', function () { | |||
var content = element.querySelector('.ajax-load-content'); | |||
var wikiText = content ? (content.textContent || content.innerText) : null; | |||
if (!wikiText) return; | |||
var placeholder = document.createElement("span"); | |||
placeholder.textContent = "Пожалуйста, подождите, содержимое загружается..."; | |||
element.replaceWith(placeholder); | |||
queue.push({ wikiText: wikiText, placeholder: placeholder }); | |||
processQueue(); | |||
}); | |||
}); | |||
if (queue.length > 0) processQueue(); | |||
} | } | ||
// Для "Шаблон:CheckboxCreator" | // Для "Шаблон:CheckboxCreator" | ||
function initCheckboxCreator() { | |||
var containers = document.querySelectorAll('.checkbox-generator'); | |||
function parseBool(v) { | |||
if (v === undefined || v === null) return false; | |||
v = String(v).trim().toLowerCase(); | |||
return v === '1' || v === 'true' || v === 'yes' || v === 'checked'; | |||
} | |||
function makeCheckbox(container, spec) { | |||
var input = document.createElement('input'); | |||
input.type = 'checkbox'; | |||
if (spec.cls) input.className = spec.cls; | |||
if (spec.name) input.name = spec.name; | |||
if (spec.id) input.id = spec.id; | |||
if (spec.checked) input.checked = true; | |||
if (spec.disabled) input.disabled = true; | |||
var label = document.createElement('label'); | |||
if (spec.id) label.htmlFor = spec.id; | |||
label.textContent = spec.label || ''; | |||
var wrapper = document.createElement('span'); | |||
wrapper.className = 'checkbox-gen-item'; | |||
wrapper.appendChild(input); | |||
wrapper.appendChild(label); | |||
container.appendChild(wrapper); | |||
} | |||
containers.forEach(function(container) { | |||
if (container.dataset.checkboxInitialized === '1') return; | |||
var itemsRaw = container.dataset.cboxItems; | |||
if (itemsRaw) { | |||
try { | |||
var arr = JSON.parse(itemsRaw); | |||
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(); | |||
} | } | ||
if (document.querySelectorAll('.ajax-load-content').length > 0) { | if (document.querySelectorAll('.ajax-load-content').length > 0) { | ||
initAjaxLoader(); | |||
} | |||
var checkboxExist = document.querySelectorAll('.checkbox-generator'); | |||
if (checkboxExist.length > 0) { | |||
initCheckboxCreator(); | |||
} | } | ||
}); | }); | ||
| Строка 981: | Строка 973: | ||
/* Добавляет кнопку «Вверх» слева */ | /* Добавляет кнопку «Вверх» слева */ | ||
function scrollTop(){ | function scrollTop(){ | ||
$(window).scroll(function(e) { | |||
if($(window).scrollTop()>0) { | |||
$("#scroll-top").fadeIn(300); | |||
} else{ | |||
$("#scroll-top").fadeOut(300); | |||
} | |||
}); | |||
} | } | ||
| Строка 1414: | Строка 1406: | ||
(function($, mw) { | (function($, mw) { | ||
mw.loader.using('ext.gadget.theme').then(function() { | |||
const { loadTheme, initThemeMenu } = mw.themeUtils; | |||
function createSettingsDropdown(currentTheme) { | |||
const $dropdown = $('<div>', { class: 'theme-dropdown' }); | |||
const $details = $('<details>', { id: 'theme-preferences-details', class: 'theme-dropdown-details' }); | |||
const $summary = $('<summary>', { class: 'theme-dropdown-summary', 'data-tooltip-initialized': 'true' }) | |||
.append($('<span>', { class: 'theme-icon theme-icon-settings' })); | |||
$details.append($summary); | |||
const $window = $('<div>', { id: 'theme-preferences', class: 'theme-window' }).hide(); | |||
const $header = $('<div>', { | |||
id: 'theme-preferences__header', | |||
class: 'theme-window__header', | |||
text: 'Параметры' | |||
}); | |||
$window.append($header); | |||
const $content = $('<div>', { | |||
id: 'theme-preferences__content', | |||
class: 'theme-window__content' | |||
}); | |||
$window.append($content); | |||
initThemeMenu($content, currentTheme); | |||
$dropdown.append($details, $window); | |||
const $container = $('#user-tools').length ? $('#user-tools') : $('.minerva-search-form'); | |||
$container.append($dropdown); | |||
const $cover = $('#menus-cover'); | |||
$details.on('toggle', function() { | |||
const isOpen = $(this).prop('open'); | |||
$window.toggle(isOpen); | |||
if ($cover.length) { | |||
$cover.css('display', isOpen ? 'block' : 'none'); | |||
} | |||
}); | |||
$(document).on('click', function(e) { | |||
const isClickInside = $(e.target).closest('.theme-window, .theme-dropdown-summary').length > 0; | |||
if (!isClickInside && $details.prop('open')) { | |||
$details.removeAttr('open'); | |||
if ($cover.length) { | |||
$cover.css('display', 'none'); | |||
} | |||
} | |||
}); | |||
} | |||
function init() { | |||
const theme = loadTheme(); | |||
createSettingsDropdown(theme); | |||
} | |||
$(function() { | |||
setTimeout(init, 100); | |||
}); | |||
}); | |||
}(jQuery, mediaWiki)); | }(jQuery, mediaWiki)); | ||