Bước tới nội dung

Khác biệt giữa bản sửa đổi của “MediaWiki:Common.js”

Từ Từ nguyên Tiếng Việt
Không có tóm lược sửa đổi
Thẻ: Đã bị lùi lại
Không có tóm lược sửa đổi
Thẻ: Đã bị lùi lại
Dòng 1: Dòng 1:
// Example columns
// Optimized & Modernized Version (with your requested behaviors preserved)
function excol() {
 
     var dl = document.getElementsByTagName('dl');
const optimizeColumns = () => {
    var maxwidth = 0;
    // Example columns (excol)
    var cnt = 0;
     document.querySelectorAll('dl').forEach(dl => {
    for (var i = 0; i < dl.length; i++) {
         let maxWidth = 0;
         cnt = 0;
         const dds = dl.querySelectorAll('dd');
         var dd = dl[i].getElementsByTagName('dd');
         const containerWidth = dl.clientWidth;
         for (j = 0; j < dd.length; j++) {
 
             dd[j].style.setProperty('min-width', 'max-content');
        dds.forEach(dd => {
             dd[j].style.setProperty('column-span', 'unset');
             dd.style.setProperty('min-width', 'max-content');
             if (dd[j].clientWidth + parseFloat(window.getComputedStyle(dd[j]).marginLeft) > dl[i].clientWidth / 2) {
             dd.style.setProperty('column-span', 'unset');
                 dd[j].style.setProperty('min-width', 'calc(100% - 1.6em)');
 
                 dd[j].style.setProperty('column-span', 'all');
             const ddWidth = dd.clientWidth + parseFloat(getComputedStyle(dd).marginLeft || 0);
 
            if (ddWidth > containerWidth / 2) {
                 dd.style.setProperty('min-width', 'calc(100% - 1.6em)');
                 dd.style.setProperty('column-span', 'all');
            } else if (maxWidth < ddWidth) {
                maxWidth = ddWidth + 5;
             }
             }
             if (maxwidth < dd[j].clientWidth && dd[j].style.minWidth != 'calc(100% - 1.6em)') {
        });
                maxwidth = dd[j].clientWidth + parseFloat(window.getComputedStyle(dd[j]).marginLeft) + 5;
 
             }
        const count = dds.length;
        console.log(maxwidth);
        if (count >= 6) {
         cnt++;
             if (maxWidth * 3 < containerWidth) dl.style.columnCount = 3;
            else if (maxWidth * 2 < containerWidth) dl.style.columnCount = 2;
             else dl.style.columnCount = 1;
         } else {
            dl.style.columnCount = 1;
         }
         }
         if (cnt >= 6 && maxwidth * 3 < dl[i].clientWidth) {
    });
             dl[i].style.columns = 3
 
         } else if (cnt >= 6 && maxwidth * 2 < dl[i].clientWidth && maxwidth * 3 > dl[i].clientWidth) {
    // Cognates columns
             dl[i].style.columns = 2
    document.querySelectorAll('.cognates ul').forEach(ul => {
        const lis = ul.querySelectorAll('li');
         if (!lis.length) return;
 
        let widestWidth = 0;
        lis.forEach(li => widestWidth = Math.max(widestWidth, li.clientWidth));
 
        const refText = document.querySelector('.cognates .reference-text');
        if (!refText) return;
 
        const refOl = refText.querySelector('ol');
        const marginLeft = refOl ? parseFloat(getComputedStyle(refOl).marginLeft || 0) : 0;
        const containerWidth = refText.clientWidth;
        const itemWidth = widestWidth + marginLeft + 10;
 
        if (lis.length > 7 && containerWidth > itemWidth * 3) {
             ul.style.columnCount = 3;
         } else if (lis.length > 4 && containerWidth > itemWidth * 2) {
             ul.style.columnCount = 2;
         } else {
         } else {
             dl[i].style.columns = 1
             ul.style.columnCount = 1;
         }  
        }
    });
};
 
// Wikipedia links
const cleanWikiLinks = () => {
    document.querySelectorAll('.extiw').forEach(link => {
        link.title = link.title.replace('wikipedia:vi:', '');
    });
};
 
// Keyboard shortcuts
const setupShortcuts = () => {
    document.addEventListener('keydown', e => {
        const isMac = navigator.platform.includes('Mac');
        if (!(isMac ? e.metaKey : e.ctrlKey)) return;
 
        const map = {
            's': '[value="Save changes"]',
            'p': '[value="Show preview"]',
            'e': 'a[accesskey="e"]',
            'r': 'input[accesskey="r"]',
            'g': 'input[accesskey="g"]'
        };
 
        const selector = map[e.key];
        if (selector) {
            e.preventDefault();
            var el = document.querySelector(selector);
            if (el) el.click();
        }
    });
};
 
// Clean citations
const cleanCitations = () => {
    const citerefs = document.querySelectorAll('[id^="cite_ref-"]');
    citerefs.forEach(ref => {
        if (ref.childNodes[0] && ref.childNodes[0].textContent === ' ') {
            ref.childNodes[0].textContent = '';
        }
    });
 
    if (citerefs.length) {
        const parent = citerefs[0].parentElement;
        if (parent) {
            parent.innerHTML = parent.innerHTML.replaceAll(' <sup id="cite_ref-', '<sup id="cite_ref-');
         }
     }
     }
}
};
 
