Regis / Copy Message Text

// ==UserScript==
// @name         Copy Message Text
// @namespace    https://ru.waysofhistory.com/
// @version      1.2
// @description  Позволяет копировать текст из переписки вместе с тегами.
// @author       Regis
// @match        https://*.waysofhistory.com/gen/html/*
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    var $ = unsafeWindow.jQuery;
    if (!$) {
        // Денех нет, валим отсюда!
        return;
    }

    if (!unsafeWindow.vMessage) {
        // Некорректная страница, либо несовместимая версия
        return;
    }

    function addButtons() {
        $('.message-list').find('.list li').each(function () {
            var $li = $(this);
            if ($li.find('.copyMessageTextBtn').length === 0) {
                $(this).prepend('<button class="copyMessageTextBtn" style="border: 1px solid; border-radius: 4px; padding: 2px; color: dimgray; float: right">Copy</button>');
            }
        });
    }

    var originalAppendList = unsafeWindow.vMessage.prototype.appendList;
    unsafeWindow.vMessage.prototype.appendList = function () {
        originalAppendList.apply(this, arguments);
        addButtons();
    };


    var copyMessageTextHandler = function () {
        var textContainer = $(this).closest('li').find('.text');
        var result = '';

        var linkHandlers = {
            '/#/townInfo/': function (s) {
                return '[t' + s + ']';
            },
            '/#/account/': function (s) {
                return '[p' + s + ']';
            },
            '/#/countryInfo/': function (s) {
                return '[c' + s + ']';
            },
            // Note: не работает, так как ссылки на постройки оборачиваются в div
            '/#/buildinfo/': function (s) {
                return '[b' + s + ']';
            },
            '/#/unitinfo/': function (s) {
                return '[u' + s + ']';
            },
            '/#/scienceinfo/': function (s) {
                return '[s' + s + ']';
            },
            '/#/report/': function (s) {
                return '[r' + s.replace('-', '/') + ']';
            },
            '/#map/o=': function (s) {
                return '[m' + s.replace('&x=', '/').replace('&y=', '/') + ']';
            },
            '/#/sendArmy/groupid=': function (s) {
                return'[g' + s.replace('&key=', '/') + ']';
            },
            '/#message/': function (s) {
                return '[w' + s + ']';
            }
        };

        textContainer.contents().each(function () {
            var nodeType = this.nodeType;
            if (nodeType === 3) {
                // Text node
                result += $(this).text();
                return;
            } else if (nodeType === 1) {
                // Element node
                var tagName = this.tagName;
                if (tagName === 'BR') {
                    result += '\n';
                } else if (tagName === 'A') {
                    var href = this.getAttribute('href');
                    if (href === '') {
                        href = $(this).data('href');
                    }
                    for (var prefix in linkHandlers) {
                        if (linkHandlers.hasOwnProperty(prefix)) {
                            if (href.indexOf(prefix) === 0) {
                                var suffix = href.slice(prefix.length);
                                result += linkHandlers[prefix](suffix);
                                return;
                            }
                        }
                    }
                }
            }
            // Failed to parse. Fallback to usual text.
            result += $(this).text();
        });
        var textBox = $(this).closest('form.tab').find('.message-inputWrp textarea').get(0);
        var oldText = textBox.value;
        if (oldText.length > 0) {
            result = '\n' + result;
        }
        textBox.value += result;

    };
    $(document).on('click', '.copyMessageTextBtn', copyMessageTextHandler);

})();