Confluence Jira 复制标题和链接

Add a button to copy the title and link of a Confluence page

// ==UserScript==
// @name         Confluence Jira 复制标题和链接
// @description:zh-CN 点击按钮以markdown格式复制标题文本+链接
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Add a button to copy the title and link of a Confluence page
// @author      cheerchen37
// @license     MIT
// @copyright   2024, https://github.com/cheerchen37/confluence-kopipe
// @match        *://*.atlassian.net/*
// @grant        none
// @icon         data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pjxzdmcgdmlld0JveD0iMCAwIDQwIDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZS8+PGcgaWQ9IkNvbmZsdWVuY2UiPjxwYXRoIGQ9Ik0yNS42LDIyYzEuODYuOSwzLjkyLDEuODcsNSwyLjM2YS43Ni43NiwwLDAsMSwuMzgsMWwtMi4zNiw1LjM0djBhLjc3Ljc3LDAsMCwxLTEsLjM2bC00LjkyLTIuMzRjLTMuNTctMS43MS01LjU1LTIuMS03LjUxLDEuMTRsLS43NCwxLjIzaDBhLjc2Ljc2LDAsMCwxLTEuMDUuMjVsLTUtMy4wNmEuNzYuNzYsMCwwLDEtLjI1LTFsLjc2LTEuMjVDMTMuMjIsMTksMTguOTEsMTguNzksMjUuNiwyMlptNS41My04LjFjLjI1LS40LjUzLS44Ny43Ni0xLjI1YS43Ni43NiwwLDAsMC0uMjUtMWwtNS0zLjA1YS43Ni43NiwwLDAsMC0xLjA2LjIxbDAsMGMtLjE5LjMzLS40NS43Ny0uNzMsMS4yMy0yLDMuMjQtMy45NCwyLjg1LTcuNTEsMS4xNEwxMi40Myw4Ljg5YS43NS43NSwwLDAsMC0xLC4zN3YwTDksMTQuNjJhLjc4Ljc4LDAsMCwwLC4zOCwxYzEsLjQ5LDMuMTEsMS40Niw1LDIuMzZDMjEuMDksMjEuMjMsMjYuNzgsMjEsMzEuMTMsMTMuOTRaIi8+PC9nPjwvc3ZnPg==
// ==/UserScript==

(function() {
    'use strict';
    // 添加按钮样式和提示样式
    const style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = `
        #customCopyButton {
            position: fixed;
            top: 20px;
            right: 470px; /* Moved left 50px from the right edge */
            padding: 10px 15px;
            background-color: #0052CC;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 1000;
        }
        #customCopyButton:hover {
            background-color: #003380;
        }
        #copyFeedback {
            position: fixed;
            top: 50px;
            right: 470px;
            background-color: #000;
            color: #fff;
            padding: 5px 10px;
            border-radius: 5px;
            display: none;
            z-index: 1001;
        }
        #customCopyButton:hover .tooltip {
            visibility: visible;
            opacity: 1;
        }
    `;
    document.head.appendChild(style);

    function addButton() {
        if (!document.getElementById('customCopyButton')) {
            const button = document.createElement('button');
            button.id = 'customCopyButton';
            button.textContent = 'Copy Title & Link';
            document.body.appendChild(button);

            const feedback = document.createElement('div');
            feedback.id = 'copyFeedback';
            feedback.textContent = 'Copied!';
            document.body.appendChild(feedback);

            button.addEventListener('click', function() {
               let titleText = '';
                // Check if it's Confluence
                if (document.location.href.includes("wiki")) {
                    titleText = document.getElementById('title-text') ? document.getElementById('title-text').textContent : '';
                }
                // Check if it's Jira
                else if (document.location.href.includes("browse")) {
                    const jiraTitleElement = document.querySelector('h1[data-testid="issue.views.issue-base.foundation.summary.heading"]');
                    titleText = jiraTitleElement ? jiraTitleElement.textContent : '';
                }
                const pageLink = window.location.href;

                const tempTextarea = document.createElement('textarea');
                document.body.appendChild(tempTextarea);
                tempTextarea.value = `[${titleText}](${pageLink})`;
                tempTextarea.select();
                document.execCommand('copy');
                document.body.removeChild(tempTextarea);

                // 显示反馈信息
                feedback.style.display = 'block';
                setTimeout(() => { feedback.style.display = 'none'; }, 1000);
            });
        }
    }

    // Mutation Observer to monitor DOM changes
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.removedNodes.length || mutation.addedNodes.length) {
                addButton();
            }
        });
    });

    const config = { childList: true, subtree: true };
    observer.observe(document.body, config);

    // Initial button add
    addButton();
})();