MediaWiki:Common.js: відмінності між версіями
Перейти до навігації
Перейти до пошуку
Немає опису редагування |
Немає опису редагування Мітка: Скасовано |
||
| Рядок 10: | Рядок 10: | ||
document.head.appendChild(meta); | document.head.appendChild(meta); | ||
} | } | ||
})();$(function() { | })(); | ||
$(function() { | |||
$('.category-card').each(function() { | $('.category-card').each(function() { | ||
var $card = $(this); | var $card = $(this); | ||
| Рядок 31: | Рядок 33: | ||
}); | }); | ||
}); | }); | ||
/* ══════════════════════════════════════════════ | /* ══════════════════════════════════════════════ | ||
ВИПАДКОВІ СТАТТІ | ВИПАДКОВІ СТАТТІ (FIX) | ||
══════════════════════════════════════════════ */ | ══════════════════════════════════════════════ */ | ||
function loadRandomArticles() { | function loadRandomArticles() { | ||
var list = document.getElementById('random-articles-list'); | var list = document.getElementById('random-articles-list'); | ||
if (!list) return; | if (!list) return; | ||
list.innerHTML = '<div class="random-articles-loading">Завантаження...</div>'; | list.innerHTML = '<div class="random-articles-loading">Завантаження...</div>'; | ||
var apiBase = mw.config.get('wgScriptPath') + '/api.php'; | var apiBase = mw.config.get('wgScriptPath') + '/api.php'; | ||
var excludedPages = ['Головна сторінка', 'Структурні підрозділи', 'Викладачі']; | var excludedPages = ['Головна сторінка', 'Структурні підрозділи', 'Викладачі']; | ||
fetch(apiBase + '?action=query&list=random&rnnamespace=0&rnlimit=10&format=json') | fetch(apiBase + '?action=query&list=random&rnnamespace=0&rnlimit=10&format=json') | ||
.then(function (r) { return r.json(); }) | .then(function (r) { return r.json(); }) | ||
.then(function (data) { | .then(function (data) { | ||
if (!data.query || !data.query.random) { | |||
throw new Error('Random API error'); | |||
} | |||
var pages = data.query.random | var pages = data.query.random | ||
.filter(function (p) { return excludedPages.indexOf(p.title) === -1; }) | .filter(function (p) { return excludedPages.indexOf(p.title) === -1; }) | ||
.slice(0, 3); | .slice(0, 3); | ||
var titles = pages.map(function (p) { return p.title; }).join('|'); | var titles = pages.map(function (p) { return p.title; }).join('|'); | ||
return fetch( | return fetch( | ||
apiBase + '?action=query' + | apiBase + '?action=query' + | ||
'&titles=' + encodeURIComponent(titles) + | '&titles=' + encodeURIComponent(titles) + | ||
'&prop=revisions&rvprop=content&format=json' | '&prop=revisions&rvslots=main&rvprop=content&format=json' | ||
); | ); | ||
}) | }) | ||
.then(function (r) { return r.json(); }) | .then(function (r) { return r.json(); }) | ||
.then(function (data) { | .then(function (data) { | ||
var pages = Object.values(data.query.pages); | |||
var pages = Object.values((data.query && data.query.pages) || {}); | |||
list.innerHTML = ''; | list.innerHTML = ''; | ||
var promises = pages.map(function (page) { | var promises = pages.map(function (page) { | ||
var title = page.title; | var title = page.title; | ||
var pageUrl = mw.config.get('wgArticlePath').replace( | var pageUrl = mw.config.get('wgArticlePath').replace( | ||
'$1', encodeURIComponent(title.replace(/ /g, '_')) | '$1', encodeURIComponent(title.replace(/ /g, '_')) | ||
); | ); | ||
var content = (page.revisions && page.revisions[0]) | |||
var content = ''; | |||
if (page.revisions && | |||
page.revisions[0] && | |||
page.revisions[0].slots && | |||
page.revisions[0].slots.main) { | |||
content = page.revisions[0].slots.main['*'] || ''; | |||
} | |||
var excerpt = extractDescription(content) || 'Немає опису.'; | var excerpt = extractDescription(content) || 'Немає опису.'; | ||
var imgName = extractImageName(content); | var imgName = extractImageName(content); | ||
if (imgName) { | if (imgName) { | ||
var fileTitle = /^(Файл|File|Image|Зображення):/i.test(imgName) | var fileTitle = /^(Файл|File|Image|Зображення):/i.test(imgName) | ||
? imgName : 'File:' + imgName; | ? imgName : 'File:' + imgName; | ||
return fetch( | return fetch( | ||
apiBase + '?action=query' + | apiBase + '?action=query' + | ||
| Рядок 86: | Рядок 104: | ||
var ip = Object.values(imgData.query.pages); | var ip = Object.values(imgData.query.pages); | ||
var ii = ip[0] && ip[0].imageinfo && ip[0].imageinfo[0]; | var ii = ip[0] && ip[0].imageinfo && ip[0].imageinfo[0]; | ||
return { title: title, excerpt: excerpt, pageUrl: pageUrl, | return { | ||
title: title, | |||
excerpt: excerpt, | |||
pageUrl: pageUrl, | |||
imgSrc: ii ? (ii.thumburl || ii.url) : null | |||
}; | |||
}) | }) | ||
.catch(function () { | .catch(function () { | ||
| Рядок 93: | Рядок 115: | ||
}); | }); | ||
} | } | ||
return Promise.resolve({ title: title, excerpt: excerpt, pageUrl: pageUrl, imgSrc: null }); | |||
return Promise.resolve({ | |||
title: title, | |||
excerpt: excerpt, | |||
pageUrl: pageUrl, | |||
imgSrc: null | |||
}); | |||
}); | }); | ||
return Promise.all(promises); | return Promise.all(promises); | ||
}) | }) | ||
| Рядок 101: | Рядок 129: | ||
var el = document.getElementById('random-articles-list'); | var el = document.getElementById('random-articles-list'); | ||
if (!el) return; | if (!el) return; | ||
el.innerHTML = ''; | el.innerHTML = ''; | ||
results.forEach(function (item) { | results.forEach(function (item) { | ||
var thumbHtml = item.imgSrc | var thumbHtml = item.imgSrc | ||
? '<img class="random-article-thumb" src="' + item.imgSrc + '" alt="">' | ? '<img class="random-article-thumb" src="' + item.imgSrc + '" alt="">' | ||
: '<div class="random-article-thumb-placeholder">📄</div>'; | : '<div class="random-article-thumb-placeholder">📄</div>'; | ||
var card = document.createElement('a'); | var card = document.createElement('a'); | ||
card.href = item.pageUrl; | card.href = item.pageUrl; | ||
| Рядок 115: | Рядок 146: | ||
'<div class="random-article-excerpt">' + mw.html.escape(item.excerpt) + '</div>' + | '<div class="random-article-excerpt">' + mw.html.escape(item.excerpt) + '</div>' + | ||
'</div>'; | '</div>'; | ||
el.appendChild(card); | el.appendChild(card); | ||
}); | }); | ||
}) | }) | ||
.catch(function (err) { | .catch(function (err) { | ||
console.error('[RA]', err); | console.error('[RA]', err); | ||
list.innerHTML = '<div class="random-articles-loading">Не вдалося завантажити статті.</div>'; | |||
}); | }); | ||
} | } | ||
mw.hook('wikipage.content').add(function () { | mw.hook('wikipage.content').add(function () { | ||
var panel = document.getElementById('random-articles-panel'); | var panel = document.getElementById('random-articles-panel'); | ||
if (!panel) return; | if (!panel) return; | ||
loadRandomArticles(); | loadRandomArticles(); | ||
var btn = document.getElementById('random-articles-refresh'); | var btn = document.getElementById('random-articles-refresh'); | ||
if (btn) btn.addEventListener('click', loadRandomArticles); | if (btn) btn.addEventListener('click', loadRandomArticles); | ||
}); | }); | ||
/* ───────────────────────────────────────────── | |||
ПАРСЕРИ | |||
──────────────────────────────────────────── */ | |||
function extractImageName(wikitext) { | |||
if (!wikitext) return null; | |||
var m = wikitext.match(/\|\s*image\s*=\s*([^\|\n\}]+)/i); | |||
if (m && m[1].trim()) return m[1].trim(); | |||
m = wikitext.match(/\[\[(?:Файл|File|Зображення|Image):([^\|\]]+)/i); | |||
return m ? m[1].trim() : null; | |||
} | |||
function extractDescription(wikitext) { | |||
if (!wikitext) return ''; | |||
var text = wikitext | |||
.replace(/\{\{[\s\S]*?\}\}/g, '') | |||
.replace(/\[\[(?:[^\|\]]*\|)?([^\]]+)\]\]/g, '$1') | |||
.replace(/'{2,3}/g, '') | |||
.replace(/<[^>]+>/g, ''); | |||
var lines = text.split('\n') | |||
.map(function (l) { return l.trim(); }) | |||
.filter(function (l) { return l.length > 20; }); | |||
if (!lines.length) return ''; | |||
var result = lines[0].substring(0, 180); | |||
return lines[0].length > 180 ? result + '…' : result; | |||
} | } | ||
Версія за 11:40, 24 березня 2026
// Виправляємо viewport
(function() {
var viewport = document.querySelector('meta[name="viewport"]');
if (viewport) {
viewport.setAttribute('content', 'width=device-width, initial-scale=1.0');
} else {
var meta = document.createElement('meta');
meta.name = 'viewport';
meta.content = 'width=device-width, initial-scale=1.0';
document.head.appendChild(meta);
}
})();
$(function() {
$('.category-card').each(function() {
var $card = $(this);
var href = $card.attr('data-href');
if (href) {
$card.css('cursor', 'pointer');
$card.on('click', function(e) {
if ($(e.target).closest('a').length === 0) {
window.location.href = href;
}
});
$card.hover(
function() { $card.addClass('card-hover'); },
function() { $card.removeClass('card-hover'); }
);
}
});
});
/* ══════════════════════════════════════════════
ВИПАДКОВІ СТАТТІ (FIX)
══════════════════════════════════════════════ */
function loadRandomArticles() {
var list = document.getElementById('random-articles-list');
if (!list) return;
list.innerHTML = '<div class="random-articles-loading">Завантаження...</div>';
var apiBase = mw.config.get('wgScriptPath') + '/api.php';
var excludedPages = ['Головна сторінка', 'Структурні підрозділи', 'Викладачі'];
fetch(apiBase + '?action=query&list=random&rnnamespace=0&rnlimit=10&format=json')
.then(function (r) { return r.json(); })
.then(function (data) {
if (!data.query || !data.query.random) {
throw new Error('Random API error');
}
var pages = data.query.random
.filter(function (p) { return excludedPages.indexOf(p.title) === -1; })
.slice(0, 3);
var titles = pages.map(function (p) { return p.title; }).join('|');
return fetch(
apiBase + '?action=query' +
'&titles=' + encodeURIComponent(titles) +
'&prop=revisions&rvslots=main&rvprop=content&format=json'
);
})
.then(function (r) { return r.json(); })
.then(function (data) {
var pages = Object.values((data.query && data.query.pages) || {});
list.innerHTML = '';
var promises = pages.map(function (page) {
var title = page.title;
var pageUrl = mw.config.get('wgArticlePath').replace(
'$1', encodeURIComponent(title.replace(/ /g, '_'))
);
var content = '';
if (page.revisions &&
page.revisions[0] &&
page.revisions[0].slots &&
page.revisions[0].slots.main) {
content = page.revisions[0].slots.main['*'] || '';
}
var excerpt = extractDescription(content) || 'Немає опису.';
var imgName = extractImageName(content);
if (imgName) {
var fileTitle = /^(Файл|File|Image|Зображення):/i.test(imgName)
? imgName : 'File:' + imgName;
return fetch(
apiBase + '?action=query' +
'&titles=' + encodeURIComponent(fileTitle) +
'&prop=imageinfo&iiprop=url&iiurlwidth=120&format=json'
)
.then(function (r) { return r.json(); })
.then(function (imgData) {
var ip = Object.values(imgData.query.pages);
var ii = ip[0] && ip[0].imageinfo && ip[0].imageinfo[0];
return {
title: title,
excerpt: excerpt,
pageUrl: pageUrl,
imgSrc: ii ? (ii.thumburl || ii.url) : null
};
})
.catch(function () {
return { title: title, excerpt: excerpt, pageUrl: pageUrl, imgSrc: null };
});
}
return Promise.resolve({
title: title,
excerpt: excerpt,
pageUrl: pageUrl,
imgSrc: null
});
});
return Promise.all(promises);
})
.then(function (results) {
var el = document.getElementById('random-articles-list');
if (!el) return;
el.innerHTML = '';
results.forEach(function (item) {
var thumbHtml = item.imgSrc
? '<img class="random-article-thumb" src="' + item.imgSrc + '" alt="">'
: '<div class="random-article-thumb-placeholder">📄</div>';
var card = document.createElement('a');
card.href = item.pageUrl;
card.className = 'random-article-card';
card.innerHTML =
thumbHtml +
'<div class="random-article-info">' +
'<div class="random-article-title">' + mw.html.escape(item.title) + '</div>' +
'<div class="random-article-excerpt">' + mw.html.escape(item.excerpt) + '</div>' +
'</div>';
el.appendChild(card);
});
})
.catch(function (err) {
console.error('[RA]', err);
list.innerHTML = '<div class="random-articles-loading">Не вдалося завантажити статті.</div>';
});
}
mw.hook('wikipage.content').add(function () {
var panel = document.getElementById('random-articles-panel');
if (!panel) return;
loadRandomArticles();
var btn = document.getElementById('random-articles-refresh');
if (btn) btn.addEventListener('click', loadRandomArticles);
});
/* ─────────────────────────────────────────────
ПАРСЕРИ
──────────────────────────────────────────── */
function extractImageName(wikitext) {
if (!wikitext) return null;
var m = wikitext.match(/\|\s*image\s*=\s*([^\|\n\}]+)/i);
if (m && m[1].trim()) return m[1].trim();
m = wikitext.match(/\[\[(?:Файл|File|Зображення|Image):([^\|\]]+)/i);
return m ? m[1].trim() : null;
}
function extractDescription(wikitext) {
if (!wikitext) return '';
var text = wikitext
.replace(/\{\{[\s\S]*?\}\}/g, '')
.replace(/\[\[(?:[^\|\]]*\|)?([^\]]+)\]\]/g, '$1')
.replace(/'{2,3}/g, '')
.replace(/<[^>]+>/g, '');
var lines = text.split('\n')
.map(function (l) { return l.trim(); })
.filter(function (l) { return l.length > 20; });
if (!lines.length) return '';
var result = lines[0].substring(0, 180);
return lines[0].length > 180 ? result + '…' : result;
}