CkEditor5はブラウザに組み込める高機能なリッチテキストエディタです。
エディタ自体の多機能さはもちろんですが、ほどんどの機能がCKEditorのプラグインとして設定されており、機能拡張も考慮されて作られています。
今回はそのCKEditor5のちょっとしたカスタマイズを5点ご紹介します。
目次
ADs
CKEditor5はClassic・Inline・Baloon・Baloon Block・Documentの5種類があります。
フォルダで分かれていますので、使いたいタイプのエディタのフォルダ上で初回のみnpm installを実行し、ファイルを編集した後はnpm run buildを実行します。
そうしてできあがったbuildフォルダ内のckeditor.jsが本体です。
使いたいページでこのJSファイルをロードして使用します。
ビルドの方法を理解したところで、カスタマイズをやっていきます。
ブラウザからテキストをコピーしてCKEditorにCtrl + Vでペーストした場合、styleによる装飾やリンクがそのまま入ります。
Ctrl + Shift + Vでペーストすると装飾なしのプレーンテキストとしてペーストされます。
このCtrl + Shift + Vのペーストをデフォルトとするカスタマイズです。
clipboardpipeline.jsというファイルの以下の部分を
1 2 3 4 5 |
if ( dataTransfer.getData( 'text/html' ) ) { content = normalizeClipboardHtml( dataTransfer.getData( 'text/html' ) ); } else if ( dataTransfer.getData( 'text/plain' ) ) { content = plainTextToHtml( dataTransfer.getData( 'text/plain' ) ); } |
こうします。
1 2 3 4 5 |
if ( dataTransfer.getData( 'text/html' ) ) { content = plainTextToHtml( dataTransfer.getData( 'text/plain' ) ); } else if ( dataTransfer.getData( 'text/plain' ) ) { content = plainTextToHtml( dataTransfer.getData( 'text/plain' ) ); } |
これでCtrl + Vによるペースト時にもプレーンテキストとして貼り付けられます。
「フォーマットの削除」ボタンをクリックすると文字サイズや太字・斜体などの装飾が解除されますが、リンクはそのまま残ります。
これをリンクも含めて解除されるようにするカスタマイズです。
extend以降で下記構文を追加します。
1 2 3 4 5 6 7 |
editor.model.schema.extend( '$text', { allowAttributes: 'linkHref' } ); //以下の行を追加 editor.model.schema.setAttributeProperties( 'linkHref', { isFormatting: true }); //追加ここまで |
CKEditorはEnterで改行を挿入すると<p></p>が挿入され、Shift + Enterで<br>が挿入される仕様です。
つまり一行ごとに<p></p>となるのですが、単なるEnterによる改行も<br>となるようにするカスタマイズです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
あいうえお かきく けこ ↓ デフォルトだとこうなるのでこうなる <p>あいうえお</p> <p></p> <p>かきく</p> <p>けこ</p> ↓ こうしたい あいうえお<br> <br> かきく<br> けこ |
まずEnterによる改行挿入を無効にします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
this.listenTo( viewDocument, 'enter', ( evt, data ) => { data.preventDefault(); /* 処理の部分をコメントアウト // The soft enter key is handled by the ShiftEnter plugin. if ( data.isSoft ) { return; } editor.execute( 'enter' ); view.scrollToTheSelection(); */ }, { priority: 'low' } ); |
そして、Shift + Enterで実行される処理をEnterのみでも実行するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
this.listenTo( viewDocument, 'enter', ( evt, data ) => { data.preventDefault(); // The hard enter key is handled by the Enter plugin. /* isSoftはShiftを押されたとき if ( !data.isSoft ) { return; } */ editor.execute( 'shiftEnter' ); view.scrollToTheSelection(); }, { priority: 'low' } ); |
これでEnterによる改行も<br>が入るようになります。
前述の改行と同様の仕様ですが、CKEditorは改行があるテキストをペーストすると一行ごとに<p>で分割されてペーストされます。
これを<br>に変更するカスタマイズです。
デフォルトでは2連続の改行は<p>に、1つの改行は<br>にするという加工がされます。
それを2連続の改行を2つの<br>にするようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
text = text // Encode <>. .replace( /</g, '<' ) .replace( />/g, '>' ) // Creates a paragraph for each double line break. .replace( /\r?\n\r?\n/g, '</p><p>' ) // Creates a line break for each single line break. .replace( /\r?\n/g, '<br>' ) // Preserve trailing spaces (only the first and last one – the rest is handled below). .replace( /^\s/, ' ' ) .replace( /\s$/, ' ' ) // Preserve other subsequent spaces now. .replace( /\s\s/g, ' ' ); if ( text.includes( '</p><p>' ) || text.includes( '<br>' ) ) { // If we created paragraphs above, add the trailing ones. text = `<p>{ text }</p>`; } |
上記部分を以下のように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
export default function plainTextToHtml( text ) { text = text // Encode <>. .replace( /</g, '<' ) .replace( />/g, '>' ) // Creates a paragraph for each double line break. .replace( /\r?\n\r?\n/g, '<br><br>' ) // Creates a line break for each single line break. .replace( /\r?\n/g, '<br>' ) // Preserve trailing spaces (only the first and last one – the rest is handled below). .replace( /^\s/, ' ' ) .replace( /\s$/, ' ' ) // Preserve other subsequent spaces now. .replace( /\s\s/g, ' ' ); if ( text.includes( '</p><p>' ) || text.includes( '<br>' ) ) { // If we created paragraphs above, add the trailing ones. text = `<p>{ text }</p>`; } // TODO: // * What about '\nfoo' vs ' foo'? return text; } |
最後の
text = <p>${ text }</p>
;
をコメントアウトすると、大外の<p>も追加されなくなります。状況に応じて判断してみてください。
<br>による改行をまたいで装飾やリンクを設定した場合、改行の前後で2つの<span>や<a>として設置されます。
これをタグ内に<br>を含めるようにするカスタマイズです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
あいうえお<br /> かきくけこさしすせそ ↓デフォルトではリンクを貼るとこうなる あいう<a href="">えお</a><br /> <a href="">かきくけ</a>こさしすせそ ではなく あいう<a href="">えお<br /> <a href="">かきくけ</a>こさしすせそ こうなるようにする |
改行を通常テキストと同じように扱ってくれればよいので、その設定を追加します。
1 2 3 4 5 |
schema.register( 'softBreak', { allowWhere: '$text', isInline: true, inheritAllFrom: '$text' //これを追加 }); |
CKEditorは改行は<br>を挿入するのではなく、<strong>改行オブジェクト</strong>を挿入します。
この改行オブジェクトがaやspanに含まれることを許容していないため、前述のように改行単位で分割されてしまいます。
そこで改行を通常のテキストと同様にみなすという判定を追加することがこのカスタマイズになります。
ちなみに、CKEditorは
・太字プロパティを持ったテキストオブジェクト
・選択範囲オブジェクト
・カーソル位置オブジェクト
というふうにすべての要素をオブジェクトとして管理しています。
この点を把握してからソースを読んでみるとCKEditorの仕組みが分かりやすいと思います。
この5点のカスタマイズを反映したCKEditorはDEMOで試すことができます。
デフォルトの挙動と見比べてみてください。
編集内容は数文字~数行の修正という軽微なものばかりですが、CKEditorは巨大なライブラリのため、該当箇所を探し当てるのが何より大変です。
日本語の情報も少ないため、CKEditor使いの方はぜひ情報やノウハウを公開していきましょう。私もがんばります。
ADs
コメントはまだありません。