Monday, August 15, 2022
HomeJavaScriptA clipboard magic trick - how one can use completely different MIME...

A clipboard magic trick – how one can use completely different MIME varieties with the Clipboard API


I found an online improvement magic trick from Cyrus Roshan immediately. It took me an excellent 20 minutes to determine how the trick works, and I discovered some issues about JavaScript clipboard dealing with and MIME varieties. Sounds intriguing? Learn on!

Strive the magic tips your self; I will wait. 😉

Screen showing six ascii art playing cards tasking you to click and automatically copy one.

Should you did not attempt it, here is the movement:

  1. You are tasked to click on an ASCII artwork play card. The cardboard’s characters are mechanically copied to your clipboard utilizing JavaScript.
  2. Then, a brand new display tells you to stick the copied ASCII card right into a textarea (which works as anticipated).
  3. Subsequent, you are instructed to open a brand new Google Doc and paste your clipboard content material into it (the ASCII artwork enjoying card).
  4. The simply copied ASCII artwork now features a new line telling you to stick the identical content material into the URL bar, and increase! 🪄 You simply pasted Cyrus’ Twitter profile URL.

Whoot? That is magic! 🤯

After creating fifteen completely different Google paperwork questioning if Cyros one way or the other injects JavaScript into Google Docs (which he would not), I discovered how this trick works.

Cyros’ web page leverages a nifty characteristic of the JavaScript Clipboard API (navigator.clipboard), and like each magic trick, as soon as you know the way it really works, it is stupidly easy.

Should you’ve been doing internet improvement lengthy sufficient, you would possibly bear in mind the doc.execCommand('copy') command. This outdated strategy to work together with the clipboard is now deprecated and changed by the Clipboard API. The newer API has the one function of interacting with the clipboard and works asynchronously. Yay!

However does the Clipboard API work all over the place immediately? At first look, navigator.clipboard appears to be cross-browser supported…

… however be careful! Wanting deeper into it, you will discover out that simply because navigator.clipboard is offered, it doesn’t suggest all performance is offered.

The way to place plain textual content within the clipboard

Placing textual content into the clipboard is simple utilizing the API. This is an instance.

await navigator.clipboard.writeText(
  "That is some cool copied textual content, is not it?"
);

Click on the button under and paste the brand new clipboard content material into the enter fields to verify it really works.

writeText covers many customary use instances, but it surely’s not what the magic trick makes use of. Let’s dig deeper!

The way to write completely different MIME varieties to the clipboard

As seen, putting textual content on the clipboard is shortly executed. However how would you deal with photos or different textual content codecs akin to richtext or HTML? Is it potential to place these into the clipboard with JavaScript, too?

There’s one other methodology accessible to place content material within the clipboard – clipboard.write.

await navigator.clipboard.write([
  new ClipboardItem({
    'text/plain': new Blob(["That's some cool plain text, isn't it?"], {
      kind: 'textual content/plain',
    }),
  }),
]);

clipboard.write would not settle for strings however ClipboardItems. The principle distinction between the 2 strategies is that if you wish to put something however plain textual content into the clipboard, you will need to outline the matching MIME kind utilizing a ClipboardItem.

It is extra code to put in writing however nonetheless a good expertise in my view. Candy!

Sadly, neither navigator.clipboard.write nor the worldwide ClipboardItem property is outlined in Firefox on the time of writing (each are behind the dom.occasions.asyncClipboard.clipboardItem flag).

I did not do the analysis however should you’re on the lookout for a cross-browser resolution to position issues aside from textual content within the clipboard, I am certain some libraries have you ever coated.

And here is annother instance to play with. It appears to be like the identical because the earlier one, however now it makes use of navigator.clipboard.write.

Refill your clipboard!

Are you able to already think about how the magic trick works now that you’ve got seen some code?

That is proper; the trick relies on completely different content material MIME varieties. Enter fields and textareas deal with pasted plain textual content simply advantageous, however there are clearly different accessible MIME varieties.

A clipboard might maintain sorts of picture/gif, picture/jpeg, textual content/rtf, the nice outdated textual content/html, and all kinds of fanciness.

And due to the Clipboard API, you are in charge of the MIME kind and may even retailer textual content and pictures in the identical write operation.

And it isn’t solely a single operation; it is even a single clipboard entry.

navigator.clipboard.write([
  new ClipboardItem({
    'text/plain': new Blob(["That's some cool plain text, isn't it?"], {
      kind: 'textual content/plain',
    }),
    'textual content/html': new Blob(
      [
        '<div style="/* some styles */">Oh yeah - text/html!</div>',
      ],
      {
        kind: 'textual content/html',
      }
    ),
  }),
]);

The instance above reveals how one can put completely different content material as plain textual content and HTML into your clipboard. 😲

Now it is solely a matter of the place you paste the content material to see this magic in motion.

A div with an contentEditable attribute can settle for and render HTML. 😲 Should you paste content material with the MIME kind textual content/html into it, it can render it simply advantageous.

To show it, hit the button under and see what occurs whenever you paste it into the enter fields and the editable div.

Cyrus’ trick makes use of this performance.

Initially, the magic trick places plain textual content into the clipboard, however afterward, it shops a ClipboardItem with a number of MIME varieties. textual content/plain holds his Twitter profile URL and textual content/html contains the ASCII artwork card. Google Docs then renders the pasted HTML, whereas the URL bar renders the plain textual content.

The way to examine your clipboard

Whereas I used to be debugging the magic trick, I found that inspecting your clipboard is not simple on MacOS. Regardless that the Finder supplies a approach to have a look at what’s within the clipboard (Finder > Edit > Present clipboard), it all the time reveals the plain textual content entry.

MacOS window showing the content of the clipboard. It's showing plain text.

I constructed a fast clipboard inspector utilizing the Clipboard API’s learn strategies. And right here it turned very fascinating.

Sadly, it is the identical story of Firefox not supporting advanced clipboard interactions (it is behind one other flag – dom.occasions.asyncClipboard.learn) and though Safari helps navigator.clipboard.write it has a shock for us.

MDN explains to make use of navigator.learn as follows:

attempt {
  const permission = await navigator.permissions.question({ identify: 'clipboard-read' });
  if (permission.state === 'denied') {
    throw new Error('Not allowed to learn clipboard.');
  }
  const clipboardContents = await navigator.clipboard.learn();
  for (const merchandise of clipboardContents) {
    
  }
} catch (error) {
  console.error(error.message);
}

It really works advantageous in Chromiums, but it surely seems that Safari would not assist navigator.permissions. 🤦‍♂️

This implies you need to test if navigator.permissions is offered, too. And whether it is, ask for permissions and if not, attempt to use navigator.clipboard.learn anyhow.

On this case, Safari reveals slightly “Paste” mini permission dialog. Should you do not click on it, navigator.clipboard.learn will throw an exception. Ufff…

Big button with a native MacOS "Paste" button on top of it.

This is a abstract on how one can use navigator.clipboard.learn:

  • For Chromiums it is best to use the Permissions API.
  • You’ll be able to’t learn the clipboard content material utilizing Firefox.
  • In Safari you simply should attempt it and see if it really works.

Have enjoyable with it under.

Aspect notice: not all clipboard content material is accessible

Inspecting and accessing text-based clipboard content material appeared to work advantageous in Chromiums. But when I copy a picture from the MacOS Finder navigator.clipboard.learn would not like that both and throws a No legitimate knowledge on clipboard exception.

JavaScript exception "No valid data on clipboard"

So, should you’re planning to make use of navigator.clipboard.learn, you need to characteristic detect the Permissions API and likewise make certain to attempt/catch all of your learn calls.

This little magic trick turned fairly a journey. However here is what I discovered:

  1. The Clipboard API lets you write a number of entries in numerous MIME varieties to the clipboard.
  2. Utilizing the Clipboard API continues to be a ache should you’re focusing on all main browsers.
  3. Not every part in your clipboard is accessible by way of JavaScript.

If you wish to study extra there’s an excellent article on the async Clipboard API on internet.dev and Thomas has you coated, too.

And with this, blissful pasting! 👋

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments