Accepting All Changes With JavaScript

In previous installments we've looked at ways to detect the presence of track changes data and accept the changes using XSLT. This time round, we'll use JavaScript string parsing to accept all the changes. This technique is useful for any environments where an XSLT processor isn't readily available1. It should be reasonably straight forward to port the example code to other programming languages.

The first step is to remove the <change> tags within the document content. As the tag is always an empty tag, this is a very simple regular expression:

source = source.replace(/<change[^>]*>/gim, '');

Firstly the pattern <change[^>]*> is a pattern we'll use regularly to match a specific tag regardless of what attributes it has. Secondly, the three flags we specific, gim, mean that the expression is a global match and so will match multiple tags on the same line (g), case insensitive (i) and matches across multiple lines (m).

The second step is to find the start of the div containing the track changes element:

var startTrackChangesDiv = source.search(/<div [^>]*>\s*<trackchanges [^>]*>/gim);

We again use the standard pattern for matching a specific tag, but this time we combine two of them separated by whitespace. Firstly, we find the div start tag (<div [^>]*>), then any amount of pure white space (\s*) then the trackchanges start tag (<trackchanges [^>]*>). The startTrackChangesDiv variable now contains the offset of the div start tag.

To remove the DIV we need to know where it ends. This is much simpler, since the DIV is always inserted as the last thing in the body, so it's always the last closing div tag in the document.

var endTrackChangesDiv = source.lastIndexOf('</div>') + '</div>'.length;

Finally, we remove the entire div by extracting just the content before the start of the div and after the end of the div:

source = source.substring(0, startTrackChangesDiv) +
        source.substring(endTrackChangesDiv);

The complete function winds up as:

function acceptAllChanges(source) {
    source = source.replace(/<change[^>]*>/gim, '');
    var startTrackChangesDiv = source.search(/<div [^>]*>\s+<trackchanges [^>]*>/gim);
    var endTrackChangesDiv = source.lastIndexOf('</div>') + '</div>'.length;
    source = source.substring(0, startTrackChangesDiv) +
        source.substring(endTrackChangesDiv);
    return source;
}

The end result is the document as if all the changes had been accepted in the editor, ready for publishing to the world.

1 - while XSLT is available in modern browsers via JavaScript, it's often easier to use this string parsing approach than to handle the browser incompatibilities with XSLT.

Adrian spends his days working out ways to make life easier for Ephox clients through initiatives like LiveWorks! Previously a senior engineer, he has now moved on to the fancier sounding title of CTO.

Leave a Reply