JavaScript
CKEditor

CKEditorでスタイルを追加する際のあれこれ

More than 3 years have passed since last update.

CKEditorをいじっていたら、色々と不都合があったので覚書。

blockquoteタグの不具合

新たに引用のスタイルを追加しようとして、以下のようなコードを書き足す。

styles.js
CKEDITOR.stylesSet.add('default', [
...
  { name: 'quote',
    element: 'blockquote',
    attributes: {'class': 'hoge'}}
...
]

すると無事ボタン一つでhtmlタグが埋め込まれる…と思ったのだが、エラーが発生した。何も選択せずにボタンを押す場合は何も問題ないのだが、既に書かれているテキストを選択した状態でボタンを押すとタグが埋め込まれない。

どうやらckeditor.jsに問題があるらしく、山のようなコードと立ち向かうことに。解決策は以下の通り。

ckeditor.js
...
{for(var c=a.document,d=a.getRanges(),e=b?this.removeFromRange:this.applyToRange,f,g=d.createIterator();f=g.getNextRange();)e.call(this,f);a.selectRanges(d);c.removeCustomData("doc_processing_style")}var J={address:1,
// ここに追記
blockquote:1,
div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,details:1,datagrid:1,datalist:1},t={a:1,
embed:1,hr:1,img:1,li:1,object:1,ol:1,table:1,td:1,tr:1,th:1,ul:1,dl:1,dt:1,dd:1,form:1,audio:1,video:1},
...

他のタグにおける不具合も、同様にして対処可能だと思われる(検証は誰かお願いします)。

「ブロックスタイル」「インラインスタイル」などの表示を消す

「スタイル」ボタンをクリックすると、ご丁寧に「ブロックスタイル」「インラインスタイル」と種類別に分けてくれるのだが、どうにも煩わしいので削除。これも同様にckeditor.jsを編集することで解決できた。

ckeditor.js
...
(function(){CKEDITOR.plugins.add("stylescombo",{requires:"richcombo",init:function(c){var j=c.config,f=c.lang.stylescombo,e={},i=[],k=[];c.on("stylesSet",function(b){if(b=b.data.styles){for(var a,h,d=0,g=b.length;d<g;d++)if(a=b[d],!(c.blockless&&a.element in CKEDITOR.dtd.$block)&&(h=a.name,a=new CKEDITOR.style(a),!c.filter.customConfig||c.filter.check(a)))a._name=h,a._.enterMode=j.enterMode,a._.weight=d+1E3*(a.type==CKEDITOR.STYLE_OBJECT?1:a.type==CKEDITOR.STYLE_BLOCK?2:3),e[h]=a,i.push(a),k.push(a);
i.sort(function(a,b){return a._.weight-b._.weight})}});c.ui.addRichCombo("Styles",{label:f.label,title:f.panelTitle,toolbar:"styles,10",allowedContent:k,panel:{css:[CKEDITOR.skin.getPath("editor")].concat(j.contentsCss),multiSelect:!0,attributes:{"aria-label":f.panelTitle}},init:function(){var b,a,c,d,g,e;g=0;
for(e=i.length;g<e;g++)b=i[g],a=b._name,d=b.type,d!=c,

//ここをコメントアウトする
//&&(this.startGroup(f["panelTitle"+d]),c=d)

this.add(a,b.type==CKEDITOR.STYLE_OBJECT?a:b.buildPreview(),a);this.commit()},onClick:function(b){c.focus();
c.fire("saveSnapshot");var b=e[b],a=c.elementPath();c[b.checkActive(a)?"removeStyle":"applyStyle"](b);c.fire("saveSnapshot")},onRender:function(){c.on("selectionChange",function(b){for(var a=this.getValue(),b=b.data.path.elements,c=0,d=b.length,g;c<d;c++){g=b[c];for(var f in e)if(e[f].checkElementRemovable(g,!0)){f!=a&&this.setValue(f);return}}this.setValue("")},this)},onOpen:function(){var b=c.getSelection().getSelectedElement(),b=c.elementPath(b),a=[0,0,0,0];this.showAll();this.unmarkAll();for(var h in e){var d=
e[h],g=d.type;d.checkApplicable(b,c.activeFilter)?a[g]++:this.hideItem(h);d.checkActive(b)&&this.mark(h)}
a[CKEDITOR.STYLE_BLOCK]||this.hideGroup(f["panelTitle"+CKEDITOR.STYLE_BLOCK]);a[CKEDITOR.STYLE_INLINE]||this.hideGroup(f["panelTitle"+CKEDITOR.STYLE_INLINE]);a[CKEDITOR.STYLE_OBJECT]||this.hideGroup(f["panelTitle"+CKEDITOR.STYLE_OBJECT])},refresh:function(){var b=c.elementPath();if(b){for(var a in e)if(e[a].checkApplicable(b,c.activeFilter))return;this.setState(CKEDITOR.TRISTATE_DISABLED)}},reset:function(){e=
{};i=[]}})}})})();
...

これによって表示は消えたが、機能がブロック要素とインライン要素でソートされてしまう件は解決できないまま。どなたか詳しい方がいらっしゃれば教えていただきたいです…。