Skip to content

Commit

Permalink
Copy to clipboard: Removed ClipboardJS dependency (#2784)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed Mar 17, 2021
1 parent 459365e commit d5e14e1
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 85 deletions.
38 changes: 0 additions & 38 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions package.json
Expand Up @@ -29,9 +29,6 @@
"author": "Lea Verou",
"license": "MIT",
"readmeFilename": "README.md",
"optionalDependencies": {
"clipboard": "^2.0.0"
},
"devDependencies": {
"chai": "^4.2.0",
"danger": "^10.5.0",
Expand Down
7 changes: 1 addition & 6 deletions plugins/copy-to-clipboard/index.html
Expand Up @@ -21,12 +21,7 @@
<section>
<h1>How to use</h1>

<p>The plugin depends on <a href="https://clipboardjs.com/">clipboard.js</a> and the Prism <a href="https://prismjs.com/plugins/toolbar/">Toolbar</a> plugin. In addition to including the plugin file with your PrismJS build, ensure they are loaded before the plugin.</p>

<p>The simplest way to include clipboard.js is to use any of the
<a href="https://github.com/zenorocha/clipboard.js/wiki/CDN-Providers">recommended CDNs</a>. If you're using Browserify, clipboard.js will be loaded automatically
if it's included in your <code>package.json</code>.
If you don't load clipboard.js yourself, the plugin will load it from a CDN for you.</p>
<p>The plugin depends on the Prism <a href="https://prismjs.com/plugins/toolbar/">Toolbar</a> plugin. In addition to including the plugin file with your PrismJS build, ensure it is loaded before the plugin.</p>
</section>

<section>
Expand Down
112 changes: 75 additions & 37 deletions plugins/copy-to-clipboard/prism-copy-to-clipboard.js
Expand Up @@ -9,30 +9,73 @@
return;
}

var ClipboardJS = window.ClipboardJS || undefined;

if (!ClipboardJS && typeof require === 'function') {
ClipboardJS = require('clipboard');
/**
* When the given elements is clicked by the user, the given text will be copied to clipboard.
*
* @param {HTMLElement} element
* @param {CopyInfo} copyInfo
*
* @typedef CopyInfo
* @property {() => string} getText
* @property {() => void} success
* @property {(reason: unknown) => void} error
*/
function registerClipboard(element, copyInfo) {
element.addEventListener('click', function () {
copyTextToClipboard(copyInfo);
});
}

var callbacks = [];
// https://stackoverflow.com/a/30810322/7595472

/** @param {CopyInfo} copyInfo */
function fallbackCopyTextToClipboard(copyInfo) {
var textArea = document.createElement("textarea");
textArea.value = copyInfo.getText();

if (!ClipboardJS) {
var script = document.createElement('script');
var head = document.querySelector('head');
// Avoid scrolling to bottom
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";

script.onload = function () {
ClipboardJS = window.ClipboardJS;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();

if (ClipboardJS) {
while (callbacks.length) {
callbacks.pop()();
try {
var successful = document.execCommand('copy');
setTimeout(function () {
if (successful) {
copyInfo.success();
} else {
copyInfo.error();
}
}
};
}, 1);
} catch (err) {
setTimeout(function () {
copyInfo.error(err);
}, 1);
}

script.src = 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js';
head.appendChild(script);
document.body.removeChild(textArea);
}
/** @param {CopyInfo} copyInfo */
function copyTextToClipboard(copyInfo) {
if (navigator.clipboard) {
navigator.clipboard.writeText(copyInfo.getText()).then(copyInfo.success, copyInfo.error);
} else {
fallbackCopyTextToClipboard(copyInfo);
}
}

/**
* Selects the text content of the given element.
*
* @param {Element} element
*/
function selectElementText(element) {
// https://stackoverflow.com/a/20079910/7595472
window.getSelection().selectAllChildren(element)
}

/**
Expand Down Expand Up @@ -74,32 +117,27 @@
linkCopy.textContent = settings['copy'];
linkCopy.setAttribute('type', 'button');

if (!ClipboardJS) {
callbacks.push(registerClipboard);
} else {
registerClipboard();
}

return linkCopy;

function registerClipboard() {
var clip = new ClipboardJS(linkCopy, {
'text': function () {
return element.textContent;
}
});

clip.on('success', function () {
registerClipboard(linkCopy, {
getText: function () {
return element.textContent;
},
success: function () {
linkCopy.textContent = settings['copy-success'];

resetText();
});
clip.on('error', function () {
},
error: function () {
linkCopy.textContent = settings['copy-error'];

setTimeout(function () {
selectElementText(element);
}, 1);

resetText();
});
}
}
});

return linkCopy;

function resetText() {
setTimeout(function () {
Expand Down
2 changes: 1 addition & 1 deletion plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d5e14e1

Please sign in to comment.