View on GitHub

CoreMedia CKEditor 5 Plugins

CoreMedia's CKEditor 5 Plugins provides plugins for CKEditor 5 with focus on integration into CoreMedia CMS.

Download this project as a .zip file Download this project as a tar.gz file

CoreMedia Differencing Plugin

API Documentation

Module: @coremedia/ckeditor5-coremedia-differencing

Other than possibly suggested by the plugin-name, this plugin does not take care of calculating differences by itself. It is meant to ensure, that differencing data as generated in CoreMedia Studio are forwarded to editing view, so that CSS rules can be applied to it, to highlight changes, additions and deletions.

Installation

pnpm install @coremedia/ckeditor5-coremedia-differencing
import Differencing from "@coremedia/ckeditor5-coremedia-differencing/Differencing";

ClassicEditor.create(document.querySelector('#editor'), {
  plugins: [
    Differencing,
    /* ... */
  ],
}).then((editor) => {
  /* By default, plugin is not enabled. */
  newEditor.plugins.get("Differencing")?.activateDifferencing();
});

Note, that to ease set up of two CKEditors for the same with the same configuration despite the Differencing plugin, the plugin is disabled by default.

To enable it in certain context (like the differencing view in CoreMedia Studio), you have to explicitly enable the plugin prior to loading the augmented data from server.

CoreMedia Server-Side Differencing

In CoreMedia Studio, differences of CoreMedia RichText are evaluated on the server. The corresponding response is similar to this:

<div xmlns="http://www.coremedia.com/2003/richtext-1.0"
     xmlns:xdiff="http://www.coremedia.com/2015/xdiff">
  <p>
    Lorem ipsum dolor sit amet,
    <strong class="color--red background-color--purple">
      <xdiff:span
              xdiff:class="diff-html-changed"
              xdiff:changes="&lt;b&gt;Strong&lt;/b&gt; style added with class color--red background-color--purple."
              xdiff:id="changed-diff-0">
        consectetuer
      </xdiff:span>
    </strong> adipiscing elit.</p>
</div>

The (yet) only relevant attributes used from server-side differencing are xdiff:class applied to xdiff:span and xdiff:changetype applied to image elements.

xdiff:class may have one of these values:

xdiff:changetype is used for images and its value may be one of these:

The (yet) ignored attributes (but forwarded to editing view) are:

Artificial xdiff:br

Detecting added or removed newlines throughout the CKEditor view and model hierarchy is at least challenging. To ease detecting such added or removed newlines, the default data-processing for CoreMedia RichText 1.0 transforms such added/removed newlines to xdiff:br elements. In this early processing stage, they are easy to detect.

The xdiff:br elements otherwise hold the same attributes as any xdiff:span, which is the element they originated from in the original server response.

CSS Styling

xdiff:span

As xdiff:span is forwarded to editing view, it may be used for highlighting changes, as for example:

xdiff\:span[xdiff\:class="diff-html-added"] {
  color: rgba(92, 160, 63, 1);
  text-decoration: underline;
}
xdiff\:span[xdiff\:class="diff-html-removed"] {
  color: rgba(196, 19, 19, 1);
  text-decoration: line-through;
}
xdiff\:span[xdiff\:class="diff-html-changed"] {
  color: rgba(255, 255, 255, 1);
  background-color: rgba(92, 160, 63, 1);
}
xdiff\:span[xdiff\:class="diff-html-conflict"] {
  color: rgba(255, 255, 255, 1);
  background-color: rgba(196, 19, 19, 1);
}

xdiff:br

As stated in the introduction, <xdiff:br/> is an artificial element. It gets transformed from an empty <xdiff:span/> in the data-processing stage as provided for CoreMedia RichText 1.0.

It is meant to be used to highlight added/removed newlines, for example as follows:

xdiff\:br[xdiff\:class="diff-html-added"]::before {
  /* Some symbol to represent a new-line character. */
  content: '↩';
  height: 16px;
  position: absolute;
  margin-left: 3px;
}

img and xdiff:changetype

If applying rules to <img> elements, it is important to understand, that CKEditor adds the corresponding xdiff:changetype to the surrounding element of the image. For ImageInline plugin, this is some <span> having class attribute image-inline, for images kept via General HTML Support (GHS), it is a <span> with class attribute html-object-embed.

To support CKEditor with or without image plugin and possible fallback to GHS, corresponding CSS rules may look like this:

span.image-inline[xdiff\:changetype="diff-added-image"] > img,
span.html-object-embed[xdiff\:changetype="diff-added-image"] > img {
  box-sizing: border-box;
  outline: 2px solid rgba(92, 160, 63, 1) !important;
  outline-offset: -2px;
}
span.image-inline[xdiff\:changetype="diff-removed-image"] > img,
span.html-object-embed[xdiff\:changetype="diff-removed-image"] > img {
  box-sizing: border-box;
  outline: 2px solid rgba(196, 19, 19, 1) !important;
  outline-offset: -2px;
}
span.image-inline[xdiff\:changetype="diff-conflict-image"] > img,
span.html-object-embed[xdiff\:changetype="diff-conflict-image"] > img {
  box-sizing: border-box;
  outline: 4px dashed rgba(196, 19, 19, 1) !important;
  outline-offset: -4px;
}

Assumptions

Requirements