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 em recortar e colar fragmentos de um documento HTML. Pode haver requisitos para transferir documentos HTML inteiros através da área de transferência; no entanto, este artigo é orientado por um requisito para transferir fragmentos de texto HTML selecionado. Como tal, um método que exigia que todo o documento HTML fosse copiado para a área de transferência é visto como muito pesado.
O CF_HTML
formato da área de transferência 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 tags adjacentes anteriores, seja examinado por um aplicativo para que as tags circundantes do fragmento HTML possam ser observadas com seus atributos. Embora caiba aos aplicativos decidir como interpretar tais fragmentos, algumas diretrizes básicas são incluídas aqui com base em implementações 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 codificação UTF-8. Observe que o uso de 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íveis por humanos (ou seja, localizáveis).
Você pode descrever o layout geral ou a CF_HTML
sintaxe da área de transferência na forma pseudo-Backus–Naur da seguinte forma:
Observação
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"
Descrição Cabeçalhos e Deslocamentos
O cabeçalho de descrição inclui o número da 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
: vv número da versão da área de transferência. A versão inicial éVersion:0.9
. A partir do Windows 10 20H2 isso é agoraVersion:1.0
.StartHTML
: Deslocamento (em bytes) do início da área de transferência para o início do contexto ou-1
, se nenhum contexto.EndHTML
: Deslocamento (em bytes) do início da área de transferência para o final do contexto ou-1
, se nenhum contexto.StartFragment
: Deslocamento (em bytes) do início da área de transferência para o início do fragmento.EndFragment
: Deslocamento (em bytes) do início da área de transferência para o final do fragmento.StartSelection
: opcional. Deslocamento (em bytes) do início da área de transferência para o início da seleção.EndSelection
: opcional. Deslocamento (em bytes) do início da área de transferência para o final da seleção.
As StartSelection
palavras-chave e são opcionais e EndSelection
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 podem estender o cabeçalho, por exemplo, uma vez que o HTML começa no StartHTML
deslocamento, então múltiplos StartFragment
e EndFragment
pares podem ser adicionados posteriormente para suportar a seleção não contígua de CF_HTML
fragmentos.
Sintaxe de deslocamento
Para a conveniência dos programas que geram os deslocamentos de bytes, os valores de deslocamento podem ser opcionalmente preenchidos à esquerda com uma quantidade arbitrária de zero dígitos '0'
. A razão para isso é que os programas que farejam o HTML para os deslocamentos poderiam gravar dez (10) zeros em seu buffer de saída para cada palavra-chave (por exemplo, StartHTML: 0000000000
). Mais tarde, quando o deslocamento exato StartHTML
é conhecido (digamos, 71), o programa pode substituir os zeros mais à direita com "71" no buffer (por exemplo, resultando em StartHTML: 0000000071
).
O único conjunto de caracteres suportado pela á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 ) podem estar usando quaisquer outros caracteres codificados em StartHTML
UTF-8.
As extremidades das linhas no cabeçalho do formato da área de transferência (acima) podem ser representadas por CRLF (Windows), LF (Unix) ou CR solitário (<br>
arcaico).
O fragmento, a seleção e seu contexto
Element | Cabeçalhos de descrição | Requer HTML válido para posições de caracteres iniciais e finais |
---|---|---|
Contexto | StartHTML e EndHTML |
Sim |
Fragmento | StartFragment e EndFragment |
Sim |
Seleção | 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 original contendo a seleção do usuário será transportado textualmente, pelo contrário, pode ser um documento HTML mínimo, mas bem formado.
Esse contexto contém o fragmento e todas as tags adjacentes anteriores (tags start e end; essas tags adjacentes 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 <base href="">
elementos 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 <base href="">
elemento para incluí-lo no contexto se esse elemento ainda não estiver presente. Dessa forma, URIs não absolutos no fragmento HTML podem ser resolvidos.
O contexto é opcional, pois informações suficientes são incluídas no fragmento para que ocorra a colagem básica de um fragmento HTML. Se o contexto não for armazenado, somente o fragmento será armazenado e o StartHTML=EndHTML=-1
arquivo .
Fragmento
O fragmento (<fragment-text>
acima) contém um fragmento HTML válido.
Um fragmento HTML 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 <div>
elemento que contém 3 <p>
elementos. Um fragmento que consiste em um elemento que contém três <p>
elementos seria inválido porque um elemento (um <span>
<span>
elemento) não pode conter elementos de nível de bloco como filhos.
Assim, o fragmento representa efetivamente a maior área na tela interna, 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 atributos de qualquer elemento que tenha uma marca de fim dentro do texto selecionado e marcas de fim no final do fragmento para qualquer marca de início 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 e para indicar onde o fragmento começa e <!--EndFragment-->
termina, esses comentários <!--StartFragment-->
HTML devem ser usados textualmente, sem caracteres de espaço em branco dentro de cada comentário em si. Assim, o início e o fim do fragmento são indicados pela presença desses comentários e pelos StartFragment
cabeçalhos e EndFragment
. Espera-se que as ferramentas produzam essas informações. Essa redundância é intencional e foi introduzida para poder encontrar o início do fragmento (a partir da contagem de bytes) e marcar a posição do fragmento diretamente na árvore HTML.
Seleção
A seleção é opcional porque informações suficientes são incluídas no fragmento para colagem básica. Se a seleção não estiver armazenada, ambas StartSelection
e EndSelection
não serão armazenadas no cabeçalho.
Se presente, a seleção é o intervalo exato de texto que o usuário selecionou (dentro do fragmento), isso adiciona mais informações ao fragmento, indicando o texto selecionado exato, sem as tags de início e fim bem formadas e equilibradas.
Lembre-se, a seleção pode representar uma sequência de texto que pode começar em qualquer elemento dado 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 manipula HTML recortar e colar; Outros aplicativos podem ou não seguir esses cenários. O formato da área de transferência descrito aqui destina-se a permitir flexibilidade para como um aplicativo escolhe funcionar. (Esses cenários mostram apenas HTML bom, ou seja, sem marcas sobrepostas.)
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 aparecerá da seguinte maneira:
Isso é normal. Isso é ousado.Este é negrito itálico.Isso está em itálico.
Quando o usuário tiver carregado o texto HTML acima em um aplicativo baseado em MSHTML (MSHTML, também conhecido como Trident, era o mecanismo do Internet Explorer), MSHTML manipula a cópia de uma subsequência de HTML da seguinte maneira:
- O usuário seleciona um texto sem qualquer espaço em branco à esquerda ou à direita, por exemplo, "negrito Isto é negrito itálico Isto" do exemplo acima.
- Para copiar o texto para a área de transferência, o usuário clica no botão de comando Copiar.
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 aparecerá 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 lida com a cópia de uma subcadeia de caracteres 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 10 e Item 11. Essa seleção é copiada para a área de transferência.
O que se segue é o que estará na área de transferência (note 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 - Colando um fragmento de uma lista <ol>
ordenada 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 aparecerá da seguinte maneira:
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6
Como o MSHTML lida com a cópia de uma subcadeia de caracteres de itens de lista numerados HTML
- O usuário faz uma seleção de texto desde o início do item 3, passando pelo item 4 e até o final do item 5. O usuário invoca o comando Copiar.
- O seguinte HTML está na área de transferência (quebras de linha adicionadas para clareza) - a localização precisa dos comentários depende de como o usuário lidou com a lógica de seleção de
<!--Star/EndFragment -->
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 agora for colado em um documento vazio, o seguinte HTML será criado:
<body>
<ol>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ol>
</body>
Isso aparecerá da seguinte maneira:
- Item 3
- Item 4
- Item 5
Cenário 5 - Colando 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 aparecerá da seguinte maneira:
IE4/MSHTML é um editor WYSIWYG que suporta:
- Recortar
- Copiar
- Colar
Esta é uma ótima ferramenta!
Como o MSHTML lida com 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 suporta: Cut Cop". Como se fosse texto sem formatação, essa seleção se pareceria com este fragmento HTML quebrado:
WYSIWYG Editor, which supports:</p>
<ul>
<li>Cut</li>
<li>Cop
Quando o usuário pressiona o botão de comando Copiar, sua área de transferência terá a seguinte 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.