Table of contents

Paste substitutions

Sometimes you need to handle pasted content with your plugin. For example, pasted headers should be handled by Header Tool and pasted images — by Image Tool.

Tools API allows you to substitute pasted HTML tags, Files and string patterns. To make it work you need just two things: static getter pasteConfig and onPaste method.

Static getter pasteConfig should return an object with paste substitutions configuration:

  1. tags — array of tags to substitute
  2. files — object with mimeTypes and extensions arrays
  3. patterns — object where key is your pattern name and RegExp pattern as value

For SimpleImage we need to substitute img tags, handle files with image/* MIME-type and handle URLs to images.

For each of substitutions (tags, files, and patterns) you need just one method — onPaste. It accepts CustomEvent object as an argument which can have three types: tag, file, and pattern. Each event provides info about pasted content in detail property.

  • Tag event contains pasted HTML element in detail.data property.
  • File event contains pasted file object in detail.file property.
  • Pattern event contains pasted string in detail.data property and pattern name in detail.key.

Lets add them step-by-step.

To create our Image Blocks from pasted img tags we need to specify tags key of pasteConfig and implement a handler for tag event type at onPaste:

class SimpleImage { // ... toolbox static getter static get pasteConfig() { return { tags: ['IMG'] } } // ... constructor // ... render // ... _createImage // ... save // ... validate // ... renderSettings // ... _toggleTune // ... _acceptTuneView onPaste(event){ switch (event.type){ case 'tag': const imgTag = event.detail.data; this._createImage(imgTag.src); break; } } }

Thats it. Now you can open any external article, copy a text with images and paste to the Editor. You should see Image Blocks created from pasted content.

To create Blocks from pasted (by CTRL+V or by drag-n-drop) files, add the files key to the pasteConfig and handle a file event type with onPaste:

class SimpleImage { // ... toolbox static getter static get pasteConfig() { return { // ... tags files: { mimeTypes: ['image/*'], extensions: ['gif', 'jpg', 'png'] // You can specify extensions instead of mime-types } } } // ... constructor // ... render // ... _createImage // ... save // ... validate // ... renderSettings // ... _toggleTune // ... _acceptTuneView onPaste(event){ switch (event.type){ // ... case 'tag' case 'file': /* We need to read file here as base64 string */ const file = event.detail.file; const reader = new FileReader(); reader.onload = (loadEvent) => { this._createImage(loadEvent.target.result); }; reader.readAsDataURL(file); break; } } }

For now you can try to drag-n-drop or CTRL+V (CMD+V) image files into the Editor. Our Image Blocks should be created.

Let's add ability to create Image Blocks by pasting an image URL to the empty paragraph.

For doing this, we should add a patterns key to the pasteConfig and implement a handler for pattern event type at onPaste

class SimpleImage { // ... toolbox static getter static get pasteConfig() { return { // ... tags // ... files patterns: { image: /https?:\/\/\S+\.(gif|jpe?g|tiff|png)$/i } } } // ... constructor // ... render // ... _createImage // ... save // ... validate // ... renderSettings // ... _toggleTune // ... _acceptTuneView onPaste(event){ switch (event.type){ // ... case 'tag' // ... case 'file' case 'pattern': const src = event.detail.data; this._createImage(src); break; } } }

Now try to copy image URL from somewhere and paste it to the empty paragraph — an Image Block should be rendered.

In next chapter we will learn how to sanitise output data from unsupported HTML entities.