User:CFA/scripts/attributetranslation.js

(function {   'use strict';

function createInputGUI(contributors) { var gui = document.createElement('div'); gui.style.position = 'fixed'; gui.style.top = '50%'; gui.style.left = '50%'; gui.style.transform = 'translate(-50%, -50%)'; gui.style.backgroundColor = '#f8f9fa'; gui.style.border = '1px solid #a2a9b1'; gui.style.padding = '20px'; gui.style.zIndex = 10000; gui.style.overflowY = 'auto'; gui.style.maxHeight = '80vh'; gui.innerHTML = ` Language code The two-letter language code of the Wikipedia that this article was translated from.  Article name The name of the page on the other Wikipedia that this article was translated from.    Add to talk page Add  to the talk page if the translated content is significant. Warn users Send a notice to the user(s) who added the non-attributed text. Submit <button id="closeGUI">Close <div id="logContainer" style="display: none; margin-top: 20px; border-top: 1px solid #a2a9b1; padding-top: 10px;"> Log <ul id="logList" style="list-style-type: none; padding-left: 0;"></ul> `;

document.body.appendChild(gui);

var contributorsList = document.getElementById('contributorsList'); if (!contributorsList) { console.error('Contributors list container not found.'); return; }

contributors.forEach(function(contributor) {           var checkbox = document.createElement('input');            checkbox.type = 'checkbox';            checkbox.style = "transform: scale(0.75);margin-right:3px;";            checkbox.name = 'contributors';            checkbox.value = contributor.username;            var label = document.createElement('label');            label.style = "font-size:75%";            label.appendChild(checkbox);            label.appendChild(document.createTextNode(`${contributor.username} — ${contributor.edits} edit${contributor.edits === 1 ?  : 's'}${contributor.isCreator ? ' (Page Creator)' : }`));            label.appendChild(document.createElement('br'));            contributorsList.appendChild(label);        });

document.getElementById('submitTranslation').addEventListener('click', function {           var langCode = document.getElementById('langCode').value.trim;            var articleName = document.getElementById('articleName').value.trim;            var selectedContributors = Array.from(document.querySelectorAll('input[name=contributors]:checked')).map(function(checkbox) { return checkbox.value; });           var addTemplate = document.getElementById('addTranslatedPageTemplate').checked;

if (langCode && articleName && selectedContributors.length > 0) { processTranslation(langCode, articleName, selectedContributors, addTemplate); document.getElementById('logContainer').style.display = 'block'; } else { alert('Please fill in both fields and select at least one contributor.'); }       });

document.getElementById('closeGUI').addEventListener('click', function {           document.body.removeChild(gui);        }); }

function processTranslation(langCode, articleName, selectedContributors, addTemplate) { var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' ');

var editSummary = `This article contains content translated from the Wikipedia article at ${langCode}:${articleName}; see its history for attribution. (AT)`;

var tasksCompleted = 0; var totalTasks = 1 + (addTemplate ? 1 : 0) + selectedContributors.length; var logList = document.getElementById('logList');

function addLogEntry(message, success) { var listItem = document.createElement('li'); listItem.style.display = 'flex'; listItem.style.alignItems = 'center';

var checkmark = document.createElement('span'); checkmark.style.display = 'inline-block'; checkmark.style.width = '16px'; checkmark.style.height = '16px'; checkmark.style.marginRight = '8px'; checkmark.style.backgroundColor = success ? 'green' : 'red'; checkmark.style.borderRadius = '50%';

listItem.appendChild(checkmark); listItem.appendChild(document.createTextNode(message)); logList.appendChild(listItem); }

function checkCompletion { tasksCompleted++; if (tasksCompleted === totalTasks) { setTimeout( => {                   location.reload;                }, 1000); }       }

// Dummy edit $.ajax({           url: mw.util.wikiScript('api'),            type: 'GET',            data: {                format: 'json',                action: 'query',                prop: 'revisions',                rvprop: 'content',                titles: pageTitle            },            success: function(data) {                var pages = data.query.pages;                var pageContent = '';                for (var pageId in pages) {                    if (pages.hasOwnProperty(pageId)) {                        pageContent = pages[pageId].revisions[0]['*'];                    }                }                pageContent += '\n​';

$.ajax({                   url: mw.util.wikiScript('api'),                    type: 'POST',                    data: {                        format: 'json',                        action: 'edit',                        title: pageTitle,                        text: pageContent,                        summary: editSummary,                        minor: true,                        token: mw.user.tokens.get('csrfToken')                    },                    success: function {                        console.log('Dummy edit successful');                        addLogEntry('Added dummy edit to article', true);                        checkCompletion;                    },                    error: function(jqXHR, textStatus, errorThrown) {                        console.error('Error performing dummy edit:', textStatus, errorThrown);                        addLogEntry('Failed to add dummy edit to article', false); checkCompletion; }               });            },            error: function(jqXHR, textStatus, errorThrown) {                console.error('Error retrieving page content:', textStatus, errorThrown);                addLogEntry('Failed to retrieve page content', false);                checkCompletion;            }        });

