1
1

はじめに

タイトルが長くなってしまいましたが、タイトルの通りなんですwww
前回、Summernoteのツールバーをカスタマイズしましたが、簡易な更新機能などを持たせたシステムのようなケースですと、WYSIWYG特有のコピペに対するスタイルの引継ぎ機能が余計な作業を発生させる原因になったりします。
プレーンなテキストでコピペしたいのにできないから、一旦メモ帳などにコピペして改めてエディタにコピペしたり、エディタにコピペした後クリーンボタンなどでプレーンテキストにしたりなど…
元からプレーンテキストでコピペされるのであればしなくていい作業が発生してしまいます。
(本格的なCMSの場合はあったほうが良い場合ももちろんあります)

今回はWordやブラウザからSummernoteのエディタ部分へコピペする際に、プレーンテキストでコピーされるようにカスタマイズしていこうと思います。

前回の記事の内容はこちら

1. 基本のソース

前回ツールバーのカスタマイズまで完了したソースです。

test.html
<!DOCTYPE html>
<html lang="ja">
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Summernote Test</title>
 
	<!-- CSS -->
	<link rel="stylesheet" href="./js/snote/summernote-lite.min.css" type="text/css" />
	<!-- /CSS -->

	<!-- JavaScript -->
	<script src="./js/jquery-3.7.1.slim.min.js" type="text/javascript"></script>
	<script src="./js/snote/summernote-lite.min.js" type="text/javascript"></script>
	<script src="./js/snote/lang/summernote-ja-JP.min.js" type="text/javascript"></script>
	<!-- /JavaScript -->
<head>
<body>

	<lavel for="hoge">Summernote Test</label>
	<textarea id="hoge" value=""></textarea>

	<script type="text/javascript">
	$(function(){
		$('#hoge').summernote({
			lang: 'ja-JP',
			height: 400,
			toolbar: [
				['view', ['undo', 'redo']],
				['font', ['clear', 'hr']],
				['para', ['ul', 'ol']],
				['insert', ['link', 'picture']]
			]
		});
	});
	</script>

</body>
</html>

ここからカスタマイズしてみようと思います。

2. summernote-cleaner.js

今回はクリーナープラグインを利用していきます。
こういった便利なプラグインがわんさか転がっているのもオープンソースのいいところ。
まずはGitHubでクリーナープラグインをダウンロードしてきます。

ダウンロードしたzipファイルの中からsummernote-cleaner.jsを適当な場所にポイっとします。
私の場合は以前投稿した「【WYSIWYGエディタ】Summernoteの使い方(日本語化)」の中で書いたファイル構成の中のsnoteディレクトリ中に入れました。

root
 ├─ test.html ← Test表示用HTML
 └─ js
     ├─ jquery-3.7.1.slim.min.js
     └─ snote
          ├─ summernote-lite.min.js
          ├─ summernote-cleaner.js ← ここ!
          ├─ summernote-lite.min.css
          ├─ font
          │   ├─ summernote.ttf
          │   ├─ summernote.eot
          │   ├─ summernote.woff
          │   └─ summernote.woff2
          └─ lang
              └─ summernote-ja-JP.min.js

こんな感じ。

3. 実装の前にまずは中身を確認

私はこういったプラグインを実装する前には必ず中身を確認します。
理由は自分自身の勉強と、明らかに不自然な記述が無いかの確認のためです。
私のように素人に毛が生えた程度のスキルだと勉強が必要なんですw

ってことで、中身を見てみると…ふむふむ…専用のボタンもツールバーに表示できるみたいです。
私の場合は作業を減らしたいという目的なので必要ありませんが、ボタンも表示させたくなった時のために、ソースの13~22行目の部分に追記していきます。
念のため。
なので、summernote-cleaner.jsを開いて

	$.extend(true, $.summernote.lang, {
		'en-US': {
			cleaner: {
				tooltip: 'Cleaner',
				not: 'Text has been cleaned!',
				limitText: 'Text',
				limitHTML: 'HTML'
			}
		}, // ← ここのカンマを忘れずに!
		'ja-JP': {
			cleaner: {
				tooltip: 'クリーナー',
				not: '文字がきれいになりました!',
				limitText: 'テキスト',
				limitHTML: 'HTML'
			}
		}
	});

こんな感じに追記すれば日本語化ができると思います。
これで万が一クリーナーボタンが必要になってもちゃんと日本語化されてくれます。

4. クリーナーのオプション設定を確認

まずは設定内容を紐解くためにプラグインのドキュメントを確認。

ざっくり説明。

action:どの行動をしたときに実行するか

  • button クリーナーボタンをクリックしたとき
  • paste コピペしたとき
  • both 両方

icon:クリーナーボタンのアイコン

'<i class="note-icon">好きなSVG</i>'

keepHtml:HTMLのマークアップを保持

  • true 保持する
  • false 保持しない(クリップボードから利用)

