JSPで行こう!

画像をクリップボードから挿入する

こちらの文章は、先にファイルアップロードの実装が出来ている前提です。
ファイルアップロードの方法については、別の章を参照してください。

TinyMCE は、当初の 4.8 ではなく、5.7 にアップグレードしています。
画像プラグインの設定も併せて変えることで、「アップロード」用のタブが表示されます。

MCE5.7の画像プラグイン

これで、ドラッグ&ドロップやこの画面からサーバーにアップロード出来ますが、
残念な事に、今のところクリップボード(画像のコピー&貼り付け)からの直接アップロードは出来ません。
「今のところ」と書いたのは、やろうと思えば難しくないので、そのうちサポートされるだろうと思うからです。

その間使えないのもしゃくなので、簡易的に実装してみました。
既に他の章で書きましたが、クリップボードからアップロードできる事は確認しています。
なので、後は然るべき場所のイベントを拾って実行すれば良いだけです。
場所としては、上の画像の「画像のソース」の入力が適当でしょう。
そこで、この場所のリソースをchromの開発ツールで調べてみると、
id に"mceu_109-inp"等と読み取れますが、どうも実行の都度変わるようです。
ですので、とりあえずは、class をセレクタにする事にしました。
他の場所で同じ class の項目があるとそこでアップロードが働いてしまう懸念はあるのですが、そこは解った上で使って下さい。
jQuery を使ったコードは下記の通りです。(エラー処理は省略)

$(function() {

  $(document).on('paste', '.mce-textbox', function (event) {
    // event からクリップボードのアイテムを取り出す
    var items = event.originalEvent.clipboardData.items;
    clipboard_upload(items, $(this));
  });

  async function clipboard_upload(items, elm) {
    for (var i = 0 ; i < items.length ; i++) {
      var item = items[i];
      // 画像のみサーバへ送信する
      if (item.type.indexOf("image") != -1) {
        var file = item.getAsFile();
        var result = await file_upload(file);
        if( result.location ) {
          elm.val(result.location);
        }
        break;
      }
    }
  }

  function file_upload(file)
  {
    // フォームデータを取得
    var formdata = new FormData();
    formdata.append('file', file);

    var deferred = new $.Deferred;

    // POSTでアップロード
    $.ajax({
        url  : "uploader_json_mce.jsp",
        type : "POST",
        data : formdata,
        cache       : false,
        contentType : false,
        processData : false,
        dataType    : "json"
    })
    .done(function(result, textStatus, jqXHR){
        deferred.resolve(result)
    })
    .fail(function(jqXHR, textStatus, errorThrown){
        deferred.reject(xhr);
    });
    return deferred.promise();
  }

});

ファイルアップロードが成功すると、テキストにリンク文字列が挿入されます。
ソースコードの注意点として、$(document).on にしないと動的に作成された要素は jQueryのイベントハンドラに登録される保証がありません。
また、アップロード結果との同期を取りたかったので、async/await を使っています。
promiseチェインでも良いですが、こちらのほうが圧倒的に処理の意味が伝わり易いと思います。

« 前頁 次頁 »