先日公開された [vscode.dev](! vscode.dev) を触った際、なんか Native File System API というのを使えばブラウザから普通にローカルファイルを扱えると知ったので、試しにブラウザで動くテキストエディタを作ってみた。
Chromium 系のブラウザ (Chrome, Edge など) だと大体動くけど Brave はだめ らしい。http サーバーを立てずに、ローカルの HTML ファイルとして開いても動く。
注意点としては、既存ファイルを上書き保存をすると作成日が保存した時点になってしまう。
html
<div id='filename'>名称未設定ファイル</div>
<textarea id='editor'></textarea>
<div>
<button id='open'>開く</button>
<button id='save'>上書き保存</button>
<button id='saveas'>名前をつけて保存</button>
</div>
css
#editor {
width: 320px;
height: 160px;
}
#filename {
color: #888888;
}
JS
const fileNameDiv = document.getElementById('filename')
let fileHandle
// テキストファイルだけ開けるようなオプション
const pickerOpts = {
types: [
{
description: 'Texts',
accept: {
'text/*': ['.txt', '.text']
}
}
],
multiple: false,
}
document.getElementById('open').onclick = async () => {
try {
[ fileHandle ] = await window.showOpenFilePicker(pickerOpts)
if (fileHandle.kind !== 'file') return
fileNameDiv.textContent = fileHandle.name
const fileData = await fileHandle.getFile()
const content = await fileData.text()
document.getElementById('editor').value = content
} catch (e) {
// ファイル選択をキャンセルした時などにここに飛ぶ
console.error(e)
}
}
document.getElementById('save').onclick = async () => {
if (fileHandle.kind !== 'file') return
const content = document.getElementById('editor').value
const writableStream = await fileHandle.createWritable()
await writableStream.write(content)
await writableStream.close()
}
document.getElementById('saveas').onclick = async () => {
try {
const content = document.getElementById('editor').value
fileHandle = await window.showSaveFilePicker(pickerOpts)
if (fileHandle.kind !== 'file') return
const writableStream = await fileHandle.createWritable()
await writableStream.write(content)
await writableStream.close()
fileNameDiv.textContent = fileHandle.name
} catch (e) {
console.error(e)
}
}