Native File System API로 텍스트 편집기 만들기

10513 단어 자바스크립트
요 전날 공개된 vs 개로. 에서 v을 접했을 때, 어쩐지 Native File System API라고 하는 것을 사용하면 브라우저로부터 보통으로 로컬 파일을 취급할 수 있다고 알았으므로, 시험에 브라우저로 움직이는 텍스트 에디터를 만들어 보았다.

Chromium 계열의 브라우저(Chrome, Edge 등)라면 대체로 움직이지만 브레이브 같다. 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)
    }
}

좋은 웹페이지 즐겨찾기