Копирование HTML из выделения в буфер обмена с собственным JavaScript - PullRequest
0 голосов
/ 03 сентября 2018

Я создал пользовательское контекстное меню (включая пункт меню для копирования произвольного текста, который был ранее выбран в буфер обмена), которое работает нормально, за исключением одного: при попытке скопировать и вставить фрагмент текста с веб-страницы где-то еще форматирование указанного фрагмента (разрывы строк и т. д.) потеряно.

Теперь меня беспокоит вопрос, есть ли способ получить выделенный (произвольный) текст и сохранить его форматирование? В настоящее время я использую эту функцию для получения текста:

function GetSelection()
  {
var l_result;

  if(window.getSelection)
    l_result = window.getSelection();
  else
    if(document.getSelection)
      l_result = document.getSelection();
    else
      if(document.selection)
        l_result = document.selection.createRange().text;

  return l_result;
  }

Эта функция вызывается нажатием на пункт меню Копировать в контекстном меню, и поэтому имеет обязательное вмешательство пользователя.

Для облегчения механизма передачи я также прикрепил следующий обработчик событий (я нашел эту часть в этом ответе ; к сожалению, каждый получает содержимое целого элемента и копирует его в буфер обмена, что нарушает условие, что произвольный текст, выбранный пользователем, должен быть скопирован):

document.addEventListener('copy', function (p_event) {
  if(selected == '')
    return;

  p_event.clipboardData.setData('text/plain', selected);
  p_event.preventDefault();
  selected = '';
  }, true);

В данный момент тип MIME копируемого выделения установлен на text/plain, потому что в настоящее время я не могу убедить объект clipboardData принять его как text/html. Сейчас я немного погуглил, но пока не нашел жизнеспособного решения.
Вот полная тестовая страница для демонстрации эффекта (протестировано с Firefox 61.0.2):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xml:lang="en">
<head>
<title>Clipboard Test Case</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<script type="application/javascript">
/* <![CDATA[ */
var selected = '';

function GetSelection()
  {
var l_result;

  if(window.getSelection)
    l_result = window.getSelection();
  else
    if(document.getSelection)
      l_result = document.getSelection();
    else
      if(document.selection)
        l_result = document.selection.createRange().text;

  return l_result;
  }

document.addEventListener('DOMContentLoaded', function () {
  document.addEventListener('copy', function(p_element) {
    if(selected == '')
      return;

    p_event.clipboardData.setData('text/html', selected);   // Fails
    p_event.clipboardData.setData('text/plain', selected);  // Works
    p_event.preventDefault();
    selected = '';
    }, true);

  document.getElementById('grab-text').addEventListener('click', function (p_event) {
    selected = GetSelection();
    if(selected == '')
      {
      alert('Please select some text first!');
      return;
      }

    document.execCommand('copy');
    }, false);
  }, false);
/* ]]> */
</script>
</head>
<body>
<header><h1>Clipboard Test Case</h1></header>
<main>
<p style="white-space: pre;">
Lorem ipsum dolor sit amet,
consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt
ut labore et dolore magna aliquyam erat,
sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet,
consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt
ut labore et dolore magna aliquyam erat,
sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
<form action="javascript:void(0);">
<input type="button" id="grab-text" value="Grab text!" />
</form>
</main>
</body>
</html>

Жизнеспособные решения должны быть на нативном JavaScript и не содержать JQuery или других библиотек, ни обходных путей через Flash или тому подобное.

...