TinyMCE ドラッグでコピーしたのと同じようにコピーする

tinymce

 

TinyMCEビジュアルエディタ上を全選択してコピーする。

通常のコピーだと、HTMLタグ付きで、テキストとしてコピーするため、別のビジュアルエディタ上に貼り付けるとHTMLソースがむき出しになる。

 

エディタ上でドラッグしてコピーすると、何故かHTMLタグがテキストとしてコピーされずに、別のエディタにHTMLを反映させつつ貼り付けできる。

 

これは、ブラウザのクリップボードAPIとエディタの内部動作に関係しているらしい。

 

全選択などで選択してコピーした場合、HTMLタグを含むすべてをプレーンテキストとしてコピーされ、ドラッグで選択してコピーした場合は、プレーンテキストとHTMLの両方としてコピーされる。

 

従って、すべてがプレーンテキストでコピーされた場合は、貼り付け時にエスケープされてしまってHTMLタグがむき出しになるが、ドラッグでコピーした場合は、エディタに貼り付けるときにTinyMCEが適切に処理する事が出来るためHTMLを認識しつつテキストとして貼り付けられるっぽい。

 

今回はこの、ドラッグでコピーした状態をJSのボタンで実現したい。

Javascript

function copyHTMLContent() {
  var editor = tinymce.get('info');
  if (editor) {
    editor.execCommand('SelectAll');
    editor.execCommand('copy');
    alert('HTMLコンテンツがクリップボードにコピーされました');
  }
}

 

HTML

<textarea id="info"></textarea>
<button onclick="copyHTMLContent()">ドラッグっぽくコピーする!</button>

 

 

execCommand()は非推奨のためClipboard API を使用して以下のように書く事も出来る。

 

Javascript

async function copyHTMLContent() {
  var editor = tinymce.get('info');
  if (editor) {
    // エディタの内容を取得
    var content = editor.getContent();
    
    try {
      // クリップボードにHTML形式で書き込む
      await navigator.clipboard.write([
        new ClipboardItem({
          'text/html': new Blob([content], { type: 'text/html' }),
          'text/plain': new Blob([editor.getContent({ format: 'text' })], { type: 'text/plain' })
        })
      ]);
      alert('HTMLコンテンツがクリップボードにコピーされました');
    } catch (err) {
      console.error('クリップボードへの書き込みに失敗しました: ', err);
    }
  }
}

 

非同期を使わない場合

function copyHTMLContent() {
  var editor = tinymce.get('info');
  if (editor) {
    // エディタの内容を取得
    var content = editor.getContent();
    
    // クリップボードにHTML形式で書き込む
    navigator.clipboard.write([
      new ClipboardItem({
        'text/html': new Blob([content], { type: 'text/html' }),
        'text/plain': new Blob([editor.getContent({ format: 'text' })], { type: 'text/plain' })
      })
    ]).then(function() {
      alert('HTMLコンテンツがクリップボードにコピーされました');
    }).catch(function(err) {
      console.error('クリップボードへの書き込みに失敗しました: ', err);
    });
  }
}