// Line-break arrows - Preserved original fallback entries[0] case
const processEntryArrows = () => {
    if (window.location.href.search('index.php') >= 0 || window.location.href.lastIndexOf(':') !== 5) return;
 
    var ol = document.querySelector('ol');
    const entries = ol ? ol.querySelectorAll('li') : null;
    if (!entries) return;
 
    entries.forEach((entryEl, i) => {
        if (!entryEl.innerHTML.includes('> →')) return;
 
        const parts = entryEl.innerHTML.split('> →');
        let newHTML = parts[0] + 'b>';
        let didFallback = false;  // FIX: flag to track if entries[0] fallback was used
 
        for (let j = 1; j < parts.length; j++) {
            if (j < parts.length - 1) {
                newHTML += `<br><span style="display:inline-block;margin-left:calc(${j+1}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${parts[j]}</span>`;
            } else {
                // Last part - keep original fallback logic
                if (parts[j].search('dl') > -1) {
                    const beforeDl = parts[j].split('<dl')[0];
                    const lastSpaceIdx = beforeDl.lastIndexOf(' ');
                    const textBefore = beforeDl.slice(0, lastSpaceIdx);
                    const lastWord = beforeDl.slice(lastSpaceIdx + 1);


// Cognates columns
                    newHTML += `<br><span style="display:inline-block;margin-left:calc(${parts.length}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${textBefore}&nbsp;${lastWord}</span><dl${parts[j].split('<dl')[1]}`;
function cogcol() {
                } else if (parts[j].slice(parts[j].lastIndexOf(' ') - 2, parts[j].lastIndexOf(' ')) !== '<a') {
    var cognates = document.querySelectorAll('.cognates ul');
                    const lastSpace = parts[j].lastIndexOf(' ');
    for (var c = 0; c < cognates.length; c++) {
                    newHTML += `<br><span style="display:inline-block;margin-left:calc(${parts.length}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${parts[j].slice(0, lastSpace)}&nbsp;${parts[j].slice(lastSpace + 1)}</span>`;
        var widest = null;
                 } else {
        var widestwidth = 0;
                    // Original fallback: append to first entry
        var coglis = cognates[c].querySelectorAll('li');
                    entries[0].innerHTML += `<br><span style="display:inline-block;margin-left:calc(${parts.length}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${parts[j]}`;
        for (var l = 0; l < coglis.length; l++) {
                    didFallback = true; // FIX: mark that we used the fallback
            if (widest == null) {
                }
                widestwidth = coglis[l].clientWidth;
                 widest = l;
            } else if (widestwidth < coglis[l].clientWidth) {
                widestwidth = coglis[l].clientWidth;
                widest = l;
             }
             }
         }
         }


         if (document.querySelector('.cognates .reference-text').clientWidth > (widestwidth + parseFloat(window.getComputedStyle(document.querySelector('.reference-text ol'))['marginLeft'])) * 3 + 10 && cognates[c].querySelectorAll('li').length > 7) {
         // FIX: only overwrite innerHTML if we didn't use the entries[0] fallback
            cognates[c].style.columnCount = 3;
         if (!didFallback) {
         } else if (document.querySelector('.cognates .reference-text').clientWidth > (widestwidth + parseFloat(window.getComputedStyle(document.querySelector('.reference-text ol'))['marginLeft'])) * 2 + 10 && cognates[c].querySelectorAll('li').length > 4) {
             entryEl.innerHTML = newHTML;
             cognates[c].style.columnCount = 2;
        } else {
            cognates[c].style.columnCount = 1;
         }
         }
     }
     });
}
};
excol();
 
