Jump to content

User:Polygnotus/Scripts/SourceTable.js

From Wikipedia, the free encyclopedia
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.
// Only run on AfD edit pages
if (mw.config.get('wgPageName').startsWith('Wikipedia:Articles_for_deletion/') && mw.config.get('wgAction') === 'edit') {
    $(function() {
        console.log('AfD script running, attempting to add button...');
        
        // Try to find the exact structure we see in your HTML
        // h1#firstHeading with a span#firstHeadingTitle inside
        if ($('#firstHeading').length) {
            $('<button>')
                .attr('id', 'generateSourceTableButton')
                .text('Generate Source Table')
                .css({
                    'margin-left': '10px',
                    'margin-bottom': '5px',
                    'display': 'inline-block',
                    'vertical-align': 'middle',
                    'font-size': '15px',
                    'padding': '4px 8px'
                })
                .click(function(e) {
                    e.preventDefault(); // Prevent any default behavior
                    generateSourceTable();
                })
                .appendTo('#firstHeading'); // Add to the heading element
            
            console.log('Button added to #firstHeading');
        } 
        // Fallback - try adding it to the edit form area
        else if ($('#editform').length) {
            $('<button>')
                .attr('id', 'generateSourceTableButton')
                .text('Generate Source Table')
                .css({
                    'margin': '10px 0',
                    'display': 'block'
                })
                .click(function(e) {
                    e.preventDefault(); // Prevent any default behavior
                    generateSourceTable();
                })
                .prependTo('#editform');
            
            console.log('Button added to #editform as fallback');
        } else {
            console.error('Could not find any suitable element to attach the button to');
        }
    });
}

function generateSourceTable() {
    // Extract article name from AfD page title
    var afdPageName = mw.config.get('wgPageName');
    var articleName = extractArticleName(afdPageName);
    
    console.log('Generating source table for article:', articleName);
    
    // Fetch article content
    new mw.Api().get({
        action: 'query',
        prop: 'revisions',
        rvprop: 'content',
        titles: articleName,
        formatversion: 2
    }).done(function(data) {
        try {
            if (!data.query || !data.query.pages || data.query.pages.length === 0) {
                mw.notify('Error: Could not retrieve article data.', {type: 'error'});
                console.error('API response did not contain expected data:', data);
                return;
            }
            
            var page = data.query.pages[0];
            if (page.missing) {
                mw.notify('The article "' + articleName + '" could not be found.', {type: 'error'});
                console.error('Article not found:', articleName);
                return;
            }
            
            if (!page.revisions || page.revisions.length === 0) {
                mw.notify('No revisions found for the article.', {type: 'error'});
                console.error('No revisions found for:', articleName);
                return;
            }
            
            var pageContent = page.revisions[0].content;
            
            // Extract references
            var references = extractReferences(pageContent);
            
            if (references.length === 0) {
                // If there are no references, notify the user
                mw.notify('No references found in the article.', {type: 'warning'});
                console.warn('No references found in:', articleName);
                return;
            }
            
            var tableWikicode = '\n\n{{static row numbers}}\n';
            tableWikicode += '{| class="wikitable mw-collapsible static-row-numbers"\n';
            tableWikicode += `|+ class="nowrap" | Source review by ~~` + `~\n`;
            tableWikicode += '|-\n';
            tableWikicode += '! Source !! Comments\n';
            references.forEach(function(ref) {
                tableWikicode += '|-\n| ' + ref + ' \n|| \n';
            });
            tableWikicode += '|}';
            
            // Get the edit textarea - it's always #wpTextbox1 in Wikipedia's edit interface
            var editTextarea = document.getElementById('wpTextbox1');
            if (editTextarea) {
                // Insert the table at the end of the current content
                editTextarea.value += tableWikicode;
                
                // Trigger a change event to update the preview if it's open
                $(editTextarea).trigger('change');
                
                mw.notify('Source table added to the edit area. Please review and save your changes when ready.', {type: 'success'});
                console.log('Source table successfully added to edit area');
            } else {
                mw.notify('Failed to find the edit textarea.', {type: 'error'});
                console.error('Could not find edit textarea #wpTextbox1');
            }
        } catch (error) {
            mw.notify('An error occurred: ' + error.message, {type: 'error'});
            console.error('Error processing article data:', error);
        }
    }).fail(function(error) {
        mw.notify('Failed to fetch article content. Please try again.', {type: 'error'});
        console.error('API request failed:', error);
    });
}

function extractArticleName(afdPageName) {
    var articleName = afdPageName.replace('Wikipedia:Articles_for_deletion/', '');
    
    // Handle nomination numbers (1st, 2nd, etc.)
    var nominationMatch = articleName.match(/(.*) \((\d+)(st|nd|rd|th) nomination\)$/);
    if (nominationMatch) {
        articleName = nominationMatch[1];
    }
    
    console.log('Extracted article name:', articleName);
    return articleName;
}

function extractReferences(content) {
    var references = [];
    var index = 0;
    
    while (true) {
        var startIndex = content.indexOf('<ref', index);
        if (startIndex === -1) break;
        
        var endIndex = content.indexOf('>', startIndex);
        if (endIndex === -1) break;
        
        var tagContent = content.substring(startIndex, endIndex + 1);
        
        if (tagContent.endsWith('/>')) {
            // This is a self-closing tag, skip it
            index = endIndex + 1;
            continue;
        }
        
        var refEndIndex = content.indexOf('</ref>', endIndex);
        if (refEndIndex === -1) break;
        
        var refContent = content.substring(endIndex + 1, refEndIndex).trim();
        
        // Replace {{|}} with &#x7c;
        refContent = refContent.replace(/\{\{\!\}\}/g, '&#x7c;');
        
        references.push(refContent);
        
        index = refEndIndex + 6; // Move past '</ref>'
    }
    
    console.log('Extracted', references.length, 'references');
    return references;
}