MediaWiki:Common.js: Unterschied zwischen den Versionen
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung Markierung: Zurückgesetzt |
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung Markierung: Zurückgesetzt |
||
| Zeile 219: | Zeile 219: | ||
/* ADOS Whisky-Ratings – RatePage Frontend ( | /* ADOS Whisky-Ratings – RatePage Frontend (ultra-kompatibel: ES3/ES5 only) */ | ||
mw.loader.using(['mediawiki.api', 'mediawiki.user']).then(function () { | mw.loader.using(['mediawiki.api', 'mediawiki.user']).then(function () { | ||
// ----- | // ---- kleines get()-Hilfswerkzeug ohne ?. ---- | ||
function get(obj, | function get(obj, path) { | ||
var cur = obj; | var cur = obj, i; | ||
for ( | for (i = 0; i < path.length; i++) { | ||
if (!cur || typeof cur !== 'object') return undefined; | if (!cur || typeof cur !== 'object') return undefined; | ||
cur = cur[ | cur = cur[path[i]]; | ||
} | } | ||
return cur; | return cur; | ||
} | } | ||
// ---- | // ---- Bootstrapping ---- | ||
function boot(root) { | function boot(root) { | ||
var scope = root || document; | var scope = root || document; | ||
var i, nodes; | |||
nodes = scope.querySelectorAll('.whisky-rating__item'); | |||
for (i = 0; i < | for (i = 0; i < nodes.length; i++) setupWidget(nodes[i]); | ||
nodes = scope.querySelectorAll('[data-ratepage-summary="true"]'); | |||
for (i = 0; i < | for (i = 0; i < nodes.length; i++) renderSummary(nodes[i]); | ||
nodes = scope.querySelectorAll('.whisky-rating__meta-only'); | |||
for (i = 0; i < nodes.length; i++) renderMetaOnly(nodes[i]); | |||
} | } | ||
| Zeile 251: | Zeile 253: | ||
} | } | ||
mw.hook('wikipage.content').add(function($content) { | // Achtung: $content ist jQuery – wir nehmen das rohe DOM-Element | ||
mw.hook('wikipage.content').add(function($content){ | |||
if ($content && $content[0]) boot($content[0]); | if ($content && $content[0]) boot($content[0]); | ||
}); | }); | ||
// | // ---- Widget (Gläser) ---- | ||
function setupWidget(box) { | function setupWidget(box) { | ||
var pageId = mw.config.get('wgArticleId'); | var pageId = mw.config.get('wgArticleId'); | ||
| Zeile 270: | Zeile 273: | ||
} | } | ||
var buttons = []; | var buttons = []; | ||
for ( | var i; | ||
for (i = 1; i <= scale; i++) { | |||
(function(iVal){ | (function(iVal){ | ||
var btn = document.createElement('button'); | var btn = document.createElement('button'); | ||
| Zeile 303: | Zeile 306: | ||
function highlight(n) { | function highlight(n) { | ||
for ( | var j; | ||
for (j = 0; j < buttons.length; j++) { | |||
var active = (j < n); | var active = (j < n); | ||
buttons[j].classList.toggle('is-active', active); | buttons[j].classList.toggle('is-active', active); | ||
| Zeile 310: | Zeile 314: | ||
} | } | ||
function updateStats() { | function updateStats() { | ||
var api = new mw.Api(); | var api = new mw.Api(); | ||
| Zeile 322: | Zeile 325: | ||
try { | try { | ||
var pages = get(data, ['query','pages']) || {}; | var pages = get(data, ['query','pages']) || {}; | ||
var | var keys = []; | ||
for (var k in pages) if (Object.prototype.hasOwnProperty.call(pages, k)) keys.push(k); | |||
var pid = keys.length ? keys[0] : String(pageId); | |||
var page = pages[pid] || {}; | var page = pages[pid] || {}; | ||
var pr = page.pagerating; | var pr = page.pagerating; | ||
| Zeile 338: | Zeile 343: | ||
var hist = pr.pageRating || {}; | var hist = pr.pageRating || {}; | ||
var total = 0, sum = 0; | var total = 0, sum = 0; | ||
Object. | for (var key in hist) { | ||
if (Object.prototype.hasOwnProperty.call(hist, key)) { | |||
var s = parseInt(key, 10), c = parseInt(hist[key], 10); | |||
} | if (!isNaN(s) && !isNaN(c)) { total += c; sum += s * c; } | ||
} | |||
} | |||
meta.textContent = total | meta.textContent = total | ||
? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)') | ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)') | ||
| Zeile 355: | Zeile 362: | ||
box.classList.add('whisky-rating--disabled'); | box.classList.add('whisky-rating--disabled'); | ||
var gls = widget.querySelectorAll('.whisky-glass'); | var gls = widget.querySelectorAll('.whisky-glass'); | ||
for (var | for (var i2 = 0; i2 < gls.length; i2++) gls[i2].disabled = true; | ||
if | if (meta.textContent.indexOf('nicht abstimmen') === -1) { | ||
meta.textContent += (meta.textContent ? ' • ' : '') + 'Du darfst hier nicht abstimmen.'; | meta.textContent += (meta.textContent ? ' • ' : '') + 'Du darfst hier nicht abstimmen.'; | ||
} | } | ||
} | } | ||
} catch (e) { | } catch (e) { | ||
console.error(e); | if (window.console && console.error) console.error(e); | ||
if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.'; | if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.'; | ||
} | } | ||
}).fail(function (xhr) { | }).fail(function (xhr) { | ||
console.error('Pagerating-Load-Error', xhr); | if (window.console && console.error) console.error('Pagerating-Load-Error', xhr); | ||
if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.'; | if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.'; | ||
}); | }); | ||
} | } | ||
function vote(value) { | function vote(value) { | ||
var api = new mw.Api(); | var api = new mw.Api(); | ||
| Zeile 402: | Zeile 408: | ||
} | } | ||
} catch(e){} | } catch(e){} | ||
console.error('RatePage-API-Fehler:', xhr); | if (window.console && console.error) console.error('RatePage-API-Fehler:', xhr); | ||
if (meta) meta.textContent = 'Speichern fehlgeschlagen: ' + msg; | if (meta) meta.textContent = 'Speichern fehlgeschlagen: ' + msg; | ||
}); | }); | ||
| Zeile 410: | Zeile 416: | ||
} | } | ||
// | // ---- Meta-only Ø (einzelne Kategorie irgendwo im Text) ---- | ||
function renderMetaOnly(box) { | function renderMetaOnly(box) { | ||
var pageId = parseInt(box.dataset.ratepagePageid || mw.config.get('wgArticleId'), 10); | var pageId = parseInt(box.dataset.ratepagePageid || mw.config.get('wgArticleId'), 10); | ||
| Zeile 422: | Zeile 428: | ||
}).done(function (data) { | }).done(function (data) { | ||
var pages = get(data, ['query','pages']) || {}; | var pages = get(data, ['query','pages']) || {}; | ||
var | var keys = []; | ||
for (var k in pages) if (Object.prototype.hasOwnProperty.call(pages, k)) keys.push(k); | |||
var pid = keys.length ? keys[0] : String(pageId); | |||
var pr = pages[pid] && pages[pid].pagerating; | var pr = pages[pid] && pages[pid].pagerating; | ||
if (!pr) { box.textContent = ''; return; } | if (!pr) { box.textContent = ''; return; } | ||
| Zeile 428: | Zeile 436: | ||
var hist = pr.pageRating || {}; | var hist = pr.pageRating || {}; | ||
var total = 0, sum = 0; | var total = 0, sum = 0; | ||
Object. | for (var key in hist) { | ||
if (Object.prototype.hasOwnProperty.call(hist, key)) { | |||
var s = Number(key), c = Number(hist[key]); | |||
} | if (s && c) { total += c; sum += s * c; } | ||
} | |||
} | |||
box.textContent = total ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)') : 'Noch keine Bewertungen'; | box.textContent = total ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)') : 'Noch keine Bewertungen'; | ||
}); | }); | ||
} | } | ||
// | // ---- Kompakte Ø-Tabelle oben (NASE/GESCHMACK/ABGANG) ---- | ||
function renderSummary(container) { | function renderSummary(container) { | ||
var pageId = mw.config.get('wgArticleId'); | var pageId = mw.config.get('wgArticleId'); | ||
var | var raw = container.dataset.ratepageContests || 'NASE,GESCHMACK,ABGANG'; | ||
var contests = raw.split(','); | |||
for ( | var i; | ||
for (i = 0; i < contests.length; i++) contests[i] = contests[i].replace(/^\s+|\s+$/g, ''); | |||
contests = contests.filter(function(s){ return !!s; }); | contests = contests.filter(function(s){ return !!s; }); | ||
| Zeile 456: | Zeile 467: | ||
}).then(function (data) { | }).then(function (data) { | ||
var pages = get(data, ['query','pages']) || {}; | var pages = get(data, ['query','pages']) || {}; | ||
var | var keys = []; | ||
for (var k in pages) if (Object.prototype.hasOwnProperty.call(pages, k)) keys.push(k); | |||
var pid = keys.length ? keys[0] : String(pageId); | |||
var pr = pages[pid] && pages[pid].pagerating; | var pr = pages[pid] && pages[pid].pagerating; | ||
if (!pr || (typeof pr.canSee !== 'undefined' && pr.canSee === 0)) { | if (!pr || (typeof pr.canSee !== 'undefined' && pr.canSee === 0)) { | ||
| Zeile 463: | Zeile 476: | ||
var hist = pr.pageRating || {}; | var hist = pr.pageRating || {}; | ||
var total = 0, sum = 0; | var total = 0, sum = 0; | ||
Object. | for (var key in hist) { | ||
if (Object.prototype.hasOwnProperty.call(hist, key)) { | |||
var s = Number(key), c = Number(hist[key]); | |||
} | if (s && c) { total += c; sum += s * c; } | ||
} | |||
} | |||
var avg = total ? Math.round((sum / total) * 10) / 10 : null; | var avg = total ? Math.round((sum / total) * 10) / 10 : null; | ||
return { contest: contest, total: total, avg: avg, label: labels[contest] || contest }; | return { contest: contest, total: total, avg: avg, label: labels[contest] || contest }; | ||
| Zeile 472: | Zeile 487: | ||
} | } | ||
var promises = []; | |||
for (i = 0; i < contests.length; i++) promises.push(fetchContest(contests[i])); | |||
Promise.all(promises).then(function (rows) { | |||
var table = document.createElement('table'); | var table = document.createElement('table'); | ||
table.className = 'whisky-summary__table'; | table.className = 'whisky-summary__table'; | ||
| Zeile 483: | Zeile 501: | ||
for (var r = 0; r < rows.length; r++) { | for (var r = 0; r < rows.length; r++) { | ||
var row = rows[r]; | var row = rows[r]; | ||
var avgText = (row.avg !== null) ? row.avg.toFixed(1) : '–'; | var avgText = (row.avg !== null) ? (row.avg.toFixed ? row.avg.toFixed(1) : (Math.round(row.avg*10)/10)) : '–'; | ||
var totalText = row.total ? String(row.total) : '0'; | var totalText = row.total ? String(row.total) : '0'; | ||
var tr = document.createElement('tr'); | var tr = document.createElement('tr'); | ||
| Zeile 491: | Zeile 509: | ||
table.appendChild(tbody); | table.appendChild(tbody); | ||
container. | // replaceChildren ist relativ neu – wir nehmen fallback | ||
while (container.firstChild) container.removeChild(container.firstChild); | |||
container.appendChild(table); | |||
}); | }); | ||
} | } | ||
}); | }); | ||