Формат буфера обмена HTML

Требования к передаче HTML-текста с помощью буфера обмена отличаются в зависимости от сценария. Эта статья связана с вырезанием и вставкой фрагментов HTML-документа. Могут потребоваться требования для передачи целых HTML-документов через буфер обмена; Однако эта статья обусловлена требованием передачи фрагментов выделенного HTML-текста. Таким образом, метод, который требует копирования всего HTML-документа в буфер обмена, рассматривается как слишком тяжелый вес.

Формат CF_HTML буфера обмена позволяет хранить фрагмент необработанного HTML-текста и его контекст (т. е. внешний HTML) в буфере обмена как ASCII. Это позволяет контексту фрагмента HTML, состоящего из всех предыдущих окружающих тегов, проверяться приложением, чтобы окружающие теги фрагмента HTML можно было отметить с их атрибутами. Хотя это зависит от приложений, чтобы решить, как интерпретировать такие фрагменты, некоторые основные рекомендации включены здесь на основе реализаций IE4/MSHTML.

Официальное имя буфера обмена (строка, используемая RegisterClipboardFormat) — "HTML Format".

Description

CF_HTML — это формат буфера обмена текста, хотя всегда используется кодировка UTF-8. Обратите внимание, что использование UTF-8 здесь является исключением из общего правила, которое API Windows использует UTF-16 для представления текстовых строк, особенно строк, доступных для чтения пользователем (например, локализуемых) строк.

Вы можете описать общий макет или синтаксис CF_HTML буфера обмена в форме псевдо-Backus–Naur, как показано ниже.

Примечание.

Эта грамматика не является нормативным**

<cf-html>                ::= <description-header> <context>
<context>                ::= [<preceding-context>] <fragment> [<trailing-context>]

<description-header>     ::= "Version:" <version> <br> ( <header-offset-keyword> ":" <header-offset-value> <br> )*
<header-offset-keyword>  ::= "StartHTML" | "EndHTML" | "StartFragment" | "EndFragment" | "StartSelection" | "EndSelection"
<header-offset-value>    ::= { Base 10 (decimal) integer string with optional _multiple_ leading zero digits (see "Offset syntax" below) }
<version>                ::= "0.9" | "1.0"
<fragment>               ::= <fragment-start-comment> <fragment-text> <fragment-end-comment>
<fragment-start-comment> ::= "<!--StartFragment -->"
<fragment-end-comment>   ::= "<!--EndFragment -->"
<preceding-context>      ::= { Arbitrary HTML }
<trailing-context>       ::= { Arbitrary HTML }
<fragment-text>          ::= { Arbitrary HTML }
<br>                     ::= "\r" | "\n" | "\r\n"

Описание заголовков и смещения

Заголовок описания содержит номер версии буфера обмена и смещения, указывающие, где контекст и начало и конец фрагмента. Описание — это список текстовых ключевое слово ASCII, за которым следует строка и двоеточие (:)).

  • Version: номер версии vv буфера обмена. Начальная Version:0.9версия : . По состоянию на Windows 10 20H2 это сейчас Version:1.0.
  • StartHTML: смещение (в байтах) с начала буфера обмена до начала контекста или -1 отсутствие контекста.
  • EndHTML: смещение (в байтах) с начала буфера обмена до конца контекста или -1 отсутствие контекста.
  • StartFragment: смещение (в байтах) с начала буфера обмена до начала фрагмента.
  • EndFragment: смещение (в байтах) с начала буфера обмена до конца фрагмента.
  • StartSelection: необязательный параметр. Смещение (в байтах) с начала буфера обмена до начала выделения.
  • EndSelection: необязательный параметр. Смещение (в байтах) с начала буфера обмена до конца выделенного фрагмента.

И StartSelectionEndSelection ключевое слово являются необязательными и должны быть опущены, если вы не хотите, чтобы приложение создавало эти сведения.

Будущие редакции CF_HTML формата буфера обмена могут расширить заголовок, например, так как HTML начинается со StartHTML смещения, а затем StartFragment несколько и EndFragment пары могут быть добавлены позже для поддержки неконтентного выбора фрагментов.

Синтаксис смещения

Для удобства программ, создающих смещения байтов, значения смещения могут быть при необходимости левой панели с произвольным количеством нулевых цифр '0'. Причиной этого является то, что программы, хнюющие HTML для смещения, могут записывать десять (10) ноль в выходной буфер для каждого ключевое слово (например, StartHTML: 0000000000). Позже, когда точное StartHTML смещение известно (например, 71), программа может перезаписать последние правые нули с "71" в буфере (например, в результате StartHTML: 0000000071).

