diff --git a/customize.dist/ckeditor-contents.css b/customize.dist/ckeditor-contents.css index e49cd16fd..4d2abae08 100644 --- a/customize.dist/ckeditor-contents.css +++ b/customize.dist/ckeditor-contents.css @@ -165,11 +165,13 @@ a > img { border-left: none; border-right-width: 4px; margin-right: -5px; + margin-left: -1px; } .cp-cursor-position[data-type="end"] { border-right: none; border-left-width: 4px; margin-left: -5px; + margin-right: -1px; } .cp-cursor-avatar { display: flex; diff --git a/www/code/inner.js b/www/code/inner.js index 36137a6f3..9e4d0a207 100644 --- a/www/code/inner.js +++ b/www/code/inner.js @@ -310,18 +310,24 @@ define([ }); framework.setContentGetter(function () { + CodeMirror.removeCursors(); var content = CodeMirror.getContent(); content.highlightMode = CodeMirror.highlightMode; previewPane.draw(); return content; }); + var cursorTo; + var updateCursor = function () { + if (cursorTo) { clearTimeout(cursorTo); } + if (editor._noCursorUpdate) { return; } + cursorTo = setTimeout(function () { + framework.updateCursor(); + }, 500); // 500ms to make sure it is sent after chainpad sync + }; framework.onCursorUpdate(CodeMirror.setRemoteCursor); framework.setCursorGetter(CodeMirror.getCursor); - editor.on('cursorActivity', function () { - if (editor._noCursorUpdate) { return; } - framework.updateCursor(); - }); + editor.on('cursorActivity', updateCursor); framework.onEditableChange(function () { editor.setOption('readOnly', framework.isLocked() || framework.isReadOnly()); diff --git a/www/common/sframe-common-codemirror.js b/www/common/sframe-common-codemirror.js index b7dfb531e..f72289623 100644 --- a/www/common/sframe-common-codemirror.js +++ b/www/common/sframe-common-codemirror.js @@ -402,6 +402,12 @@ define([ return html; }; var marks = {}; + exp.removeCursors = function () { + for (var id in marks) { + marks[id].clear(); + delete marks[id]; + } + }; exp.setRemoteCursor = function (data) { if (data.leave) { $('.cp-codemirror-cursor[id^='+data.id+']').each(function (i, el) { diff --git a/www/pad/cursor.js b/www/pad/cursor.js index ea3d7760c..491deb306 100644 --- a/www/pad/cursor.js +++ b/www/pad/cursor.js @@ -136,6 +136,15 @@ define([ end: cursorObj.selectionEnd }, ops); var cursorEl = makeCursor(id, cursorObj); + ['start', 'end'].forEach(function (t) { + // Prevent the cursor from creating a new line at the beginning + if (r[t].el.nodeName.toUpperCase() === 'BODY') { + if (!r[t].el.childNodes.length) { r[t] = null; return; } + r[t].el = r[t].el.childNodes[0]; + r[t].offset = 0; + } + }); + if (!r.start || !r.end) { return; } if (r.start.el === r.end.el && r.start.offset === r.end.offset) { // Cursor addCursorAtRange(cursorEl, r, cursorObj, ''); diff --git a/www/slide/inner.js b/www/slide/inner.js index 74254c7b5..6da8072c3 100644 --- a/www/slide/inner.js +++ b/www/slide/inner.js @@ -466,17 +466,23 @@ define([ }); framework.setContentGetter(function () { + CodeMirror.removeCursors(); var content = CodeMirror.getContent(); Slide.update(content.content); return content; }); + var cursorTo; + var updateCursor = function () { + if (cursorTo) { clearTimeout(cursorTo); } + if (editor._noCursorUpdate) { return; } + cursorTo = setTimeout(function () { + framework.updateCursor(); + }, 500); // 500ms to make sure it is sent after chainpad sync + }; framework.onCursorUpdate(CodeMirror.setRemoteCursor); framework.setCursorGetter(CodeMirror.getCursor); - editor.on('cursorActivity', function () { - if (editor._noCursorUpdate) { return; } - framework.updateCursor(); - }); + editor.on('cursorActivity', updateCursor); framework.onEditableChange(function () { editor.setOption('readOnly', framework.isLocked() || framework.isReadOnly());