↑↑↑コピペできなかった理由はこれか?

keepTagContents:内容は保持して削除するタグ

badTags:内容を含んだ完全削除するタグ

badAttributes:属性を削除するタグ

limitChars:文字数の制限

  • 0 最大入力を許可
  • 数値 入力した数値で処理する文字数を制限

limitDisplay:下部に表示されるステータス領域の表示内容

  • text テキストの文字数のみ
  • html HTMLの文字数のみ
  • Both HTMLとテキストの両方

limitStop:limitCharsで設定された文字数に達した時どうするか

  • true 入力を停止
  • false どうもしない

limitType:テキスト長さとHTML長さのどちらで制限をかけるか

  • text テキスト長さで制限
  • html HTML長さで制限
  • Both HTMLとテキストの両方

notTimeOut:ステータスメッセージが非表示になるまでの時間(ミリ秒)

keepImages:ペーストした画像を保持するか

  • true 保持する
  • false imagePlaceholderで設定された画像に置き換え

imagePlaceholder:ペーストした画像を指定された画像に置き換え

うん、要らないものがいっぱいあったなぁ…反省!
私の場合の要件をまとめると、

  • テキストのみをコピぺさせるようにして、スタイル要素を省いた状態でペーストさせたい
  • 画像のコピペはさせたくない
  • 改行は残ってほしい

こうすることでお客様自身の作業が単純化されて、決まった形でのルーティンワークになりやすいと思います。(あくまでも私見です)
これこそが制限することで簡易な作業にしていく施策のように思います。

6. summernote-cleaner.jsの実装

オプション設定も確認できたのでまずはsummernote-cleaner.jsの読み込み。
head内のSummernoteのスクリプト読み込み部分の下に

<script src="./js/snote/summernote-cleaner.js" type="text/javascript"></script>

を書き込んで、あとはSummernote実行部分に

toolbar: [
	['cleaner',['cleaner']],
	//省略
],
cleaner: {
	action: 'paste',
	icon: '<i class="note-icon"><svg xmlns="http://www.w3.org/2000/svg" id="libre-paintbrush" viewBox="0 -3 14 14" width="14" height="14"><path d="m 11.821425,1 q 0.46875,0 0.82031,0.311384 0.35157,0.311384 0.35157,0.780134 0,0.421875 -0.30134,1.01116 -2.22322,4.212054 -3.11384,5.035715 -0.64956,0.609375 -1.45982,0.609375 -0.84375,0 -1.44978,-0.61942 -0.60603,-0.61942 -0.60603,-1.469866 0,-0.857143 0.61608,-1.419643 l 4.27232,-3.877232 Q 11.345985,1 11.821425,1 z m -6.08705,6.924107 q 0.26116,0.508928 0.71317,0.870536 0.45201,0.361607 1.00781,0.508928 l 0.007,0.475447 q 0.0268,1.426339 -0.86719,2.32366 Q 5.700895,13 4.261155,13 q -0.82366,0 -1.45982,-0.311384 -0.63616,-0.311384 -1.0212,-0.853795 -0.38505,-0.54241 -0.57924,-1.225446 -0.1942,-0.683036 -0.1942,-1.473214 0.0469,0.03348 0.27455,0.200893 0.22768,0.16741 0.41518,0.29799 0.1875,0.130581 0.39509,0.24442 0.20759,0.113839 0.30804,0.113839 0.27455,0 0.3683,-0.247767 0.16741,-0.441965 0.38505,-0.753349 0.21763,-0.311383 0.4654,-0.508928 0.24776,-0.197545 0.58928,-0.31808 0.34152,-0.120536 0.68974,-0.170759 0.34821,-0.05022 0.83705,-0.07031 z"/></svg></i>',
	keepHtml: false,
	limitChars: false,
	limitDisplay: 'both',
	limitStop: false,
	limitType: 'both',
	notTimeOut: 1000
}

を追記。
結構削ったソースになりました。
ちなみにアイコンのsvgがずれていたので、viewBox="0 0 14 14"をviewBox="0 -3 14 14"にプチ修正しています。

結果、ブラウザなどからコピペした時に、テキストのみが p タグに囲まれて、改行は再現された状態でペーストされるようになりました♪

後は見た目調整のためにCSSを追記します。

/* 背景が白じゃなくてもSummernoteの背景が白くなるように */
.note-editing-area {
	background-color: #fff;
}

/* 下部に表示されるステータスエリアの高さと背景色の調整 */
.note-editor.note-frame .note-status-output {
	height: 15px;
	background-color: #f7f7f7;
}

/* ステータスエリアに表示されるテキストの調整 */
.note-editor.note-frame .note-status-output small {
	font-size: 80%;
	line-height: 1.3;
}

さらに私の場合ボタンは要らないのでボタンを非表示にして…
さて、これでいい感じになるはず。

ブラウザで早速確認!

image.png

