CKEditor5で特定のクラスがある場合ツールバーを非表示にする方法

掲載日

結論

cssで消せます。

:root:has(.ck-editor__editable [ここに任意のクラス名等].ck-widget_selected) .ck-balloon-panel_visible {
    display: none;
}

経緯

CKEditor5を使用していて、以下のような要件がありました。
 

CKEditor5のファイル添付をしている例のスクリーンショット。
  • ファイル添付時、リンクの先頭に自動で対応するファイルアイコンを追加したい。(添付参照)
  • 文中にリンクを貼り付け時、target="_blank"な(別タブで開く)リンクの場合、リンクの後ろに自動で外部サイトを開くアイコンを追加したい。(添付参照)
  • それらのアイコンは必要に応じて削除もしたい。(よって、スタイルでbefore, after要素を駆使して追加は難しく本文中にimgタグを使って追加したい。)

 

CKEditor5で自動追加の画像にもツールバーが出てしまっているスクリーンショット。

すると、自動で追加したアイコンは本文中の画像として扱われるので、CKEditor5の画像プラグインの対象となりカーソルを当てるとツールバーが表示されます。(添付参照)

消せば良いものを(まぁどうせ誰も触らんだろうからだしっぱでもええやろ…)と思っていました。

が、運用の中でアイコンの画像のツールバーを使う方はいました。(もちろんだしっぱでもまぁええかと思った自分が悪いです。)

自動追加した画像にはクラスを付与しており、スタイルシート側で画像サイズを決めていたため、「ツールバーを使ってアップロードした画像が小さい(アイコンサイズと同じにスタイルで修正されるため)けど何で?」という問い合わせに発展してしまいました。

再発防止のため、システムで追加した画像にはカーソルを合わせてもツールバーを出さないように修正していきます。

対策

案1. カーソルの移動を監視してdisabledする。

CKEditor5ではカーソルの移動を監視できるので、都度カーソルがあたっている位置の要素を取得し、
imgタグかつ特定のクラスを持っている場合、プラグインをdisabledすることも可能です。

ClassicEditor
    .create(document.querySelector("#editor"), config)
    .then(editor => {
        editor.model.document.on('change', () => {
            const model = editor.data.model;
            let html = editor.data.stringify(model.getSelectedContent(model.document.selection));
            let iconImage = $(html).find(".[任意のクラス名]")

            if (iconImage.length > 0) {
                editor.commands.get("[任意の画像アップロードプラグイン名]").isEnabled = false
            }
        })
    });

こっちの方が正しい感じはするのですが、都度監視してdisabledする(CKEditor5の内部に干渉する)というのもトラブルの頻度に対して修正のリスクが大きくてちょっとイマイチな気がしました。

案2. cssで非表示にしてしまう。

今回は「対象に特定のクラスを付与している」という特徴があったのでこちらを選択しました。

以下の三行をcssに追加するだけなので非常に簡単かつ、スタイルなので処理自体に与える影響はかなり限定的だと思われるのでこちらを採用しました。

:root:has(.ck-editor__editable [ここに任意のクラス名等].ck-widget_selected) .ck-balloon-panel_visible {
    display: none;
}
  • まず、CKEditor5では、編集領域とツールバーは親子要素で繋がっていないので、:rootセレクタを使ってhtmlまで遡っています。
  • :has(XXX)セレクタを使って(XXX)内の条件を満たす場合にスタイルを反映します。
  • (XXX)内の条件は、.ck-editor__editable(編集領域)に、.ck-widget_selected(選択中の)[ここに任意のクラス名等](任意のクラス名)があれば、ということでここで「特定のクラスの画像が選択されている場合」を指定しています。
  • 最後に.ck-balloon-panel_visible(ツールバー)を指定して、後はdisplay: none;で非表示としています。

おわりに

:root:hasを組み合わせて、親子要素外の条件を使ってスタイルを操作できることを初めて知りました。
色々応用が効いて便利そうなので備忘録として。

 

それはそれとして、CKEditor5のツールバーの表示・非表示条件はもっとラフに設定出来る気もするので、
追々分かったら追記していきたいと思います。

 

記事の作成者のA.W.のアイコン

この記事を書いた人

A.W.
茨城県在住Webエンジニアです。 PHP、PostgreSQL、Linuxなどを業務で使用しています。 趣味ではGoやNuxt、Flutterをやってます。

Comment

関連記事

check コピーしました!