MediaWiki:Common.js: Perbedaan antara revisi
Tidak ada ringkasan suntingan Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
Tidak ada ringkasan suntingan Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
||
| Baris 1: | Baris 1: | ||
/* ========================================================== | /* ========================================================== | ||
🧠 MIPPEDIA DATA - ULTIMATE CLEAN | 🧠 MIPPEDIA DATA - ULTIMATE CLEAN ENGINE (FINAL FIX) | ||
========================================================== */ | ========================================================== */ | ||
(function() { | (function() { | ||
$(document).ready(function() { | $(document).ready(function() { | ||
var | var $descBox = $('#mip-auto-description'), | ||
$sourceInfo = $('#mip-source-info'), $portalLinks = $('#mip-portal-links'), | $sourceInfo = $('#mip-source-info'), | ||
$portalLinks = $('#mip-portal-links'), | |||
$projectPortal = $('#mip-project-portal'); | $projectPortal = $('#mip-project-portal'); | ||
| Baris 11: | Baris 12: | ||
var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' '), | var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' '), | ||
cacheKey = ' | cacheKey = 'mip_final_v6_' + pageTitle, | ||
currentYear = 2026; | currentYear = 2026; | ||
| Baris 20: | Baris 21: | ||
]; | ]; | ||
// --- | // --- ANTI-ACAK-ACAKAN LINKER --- | ||
function applyInstantLinks(text, callback) { | function applyInstantLinks(text, callback) { | ||
var words = text.split(/\s+/); | var words = text.split(/\s+/); | ||
// | // Hanya ambil kata unik > 3 huruf & BUKAN bagian dari judul halaman | ||
var candidates = [...new Set(words.map(w => w.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "")))].filter(w => { | var candidates = [...new Set(words.map(w => w.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "")))].filter(w => { | ||
return w.length > 3 && | return w.length > 3 && !pageTitle.toLowerCase().includes(w.toLowerCase()); | ||
}); | }); | ||
if (candidates.length === 0) return callback(text); | if (candidates.length === 0) return callback(text); | ||
// Cek ke API mana yang beneran ADA halamannya | |||
$.getJSON(mw.util.wikiScript('api'), { | $.getJSON(mw.util.wikiScript('api'), { | ||
action: 'query', | action: 'query', | ||
| Baris 39: | Baris 38: | ||
}, function(res) { | }, function(res) { | ||
var pages = res.query.pages; | var pages = res.query.pages; | ||
var | var validTitles = []; | ||
for (var id in pages) { if (id !== "-1") | for (var id in pages) { | ||
if (id !== "-1") validTitles.push(pages[id].title); | |||
} | |||
var linkedText = text; | var linkedText = text; | ||
// Urutkan dari | // Urutkan dari yang terpanjang biar nggak salah ganti | ||
validTitles.sort((a, b) => b.length - a.length).forEach(function(title) { | |||
var regex = new RegExp('\\b(' + title + ')\\b', 'gi'); | // Regex presisi: ganti kata tapi jangan ganggu yang udah jadi link | ||
var regex = new RegExp('\\b(' + title + ')\\b(?![^<]*>|[^<>]*<\/a>)', 'gi'); | |||
linkedText = linkedText.replace(regex, function(match) { | linkedText = linkedText.replace(regex, function(match) { | ||
return '<a href="/wiki/' + match.replace(/ /g, '_') + '" style="color: #0645ad; text-decoration: none;">' + match + '</a>'; | return '<a href="/wiki/' + match.replace(/ /g, '_') + '" style="color: #0645ad; text-decoration: none;">' + match + '</a>'; | ||
}); | }); | ||
| Baris 55: | Baris 56: | ||
} | } | ||
// --- | // --- FUNGSI PENDUKUNG (TETAP AMAN) --- | ||
function applyAutoBold(text) { | function applyAutoBold(text) { | ||
var regex = new RegExp('(' + pageTitle + ')', 'gi'); | var regex = new RegExp('(' + pageTitle + ')', 'gi'); | ||
| Baris 65: | Baris 66: | ||
function applyDynamicContext(text) { | function applyDynamicContext(text) { | ||
var date = new Date(), bulan = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"]; | var date = new Date(), bulan = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"]; | ||
var | var tgl = date.getDate() + " " + bulan[date.getMonth()] + " " + date.getFullYear(); | ||
return text | return text | ||
.replace(/(hari ini|saat ini|sekarang)/gi, '$1 (' + | .replace(/(hari ini|saat ini|sekarang)/gi, '$1 (' + tgl + ')') | ||
.replace(/(\d{1,2}\s(?:Januari|Februari|Maret|April|Mei|Juni|Juli|Agustus|September|Oktober|November|Desember)\s(\d{4}))/gi, function(m, f, y) { | .replace(/(\d{1,2}\s(?:Januari|Februari|Maret|April|Mei|Juni|Juli|Agustus|September|Oktober|November|Desember)\s(\d{4}))/gi, function(m, f, y) { | ||
return f + " <span style='color: #444; font-weight: bold;'>– usia " + (currentYear - parseInt(y)) + " tahun</span>"; | return f + " <span style='color: #444; font-weight: bold;'>– usia " + (currentYear - parseInt(y)) + " tahun</span>"; | ||
}); | }); | ||
} | } | ||
function renderAll(p, currentText, img) { | |||
function renderAll(p, currentText | |||
applyInstantLinks(currentText, function(linkedText) { | applyInstantLinks(currentText, function(linkedText) { | ||
var | var finalOutput = applyAutoBold(applyDynamicContext(linkedText)); | ||
var | var thumb = img ? '<div style="float: right; margin-left: 15px;"><img src="'+img+'" style="max-width: 100px; border-radius: 4px; border: 1px solid #ddd; padding: 2px;"></div>' : ''; | ||
$ | $('#mip-desc-section').show(); | ||
$descBox.show().html( | $descBox.show().html(thumb + '<span>' + finalOutput + '</span><div style="clear:both;"></div>'); | ||
$sourceInfo.show().html('<div style="font-size: 0.9em; color: #777; margin-top: 10px;">Sumber : <a href="' + p.base + encodeURIComponent(pageTitle) + '" target="_blank" style="color: #6a5acd; font-weight: bold;">' + p.name + '</a></div>'); | |||
// Portal links | |||
$portalLinks.empty(); | |||
projects.filter(pr => pr.id !== p.id).forEach(function(pr) { | |||
$.getJSON(pr.url + '?action=query&titles=' + encodeURIComponent(pageTitle) + '&format=json&origin=*', function(d) { | |||
if (d.query.pages["-1"] === undefined) { | |||
$portalLinks.append('<a href="' + pr.base + encodeURIComponent(pageTitle) + '" target="_blank" style="color: #6a5acd; font-weight: bold; margin-right: 10px;">' + pr.label + '</a>'); | |||
$projectPortal.fadeIn(); | |||
} | |||
}); | |||
}); | |||
}); | }); | ||
} | } | ||
// --- | // --- SISTEM CACHE & FETCH --- | ||
var cached = JSON.parse(localStorage.getItem(cacheKey) || "{}"); | var cached = JSON.parse(localStorage.getItem(cacheKey) || "{}"); | ||
var pCheck = projects[ | var pCheck = projects[0]; // Prioritas bahasa Indonesia | ||
$.ajax({ | $.ajax({ | ||
url: pCheck.url, | url: pCheck.url, | ||
data: { action: 'query', prop: 'revisions|pageimages', rvprop: 'timestamp', piprop: 'thumbnail', pithumbsize: 150, titles: pageTitle, format: 'json', origin: '*' } | data: { action: 'query', prop: 'extracts|revisions|pageimages', exintro: 1, explaintext: 1, rvprop: 'timestamp', piprop: 'thumbnail', pithumbsize: 150, titles: pageTitle, format: 'json', origin: '*' }, | ||
success: function(res) { | success: function(res) { | ||
var pg = res.query.pages, id = Object.keys(pg)[0]; | var pg = res.query.pages, id = Object.keys(pg)[0]; | ||
if (id !== "-1") { | |||
var ext = cleanExtract(pg[id].extract), ts = pg[id].revisions[0].timestamp, img = pg[id].thumbnail ? pg[id].thumbnail.source : ""; | |||
renderAll(pCheck, ext, img); | |||
} | } | ||
} | } | ||