Commit b4f6f32d authored by Robert Knight's avatar Robert Knight

Add a utility function to copy text to the clipboard

I evaluated popular npm packages for this purpose (eg. [1]) but encountered
issues where they were not transpiled for use in older browsers or
included workarounds for browsers we no longer support (eg. IE 9).

If we do decide to use an existing package in future, we can keep this
utility module as a wrapper around it.

[1] https://github.com/sindresorhus/copy-text-to-clipboard
parent 9b74dcbb
'use strict';
/**
* Copy the string `text` to the clipboard.
*
* In most browsers, this function can only be called in response to a user
* gesture. For example in response to a "click" event.
*/
function copyText(text) {
const temp = document.createElement('span');
temp.className = 'copy-text';
temp.textContent = text;
document.body.appendChild(temp);
try {
const range = document.createRange();
const selection = document.getSelection();
selection.removeAllRanges();
range.selectNodeContents(temp);
selection.addRange(range);
document.execCommand('copy');
} finally {
temp.remove();
}
}
module.exports = { copyText };
'use strict';
const { copyText } = require('../copy-to-clipboard');
describe('copy-to-clipboard', () => {
beforeEach(() => {
sinon.stub(document, 'execCommand');
});
afterEach(() => {
document.execCommand.restore();
});
describe('copyText', () => {
/**
* Returns the temporary element used to hold text being copied.
*/
function tempSpan() {
return document.querySelector('.copy-text');
}
it('copies the passed text to the clipboard', () => {
// We can't actually copy to the clipboard due to security restrictions,
// but we can verify that `execCommand("copy")` was called and that the
// passed text was selected at the time.
const testStr = `test string ${Math.random()}`;
document.execCommand.callsFake(() => {
assert.equal(document.getSelection().toString(), testStr);
});
copyText(testStr);
assert.calledWith(document.execCommand, 'copy');
assert.isNull(tempSpan());
});
it('removes temporary span if copying fails', () => {
document.execCommand.callsFake(() => {
assert.ok(tempSpan());
throw new Error('No clipboard access for you!');
});
try {
copyText('fibble-wobble');
} catch (e) {
assert.equal(e.message, 'No clipboard access for you!');
}
assert.isNull(tempSpan());
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment