8

編集できないコンテンツをテキスト フローに挿入する CKEditor プラグインの開発に問題があります。範囲関数を利用しようとしましたが、ドキュメントが優れていないため、ほとんど成功していません。したがって、いくつかのテキストが与えられた場合、プラグインが「[[uneditable stuff]]」を挿入し、WYSIWYG 表示でそれをスパンでラップして、色でスタイル設定できるとします。

<p>This is some text[[uneditable stuff here]]</p>

編集不可能なものを最初に挿入するとき、ユーザーが入力を続けるか、Enter キーを押して新しい行を入力できるようにしたいと考えています。次のコード (ここで取得した: CKEditor でカーソル位置をテキストの終わりに設定する方法) は Firefox では機能しますが、(当然のことながら) IE9、8、または 7 では機能しません。

var s = editor.getSelection();
editor.insertElement(e); // element 'e'= a span created earlier
var p = e.getParent();
s.selectElement(p);
var selected_ranges = s.getRanges();
selected_ranges[0].collapse(false);  //  false = to the end of the selected node
s.selectRanges(selected_ranges);  // putting the current selection there

だから私がしたいのは、カーソルが「^」の位置に移動することです:

<p>This is some text<span>[[uneditable stuff here]]</span>^</p>

新しい要素が行末にない場合、作成後、カーソルは次の場所に移動する必要があります。

<p>This is some text<span>[[uneditable stuff here]]</span>^ with more text after the new element</p>

FF では、新しい要素の後の位置ではなく、行末にカーソルを取得できます。IE では、カーソルはまだ新しい SPAN 内にあり、入力時に表示され、スパンの css カラーのままであり、SOURCE ビューに切り替えると、テキストが表示されなくなります (編集できないスパンであるため)。

range.setStartAfter メソッドがあることは知っていますが、FF/Chrome でもまったく機能させることができませんでした。

CKEditor で範囲と選択の方法を使用することを本当にうまく処理できる人はいますか? 私はしないことを知っいます!

editor.insertElement を使うだけではダメだと思い始めたので、まだ理解していない FakeElement (insertBogus?) 関数について学習する必要があります。リンクや画像などのストック プラグインには、この問題はないようです。

4

3 に答える 3

7

私はこれを解決するためにいくつかの卑劣なことをしなければなりませんでしたが、それは解決されました: . それで、実際のスパンを挿入してから、ダミーを挿入します。ただし、新しいアイテムを作成する場合のみ。

したがって、これは「選択したアイテムの編集を扱っていない場合」セクションに含まれます。ここで、「a」はエディター インスタンス、「e」は目的の編集不可アイテム、「f」はダミー スパンです。

var e=new CKEDITOR.dom.element('span',a.document);
e.setAttributes({// stuff to create our element});
var f=new CKEDITOR.dom.element('span',a.document);
f.setAttributes({
    'class':'dummyF'
});
f.setText(' '); // that's just one space

// after section dealing with editing a selected item, in "else":
var sel = a.getSelection(); // current cursor position
a.insertElement(e); // the real new element
if(CKEDITOR.env.ie || CKEDITOR.env.webkit){ // IE & Chrome like this way
    f.insertAfter(e);
    sel.selectElement(f);
}
else { //FF likes this way (to ensure cursor stays in the right place)
    f.insertAfter(e);
    var rangeObjForSelection = new CKEDITOR.dom.range( a.document );
    rangeObjForSelection.selectNodeContents( f );
    a.getSelection().selectRanges( [ rangeObjForSelection ] );
}

私は自分のコードを完全には理解していないことを認めなければなりません。私は何時間もの試行錯誤を経てそこにたどり着きました。ああ、残りの 'f' 要素を取り除くために、htmlFilter ルールを追加する必要がありました。

e.addRules({
  // e is the htmlFilter: applied to editor data before/upon output
  elements:{
    span:function(s){ // 's' is any spans found in the editor
        if(s.attributes&&s.attributes['data-cke-myelement']) {
            //stuff to do with my element
        }
        else if(s.attributes['class']=='dummyF') { //CKEDITOR.env.ie&&
            // for dummy spans to deal with "can't type or hit enter after new element" problem
            realtext = new String(s.children[0]['value']);
            realtext.replace(/^&nbsp;/,'');
            s.children[0]['value'] = realtext;
            delete s.name;
        }
    }
  }
});

また、スパンを削除する前に「nbsp」エンティティを置き換えなければならなかった理由を覚えていないことも付け加えておく必要があります。しかし、それは機能します。そして、「s」の代わりに「s.name」を使用して削除する理由がわかりません。

それが誰かを助けることを願っています。

于 2012-11-09T14:14:08.490 に答える