Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quill.js extending Blot / Parchment changes not captured in delta

I am getting to grips with quill.js- I would like to be able to create a custom blot with content that is preset, but which I can change.. I have figured out how to create a block embed blot from the medium clone guide, but I have noticed that the created node is not being captured in the delta contents- I have set some text inside a styled div, and I would like to save those changes... I would also like to use this process for things like dynamic captions... it's important that I can save the delta. node.innerText = 'test test test' sets the initial content fine, but changes are not bound to the delta.

Is there some way to either nest blots within blocks? or can I bind the blot content with a delta somehow? any helpful example code would be greatly appreciated. Thank you.

class EditModuleBlot extends BlockEmbed {
  static create(value) {
    let node = super.create();
    node.setAttribute('style', value.style);
    node.innerText = 'test test test';
    return node;
  }

  static value(node) {
    return {
      style: node.getAttribute('style')
    };
  }
}
EditModuleBlot.blotName = 'editmodule';
EditModuleBlot.tagName = 'div';

and this is my Vue.js method for invoking it:

clickAddModule() {
  let range = this.quillInstance.getSelection(true);
  this.quillInstance.insertText(range.index, '\n', Quill.sources.USER);
  this.quillInstance.insertEmbed(range.index + 1, 'editmodule', {
    style: 'padding:10px;border: 2px dashed black;'
  }, Quill.sources.USER);
  this.quillInstance.setSelection(range.index + 2, Quill.sources.SILENT);
}

The delta json does not capture the div innerText:

{
  "insert": {
    "editmodule": {
      "style": "padding:10px;border: 2px dashed black;"
    }
  }
},

* update * don't use quill for block extensions, it doesn't handle them properly--- use Slate.js or Prose Mirror or CkEditor

like image 635
Sean D. Avatar asked Apr 20 '17 21:04

Sean D.


2 Answers

I kinda figured this out, I have to extend the value method with the innerText value, but in general I have determined that quill.js is not a great editor-- I feel somewhat misled by the issues with Quill, there are serious architectural mistakes that make it extremely difficult to extend, I'm not sure they will ever be able to resolve them-- they systematically remove references to these issues, they've closed almost 1500 issues but they haven't resolved anything, they also block users who post issues--- Quill does not handle blocks within blocks which makes advanced extensions like tables impossible, the delta format also doesn't handle breaks within blocks properly, so you can't even work around them-- it's kind of a disaster--- I would recommend looking at Slate.js or Prose Mirror, they're not as complete but crucially haven't made the same mistakes, they have first class data models...

Here is the code for the fix for quill, but use something else if you can.

class EditModuleBlot extends BlockEmbed {
  static create(value) {
    let node = super.create();
    node.setAttribute('style', value.style);
    node.innerText = 'test test test';

    return node;
  }

  static value(node) {
    return {
      style: node.getAttribute('style'),
      text: node.innerText //now text will show up in the delta
    };
  }
}
like image 172
Sean D. Avatar answered Nov 03 '22 08:11

Sean D.


Whether or not you agree with @SeanD's conclusion (I'm tempted to), you may (like me) be stuck trying to get a custom Blot working.

If you end up here, I'd like to document one related thing I discovered:

...

EditModuleBlot.blotName = 'editmodule';
EditModuleBlot.tagName = 'div';
EditModuleBlog.className = 'my-edit-module';

Adding a className to your Blot prevents Quill from assuming all divs should use this Blot. If you don't have a custom class name, pasted content will be all kinds of terrible as Quill tries to force it into this format.

like image 30
Josh Avatar answered Nov 03 '22 07:11

Josh