GetmeUK / ContentTools

A JS library for building WYSIWYG editors for HTML content.
http://getcontenttools.com
MIT License
3.95k stars 395 forks source link

How to properly live insert HTML #478

Closed Arthur-min closed 6 years ago

Arthur-min commented 6 years ago

Hello,

I made a script in order to insert html: when you click on a button, it opens a modal with multiple HTML sources and insert it on click.

For example, there is a block, I use data-fixture to be able to edit desired parts with ContentTools.

<div class="row">
    <div class="col-12">
        <h1 data-fixture>Title</h1>
    </div>
</div>

<div class="row">
    <div class="col-6">
        <p data-fixture>
            Textarea
        </p>
    </div>

    <div class="col-6">
        <p data-fixture>
            Textarea
        </p>
    </div>
</div>

When you click on a block:

var html = event.currentTarget.getAttribute('data-html');
var div = document.createElement('div');

div.innerHTML = html;
wrapper.appendChild(div);
editor.syncRegions();

See example : https://preview.ibb.co/i6Ds3H/ex.png

The problem is related to the history, when I Cancel the ContentTools edition, it throw an error:

content-tools.js:8820 Uncaught TypeError: Failed to execute 'replaceChild' on 'Node': parameter 1 is not of type 'Node'

_EditorApp.prototype.revertToSnapshot = function(snapshot, restoreEditable) {
      ...
      for (name in _ref) {
        region = _ref[name];
       ...
        if (region.children.length === 1 && region.children[0].isFixed()) {
          wrapper = this.constructor.createDiv();
          wrapper.innerHTML = snapshot.regions[name];
          domRegions.push(wrapper.firstElementChild);
          region.domElement().parentNode.replaceChild(wrapper.firstElementChild, region.domElement());
        } ...

wrapper.firstElementChild is null.

How can I revert to the initial state without browsing each inserted regions?

Thank you!