Единственным набором символов, поддерживаемым буфером обмена, является Юникод (UTF-8). Так как первые символы UTF-8 и ASCII совпадают, описание всегда равно ASCII, но байты контекста (начиная StartHTMLс) могут использовать любые другие символы, закодированные в UTF-8.

Концы строк в заголовке формата буфера обмена (<br> выше) могут быть представлены CRLF (Windows), LF (Unix) или одиноким CR (архаичным).

Фрагмент, выделение и их контекст

Элемент Заголовки описания Требуется допустимый HTML-код для позиций начального и конечного символов
Контекст StartHTML и EndHTML. Да
Фрагмент StartFragment и EndFragment. Да
Выбор StartSelection и EndSelection. No

Контекст

Контекст является допустимым, полным HTML-документом, хотя это не означает, что весь исходный HTML-документ, содержащий выбор пользователя, будет переноситься поверх, наоборот, он может быть минимальным, но хорошо сформированным, HTML-документом.

Этот контекст содержит фрагмент и все предыдущие окружающие теги (начальные и конечные теги; эти предыдущие окружающие теги представляют все родительские узлы фрагмента до html-узла). В приведенном выше примере статья содержит полный HTML-элемент <head> , который позволяет использовать <base href=""> элементы и <title> элементы. Например, этот элемент можно вставить, чтобы получить эти дополнительные сведения. Приложение, копируемое фрагмент HTML в буфер обмена, может выбрать создание <base href=""> элемента, чтобы включить его в контекст, если такой элемент еще не присутствует. Таким образом, не абсолютные URI в фрагменте HTML можно разрешить.

Контекст необязателен , так как достаточная информация включена в фрагмент для базовой вставки фрагмента HTML. Если контекст не хранится, фрагмент сохраняется только и .StartHTML=EndHTML=-1

Фрагмент

Фрагмент (<fragment-text>выше) содержит допустимый фрагмент HTML.

Допустимый фрагмент HTML состоит из одного внешнего ЭЛЕМЕНТА HTML. Этот элемент может содержать элементы HTML-потомков, если они правильно вложены. Например, фрагмент может быть одним <div> элементом, содержащим 3 <p> элемента. Фрагмент, состоящий из <span> элемента, содержащего три <p> элемента, будет недопустимым, так как <span> элемент (элемент) не может содержать элементы уровня блока в виде дочерних элементов.

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

Перед фрагментом следует примечания <!--StartFragment--> HTML и <!--EndFragment--> указать, где начинается и заканчивается фрагмент. Эти html-комментарии должны использоваться подробно, без пробелов внутри каждого комментария. Таким образом, начало и конец фрагмента указываются наличием этих комментариев иStartFragmentEndFragment заголовками. Ожидается, что средства будут создавать эти сведения. Эта избыточность является намеренной и была введена для того, чтобы найти начало фрагмента (от числа байтов) и пометить положение фрагмента непосредственно в html-дереве.

Выбор

Выбор необязателен, так как достаточная информация включена в фрагмент для базовой вставки. Если выбор не хранится, StartSelection оба и EndSelection не хранятся в заголовке.

При наличии выборкаэто точный текстовый диапазон, выбранный пользователем (в фрагменте). Это добавляет дополнительные сведения в фрагмент, указывая точный выделенный текст, без хорошо сформированных и сбалансированных тегов начала и окончания тегов и конечных тегов.

Помните, что выделение может представлять собой запуск текста, который может начинаться в любом заданном элементе и заканчиваться любым последующим элементом - или предком. Следовательно, невозможно представить выделение текста с помощью HTML.

Сценарии

В следующих сценариях описывается, как редактор HTML IE4/MSHTML обрабатывает вырезанные и вставки HTML; другие приложения могут или не следовать этим сценариям. Формат буфера обмена, описанный здесь, предназначен для обеспечения гибкости того, как приложение выбирает функцию. (В этих сценариях отображаются только хорошие HTML-коды, то есть не перекрывающиеся теги.)

Сценарий 1. Простой фрагмент HTML

Предположим, что следующий HTML-текст:

<body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body>

Это будет выглядеть следующим образом:

Это нормально. Это полужирный.Это смелый курсив.Это курсив.

Когда пользователь загрузил приведенный выше HTML-текст в приложение на основе MSHTML (MSHTML, ака Trident, был обработчиком Интернета Обозреватель), MSHTML обрабатывает копирование подстроки HTML следующим образом:

  1. Пользователь выбирает текст без начальных или конечных пробелов, например"полужирный курсив" из приведенного выше примера.
  2. Чтобы скопировать текст в буфер обмена, пользователь нажимает кнопку "Копировать".

MSHTML помещает этот HTML-текст в буфер обмена Windows следующим образом:

