CKEditorを使ったリッチテキストエディターを作りたい。でもって見た目は全然別にしたい、いっそツールバーとか表示させないで、こちらの任意のボタン類を押したら該当機能を起動するようにしたい。
という流れ。
最低限必要なファイル
- ckeditor.js
- (config.js)
- contents.css
- lang/ja.js
- (plugins/icons.png)
- (skins/moono/editor.css)
- (skins/moono/icons.png)
- styles.js
括弧書きは空の状態で置いておく。(画像は1x1で。) なくても動くがファイルを読み込むので、HTTPステータスコード200にしてキャッシュさせるため。
あとこれでなんとなく動くけど、幾つかの機能はエラーになる。クリップボードとか。
設定
toolbar
toolbarGroups
toolbarCanCollapse: true
ツールバーを畳めるように。
toolbarStartupExpanded : false
ツールバーを最初から畳むように。toolbarCanCollapse:true
と併用。
非表示にするのはないか。
contentsCss
RTEの編集欄に読み込むCSSファイル名。初期値はCKEditorのcontents.css
。
removePlugins
プラグイン無効化。カンマ,
区切りでプラグイン名を指定する。
"elementspath"
フッターに現在位置の要素パスを表示するやつ。
"contextmenu"
, "…,liststyle,tabletools"
CKEditorの拡張コンテキストメニューをやめる。依存関係にある他のプラグインも止める。
plugins
removePlugins
の逆、使うプラグインだけを記述する。これの最小構成を探すと、こんな感じだった。
plugins:
// "dialogui,dialog,about,a11yhelp,dialogadvtab," +
"basicstyles," +
// "bidi,blockquote," +
"clipboard," +
// "button,panelbutton,panel,floatpanel,colorbutton,colordialog,templates,menu," +
"div," +
// "resize," +
"toolbar," +
// "enterkey,entities,popup,filebrowser,find,fakeobjects,flash,floatingspace,listblock,richcombo," +
"font," +
// "forms,format,horizontalrule,htmlwriter,iframe," +
"wysiwygarea,image," +
// "indent,indentblock,indentlist,smiley," +
"justify," +
// "menubutton,language,link,list,magicline,maximize,newpage,pagebreak,pastetext,pastefromword,preview,print,removeformat,save,selectall,showblocks,showborders,sourcearea,specialchar,stylescombo,tab,table,undo,wsc" +
"",
クリップボードは使ってないんだけど、ないと文字サイズ変更時にちょっと動作が妙になった。(文字の大きさを変えてもIビーム?のサイズが変わらない。)
on.instanceReady : handler
起動時のコールバック。
// ヘッダー、フッターを非表示にする例
var editor = CKEDITOR.replace($textarea[0], {
on: {
instanceReady: function (event) {
var id = event.editor.id;
// 上部を非表示にしつつ、全体の高さは維持する
var $top = $('#'+id+'_top');
var $contents = $('#' + id + '_contents');
$contents.height($contents.height() + $top.outerHeight(true));
$top.hide();
}
}
});
こんなやり方で大丈夫か?
fontSize_sizes
var editor = CKEDITOR.replace($textarea[0], {
fontSize_sizes: '小/16px;中/24px;大/48px;'
});
colorButton_colors
var editor = CKEDITOR.replace($textarea[0], {
colorButton_colors: ''
});
文書にはcolorButton_colors: 'FontColor1/FF9900,FontColor2/0066CC,FontColor3/F00'
と例示されていたが、名前は無効な感じ。
browserContextMenuOnCtrl : false
初期設定では、RTE上で右クリックするとCKEditorのコンテキストメニューが表示され、Ctrlないしcommandを押しながら右クリックすると本来のものが表示される。
この設定をしておくと、それが逆になる。
逆じゃなくて拡張メニューを完全にやめたいんだけど……。
allowedContent
編集欄に出力を許す要素、属性、クラス、スタイルを定義する。
var editor = CKEDITOR.replace($textarea[0], {
allowedContent:
"div{text-align}; p{text-align};" +
"span{color,font-size}; img[!src,width,height,alt]; a[!href];"
});
定義の仕方が独特。区切りはセミコロン;
(一部省略可能だが書いておけば間違いない)。要素は要素名だからわかる。属性は各括弧[ ]
、クラスは丸括弧( )
、スタイルは波括弧{ }
にカンマ,
区切りで羅列し、!
を冒頭に付けたものは、それがないと駄目になる。それぞれ*
が使える。
true
で全通しだけど、危険な香りがするよ。
メソッド
editor = CKEDITOR.replace(elem, options)
elem
はIDを文字列で指定しても良い。
options
はconfig.js
での設定と同じ。
var editor = CKEDITOR.replace($('#the-textarea')[0], {
toolbarGroups: [
{ name:"insert", groups: [] } // これがないと画像が表示されない
],
removePlugins: 'elementspath' // 要素パスを非表示
});
toolbarGroups
でname:"insert"
がないと、本文の画像が表示されない。未調査。
editor.commands
登録済みのコマンド一覧。
editor.execCommand(command, option)
editor.commands
に登録されているコマンドを実行する。
editor.execCommand('bold'); // 選択中の文字列を太字化
editor.commands
に登録されていても、ツールバーにボタンが表示されていないと利用出来なかった。何か有効化の処理が必要らしい。
editor.setData(html, callback)
既存の内容を破棄し、任意のHTMLを設定する。非同期で実行される。
editor.getData()
HTMLを得る。こちらは同期で実行される。
editor.insertHtml(html)
任意のHTMLコードを、現在位置に挿入する。
ブロック要素を追加しても、その内容だけが既存のブロック要素の内側へ展開されたりする。何かやり方があるのかな?
editor.insertText(text)
任意の文字列を、現在位置に挿入する。HTMLコードはエスケープされる。
editor.insertElement(element)
element
はDOMオブジェクトじゃなくて、CKEDITOR.dom.elementオブジェクト。
var tag = '<img src="img.png" />';
var element = CKEDITOR.dom.element.createFromHtml(tag);
editor.insertElement(element);
こっちのやり方なら、<h1>
の途中に<h1>
を挿入出来る。(ちゃんと分割してくれる。)
editor.applyStyle(style)
選択中の部分に任意のスタイルを適用する。
style
はCKEDITOR.styleオブジェクト。
var style = new CKEDITOR.style({
attributes: {
class: 'my-great-style and-other-class'
},
element: 'em',
name: 'My Great Style',
styles: { color:'red' }
});
editor.applyStyle(style);
同じスタイルが二重三重に追加される事はない。(べんり!)
editor.removeStyle(style)
var style = new CKEDITOR.style({
element: 'em',
name: 'My Great Style',
styles: { color:'red' }
});
editor.applyStyle(style);
editor.removeStyle(style);
定義済みコマンド
一部、fullをダウンロードしないと駄目ぽ。
機能 | コマンド名 | グループ | ボタン | マークアップ |
---|---|---|---|---|
太字 | bold |
basicstyles |
Bold |
<strong> |
斜体 | italic |
basicstyles |
Italic |
<em> |
打ち消し線 | strike |
basicstyles |
Strike |
<s> |
下線 | underline |
basicstyles |
Underline |
<u> |
左寄せ | justifyleft |
align |
JustifyLeft |
<p> |
中央寄せ | justifycenter |
align |
JustifyCenter |
<p style="text-align: center;"> |
右寄せ | justifyright |
align |
JustifyRight |
<p style="text-align: right;"> |
文字サイズ | なさそう | styles |
FontSize |
<span style="font-size:72px;"> |
文字色 | なさそう | colors |
TextColor |
<span style="color:#FF0000;"> |
背景色 | なさそう | colors |
BGColor |
<span style="background-color:#FF0000;"> |
画像 | なさそう | insert |
Image |
<img alt="" data-cke-saved-src="…" src="…" style="width: …px; height: …px;"> |
グループはtoolbarGroups:[{name:'basicstyles'}]
、ボタンはtoolbar:[['JustifyLeft']]
のようにconfigで使う。
文字のサイズと色、背景色はexecCommand()
じゃなくてapplyStyle()
に統合されてるみたい。というか、基本的に全部applyStyle()
で良いんじゃないかって気がしてる。
その他
編集欄の操作を監視
iframe
内のdocument
でaddEventListener()
する。
var id = CKEDITOR.instances.editor1.id;
var $iframe = $('#' + id + '_contents iframe');
var editorWindow = $iframe.prop('contentWindow'); // or contentDocument
$(editorWindow.document).on('click', 'img', function(event) {
console.log(event.currentTarget.src);
});
カーソル移動時に検知
自前でelementspath相当の機能を実装するときとか。
CKEDITOR.instances.editor1.on('selectionChange', function(event) {
var elements = _.map(event.data.path.elements, function(el){ return el.$; });
console.log(':selectionChange', elements);
});