MediaWiki:Common.js: различия между версиями
Pok (обсуждение | вклад) Нет описания правки |
Pok (обсуждение | вклад) Нет описания правки |
||
| (не показано 14 промежуточных версий этого же участника) | |||
| Строка 627: | Строка 627: | ||
}); | }); | ||
} | } | ||
// | function fetchParsedData(wikiText) { | ||
function | var apiUrl = "https://station14.ru/api.php?action=parse&format=json&prop=text&text=" + encodeURIComponent(wikiText) + "&origin=*"; | ||
var | return $.ajax({ | ||
url: apiUrl, | |||
var | method: "GET", | ||
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; | |||
if (options.keepNode) { | |||
container.insertBefore(options.keepNode, container.firstChild); | |||
} | |||
if (options.placeholder && options.placeholder.parentNode) { | |||
options.placeholder.replaceWith(container); | |||
} else if (options.targetRoot) { | |||
options.targetRoot.innerHTML = ""; | |||
while (container.firstChild) { | |||
options.targetRoot.appendChild(container.firstChild); | |||
} | |||
container = options.targetRoot; | |||
} | } | ||
enhanceParsedContent(container); | |||
return container; | |||
} | |||
function parseAndInjectWikiText(wikiText, options) { | |||
return fetchParsedData(wikiText) | |||
.done(function (data) { | |||
if (data && data.parse && data.parse.text) { | |||
if ( | var parsedHTML = data.parse.text["*"] || ""; | ||
injectParsedHTML(parsedHTML, options); | |||
} else if (options && options.placeholder) { | |||
options.placeholder.textContent = "API не вернул ожидаемых данных."; | |||
} | |||
}) | |||
.fail(function () { | |||
if (options && options.placeholder) { | |||
options.placeholder.textContent = "Ошибка при выполнении запроса к API."; | |||
} | } | ||
}); | }); | ||
} | |||
function createPlaceholderWithSpinner(text) { | |||
if (!text) { | |||
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; | |||
var ajaxContainers = root.querySelectorAll('.ajax-load, .ajax-load-link'); | |||
var BATCH_SIZE = 1000; | |||
var queue = []; | |||
var processing = false; | |||
function processQueue() { | function processQueue() { | ||
| Строка 691: | Строка 745: | ||
batch.forEach(function (job) { | batch.forEach(function (job) { | ||
parseAndInjectWikiText(job.wikiText, { placeholder: job.placeholder }) | |||
.always(function () { | .always(function () { | ||
remaining--; | remaining--; | ||
| Строка 722: | Строка 765: | ||
if (!wikiText) return; | if (!wikiText) return; | ||
var | var loadingHTML = loadingEl ? (loadingEl.innerHTML || "").trim() : ""; | ||
if (loadingEl && loadingEl.parentNode) { | if (loadingEl && loadingEl.parentNode) { | ||
loadingEl.parentNode.removeChild(loadingEl); | loadingEl.parentNode.removeChild(loadingEl); | ||
} | } | ||
| Строка 743: | Строка 778: | ||
container.dataset.ajaxLoaded = "1"; | container.dataset.ajaxLoaded = "1"; | ||
var placeholder = createPlaceholderWithSpinner( | 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) { | ||
contentEl.parentNode.replaceChild(placeholder, contentEl); | |||
} | } | ||
| Строка 757: | Строка 790: | ||
}, { once: true }); | }, { once: true }); | ||
} else { | } else { | ||
var placeholder = createPlaceholderWithSpinner( | 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'); | ||
| Строка 1003: | Строка 1036: | ||
} | } | ||
function | function getPageWikitext() { | ||
var title = mw.config.get('wgPageName'); | var title = mw.config.get('wgPageName'); | ||
var apiUrl = mw.util.wikiScript('api') + | var apiUrl = mw.util.wikiScript('api') + '?action=query&prop=revisions&rvslots=main&rvprop=content&titles=' + encodeURIComponent(title) + '&format=json&formatversion=2&origin=*'; | ||
return $.ajax({ | return $.ajax({ | ||
| Строка 1043: | Строка 1068: | ||
function stripProjectSelectionTemplate(text) { | function stripProjectSelectionTemplate(text) { | ||
return String(text || '').replace(/\{\{\s*переключатель проекта\b[\s\S]*?\}\}/ig, ''); | |||
} | } | ||
function | function buildWikitext(text, projectName) { | ||
return '{{#vardefine:JsonPath|' + projectName + '}}\n' + stripProjectSelectionTemplate(text); | |||
return '{{#vardefine: | |||
} | } | ||
function | function refreshForProject(projectName) { | ||
var | 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 () { | .fail(function () { | ||
placeholder.textContent = 'Ошибка загрузки страницы.'; | |||
}); | }); | ||
} | } | ||
| Строка 1107: | Строка 1100: | ||
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 || ''; | ||
| Строка 1155: | Строка 1144: | ||
} | } | ||
var portletList = document.querySelector('#mw-content .mw-portlet-body ul'); | |||
if (portletList) { | |||
portletList.appendChild(form); | |||
} | |||
(function ( | (function (menuNode) { | ||
var | 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); | |||
})( | |||
} | } | ||
} | } | ||