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

Нет описания правки
Нет описания правки
 
(не показано 16 промежуточных версий этого же участника)
Строка 627: Строка 627:
});
});
}
}
// Для "Шаблон:Ajax"
function fetchParsedData(wikiText) {
function initAjaxLoader() {
var apiUrl = "https://station14.ru/api.php?action=parse&format=json&prop=text&text=" + encodeURIComponent(wikiText) + "&origin=*";
var ajaxContainers = document.querySelectorAll('.ajax-load, .ajax-load-link');
return $.ajax({
var BATCH_SIZE = 1000;
url: apiUrl,
var queue = [];
method: "GET",
var processing = false;
dataType: "json"
});
}
 
function enhanceParsedContent(root) {
if (!root) return;
 
var scripts = Array.prototype.slice.call(root.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 () {
$(root).find('table.sortable').tablesorter();
$(root).find('.mw-collapsible').makeCollapsible();
});
 
mw.hook('wikipage.content').fire(root);
 
initAjaxLoader(root);
}
 
function injectParsedHTML(parsedHTML, options) {
options = options || {};
 
var container = document.createElement("span");
container.innerHTML = parsedHTML;


var loadingImgHTML = '<img alt="Файл:Silva-loading.gif" src="/images/4/45/Silva-loading.gif?20260316201152" decoding="async" width="16" height="16" data-file-width="16" data-file-height="16" style="vertical-align:middle;margin-right:6px">';
if (options.keepNode) {
container.insertBefore(options.keepNode, container.firstChild);
}


function fetchParsedData(wikiText) {
if (options.placeholder && options.placeholder.parentNode) {
var apiUrl = "https://station14.ru/api.php?action=parse&format=json&prop=text&text=" + encodeURIComponent(wikiText) + "&origin=*";
options.placeholder.replaceWith(container);
return $.ajax({
} else if (options.targetRoot) {
url: apiUrl,
options.targetRoot.innerHTML = "";
method: "GET",
while (container.firstChild) {
dataType: "json"
options.targetRoot.appendChild(container.firstChild);
});
}
container = options.targetRoot;
}
}


function applyParsedHTML(parsedHTML, placeholder) {
enhanceParsedContent(container);
var newContainer = document.createElement("span");
newContainer.innerHTML = parsedHTML;


if (placeholder && placeholder.parentNode) {
return container;
placeholder.replaceWith(newContainer);
}
}


var scripts = Array.prototype.slice.call(newContainer.querySelectorAll("script"));
function parseAndInjectWikiText(wikiText, options) {
scripts.forEach(function (scr) {
return fetchParsedData(wikiText)
var parent = scr.parentNode;
.done(function (data) {
var scriptNode = document.createElement("script");
if (data && data.parse && data.parse.text) {
if (scr.src) {
var parsedHTML = data.parse.text["*"] || "";
scriptNode.src = scr.src;
injectParsedHTML(parsedHTML, options);
if (scr.defer) scriptNode.defer = true;
} else if (options && options.placeholder) {
if (scr.async) scriptNode.async = true;
options.placeholder.textContent = "API не вернул ожидаемых данных.";
parent.replaceChild(scriptNode, scr);
}
} else {
})
try { $.globalEval(scr.textContent || scr.innerText || ""); } catch (e) {}
.fail(function () {
parent.removeChild(scr);
if (options && options.placeholder) {
options.placeholder.textContent = "Ошибка при выполнении запроса к API.";
}
}
});
});
}


mw.loader.using(['jquery.tablesorter', 'jquery.makeCollapsible'], function () {
function createPlaceholderWithSpinner(text) {
$(newContainer).find('table.sortable').tablesorter();
if (!text) {
$(newContainer).find('.mw-collapsible').makeCollapsible();
loadingImgHTML = '<img alt="Файл:Silva-loading.gif" src="/images/4/45/Silva-loading.gif" decoding="async" width="16" height="16" style="vertical-align:middle;margin-right:6px">';
});
text = loadingImgHTML + '<span class="ajax-load-text">Пожалуйста, подождите, содержимое загружается...</span>';
}
 
var placeholder = document.createElement("span");
placeholder.className = "ajax-load-placeholder";
placeholder.innerHTML = text;
 
return placeholder;
}
 
// Для "Шаблон:Ajax"
function initAjaxLoader(root) {
root = root || document;


mw.hook('wikipage.content').fire(newContainer);
var ajaxContainers = root.querySelectorAll('.ajax-load, .ajax-load-link');
mw.loader.load('//station14.ru/w/index.php?title=MediaWiki:Common.js&action=raw&ctype=text/javascript');
var BATCH_SIZE = 1000;
}
var queue = [];
var processing = false;


function processQueue() {
function processQueue() {
Строка 691: Строка 745:


batch.forEach(function (job) {
batch.forEach(function (job) {
fetchParsedData(job.wikiText)
parseAndInjectWikiText(job.wikiText, { placeholder: job.placeholder })
.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 () {
.always(function () {
remaining--;
remaining--;
Строка 722: Строка 765:
if (!wikiText) return;
if (!wikiText) return;


var loadingText = (loadingEl && (loadingEl.textContent || loadingEl.innerText || "").trim()) || "Загрузка...";
var loadingHTML = loadingEl ? (loadingEl.innerHTML || "").trim() : "";


if (loadingEl && loadingEl.parentNode) {
if (loadingEl && loadingEl.parentNode) {
loadingEl.parentNode.removeChild(loadingEl);
loadingEl.parentNode.removeChild(loadingEl);
loadingEl = null;
}
function createPlaceholderWithSpinner(text) {
var placeholder = document.createElement("span");
placeholder.className = "ajax-load-placeholder";
placeholder.innerHTML = loadingImgHTML + '<span class="ajax-load-text">' + (text || '') + '</span>';
return placeholder;
}
}


Строка 743: Строка 778:
container.dataset.ajaxLoaded = "1";
container.dataset.ajaxLoaded = "1";


var placeholder = createPlaceholderWithSpinner(loadingText);
var placeholder = createPlaceholderWithSpinner(loadingHTML);


if (container && container.parentNode) {
if (container && container.parentNode) {
container.parentNode.replaceChild(placeholder, container);
container.parentNode.replaceChild(placeholder, container);
} else {
} else if (contentEl && contentEl.parentNode) {
if (contentEl && contentEl.parentNode) {
contentEl.parentNode.replaceChild(placeholder, contentEl);
contentEl.parentNode.replaceChild(placeholder, contentEl);
}
}
}


Строка 757: Строка 790:
}, { once: true });
}, { once: true });
} else {
} else {
var placeholder = createPlaceholderWithSpinner(loadingText);
var placeholder = createPlaceholderWithSpinner(loadingHTML);


if (contentEl && contentEl.parentNode) {
if (contentEl && contentEl.parentNode) {
Строка 988: Строка 1021:
}
}
}
}
//
// Для "Шаблон:Переключатель_проекта"
function initProjectSelectionGenerator() {
function initProjectSelectionGenerator() {
var containers = document.getElementsByClassName('js-project-selection-generator');
var containers = document.getElementsByClassName('js-project-selection-generator');
Строка 997: Строка 1030:
.replace(/\s+/g, '-')
.replace(/\s+/g, '-')
.replace(/[^A-Za-z0-9_\-\u0400-\u04FF]/g, '');
.replace(/[^A-Za-z0-9_\-\u0400-\u04FF]/g, '');
}
function getContentRoot() {
return document.querySelector('#mw-content-text .mw-parser-output') || document.querySelector('#mw-content-text');
}
function getPageWikitext() {
var title = mw.config.get('wgPageName');
var apiUrl = mw.util.wikiScript('api') + '?action=query&prop=revisions&rvslots=main&rvprop=content&titles=' + encodeURIComponent(title) + '&format=json&formatversion=2&origin=*';
return $.ajax({
url: apiUrl,
method: 'GET',
dataType: 'json'
}).then(function (data) {
if (!data || !data.query || !data.query.pages || !data.query.pages.length) {
return '';
}
var page = data.query.pages[0];
if (!page.revisions || !page.revisions.length) {
return '';
}
var rev = page.revisions[0];
if (rev.slots && rev.slots.main && typeof rev.slots.main.content === 'string') {
return rev.slots.main.content;
}
if (typeof rev.content === 'string') {
return rev.content;
}
return '';
});
}
function stripProjectSelectionTemplate(text) {
return String(text || '').replace(/\{\{\s*переключатель проекта\b[\s\S]*?\}\}/ig, '');
}
function buildWikitext(text, projectName) {
return '{{#vardefine:JsonPath|' + projectName + '}}\n' + stripProjectSelectionTemplate(text);
}
function refreshForProject(projectName) {
var root = getContentRoot();
if (!root) return;
var placeholder = createPlaceholderWithSpinner();
root.innerHTML = '';
root.appendChild(placeholder);
getPageWikitext()
.then(function (sourceText) {
var wikitext = buildWikitext(sourceText, projectName);
return parseAndInjectWikiText(wikitext, {
placeholder: placeholder,
targetRoot: root
});
})
.fail(function () {
placeholder.textContent = 'Ошибка загрузки страницы.';
});
}
}


for (var ci = 0; ci < containers.length; ci++) {
for (var ci = 0; ci < containers.length; ci++) {
var container = containers[ci];
var container = containers[ci];
var rawText = container.textContent || '';
var rawText = container.textContent || '';
var items = rawText.split(',');
var items = rawText.split(',');
Строка 1016: Строка 1116:
}
}


var ul = document.createElement('ul');
var form = document.createElement('form');
ul.className = 'project-menu';
form.className = 'js-project-menu';


for (var j = 0; j < projects.length; j++) {
for (var j = 0; j < projects.length; j++) {
Строка 1023: Строка 1123:
var projectId = 'project-' + normalizeIdPart(projectName);
var projectId = 'project-' + normalizeIdPart(projectName);


var li = document.createElement('li');
var div = document.createElement('div');
li.className = 'mw-list-item mw-list-item-js';


var input = document.createElement('input');
var input = document.createElement('input');
input.type = 'radio';
input.type = 'radio';
input.name = 'project-selection';
input.name = 'js-project-selection';
input.value = projectName;
input.value = projectName;
input.id = projectId;
input.id = projectId;
Строка 1040: Строка 1139:
label.textContent = projectName;
label.textContent = projectName;


li.appendChild(input);
div.appendChild(input);
li.appendChild(label);
div.appendChild(label);
ul.appendChild(li);
form.appendChild(div);
}
}


container.textContent = '';
var portletList = document.querySelector('#mw-content .mw-portlet-body ul');
container.appendChild(ul);
if (portletList) {
portletList.appendChild(form);
}
 
(function (menuNode) {
menuNode.addEventListener('change', function (event) {
var target = event.target;
if (!target || target.tagName !== 'INPUT') return;
if (target.type !== 'radio') return;
if (target.name !== 'js-project-selection') return;
if (!target.checked) return;
 
refreshForProject(target.value);
});
})(form);
}
}
}
}