// Add template if (addTemplate) { var talkPageTitle = 'Talk:' + pageTitle;

$.ajax({               url: mw.util.wikiScript('api'),                type: 'POST',                data: {                    format: 'json',                    action: 'edit',                    title: talkPageTitle,                    summary: `Adding  attribution (AT)`,                    section: 'new',                    sectiontitle: '',                    text: ``,                    token: mw.user.tokens.get('csrfToken')                },                success: function {                    console.log('Article talk page updated');                    addLogEntry('Added template to talk page', true);                    checkCompletion;                },                error: function(jqXHR, textStatus, errorThrown) {                    console.error('Error updating article talk page:', textStatus, errorThrown);                    addLogEntry('Failed to add template to talk page', false); checkCompletion; }           });        }

// Notify contributors selectedContributors.forEach(function(contributor) {           notifyContributor(contributor, langCode, articleName);        });

function notifyContributor(contributor, langCode, articleName) { var subst = "subst:"; var sig = "" + ""; var notificationMessage = ` ${sig}`;

$.ajax({               url: mw.util.wikiScript('api'),                type: 'POST',                data: {                    format: 'json',                    action: 'edit',                    title: 'User talk:' + contributor,                    summary: `Adding non-attributed translation notice (AT)`,                    section: 'new',                    sectiontitle: 'Non-attributed translations',                    text: notificationMessage,                    token: mw.user.tokens.get('csrfToken')                },                success: function {                    console.log('Notification sent to user talk page');                    addLogEntry(`Warned user (${contributor})`, true);                    checkCompletion;                },                error: function(jqXHR, textStatus, errorThrown) {                    console.error('Error sending notification:', textStatus, errorThrown); addLogEntry(`Failed to warn user (${contributor})`, false); if (confirm("Could not notify contributor. Retry?")) { notifyContributor(contributor, langCode, articleName); } else { checkCompletion; }               }            });        }    }

function getPageContributors(pageTitle, callback) { $.ajax({           url: mw.util.wikiScript('api'),            type: 'GET',            data: {                format: 'json',                action: 'query',                prop: 'revisions',                rvprop: 'user',                titles: pageTitle,                rvlimit: 'max',                rvdir: 'newer'            },            success: function(data) {                var pages = data.query.pages;                var contributors = [];                for (var pageId in pages) {                    if (pages.hasOwnProperty(pageId)) {                        var revisions = pages[pageId].revisions;                        var creator = true;                        revisions.forEach(function(revision) { if (revision.user && revision.user !== '') { var contributorIndex = contributors.findIndex(function(item) {                                   return item.username === revision.user;                                }); if (contributorIndex === -1) { contributors.push({ username: revision.user, edits: 1, isCreator: creator }); } else { contributors[contributorIndex].edits++; }                               creator = false; }                       });                    }                }                callback(contributors);            },            error: function(jqXHR, textStatus, errorThrown) {                console.error('Error retrieving page contributors:', textStatus, errorThrown);            }        }); }

function addButtonToToolbar { var allowedNamespaces = [0, 118];

var currentNamespace = mw.config.get('wgNamespaceNumber');

if (allowedNamespaces.includes(currentNamespace)) { mw.util.addPortletLink(               'p-cactions',                '#',                'Translation attribution',                'ca-translation-attribution',                'AttributeTranslation',                null,                null            );

document.getElementById('ca-translation-attribution').addEventListener('click', function {               var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' ');                getPageContributors(pageTitle, function(contributors) { createInputGUI(contributors); });           });        }    }

addButtonToToolbar; });