User:Polygnotus/DuplicateReferences.js

This is an old revision of this page, as edited by Polygnotus (talk | contribs) at 23:34, 15 July 2024. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
mw.loader.using(['mediawiki.util'], function () {
    $(document).ready(function () {
        if ((mw.config.get('wgNamespaceNumber') !== 0 && mw.config.get('wgPageName') !== 'User:Polygnotus/dupreftest') || mw.config.get('wgAction') !== 'view') {
            return;
        }
        
        let referencesHeading = document.getElementById("References");
        if (!referencesHeading) {
            return;
        }
        
        const style = document.createElement('style');
        style.textContent = `
            li:target { border: 1px dotted red; padding: 2px; background-color: #ffcccc !important;}
            .duplicate-citation-highlight { background-color: #ffe6e6; }
            .duplicate-citation-hover { background-color: #ffcccc; }
            .duplicate-citation-clicked { border: 1px dotted red; padding: 2px; background-color: #ffe6e6; }
            .grouped-references { margin-left: 20px; }
            .grouped-references-toggle { cursor: pointer; color: blue; }
            .grouped-references-content { display: none; }
            .grouped-references-content.expanded { display: block; }
        `;
        document.head.appendChild(style);
        
        let parentDiv = referencesHeading.closest("div");
        let newParagraph = document.createElement("p");
        newParagraph.style.color = "red";
        
        function addDuplicateCitationsTemplate() {
            // ... (unchanged)
        }

        function getDuplicateInfo() {
            // ... (unchanged)
        }

        function calculateSimilarity(str1, str2) {
            // ... (unchanged)
        }

        function editDistance(s1, s2) {
            // ... (unchanged)
        }

        function getAllVisibleText(element) {
            // ... (unchanged)
        }

        function extractVisibleText(htmlString) {
            // ... (unchanged)
        }

        function checkDuplicateReferenceLinks() {
            const referenceSpans = document.querySelectorAll('span.reference-text');
            const urlMap = new Map();
            const duplicates = new Map();
            const contentMap = new Map();
            let totalLinks = 0;
            
            // Create a map of cite_note ids to their correct reference numbers
            const citeNoteMap = new Map();
            document.querySelectorAll('.reference').forEach(ref => {
                const link = ref.querySelector('a');
                if (link) {
                    const linkHref = link.getAttribute('href');
                    if (linkHref) {
                        const citeNoteId = linkHref.substring(1);  // Remove the leading '#'
                        const refNumber = citeNoteId.split('-').pop();
                        citeNoteMap.set(citeNoteId, refNumber);
                    }
                }
            });
            
            referenceSpans.forEach((span) => {
                // ... (unchanged code for processing each reference)
            });
            
            if (duplicates.size > 0 || Array.from(contentMap.values()).some(group => group.length > 1)) {
                if (document.querySelector('table.box-Duplicated_citations') === null) {
                    // ... (unchanged code for adding the template link)
                }
                
                // Group and collapse duplicate references
                groupAndCollapseDuplicates(duplicates, contentMap);
                
                // Display information about duplicates
                displayDuplicateInfo(duplicates, contentMap);
                
                parentDiv.after(newParagraph);
            }
        }
        
        function groupAndCollapseDuplicates(duplicates, contentMap) {
            const referencesSection = document.querySelector('ol.references');
            if (!referencesSection) return;
            
            // Process URL-based duplicates
            duplicates.forEach((refInfo, url) => {
                if (refInfo.length > 1) {
                    const groupContainer = document.createElement('li');
                    groupContainer.className = 'grouped-references';
                    const toggle = document.createElement('span');
                    toggle.className = 'grouped-references-toggle';
                    toggle.textContent = `[+] ${refInfo.length} references to ${url}`;
                    groupContainer.appendChild(toggle);
                    
                    const content = document.createElement('ol');
                    content.className = 'grouped-references-content';
                    refInfo.forEach(ref => {
                        const originalRef = document.getElementById(ref.citeNote);
                        if (originalRef) {
                            content.appendChild(originalRef.cloneNode(true));
                            originalRef.remove();
                        }
                    });
                    groupContainer.appendChild(content);
                    
                    toggle.addEventListener('click', () => {
                        content.classList.toggle('expanded');
                        toggle.textContent = content.classList.contains('expanded') ?
                            `[-] ${refInfo.length} references to ${url}` :
                            `[+] ${refInfo.length} references to ${url}`;
                    });
                    
                    referencesSection.appendChild(groupContainer);
                }
            });
            
            // Process content-based duplicates
            contentMap.forEach((group, content) => {
                if (group.length > 1) {
                    const groupContainer = document.createElement('li');
                    groupContainer.className = 'grouped-references';
                    const toggle = document.createElement('span');
                    toggle.className = 'grouped-references-toggle';
                    toggle.textContent = `[+] ${group.length} similar references`;
                    groupContainer.appendChild(toggle);
                    
                    const contentDiv = document.createElement('ol');
                    contentDiv.className = 'grouped-references-content';
                    group.forEach(ref => {
                        const originalRef = document.getElementById(ref.citeNote);
                        if (originalRef) {
                            contentDiv.appendChild(originalRef.cloneNode(true));
                            originalRef.remove();
                        }
                    });
                    groupContainer.appendChild(contentDiv);
                    
                    toggle.addEventListener('click', () => {
                        contentDiv.classList.toggle('expanded');
                        toggle.textContent = contentDiv.classList.contains('expanded') ?
                            `[-] ${group.length} similar references` :
                            `[+] ${group.length} similar references`;
                    });
                    
                    referencesSection.appendChild(groupContainer);
                }
            });
        }
        
        function displayDuplicateInfo(duplicates, contentMap) {
            // ... (unchanged code for displaying duplicate information)
        }
        
        checkDuplicateReferenceLinks();
    });
});