MTで画像をドラッグ&ドロップするとData URIで配置される

公開

今日会社で話が出て調べたのですが、FirefoxでMovable Typeの記事編集エリアに画像をドラッグ&ドロップすると、Data URIで配置されることが分かりました。どうもcontenteditable="true"な要素にファイルをドラッグ&ドロップするとそうなるようです。
画像がData URIで配置された様子

このままだと、画像はこの記事データに直接埋め込まれることとなり、Movable Typeのアイテム管理にも入らないので後々ちょっと支障が出そう。ひとまずファイルのドラッグアンドドロップをキャンセルするパッチを見つけたので、Extend TinyMCEの設定ファイルmt-static/plugins/ExtendTinyMCE/extension.jsに書き加えて対処することを提案しました。

$.extend(config, {

    // 省略

    setup: function (editor) {
        // https://tracker.moodle.org/secure/attachment/35976/0216-Prevent-drag-drop-of-images-into-TinyMCE.patch
        editor.onInit.add(function() {
            editor.dom.bind(editor.getWin(), ['dragenter', 'dragover', 'draggesture', 'drag', 'drop'], function(e) {
                // Cancel drop event if it's an image file being dragged in
                if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length) {
                    e.preventDefault();
                    e.stopPropagation();
                    alert("画像・ファイルは、「画像の挿入」「アイテムの挿入」ボタンを使って配置して下さい。");
                    return false;
                }
            });
        });
    },
});

MT6ならData APIでアップロードできるかも

ここから先はまだ言わなかったのですが、ファイルがドラッグ&ドロップされたことが分かるなら、MT6のData APIを使ってアップロードしてしまえば...、と考えました。ひとまずMTの編集画面ではなく、素のHTMLにコードを書いてみたところ、上手くアップロードして編集画面に配置できました。

HTML・JavaScript

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Asset Upload</title>
</head>
<body>
<div id="editor" contenteditable="true" style="border: 1px solid #ccc; width: 960px; height: 500px;">
</div>

<script src="mt-static/jquery/jquery.js"></script>
<script src="mt-static/data-api/v2/js/mt-data-api.js"></script>
<script>
(function ($) {
    var authDfd = $.Deferred();
    var $editor = $("#editor");
    var api = new MT.DataAPI({
        clientId: "test",
        baseUrl: "http://path/to/mt/mt-data-api.cgi",
        format: "json"
    });

    api.authenticate({
        username: "[your username]",
        password: "[your password]",
        remember: true
    }, function (response) {
        if (response.error) {
            authDfd.reject();
        }

        api.storeTokenData(response);
        authDfd.resolve();
    });

    authDfd.done(function () {
        $editor.on("drop", function (e) {
            var data = {
                file: e.originalEvent.dataTransfer.files[0],
                path: "images/",
                autoRenameIfExists: true,
                normalizeOrientation: true
            };

            e.preventDefault();

            api.uploadAsset({ site_id: 1 }, data, function (response) {
                var url;
                if (response.error) {
                    // Do something;
                }

                url = response.url;
                $editor.append("<img src='" + url + "' alt=''>");
            });
        });
    });
}(jQuery));
</script>
</body>
</html>

操作結果

編集エリアと仮定した要素にアップロードした画像が配置できました。
画像がData URIで配置された様子

課題と今後

画像のアップロードはできるのですが、サムネイルの生成も必要だったり、大きな画像をリサイズして配置したり、ということが考えられるので、まだ工夫が必要そうです。また、アップロードに時間がかかる場合も想定されるので、何らかの対処が必要かもしれません。

上手くいけば、Extend TinyMCEに組み込むかもしれません。ひとまずそのままのサイズで配置できるように実装しても良いかもしれませんね。

2015年3月31日追記:続編「Extend TinyMCEを使ってドラッグ&ドロップで画像を配置できるようにする」を書きました。