cogcol();
// Video zoom
window.addEventListener('resize', () => {
const setupVideoZoom = () => {
    cogcol();
    const zoombtns = document.getElementsByClassName('enlarge');
    excol();
    const videos = document.querySelectorAll('[title="Play video"]');
})
 
    const resizeVideo = (index, multiply) => {
        const vid = videos[index];
        if (!vid) return;
 
        vid.width *= multiply;
        vid.height *= multiply;
 
        const w = vid.width + 'px';
        const h = vid.height + 'px';


if (document.querySelector('.notelistalpha') != null && document.querySelector('.notelistalpha').childElementCount < 2) { document.querySelector('.notelistalpha').style.visibility = 'hidden' };
        vid.style.width = w; vid.style.height = h;


// Wikipedia links
        let parent = vid.parentElement;
var wlinks = document.getElementsByClassName('extiw');
        while (parent && parent !== document.body) {
for (var i = 0; i < wlinks.length; i++) {
            parent.style.width = w;
    wlinks[i].title = wlinks[i].title.replace('wikipedia:vi:', '')
            parent.style.height = h;
}
            parent = parent.parentElement;
        }


// CTRL + shortcuts
        const btn = zoombtns[index];
document.addEventListener("keydown", function(e) {
        if (btn) {
    if (e.key === 's' && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
            const isEnlarge = multiply > 1;
        e.preventDefault();
            btn.onclick = () => resizeVideo(index, isEnlarge ? 0.5 : 2);
        document.querySelector('[value="Save changes"]').click();
            btn.title = isEnlarge ? 'Thu nhỏ' : 'Phóng to';
        }
     };
     };
     if (e.key === 'p' && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
 
         e.preventDefault();
     Array.from(zoombtns).forEach((btn, i) => {
        document.querySelector('[value="Show preview"]').click();
        btn.onclick = () => resizeVideo(i, 2);
        btn.title = 'Phóng to';
    });
};
 
// Zoomed text
// FIX: wrap HTMLCollection with Array.from() before calling .forEach()
const setupZoomText = () => {
    const wrapClass = (className) => {
         Array.from(document.getElementsByClassName(className)).forEach(el => {
            const html = el.innerHTML;
            el.innerHTML = `<div class="tttext">${html}<span class="ttzoom"> ${html}</span></div>`;
        });
     };
     };
    if (e.key === 'e' && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
        e.preventDefault();
        document.querySelector('a[accesskey="e"]').click();
    };
    if (e.key === 'r' && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
        e.preventDefault();
        document.querySelector('input[accesskey="r"]').click();
    };
    if (e.key === 'g' && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
        e.preventDefault();
        document.querySelector('input[accesskey="g"]').click();
    };
}, false);


// Remove space before citation
    wrapClass('Hani');
var citerefs = document.querySelectorAll('[id^="cite_ref-"]');
    wrapClass('notHani');
if (citerefs.length > 0) {
 
     for (var i = 0; i < citerefs.length; i++) {
     document.querySelectorAll('.ttzoom').forEach(span => {
         if (citerefs[i].childNodes[0].textContent == ' ') {
         if (span.getBoundingClientRect().right + 20 > window.innerWidth) {
             citerefs[i].childNodes[0].textContent = '';
             span.style.left = '-800%';
         }
         }
    });
};
// Hide empty ruby
const hideEmptyRuby = () => {
    document.querySelectorAll('rt').forEach(rt => {
        if (rt.innerText.trim() === '') rt.style.display = 'none';
    });
};
// Replace textimg - original i++ behavior preserved (skips every other element)
const setTextImgPlaceholders = () => {
    const textimg = document.querySelectorAll('[class*="textimg"]');
    for (let i = 0; i < textimg.length; i++) {
        const img = textimg[i].querySelector('img');
        if (img) img.src = 'https://www.tunguyentiengviet.com/images/4/47/Placeholder.png';
        i++;  // original manual i++ kept exactly as requested
     }
     }
    citerefs[0].parentElement.innerHTML = citerefs[0].parentElement.innerHTML.replaceAll(' <sup id="cite_ref-', '<sup id="cite_ref-');
};
}


