UNPKG

v-md-editor

Version:

A markdown editor built on Vue

66 lines (55 loc) 2.27 kB
import copyToClipboard from 'copy-to-clipboard'; function isCopyButton(el) { return el.classList.contains('v-md-copy-code-btn'); } function findCodeWrapperEl(el) { if (el.classList.contains('v-md-pre-wrapper')) { return el; } return findCodeWrapperEl(el.parentNode); } function getPreviewEl(el) { const previewElClass = 'v-md-editor-preview'; return el.classList.contains(previewElClass) ? el : el.querySelector(`.${previewElClass}`); } let timerId = null; export default function createCopyCodePreview() { return { install(VMdEditor) { if (!VMdEditor.mixins) VMdEditor.mixins = []; VMdEditor.mixins.push({ emits: ['copy-code-success'], mounted() { this.$nextTick(() => { const previewEl = getPreviewEl(this.$el); previewEl.addEventListener('click', this.handleCopyCodeClick); }); }, beforeUnmount() { const previewEl = getPreviewEl(this.$el); previewEl.removeEventListener('click', this.handleCopyCodeClick); }, methods: { handleCopyCodeClick({ target }) { if (isCopyButton(target)) { const codeWrapper = findCodeWrapperEl(target.parentNode); if (codeWrapper && timerId === null) { const code = codeWrapper.querySelector('code').innerText; const domI = target.getElementsByTagName("i")[0]; const svgCopy = domI.innerHTML; const svgSuccess = '<svg viewBox="0 0 1024 1024" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M375.552 754.995L130.15 498.227a38.4 38.4 0 0 0-55.5 53.043l272.588 285.236a38.4 38.4 0 0 0 54.99 0.563L902.4 334.285a38.4 38.4 0 0 0-54.528-54.221l-472.371 474.88z" p-id="18613"></path></svg>'; copyToClipboard(code); domI.innerHTML = svgSuccess; timerId = setTimeout(() => { domI.innerHTML = svgCopy; timerId = null; }, 2000) this.$emit('copy-code-success', code); } } }, }, }); }, }; }