MediaWiki:Common.js: Difference between revisions
No edit summary Tag: Reverted |
No edit summary Tag: Reverted |
||
| Line 139: | Line 139: | ||
}); | }); | ||
} | } | ||
}); | |||
/* Random Page Teaser with robust thumbnail fallback (no PageImages required) */ | |||
mw.loader.using(['mediawiki.api', 'mediawiki.util']).then(function () { | |||
var isMain = mw.config.get('wgIsMainPage') || mw.config.get('wgPageName') === 'Main_Page'; | |||
var box = document.getElementById('random-teaser'); | |||
if (!isMain || !box) return; | |||
var api = new mw.Api(); | |||
var THUMB_WIDTH = 280; | |||
function esc(s){ return mw.html.escape(String(s || '')); } | |||
function render(page, imgUrl) { | |||
var title = page.title; | |||
var url = mw.util.getUrl(title); | |||
var extract = (page.extract || '').replace(/\n+/g, ' ').trim(); | |||
if (extract.length > 420) extract = extract.slice(0, 420).replace(/\s+\S*$/, '') + '…'; | |||
box.innerHTML = | |||
'<div class="thumb">' + | |||
(imgUrl ? '<img src="' + esc(imgUrl) + '" alt="">' : '<span>🡲</span>') + | |||
'</div>' + | |||
'<div class="content">' + | |||
'<h3><a href="' + url + '">' + esc(title) + '</a></h3>' + | |||
'<p>' + (esc(extract) || 'No description available.') + '</p>' + | |||
'<div class="actions">' + | |||
'<a class="btn" href="' + url + '">Open</a>' + | |||
'<button type="button" class="btn" id="rand-refresh">Another</button>' + | |||
'<a class="btn" href="' + mw.util.getUrl('Special:Random') + '">Special:Random</a>' + | |||
'</div>' + | |||
'</div>'; | |||
box.classList.remove('loading'); | |||
var refreshBtn = document.getElementById('rand-refresh'); | |||
if (refreshBtn) refreshBtn.addEventListener('click', function () { | |||
box.classList.add('loading'); loadRandom(); | |||
}); | |||
} | |||
// Try to resolve a thumbnail URL from PageImages; if absent, fallback to first image->imageinfo | |||
function resolveThumb(page) { | |||
// 1) If PageImages is installed AND page has .thumbnail, use it | |||
if (page.thumbnail && page.thumbnail.source) { | |||
return Promise.resolve(page.thumbnail.source); | |||
} | |||
// 2) Fallback: get first File used on the page | |||
return api.get({ | |||
action: 'query', | |||
formatversion: 2, | |||
prop: 'images', | |||
pageids: page.pageid, | |||
imlimit: 50 | |||
}).then(function (res) { | |||
var p = (res.query && res.query.pages && res.query.pages[0]) || {}; | |||
var files = (p.images || []).map(function (x){ return x.title; }); | |||
// Prefer common raster types, skip SVG/ICO if chceš | |||
var pick = files.find(function (t) { | |||
return /\.(jpg|jpeg|png|gif|webp)$/i.test(t || ''); | |||
}) || files[0]; | |||
if (!pick) return null; | |||
// 3) Ask for thumbnail url of that file | |||
return api.get({ | |||
action: 'query', | |||
formatversion: 2, | |||
titles: pick, | |||
prop: 'imageinfo', | |||
iiprop: 'url', | |||
iiurlwidth: THUMB_WIDTH | |||
}).then(function (imgRes) { | |||
var imgPage = imgRes.query && imgRes.query.pages && imgRes.query.pages[0]; | |||
var info = imgPage && imgPage.imageinfo && imgPage.imageinfo[0]; | |||
return info && (info.thumburl || info.url) || null; | |||
}); | |||
}); | |||
} | |||
function loadRandom() { | |||
api.get({ | |||
action: 'query', | |||
formatversion: 2, | |||
generator: 'random', | |||
grnnamespace: 0, | |||
grnlimit: 1, | |||
// PageImages (if present) + extract; if PageImages is missing, API len ignoruje thumbnail a nič sa nepokazí | |||
prop: 'extracts|pageimages', | |||
exintro: 1, | |||
explaintext: 1, | |||
exchars: 600, | |||
pithumbsize: THUMB_WIDTH, | |||
pilicense: 'any' | |||
}).then(function (data) { | |||
var page = data.query && data.query.pages && data.query.pages[0]; | |||
if (!page) throw new Error('No random page returned'); | |||
return resolveThumb(page).then(function (thumbUrl) { | |||
render(page, thumbUrl); | |||
}); | |||
}).catch(function (e) { | |||
console.warn('Random teaser error:', e); | |||
box.classList.remove('loading'); | |||
box.innerHTML = '<div class="content"><h3>Random page</h3><p>Could not load a preview.</p></div>'; | |||
}); | |||
} | |||
loadRandom(); | |||
}); | }); | ||