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 - CLEAN AUTO-LINK ENGINE (FIXED)
   🧠 MIPPEDIA DATA - ULTIMATE CLEAN LINKER (v5)
   ========================================================== */
   ========================================================== */
(function() {
(function() {
Baris 11: Baris 11:


         var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' '),
         var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' '),
             cacheKey = 'mip_clean_v4_' + pageTitle,  
             cacheKey = 'mip_clean_v5_' + pageTitle,  
             currentYear = 2026;
             currentYear = 2026;


Baris 20: Baris 20:
         ];
         ];


         // --- FUNGSI BATCH AUTO-LINKER (FILTERED & SAFE) ---
         // --- FUNGSI AUTO-LINKER (ANTI-BERANTAKAN) ---
         function applyInstantLinks(text, callback) {
         function applyInstantLinks(text, callback) {
             var words = text.split(/\s+/);
             var words = text.split(/\s+/);
             // Ambil kata unik, panjang > 3, abaikan kata yang ada di judul halaman ini
             // Filter: Minimal 4 huruf, bukan bagian dari judul, bukan kata umum
            var stopWords = ["adalah", "sebuah", "dengan", "dalam", "untuk", "dari"];
             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 && !pageTitle.toLowerCase().includes(w.toLowerCase());
                 return w.length > 3 &&  
                      !pageTitle.toLowerCase().includes(w.toLowerCase()) &&
                      !stopWords.includes(w.toLowerCase());
             });
             });
              
              
Baris 37: Baris 40:
                 var pages = res.query.pages;
                 var pages = res.query.pages;
                 var existingTitles = [];
                 var existingTitles = [];
               
                 for (var id in pages) { if (id !== "-1") existingTitles.push(pages[id].title); }
                // HANYA ambil judul yang statusnya ADA (ID bukan -1)
                 for (var id in pages) {
                    if (id !== "-1") {
                        existingTitles.push(pages[id].title);
                    }
                }


                 var linkedText = text;
                 var linkedText = text;
                 existingTitles.forEach(function(title) {
                // Urutkan dari kata terpanjang biar nggak salah timpa
                    // Regex presisi: hanya ganti kata yang beneran ada halamannya
                 existingTitles.sort((a, b) => b.length - a.length).forEach(function(title) {
                     var regex = new RegExp('\\b(' + title + ')\\b', 'gi');
                     var regex = new RegExp('\\b(' + title + ')\\b', 'gi');
                     linkedText = linkedText.replace(regex, function(match) {
                     linkedText = linkedText.replace(regex, function(match) {
                         return '<a href="/wiki/' + match.replace(/ /g, '_') + '" style="color: #0645ad; font-weight: bold; text-decoration: none;">' + match + '</a>';
                        // Link Biru Biasa (Gak Tebal)
                         return '<a href="/wiki/' + match.replace(/ /g, '_') + '" style="color: #0645ad; text-decoration: none;">' + match + '</a>';
                     });
                     });
                 });
                 });
