VS codeのソースをもとにウェブブラウザー上で動くよう作成されたMonaco Editor。自身のウェブサイトにエディタを埋め込むことで、エンジニア向けサービス等はぐっとUI/UXが改善されます。
今回は、Monaco Editorで埋め込まれたエディタに対して、ユーザーがコードを書き込む等の変更を行ったイベントをリッスンする方法についてまとめます。Monaco Editorに関する基本的な使い方が分かっている前提で説明を進めるので、場合によってはMonaco Editorの基本的な使い方を事前に読んでいただくとよいかと思います。
前提
chrome(バージョン: 101.0.4951.67)
Monaco Editor version 0.33.0.
説明のために使用するサンプルコード
以下のようなサンプルコードのサイトを使用します。
<!DOCTYPE html>
<html>
<head>
<title>browser-amd-editor</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<h2>Monaco Editor Sample</h2>
<div
id="container"
style="width: 800px; height: 600px; border: 1px solid grey;"
></div>
<script src="./node_modules/monaco-editor/min/vs/loader.js"></script>
<script>
require.config({ paths: { vs: "./node_modules/monaco-editor/min/vs" } });
require(["vs/editor/editor.main"], function () {
var editor = monaco.editor.create(
document.getElementById("container"),
{
value: [
"function x() {",
'\tconsole.log("Hello world!");',
"}",
].join("\n"),
language: "javascript",
}
);
});
</script>
</body>
</html>
今回リッスンしようとしているイベントは、例えば、以下の画像のように空行が追加する等です。
テキストエディタの変更をリッスンするために必要なイベントが何なのかは、公式ドキュメントやPlay Groundに明記されておらず、Monaco Editorに関する情報は日本語でほとんど存在しないです。自分なりにいろんなコードを試すか、海外サイト(例えばStack Overflow等)を見た方が近道だったりします。
テキストエディタの変更をリッスンするために必要なコード
テキストエディタの変更をリッスンするために必要なコードは以下のように、getModelメソッドとonDidChangeContentメソッドを用いたものになります。
editor.getModel().onDidChangeContent((event) => {
console.log(editor.getValue());
console.log(event);
});
HTMLファイル全体はこんな感じです。
<!DOCTYPE html>
<html>
<head>
<title>browser-amd-editor</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<h2>Monaco Editor Sample</h2>
<div
id="container"
style="width: 800px; height: 600px; border: 1px solid grey;"
></div>
<!-- OR ANY OTHER AMD LOADER HERE INSTEAD OF loader.js -->
<script src="./node_modules/monaco-editor/min/vs/loader.js"></script>
<script>
require.config({ paths: { vs: "./node_modules/monaco-editor/min/vs" } });
require(["vs/editor/editor.main"], function () {
var editor = monaco.editor.create(
document.getElementById("container"),
{
value: [
"function x() {",
'\tconsole.log("Hello world!");',
"}",
].join("\n"),
language: "javascript",
}
);
editor.getModel().onDidChangeContent((event) => {
console.log(editor.getValue());
console.log(event);
});
});
</script>
</body>
</html>
これで、エディタ内に変更があるたびに、特定の処理を実行できます。
今回は、
console.log(editor.getValue());
console.log(event);
との処理を書いています。
それぞれどのようにコンソールに出力されているか見てみましょう。
すると、イベントがリッスンされて、editor.getValue()
がコンソールに出力されます。
画像. console.log(editor.getValue());
の結果
また、console.log(event);
の方では、以下のような連想配列(Hash, Object)が出力がされています。
changesというkeyの値である配列の0番目に格納されている連想配列のtextというkeyの場所に、今回の変更'\n\t'
(改行とタブを行ったことになっている)が書かれています。
console.log(event);
については、改行だと分かりにくいかと思いますので、a
と記載した場合のコンソールも合わせて表示します。
getModelメソッドを詳しく解説
getModelについてはMonaco Editor公式ドキュメントのおそらくここが該当します。「おそらく」とつけたのは、パラメーター(引数)がなくて実行された場合の記述がないためです。
Interface ITextModelオブジェクトを返します。
onDidChangeContentメソッドを詳しく解説
onDidChangeContentについては、Monaco Editor公式ドキュメントにて、以下のように記述されています。
onDidChangeContent
onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable
An event emitted when the contents of the model have changed.
Interface ITextModelオブジェクト(=model)に変化があった場合に、IModelContentChangedEventイベントをリッスンします。