Search code examples
javascriptangulartypescriptquillngx-quill

ngx-quill/quill.js strip custom blots from innerHTML


Title might be misguiding, however i don't know how to title it better. What i want to achieve is twitter-widget like embedding for my custom blots. For that I've created my sample "renderer" class:

class TestRenderer {
    render(id: number, node: HTMLElement) {
        node.innerHTML = `<h1>ELEMENT ${id}</h1>`;
    }
}

And normal Quill blot class that extends BlockEmbed

export class TestBlot extends BlockEmbed {
  static blotName = 'test';
  static tagName = 'test-embeded';
  static className = 'test-embeded';

  static create(id: any) {
    const node = super.create();
    node.dataset.id = id;
    RENDERER.render(id, node);


    node.addEventListener('click', (e) => {
      e.preventDefault();
      RENDERER.render(666, node);
    });

    return node;
  }

  static value(domNode: HTMLElement) {
    return domNode.dataset.id;
  }
}

I thought I used similar approach as twitter-widget tweet-embed which i've got from official quill parchment tutorial, but HTML output is different. The twitter is stripped from all inner HTML, its just simple:

<twitter-embeded class="twitter-embeded" data-id="464454167226904576" contenteditable="false" style="cursor: pointer;"></twitter-embeded>

And my custom blot element looks like this:

<test-embeded class="test-embeded" data-id="742878714"><h1>ELEMENT 742878714</h1></test-embeded>

When i manually remove <h1>ELEMENT 742878714</h1> editor still recognizes its content and displaying everything properly. Its very ineffective way, and i want to avoid checking whole Quill HTML content and stripping all my custom elements from innerHTML.


Solution

  • Ok, seems like strange quills behavior. Its just the way Quill handling async requests, so simply change to "renderer" class solved my problem:

    export class TestRenderer {
        render(id: number, node: HTMLElement) {
            node.innerHTML = ``;
            setTimeout(() => {
                node.innerHTML = `<h1>ELEMENT ${id}</h1>`;
            }, 1000);
        }
    }
    

    Output from this is as expected:

    <test-embeded class="test-embeded" data-id="108962878"></test-embeded><p><br></p>
    

    Closed.