Vlad V.
Vlad V.

Reputation: 11

How to set cursor position in CodeMirror in accordance to cursor position in TinyMCE 5?

I have a form on the webpage, which uses TinyMCE 5 to edit one of the fields. In my configuration, the TinyMCE uses CodeMirror in order to inspect/edit the html-code of the field's content. When the CodeMirror starts, it positions the cursor at the beginning of the code, but I would like to find a way how to set initial cursor position in CodeMirror to the place in html-code, which corresponds to the position of cursor in TinyMCE. In other words, if the cursor is located e.g. inside a table in TinyMCE when I call the CodeMirror (by pressing "code" button on menu panel), I would like the CodeMirror to set its cursor close to or inside the <table> tag in the html-code.

The solution, which comes to my mind, is to get the tag name at the cursor position in TinyMCE, then start CodeMirror, find the line in CodeMirror, which contains that tag, and finally position the cursor to that line. But I don't really understand how to implement this. Should I edit the codemirror/plugin.js or there is another less destructive way?

Any ideas are welcome! Thanks!

Upvotes: 0

Views: 1179

Answers (1)

Vlad V.
Vlad V.

Reputation: 11

After some research I've found the answer to my question. I hope it will be helpful for someone else.

First of all, the functionality described in my question has already been implemented in the CodeMirror. It's controlled by the CodeMirror option saveCursorPosition. If it's set to true, CodeMirror positions cursor to the place in the html-code, which corresponds to the position of the cursor in the TinyMCE editor and vice versa.

But the most funny thing is that all of the above doesn't work :) In order to save the cursor position, the tinymce-codemirror plugin adds the invisible span to the html-code of the TinyMCE content (<span style="display: none;" class="CmCaReT">&#x0;</span>). Just before the CodeMirror instance is activated, the plugin replaces that span with invisible character (UTF code = 0), otherwise the span tag would be visible in the CodeMirror.

This replacement is performed by the following code (in the source.html file located at the same folder as plugin.js and plugin.min.js): html.replace(/<span\s+style="display: none;"\s+class="CmCaReT"([^>]*)>([^<]*)<\/span>/gm, String.fromCharCode(chr)). The regular expression should find all those span-s, but it doesn't! The reason is that style and class attributes appear to be in opposite order: the class is the first, then follows the style. (I think this is the surprise made by the browser - I use Firefox.)

Now, we have to change the regular expression to /<span\s+(style="display: none;")*\s*(class="CmCaReT")\s+(style="display: none;")*([^>]*)>([^<]*)<\/span>/gm , which catches the span tag regardless of the order of its attributes.

So, now jumping between corresponding positions in TinyMCE and CodeMirror works fine!

Upvotes: 1

Related Questions