MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
No edit summary Tag: Reverted |
No edit summary Tag: Reverted |
||
| Line 243: | Line 243: | ||
}).catch(function (e) { | }).catch(function (e) { | ||
console.warn('Random teaser error:', 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(); | |||
}); | |||
/* Random Page Teaser — works without PageImages/TextExtracts */ | |||
$(function () { | |||
var box = document.getElementById('random-teaser'); | |||
if (!box) return; | |||
var api = new mw.Api(); | |||
var THUMB_WIDTH = 280; | |||
function esc(s){ return mw.html.escape(String(s || '')); } | |||
function makeExcerptFromHTML(html, maxChars) { | |||
// Build a sandbox DOM, pick first paragraph text | |||
var tmp = document.createElement('div'); | |||
tmp.innerHTML = html; | |||
var p = tmp.querySelector('p'); | |||
var txt = (p ? p.innerText : tmp.innerText || '').replace(/\s+/g, ' ').trim(); | |||
if (txt.length > maxChars) txt = txt.slice(0, maxChars).replace(/\s+\S*$/, '') + '…'; | |||
return txt || 'No description available.'; | |||
} | |||
function pickImageTitle(list) { | |||
if (!Array.isArray(list) || !list.length) return null; | |||
// Prefer common raster formats | |||
var preferred = list.find(function (t) { return /\.(jpe?g|png|gif|webp)$/i.test(t); }); | |||
return preferred || list[0] || null; | |||
} | |||
function getThumbUrl(fileTitle) { | |||
if (!fileTitle) return Promise.resolve(null); | |||
return api.get({ | |||
action: 'query', | |||
formatversion: 2, | |||
titles: fileTitle, | |||
prop: 'imageinfo', | |||
iiprop: 'url', | |||
iiurlwidth: THUMB_WIDTH | |||
}).then(function (res) { | |||
var p = res.query && res.query.pages && res.query.pages[0]; | |||
var ii = p && p.imageinfo && p.imageinfo[0]; | |||
return (ii && (ii.thumburl || ii.url)) || null; | |||
}).catch(function(){ return null; }); | |||
} | |||
function render(title, extract, imgUrl) { | |||
var url = mw.util.getUrl(title); | |||
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) + '</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(); | |||
}); | |||
} | |||
function loadRandom() { | |||
// 1) Get random article (namespace 0) | |||
api.get({ | |||
action: 'query', | |||
formatversion: 2, | |||
list: 'random', | |||
rnnamespace: 0, | |||
rnlimit: 1 | |||
}).then(function (r) { | |||
var item = r && r.query && r.query.random && r.query.random[0]; | |||
if (!item) throw new Error('No random page'); | |||
var title = item.title; | |||
// 2) Parse HTML + list images (no extensions needed) | |||
return api.get({ | |||
action: 'parse', | |||
page: title, | |||
prop: 'text|images', | |||
redirects: 1 | |||
}).then(function (p) { | |||
var html = p.parse && p.parse.text && p.parse.text['*'] || ''; | |||
var images = p.parse && p.parse.images || []; | |||
var excerpt = makeExcerptFromHTML(html, 420); | |||
var fileTitle = pickImageTitle(images); | |||
// 3) Resolve thumbnail URL (if any) | |||
return getThumbUrl(fileTitle).then(function (thumb) { | |||
render(title, excerpt, thumb); | |||
}); | |||
}); | |||
}).catch(function (e) { | |||
// Graceful fallback | |||
console.warn('Random teaser failed:', e); | |||
box.classList.remove('loading'); | box.classList.remove('loading'); | ||
box.innerHTML = '<div class="content"><h3>Random page</h3><p>Could not load a preview.</p></div>'; | box.innerHTML = '<div class="content"><h3>Random page</h3><p>Could not load a preview.</p></div>'; | ||
Revision as of 08:48, 5 September 2025
/* Any JavaScript here will be loaded for all users on every page load. */
/****************************************/
/* sliders using jquery by User:Tierrie */
/****************************************/
mw.loader.using( ['jquery.cookie']);
/****************************************/
/* sliders using jquery by User:Tierrie */
/****************************************/
mw.loader.using( ['jquery.ui'], function() {
$( "[class^=portal_vtab]" ).tabs().addClass( "ui-tabs-vertical ui-helper-clearfix" );
$( "[class^=portal_vtab] li" ).removeClass( "ui-corner-top" ).addClass( "ui-corner-left" );
var $tabs = $("#portal_slider").tabs({ fx: {opacity:'toggle', duration:100} } );
$("[class*=portal_sliderlink]").click(function() { // bind click event to link
$tabs.tabs('select', this.className.match(/portal_sliderlink-(\d+)/)[1]);
console.log("Sliding to " + this.className.match(/portal_sliderlink-(\d+)/)[1]);
return false;
});
$('#portal_next').click(function() {
$tabs.tabs('select', ($tabs.tabs('option', 'selected') == ($tabs.tabs('length'))-1) ? 0 : $tabs.tabs('option', 'selected') + 1 ); // switch to next tab
return false;
});
$('#portal_prev').click(function() { // bind click event to link
$tabs.tabs('select', ($tabs.tabs('option', 'selected') == 0) ? ($tabs.tabs('length')-1) : $tabs.tabs('option', 'selected') - 1 ); // switch to previous tab
return false;
});
});
/* lockdown for reference popup configuration */
((window.dev = window.dev || {}).ReferencePopups = dev.ReferencePopups || {}).lockdown = true;
/* Disable license check for multi upload */
mw.config.set('UMFBypassLicenseCheck', true);
mw.loader.using('mediawiki.util').then(function () {
var g = mw.config.get('wgUserGroups')||[];
var isAdmin = g.indexOf('sysop')!==-1 || g.indexOf('interface-admin')!==-1;
if (!isAdmin) document.querySelectorAll('.only-sysop').forEach(el=>el.style.display='none');
});
/* Random Page Teaser on Main Page
* Fetches a random page (namespace 0), shows title, extract and thumbnail.
*/
mw.loader.using(['mediawiki.api', 'mediawiki.util']).then(function () {
// Run only on main page (adjust if your main page title differs)
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();
function renderCard(data) {
var page = (data && data.query && data.query.pages && data.query.pages[0]) || null;
if (!page) {
box.innerHTML = '<div class="content"><h3>Random page</h3><p>Could not load a page.</p></div>';
box.classList.remove('loading');
return;
}
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*$/, '') + '…';
var img = (page.thumbnail && page.thumbnail.source) ? page.thumbnail.source : null;
box.innerHTML =
'<div class="thumb">' +
(img ? '<img src="' + img + '" alt="">' : '<span>🡲</span>') +
'</div>' +
'<div class="content">' +
'<h3><a href="' + url + '">' + mw.html.escape(title) + '</a></h3>' +
'<p>' + (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();
});
}
function loadRandom() {
api.get({
action: 'query',
formatversion: 2,
generator: 'random',
grnnamespace: 0, // only main/article namespace
grnlimit: 1,
prop: 'extracts|pageimages',
exintro: 1,
explaintext: 1, // plain text extract
exchars: 600, // server-side clamp
pithumbsize: 280, // thumbnail width
pilicense: 'any'
}).then(renderCard).catch(function () {
renderCard(null);
});
}
loadRandom();
});
api.get({
action: 'query',
formatversion: 2,
generator: 'random',
grnnamespace: 0,
grnlimit: 1,
prop: 'extracts|images',
exintro: 1,
explaintext: 1,
exchars: 600
}).then(function (data) {
var page = data.query.pages[0];
if (page.images && page.images.length) {
// vezme prvý obrázok
var file = page.images[0].title;
api.get({
action: 'query',
titles: file,
prop: 'imageinfo',
iiprop: 'url',
iiurlwidth: 280
}).then(function (imgData) {
var imgPage = Object.values(imgData.query.pages)[0];
var img = imgPage.imageinfo[0].thumburl;
// tu už máš thumbnail
});
}
});
/* 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();
});
/* Random Page Teaser — works without PageImages/TextExtracts */
$(function () {
var box = document.getElementById('random-teaser');
if (!box) return;
var api = new mw.Api();
var THUMB_WIDTH = 280;
function esc(s){ return mw.html.escape(String(s || '')); }
function makeExcerptFromHTML(html, maxChars) {
// Build a sandbox DOM, pick first paragraph text
var tmp = document.createElement('div');
tmp.innerHTML = html;
var p = tmp.querySelector('p');
var txt = (p ? p.innerText : tmp.innerText || '').replace(/\s+/g, ' ').trim();
if (txt.length > maxChars) txt = txt.slice(0, maxChars).replace(/\s+\S*$/, '') + '…';
return txt || 'No description available.';
}
function pickImageTitle(list) {
if (!Array.isArray(list) || !list.length) return null;
// Prefer common raster formats
var preferred = list.find(function (t) { return /\.(jpe?g|png|gif|webp)$/i.test(t); });
return preferred || list[0] || null;
}
function getThumbUrl(fileTitle) {
if (!fileTitle) return Promise.resolve(null);
return api.get({
action: 'query',
formatversion: 2,
titles: fileTitle,
prop: 'imageinfo',
iiprop: 'url',
iiurlwidth: THUMB_WIDTH
}).then(function (res) {
var p = res.query && res.query.pages && res.query.pages[0];
var ii = p && p.imageinfo && p.imageinfo[0];
return (ii && (ii.thumburl || ii.url)) || null;
}).catch(function(){ return null; });
}
function render(title, extract, imgUrl) {
var url = mw.util.getUrl(title);
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) + '</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();
});
}
function loadRandom() {
// 1) Get random article (namespace 0)
api.get({
action: 'query',
formatversion: 2,
list: 'random',
rnnamespace: 0,
rnlimit: 1
}).then(function (r) {
var item = r && r.query && r.query.random && r.query.random[0];
if (!item) throw new Error('No random page');
var title = item.title;
// 2) Parse HTML + list images (no extensions needed)
return api.get({
action: 'parse',
page: title,
prop: 'text|images',
redirects: 1
}).then(function (p) {
var html = p.parse && p.parse.text && p.parse.text['*'] || '';
var images = p.parse && p.parse.images || [];
var excerpt = makeExcerptFromHTML(html, 420);
var fileTitle = pickImageTitle(images);
// 3) Resolve thumbnail URL (if any)
return getThumbUrl(fileTitle).then(function (thumb) {
render(title, excerpt, thumb);
});
});
}).catch(function (e) {
// Graceful fallback
console.warn('Random teaser failed:', e);
box.classList.remove('loading');
box.innerHTML = '<div class="content"><h3>Random page</h3><p>Could not load a preview.</p></div>';
});
}
loadRandom();
});