JSFiddle - React, Tailwind, and code Playground

iFrame content for dual TinyMCE communication

by tonytlwu

HTML

<script src="https://tinymce.cachefly.net/4.3/tinymce.min.js"></script>
<div id="jumbotron">This is inside a real iFrame</div>
<div id="something">
  This bit isn't editable. The bit underneath is though.
</div>
<div class="editable">

  <h3>Here's a bunch of content</h3>
  <p>
    Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Vestibulum id ligula porta felis euismod semper.
  </p>
  <ul>
    <li>Risus Egestas</li>
    <li>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</li>
    <li>Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</li>
    <li>Adipiscing Magna Parturient Justo</li>
  </ul>
</div>

CSS

body {
  background: #fff;
  font-size: 14px;
  font-family: 'Open Sans';
  overflow: hidden;
}

h1,
h2,
h3 {
  font-family: Dosis;
  font-weight: 200;
  font-size: 1.65em;
  color: #00abd1;
}

.mce-tinymce-inline {
  display: none !important;
}

.editable {
  padding: 15px;
}

#something {
  border-bottom: 1px solid #ffdab1;
  padding-bottom: 25px;
  margin-bottom: 10px;
}

#jumbotron {
  margin: -10px -10px 15px;
  background-color: #000;
  color: #fff;
  text-align: center;
  padding: 15px 0;
  line-height: 1;
}

JavaScript

function processMessage (e) {
  var data = JSON.parse(e.data);
  if ( data.message ) {
  	switch (data.message) {
      case 'tinymceExecCommand':
      	var cmd = data.payload.cmd;
        var ui = data.payload.ui;
        var value = data.payload.value;
        tinymce.activeEditor.execCommand(cmd, ui, value);
        break;
    }
  }
}
if (window.addEventListener) {
  // For standards-compliant web browsers
  window.addEventListener("message", processMessage, false);
} else {
  window.attachEvent("onmessage", processMessage);
}

// Preview TinyMCE setup
tinymce.init({
  selector: '.editable',
  menubar: false,
  inline: true,
  setup: function(ed) {
    ed.on('change paste keyup mouseup focus blur', function(e) {
      var activeButtons = document.querySelectorAll('.mce-tinymce-inline .mce-toolbar-grp .mce-btn');
      var label = null;
      var activeLabels = [];
      var inactiveLabels = [];
      var msgObj = {
      	message: 'tinymceSetButtonStates',
        payload: {
        	activeLabels: [],
          inactiveLabels: []
        }
      };
      
      for (var i = 0, l = activeButtons.length; i < l; i++) {
        label = activeButtons[i].getAttribute('aria-label');
        if (label !== null) {
          if (activeButtons[i].classList.contains('mce-active')) {
          	activeLabels.push(label);
          } else {
            inactiveLabels.push(label);
          }
        }
      }
      msgObj.payload.activeLabels = activeLabels;
      msgObj.payload.inactiveLabels = inactiveLabels;
      
      parent.postMessage(JSON.stringify(msgObj), '*');
    });
  }
});