これをエディタの状態を確認するヘルパーで解決しました。
Template.document.helpers({
ck_deduplicate: function() {
var elt = document.getElementById('wikiedit');
if (elt) {
elt.innerHTML = '';
}
return this.wikipage.text;
}
});
ページのマークアップ:
#wikiedit(contenteditable="true")
{{{ ck_deduplicate }}}
ライブの保存、私は開かれたエディタの内容を保存して更新するように設定いくつかのよりスマートなコードで
を入力します。ライブセービングの最終解決策はthis questionです。
メテオの場合、以下の設定があります。まず、CKEditorの設定。文書を保存する前に、ブックマークを作成しDOMを操作してその要素を保存するようにしました(設定変更あり)。
Template.single_doc.rendered = function() {
console.log('rendered')
var wiki_id = Router.current().data().wikipage._id,
// the method that does the main job of setting up CKEditor
assign_change = function(ev) {
var e = ev.editor,
// timeout is stored to cancel if key is pressed within 2 seconds
save_timeout,
// data saving function
save_data = function() {
clearTimeout(save_timeout);
var bm = e.getSelection().createBookmarks()[0];
$(bm.startNode).attr('data-selection-bookmark','1');
console.log('update', {_id: wiki_id, text: e.getSnapshot()});
Meteor.call('doc.update', {_id: wiki_id, text: e.getSnapshot()})
};
// config updated to allow spans with our attribute
e.on('configLoaded', function() {
e.config.extraAllowedContent = "span[data-selection-bookmark]";
});
// watch document changed
e.on('change', function() {
console.log('change event');
clearTimeout(save_timeout);
save_timeout = setTimeout(save_data, 2000);
});
},
// unfortunately, had to wrap `editor.on('change')` in the assign_change above
// because when `.rendered` is triggered, CKEditor is not loaded yet.
// Have to wait for it.
assign_event = function() {
if (typeof(CKEDITOR) == 'undefined') {
setTimeout(assign_event, 100);
return;
}
CKEDITOR.on('instanceReady', assign_change);
};
assign_event();
}
次に、手動でCKEditorデータを更新し、必要に応じてカーソルを移動するヘルパーです。
Template.single_doc.helpers({
ck_deduplicate: function() {
// the helper either outputs the text into the document on document init
// or when the template is re-rendered, it updates CKEditor
var elt = document.getElementById('wikiedit');
// if dom works, then it's an update, should work with CKEDITOR
if (elt) {
// get its instance and create a range object (selection tool in CKE)
var e = CKEDITOR.instances.wikiedit,
range = e.createRange();
// load the data
e.loadSnapshot(this.wikipage.text);
// inside the text there is <span> with a bookmark
var sel = e.getSelection(),
// find the bookmark
$span = $(e.document.$).find('[data-selection-bookmark]');
// select before it
range.setStartBefore(new CKEDITOR.dom.node($span[0]));
// collapse to the start
range.collapse(true);
// do selection
range.select();
// remove the bookmark data
$(e.document.$).find('[data-selection-bookmark]').remove();
return '';
}
return this.wikipage.text;
}
});
1つの欠点は、これを同時に編集する2人では機能しないことです。彼らはいつもカーソルを盗みます。そのためには、メモリに格納された相対位置がうまくいくはずです。しかし、これは一時的な回避策と出発点としては十分です。これが他の人に役立つことを望みます。