// Line-break arrows
// Highlight entry
var entries = '';
const highlightEntry = () => {
if (window.location.href.search('index.php') < 0 && window.location.href.lastIndexOf(':') == 5) {
    if (window.location.href.includes('#entry')) {
    entries = document.querySelector('ol').querySelectorAll('li');
        const id = window.location.href.substring(window.location.href.indexOf('#') + 1);
    for (i = 0; i < entries.length; i++) {
        const el = document.getElementById(id);
        if (entries[i].innerHTML.match(/> →/g) != null) {
        if (el && el.parentElement) {
            var entry = entries[i].innerHTML.split('> →');
            el.parentElement.style.background = 'rgba(255,222,100,0.4)';
            entries[i].innerHTML = '';
            entries[i].innerHTML += entry[0] + 'b>';
            for (j = 1; j < entry.length - 1; j++) {
                entries[i].innerHTML += '<br><span style="display:inline-block;margin-left:calc(' + (j + 1) + 'em + 0.5ch);text-indent: calc(-1em - 0.5ch)">' + '<arrow>↳ </arrow>' + entry[j] + '></span>';
            }
            if (entry[entry.length - 1].search('dl') > -1 && entry[entry.length - 1].split('<dl')[0].slice(0, entry[entry.length - 1].split('<dl')[0].lastIndexOf(' ')).slice(entry[entry.length - 1].split('<dl')[0].slice(0, entry[entry.length - 1].split('<dl')[0].lastIndexOf(' ')).length - 2) != '<a') {
                entries[i].innerHTML += '<br><span style="display:inline-block;margin-left:calc(' + entry.length + 'em + 0.5ch);text-indent: calc(-1em - 0.5ch)">' + '<arrow>↳ </arrow>' + entry[entry.length - 1].split('<dl')[0].slice(0, entry[entry.length - 1].split('<dl')[0].lastIndexOf(' ')) + '&nbsp;' + entry[entry.length - 1].split('<dl')[0].slice(entry[entry.length - 1].split('<dl')[0].lastIndexOf(' ') + 1) + '</span><dl' + entry[entry.length - 1].split('<dl')[1];
            } else if (entry[entry.length - 1].slice(entry[entry.length - 1].lastIndexOf(' ') - 2, entry[entry.length - 1].lastIndexOf(' ')) != '<a') {
                entries[i].innerHTML += '<br><span style="display:inline-block;margin-left:calc(' + entry.length + 'em + 0.5ch);text-indent: calc(-1em - 0.5ch)">' + '<arrow>↳ </arrow>' + entry[entry.length - 1].slice(0, entry[entry.length - 1].lastIndexOf(' ')) + '&nbsp;' + entry[entry.length - 1].slice(entry[entry.length - 1].lastIndexOf(' ') + 1) + '</span>';
            } else {
                entries[0].innerHTML += '<br><span style="display:inline-block;margin-left:calc(' + entry.length + 'em + 0.5ch);text-indent: calc(-1em - 0.5ch)">' + '<arrow>↳ </arrow>' + entry[entry.length - 1]
            }
         }
         }
     }
     }
}
};
// Remove double spaces & replace Word Connectors * replace → arrow
if (window.location.href.indexOf('MediaWiki') == -1) {
    document.getElementById('mw-content-text').innerHTML = document.getElementById('mw-content-text').innerHTML.replaceAll('  ', ' ');
}
if (window.location.href.indexOf('index') == -1) {
    document.getElementById('mw-content-text').innerHTML = document.getElementById('mw-content-text').innerHTML.replaceAll(' &gt; ', '<con> &gt; </con>').replaceAll(' ~ ', '<con> ~ </con>');
}


