はじめに
Railsに導入したMediumエディターにフォントカラーの編集機能を追加する方法を自分の備忘録として書いておきます。
環境
Rails6 (6.0.1)
ruby 2.7.0
jQuery(3.4.1)をインストール済み
参考
medium-editor support for font color?
https://github.com/Olgagr/vanilla-color-picker
MediumEditorとは?
有名ブログサービスのMediumで使われているWYSIWYGエディターです。Gemのmedium-editor-railsをインストールすることで簡単にMediumエディターをRailsアプリに導入することができます。
MediumEditorを適用させる
テキストエリアにeditableというクラスを付与させた上で、下記のスクリプトを実行するとMedium Editorが適用されます。
var editor = new MediumEditor('.editable', {
// placeholder の設定
placeholder: {
text: 'テキストを入力してください',
hideOnClick: true
}
});
$('.editable').mediumInsert({
editor: editor
});
※RailsにMediumEditorを導入する際はこちらの記事を参考にしました。
フォントカラーの編集機能を追加する方法
vanilla-color-pickerを利用して、機能拡張を行います。
ディレクトリ構成は以下になります。
ディレクトリ構成
app/
├ 〜
└ javascript/
├ packs/
│ └ application.js
├ vanilla-color-picker.js
├ color_picker.js
└ medium_editor.js
1. vanilla-color-picker.jsをjavascriptディレクトリの配下に置く
ファイルはこちらのファイルを利用しました。
2. color-picker.jsをjavascriptディレクトリに作成
このファイルでColorPickerExtension()を下記のように定義します。
(function () {
function ColorPickerExtension() {
this.button = document.createElement('button');
this.button.classList.add('medium-editor-action');
this.button.classList.add('editor-color-picker');
this.button.title = '文字色'
this.button.innerHTML = '<i class="fa fa-paint-brush"></i>';
this.button.onclick = this.onClick.bind(this);
}
/**
* onClick
* The click event handler that calls `insertHtmlAtCaret` method.
*
* @name onClick
* @function
*/
ColorPickerExtension.prototype.onClick = function (e) {
e.preventDefault();
e.stopPropagation();
this.selectionState = this.base.exportSelection();
// If no text selected, stop here.
if (this.selectionState && (this.selectionState.end - this.selectionState.start === 0)) {
return;
}
// 選択できるフォントカラーを指定します
var pickerColors = [
"#1abc9c",
"#2ecc71",
"#3498db",
"#9b59b6",
"#34495e",
"#16a085",
"#27ae60",
"#2980b9",
"#8e44ad",
"#2c3e50",
"#f1c40f",
"#e67e22",
"#e74c3c",
"#bdc3c7",
"#95a5a6",
"#f39c12"
];
var picker = vanillaColorPicker(this.document.querySelector(".medium-editor-toolbar-active .editor-color-picker").parentNode);
picker.set("customColors", pickerColors);
picker.set("positionOnTop");
picker.openPicker();
picker.on("colorChosen", function (color) {
this.base.importSelection(this.selectionState);
this.document.execCommand("styleWithCSS", false, true);
this.document.execCommand("foreColor", false, color);
}.bind(this));
};
/**
* getButton
* This function is called by the Medium Editor and returns the button that is
* added in the toolbar
*
* @name getButton
* @function
* @return {HTMLButtonElement} The button that is attached in the Medium Editor
* toolbar
*/
ColorPickerExtension.prototype.getButton = function () {
return this.button;
};
// windowオブジェクトに定義します
window.ColorPickerExtension = ColorPickerExtension;
})();
3. MediumEditorのextensionsオプションにColorPickerExtension()を追加
2で定義したColorPickerExtension()をextensionsオプションに追加します。
extensions: {
"colorPicker": new ColorPickerExtension()
}
これで"colorPicker"をtoolbarのbuttonsオプションに指定してあげるとMedium Editorでフォントカラーを編集できるボタンを表示させることができます。
toolbar: {
buttons: ['bold', 'italic', 'underline', 'anchor', 'colorPicker', 'indent', 'outdent'],
diffLeft: 25,
diffTop: -10,
}
ファイル全体の内容は以下
var editor = new MediumEditor('.editable', {
// placeholder の設定
placeholder: {
text: 'テキストを入力してください',
hideOnClick: true
},
toolbar: {
buttons: ['bold', 'italic', 'underline', 'anchor', 'colorPicker', 'indent', 'outdent'],
diffLeft: 25,
diffTop: -10,
},
extensions: {
"colorPicker": new ColorPickerExtension()
}
});
$('.editable').mediumInsert({
editor: editor
});
4.application.jsを編集
この状態では、vanilla-color-picker.jsとcolor-picker.jsが読み込まれていない状態なのでapplication.jsに追記します。
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("jquery")
//追加 ----
require("vanilla-color-picker.js")
require("color-picker.js")
// -------
require("medium_editor.js")