Formato de área de transferência HTML
Os requisitos para transferir texto HTML por meio da área de transferência diferem dependendo do cenário. Este artigo se preocupa com o corte e a colagem de fragmentos de um documento HTML. Pode haver requisitos para transferir documentos HTML inteiros por meio da área de transferência; no entanto, este artigo é orientado por um requisito para transferir fragmentos de texto HTML selecionado. Assim, um método que exigia que todo o documento HTML fosse copiado para a área de transferência é visto como muito pesado.
O formato da área de transferência CF_HTML
permite que um fragmento de texto HTML bruto e seu contexto (ou seja, HTML externo) sejam armazenados na área de transferência como ASCII. Isso permite que o contexto do fragmento HTML, que consiste em todas as marcas ao redor anteriores, seja examinado por um aplicativo para que as marcas ao redor do fragmento HTML possam ser anotadas com seus atributos. Embora cabe aos aplicativos decidir como interpretar esses fragmentos, algumas diretrizes básicas são incluídas aqui com base nas implementações do IE4/MSHTML.
O nome oficial da área de transferência (a cadeia de caracteres usada por RegisterClipboardFormat
) é "HTML Format
".
Descrição
CF_HTML
é um formato de área de transferência de texto, embora sempre usando a codificação UTF-8. Observe que o uso do UTF-8 aqui é uma exceção à regra geral de que a API do Windows usa UTF-16 para representar cadeias de caracteres de texto, especialmente cadeias de caracteres legível por humanos (ou seja, localizáveis).
Você pode descrever o layout geral ou a sintaxe da área de transferência CF_HTML
no formato pseudo-Backus–Naur da seguinte maneira:
Nota
Esta gramática não é normativa**
<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"
Cabeçalhos e deslocamentos de descrição
O cabeçalho de descrição inclui o número de versão da área de transferência e deslocamentos, indicando onde o contexto e o fragmento começam e terminam. A descrição é uma lista de palavras-chave de texto ASCII seguidas por uma cadeia de caracteres e separadas por dois-pontos (:).
-
Version
: número de versão vv da área de transferência. A versão inicial éVersion:0.9
. A partir do Windows 10 20H2, agora éVersion:1.0
. -
StartHTML
: Deslocamento (em bytes) do início da área de transferência até o início do contexto ou-1
se nenhum contexto. -
EndHTML
: Deslocamento (em bytes) do início da área de transferência até o final do contexto ou-1
se nenhum contexto. -
StartFragment
: Deslocamento (em bytes) do início da área de transferência até o início do fragmento. -
EndFragment
: deslocamento (em bytes) do início da área de transferência até o final do fragmento. -
StartSelection
: opcional. Deslocamento (em bytes) do início da área de transferência até o início da seleção. -
EndSelection
: opcional. Deslocamento (em bytes) do início da área de transferência até o final da seleção.
As palavras-chave StartSelection
e EndSelection
são opcionais e devem ser omitidas se você não quiser que o aplicativo gere essas informações.
Revisões futuras do formato da área de transferência CF_HTML
podem estender o cabeçalho, por exemplo, uma vez que o HTML começa no deslocamento StartHTML
, então vários pares de StartFragment
e EndFragment
podem ser adicionados posteriormente para dar suporte à seleção nãotiguosa de fragmentos.
Sintaxe de deslocamento
Para a conveniência dos programas que geram os deslocamentos de bytes, os valores de deslocamento podem ser opcionalmente adicionados à esquerda com uma quantidade arbitrária de zero dígitos '0'
. O motivo para isso é que os programas que detectam o HTML para os deslocamentos podem gravar dez (10) zeros em seu buffer de saída para cada palavra-chave (por exemplo, StartHTML: 0000000000
). Posteriormente, quando o deslocamento exato StartHTML
for conhecido (digamos, 71), o programa poderá substituir os zeros mais à direita com "71" no buffer (por exemplo, resultando em StartHTML: 0000000071
).
O único conjunto de caracteres compatível com a área de transferência é Unicode (UTF-8). Como os primeiros caracteres de UTF-8 e ASCII correspondem, a descrição é sempre ASCII, mas os bytes do contexto (começando em StartHTML
) podem estar usando qualquer outro caractere codificado em UTF-8.
As extremidades das linhas no cabeçalho de formato de área de transferência (<br>
acima) podem ser representadas por CRLF (Windows), LF (Unix) ou CR solitário (arcaico).
O fragmento, a seleção e seu contexto
Elemento | Cabeçalhos de descrição | Requer HTML válido para posições de caractere inicial e final |
---|---|---|
Contexto |
StartHTML e EndHTML |
Sim |
Fragmento |
StartFragment e EndFragment |
Sim |
Escolha |
StartSelection e EndSelection |
Não |
Contexto
O contexto é um documento HTML válido e completo– embora isso não signifique que todo o documento HTML de origem original que contém a seleção do usuário será carregado verbatim; pelo contrário, pode ser um documento HTML mínimo, mas bem formado.
Esse contexto contém o fragmento e todas as marcas ao redor anteriores (marcas de início e de término; essas marcas ao redor anteriores representam todos os nós pai do fragmento, até o nó HTML). O artigo de exemplo acima tem um elemento HTML <head>
completo que permite o uso de elementos <base href="">
e <title>
. Por exemplo, esse elemento pode ser inserido para obter essas informações adicionais. Um aplicativo que copia um fragmento de HTML para a área de transferência pode optar por criar um elemento <base href="">
para incluí-lo no contexto se esse elemento ainda não estiver presente. Dessa forma, URIs não absolutas no fragmento HTML podem ser resolvidas.
O contexto é opcional, pois informações suficientes são incluídas no fragmento para que a colagem básica de um fragmento HTML ocorra. Se o contexto não estiver armazenado, o fragmento será armazenado apenas e o StartHTML=EndHTML=-1
.
Fragmento
O fragmento (<fragment-text>
acima) contém um fragmento HTML válido.
Um fragmento HTML de válido consiste em um único elemento HTML externo. Esse elemento pode conter elementos HTML descendentes desde que estejam aninhados corretamente. Por exemplo, um fragmento pode ser um único elemento <div>
que contém três elementos <p>
. Um fragmento que consiste em um elemento <span>
que contém três elementos <p>
seria inválido porque um elemento <span>
(um elemento) não pode conter elementos de nível de bloco como filhos.
Assim, o fragmento representa efetivamente a área maior na tela, na qual o usuário fez sua seleção de texto (para copiar, por exemplo). A seleção contém o texto selecionado mais as marcas de abertura e os atributos de qualquer elemento que tenha uma marca final dentro do texto selecionado e marcas de término no final do fragmento para qualquer marca inicial incluída. Essas são todas as informações necessárias para a colagem básica de um fragmento HTML.
O fragmento deve ser precedido e seguido pelos comentários HTML <!--StartFragment-->
e <!--EndFragment-->
para indicar onde o fragmento começa e termina; esses comentários HTML devem ser usados verbatim, sem caracteres de espaço em branco dentro de cada comentário em si. Portanto, o início e o fim do fragmento são indicados pela presença desses comentários e pelos cabeçalhos StartFragment
e EndFragment
. Espera-se que as ferramentas produzam essas informações. Essa redundância é intencional e foi introduzida para ser capaz de localizar o início do fragmento (da contagem de bytes) e marcar a posição do fragmento diretamente na árvore HTML.
Escolha
O de seleção de é opcional porque informações suficientes são incluídas no fragmento para colagem básica. Se a seleção não estiver armazenada, StartSelection
e EndSelection
não serão armazenados no cabeçalho.
Se estiver presente, o de seleção de será o intervalo exato de texto selecionado pelo usuário (dentro do fragmento ); isso adiciona mais informações ao fragmento indicando o texto exato selecionado, sem as marcas de início e de término bem formadas e equilibradas e marcas de término.
Lembre-se de que a seleção de pode representar uma execução de texto que pode começar em qualquer elemento determinado e terminar em qualquer elemento subsequente - ou ancestral - . Consequentemente, é impossível representar uma seleção de texto usando HTML.
Cenários
Os cenários a seguir descrevem como o editor HTML IE4/MSHTML lida com corte e colagem HTML; outros aplicativos podem ou não seguir esses cenários. O formato de área de transferência descrito aqui destina-se a permitir flexibilidade para como um aplicativo opta por funcionar. (Esses cenários mostram apenas um html bom, ou seja, nenhuma marca sobreposta.)
Cenário 1 – Fragmento simples de HTML
Suponha o seguinte texto HTML:
<body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body>
Isso será exibido da seguinte maneira:
Isso é normal. isso é negrito.Isso é negrito itálico.isso é itálico.
Quando o usuário carregou o texto HTML acima em um aplicativo baseado em MSHTML (MSHTML, também conhecido como Trident, era o mecanismo do Internet Explorer), o MSHTML manipula a cópia de uma subcadeia de caracteres de HTML da seguinte maneira:
- O usuário seleciona um texto sem qualquer espaço em branco à esquerda ou à direita, por exemplo, "bold This is bold italic This" no exemplo acima.
- Para copiar o texto para a área de transferência, o usuário clica no botão Copiar comando.
MSHTML colocará esse texto HTML na Área de Transferência do Windows da seguinte maneira:
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>
Cenário 2 – Fragmento de uma tabela em HTML
Suponha o seguinte texto 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>
Isso será exibido da seguinte maneira:
Cabeça 1 Item 1 Item 2 Item 3 Item 4 Item 5 Item 6 Item 7 Item 8 Cabeça 2 Item 9 Item 10 Item 11 Item 12
Como o MSHTML manipula a cópia de uma subcadeia de caracteres de HTML de uma tabela
Quando o usuário usa o mouse para fazer uma seleção de texto cobrindo as células da tabela Item 6, Item 7, Item 10e Item 11. Essa seleção é copiada para a área de transferência.
O que se segue é o que estará na área de transferência (observe que esta é a interpretação do IE4/MSHTML). Quebras de linha foram adicionadas para maior clareza.
<!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>
A seleção, delimitada por StartSelection
e EndSelection
, é mostrada em negrito.
Cenário 3 – Colar um fragmento de uma lista ordenada <ol>
em texto sem formatação
Suponha o seguinte texto 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>
Isso será exibido da seguinte maneira:
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6
Como o MSHTML manipula a cópia de uma subcadeia de caracteres de itens de lista numerados em HTML
- O usuário faz uma seleção de texto desde o início de item 3, até item 4e até o final do item 5 5. O usuário invoca o comando Copiar.
- O HTML a seguir está na área de transferência (quebras de linha adicionadas para maior clareza) – o local preciso dos comentários de
<!--Star/EndFragment -->
depende de como o usuário lidou com a lógica de seleção de texto do navegador:
<html>
<body>
<ol>
<!-- StartFragment-->
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<!-- EndFragment-->
</ol>
</body>
</html>
Se esse fragmento fosse colado agora em um documento vazio, o html a seguir será criado:
<body>
<ol>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ol>
</body>
Isso será exibido da seguinte maneira:
- Item 3
- Item 4
- Item 5
Cenário 5 – Colar uma região parcialmente selecionada
Suponha o seguinte texto 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>
Isso será exibido da seguinte maneira:
O IE4/MSHTML é um Editor WYSIWYG compatível com:
- Cortar
- Copiar
- Colar
Esta é uma ótima ferramenta!
Como o MSHTML manipula a cópia de uma subcadeia de caracteres de itens de lista HTML
O usuário usa o mouse para arrastar uma seleção de texto, por exemplo, "Editor WYSIWYG que dá suporte a: Cut Cop". Como se fosse um texto sem formatação, essa seleção seria semelhante a este fragmento HTML quebrado:
WYSIWYG Editor, which supports:</p>
<ul>
<li>Cut</li>
<li>Cop
Quando o usuário pressionar o botão Copiar comando, sua área de transferência terá esta aparência (quebras de linha foram adicionadas para maior clareza; o texto em negrito indica o que o usuário realmente selecionou):
<html> <body> <!-- StartFragment--> <p>WYSIWYG Editor, which supports</p> <ul> <li>Cut</li> <li>Cop</li> </ul> <!-- EndFragment--> </body> </html>
Observe que:
- O texto anterior a "WYSIWYG" foi removido.
- O item de lista (
<li>Paste</li>
) foi removido, pois nenhum deles estava na seleção do usuário. - O "y" de "Copy" foi removido.