MediaWiki:Timeless.js
Not: Yayımladıktan sonra değişiklikleri görmeniz için tarayıcınızın önbelleğini temizlemeniz gerekebilir.
- Firefox / Safari: Shift tuşuna basılıyken Yeniden Yükle'ye tıklayın ya da Ctrl-F5 ya da Ctrl-R tıklayın (Mac için ⌘-R)
- Google Chrome: Ctrl-Shift-R'ye basın. (Mac için ⌘-Shift-R)
- Edge: Ctrl basılıyken Yenile'ye tıklayın ya da Ctrl-F5'e basın.
/* ==========================================================================
FENPEDIA SAF POPUP MODAL SİSTEMİ — PERFORMANS SÜRÜMÜ
- Timelessbalon.css dinamik enjeksiyonu kaldırıldı (CSS zaten Common.css'te).
- extractLessonMenu tek tanım + üst kapsamda (scoping hatası giderildi).
- Ağır sidebar taraması requestIdleCallback ile idle anına ertelendi.
========================================================================== */
(function () {
'use strict';
// 🟢 Ders menüsünü sidebar'dan çıkarır (TEK tanım, üst kapsam)
function extractLessonMenu() {
var $lessonMenuSource = null;
// Menüyü içeren en dış kapsayıcıyı tespit et
$('.sidebar-chunk, #mw-panel, .mw-sidebar-inner, nav, .custom-sidebar').each(function () {
var $this = $(this);
var textContent = $this.text();
if (textContent && (/Konu Anlatim/i.test(textContent) || (/Güneş/i.test(textContent) && /Dünya/i.test(textContent) && /Ay/i.test(textContent)))) {
$lessonMenuSource = $this;
return false; // İlk doğru paneli bulduğunda aramayı durdur
}
});
if ($lessonMenuSource && $lessonMenuSource.length > 0) {
var $compiledContent = $('<div></div>');
var seenHeaders = {}; // Eklenen başlıkların metinlerini tutacak nesne
$lessonMenuSource.find('h2, h3, ul').each(function () {
var $element = $(this).clone();
$element.removeAttr('class').removeAttr('id');
// Eğer element bir başlıksa (h2 veya h3)
if ($element.is('h2, h3')) {
var headerText = $.trim($element.text()).toUpperCase();
// Bu başlık metni daha önce eklendiyse pas geç (Çift başlığı engeller)
if (seenHeaders[headerText]) {
return true; // continue anlamında
}
seenHeaders[headerText] = true; // İlk kez görüldüyse listeye kaydet
}
$element.find('li, a').removeAttr('class').removeAttr('id'); // İç stilleri temizle
$compiledContent.append($element);
});
if ($compiledContent.children().length > 0) {
$('.id-lesson-content .fn-modal-body').html($compiledContent.html());
$('.btn-lesson').addClass('btn-visible');
return true;
}
}
return false;
}
// Ağır tarama başarısız olursa sidebar'ı SADECE KISA SÜRE izle (TBT düzeltmesi)
function observeForLessonMenu() {
// Fonksiyonun ilk satırı olarak ekleyin, Anasayfa ise süreci anında bitirir
if ( mw.config.get( 'wgPageName' ) === 'Anasayfa' ) { return; }
var observer = new MutationObserver(function (mutations, obs) {
if (extractLessonMenu()) {
obs.disconnect();
}
});
observer.observe(document.body, { childList: true, subtree: true });
// 🔴 YENİ: Menü bulunamazsa 3 saniye sonra gözlemciyi KESİN OLARAK kapat.
// Aksi halde sayfa kapanana kadar HER DOM mutasyonunda 4 sidebar-chunk
// .text() taraması yapılır → mobilde tekrarlayan uzun görevler → TBT piki.
setTimeout(function () {
observer.disconnect();
}, 3000);
}
// 🟢 Ağır sidebar taramasını idle anına ertele (requestIdleCallback)
function scheduleLessonMenuExtraction() {
if (window.requestIdleCallback) {
window.requestIdleCallback(function () {
if (!extractLessonMenu()) {
observeForLessonMenu();
}
}, { timeout: 2000 });
} else {
// Eski tarayıcılar için fallback: load + 500ms gecikme
$(window).on('load', function () {
setTimeout(function () {
if (!extractLessonMenu()) {
observeForLessonMenu();
}
}, 500);
});
}
}
$(function () {
var hasTOC = $('#toc').length || $('.toc').length || $('.mw-toc').length;
// Sağ alttaki dikey buton grubunu ve gizli pencereleri sayfaya bas
if ($('.fn-floating-btn-group').length === 0) {
$('body').append(
'<div class="fn-floating-btn-group">' +
' <button class="fn-floating-btn btn-lesson" type="button" title="Ünite Menüsü">📚</button>' +
' <button class="fn-floating-btn btn-toc" type="button" title="İçindekiler">📋</button>' +
'</div>' +
'<div class="fn-modal-overlay">' +
' <div class="fn-modal-content id-lesson-content"><div class="fn-modal-body"></div></div>' +
' <div class="fn-modal-content id-toc-content"><h2>İÇİNDEKİLER</h2><div class="fn-modal-body"></div></div>' +
'</div>'
);
}
// Ağır sidebar taramasını idle anına ertele
scheduleLessonMenuExtraction();
// 🔵 MAVİ BUTON KONTROLÜ: TOC içeriğini çeker
if (hasTOC) {
var $cleanTOC = $('#toc ul, .toc ul, .mw-toc ul').first().clone();
$('.id-toc-content .fn-modal-body').html($cleanTOC);
$('.btn-toc').addClass('btn-visible');
// Orijinal TOC elemanını tamamen kaldırarak boş kabuk kalmasını önler
$('#toc, .toc, .mw-toc').appendTo('.fn-toc-wrapper');
}
// 🟢 Yeşil Buton Tıklama Olayı
$(document).on('click', '.btn-lesson', function (e) {
e.stopPropagation();
$('.fn-modal-overlay').fadeIn(200);
$('.fn-modal-content').removeClass('modal-active');
$('.id-lesson-content').addClass('modal-active');
});
// 🔵 Mavi Buton Tıklama Olayı
$(document).on('click', '.btn-toc', function (e) {
e.stopPropagation();
$('.fn-modal-overlay').fadeIn(200);
$('.fn-modal-content').removeClass('modal-active');
$('.id-toc-content').addClass('modal-active');
});
// Kapatma Olayları (Dış karartıya veya normal linklere basınca)
function closeAllModals() {
$('.fn-modal-overlay').fadeOut(200);
$('.fn-modal-content').removeClass('modal-active');
}
$(document).on('click', '.fn-modal-overlay, .fn-modal-body a', function () {
closeAllModals();
});
// MediaWiki'nin tıklama engelini baypas eder
$(window).on('hashchange', function () {
closeAllModals();
});
$('.fn-modal-content').on('click', function (e) {
e.stopPropagation();
});
});
})();