// Zoom Videos
// Main init
var zoombtn = document.getElementsByClassName("enlarge");
const init = () => {
for (var i = 0; i < zoombtn.length; i++) {
    optimizeColumns();
     zoombtn[i].setAttribute("onclick", "enlarge(" + i + ")");
    cleanWikiLinks();
     zoombtn[i].setAttribute("title", "Phóng to");
    setupShortcuts();
}
    cleanCitations();
var video = document.querySelectorAll('[title="Play video"]');
     processEntryArrows();
    setupVideoZoom();
    setupZoomText();
     hideEmptyRuby();
    setTextImgPlaceholders();
    highlightEntry();


function enlarge(vid) {
     // Empty notelistalpha
    video[vid].width *= 2;
     const notelist = document.querySelector('.notelistalpha');
    video[vid].height *= 2;
     if (notelist && notelist.childElementCount < 2) {
    video[vid].style.setProperty("height", video[vid].height + "px");
         notelist.style.visibility = 'hidden';
    video[vid].style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.style.setProperty("height", video[vid].height + "px");
    video[vid].parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
    zoombtn[vid].setAttribute("onclick", "smaller(" + vid + ")");
    zoombtn[vid].setAttribute("title", "Thu nhỏ");
}
 
function smaller(vid) {
     video[vid].width /= 2;
    video[vid].height /= 2;
    video[vid].style.setProperty("height", video[vid].height + "px");
    video[vid].style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.style.setProperty("height", video[vid].height + "px");
    video[vid].parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
    video[vid].parentElement.parentElement.parentElement.style.setProperty("width", video[vid].width + "px");
     zoombtn[vid].setAttribute("onclick", "enlarge(" + vid + ")");
    zoombtn[vid].setAttribute("title", "Thu nhỏ");
}
// Display zoomed text
var ht = document.getElementsByClassName('Hani');
if (ht.length > 0) {
    for (var i = 0; i < ht.length; i++) {
        ht[i].innerHTML = '<div class="tttext">' + ht[i].innerHTML + '<span class="ttzoom"> ' + ht[i].innerHTML + '</span></div>';
     }
}
var hc = document.getElementsByClassName('notHani');
if (hc.length > 0) {
    for (var i = 0; i < hc.length; i++) {
         hc[i].innerHTML = '<div class="tttext">' + hc[i].innerHTML + '<span class="ttzoom"> ' + hc[i].innerHTML + '</span></div>';
     }
     }
}


// Zoomed text to left if overflow
    // Global replaces
var ttzoom = document.querySelectorAll('.ttzoom')
    const content = document.getElementById('mw-content-text');
for (tt = 0; tt < ttzoom.length; tt++) {
    if (content) {
    if (ttzoom[tt].getBoundingClientRect().right + 20 > window.innerWidth) {
        if (window.location.href.indexOf('MediaWiki') === -1) {
        ttzoom[tt].style.left = '-800%'
            content.innerHTML = content.innerHTML.replaceAll('  ', ' ');
        }
        if (window.location.href.indexOf('index') === -1) {
            content.innerHTML = content.innerHTML
                .replaceAll(' &gt; ', '<con> &gt; </con>')
                .replaceAll(' ~ ', '<con> ~ </con>');
        }
     }
     }
}
// Hide empty ruby text
var rt = document.getElementsByTagName('rt');
if (rt.length > 0) {
    for (var i = 0; i < rt.length; i++) {
        if (rt[i].innerText == '') { rt[i].style.display = 'none' };
    }
}


    // Debounced resize
    let timeout;
    window.addEventListener('resize', () => {
        clearTimeout(timeout);
        timeout = setTimeout(optimizeColumns, 120);
    });
};


// Replace textimg
if (document.readyState === 'loading') {
var textimg = document.querySelectorAll('[class*="textimg"]');
     document.addEventListener('DOMContentLoaded', init);
if (textimg.length > 0) {
} else {
     for (var i = 0; i < textimg.length; i++) {
     init();
        textimg[i].querySelector('img').src = 'https://www.tunguyentiengviet.com/images/4/47/Placeholder.png';
        i++;
     }
}
}


// Highlight entry
document.querySelectorAll('.timedmediaplayer').forEach(el => el.classList.remove('notheme'));
if (window.location.href.includes('#entry')) {
    document.getElementById(window.location.href.substring(window.location.href.indexOf('#')+1,window.location.href.length)).parentElement.style.background = "rgba(255,222,100,0.4)"
}

Phiên bản lúc 22:52, ngày 25 tháng 4 năm 2026

// Optimized & Modernized Version (with your requested behaviors preserved)

const optimizeColumns = () => {
    // Example columns (excol)
    document.querySelectorAll('dl').forEach(dl => {
        let maxWidth = 0;
        const dds = dl.querySelectorAll('dd');
        const containerWidth = dl.clientWidth;

        dds.forEach(dd => {
            dd.style.setProperty('min-width', 'max-content');
            dd.style.setProperty('column-span', 'unset');

            const ddWidth = dd.clientWidth + parseFloat(getComputedStyle(dd).marginLeft || 0);

            if (ddWidth > containerWidth / 2) {
                dd.style.setProperty('min-width', 'calc(100% - 1.6em)');
                dd.style.setProperty('column-span', 'all');
            } else if (maxWidth < ddWidth) {
                maxWidth = ddWidth + 5;
            }
        });

        const count = dds.length;
        if (count >= 6) {
            if (maxWidth * 3 < containerWidth) dl.style.columnCount = 3;
            else if (maxWidth * 2 < containerWidth) dl.style.columnCount = 2;
            else dl.style.columnCount = 1;
        } else {
            dl.style.columnCount = 1;
        }
    });

    // Cognates columns
    document.querySelectorAll('.cognates ul').forEach(ul => {
        const lis = ul.querySelectorAll('li');
        if (!lis.length) return;

        let widestWidth = 0;
        lis.forEach(li => widestWidth = Math.max(widestWidth, li.clientWidth));

        const refText = document.querySelector('.cognates .reference-text');
        if (!refText) return;

        const refOl = refText.querySelector('ol');
        const marginLeft = refOl ? parseFloat(getComputedStyle(refOl).marginLeft || 0) : 0;
        const containerWidth = refText.clientWidth;
        const itemWidth = widestWidth + marginLeft + 10;

        if (lis.length > 7 && containerWidth > itemWidth * 3) {
            ul.style.columnCount = 3;
        } else if (lis.length > 4 && containerWidth > itemWidth * 2) {
            ul.style.columnCount = 2;
        } else {
            ul.style.columnCount = 1;
        }
    });
};

// Wikipedia links
const cleanWikiLinks = () => {
    document.querySelectorAll('.extiw').forEach(link => {
        link.title = link.title.replace('wikipedia:vi:', '');
    });
};

// Keyboard shortcuts
const setupShortcuts = () => {
    document.addEventListener('keydown', e => {
        const isMac = navigator.platform.includes('Mac');
        if (!(isMac ? e.metaKey : e.ctrlKey)) return;

        const map = {
            's': '[value="Save changes"]',
            'p': '[value="Show preview"]',
            'e': 'a[accesskey="e"]',
            'r': 'input[accesskey="r"]',
            'g': 'input[accesskey="g"]'
        };

        const selector = map[e.key];
        if (selector) {
            e.preventDefault();
            var el = document.querySelector(selector);
            if (el) el.click();
        }
    });
};

// Clean citations
const cleanCitations = () => {
    const citerefs = document.querySelectorAll('[id^="cite_ref-"]');
    citerefs.forEach(ref => {
        if (ref.childNodes[0] && ref.childNodes[0].textContent === ' ') {
            ref.childNodes[0].textContent = '';
        }
    });

    if (citerefs.length) {
        const parent = citerefs[0].parentElement;
        if (parent) {
            parent.innerHTML = parent.innerHTML.replaceAll(' <sup id="cite_ref-', '<sup id="cite_ref-');
        }
    }
};

// Line-break arrows - Preserved original fallback entries[0] case
const processEntryArrows = () => {
    if (window.location.href.search('index.php') >= 0 || window.location.href.lastIndexOf(':') !== 5) return;

    var ol = document.querySelector('ol');
    const entries = ol ? ol.querySelectorAll('li') : null;
    if (!entries) return;

    entries.forEach((entryEl, i) => {
        if (!entryEl.innerHTML.includes('> →')) return;

        const parts = entryEl.innerHTML.split('> →');
        let newHTML = parts[0] + 'b>';
        let didFallback = false;  // FIX: flag to track if entries[0] fallback was used

        for (let j = 1; j < parts.length; j++) {
            if (j < parts.length - 1) {
                newHTML += `<br><span style="display:inline-block;margin-left:calc(${j+1}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${parts[j]}</span>`;
            } else {
                // Last part - keep original fallback logic
                if (parts[j].search('dl') > -1) {
                    const beforeDl = parts[j].split('<dl')[0];
                    const lastSpaceIdx = beforeDl.lastIndexOf(' ');
                    const textBefore = beforeDl.slice(0, lastSpaceIdx);
                    const lastWord = beforeDl.slice(lastSpaceIdx + 1);

                    newHTML += `<br><span style="display:inline-block;margin-left:calc(${parts.length}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${textBefore}&nbsp;${lastWord}</span><dl${parts[j].split('<dl')[1]}`;
                } else if (parts[j].slice(parts[j].lastIndexOf(' ') - 2, parts[j].lastIndexOf(' ')) !== '<a') {
                    const lastSpace = parts[j].lastIndexOf(' ');
                    newHTML += `<br><span style="display:inline-block;margin-left:calc(${parts.length}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${parts[j].slice(0, lastSpace)}&nbsp;${parts[j].slice(lastSpace + 1)}</span>`;
                } else {
                    // Original fallback: append to first entry
                    entries[0].innerHTML += `<br><span style="display:inline-block;margin-left:calc(${parts.length}em + 0.5ch);text-indent:calc(-1em - 0.5ch)"><arrow>↳ </arrow>${parts[j]}`;
                    didFallback = true;  // FIX: mark that we used the fallback
                }
            }
        }

        // FIX: only overwrite innerHTML if we didn't use the entries[0] fallback
        if (!didFallback) {
            entryEl.innerHTML = newHTML;
        }
    });
};