うん、ステータスエリアも邪魔にならない感じになったし、コピペも改行ありのテキストのみになりました♪

7. HTMLまとめ

test.html
<!DOCTYPE html>
<html lang="ja">
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Summernote Test</title>
 
	<!-- CSS -->
	<link rel="stylesheet" href="./js/snote/summernote-lite.min.css" type="text/css" /><!-- Summernoteのcss -->
	<style type="text/css">
		/* 背景が白じゃなくてもSummernoteの背景が白くなるように */
		.note-editing-area {
			background-color: #fff;
		}

		/* 下部に表示されるステータスエリアの高さと背景色の調整 */
		.note-editor.note-frame .note-status-output {
			height: 15px;
			background-color: #f7f7f7;
		}

		/* ステータスエリアに表示されるテキストの調整 */
		.note-editor.note-frame .note-status-output small {
			font-size: 80%;
			line-height: 1.3;
		}
	</style>
	<!-- /CSS -->

	<!-- JavaScript -->
	<script src="./js/jquery-3.7.1.slim.min.js" type="text/javascript"></script><!-- JQuery -->
	<script src="./js/snote/summernote-lite.min.js" type="text/javascript"></script><!-- Summernoteの本体 -->
	<script src="./js/snote/lang/summernote-ja-JP.min.js" type="text/javascript"></script><!-- Summernoteの日本語化用 -->
	<script src="./js/snote/summernote-cleaner.js" type="text/javascript"></script><!-- クリーナープラグイン -->
	<!-- /JavaScript -->
<head>
<body>

	<lavel for="hoge">Summernote Test</label>
	<textarea id="hoge" value=""></textarea>

	<script type="text/javascript">
	$(function(){
		$('#hoge').summernote({
			lang: 'ja-JP',// 日本語化
			height: 400,// 初期表示の高さ
			toolbar: [
				//  ['cleaner',['cleaner']],とりあえず非表示
				['view', ['undo', 'redo']],
				['font', ['clear', 'hr']],
				['para', ['ul', 'ol']],
				['insert', ['link', 'picture']]
			],
			cleaner: {// クリーナー設定
				action: 'paste',// button | paste | both:クリーナー設定
				icon: '<i class="fa-solid fa-eraser"><svg xmlns="http://www.w3.org/2000/svg" id="libre-paintbrush" viewBox="0 -3 14 14" width="14" height="14"><path d="m 11.821425,1 q 0.46875,0 0.82031,0.311384 0.35157,0.311384 0.35157,0.780134 0,0.421875 -0.30134,1.01116 -2.22322,4.212054 -3.11384,5.035715 -0.64956,0.609375 -1.45982,0.609375 -0.84375,0 -1.44978,-0.61942 -0.60603,-0.61942 -0.60603,-1.469866 0,-0.857143 0.61608,-1.419643 l 4.27232,-3.877232 Q 11.345985,1 11.821425,1 z m -6.08705,6.924107 q 0.26116,0.508928 0.71317,0.870536 0.45201,0.361607 1.00781,0.508928 l 0.007,0.475447 q 0.0268,1.426339 -0.86719,2.32366 Q 5.700895,13 4.261155,13 q -0.82366,0 -1.45982,-0.311384 -0.63616,-0.311384 -1.0212,-0.853795 -0.38505,-0.54241 -0.57924,-1.225446 -0.1942,-0.683036 -0.1942,-1.473214 0.0469,0.03348 0.27455,0.200893 0.22768,0.16741 0.41518,0.29799 0.1875,0.130581 0.39509,0.24442 0.20759,0.113839 0.30804,0.113839 0.27455,0 0.3683,-0.247767 0.16741,-0.441965 0.38505,-0.753349 0.21763,-0.311383 0.4654,-0.508928 0.24776,-0.197545 0.58928,-0.31808 0.34152,-0.120536 0.68974,-0.170759 0.34821,-0.05022 0.83705,-0.07031 z"/></svg></i>',
				keepHtml: false,// true | false:HTMLのマークアップの保持設定
				limitChars: false,// 0 or false | #:文字数の制限
				limitDisplay: 'both',// text | html | both:ステータス領域の表示内容
				limitStop: false,// true | false:limitCharsで設定された文字数に達した時の設定
				limitType: 'both',// text | html | both:テキスト長さとHTML長さのどちらで制限をかけるか
				notTimeOut: 1000// ステータスメッセージが非表示になるまでの時間(ミリ秒)
			}
		});
	});
	</script>

</body>
</html>

最後に

さて、今回はコピペした時にプレーンテキストでコピーしたいというニッチな内容でしたが、これは人によって必要性が変わってくると思いますし、お客様や仕事の内容によっても必要有り無しが分かれると思います。
ただ単に私が必要だっただけという可能性もあるのですが、もし必要になる人が居れば参考にしてください。
次回はオリジナルボタンの作成方法についてメモっていこうと思います。

↓↓↓次の記事はこちら

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1