Quill: How to clear text formatting on paste

Created on 12 Dec 2016  路  16Comments  路  Source: quilljs/quill

Hi,

Short question, is there a way to clear content before pasting?
I do not want user to paste html content with different style, but want him to keep bullets, indent etc...

Thanks

Most helpful comment

This works quite well for me for cleaning text formatting:

this.quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
  delta.ops = delta.ops.map(op => {
    return {
      insert: op.insert
    }
  })
  return delta
})

If you want to get rid of everything (images, iframes, etc.) but plain text go with this solution:

this.quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
  let ops = []
  delta.ops.forEach(op => {
    if (op.insert && typeof op.insert === 'string') {
      ops.push({
        insert: op.insert
      })
    }
  })
  delta.ops = ops
  return delta
})

All 16 comments

For custom paste behavior you can either supply the appropriate matchers, or supply your own clipboard module.

Thank you for quick reply

Hi, I'm trying to configure matcher of clipboard module (for clearing formatting on paste) in my editorOption but without success. It would be much easier to see any example on documentation on this particular case. It would be very helpful for many beginners like me - beacuse it's not easy to do at first time... :)

I agree. I am trying too to set matcher do clean clipboard styling but I can't get any success.
Could you show us please an example of how doing this?
this is what I tried:

vm.quillEditor.clipboard.addMatcher(Node.TEXT_NODE, function (node) { return new Delta().insert(node.data); });

Thanks!

This works quite well for me for cleaning text formatting:

this.quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
  delta.ops = delta.ops.map(op => {
    return {
      insert: op.insert
    }
  })
  return delta
})

If you want to get rid of everything (images, iframes, etc.) but plain text go with this solution:

this.quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
  let ops = []
  delta.ops.forEach(op => {
    if (op.insert && typeof op.insert === 'string') {
      ops.push({
        insert: op.insert
      })
    }
  })
  delta.ops = ops
  return delta
})

How about this?

https://gist.github.com/ryanhaney/d4d205594b2993224b8ad111cebe1a13

import Quill from 'quill'
const Clipboard = Quill.import('modules/clipboard')
const Delta = Quill.import('delta')

class PlainClipboard extends Clipboard {
  onPaste (e) {
    e.preventDefault()
    const range = this.quill.getSelection()
    const text = e.clipboardData.getData('text/plain')
    const delta = new Delta()
    .retain(range.index)
    .delete(range.length)
    .insert(text)
    const index = text.length + range.index
    const length = 0
    this.quill.updateContents(delta, 'silent')
    this.quill.setSelection(index, length, 'silent')
    this.quill.scrollIntoView()
  }
}

export default PlainClipboard

@ryanhaney I have tried your solution but probably didn't understand how to apply, the toolbar and the editro disappeard... I'm from whithin vuejs so I initialized as follows:

import Quill from 'quill'
import VueQuillEditor from 'vue-quill-editor'

Quill.register('modules/clipboard', PlainClipboard, true)
Vue.use(VueQuillEditor, {
  format: ['bold', 'italic', 'list', 'header'],
  theme: 'snow',
  modules: {
    toolbar: [
      [{ header: [1, 2, false] }],
      ['bold', 'italic', 'list'],
      [{ list: 'bullet' }],
    ],
  },
})

and the editor that was as this:

immagine

turned into this:

immagine

Does this say anything to you? does yout snippet also strip bold and italics ofr just colors and fonts? I'd rather keep bold and italics as thoso are legitimate in my contest.

My snippet strips all formatting when content is pasted.

I suspect vue-quill-editor is doing something not desired.

Check out this jsfiddle: https://jsfiddle.net/hmfgvwx5/

On Thu, Jan 03, 2019 at 10:06:03AM -0800, ryanhaney wrote:

My snippet strips all formatting when content is pasted.

I suspect vue-quill-editor is doing something not desired.

Check out this jsfiddle: [1]https://jsfiddle.net/hmfgvwx5/

Mmh, this fiddleseems totally empty... didn't youforget saving?

sandro
*:-)

if i want to remain the img tag, how to modify? thanks

It would help to post more code examples to the documentation. For me, I was interested to strip everything but a certain whitelisted set of tags but it's not intuitive what I should do from this or the linked documentation.

I think for casual users it's a lot of inner concepts that need to be understood.

From what I'm reading it sounds like the matchers is more like playing whack a mole. You can paste in any amount of html and then you can write specific ones to swap b for strong, or blanket destroy all formatting.

For a simple integration where you might just have b, i, quote, list, numbered list, in the toolbar you would want to strip everything but those tags. I can't see a way of doing that.

I encapsulate the component in a div and use the onPaste event and generate a node and insert it. Could be another alternative.

<div onPaste={(event) => this.onPaste(event)} ...

Code event:

     onPaste(event) 
     {
        var brRegex = /\r?\n/g;
        let paste = (event.clipboardData || window.clipboardData).getData('text/plain');
        let divText = paste.split(brRegex)

        const selection = window.getSelection();
        if (!selection.rangeCount)
            return false;

        let div = document.createElement('div');
        divText.forEach(text =>
        {
            div.appendChild(document.createTextNode(text));
            div.appendChild(document.createElement("br"));
        });

        selection.deleteFromDocument();
        selection.getRangeAt(0).insertNode(div);

        event.preventDefault();
     }

Hi everyone,
based on some of your ideas i created a plugin, that removes all tags and attributes that are not supported. Out of the box it detects that by looking into the toolbar module, but it can also be configured manually.
I thought I post it here so others will not have to struggle :)

https://www.npmjs.com/package/quill-paste-smart

Hello everyone,
I had the same problem with the editor and found an easy solution for my case:

In the "formats" option I define the formats I want to allow in general to my editor.
These are the formats I want the user to be able to use on text in the editor.
Other formats are automatically removed when pasted into the editor.

After that I added clipboard matchers in the options which remove the previous allowed formats when pasting into the editor.
Works great for me.
All formats to set false or true are listed on this page: Quill formats

I hope this helps someone.

                var Delta = Quill.import('delta');
        var editor = new Quill('#' + element_id, {
            formats: [
                'bold',
                'strike',
                'underline',
                'color',
                'background'
            ],
            modules: {
                toolbar: [
                    ['bold', 'strike', 'underline'],     
                    [{ 'color': [] }, { 'background': [] }]
                ],
                clipboard: {
                    matchers: [
                        [ Node.ELEMENT_NODE, function(node, delta) {
                            return delta.compose(new Delta().retain(delta.length(), 
                            { color: false,
                              background: false,
                              bold: false,
                              strike: false,
                              underline: false
                            }
                            ));
                          }
                        ] 
                    ]
                }
            },
            placeholder: "銇撱亾銇儭銉€倰鍏ュ姏",
            theme: "snow"
        });

How about this?

https://gist.github.com/ryanhaney/d4d205594b2993224b8ad111cebe1a13

import Quill from 'quill'
const Clipboard = Quill.import('modules/clipboard')
const Delta = Quill.import('delta')

class PlainClipboard extends Clipboard {
  onPaste (e) {
    e.preventDefault()
    const range = this.quill.getSelection()
    const text = e.clipboardData.getData('text/plain')
    const delta = new Delta()
    .retain(range.index)
    .delete(range.length)
    .insert(text)
    const index = text.length + range.index
    const length = 0
    this.quill.updateContents(delta, 'silent')
    this.quill.setSelection(index, length, 'silent')
    this.quill.scrollIntoView()
  }
}

export default PlainClipboard

Hello @prodrammer, I tried using your code but this.quill.getSelection() returns null value every time I paste the content.

Was this page helpful?
0 / 5 - 0 ratings