// Video zoom
const setupVideoZoom = () => {
    const zoombtns = document.getElementsByClassName('enlarge');
    const videos = document.querySelectorAll('[title="Play video"]');

    const resizeVideo = (index, multiply) => {
        const vid = videos[index];
        if (!vid) return;

        vid.width *= multiply;
        vid.height *= multiply;

        const w = vid.width + 'px';
        const h = vid.height + 'px';

        vid.style.width = w; vid.style.height = h;

        let parent = vid.parentElement;
        while (parent && parent !== document.body) {
            parent.style.width = w;
            parent.style.height = h;
            parent = parent.parentElement;
        }

        const btn = zoombtns[index];
        if (btn) {
            const isEnlarge = multiply > 1;
            btn.onclick = () => resizeVideo(index, isEnlarge ? 0.5 : 2);
            btn.title = isEnlarge ? 'Thu nhỏ' : 'Phóng to';
        }
    };

    Array.from(zoombtns).forEach((btn, i) => {
        btn.onclick = () => resizeVideo(i, 2);
        btn.title = 'Phóng to';
    });
};

// Zoomed text
// FIX: wrap HTMLCollection with Array.from() before calling .forEach()
const setupZoomText = () => {
    const wrapClass = (className) => {
        Array.from(document.getElementsByClassName(className)).forEach(el => {
            const html = el.innerHTML;
            el.innerHTML = `<div class="tttext">${html}<span class="ttzoom"> ${html}</span></div>`;
        });
    };

    wrapClass('Hani');
    wrapClass('notHani');

    document.querySelectorAll('.ttzoom').forEach(span => {
        if (span.getBoundingClientRect().right + 20 > window.innerWidth) {
            span.style.left = '-800%';
        }
    });
};

// Hide empty ruby
const hideEmptyRuby = () => {
    document.querySelectorAll('rt').forEach(rt => {
        if (rt.innerText.trim() === '') rt.style.display = 'none';
    });
};

// Replace textimg - original i++ behavior preserved (skips every other element)
const setTextImgPlaceholders = () => {
    const textimg = document.querySelectorAll('[class*="textimg"]');
    for (let i = 0; i < textimg.length; i++) {
        const img = textimg[i].querySelector('img');
        if (img) img.src = 'https://www.tunguyentiengviet.com/images/4/47/Placeholder.png';
        i++;   // original manual i++ kept exactly as requested
    }
};

// Highlight entry
const highlightEntry = () => {
    if (window.location.href.includes('#entry')) {
        const id = window.location.href.substring(window.location.href.indexOf('#') + 1);
        const el = document.getElementById(id);
        if (el && el.parentElement) {
            el.parentElement.style.background = 'rgba(255,222,100,0.4)';
        }
    }
};

// Main init
const init = () => {
    optimizeColumns();
    cleanWikiLinks();
    setupShortcuts();
    cleanCitations();
    processEntryArrows();
    setupVideoZoom();
    setupZoomText();
    hideEmptyRuby();
    setTextImgPlaceholders();
    highlightEntry();

    // Empty notelistalpha
    const notelist = document.querySelector('.notelistalpha');
    if (notelist && notelist.childElementCount < 2) {
        notelist.style.visibility = 'hidden';
    }

    // Global replaces
    const content = document.getElementById('mw-content-text');
    if (content) {
        if (window.location.href.indexOf('MediaWiki') === -1) {
            content.innerHTML = content.innerHTML.replaceAll('  ', ' ');
        }
        if (window.location.href.indexOf('index') === -1) {
            content.innerHTML = content.innerHTML
                .replaceAll(' &gt; ', '<con> &gt; </con>')
                .replaceAll(' ~ ', '<con> ~ </con>');
        }
    }

    // Debounced resize
    let timeout;
    window.addEventListener('resize', () => {
        clearTimeout(timeout);
        timeout = setTimeout(optimizeColumns, 120);
    });
};

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
} else {
    init();
}

document.querySelectorAll('.timedmediaplayer').forEach(el => el.classList.remove('notheme'));