Version:1.0
StartHTML:0121
EndHTML:0272
StartFragment:0006
EndFragment:0106
StartSelection:0180
EndSelection:0225
<html><!--StartFragment--><body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body><!--EndFragment--></html>

Сценарий 2. Фрагмент таблицы в HTML

Предположим, что следующий HTML-текст:

<BODY><TABLE BORDER><TR><TH ROWSPAN=2>Head1</TH><TD>Item 1</TD><TD>Item 2</TD><TD>Item 3</TD><TD>Item 4</TD></TR><TR><TD>Item 5</TD><TD>Item 6</TD><TD>Item 7</TD><TD>Item 8</TD></TR><TR><TH>Head2</TH><TD>Item 9</TD><TD>Item 10</TD><TD>Item 11</TD><TD>Item 12</TD></TR></TABLE></BODY>

Это будет выглядеть следующим образом:

Голова 1 Пункт 1 Пункт 2 Пункт 3 Элемент 4
Элемент 5 Элемент 6 Элемент 7 Элемент 8
Голова 2 Элемент 9 Элемент 10 Элемент 11 Элемент 12

Как MSHTML обрабатывает копирование подстроки HTML из таблицы

Когда пользователь использует мышь для выделения текста, охватывающего ячейки таблицы Item 6, Item 7, Item 10 и Item 11. Затем этот выбор копируется в буфер обмена.

Ниже показано, что будет находиться в буфере обмена (обратите внимание, что это интерпретация IE4/MSHTML). Разрывы строк добавлены для ясности.

<!DOCTYPE
<HTML>
<BODY>
<TABLE BORDER>
<!--StartFragment-->
  **<TR>
    <TD>Item 6</TD>
    <TD>Item 7</TD>
  </TR>
  <TR>
    <TD>Item 10</TD>
    <TD>Item 11</TD>
  </TR>**
<!--EndFragment-->
</TABLE>
</BODY>
</HTML>

Выделение, разделенное по разделителям иEndSelection, отображается полужирным шрифтомStartSelection.

Сценарий 3. Вставка фрагмента упорядоченного списка <ol> в обычный текст

Предположим, что следующий HTML-текст:

<BODY><OL TYPE="a"><LI>Item 1<LI>Item 2<LI>Item 3<LI>Item 4<LI>Item 5<LI>Item 6</OL></BODY>

Это будет выглядеть следующим образом:

  1. Пункт 1
  2. Пункт 2
  3. Пункт 3
  4. Элемент 4
  5. Элемент 5
  6. Элемент 6

Как MSHTML обрабатывает копирование подстроки нумерованного HTML-элемента списка

  1. Пользователь выбирает текст с начала элемента 3 до элемента 4 и до конца элемента 5. Пользователь вызывает команду Copy.
  2. Следующий КОД HTML находится в буфере обмена (разрывы строк, добавленные для ясности) — точное расположение <!--Star/EndFragment --> комментариев зависит от того, как пользователь обработал логику выделения текста в браузере:
<html>
<body>
<ol>
<!-- StartFragment-->
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<!-- EndFragment-->
</ol>
</body>
</html>

Если этот фрагмент должен был быть вставлен в пустой документ, будет создан следующий HTML-код:

<body>
<ol>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ol>
</body>

Это будет выглядеть следующим образом:

  1. Пункт 3
  2. Элемент 4
  3. Элемент 5

Сценарий 5. Вставка частично выбранного региона

Предположим, что следующий HTML-текст:

<p>IE4/MSHTML is a WYSIWYG Editor that supports:</p>
<ul><li>Cut<li>Copy<li>Paste</ul>
<p>This is a Great Tool!</p>

Это будет выглядеть следующим образом:

IE4/MSHTML — это редактор WYSIWYG, который поддерживает:

  • Вырезать
  • Копия
  • Вставить

Это отличный инструмент!

Как MSHTML обрабатывает копирование подстроки элементов списка HTML

Пользователь использует мышь для перетаскивания выделения текста, например "Редактор WYSIWYG, который поддерживает: Cut Cop". Как если бы это был обычный текст, этот фрагмент HTML будет выглядеть следующим образом:

WYSIWYG Editor, which supports:</p>
<ul>
  <li>Cut</li>
  <li>Cop

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

<html>
<body>
<!-- StartFragment-->
<p>WYSIWYG Editor, which supports</p>
<ul>
	<li>Cut</li>
	<li>Cop</li>
</ul>
<!-- EndFragment-->
</body>
</html>

Обратите внимание, что:

  • Текст, предшествующий WYSIWYG, был удален.
  • Элемент списка (<li>Paste</li>) был удален, так как ни один из них не был выбран пользователем.
  • Значение "y" из "Копировать" было удалено.

См. также

Буфер обмена