Oli B Oli B - 1 year ago 228
Javascript Question

Codemirror plugin Tinymce inline mode IndexSizeError

I'm using tinymce in inline mode on a contenteditable div.

I have used the CodeMirror tinymce plugin before (not inline mode) with no issues, but it doesn't seem to work correctly in inline mode.
I've tried changing the config to

inline: false
and it works.

Clicking the Source button opens the HTML with CodeMirror and seems ok.
But when I click Ok to save it, it seems to work fine in Chrome and Firefox but in Safari it adds an
and I can't close the modal (however, I can see that it has changed the content of the editable div), clicking the Ok button again, it adds another
and console error. Clicking the cancel or X button just adds console error.

In the console I get
IndexSizeError: DOM Exception 1: Index or size was negative, or greater than the allowed value

In Chrome, it seems to work but I still get a console error
The given range isn't in document.

My tinymce config is below:

var tinymceEditText = tinymce.init({
selector: '.editableEl',
// target: ".editableElTinyMCE",
// theme: 'inlite',
inline: true,
plugins: [
'advlist autolink lists link image charmap anchor media',
'searchreplace visualblocks code fullscreen',
'template textcolor colorpicker hr fontawesome noneditable hr',
'insertdatetime contextmenu paste save codemirror',
'OBstock emoji_one'
toolbar1: 'save undo redo | styleselect | bold italic underline | forecolor backcolor | alignleft aligncenter alignright alignjustify | | code',
toolbar2: 'bullist numlist outdent indent | template | hr | anchor link unlink | image media OBstock emoji_one fontawesome ',
relative_urls: false,
remove_script_host: true,
templates: "/admin/JS/tinymce/js/tinymce/lists/template_list.php",
external_filemanager_path: "/filemanager/",
external_plugins: {"filemanager": "/filemanager/plugin.min.js"},
filemanager_title: "Uploaded Files", //the title of filemanager window default="Responsive filemanager",
filemanager_sort_by: "name", //the element to sorting (values: name,size,extension,date) default="",
filemanager_descending: 0, //descending ? or ascending (values=1 or 0) default="0"
codemirror: {
indentOnInit: true, // Whether or not to indent code on init.
smartIndent: true,
indentWithTabs: true,
saveCursorPosition: false,
path: '/admin/JS/codemirror-' + CODEMIRRORVERSION, // Path to CodeMirror distribution
config: { // CodeMirror config object
indentUnit: 4,
lineNumbers: true,
mode: "htmlmixed",
matchBrackets: true,
autoCloseBrackets: true,
autoCloseTags: true,
matchTags: {bothTags: true},
indentOnInit: true, // Whether or not to indent code on init.
smartIndent: true,
indentWithTabs: true,
lineWrapping: true,
paletteHints: false,
lint: true,
lintOnChange: true,
showHint: true,
HTMLHint: true,
CSSHint: true,
JSHint: true,
getAnnotations: true,
gutters: ['CodeMirror-lint-markers', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
foldGutter: true,
profile: 'xhtml', /* define Emmet output profile */
extraKeys: {
"Ctrl-Space": "autocomplete",
"F11": function (cm) {
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
"Esc": function (cm) {
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
jsFiles: [
cssFiles: [
'theme/' + CODETHEME + '.css',

EDIT: I've now managed to recreate this in Chrome and Firefox, by opening the source editor, clicking cancel, opening the source editor again and clicking Ok. Different errors in the console though:

Uncaught DOMException: Failed to execute 'setStart' on 'Range': There is no child at offset 3.

IndexSizeError: Index or size is negative or greater than the allowed amount

Answer Source

Finally managed to figure this one out be myself.

The issue wasn't with CodeMirror itself but actually tinymce's setContent function.

This fix for this was using the insertContent function instead and adding an extra setting in the tinymce.init

if(CMsettings.config.inlineFix) {
    editor.selection.select(editor.getBody(), true);
    editor.insertContent(codemirror.getValue().replace(cc, '<span id="CmCaReT"></span>'));
} else {
    editor.setContent(codemirror.getValue().replace(cc, '<span id="CmCaReT"></span>'));

This made the insert button work but the cancel button still had some weird behaviour with the cursor, so I ended up duplicating and modifying the whole plugin to remove the insert and cancel buttons, and add them myself in the html

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download