Skip to content

Commit

Permalink
Accept a style parameter to specify the copied style.
Browse files Browse the repository at this point in the history
If `style` parameter isn't specified, this forces a text/plain copy to make it easier to work with word processors.
This also changes the example code to exhibit the bug of issue sudodoki#46 so
that it's easier to test.

Fixes sudodoki#46
  • Loading branch information
julienw committed May 4, 2019
1 parent bc7125f commit 2986187
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ copy('Text', {
|------|--------|-----|
|options.debug |false| `Boolean`. Optional. Enable output to console. |
|options.message|Copy to clipboard: `#{key}`, Enter| `String`. Optional. Prompt message. `*` |
|options.format|"text/html"| `String`. Optional. Set the MIME type of what you want to copy as. Use `text/html` to copy as HTML, `text/plain` to avoid inherited styles showing when pasted into rich text editor. |
|options.style |false |`boolean \| Object`. Optional. If this is an object, it should have the properties `background` and/or `text` to define respectively background and text colors. Defaults are a white background and black text color. You can also set it to `true` to get these defaults. |

`*` all occurrences of `#{key}` are replaced with `⌘+C` for macOS/iOS users, and `Ctrl+C` otherwise.

Expand Down
27 changes: 19 additions & 8 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
<title>CopyButtonPlayground</title>
<link rel="stylesheet" href="example.css">
</head>
<body>
<body style='background: #ddd'>
<h1 data-test="heading"><a href="http://github.com/sudodoki/copy-to-clipboard">copy-to-clipboard Repo</a></h1>
<textarea data-test="placeholder"></textarea>
<div class="container">
<h2 id="basic-text">Basic text copy</h2>
<textarea disabled class="code half">copyToClipboard("Hello, I'm new content from your clipboard")</textarea>
<div class="half">
<button data-test="init-basic-text">Click to copy sample text</button>
<button class="copy-basic-text">Click to copy sample text</button>
<button class="copy-basic-text-default-style">Click to copy sample text with default style</button>
<button class="copy-basic-text-custom-style">Click to copy sample text with custom style</button>
</div>
</div>
<hr>
Expand All @@ -23,7 +25,7 @@ <h2 id="multiline-text">Multiline text copy</h2>
some multiline text
for us to copy</textarea>
<div class="half">
<button data-test="init-multiline-text">Click to copy multiline text</button>
<button class="copy-multiline-text">Click to copy multiline text</button>
</div>
</div>
<hr>
Expand All @@ -35,26 +37,35 @@ <h2 id="multiline-markup">Markup + text copy</h2>
</script>
</textarea>
<div class="half">
<button data-test="init-markup-text">Click to copy multiline text</button>
<button class="copy-markup-text">Click to copy multiline text</button>
</div>
</div>
<hr>
<script src="./index.js"></script>
<script>
document.querySelector('#basic-text ~ .half button')
var simpleText = "Hello, I'm new content from your clipboard";
document.querySelector('.copy-basic-text')
.addEventListener('click', function () {
copyToClipboard("Hello, I'm new content from your clipboard")
copyToClipboard(simpleText)
});
document.querySelector('.copy-basic-text-default-style')
.addEventListener('click', function () {
copyToClipboard(simpleText, { style: true })
});
document.querySelector('.copy-basic-text-custom-style')
.addEventListener('click', function () {
copyToClipboard(simpleText, { style: { background: 'red', text: 'yellow' }})
});
(function() {
var multilineContainer = document.querySelector('#multiline-text + textarea');
document.querySelector('#multiline-text ~ .half button')
document.querySelector('.copy-multiline-text')
.addEventListener('click', function () {
copyToClipboard(multilineContainer.textContent)
})
})();
(function() {
var markupContainer = document.querySelector('#multiline-markup + textarea');
document.querySelector('#multiline-markup ~ .half button')
document.querySelector('.copy-markup-text')
.addEventListener('click', function () {
copyToClipboard(markupContainer.textContent)
})
Expand Down
2 changes: 1 addition & 1 deletion example/index.js

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

7 changes: 6 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
// Project: https://github.com/sudodoki/copy-to-clipboard
// Definitions by: Denis Carriere <https://github.com/DenisCarriere>, MartynasZilinskas <https://github.com/MartynasZilinskas>

interface StyleOption {
background: string;
text: string;
}

interface Options {
debug?: boolean;
message?: string;
format?: string; // MIME type
style?: boolean | StyleOption; // MIME type
}

declare function copy(text: string, options?: Options): boolean;
Expand Down
21 changes: 18 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@ function copy(text, options) {
range,
selection,
mark,
style,
success = false;
if (!options) {
options = {};
}

if (options.style) {
// If style is the boolean `true`, use the default values.
// Otherwise, overwrite the default values with whatever is passed.
style = Object.assign({ background: 'white', text: 'black' }, options.style);
}

debug = options.debug || false;
try {
reselectPrevious = deselectCurrent();
Expand All @@ -31,6 +39,10 @@ function copy(text, options) {
mark.textContent = text;
// reset user styles for span element
mark.style.all = "unset";
if (style) {
mark.style.backgroundColor = style.background;
mark.style.color = style.text;
}
// prevents scrolling to the end of the page
mark.style.position = "fixed";
mark.style.top = 0;
Expand All @@ -43,11 +55,14 @@ function copy(text, options) {
mark.style.msUserSelect = "text";
mark.style.userSelect = "text";
mark.addEventListener("copy", function(e) {
// Prevents the "copy" event from reaching the outside world.
e.stopPropagation();
if (options.format) {
if (!style) {
// Force a text copy instead of an html copy, to make it easier to
// work with word processors.
e.preventDefault();
e.clipboardData.clearData();
e.clipboardData.setData(options.format, text);
e.clipboardData.setData('text/plain', text);
}
});

Expand All @@ -65,7 +80,7 @@ function copy(text, options) {
debug && console.error("unable to copy using execCommand: ", err);
debug && console.warn("trying IE specific stuff");
try {
window.clipboardData.setData(options.format || "text", text);
window.clipboardData.setData("text", text);
success = true;
} catch (err) {
debug && console.error("unable to copy using clipboardData: ", err);
Expand Down

0 comments on commit 2986187

Please sign in to comment.