Trello Copy

Trello 功能擴充

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name        Trello Copy
// @namespace   1207bd0a-0252-4c8d-9134-d40ac51e4248
// @match       https://trello.com/*
// @grant       none
// @version     1.0.0
// @author      Rick0
// @description Trello 功能擴充
// @require     https://unpkg.com/clipboard@2/dist/clipboard.min.js
// ==/UserScript==

// == class ==

class Card {
  url = location.href.match(/(https?:\/\/.+)\//)[1]
  title () {
    return document.querySelector('.mod-card-back-title.js-card-detail-title-input').value
  }
  // description = document.querySelector('.description-title > .u-inline-block')
  // headerIcon = document.querySelector('.window-header-icon')
  // header = document.querySelector('.window-header')
}

// == global function ==

function setCSS(src) {
  let stylesheet = createNode(`<link rel="stylesheet" type="text/css" href="${src}">`)
  document.head.appendChild(stylesheet)
}

function setClipboardJS() {
  copyButton = createNode(`<button class="oneCopy"></button>`)
  document.body.appendChild(copyButton)
  new ClipboardJS('.oneCopy')
}

function setClipboard (text) {
  copyButton.setAttribute('data-clipboard-text', text)
  copyButton.click()
}

function createNode(html) {
  let template = document.createElement('template')
  template.innerHTML = html
  
  return template.content.firstChild
}

function createButton (buttonName, eventName, callback) {
  let button = createNode(`<div><a class="button subtle" href="javascript:void(0)">${buttonName}</a></div>`)
  let link = button.querySelector('a')

  link.addEventListener(eventName, callback)

  return button
}

function createCopyButton (buttonName, text) {
  return createButton(buttonName, 'click', function () {
    setClipboard(text)
  })
}

// == global var ==



// == program start ==

// setCSS('https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.css')
setClipboardJS()

let observer = new MutationObserver(function () {
  let isCardDeatilMode = (location.pathname.slice(1, 2) === 'c')
  if (isCardDeatilMode) {
    let card = new Card()

    let tagArea = document.querySelector('.window-main-col>.card-detail-data')
    let copyArea = createNode(`<div class="window-module-title window-module-title-no-divider description-title"><span class="icon-copy icon-lg window-module-title-icon"></span><h3 class="u-inline-block">複製</h3></div>`)
    let titleCopyButton = createButton('標題', 'click', function () {
      setClipboard(card.title())
    })
    let urlCopyButton = createCopyButton('網址', card.url)
    let recordCopyButton = createButton('專案紀錄', 'click', function () {
      setClipboard(`=HYPERLINK("${card.url}","${card.title().replace(/"/g, '\"\"')}")`)
    })

    ;[
      titleCopyButton,
      urlCopyButton,
      recordCopyButton,
    ]
      .forEach(button => {
        copyArea.appendChild(button)
    })
    tagArea.insertAdjacentElement('afterend', copyArea)
  }
})
observer.observe(document.body, {
  attributeFilter: ['class'],
})