title: How can my custom CKEditor plugin properly insert special iframes with a unique placeholder image?
body: <p>There exists an iframe plugin currently built into CKEditor that allows iframes to be inserted into the editor, but displays a rather ugly placeholder no matter what is in the iframe. I am working on a plugin that takes in a video ID from the user and builds an iframe that points to a page for displaying videos on our website. I would like for my users to see a placeholder that makes it clear that they have inserted a video:</p>
  
  <p>Ugly iframe placeholder:
  <img src="https://i.stack.imgur.com/rjyVo.png" alt="Ugly iframe placeholder"></p>
  
  <p>Pretty video placeholder:
  <img src="https://i.stack.imgur.com/gyiPH.png" alt="Pretty video placeholder"></p>
  
  <p>In order to get this far I added this bit of Javascript to my plugin's onOk function. I've included context:</p>
  
  <pre><code>onOk: function () {
      var videoID = this.getValueOf('info', 'video_id');
      var caption = this.getValueOf('info', 'caption');
      var display = this.getValueOf('info', 'display');
      var size = this.getValueOf('info', 'size');
      var width = size * 160;
      var height = size * 120;
  
      if (videoID.length &gt; 0) {
          if (display == 0) {
              e.insertHtml("&lt;a onclick=window.open(this.href,this.target,'width=" + width + ",height=" + height + "'); return false; target=newVideo href=/kbs/Video.aspx?videoId=" + videoID + "&amp;amp;Width=" + width + "&amp;amp;Height=" + height + "&gt;" + caption + "&lt;/a&gt;");
          } else {/*Here is the relevant code that is applied when display is set to embedded*/
              var iframeNode;
              //iframeNode = "&lt;iframe height='" + (height + 40) + "' width='" + (width + 40) + "' src='/kbs/Video.aspx?videoId=1&amp;height=" + height + "&amp;width=" + width + "' frameBorder='0' scrolling='no'&gt;&lt;/iframe&gt;");
              iframeNode = new CKEDITOR.dom.element('iframe');
              iframeNode.setAttribute('class', 'GROK-Video');
              iframeNode.setAttribute('height', height+40);
              iframeNode.setAttribute('width', width + 40);
              iframeNode.setAttribute('src', '/kbs/Video.aspx?videoId=1&amp;height=' + height + '&amp;width=' + width);
              iframeNode.setAttribute('frameBorder', 0);
              iframeNode.setAttribute('scrolling', 'no');
              var newFakeImage = e.createFakeElement(iframeNode, 'cke_GROKVideo', 'iframe', true);
              e.insertElement(newFakeImage);
          }
      }
  }
  </code></pre>
  
  <p>The magic is in the editor's createFakeElement function. It replaces my iframe with a dummy element that is displayed as whatever image I choose with this bit of CSS in my plugin.js:</p>
  
  <pre><code>editor.addCss(
      'img.cke_GROKVideo' +
      '{' +
          'background-image: url(' + CKEDITOR.getUrl(this.path + 'images/YouTubePlayButton.png') + ');' +
          'background-position: center center;' +
          'background-repeat: no-repeat;' +
          'border: 1px solid #a9a9a9;' +
          'width: 80px;' +
          'height: 80px;' +
      '}'
  );
  </code></pre>
  
  <p>Well I've gotten pretty far, but the problem arises when the source is viewed. The image turns back into an iframe and the iframe plugin replaces it with its own placeholder! Even worse, when the document is saved and reopened for editing, the same thing happens. How can I keep my play-button placeholder without breaking or replacing the built in iframe plugin placeholder? The pagebreak plugin seems to do something similar with div, but I'm not sure how CKEditor distinguishes between a pagebreak div and an ordinary div when it puts the fake elements in the editor. Has anyone tried something like this? I would prefer to not create a custom HTML element on my website just for this.</p>