Baris 57: Baris 55:
         }
         }


         // --- FITUR ORIGINAL (TETAP TERJAGA) ---
         // --- FITUR LAMA (TETAP UTUH) ---
         function applyAutoBold(text) {  
         function applyAutoBold(text) {  
            // Tebalkan judul halaman utama tanpa menjadikannya link
             var regex = new RegExp('(' + pageTitle + ')', 'gi');
             var regex = new RegExp('(' + pageTitle + ')', 'gi');
             return text.replace(regex, '<strong>$1</strong>');  
             return text.replace(regex, '<strong>$1</strong>');  
Baris 67: Baris 64:
          
          
         function applyDynamicContext(text) {
         function applyDynamicContext(text) {
             var date = new Date();
             var date = new Date(), bulan = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"];
            var hari = ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"];
             var tglSkrg = date.getDate() + " " + bulan[date.getMonth()] + " " + date.getFullYear();
            var bulan = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"];
             var tglSkrg = hari[date.getDay()] + ", " + date.getDate() + " " + bulan[date.getMonth()] + " " + date.getFullYear();
             return text
             return text
                 .replace(/(hari ini|saat ini|sekarang)/gi, '$1 (' + tglSkrg + ')')
                 .replace(/(hari ini|saat ini|sekarang)/gi, '$1 (' + tglSkrg + ')')
Baris 91: Baris 86:
         function buildSmartLinks(currentId) {
         function buildSmartLinks(currentId) {
             $portalLinks.empty();
             $portalLinks.empty();
            var validLinks = [];
             var checkRequests = projects.filter(p => p.id !== currentId).map(function(p) {
             var checkRequests = projects.filter(p => p.id !== currentId).map(function(p) {
                 return $.ajax({ url: p.url, data: { action: 'query', titles: pageTitle, format: 'json', origin: '*' }, dataType: 'json' })
                 return $.ajax({ url: p.url, data: { action: 'query', titles: pageTitle, format: 'json', origin: '*' }, dataType: 'json' })
                     .then(function(data) { if (data.query.pages["-1"] === undefined) { validLinks.push('<a href="' + p.base + encodeURIComponent(pageTitle) + '" target="_blank" style="color: #6a5acd; text-decoration: underline; font-weight: bold;">' + p.label + '</a>'); } });
                     .then(function(data) { if (data.query.pages["-1"] === undefined) {  
            });
                        $portalLinks.append('<a href="' + p.base + encodeURIComponent(pageTitle) + '" target="_blank" style="color: #6a5acd; text-decoration: underline; font-weight: bold;">' + p.label + '</a> ');  
            $.when.apply($, checkRequests).done(function() {
                    }});
                if (validLinks.length > 0) { $portalLinks.html(validLinks.join(' <span style="color:#ccc; margin: 0 5px;">•</span> ')); $projectPortal.fadeIn(); }
             });
             });
            $.when.apply($, checkRequests).done(function() { if ($portalLinks.children().length > 0) $projectPortal.fadeIn(); });
         }
         }


         var cached = JSON.parse(localStorage.getItem(cacheKey) || "{}");
         // --- RENDER CORE ---
 
        function init() {
            var pCheck = projects[Math.floor(Math.random() * projects.length)];
            $.ajax({
                url: pCheck.url,
                data: { action: 'query', prop: 'revisions|pageimages', rvprop: 'timestamp', piprop: 'thumbnail', pithumbsize: 150, titles: pageTitle, format: 'json', origin: '*' },
                dataType: 'json',
                success: function(res) {
                    var pg = res.query.pages, id = Object.keys(pg)[0];
                    var latestTS = (id != "-1") ? pg[id].revisions[0].timestamp : "0";
                    var thumbUrl = (id != "-1" && pg[id].thumbnail) ? pg[id].thumbnail.source : "";
                    if (cached.content && cached.ts === latestTS) {
                        renderAll(cached.p, cached.content, cached.isTrans, cached.orig, cached.img);
                    } else { fetchFreshData(latestTS, thumbUrl); }
                },
                error: function() { if (cached.content) renderAll(cached.p, cached.content, cached.isTrans, cached.orig, cached.img); }
            });
        }
 
        function fetchFreshData(newTS, img) {
            var found = false;
            var shuffled = projects.sort(() => Math.random() - 0.5);
            shuffled.forEach(function(p) {
                if (found) return;
                $.ajax({
                    url: p.url,
                    data: { action: 'query', prop: 'extracts', exintro: 1, explaintext: 1, titles: pageTitle, format: 'json', origin: '*' },
                    dataType: 'json',
                    success: function(data) {
                        if (found) return;
                        var pages = data.query.pages, pageId = Object.keys(pages)[0];
                        if (pageId != "-1" && pages[pageId].extract) {
                            found = true;
                            var extract = cleanExtract(pages[pageId].extract);
                            if (p.id === 'en') {
                                $.ajax({ url: "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=id&dt=t&q=" + encodeURIComponent(extract), success: function(res) {
                                    var trans = ""; res[0].forEach(s => { if (s[0]) trans += s[0]; });
                                    finalize(p, trans, true, extract, newTS, img);
                                }});
                            } else { finalize(p, extract, false, "", newTS, img); }
                        }
                    }
                });
            });
        }
 
        function finalize(p, c, t, o, ts, img) {
            localStorage.setItem(cacheKey, JSON.stringify({p:p, content:c, isTrans:t, orig:o, ts:ts, img:img}));
            renderAll(p, c, t, o, img);
        }
 
         function renderAll(p, currentText, isTranslated, originalText, img) {
         function renderAll(p, currentText, isTranslated, originalText, img) {
             applyInstantLinks(currentText, function(linkedText) {
             applyInstantLinks(currentText, function(linkedText) {
Baris 168: Baris 111:
              
              
             $(document).off('click', '.mip-read-btn').on('click', '.mip-read-btn', function() { $(this).hide(); $('.mip-dots').hide(); $('.mip-more').fadeIn(); });
             $(document).off('click', '.mip-read-btn').on('click', '.mip-read-btn', function() { $(this).hide(); $('.mip-dots').hide(); $('.mip-more').fadeIn(); });
            $(document).off('click', '#mip-toggle-orig').on('click', '#mip-toggle-orig', function() {
                var isOrig = ($(this).text() === 'Tampilkan versi asli');
                var targetText = isOrig ? originalText : currentText;
                applyInstantLinks(targetText, function(newLinkedText) {
                    var textToDisplay = applyAutoBold(applyDynamicContext(newLinkedText));
                    $descBox.find('span').first().parent().html(img ? thumbHtml + applySummary(textToDisplay) : applySummary(textToDisplay));
                    $('#mip-toggle-orig').text(isOrig ? 'Tampilkan terjemahan' : 'Tampilkan versi asli');
                });
            });
         }
         }


         init();
         // --- INIT DATA ---
        var cached = JSON.parse(localStorage.getItem(cacheKey) || "{}");
        var pCheck = projects[Math.floor(Math.random() * projects.length)];
        $.ajax({
            url: pCheck.url,
            data: { action: 'query', prop: 'revisions|pageimages', rvprop: 'timestamp', piprop: 'thumbnail', pithumbsize: 150, titles: pageTitle, format: 'json', origin: '*' },
            dataType: 'json',
            success: function(res) {
                var pg = res.query.pages, id = Object.keys(pg)[0];
                var ts = (id != "-1") ? pg[id].revisions[0].timestamp : "0";
                var img = (id != "-1" && pg[id].thumbnail) ? pg[id].thumbnail.source : "";
                if (cached.content && cached.ts === ts) { renderAll(cached.p, cached.content, cached.isTrans, cached.orig, cached.img); }
                else {
                    $.ajax({
                        url: pCheck.url,
                        data: { action: 'query', prop: 'extracts', exintro: 1, explaintext: 1, titles: pageTitle, format: 'json', origin: '*' },
                        dataType: 'json',
                        success: function(d) {
                            var pages = d.query.pages, pid = Object.keys(pages)[0];
                            if (pid != "-1") {
                                var ext = cleanExtract(pages[pid].extract);
                                localStorage.setItem(cacheKey, JSON.stringify({p:pCheck, content:ext, isTrans:false, orig:"", ts:ts, img:img}));
                                renderAll(pCheck, ext, false, "", img);
                            }
                        }
                    });
                }
            }
        });
     });
     });
})();
})();