CKEDITOR -- cannnot restore cursor location after DOM modification -
i've read excellent answer pretty same question. however, have tried every technique @reinmar recommended, , none of them seem work.
the situation taking current html editor , wrapping pieces in span tags. set modified html , try restore user's cursor location. no technique works.
here simple example reproduce issue:
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script src="//cdn.ckeditor.com/4.4.7/standard/ckeditor.js"></script> </head> <body> <textarea id="cktest"><p>sometimes lorem. sometime ipsum. dolor.</p></textarea> <script type="text/javascript"> (function () { var checktimeout; var bookmark; var storecursorlocation = function(editor) { bookmark = editor.getselection().createbookmarks(); }; var restorecursorlocation = function(editor) { editor.getselection().selectbookmarks(bookmark); }; var validatetext = function(editor) { storecursorlocation(editor); var data = editor.document.getbody().gethtml(); data = data.replace("lorem", "<span class='err-item'>lorem</span>"); editor.document.getbody().sethtml(data); restorecursorlocation(editor); }; ckeditor.replace('cktest', { on: { 'instanceready': function(evt) { }, 'key' : function(evt) { cleartimeout(checktimeout); checktimeout = settimeout(function () { validatetext(evt.editor); }, 1000); } } }); })(); </script> </body> </html>
this code starts timer when user presses key, , waits 1 second after stop pressing keys check.
copy new .html file , run in favorite browser (i using chrome).
when ckeditor loads, use mouse place cursor somewhere in middle of text. press ctrl key , wait 1 second. see cursor jump start of text.
this code example uses
editor.getselection().createbookmarks();
to create bookmark. have tried:
editor.getselection().createbookmarks(true);
and
editor.getselection().createbookmarks2();
i have tried saving range using
var ranges = editor.getselection().getranges();
and
editor.getselection().selectranges(ranges);
in restorecursorlocation function.
(function () { var checktimeout; var bookmark; var storecursorlocation = function( editor ) { bookmark = editor.getselection().createbookmarks( true ); }; var restorecursorlocation = function( editor ) { //editor.focus(); editor.getselection().selectbookmarks( bookmark ); }; var validatetext = function( editor ) { storecursorlocation( editor ); var data = editor.document.getbody().gethtml(); data = data.replace( "spaceflight", "<span class='err-item'>spaceflight</span>" ); editor.document.getbody().sethtml( data ); restorecursorlocation( editor ); //fire event after dom changes if working widgets //editor.fire( 'contentdominvalidated' ); }; var editor = ckeditor.replace( 'editor1', { extraallowedcontent : 'span(err-item)', on: { "pluginsloaded" : function( event ){ editor.on( 'contentdom', function() { var editable = editor.editable(); editable.attachlistener( editable, 'keyup', function( e ) { cleartimeout( checktimeout ); checktimeout = settimeout(function () { validatetext( editor ); }, 100 ); }); }); } } }); })();
i have checked code, made corrections , above seems work fine. know said have tried me createbookmarks(true)
has done trick.
explanations , notes:
- you needed use
createbookmarks(true)
inserts unique span html. such bookmark not affected changes doing inside dom (there limits of course e.g. custom changes remove bookmark). - it clever use
getbody().gethtml()
,getbody().sethtml()
. if have usededitor.getdata()
have removed empty spans represent bookmarks. please note such approach may break widgets required firecontentdominvalidated
event after such changes. - i focusing editor before restoring selection “just in case” solution, have noticed editor selects bookmark without it. if however, reason, losing selection, thing use.
here have working example: http://jsfiddle.net/j_swiderski/nwbsywnn/1/
Comments
Post a Comment