mirror of https://github.com/docusealco/docuseal
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							153 lines
						
					
					
						
							3.2 KiB
						
					
					
				
			
		
		
	
	
							153 lines
						
					
					
						
							3.2 KiB
						
					
					
				// Source: https://github.com/github/clipboard-copy-element
 | 
						|
// License: MIT
 | 
						|
export default class extends HTMLElement {
 | 
						|
  constructor () {
 | 
						|
    super()
 | 
						|
    this.addEventListener('click', clicked)
 | 
						|
    this.addEventListener('focus', focused)
 | 
						|
    this.addEventListener('blur', blurred)
 | 
						|
  }
 | 
						|
 | 
						|
  connectedCallback () {
 | 
						|
    if (!this.hasAttribute('tabindex')) {
 | 
						|
      this.setAttribute('tabindex', '0')
 | 
						|
    }
 | 
						|
 | 
						|
    if (!this.hasAttribute('role')) {
 | 
						|
      this.setAttribute('role', 'button')
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  get value () {
 | 
						|
    return this.getAttribute('value') || ''
 | 
						|
  }
 | 
						|
 | 
						|
  set value (text) {
 | 
						|
    this.setAttribute('value', text)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function createNode (text) {
 | 
						|
  const node = document.createElement('pre')
 | 
						|
  node.style.width = '1px'
 | 
						|
  node.style.height = '1px'
 | 
						|
  node.style.position = 'fixed'
 | 
						|
  node.style.top = '5px'
 | 
						|
  node.textContent = text
 | 
						|
  return node
 | 
						|
}
 | 
						|
 | 
						|
function copyNode (node) {
 | 
						|
  if ('clipboard' in navigator) {
 | 
						|
    return navigator.clipboard.writeText(node.textContent || '')
 | 
						|
  }
 | 
						|
 | 
						|
  const selection = getSelection()
 | 
						|
  if (selection == null) {
 | 
						|
    return Promise.reject(new Error())
 | 
						|
  }
 | 
						|
 | 
						|
  selection.removeAllRanges()
 | 
						|
 | 
						|
  const range = document.createRange()
 | 
						|
  range.selectNodeContents(node)
 | 
						|
  selection.addRange(range)
 | 
						|
 | 
						|
  document.execCommand('copy')
 | 
						|
  selection.removeAllRanges()
 | 
						|
  return Promise.resolve()
 | 
						|
}
 | 
						|
 | 
						|
function copyText (text) {
 | 
						|
  if ('clipboard' in navigator) {
 | 
						|
    return navigator.clipboard.writeText(text)
 | 
						|
  }
 | 
						|
 | 
						|
  const body = document.body
 | 
						|
  if (!body) {
 | 
						|
    return Promise.reject(new Error())
 | 
						|
  }
 | 
						|
 | 
						|
  const node = createNode(text)
 | 
						|
  body.appendChild(node)
 | 
						|
  copyNode(node)
 | 
						|
  body.removeChild(node)
 | 
						|
  return Promise.resolve()
 | 
						|
}
 | 
						|
 | 
						|
function copyTarget (content) {
 | 
						|
  if (
 | 
						|
    content instanceof HTMLInputElement ||
 | 
						|
    content instanceof HTMLTextAreaElement
 | 
						|
  ) {
 | 
						|
    return copyText(content.value)
 | 
						|
  } else if (
 | 
						|
    content instanceof HTMLAnchorElement &&
 | 
						|
    content.hasAttribute('href')
 | 
						|
  ) {
 | 
						|
    return copyText(content.href)
 | 
						|
  } else {
 | 
						|
    return copyNode(content)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
async function copy (button) {
 | 
						|
  const id = button.getAttribute('for')
 | 
						|
  const text = button.getAttribute('value')
 | 
						|
 | 
						|
  function trigger () {
 | 
						|
    button.dispatchEvent(new CustomEvent('clipboard-copy', { bubbles: true }))
 | 
						|
  }
 | 
						|
 | 
						|
  function toggleActiveIcon () {
 | 
						|
    if (button.classList.contains('swap')) {
 | 
						|
      button.classList.toggle('swap-active')
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (text) {
 | 
						|
    await copyText(text)
 | 
						|
    trigger()
 | 
						|
    toggleActiveIcon()
 | 
						|
  } else if (id) {
 | 
						|
    const root = 'getRootNode' in Element.prototype ? button.getRootNode() : button.ownerDocument
 | 
						|
 | 
						|
    if (!(root instanceof Document || ('ShadowRoot' in window && root instanceof ShadowRoot))) return
 | 
						|
 | 
						|
    const node = root.getElementById(id)
 | 
						|
 | 
						|
    if (node) {
 | 
						|
      await copyTarget(node)
 | 
						|
      trigger()
 | 
						|
      toggleActiveIcon()
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function clicked (event) {
 | 
						|
  const button = event.currentTarget
 | 
						|
 | 
						|
  if (button instanceof HTMLElement) {
 | 
						|
    copy(button)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function keydown (event) {
 | 
						|
  if (event.key === ' ' || event.key === 'Enter') {
 | 
						|
    const button = event.currentTarget
 | 
						|
 | 
						|
    if (button instanceof HTMLElement) {
 | 
						|
      event.preventDefault()
 | 
						|
      copy(button)
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function focused (event) {
 | 
						|
  event.currentTarget.addEventListener('keydown', keydown)
 | 
						|
}
 | 
						|
 | 
						|
function blurred (event) {
 | 
						|
  event.currentTarget.removeEventListener('keydown', keydown)
 | 
						|
}
 |