User:Awesome Aasim/discussiontoolswordcount.js

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.
$(document).ready(function () {
	if (mw.config.get("wgAction") != "view" || mw.config.get("wgNamespaceNumber") < 0) return;
    mw.util.addPortletLink("p-cactions", "#", "Word Count", "t-wordcount", "Count words in discussion threads");
    $("#t-wordcount").click(async function (e) {
        e.preventDefault();
        try {
            var data = await $.get(mw.config.get('wgScriptPath') + "/api.php", {
                "action": "discussiontoolspageinfo",
                "format": "json",
                "page": mw.config.get('wgPageName'),
                "prop": "threaditemshtml",
                "excludesignatures": 1,
                "formatversion": "2"
            });
            if (data.error) {
                alert(data.error.info);
                return;
            }
            data = data.discussiontoolspageinfo.threaditemshtml;

            function countWords(node, participantWordCounts = {}, participantCommentsStrings = {}) {
                if (node.author) {
                    var author = node.author;
                    if (!participantWordCounts[author]) {
                        participantWordCounts[author] = 0;
                        participantCommentsStrings[author] = "";
                    }
                    // Count words in the HTML content
                    var wordCountStr = node.html;
                    var wordCount = $("<span/>").append(node.html).text().split(" ").length;
                    participantCommentsStrings[author] += wordCountStr + "<br/>";
                    participantWordCounts[author] += wordCount;
                }

                if (node.replies && node.replies.length > 0) {
                    for (var i = 0; i < node.replies.length; i++) {
                        countWords(node.replies[i], participantWordCounts, participantCommentsStrings);
                    }
                }
                return [participantWordCounts, participantCommentsStrings];
            }

            for (var entry of data) {
                var wordCountData = countWords(entry);
                console.log(wordCountData);
                var wordCountArray = [];
                for (var author in wordCountData[0]){
                    wordCountArray.push({"author": author, "wordCount": wordCountData[0][author], "commentString": wordCountData[1][author]});
                }
                wordCountArray.sort((a, b) => b.wordCount - a.wordCount);
                var $wordCountTable = $("<table/>").addClass("wikitable word-count-table").css("width", "100%");
                $wordCountTable.append("<tr><th>Author</th><th>Word Count</th><th>Comments</th></tr>");
                for (var i = 0; i < wordCountArray.length; i++) {
                    var row = $("<tr/>");
                    row.append($("<td/>").text(wordCountArray[i].author));
                    row.append($("<td/>").text(wordCountArray[i].wordCount));
                    row.append($("<td/>").html(wordCountArray[i].commentString));
                    $wordCountTable.append(row);
                }
                if (entry.type == "heading") {
                    var headingId = entry.id;
                    if (headingId != "h-") {
                        $(document.getElementById(headingId)).parent().parent().after($wordCountTable)
                    } else {
                        $(`#mw-content-text`).before($wordCountTable)
                    }
                }
            }
            $("#t-wordcount").remove();
        } catch (e) {
            console.error(e);
            alert("Failed to fetch discussion data.");
            return;
        }
    });
})