Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
| (158 revisi perantara oleh 2 pengguna tidak ditampilkan) |
| Baris 1: |
Baris 1: |
| | /* Otomatis alihkan Special:Upload ke Mippedia Commons */ |
| | if (mw.config.get('wgCanonicalSpecialPageName') === 'Upload') { |
| | window.location.href = 'https://commons.mippedia.org/wiki/Special:Upload'; |
| | } |
| | |
| /* Script Estimasi Waktu Baca - Spesialis Mobile (Minerva) & Desktop */ | | /* Script Estimasi Waktu Baca - Spesialis Mobile (Minerva) & Desktop */ |
| $(document).ready(function() { | | $(document).ready(function() { |
| // Hanya jalan di halaman artikel asli | | // Hanya jalan di halaman artikel asli dan BUKAN di Halaman Utama |
| if (mw.config.get('wgIsArticle') && mw.config.get('wgAction') === 'view' && mw.config.get('wgNamespaceNumber') === 0) { | | if (mw.config.get('wgIsArticle') && mw.config.get('wgAction') === 'view' && mw.config.get('wgNamespaceNumber') === 0 && !mw.config.get('wgIsMainPage')) { |
| | | |
| function hitungWaktuBaca() { | | function hitungWaktuBaca() { |
| Baris 15: |
Baris 20: |
| // Bikin elemen tampilannya | | // Bikin elemen tampilannya |
| var icon = '🕒'; // Emoji jam biar simpel dan ringan | | var icon = '🕒'; // Emoji jam biar simpel dan ringan |
| var label = (readingTime <= 1) ? 'Kurang dari 1 menit' : readingTime + ' menit'; | | var label = (readingTime <= 1) ? '- 1 menit' : readingTime + ' menit'; |
| | | |
| var html = '<div id="reading-time-auto" style="font-size: 0.9em; color: #54595d; margin-bottom: 15px; display: flex; align-items: center; font-family: sans-serif;">'; | | var html = '<div id="reading-time-auto" style="font-size: 0.9em; color: #54595d; margin-bottom: 15px; display: flex; align-items: center; font-family: sans-serif;">'; |
| html += '<span style="margin-right: 5px;">' + icon + '</span>'; | | html += '<span style="margin-right: 5px;">' + icon + '</span>'; |
| html += '<span>Estimasi waktu baca: <b>' + label + '</b></span>'; | | html += '<span>Estimasi waktu baca : <b>' + label + '</b></span>'; |
| html += '</div>'; | | html += '</div>'; |
|
| |
|
| Baris 36: |
Baris 41: |
| } | | } |
| }); | | }); |
|
| |
|
| |
|
| /* Script Tombol Back to Top (Spesial Mobile) */ | | /* Script Tombol Back to Top (Spesial Mobile) */ |
| Baris 60: |
Baris 64: |
| }); | | }); |
|
| |
|
| | | /* ========================================================== |
| /* Smart Glossary Pop-up (Pratinjau Link Ringan) */ | | 🚀 MIPPEDIA DATA BUTTON ONLY (Otomatis) |
| | Hanya memunculkan tombol jika data tersedia di pusat. |
| | ========================================================== */ |
| $(document).ready(function() { | | $(document).ready(function() { |
| if (mw.config.get('wgIsArticle') && mw.config.get('wgAction') === 'view') { | | var pageName = mw.config.get('wgPageName'); |
|
| | var namespace = mw.config.get('wgNamespaceNumber'); |
| var timer;
| | var dataDomain = 'https://data.mippedia.org'; |
| // Targetkan link di dalam konten artikel saja
| |
| $('#mw-content-text a').on('mouseenter touchstart', function(e) {
| |
| var $link = $(this);
| |
| var title = $link.attr('title');
| |
|
| |
| // Jangan jalan kalau link-nya bukan artikel (misal link luar atau redlink)
| |
| if (!title || $link.hasClass('new') || $link.hasClass('external')) return;
| |
|
| |
|
| timer = setTimeout(function() {
| | // Jalankan hanya di namespace artikel |
| $.getJSON(mw.util.wikiScript('api'), {
| | if (namespace === 0) { |
| action: 'query',
| | // Cek apakah halaman tersebut ada di Mippedia Data |
| prop: 'extracts',
| | $.ajax({ |
| exintro: true,
| | url: dataDomain + '/api.php', |
| exsentences: 2, // Ambil 2 kalimat aja biar singkat
| | data: { |
| titles: title,
| | action: 'query', |
| explaintext: true,
| | titles: pageName, |
| format: 'json'
| | format: 'json', |
| }, function(data) {
| | origin: '*' |
| var pages = data.query.pages;
| | }, |
| var pageId = Object.keys(pages)[0];
| | dataType: 'jsonp', |
| var extract = pages[pageId].extract;
| | success: function(res) { |
| | | var pages = res.query.pages; |
| if (extract) {
| | var isExist = false; |
| // Hapus pop-up lama kalau ada
| | |
| $('.wiki-preview').remove();
| | // Cek apakah ID halaman > 0 (artinya halaman ada) |
| | | for (var id in pages) { |
| var preview = $('<div class="wiki-preview" style="position:absolute; background:#fff; color:#202122; border:1px solid #a2a9b1; padding:12px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.2); z-index:10001; font-size:13px; max-width:250px; line-height:1.4; opacity:0; transition:opacity 0.3s ease;"></div>');
| | if (parseInt(id) > 0) { |
| preview.text(extract);
| | isExist = true; |
|
| | break; |
| $('body').append(preview);
| |
| | |
| // Atur posisi pop-up di deket link
| |
| var offset = $link.offset();
| |
| preview.css({
| |
| top: offset.top + 25,
| |
| left: Math.min(offset.left, $(window).width() - 270),
| |
| opacity: 1
| |
| }); | |
| | |
| // Hilang kalau klik di mana aja atau setelah 5 detik | |
| setTimeout(function() { $('.wiki-preview').fadeOut(function() { $(this).remove(); }); }, 5000);
| |
| } | | } |
| }); | | } |
| }, 600); // Delay 0.6 detik biar gak ganggu kalau cuma scrolling lewat
| |
| }).on('mouseleave', function() {
| |
| clearTimeout(timer);
| |
| });
| |
|
| |
|
| $(document).on('mousedown touchstart', function() {
| | // Jika data ditemukan, munculkan tombol melayang |
| $('.wiki-preview').remove();
| | if (isExist) { |
| | injectFloatingDataBtn(pageName, dataDomain); |
| | } |
| | } |
| }); | | }); |
| } | | } |
| });
| |
|
| |
|
| /* 3. Notifikasi Link Luar */
| | function injectFloatingDataBtn(name, domain) { |
| $(document).ready(function() {
| | if ($('#mippedia-data-btn').length) return; |
| $('a.external').click(function(e) { | |
| var url = $(this).attr('href');
| |
| if (!confirm('Anda akan meninggalkan Mippedia menuju situs luar:\n' + url + '\n\nLanjutkan?')) { | |
| e.preventDefault();
| |
| }
| |
| });
| |
| });
| |
|
| |
|
| | var $btn = $('<a>', { |
| | id: 'mippedia-data-btn', |
| | href: domain + '/wiki/' + encodeURIComponent(name), |
| | target: '_blank', |
| | style: 'position: absolute; right: 10px; top: -32px; background: #36c; color: #fff; padding: 4px 10px; border-radius: 4px; font-weight: bold; font-size: 10px; text-decoration: none; z-index: 1000; box-shadow: 0 2px 4px rgba(0,0,0,0.1);', |
| | text: 'DATA' |
| | }); |
|
| |
|
| /* 3. Anti-Ghosting pada Link Kosong (Redlinks) */ | | // Target: Area menu aksi (dekat ikon pensil) |
| $(document).ready(function() {
| | // Mendukung skin Mobile (Minerva) dan Desktop |
| $('a.new').click(function(e) {
| | var $target = $('.page-actions-menu, .mw-editsection-visualeditor, #ca-edit, .minerva__tab-container').first(); |
| var confirmCreate = confirm("Halaman ini belum tersedia di Mippedia.\n\nApakah Anda ingin berkontribusi membuatnya?"); | |
| if (!confirmCreate) {
| |
| e.preventDefault();
| |
| }
| |
| });
| |
| });
| |
| | |
| /* 1. Navigasi Bab Melayang (Vertical Stack Edition) */
| |
| $(document).ready(function() {
| |
| if (mw.config.get('wgIsArticle') && $('#toc').length) {
| |
| | | |
| // CSS untuk posisi menumpuk secara vertikal | | if ($target.length) { |
| var $quickNav = $('<div id="quick-nav" style="position:fixed; bottom:20px; right:20px; width:45px; height:45px; background:#36c; color:#fff; border-radius:50%; display:flex; align-items:center; justify-content:center; z-index:9996; box-shadow:0 4px 12px rgba(0,0,0,0.2); cursor:pointer; font-size:20px; transition: all 0.3s ease;">≡</div>');
| | $target.css('position', 'relative').append($btn); |
|
| | } else { |
| // Tombol Back to Top lo biasanya di bottom: 80px atau 90px kan?
| | // Fallback jika header tidak standar |
| // Kita paksa Back to Top naik sedikit, dan navigasi bab ada di bawahnya.
| | $('#firstHeading').css('position', 'relative').append($btn); |
| // Script ini bakal otomatis menyesuaikan posisi tombol panah atas lo.
| |
|
| |
| $('body').append($quickNav);
| |
| | |
| // Menyesuaikan posisi tombol Back to Top bawaan (jika ada) biar gak tabrakan
| |
| // Kita set navigasi di bottom 20px, dan Back to Top di bottom 80px
| |
| $('.back-to-top, #mw-mf-back-to-top').css('bottom', '85px');
| |
| | |
| $quickNav.click(function() {
| |
| var $toc = $('#toc ul').first().clone(); | |
| var $modal = $('<div id="nav-modal" style="position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:20001; display:flex; align-items:flex-end; justify-content:center; backdrop-filter:blur(5px); opacity:0; transition:opacity 0.3s ease;">' +
| |
| '<div id="nav-card" style="background:#fff; width:100%; max-height:75%; overflow-y:auto; border-top-left-radius:30px; border-top-right-radius:30px; padding:25px; transform:translateY(100%); transition:transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);">' +
| |
| '<div style="width:50px; height:5px; background:#eee; border-radius:10px; margin:0 auto 20px;"></div>' +
| |
| '<h3 style="margin-top:0; color:#36c; font-size:1.3em; text-align:center;">Daftar Isi</h3>' +
| |
| '<div id="nav-list" style="margin-top:10px;"></div>' +
| |
| '</div></div>');
| |
|
| |
| $('body').append($modal);
| |
| $modal.find('#nav-list').append($toc);
| |
|
| |
| setTimeout(function() {
| |
| $modal.css('opacity', '1');
| |
| $modal.find('#nav-card').css('transform', 'translateY(0)');
| |
| }, 10);
| |
| | |
| // Styling link agar terasa seperti menu aplikasi
| |
| $modal.find('a').css({
| |
| 'display':'block',
| |
| 'padding':'15px 10px',
| |
| 'color':'#333',
| |
| 'text-decoration':'none',
| |
| 'border-bottom':'1px solid #f9f9f9',
| |
| 'font-size':'1.1em'
| |
| });
| |
| | |
| function closeModal() {
| |
| $modal.find('#nav-card').css('transform', 'translateY(100%)');
| |
| $modal.css('opacity', '0');
| |
| setTimeout(function() { $modal.remove(); }, 400);
| |
| }
| |
| | |
| $modal.on('click', function(e) { if(e.target === this) closeModal(); });
| |
| }); | |
| }
| |
| });
| |
| | |
| /* 2. Auto-Night Shift (Berdasarkan Jam Lokal) */
| |
| $(document).ready(function() {
| |
| var hour = new Date().getHours();
| |
| if (hour >= 21 || hour < 6) { // Jam 9 malem sampe 6 pagi
| |
| $("<style id='night-shift'>").prop("type", "text/css").html(`
| |
| body::after { | |
| content: "";
| |
| position: fixed;
| |
| top: 0; left: 0;
| |
| width: 100vw; height: 100vh;
| |
| background: rgba(255, 165, 0, 0.05); /* Filter orange tipis */
| |
| pointer-events: none;
| |
| z-index: 99999;
| |
| } | |
| `).appendTo("head");
| |
| }
| |
| });
| |
| | |
| /* 3. Smooth Fade-In saat Ganti Halaman */
| |
| $(document).ready(function() {
| |
| $('body').css({'opacity': '0', 'transition': 'opacity 0.5s ease'});
| |
| setTimeout(function() { $('body').css('opacity', '1'); }, 100);
| |
| });
| |
| | |
| /* 2. Auto-Source on Copy (Kredit Otomatis) */
| |
| document.addEventListener('copy', function(e) {
| |
| var selection = window.getSelection();
| |
| if (selection.toString().length > 1) { // Hanya aktif kalau copy lebih dari 50 karakter
| |
| var body_element = document.getElementsByTagName('body')[0];
| |
| var newdiv = document.createElement('div');
| |
| newdiv.style.position = 'absolute';
| |
| newdiv.style.left = '-99999px';
| |
| body_element.appendChild(newdiv);
| |
| newdiv.innerHTML = selection + '<br /><br />Sumber: ' + document.title + '<br />Link: ' + window.location.href;
| |
| selection.selectAllChildren(newdiv);
| |
| window.setTimeout(function() {
| |
| body_element.removeChild(newdiv);
| |
| }, 0);
| |
| }
| |
| });
| |
| | |
| /* ==========================================================
| |
| 🚀 MIPPEDIA DATA INTEGRATION (Global Version)
| |
| Berfungsi untuk: User Login & Anonim
| |
| Posisi: Di bawah Estimasi Waktu Baca (Header)
| |
| ========================================================== */
| |
| $(document).ready(function() {
| |
| function injectMippediaData() {
| |
| // 1. Cari template asli
| |
| var $dataTemplate = $('.mw-parser-output div:contains("Mippedia Data")').first();
| |
| var dataUrl = $dataTemplate.find('a').attr('href');
| |
| | |
| // 2. Jika ketemu dan belum pernah di-inject sebelumnya
| |
| if ($dataTemplate.length && dataUrl && $('#mippedia-data-btn').length === 0) {
| |
|
| |
| // Buat tombol bergaya metadata yang premium
| |
| var $newBtn = $(`
| |
| <div id="mippedia-data-btn" style="margin: 10px 0; display: inline-block;">
| |
| <a href="${dataUrl}" target="_blank" style="text-decoration: none !important;">
| |
| <div style="display: flex; align-items: center; background: #36c; color: #fff; padding: 6px 12px; border-radius: 8px; font-family: sans-serif; box-shadow: 0 4px 10px rgba(54,102,204,0.25);">
| |
| <span style="font-size: 14px; margin-right: 8px;"></span>
| |
| <span style="font-size: 11px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase;">Lihat di Mippedia Data</span>
| |
| </div>
| |
| </a>
| |
| </div>
| |
| `);
| |
| | |
| // 3. PENEMPATAN POSISI (Target: Di bawah estimasi waktu baca)
| |
| var $targetHeader = $('.tagline, .minerva__subtitle, .estimasi-baca-container');
| |
|
| |
| if ($targetHeader.length) {
| |
| // Taruh tepat di bawah estimasi waktu baca atau subtitle
| |
| $targetHeader.last().after($newBtn);
| |
| // Hapus template lama dari dalam artikel agar tidak dobel
| |
| $dataTemplate.hide();
| |
| } else {
| |
| // Fallback: Jika header tidak ketemu, taruh di bawah judul utama
| |
| $('#firstHeading').after($newBtn);
| |
| $dataTemplate.hide();
| |
| }
| |
| } | | } |
| }
| |
|
| |
| // Jalankan segera dan ulangi sekali lagi untuk memastikan render mobile selesai
| |
| injectMippediaData();
| |
| setTimeout(injectMippediaData, 1500);
| |
| });
| |
|
| |
| /* Smart Random Toaster Mippedia (Fixed: Article & Main Page Only) */
| |
| $(document).ready(function() {
| |
| var ns = mw.config.get('wgNamespaceNumber');
| |
| var action = mw.config.get('wgAction');
| |
| var isMainPage = mw.config.get('wgIsMainPage');
| |
| var isDiff = mw.config.get('wgDiffOldId') !== null;
| |
|
| |
| // VALIDASI: Cuma di Artikel (NS 0), Halaman Utama, dan saat 'View' saja
| |
| if ((ns === 0 || isMainPage) && action === 'view' && !isDiff) {
| |
|
| |
| var mippediaDatabase = [
| |
| // KATEGORI: FAKTA UNIK (💡)
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia adalah proyek ensiklopedia mandiri yang berfokus pada sejarah, musik, dan teknologi." },
| |
| { type: "💡 FAKTA UNIK", text: "Rumi Haitami, pendiri Mippedia, adalah musisi dan pengusaha muda asal Indonesia." },
| |
| { type: "💡 FAKTA UNIK", text: "Nama 'Mippedia' merepresentasikan identitas kolektif dari Mippedia Community." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia tidak berafiliasi dengan Wikimedia Foundation dan mengelola server secara mandiri." },
| |
| { type: "💡 FAKTA UNIK", text: "Sugar Store Id merupakan bagian dari ekosistem bisnis yang dikembangkan pendiri Mippedia." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia memiliki ribuan item data yang terhubung melalui sistem Mippedia Data." },
| |
| { type: "💡 FAKTA UNIK", text: "Proyek ini dimulai dengan visi untuk mendokumentasikan pengetahuan secara profesional dan bebas." },
| |
| { type: "💡 FAKTA UNIK", text: "Logo Mippedia melambangkan integrasi ilmu pengetahuan global dan lokal." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia Community terdiri dari kontributor yang ahli di bidang teknologi dan dokumentasi digital." },
| |
| { type: "💡 FAKTA UNIK", text: "Selain ensiklopedia, ekosistem Mippedia juga mencakup label rekaman musik." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia mendukung standarisasi Wikidata untuk sinkronisasi informasi tokoh." },
| |
| { type: "💡 FAKTA UNIK", text: "Setiap artikel di sini melewati proses kurasi oleh tim administrator Mippedia." },
| |
| { type: "💡 FAKTA UNIK", text: "Sistem pencarian Mippedia dirancang untuk menemukan artikel dalam hitungan milidetik." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia menggunakan platform MediaWiki yang telah dimodifikasi secara ekstrim untuk kenyamanan pengguna." },
| |
| { type: "💡 FAKTA UNIK", text: "Warna biru pada tema Mippedia melambangkan kepercayaan, profesionalisme, dan teknologi." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia adalah salah satu proyek wiki independen terbesar yang dikelola oleh komunitas lokal." },
| |
| { type: "💡 FAKTA UNIK", text: "Konten musik di Mippedia mencakup diskografi lengkap dari artis-artis di bawah label Mippedia." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia menyediakan portal khusus bagi administrator untuk mengelola sistem secara real-time." },
| |
| { type: "💡 FAKTA UNIK", text: "Data kelahiran dan riwayat tokoh di Mippedia diambil dari sumber primer yang tervalidasi." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia sering melakukan pembaruan sistem pesan sistem untuk menjaga keamanan komunitas." },
| |
| { type: "💡 FAKTA UNIK", text: "User interface Mippedia dioptimasi agar ramah bagi pengguna perangkat mobile." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia memiliki kebijakan privasi yang ketat untuk melindungi data setiap pembacanya." },
| |
| { type: "💡 FAKTA UNIK", text: "Sistem 'Dengarkan Artikel' di Mippedia menggunakan teknologi sintesis suara yang jernih." },
| |
| { type: "💡 FAKTA UNIK", text: "Mippedia secara aktif mengarsipkan dokumen sejarah yang jarang ditemukan di tempat lain." },
| |
| { type: "💡 FAKTA UNIK", text: "Setiap gambar yang diunggah ke Mippedia disimpan dalam repositori lokal yang aman." },
| |
|
| |
| // KATEGORI: INFORMASI (ℹ️)
| |
| { type: "ℹ️ INFORMASI", text: "Anda dapat mendengarkan isi artikel ini dengan mengklik ikon 🔊 di bagian atas halaman." },
| |
| { type: "ℹ️ INFORMASI", text: "Klik ikon ≡ di pojok kanan bawah untuk melihat daftar isi dan melompat antar bagian." },
| |
| { type: "ℹ️ INFORMASI", text: "Gunakan fitur 'Back to Top' (ikon panah) untuk kembali ke atas halaman dengan cepat." },
| |
| { type: "ℹ️ INFORMASI", text: "Artikel ini terakhir diperbarui sesuai dengan log aktivitas Mippedia Community." },
| |
| { type: "ℹ️ INFORMASI", text: "Anda bisa membagikan artikel ini melalui tombol share yang tersedia di akhir tulisan." },
| |
| { type: "ℹ️ INFORMASI", text: "Mippedia Data menyediakan basis data teknis yang terhubung dengan artikel ini." },
| |
| { type: "ℹ️ INFORMASI", text: "Aktifkan Mode Malam pada browser Anda untuk pengalaman membaca yang lebih nyaman di Mippedia." },
| |
| { type: "ℹ️ INFORMASI", text: "Seluruh konten di sini dilindungi oleh lisensi Creative Commons BY-SA 4.0." },
| |
| { type: "ℹ️ INFORMASI", text: "Untuk bantuan teknis atau laporan bug, silakan hubungi tim administrator Mippedia." },
| |
| { type: "ℹ️ INFORMASI", text: "Anda bisa melihat estimasi waktu baca artikel tepat di bawah judul halaman." },
| |
| { type: "ℹ️ INFORMASI", text: "Mippedia menyediakan fitur pencarian pintar di header untuk menemukan topik terkait." },
| |
| { type: "ℹ️ INFORMASI", text: "Pastikan Anda melihat bagian 'Referensi' untuk memverifikasi keaslian data artikel." },
| |
| { type: "ℹ️ INFORMASI", text: "Pendaftaran kontributor Mippedia Community dibuka secara berkala melalui pengumuman resmi." },
| |
| { type: "ℹ️ INFORMASI", text: "Sistem Mippedia secara otomatis mendeteksi perangkat Anda untuk memberikan tampilan terbaik." },
| |
| { type: "ℹ️ INFORMASI", text: "Ikon DATA di sebelah tab Pembicaraan akan mengarahkan Anda ke metadata lengkap tokoh tersebut." },
| |
| { type: "ℹ️ INFORMASI", text: "Mippedia menjaga integritas data dengan sistem proteksi halaman dari suntingan anonim berbahaya." },
| |
| { type: "ℹ️ INFORMASI", text: "Anda bisa mengunduh artikel Mippedia dalam format PDF melalui menu aksi di pojok kanan." },
| |
| { type: "ℹ️ INFORMASI", text: "Jaringan Mippedia mencakup berbagai subdomain untuk proyek bahasa yang berbeda." },
| |
| { type: "ℹ️ INFORMASI", text: "Gunakan fitur seleksi teks untuk mencari istilah yang tidak Anda mengerti di dalam Mippedia." },
| |
| { type: "ℹ️ INFORMASI", text: "Pesan toast ini hanya muncul sekali per sesi halaman untuk kenyamanan membaca Anda." },
| |
| { type: "ℹ️ INFORMASI", text: "Mippedia Community berkomitmen menjaga netralitas informasi di setiap artikel sejarah." },
| |
| { type: "ℹ️ INFORMASI", text: "Pembaruan basis data Mippedia dilakukan setiap hari untuk memastikan akurasi informasi." },
| |
| { type: "ℹ️ INFORMASI", text: "Anda dapat melihat riwayat penyuntingan artikel melalui tab 'History' di menu navigasi." },
| |
| { type: "ℹ️ INFORMASI", text: "Mippedia mendukung integrasi media kaya seperti audio dan video berkualitas tinggi." },
| |
| { type: "ℹ️ INFORMASI", text: "Terima kasih telah menjadi bagian dari pembaca setia Mippedia Community!" }
| |
| ];
| |
|
| |
| var randomItem = mippediaDatabase[Math.floor(Math.random() * mippediaDatabase.length)];
| |
|
| |
| setTimeout(function() {
| |
| if ($('input:focus, textarea:focus').length > 0) return;
| |
|
| |
| var $toaster = $('<div id="smart-toaster" style="position:fixed; top:25px; left:20px; right:20px; background:rgba(255,255,255,0.98); border-left:5px solid #36c; color:#333; padding:15px; border-radius:12px; z-index:11000; box-shadow:0 10px 30px rgba(0,0,0,0.15); backdrop-filter:blur(10px); display:none; font-family:sans-serif;">' +
| |
| '<div style="color:#36c; font-weight:bold; font-size:11px; margin-bottom:5px; text-transform:uppercase; letter-spacing:1px;">' + randomItem.type + '</div>' +
| |
| '<div style="font-size:13px; line-height:1.4; color:#444;">' + randomItem.text + '</div>' +
| |
| '</div>');
| |
|
| |
| $('body').append($toaster);
| |
| $toaster.slideDown(500).delay(7000).slideUp(500, function() { $(this).remove(); });
| |
| }, 5000);
| |
| } | | } |
| }); | | }); |
|
| |
|
| /* ========================================================== | | /* ========================================================== |
| 🛡️ MIPPEDIA SHIELD: PROTEKSI HALAMAN SENSITIF (FULL CODE) | | 🚀 MIPPEDIA COMMAND CENTER: AUTO-SYNC ENGINE (V4) |
| Hanya untuk Pengurus, Birokrat, dan Pengawas. | | Status: Global Login User | Auto-Purge | High Reliability |
| ========================================================== */ | | ========================================================== */ |
| $(document).ready(function() {
| | (function($, mw) { |
| | | "use strict"; |
| // 1. DAFTAR HALAMAN YANG MAU DIKUNCI
| |
| // Tambah atau hapus di dalam kurung siku ini. Gunakan koma sebagai pemisah.
| |
| var protectedPages = [
| |
| "MediaWiki:",
| |
| "Mippedia:Privasi",
| |
| "Mippedia:Kebijakan",
| |
| "Spesial:Versi",
| |
| "Mippedia:Ketentuan_penggunaan"
| |
| ];
| |
|
| |
|
| // 2. CEK STATUS USER & HALAMAN
| | var conf = mw.config.get(['wgNamespaceNumber', 'wgAction', 'wgPageName', 'wgIsMainPage', 'wgUserName']); |
| var userGroups = mw.config.get('wgUserGroups') || []; | | // Filter: Hanya artikel, hanya saat baca, hanya user yang sudah login |
| // Daftar grup yang KEBAL proteksi (bisa akses halaman)
| | if (conf.wgNamespaceNumber !== 0 || conf.wgAction !== 'view' || conf.wgIsMainPage || conf.wgUserName === null) return; |
| var isStaff = userGroups.some(r => ["sysop", "bureaucrat", "steward", "interface-admin"].includes(r));
| |
|
| |
| var currentPage = mw.config.get('wgPageName');
| |
| // Cek apakah halaman saat ini masuk dalam daftar proteksi | |
| var shouldProtect = protectedPages.some(prefix => currentPage.startsWith(prefix.replace(/ /g, '_'))); | |
|
| |
|
| // 3. EKSEKUSI PROTEKSI (Hanya jika user BUKAN staff) | | $(document).ready(function() { |
| if (shouldProtect && !isStaff) {
| | var currentTitle = conf.wgPageName; |
| | | // Penentuan subdomain (id, en, concise) |
| // Hapus total konten asli agar tidak bisa diintip/disunting | | var hostParts = window.location.hostname.split('.'); |
| $('body').addClass('mippedia-locked').html(''); | | var langKey = hostParts[0] === 'mippedia' || hostParts[0] === 'www' ? 'id' : hostParts[0]; |
|
| |
|
| // Inject CSS khusus untuk tampilan Mobile-Friendly & Auto-Center
| | $.ajax({ |
| $('<style>').prop('type', 'text/css').html(` | | url: 'https://data.mippedia.org/api.php', |
| html, body {
| | data: { |
| margin: 0 !important;
| | action: 'query', |
| padding: 0 !important;
| | prop: 'revisions', |
| height: 100% !important;
| | titles: 'MediaWiki:ShortDesc-Data.json', |
| width: 100% !important;
| | rvprop: 'content', |
| overflow: hidden !important;
| | format: 'json', |
| background: #f8f9fa !important;
| | origin: '*' |
| } | | }, |
| #protection-wrapper {
| | dataType: 'jsonp', |
| display: flex;
| | success: function(res) { |
| align-items: center;
| | try { |
| justify-content: center;
| | var pages = res.query.pages; |
| min-height: 100vh;
| | var pageId = Object.keys(pages)[0]; |
| width: 100vw;
| | if (pageId === "-1") return; |
| padding: 20px;
| |
| box-sizing: border-box;
| |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
| |
| } | |
| .protection-card {
| |
| width: 100%; | |
| max-width: 400px; | |
| background: #ffffff; | |
| padding: 40px 25px;
| |
| border-radius: 30px;
| |
| box-shadow: 0 15px 50px rgba(54, 102, 204, 0.15); | |
| border: 1px solid #eef0f2; | |
| text-align: center; | |
| } | |
| .shield-icon { font-size: 70px; display: block; margin-bottom: 20px; } | |
| .lock-title { color: #1a1a1a; font-size: 24px; font-weight: 800; margin: 0 0 15px 0; } | |
| .lock-desc { color: #5f6368; font-size: 15px; line-height: 1.6; margin-bottom: 25px; }
| |
| .admin-notice {
| |
| background: #fff5f5; | |
| color: #d93025;
| |
| padding: 12px;
| |
| border-radius: 12px;
| |
| font-size: 13px;
| |
| font-weight: 700;
| |
| margin-bottom: 30px;
| |
| border: 1px solid #fadbd8;
| |
| }
| |
| .btn-back {
| |
| background: #36c;
| |
| color: #fff;
| |
| border: none;
| |
| padding: 16px;
| |
| border-radius: 18px;
| |
| font-weight: 700;
| |
| font-size: 16px;
| |
| width: 100%;
| |
| cursor: pointer;
| |
| box-shadow: 0 4px 12px rgba(51, 102, 204, 0.3);
| |
| }
| |
| .link-home { display: block; margin-top: 20px; color: #70757a; font-size: 14px; text-decoration: none; }
| |
| .footer-ver { margin-top: 40px; font-size: 10px; color: #bdc1c6; font-weight: bold; letter-spacing: 2px; }
| |
| `).appendTo('head');
| |
|
| |
|
| // Tampilkan layar kunci
| | var fullData = JSON.parse(pages[pageId].revisions[0]['*']); |
| var shieldHTML = `
| | var targetDesc = (fullData[currentTitle] && fullData[currentTitle][langKey]) ? fullData[currentTitle][langKey].trim() : ""; |
| <div id="protection-wrapper">
| |
| <div class="protection-card">
| |
| <span class="shield-icon">🛡️</span>
| |
| <h2 class="lock-title">Akses Dibatasi</h2>
| |
| <p class="lock-desc">
| |
| Halaman ini telah dilindungi oleh <b>Mippedia Community</b> untuk menjaga stabilitas sistem.
| |
| </p> | |
| <div class="admin-notice">
| |
| Hanya Administrator & Birokrat yang dapat mengakses halaman ini.
| |
| </div>
| |
| <button class="btn-back" onclick="window.history.back()">
| |
| Kembali ke Halaman Sebelumnya
| |
| </button>
| |
| <a href="/" class="link-home">Kembali ke Beranda</a>
| |
| <div class="footer-ver">MIPPEDIA COMMUNITY SECURE v2.0</div>
| |
| </div>
| |
| </div>
| |
| `;
| |
|
| |
|
| $('body').append(shieldHTML);
| | syncMetadata(currentTitle, targetDesc); |
|
| | } catch (e) { |
| // Ubah judul tab browser
| | console.log("Mippedia System: Data sync not required or entry missing."); |
| document.title = "Akses Dilindungi - Mippedia bahasa Indonesia, ensiklopedia umum";
| |
| }
| |
| });
| |
| | |
| /* ==========================================================
| |
| 🛡️ MIPPEDIA FILE VERIFICATION SYSTEM v3.1 (PRECISION)
| |
| Fix: Kotak lebih ramping & Ikon lebih proporsional
| |
| ========================================================== */
| |
| $(document).ready(function() {
| |
| if (mw.config.get('wgNamespaceNumber') === 6) {
| |
|
| |
| var $content = $('#mw-content-text');
| |
| var pageText = $content.text();
| |
| var badgeTitle = "";
| |
| var badgeStyle = "";
| |
| | |
| if (pageText.includes("Aset Resmi")) {
| |
| badgeTitle = "ASET RESMI";
| |
| badgeStyle = "border: 1px solid #36c; background: #f0f7ff;";
| |
| } else if (pageText.includes("Terverifikasi")) {
| |
| badgeTitle = "TERVERIFIKASI";
| |
| badgeStyle = "border: 1px solid #00af89; background: #e6fffb;";
| |
| }
| |
| | |
| if (badgeTitle !== "") {
| |
| // Ukuran gambar dinaikin ke 24px biar lebih jelas centangnya
| |
| var fileName = "Verified_Badge.png";
| |
|
| |
| new mw.Api().parse('[[Berkas:' + fileName + '|24px|link=]]')
| |
| .done(function(renderedImage) {
| |
| var badgeHTML = ` | |
| <div id="mippedia-sleek-badge" style="display: inline-flex; align-items: center; border-radius: 8px; padding: 2px 8px; margin: 5px 0 12px 0; height: 32px; box-sizing: border-box; font-family: sans-serif; vertical-align: middle; ${badgeStyle}">
| |
| <div style="margin-right: 6px; display: flex; align-items: center; justify-content: center; width: 24px;">${renderedImage}</div>
| |
| <span style="font-weight: 800; font-size: 11px; letter-spacing: 0.5px; color: #1a1a1a; text-transform: uppercase; white-space: nowrap; line-height: 1;">${badgeTitle}</span>
| |
| </div>
| |
| `;
| |
| | |
| $('#firstHeading').after(badgeHTML);
| |
| $('.mippedia-hidden-key').hide();
| |
| });
| |
| | |
| $content.find(':contains("Aset Resmi"), :contains("Terverifikasi")').each(function() {
| |
| var $this = $(this);
| |
| if ($this.children().length === 0 && ($this.text().trim() === "Aset Resmi" || $this.text().trim() === "Terverifikasi")) {
| |
| $this.addClass('mippedia-hidden-key').css('display', 'none');
| |
| } | | } |
| });
| |
| }
| |
| }
| |
| });
| |
|
| |
| /* ==========================================================
| |
| 🛡️ MIPPEDIA VERIFICATION SYSTEM v8.0 (ANTI-GAGAL)
| |
| ========================================================== */
| |
| $(document).ready(function() {
| |
| var user = mw.config.get('wgUserName');
| |
| var pageName = mw.config.get('wgPageName');
| |
| var ns = mw.config.get('wgNamespaceNumber');
| |
| var isAdmin = mw.config.get('wgUserGroups').includes('sysop');
| |
| var $content = $('#mw-content-text');
| |
|
| |
| // --- 1. AUTO-FILL TEKS (PENGGUNA) ---
| |
| if (mw.config.get('wgAction') === 'edit' && sessionStorage.getItem('mippedia_req_text')) {
| |
| var savedText = sessionStorage.getItem('mippedia_req_text');
| |
| $('#wpTextbox1').val(savedText + "\n\n**Alasan saya:** \n(Tulis alasan lo di sini, boys!) \n\n<div class='mippedia-status'>'''Status: 🕒 Sedang diajukan'''</div>\n\n--" + user);
| |
| sessionStorage.removeItem('mippedia_req_text');
| |
| }
| |
|
| |
| // --- 2. TOMBOL MINTA (HALAMAN BERKAS) ---
| |
| if (ns === 6) {
| |
| if (!$content.text().includes("Aset Resmi")) {
| |
| var $reqBtn = $('<button>').html('<span>📩</span> Minta Verifikasi').css({
| |
| 'background': '#36c', 'color': '#fff', 'border': 'none', 'padding': '5px 15px',
| |
| 'border-radius': '20px', 'font-size': '11px', 'font-weight': '800', 'cursor': 'pointer', 'margin': '10px 0'
| |
| });
| |
| $reqBtn.click(function() {
| |
| if (!user) { window.location.href = mw.util.getUrl('Istimewa:Masuk_log', { returnto: pageName }); return; }
| |
| var talkPage = "Pembicaraan_Berkas:" + mw.config.get('wgTitle');
| |
| sessionStorage.setItem('mippedia_req_text', "Halo Pengurus Mippedia,\n\nSaya memohon verifikasi untuk berkas [[:" + pageName + "]].");
| |
| window.location.href = mw.util.getUrl(talkPage, { action: 'edit', section: 'new', preloadtitle: 'Permintaan Verifikasi Berkas' });
| |
| });
| |
| setTimeout(function() { $('#firstHeading').after($reqBtn); }, 600);
| |
| }
| |
| }
| |
|
| |
| // --- 3. PANEL ADMIN & AUTOMATION (HALAMAN PEMBICARAAN) ---
| |
| if (ns === 7) {
| |
| var api = new mw.Api();
| |
| var filePage = pageName.replace('Pembicaraan_Berkas:', 'Berkas:');
| |
| var fullContent = $content.text();
| |
| var isPending = fullContent.includes("Status: 🕒 Sedang diajukan");
| |
|
| |
| // Ambil User Pengaju
| |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'user', rvlimit: 1, rvdir: 'newer' }).done(function(data) {
| |
| var pages = data.query.pages;
| |
| var requester = "";
| |
| for (var id in pages) { requester = pages[id].revisions[0].user; }
| |
|
| |
| // Tombol Coba Lagi buat Pengaju
| |
| if (fullContent.includes("Status: ❌ Ditolak") && user === requester) {
| |
| var $retryBtn = $('<button>').text('🔄 Coba Lagi').css({'background':'#36c','color':'#fff','border':'none','padding':'4px 10px','border-radius':'4px','cursor':'pointer','display':'block','margin-top':'10px'});
| |
| $retryBtn.click(function() { window.location.href = mw.util.getUrl(filePage); });
| |
| $('.mippedia-status').append($retryBtn);
| |
| } | | } |
| | }); |
|
| |
|
| // PANEL ADMIN | | function syncMetadata(title, dataCenterDesc) { |
| if (isAdmin && isPending) { | | var api = new mw.Api(); |
| var $panel = $('<div id="admin-panel" style="background:#f0f5ff; border:2px solid #36c; padding:15px; border-radius:10px; margin:15px 0;">' + | | api.get({ |
| '<div style="font-weight:bold; color:#36c; margin-bottom:10px;">🛡️ ADMIN CONTROL</div></div>');
| | action: 'query', |
| | prop: 'revisions', |
| | titles: title, |
| | rvprop: 'content', |
| | formatversion: 2 |
| | }).done(function(data) { |
| | var content = data.query.pages[0].revisions[0].content; |
| | var shortDescPattern = /\{\{SHORTDESC:.*?\}\}\n?/gi; |
| | var hasLocalDesc = shortDescPattern.test(content); |
| | | |
| var $btnApprove = $('<button>').text('✅ SETUJUI').css({'background':'#00af89','color':'#fff','border':'none','padding':'8px 15px','margin-right':'10px','cursor':'pointer'}); | | var localMatch = content.match(/\{\{SHORTDESC:(.*?)\}\}/i); |
| var $btnReject = $('<button>').text('❌ TOLAK').css({'background':'#d33','color':'#fff','border':'none','padding':'8px 15px','cursor':'pointer'});
| | var currentLocalDesc = localMatch ? localMatch[1].trim() : ""; |
| | |
| $btnApprove.click(function() {
| |
| $btnApprove.prop('disabled', true).text('Processing...');
| |
|
| |
| // STEP 1: Nulis "Aset Resmi" di Berkas
| |
| api.postWithToken('edit', { action: 'edit', title: filePage, appendtext: '\nAset Resmi', summary: 'Verifikasi Disetujui' }).done(function() {
| |
| // STEP 2: Ganti teks status di halaman diskusi
| |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content' }).done(function(res) {
| |
| var content = res.query.pages[Object.keys(res.query.pages)[0]].revisions[0]['*'];
| |
| var newText = content.replace("Status: 🕒 Sedang diajukan", "Status: ✅ '''Disetujui'''");
| |
| api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Update Status: Disetujui' }).done(function() {
| |
| // STEP 3: Kirim notif ke User
| |
| var msg = "\n== Notifikasi Verifikasi ==\nHalo [[" + requester + "]], permohonan Anda untuk [[:" + filePage + "]] telah '''DISETUJUI'''. --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 16.37 (UTC)";
| |
| api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:" + requester, section: 'new', text: msg }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| });
| |
| });
| |
| }); | |
| | |
| $btnReject.click(function() {
| |
| var alasan = prompt("Alasan penolakan:");
| |
| if (!alasan) return;
| |
| $btnReject.prop('disabled', true).text('Processing...');
| |
| | |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content' }).done(function(res) {
| |
| var content = res.query.pages[Object.keys(res.query.pages)[0]].revisions[0]['*'];
| |
| var newText = content.replace("Status: 🕒 Sedang diajukan", "Status: ❌ '''Ditolak'''\n\n''Alasan: " + alasan + "''");
| |
| api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Update Status: Ditolak' }).done(function() {
| |
| var msg = "\n== Notifikasi Verifikasi ==\nHalo [[" + requester + "]], permohonan Anda untuk [[:" + filePage + "]] '''DITOLAK''' karena: ''" + alasan + "''. --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 16.37 (UTC)";
| |
| api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:" + requester, section: 'new', text: msg }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| });
| |
| });
| |
| | |
| $panel.append($btnApprove, $btnReject);
| |
| $('#mw-content-text').prepend($panel);
| |
| }
| |
| });
| |
| }
| |
| });
| |
| | |
| /* ==========================================================
| |
| 🛡️ MIPPEDIA AUTO-PROTECTION SYSTEM (ADAPTIVE & AUTO-NOTIF)
| |
| Fitur: Request Protect, Auto-Lock, & Pesan Otomatis ke User
| |
| ========================================================== */
| |
| $(document).ready(function() {
| |
| var user = mw.config.get('wgUserName');
| |
| var pageName = mw.config.get('wgPageName');
| |
| var ns = mw.config.get('wgNamespaceNumber');
| |
| var isAdmin = mw.config.get('wgUserGroups').includes('sysop');
| |
| var $content = $('#mw-content-text');
| |
|
| |
|
| // --- 1. AUTO-FILL TEKS PERLINDUNGAN ---
| | // AKSI 1: HAPUS (Jika di pusat kosong/dihapus, tapi di artikel lokal masih ada) |
| if (mw.config.get('wgAction') === 'edit' && sessionStorage.getItem('mippedia_protect_text')) {
| | if (dataCenterDesc === "" && hasLocalDesc) { |
| var savedText = sessionStorage.getItem('mippedia_protect_text');
| | console.log("Mippedia: Purging metadata..."); |
| $('#wpTextbox1').val(savedText + "\n\n**Alasan Perlindungan:** \n(Tulis alasan kenapa berkas ini perlu dikunci, boys!) \n\n<div class='mippedia-status'>'''Status: 🕒 Sedang diajukan'''</div>\n\n--" + user);
| | saveEdit(title, content.replace(shortDescPattern, ""), "Purge out-of-sync metadata"); |
| sessionStorage.removeItem('mippedia_protect_text');
| | } |
| }
| | // AKSI 2: UPDATE/TAMBAH (Jika data di pusat ada dan beda dengan lokal) |
| | | else if (dataCenterDesc !== "" && dataCenterDesc !== currentLocalDesc) { |
| // --- 2. TOMBOL DINAMIS (DI HALAMAN BERKAS) ---
| | console.log("Mippedia: Syncing with Data Center..."); |
| if (ns === 6 && user) { // Khusus user login
| | var cleanedContent = content.replace(shortDescPattern, ""); |
| var api = new mw.Api();
| | // Menaruh di paling atas agar terbaca Extension ShortDescription |
| api.get({ action: 'query', prop: 'info', titles: pageName, inprop: 'protection' }).done(function(data) {
| | var newContent = '{{SHORTDESC:' + dataCenterDesc + '}}\n' + cleanedContent; |
| var page = data.query.pages[Object.keys(data.query.pages)[0]];
| | saveEdit(title, newContent, "Sync metadata: " + dataCenterDesc); |
| var protections = page.protection;
| |
|
| |
| var isFull = false;
| |
| var isSemi = false;
| |
| | |
| protections.forEach(function(p) {
| |
| if (p.type === 'edit') {
| |
| if (p.level === 'sysop') isFull = true;
| |
| if (p.level === 'autoconfirmed') isSemi = true; | |
| } | | } |
| }); | | }); |
| | } |
|
| |
|
| // Jika Full, tombol hilang. Jika Semi, tombol minta Penuh.
| | function saveEdit(title, text, summary) { |
| if (isFull) return;
| | // Menggunakan token user yang sedang login saat ini |
| var btnLabel = isSemi ? '🔒 Minta Perlindungan Penuh' : '🔒 Minta Perlindungan'; | | new mw.Api().postWithEditToken({ |
| var reqType = isSemi ? 'Perlindungan Penuh' : 'Perlindungan'; | | action: 'edit', |
| | | title: title, |
| var $protBtn = $('<button>').html('<span></span> ' + btnLabel).css({
| | text: text, |
| 'background': '#d33', 'color': '#fff', 'border': 'none', 'padding': '5px 15px', | | summary: '🤖 ' + summary, |
| 'border-radius': '20px', 'font-size': '11px', 'font-weight': '800', 'cursor': 'pointer', 'margin': '10px 5px' | | minor: true // Menandai sebagai suntingan kecil |
| | // Parameter 'bot: true' DIHAPUS agar bisa dijalankan semua pengguna login |
| | }).done(function() { |
| | console.log("Mippedia: " + title + " synced successfully."); |
| }); | | }); |
| | | } |
| $protBtn.click(function() {
| | }); |
| var talkPage = "Pembicaraan_Berkas:" + mw.config.get('wgTitle');
| | })(jQuery, mediaWiki); |
| sessionStorage.setItem('mippedia_protect_text', "Halo Pengurus Mippedia,\n\nSaya memohon " + reqType + " untuk berkas [[:" + pageName + "]] guna menghindari penyalahgunaan.");
| |
| window.location.href = mw.util.getUrl(talkPage, { action: 'edit', section: 'new', preloadtitle: 'Permintaan Perlindungan Berkas' });
| |
| });
| |
| | |
| setTimeout(function() { $('#firstHeading').after($protBtn); }, 650);
| |
| }); | |
| }
| |
| | |
| // --- 3. PANEL ADMIN PERLINDUNGAN (DI HALAMAN PEMBICARAAN) --- | |
| if (ns === 7) {
| |
| var api = new mw.Api();
| |
| var filePage = pageName.replace('Pembicaraan_Berkas:', 'Berkas:');
| |
| var isPending = $content.text().includes("Status: 🕒 Sedang diajukan");
| |
| | |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'user', rvlimit: 1, rvdir: 'newer' }).done(function(data) {
| |
| var pages = data.query.pages;
| |
| var requester = "";
| |
| for (var id in pages) { requester = pages[id].revisions[0].user; }
| |
| | |
| if (isAdmin && isPending && $content.text().includes("Permintaan Perlindungan")) {
| |
| var $panel = $('<div style="background:#fff0f0; border:2px solid #d33; padding:15px; border-radius:10px; margin:15px 0;">' +
| |
| '<div style="font-weight:bold; color:#d33; margin-bottom:10px;">🛡️ ADMIN PROTECTION CONTROL</div>' +
| |
| '<p style="font-size:11px;">Pilih tingkat perlindungan untuk berkas ini:</p></div>');
| |
|
| |
| var $btnSemi = $('<button>').text('SEMI-PROT').attr('title', 'Hanya user terdaftar').css({'background':'#faad14','color':'#fff','border':'none','padding':'8px 12px','margin-right':'8px','cursor':'pointer','font-weight':'bold'});
| |
| var $btnFull = $('<button>').text('FULL-PROT').attr('title', 'Hanya pengurus').css({'background':'#d33','color':'#fff','border':'none','padding':'8px 12px','margin-right':'8px','cursor':'pointer','font-weight':'bold'});
| |
| var $btnReject = $('<button>').text('TOLAK').css({'background':'#555','color':'#fff','border':'none','padding':'8px 12px','cursor':'pointer'});
| |
| | |
| // FUNGSI EKSEKUSI PROTEKSI (Tetap menjaga sistem kirim pesan otomatis ke user)
| |
| function executeProtect(level, levelName) {
| |
| var editRight = (level === 'sysop') ? 'sysop' : 'autoconfirmed';
| |
| | |
| api.postWithToken('csrf', {
| |
| action: 'protect',
| |
| title: filePage,
| |
| protections: 'edit=' + editRight + '|move=' + editRight,
| |
| expiry: 'infinite',
| |
| reason: 'Permintaan disetujui: ' + levelName
| |
| }).done(function() {
| |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content' }).done(function(res) {
| |
| var content = res.query.pages[Object.keys(res.query.pages)[0]].revisions[0]['*'];
| |
| var newText = content.replace("Status: 🕒 Sedang diajukan", "Status: ✅ '''Dilindungi (" + levelName + ")'''");
| |
|
| |
| api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Status: Protection Granted' }).done(function() {
| |
| // FITUR OTOMATIS KIRIM PESAN (TIDAK DIBUANG)
| |
| var msg = "\n== Notifikasi Perlindungan ==\nHalo [[" + requester + "]], permohonan perlindungan untuk [[:" + filePage + "]] telah '''DISETUJUI''' dengan tingkat '''" + levelName + "'''. --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 17.37 (UTC)";
| |
| api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:" + requester, section: 'new', text: msg }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| });
| |
| });
| |
| }
| |
| | |
| $btnSemi.click(function() { executeProtect('autoconfirmed', 'Semi Perlindungan'); });
| |
| $btnFull.click(function() { executeProtect('sysop', 'Perlindungan Penuh'); });
| |
| $btnReject.click(function() {
| |
| var alasan = prompt("Alasan penolakan:");
| |
| if (!alasan) return;
| |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content' }).done(function(res) {
| |
| var content = res.query.pages[Object.keys(res.query.pages)[0]].revisions[0]['*'];
| |
| var newText = content.replace("Status: 🕒 Sedang diajukan", "Status: ❌ '''Ditolak'''\n\n''Alasan: " + alasan + "''");
| |
| api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Status: Protection Rejected' }).done(function() {
| |
| // FITUR OTOMATIS KIRIM PESAN PENOLAKAN
| |
| var msg = "\n== Notifikasi Perlindungan ==\nHalo [[" + requester + "]], permohonan perlindungan untuk [[:" + filePage + "]] '''DITOLAK''' karena: ''" + alasan + "''. --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 17.37 (UTC)";
| |
| api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:" + requester, section: 'new', text: msg }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| });
| |
| });
| |
| | |
| $panel.append($btnSemi, $btnFull, $btnReject);
| |
| $('#mw-content-text').prepend($panel);
| |
| }
| |
| });
| |
| }
| |
| });
| |
|
| |
|
| /* ========================================================== | | /* ========================================================== |
| 🛡️ MIPPEDIA ARTICLE PROTECTION SYSTEM (PERFECT ALIGNMENT) | | 🚀 MIPPEDIA METADATA GUARD - RADAR SYSTEM (V5) |
| Fokus: Posisi Sejajar, Teks Tebal, & Warna Standar | | Status: Professional Messaging | Hybrid Mobile/Desktop |
| ========================================================== */ | | ========================================================== */ |
| $(document).ready(function() {
| | (function($, mw) { |
| var user = mw.config.get('wgUserName');
| | "use strict"; |
| var pageName = mw.config.get('wgPageName');
| |
| var ns = mw.config.get('wgNamespaceNumber');
| |
| var isAdmin = mw.config.get('wgUserGroups').includes('sysop');
| |
| var $content = $('#mw-content-text');
| |
| | |
| // --- 1. AUTO-FILL TEKS PERLINDUNGAN ---
| |
| if (mw.config.get('wgAction') === 'edit' && sessionStorage.getItem('mippedia_art_protect')) {
| |
| var savedText = sessionStorage.getItem('mippedia_art_protect');
| |
| $('#wpTextbox1').val(savedText + "\n\n**Alasan Perlindungan:** \n(Tulis alasan lo, boys!) \n\n<div class='mippedia-status'>'''Status: 🕒 Sedang diajukan'''</div>\n\n--" + user);
| |
| sessionStorage.removeItem('mippedia_art_protect');
| |
| }
| |
| | |
| // --- 2. TOMBOL DINAMIS (POSISI PRESISI & TEKS TEBAL) ---
| |
| if (ns === 0 && user) {
| |
| var api = new mw.Api();
| |
| api.get({ action: 'query', prop: 'info', titles: pageName, inprop: 'protection' }).done(function(data) {
| |
| var page = data.query.pages[Object.keys(data.query.pages)[0]];
| |
| var protections = page.protection;
| |
| var isFull = protections.some(p => p.type === 'edit' && p.level === 'sysop');
| |
| var isSemi = protections.some(p => p.type === 'edit' && p.level === 'autoconfirmed');
| |
| | |
| if (isFull) return;
| |
| | |
| var btnLabel = isSemi ? 'Proteksi Penuh' : 'Proteksi';
| |
| var reqType = isSemi ? 'Perlindungan Penuh' : 'Perlindungan';
| |
| | |
| // Membuat item list dengan padding supaya tidak terlalu ke kiri
| |
| var $protLink = $('<li>').attr({
| |
| 'id': 'ca-protect-request',
| |
| 'class': 'mw-list-item'
| |
| }).append(
| |
| $('<a>').attr({'href': '#', 'title': 'Minta perlindungan'}).css({
| |
| 'display': 'flex',
| |
| 'align-items': 'center',
| |
| 'padding': '6px 12px' // Memberi ruang agar tidak mepet ke kiri
| |
| }).append(
| |
| $('<span>').html('🔒 ' + btnLabel).css({
| |
| 'color': '#202122',
| |
| 'font-weight': 'bold', // Tulisan jadi tebal
| |
| 'margin-left': '2px' // Jarak halus setelah ikon
| |
| })
| |
| )
| |
| );
| |
| | |
| $protLink.click(function(e) {
| |
| e.preventDefault();
| |
| var talkPage = "Pembicaraan:" + mw.config.get('wgTitle');
| |
| sessionStorage.setItem('mippedia_art_protect', "Halo Pengurus,\n\nSaya memohon " + reqType + " untuk [[" + pageName + "]].");
| |
| window.location.href = mw.util.getUrl(talkPage, { action: 'edit', section: 'new', preloadtitle: 'Permintaan Perlindungan Artikel' });
| |
| });
| |
| | |
| // Menyisipkan ke menu
| |
| $('#p-cactions ul, #p-views ul').append($protLink);
| |
| });
| |
| }
| |
| | |
| // --- 3. PANEL ADMIN (LOGIKA BERANTAI ANTI-MACET) ---
| |
| if (ns === 1 && isAdmin && $content.text().includes("Sedang diajukan")) { | |
| var api = new mw.Api();
| |
| var articlePage = pageName.replace('Pembicaraan:', '');
| |
|
| |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'user|content', rvlimit: 1 }).done(function(res) {
| |
| var pg = res.query.pages[Object.keys(res.query.pages)[0]];
| |
| var requester = pg.revisions[0].user;
| |
| var oldContent = pg.revisions[0]['*'];
| |
| | |
| var $panel = $('<div style="background:#fff0f0; border:2px solid #d33; padding:15px; border-radius:10px; margin-bottom:15px;">' +
| |
| '<b>🛡️ ADMIN CONTROL</b><br><small>Request by: '+requester+'</small></div>');
| |
|
| |
| var $btnOk = $('<button>').text('✅ SETUJUI').css({'background':'#d33','color':'#fff','padding':'5px 12px','border':'none','cursor':'pointer','font-weight':'bold'});
| |
| var $btnNo = $('<button>').text('❌ TOLAK').css({'background':'#555','color':'#fff','padding':'5px 12px','border':'none','cursor':'pointer','margin-left':'10px'});
| |
| | |
| $btnOk.click(function() {
| |
| var level = oldContent.includes("Penuh") ? "sysop" : "autoconfirmed";
| |
| $(this).prop('disabled', true).text('Processing Step 1/3...');
| |
| | |
| api.postWithToken('csrf', {
| |
| action: 'protect', title: articlePage, protections: 'edit='+level+'|move='+level, expiry: 'infinite', reason: 'Approved'
| |
| }).then(function() {
| |
| $btnOk.text('Processing Step 2/3...');
| |
| var newText = oldContent.replace("Status: 🕒 Sedang diajukan", "Status: ✅ '''Dilindungi ("+level+")'''");
| |
| return api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Status Updated' });
| |
| }).then(function() {
| |
| $btnOk.text('Processing Step 3/3...');
| |
| var msg = "\n== Notifikasi ==\nHalo [["+requester+"]], permohonan perlindungan [["+articlePage+"]] udah disetujui, boys! --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 19.40 (UTC)";
| |
| return api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:"+requester, section: 'new', text: msg });
| |
| }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| | |
| $btnNo.click(function() {
| |
| var alasan = prompt("Alasan:");
| |
| if (!alasan) return;
| |
| $(this).prop('disabled', true).text('Rejecting...');
| |
| var newText = oldContent.replace("Status: 🕒 Sedang diajukan", "Status: ❌ '''Ditolak'''\n\nAlasan: " + alasan);
| |
| api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Rejected' }).then(function() {
| |
| var msg = "\n== Notifikasi ==\nSori [["+requester+"]], permintaan lo ditolak: " + alasan + " --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 19.40 (UTC)";
| |
| return api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:"+requester, section: 'new', text: msg });
| |
| }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| | |
| $panel.append($btnOk, $btnNo);
| |
| $('#mw-content-text').prepend($panel);
| |
| });
| |
| }
| |
| });
| |
|
| |
|
| /* ==========================================================
| |
| 🛡️ MIPPEDIA USER PAGE PROTECTION SYSTEM
| |
| Khusus Namespace Pengguna - Versi Stabil, Rapi & Otomatis
| |
| ========================================================== */
| |
| $(document).ready(function() {
| |
| var user = mw.config.get('wgUserName');
| |
| var pageName = mw.config.get('wgPageName');
| |
| var ns = mw.config.get('wgNamespaceNumber'); | | var ns = mw.config.get('wgNamespaceNumber'); |
| var isAdmin = mw.config.get('wgUserGroups').includes('sysop'); | | if (ns !== 0 || mw.config.get('wgIsMainPage')) return; |
| var $content = $('#mw-content-text');
| |
|
| |
|
| // --- 1. AUTO-FILL TEKS PERLINDUNGAN --- | | var shortDescRegex = /\{\{SHORTDESC:.*?\}\}/gi; |
| if (mw.config.get('wgAction') === 'edit' && sessionStorage.getItem('mippedia_user_protect')) {
| | var originalShortDesc = null; |
| var savedText = sessionStorage.getItem('mippedia_user_protect');
| |
| $('#wpTextbox1').val(savedText + "\n\n**Alasan Perlindungan:** \n(Tulis alasan kenapa halaman pengguna ini perlu dikunci, boys!) \n\n<div class='mippedia-status'>'''Status: 🕒 Sedang diajukan'''</div>\n\n--" + user);
| |
| sessionStorage.removeItem('mippedia_user_protect');
| |
| }
| |
|
| |
|
| // --- 2. TOMBOL DINAMIS (KHUSUS NAMESPACE PENGGUNA / NS 2) --- | | function validateAndBlock(e) { |
| if (ns === 2 && user) {
| | var $textbox = $('#wpTextbox1, textarea.previewable-render, .editor-container textarea, textarea[name="wpTextbox1"]'); |
| var api = new mw.Api(); | | if (!$textbox.length) return true; |
| api.get({ action: 'query', prop: 'info', titles: pageName, inprop: 'protection' }).done(function(data) {
| |
| var page = data.query.pages[Object.keys(data.query.pages)[0]];
| |
| var protections = page.protection;
| |
| var isFull = protections.some(p => p.type === 'edit' && p.level === 'sysop');
| |
| var isSemi = protections.some(p => p.type === 'edit' && p.level === 'autoconfirmed');
| |
|
| |
|
| if (isFull) return;
| | var currentContent = $textbox.val() || ""; |
| | var currentMatch = currentContent.match(shortDescRegex); |
| | var currentShortDesc = currentMatch ? currentMatch[0] : ""; |
|
| |
|
| var btnLabel = isSemi ? 'Proteksi Penuh' : 'Proteksi Profil'; | | if (originalShortDesc === null) { |
| var reqType = isSemi ? 'Perlindungan Penuh' : 'Perlindungan'; | | originalShortDesc = currentShortDesc; |
| | return true; |
| | } |
|
| |
|
| var $protLink = $('<li>').attr({
| | if (originalShortDesc !== currentShortDesc) { |
| 'id': 'ca-protect-user-request',
| | // --- PESAN PROFESIONAL BARU --- |
| 'class': 'mw-list-item'
| | window.alert( |
| }).append( | | "MIPPEDIA SYSTEM NOTIFICATION\n" + |
| $('<a>').attr({'href': '#', 'title': 'Minta perlindungan halaman pengguna'}).css({ | | "────────────────────────────\n\n" + |
| 'display': 'flex',
| | "Suntingan anda tidak bisa di lanjutkan untuk di terbitkan, Karena sinkronisasi otomatis terdeteksi tidak valid.\n\n" + |
| 'align-items': 'center',
| | "Untuk menjaga integritas metadata, deskripsi singkat (ShortDescription) wajib dikelola melalui repositori Mippedia Data.\n\n" + |
| 'padding': '6px 12px'
| | "Harap urungkan perubahan manual pada kode {{SHORTDESC}} untuk melanjutkan proses penyimpanan." |
| }).append( | |
| $('<span>').html('🔒 ' + btnLabel).css({
| |
| 'color': '#202122',
| |
| 'font-weight': 'bold',
| |
| 'margin-left': '2px'
| |
| })
| |
| )
| |
| ); | | ); |
|
| |
| $protLink.click(function(e) {
| |
| e.preventDefault();
| |
| // Halaman Pengguna pake Pembicaraan Pengguna: (Namespace 3)
| |
| var talkPage = "Pembicaraan_Pengguna:" + mw.config.get('wgTitle');
| |
| sessionStorage.setItem('mippedia_user_protect', "Halo Pengurus,\n\nSaya memohon " + reqType + " untuk halaman pengguna [[" + pageName + "]] guna menghindari vandalisme profil.");
| |
| window.location.href = mw.util.getUrl(talkPage, { action: 'edit', section: 'new', preloadtitle: 'Permintaan Perlindungan Halaman Pengguna' });
| |
| });
| |
|
| |
| $('#p-cactions ul, #p-views ul').append($protLink);
| |
| });
| |
| }
| |
|
| |
| // --- 3. PANEL ADMIN (HALAMAN PEMBICARAAN PENGGUNA / NS 3) ---
| |
| if (ns === 3 && isAdmin && $content.text().includes("Sedang diajukan")) {
| |
| var api = new mw.Api();
| |
| // Target perlindungan adalah halaman pengguna utamanya
| |
| var targetUserPage = "Pengguna:" + mw.config.get('wgTitle');
| |
|
| |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'user|content', rvlimit: 1 }).done(function(res) {
| |
| var pg = res.query.pages[Object.keys(res.query.pages)[0]];
| |
| var requester = pg.revisions[0].user;
| |
| var oldContent = pg.revisions[0]['*'];
| |
|
| |
| if (!$content.text().includes("Permintaan Perlindungan Halaman Pengguna")) return;
| |
|
| |
| var $panel = $('<div style="background:#fff0f0; border:2px solid #d33; padding:15px; border-radius:10px; margin-bottom:15px;">' +
| |
| '<b>🛡️ ADMIN USER-PAGE CONTROL</b><br><small>Request by: '+requester+'</small></div>');
| |
| | | |
| var $btnOk = $('<button>').text('✅ SETUJUI').css({'background':'#d33','color':'#fff','padding':'5px 12px','border':'none','cursor':'pointer','font-weight':'bold'}); | | e.preventDefault(); |
| var $btnNo = $('<button>').text('❌ TOLAK').css({'background':'#555','color':'#fff','padding':'5px 12px','border':'none','cursor':'pointer','margin-left':'10px'}); | | e.stopPropagation(); |
| | | e.stopImmediatePropagation(); |
| $btnOk.click(function() { | | return false; |
| var level = oldContent.includes("Penuh") ? "sysop" : "autoconfirmed";
| | } |
| $(this).prop('disabled', true).text('Step 1/3...');
| | return true; |
| | |
| // STEP 1: PROTEKSI
| |
| api.postWithToken('csrf', {
| |
| action: 'protect', title: targetUserPage, protections: 'edit='+level+'|move='+level, expiry: 'infinite', reason: 'User Page Protection: Approved'
| |
| }).then(function() {
| |
| // STEP 2: UPDATE STATUS
| |
| $btnOk.text('Step 2/3...');
| |
| var newText = oldContent.replace("Status: 🕒 Sedang diajukan", "Status: ✅ '''Dilindungi ("+level+")'''");
| |
| return api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Protection Status Updated' });
| |
| }).then(function() {
| |
| // STEP 3: NOTIFIKASI OTOMATIS (KE USER)
| |
| $btnOk.text('Step 3/3...');
| |
| var msg = "\n== Notifikasi Perlindungan Profil ==\nHalo [["+requester+"]], permohonan perlindungan untuk halaman pengguna lo [["+targetUserPage+"]] udah disetujui dan aktif, boys! --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 19.48 (UTC)";
| |
| return api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:"+requester, section: 'new', text: msg });
| |
| }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| | |
| $btnNo.click(function() {
| |
| var alasan = prompt("Alasan penolakan:");
| |
| if (!alasan) return;
| |
| $(this).prop('disabled', true).text('Rejecting...');
| |
| var newText = oldContent.replace("Status: 🕒 Sedang diajukan", "Status: ❌ '''Ditolak'''\n\nAlasan: " + alasan);
| |
| api.postWithToken('edit', { action: 'edit', title: pageName, text: newText, summary: 'Protection Rejected' }).then(function() {
| |
| var msg = "\n== Notifikasi ==\nHalo [["+requester+"]], permintaan perlindungan profil lo belum bisa disetujui karena: " + alasan + " --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 19.48 (UTC)";
| |
| return api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:"+requester, section: 'new', text: msg });
| |
| }).done(function() {
| |
| location.reload();
| |
| });
| |
| });
| |
| | |
| $panel.append($btnOk, $btnNo);
| |
| $('#mw-content-text').prepend($panel);
| |
| });
| |
| } | | } |
| });
| |
|
| |
| /* ==========================================================
| |
| 🔵 MIPPEDIA IRONCLAD SYSTEM V4 - FULL EDITION
| |
| Fitur: Auto-Text, Auto-Message, Auto-Status, Pop-up & Security
| |
| ========================================================== */
| |
| $(document).ready(function() {
| |
| var user = mw.config.get('wgUserName'),
| |
| pageName = mw.config.get('wgPageName'),
| |
| ns = mw.config.get('wgNamespaceNumber'),
| |
| isAdmin = mw.config.get('wgUserGroups').includes('sysop'),
| |
| api = new mw.Api();
| |
|
| |
| var vBadgeUrl = mw.config.get('wgScriptPath') + '/index.php?title=Special:Redirect/file/Verified_Badge.png';
| |
|
| |
|
| // --- 1. POP-UP TERVERIFIKASI --- | | // Radar untuk menangkap elemen editor saat muncul (terutama di Mobile) |
| function showVerifiedPopup() { | | var observer = new MutationObserver(function() { |
| var modalHtml = '<div id="mippedia-v-modal" style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.75);z-index:99999;display:flex;align-items:center;justify-content:center;">' + | | var $textbox = $('#wpTextbox1, .editor-container textarea, textarea[name="wpTextbox1"]'); |
| '<div style="background:#fff;padding:30px;border-radius:20px;width:85%;max-width:320px;text-align:center;box-shadow:0 15px 35px rgba(0,0,0,0.5);">' +
| | if ($textbox.length && originalShortDesc === null) { |
| '<img src="' + vBadgeUrl + '&width=60" style="width:60px;height:60px;margin-bottom:15px;">' +
| | var content = $textbox.val() || ""; |
| '<h2 style="margin:0 0 10px 0;color:#1a1a1a;font-size:20px;font-weight:bold;">Akun Terverifikasi</h2>' +
| | var match = content.match(shortDescRegex); |
| '<p style="color:#555;line-height:1.5;font-size:13px;margin-bottom:20px;">Mippedia telah mengonfirmasi bahwa identitas pemilik akun ini adalah asli. Lencana ini menandakan kredibilitas tinggi.</p>' +
| | originalShortDesc = match ? match[0] : ""; |
| '<button id="close-v-modal" style="background:#0095f6;color:#fff;border:none;padding:12px 0;width:100%;border-radius:10px;cursor:pointer;font-weight:bold;">Mengerti</button>' +
| |
| '</div></div>';
| |
| $('body').append(modalHtml);
| |
| $('#close-v-modal').click(function() { $('#mippedia-v-modal').remove(); }); | |
| }
| |
| | |
| // --- 2. RENDER BADGE (RIWAYAT & PROFIL) ---
| |
| api.get({ action: 'query', list: 'categorymembers', cmtitle: 'Category:Pengguna_Terverifikasi', cmlimit: 'max' }).done(function(d) {
| |
| var vUsers = d.query.categorymembers.map(function(m) { return m.title.replace('Pengguna:', ''); });
| |
| | |
| mw.hook('wikipage.content').add(function() {
| |
| $('.mw-userlink').each(function() { | |
| var name = $(this).text().trim();
| |
| if (vUsers.includes(name) && !$(this).next('.mp-v-g').length) {
| |
| $(this).after('<span class="mp-v-g" style="margin-left:3px;vertical-align:middle;display:inline-block;"><img src="' + vBadgeUrl + '&width=13" style="width:13px;height:13px;position:relative;top:-1px;"></span>');
| |
| }
| |
| }); | |
| });
| |
| | |
| if ((ns === 2 || ns === 3) && vUsers.includes(mw.config.get('wgTitle')) && !$('#firstHeading .mp-v-p').length) {
| |
| var $pBadge = $('<span class="mp-v-p" style="margin-left:6px;vertical-align:middle;display:inline-flex;cursor:pointer;"><img src="' + vBadgeUrl + '&width=20" style="width:20px;height:20px;"></span>'); | |
| $pBadge.click(showVerifiedPopup);
| |
| $('#firstHeading').append($pBadge);
| |
| } | | } |
| }); | | }); |
|
| |
|
| // --- 3. PROTEKSI KATEGORI (SATPAM NS PENGGUNA) --- | | observer.observe(document.body, { childList: true, subtree: true }); |
| if (ns === 2 && ['edit', 'submit'].includes(mw.config.get('wgAction'))) {
| |
| $('#editform').on('submit', function(e) {
| |
| var content = $('#wpTextbox1').val();
| |
| if (/\[\[Category:Pengguna_Terverifikasi\]\]/gi.test(content) && !sessionStorage.getItem('is_system_verify')) {
| |
| alert("⚠️ DITOLAK: Penambahan kategori manual dilarang!");
| |
| $('#wpTextbox1').val(content.replace(/\[\[Category:Pengguna_Terverifikasi\]\]/gi, ''));
| |
| return false;
| |
| }
| |
| });
| |
| }
| |
| | |
| // --- 4. OTOMATISASI TEKS REQUEST ---
| |
| if (mw.config.get('wgAction') === 'edit' && sessionStorage.getItem('mippedia_verify_req')) {
| |
| var reqText = sessionStorage.getItem('mippedia_verify_req');
| |
| $('#wpTextbox1').val(reqText + "\n\n**Alasan:**\n(Tulis alasan lo di sini, boys!)\n\n<div class='mippedia-status'>'''Status: 🕒 Sedang diverifikasi'''</div>\n\n--" + user);
| |
| sessionStorage.removeItem('mippedia_verify_req');
| |
| }
| |
|
| |
|
| // --- 5. TOMBOL MINTA VERIFIKASI --- | | // Event listener untuk tombol simpan di berbagai platform |
| if (ns === 2 && user && pageName.includes('Pengguna:' + user)) { | | $(document).on('click mousedown touchstart', |
| if (!$('#ca-verify-request').length) { | | '#wpSave, .mw-ui-button.primary, button.submit, .editor-save, .save-button, button[type="submit"]', |
| var $btn = $('<li>').attr('id','ca-verify-request').addClass('mw-list-item').append($('<a>').attr('href', '#').append($('<span>').text('🔵 Verifikasi').css({'color':'#0095f6','font-weight':'bold'})));
| | function(e) { |
| $btn.click(function(e) {
| | return validateAndBlock(e); |
| e.preventDefault();
| |
| sessionStorage.setItem('mippedia_verify_req', "== Permintaan Verifikasi ==\nHalo Pengurus, mohon verifikasi akun saya.");
| |
| window.location.href = mw.util.getUrl("Pembicaraan_Pengguna:" + user, { action: 'edit', section: 'new' });
| |
| });
| |
| $('#p-cactions ul, #p-views ul').append($btn); | |
| } | | } |
| } | | ); |
|
| |
|
| // --- 6. SISTEM ADMIN OTOMATIS (APPROVE & PESAN) --- | | window.addEventListener('submit', function(e) { |
| if (ns === 3 && isAdmin && $('#mw-content-text').text().includes("Sedang diverifikasi")) {
| | if (!validateAndBlock(e)) e.preventDefault(); |
| api.get({ action: 'query', prop: 'revisions', titles: pageName, rvprop: 'user|content', rvlimit: 1 }).done(function(res) { | | }, true); |
| var pg = res.query.pages[Object.keys(res.query.pages)[0]],
| |
| requester = pg.revisions[0].user,
| |
| oldContent = pg.revisions[0]['*'];
| |
|
| |
|
| var $pnl = $('<div style="background:#f0f7ff;border:2px solid #0095f6;padding:12px;border-radius:10px;margin-bottom:10px">').append('<b>🔵 ADMIN SYSTEM</b><br>');
| | })(jQuery, mediaWiki); |
| var $btnApprove = $('<button>').text('✅ APPROVE').css({'background':'#0095f6','color':'#fff','border':'none','padding':'5px 15px','cursor':'pointer','font-weight':'bold','border-radius':'4px'});
| |
|
| |
|
| $btnApprove.click(function() {
| | $(function() { |
| $(this).prop('disabled', true).text('Processing...');
| | $('.ambox-learn-more').on('click', function(e) { |
| sessionStorage.setItem('is_system_verify', 'true');
| | e.preventDefault(); |
|
| | var $parentBox = $(this).closest('.ambox'); |
| // A. Tambah Kategori ke Profil
| | |
| api.postWithToken('edit', { action: 'edit', title: "Pengguna:" + mw.config.get('wgTitle'), appendtext: '\n[[Category:Pengguna_Terverifikasi]]', summary: 'System: Verified' })
| | $parentBox.toggleClass('ambox-active'); |
| .then(function() {
| | $parentBox.find('.ambox-text-long').slideToggle('fast'); |
| // B. Update Status di Halaman Talk
| | |
| var newT = oldContent.replace("Status: 🕒 Sedang diverifikasi", "Status: ✅ '''Akun Terverifikasi''' 🔵");
| | // Ubah teks tombol pas dibuka |
| return api.postWithToken('edit', { action: 'edit', title: pageName, text: newT, summary: 'Approved' });
| | if ($parentBox.hasClass('ambox-active')) { |
| }).then(function() {
| | $(this).text('Sembunyikan'); |
| // C. Kirim Pesan Otomatis ke Wall User
| | } else { |
| var msg = "\n== Profil Terverifikasi ==\nHalo [["+requester+"]], akun Anda resmi terverifikasi dengan centang biru 🔵. --[[Pengguna:Admin|Admin]] ([[Pembicaraan Pengguna:Admin|bicara]]) 10 April 2026 21.24 (UTC)";
| | $(this).text('Pelajari selengkapnya'); |
| return api.postWithToken('edit', { action: 'edit', title: "Pembicaraan_Pengguna:" + requester, section: 'new', text: msg, summary: 'Verification Notice' });
| | } |
| }).done(function() {
| | }); |
| sessionStorage.removeItem('is_system_verify');
| |
| location.reload();
| |
| });
| |
| });
| |
| $('#mw-content-text').prepend($pnl.append($btnApprove)); | |
| }); | |
| } | |
| }); | | }); |