Async Clipboard API Demo
by juberti
HTML
<h1>Async Clipboard API Demo</h1>
<section>
<button id="copy"><strong>Copy</strong><br><em>(write to clipboard)</em></button>
<button id="paste"><strong>Paste</strong><br><em>(read from clipboard)</em></button>
</section>
<textarea id="out" placeholder="Text to copy"></textarea>
<h3>Permissions:</h3>
<section id="permbuttons"></section>
<div id="toast" hidden></div>
SCSS
html, body {
font: 16px/1.3 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 300;
height: 100%;
padding: 0;
margin: 0;
background: #eee;
overflow: hidden;
text-align: center;
}
h1 {
margin: 10px;
font: inherit;
font-size: 200%;
color: #634884;
text-shadow: 0 1px 0 #fff;
}
h3 {
margin: 0;
font: inherit;
font-size: 140%;
color: #666;
text-shadow: 0 1px 0 #fff;
}
strong {
font-weight: 500;
}
em {
font-size: 80%;
}
section {
margin: 5px auto;
max-width: 500px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-around;
}
section > * {
flex: 0 1 45%;
}
button {
position: relative;
box-sizing: border-box;
margin: 5px;
padding: 10px 20px;
border: 2px solid #230844;
background: #634884;
border-radius: 5px;
color: #fff;
text-shadow: 0 -1px 0 #000;
cursor: pointer;
font: inherit;
line-height: 1.1;
outline: none;
white-space: nowrap;
}
button:hover, button:focus {
background: #8368A4;
}
textarea {
box-sizing: border-box;
display: block;
max-width: 478px;
margin: 10px auto;
padding: 10px;
font: inherit;
color: #555;
border: 2px solid #432864;
border-radius: 5px;
width: calc(100% - 22px);
height: 6em;
outline: none;
}
#perms {
display: inline-block;
text-align: left;
color: #444;
}
#permbuttons button {
text-align: left;
padding-left: 40px;
&:before {
position: absolute;
content: '\1f47b';
left: 10px;
top: 50%;
transform: translateY(-50%);
font-size: 130%;
text-shadow: 0 0 1px rgba(0,0,0,0.5);
}
&[data-state="granted"] {
background: #495;
border-color: #051;
&:before {
content: '\2705';
}
}
&[data-state="denied"] {
background: #945;
border-color: #501;
&:before {
content: '\1f6ab';
}
}
}
#toast, #toast[hidden] {
display: block;
position:...
JavaScript
/** Write contents of the textarea to the clipboard when clicking "Copy" */
doCopy = function() {
navigator.clipboard.writeText(out.value)
.then(() => {
log('Text copied.');
})
.catch((e) => {
log('Failed to read clipboard' + e);
});
};
/** Read from clipboard when clicking the Paste button */
doPaste = function() {
navigator.clipboard.readText()
.then(text => {
out.value = text;
log('Text pasted.');
})
.catch((e) => {
log('Failed to read clipboard' + e);
});
};
copy.onclick = () => setTimeout(doCopy, 900);
paste.onclick = doPaste;
//setInterval(doCopy, 1000);
/** Watch for pastes */
navigator.clipboard.addEventListener('clipboardchange', e => {
navigator.clipboard.getText().then( text => {
log('Updated clipboard contents: '+text)
})
});
function log(value) {
console.log(value);
clearTimeout(log.timer);
if (toast.hidden) toast.textContent = value;
else toast.textContent += '\n' + value;
toast.className = String(value).match(/error/i) ? 'error' : '';
toast.hidden = false;
log.timer = setTimeout( () => { toast.hidden = true; }, 3000);
}