HTML5 Local File Drop and Input File

HTML5 は Local ファイルの編集もできる。
一番利用されるだろうと思われるのはやはりテキストファイルの編集。
ということで今回はファイルの読み込みを勉強する。
<imput> を利用するかドラッグアンドドロップで読み取る方法を。

これは興味がある人が多いようで検索するとワラワラ見つかるね。
でも手段が結構バラバラだったりするので一番最適と思われる方法を探す。
手段は File object を得て FileReader で読み込めばいいようだ。

残念ながら Opera 11.51 はドラッグアンドドロップ未対応だ…
HTML5 の仕様に含まれているのだから今後は対応してくれるだろう。
IE はどうでもいい。

とにかく Firefox, WebKit で上手くいったコード。
Opera も Input だけなら読み込みできる。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Drop and Input</title>

<script>
function writeText(f) {
    var reader = new FileReader();
    reader.readAsText(f, "utf-8");
    var text = document.getElementById("IDTEXT");
    reader.onload = function(e) {
        text.innerHTML = e.target.result;
    }
    reader.onerror = function(e) {
        switch (e.target.error.code) {
        case 1:
            text.innerHTML = "NOT_FOUND_ERROR!";
            break;
        case 2:
            text.innerHTML = "SECURITY_ERROR!";
            break;
        case 3:
            text.innerHTML = "ABORT_ERROR!";
            break;
        case 4:
            text.innerHTML = "NOT_READABLE_ERROR!";
            break;
        case 5:
            text.innerHTML = "ENCODING_ERROR!";
            break;
        default:
            text.innerHTML = "Unknown ERROR!";
        }
    }
}
function changeInputValue(e) {
    var f = e.target.files[0];
    writeText(f);
}
function init() {
    document.addEventListener("dragover", function(e) {
        e.preventDefault();
    }, false);
    document.addEventListener("drop", function(e) {
        e.preventDefault();
        var f = e.dataTransfer.files[0];
        writeText(f);
    }, false);
}
</script>

</head>

<body onLoad="init()">
<p>Drop here</p>

<form>
<input type="file" id="IDURI" onchange="changeInputValue(event);">
</form>

<p id="IDTEXT">URI</p>

</body>
</html>

コンストラクタ(という表現は正しいのだろうか?)
init でこう書けば event object が得られるようだ。
preventDefault メソッドを呼んでブラウザのデフォルト動作を無効にする。
dataTransfer.files メソッドで File object の List が得られる。
その List から添字を使って取り出す、複数ファイルなら for 文を使う。

input は onchange でこう書けば event object 付きで関数が呼べるようだ。
target.files メソッドで File object の List が同様に得られる。

肝心なファイルを読み込んで書き出す処理は少し面倒。
C の fopen や Python の open, read みたいにはいかないようだ。
FileReader の readAsText 関数で読み込んでコールバックで処理する。
読み込みが正常終了すると onload が呼ばれるので event object の target.result プロパティからテキストを得る。

どうでもいいけど Python ばかりやっているとこういう書き方が不自然で…
IronPython の時も思ったけどイコールでの代入時に括弧が無いと変に感じる。

ところで onerror の処理をやたら丁寧に書いていますが…
Original Webkit Browser @ Fedora 15 | PaePoi
で表示できなかったから原因を調べるためである。

WebKitWebSettings

# setting
setting = self.webview.get_settings()
setting.set_property("enable-file-access-from-file-uris", True)

を __init__() のどこかに入れれば表示できるようになります。
Local のファイルアクセスは WebKit デフォルト状態では弾かれるようです。
Chrome では読み込めるようなのにとコレだけで一日悩んでしまったぞと。

書き込みは FileWriter を使う、後日。
その前にリストボックス作成と JavaSclipt で ini ファイル読み書きをやりたい。
何を作ろうとしているかはわかる人には解る。
現実として作りたいアプリが無いとプログラミングの勉強は絶対に続かないよ。