Formát schránky HTML
Požadavky na přenos textu HTML pomocí schránky se liší v závislosti na scénáři. Tento článek se zabývá vyjmutím a vložením fragmentů dokumentu HTML. Můžou existovat požadavky na přenos celých dokumentů HTML prostřednictvím schránky; tento článek je však řízen požadavkem na přenos fragmentů vybraného textu HTML. Metoda, která vyžadovala zkopírování celého dokumentu HTML do schránky, je považována za příliš velkou váhu.
Formát schránky CF_HTML
umožňuje fragment nezpracovaného textu HTML a jeho kontextu (tj. vnější html) uložit do schránky jako ASCII. To umožňuje kontext fragmentu HTML, který se skládá ze všech předchozích okolních značek, prozkoumat aplikací tak, aby okolní značky fragmentu HTML bylo možné zaznamenat pomocí jejich atributů. I když je na aplikacích, aby se rozhodli, jak tyto fragmenty interpretovat, jsou zde uvedeny některé základní pokyny na základě implementací IE4/MSHTML.
Oficiální název schránky (řetězec používaný RegisterClipboardFormat
) je "HTML Format
".
Popis
CF_HTML
je textový formát schránky, i když vždy používá kódování UTF-8. Všimněte si, že použití UTF-8 je zde výjimkou obecného pravidla, které rozhraní API systému Windows používá pro reprezentaci textových řetězců UTF-16, zejména řetězce čitelné pro člověka (tj. lokalizovatelné).
Obecné rozložení nebo syntaxi schránky CF_HTML
můžete popsat ve formě pseudo Backus–Naur takto:
Poznámka
Tato gramatika není normativní**
<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"
Popis záhlaví a posunů
Záhlaví popisu obsahuje číslo verze schránky a posuny, které označují, kde je kontext a začátek a konec fragmentu. Popis je seznam textových klíčových slov ASCII následovaných řetězcem a odděleným dvojtečkam (:).
-
Version
: číslo verze vv schránky. Počáteční verze jeVersion:0.9
. Od Windows 10 20H2 je to nyníVersion:1.0
. -
StartHTML
: Posun (v bajtech) od začátku schránky na začátek kontextu nebo-1
, pokud žádný kontext neexistuje. -
EndHTML
: Posun (v bajtech) od začátku schránky na konec kontextu nebo-1
, pokud žádný kontext neexistuje. -
StartFragment
: Posun (v bajtech) od začátku schránky na začátek fragmentu. -
EndFragment
: Posun (v bajtech) od začátku schránky na konec fragmentu. -
StartSelection
: Volitelné. Posun (v bajtech) od začátku schránky na začátek výběru. -
EndSelection
: Volitelné. Posun (v bajtech) od začátku schránky na konec výběru
Klíčová slova StartSelection
a EndSelection
jsou nepovinná a pokud nechcete, aby aplikace tyto informace vygenerovala, je nutné je vynechat.
Budoucí revize formátu schránky CF_HTML
mohou například rozšířit záhlaví, protože html začíná na StartHTML
posunu, pak může být později přidáno více StartFragment
a EndFragment
páry, aby podporovaly nesouvislé výběr fragmentů.
Syntaxe posunu
Pro pohodlí programů vygenerovaných posuny bajtů mohou být hodnoty posunu volitelně ponechány na levé straně s libovolným množstvím nulových číslic '0'
. Důvodem je, že programy, které kód HTML pro posuny šifrují, by mohly napsat deset (10) nul do výstupní vyrovnávací paměti pro každé klíčové slovo (např. StartHTML: 0000000000
). Když je později známo přesné StartHTML
posunu (například 71), program může přepsat nuly nejvíce vpravo "71" ve vyrovnávací paměti (např. výsledkem StartHTML: 0000000071
).
Jedinou znakovou sadou podporovanou schránkou je Unicode (UTF-8). Vzhledem k tomu, že se první znaky UTF-8 a ASCII shodují, popis je vždy ASCII, ale bajty kontextu (počínaje StartHTML
) můžou používat jakékoli jiné znaky kódované v kódování UTF-8.
Konce řádků v záhlaví formátu schránky (<br>
výše) mohou být reprezentovány CRLF (Windows), LF (Unix) nebo lone CR (archaic).
Fragment, výběr a jejich kontext
Element | Záhlaví popisu | Vyžaduje platný kód HTML pro počáteční a koncové pozice znaků. |
---|---|---|
Kontext |
StartHTML a EndHTML |
Ano |
Úlomek |
StartFragment a EndFragment |
Ano |
Selekce |
StartSelection a EndSelection |
Ne |
Kontext
Kontext je platný, úplný dokument HTML – i když to neznamená, že celý původní zdrojový dokument HTML obsahující výběr uživatele se přenese doslovně; naopak může být minimální, ale dobře formátovaný dokument HTML.
Tento kontextový obsahuje fragment a všechny předchozí okolní značky (počáteční a koncové značky; tyto předchozí okolní značky představují všechny nadřazené uzly fragmentu, dokud uzel HTML). Výše uvedený příklad článku obsahuje kompletní html <head>
element, který umožňuje použití <base href="">
a <title>
elementů. Tento prvek lze například vložit, aby získal tyto další informace. Aplikace, která kopíruje fragment KÓDU HTML do schránky, se může rozhodnout vytvořit prvek <base href="">
, který se má zahrnout do kontextu, pokud takový prvek ještě neexistuje. Tímto způsobem lze přeložit ne absolutní identifikátory URI v fragmentu HTML.
Kontext je nepovinný, protože do fragmentu jsou zahrnuty dostatečné informace pro základní vložení fragmentu HTML, který se má provést. Pokud kontext není uložen, uloží se pouze fragment a StartHTML=EndHTML=-1
.
Úlomek
Fragment (<fragment-text>
výše) obsahuje platný fragment HTML.
platný fragment HTML se skládá z jednoho vnějšího elementu HTML. Tento element může obsahovat odvozené elementy HTML za předpokladu, že jsou správně vnořené. Fragment může být například jediný prvek <div>
, který obsahuje 3 <p>
elementy. Fragment skládající se z elementu <span>
, který obsahuje tři prvky <p>
, by byl neplatný, protože prvek <span>
(element) nemůže obsahovat prvky na úrovni bloku jako podřízené prvky.
Fragment tedy efektivně představuje větší oblast na obrazovce, ve které uživatel provedl výběr textu (například pro kopírování). Výběr obsahuje vybraný text a počáteční značky a atributy všech prvků, které mají koncovou značku ve vybraném textu, a koncové značky na konci fragmentu pro všechny zahrnuté počáteční značky. Toto jsou všechny informace potřebné pro základní vkládání fragmentu HTML.
Před fragmentu by měly následovat komentáře HTML <!--StartFragment-->
a <!--EndFragment-->
, které označují, kde fragment začíná a končí; tyto komentáře HTML musí být použity doslovné, bez prázdných znaků v každém komentáři. Začátek a konec fragmentu jsou tedy označeny přítomností těchto komentářů a hlavičkami StartFragment
a EndFragment
. Očekává se, že tyto informace vytvoří nástroje. Tato redundance je úmyslná a byla zavedena tak, aby mohla najít začátek fragmentu (z počtu bajtů) a označit pozici fragmentu přímo ve stromu HTML.
Selekce
Výběr je nepovinný, protože do fragmentu jsou zahrnuty dostatečné informace pro základní vkládání. Pokud výběr není uložený, StartSelection
i EndSelection
se v záhlaví neuloží.
Pokud existuje, výběr je přesný rozsah textu, který uživatel vybral (v fragmentu); tím se do fragmentu přidají další informace tím, že udávají přesný vybraný text, bez dobře formátované a vyvážené počáteční a koncové značky a koncové značky.
Nezapomeňte, že výběr může představovat běh textu, který může začínat v jakémkoli daném prvku a končit libovolný následný prvek – nebo nadřazený prvek. V důsledku toho není možné reprezentovat výběr textu pomocí HTML.
Scénáře
Následující scénáře popisují, jak editor HTML IE4/MSHTML zpracovává vyjmutí a vložení HTML; jiné aplikace můžou nebo nemusí tyto scénáře dodržovat. Zde popsaný formát schránky je určený k tomu, aby umožňoval flexibilitu fungování aplikace. (Tyto scénáře ukazují pouze dobrý kód HTML, tj. žádné překrývající se značky.)
Scénář 1 – jednoduchý fragment KÓDU HTML
Předpokládejme následující text HTML:
<body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body>
Zobrazí se takto:
To je normální. To je tučné.To je tučná kurzíva.To je kurzíva.
Když uživatel načetl výše uvedený text HTML do aplikace založené na MSHTML (MSHTML, aka Trident, byl internet explorerový modul), MSHTML zpracovává kopírování podřetězu HTML následujícím způsobem:
- Uživatel vybere text bez úvodního nebo koncového prázdného znaku, například tučné písmo Toto je tučné kurzíva Toto je z výše uvedeného příkladu.
- Pokud chcete text zkopírovat do schránky, uživatel klikne na příkazové tlačítko Kopírovat.
MSHTML umístí tento text HTML do schránky systému Windows následujícím způsobem:
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>
Scénář 2 – Fragment tabulky v HTML
Předpokládejme následující text 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>
Zobrazí se takto:
Hlava 1 Položka 1 Položka 2 Položka 3 Položka 4 Položka 5 Položka 6 Položka 7 Položka 8 Hlava 2 Položka 9 Položka 10 Položka 11 Položka 12
Jak MSHTML zpracovává kopírování podřetětěce HTML z tabulky
Když uživatel použije myš k výběru textu, který pokrývá buňky tabulky Položka 6, Položka 7, Položka 10a Položka 11. Tento výběr se pak zkopíruje do schránky.
Co následuje, je to, co bude ve schránce (všimněte si, že to je interpretace IE4/MSHTML). Konce řádků byly přidány pro přehlednost.
<!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>
Výběr oddělený StartSelection
a EndSelection
je zobrazen tučným písmem.
Scénář 3 – Vložení fragmentu uspořádaného seznamu <ol>
do prostého textu
Předpokládejme následující text 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>
Zobrazí se takto:
- Položka 1
- Položka 2
- Položka 3
- Položka 4
- Položka 5
- Položka 6
Jak MSHTML zpracovává kopírování podřetětěce položek číslovaného seznamu HTML
- Uživatel provede výběr textu od začátku položky 3, prostřednictvím položky 4a na konec položky 5. Uživatel vyvolá příkaz Kopírovat.
- Následující kód HTML je ve schránce (konce řádků přidány pro přehlednost) – přesné umístění komentářů
<!--Star/EndFragment -->
závisí na tom, jak uživatel zpracoval logiku výběru textu prohlížeče:
<html>
<body>
<ol>
<!-- StartFragment-->
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<!-- EndFragment-->
</ol>
</body>
</html>
Pokud by tento fragment byl nyní vložen do prázdného dokumentu, vytvoří se následující kód HTML:
<body>
<ol>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ol>
</body>
Zobrazí se takto:
- Položka 3
- Položka 4
- Položka 5
Scénář 5 – Vložení částečně vybrané oblasti
Předpokládejme následující text 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>
Zobrazí se takto:
IE4/MSHTML je editor WYSIWYG, který podporuje:
- Řezat
- Kopírovat
- Pasta
To je skvělý nástroj!
Jak MSHTML zpracovává kopírování podřetětěce položek seznamu HTML
Uživatel pomocí myši přetáhne výběr textu, například "Editor WYSIWYG, který podporuje: Cut Cop". Jako by to byl prostý text, tento výběr by vypadal jako tento poškozený fragment HTML:
WYSIWYG Editor, which supports:</p>
<ul>
<li>Cut</li>
<li>Cop
Když uživatel stiskne příkazové tlačítko Kopírovat, bude jeho schránka vypadat takto (konce řádků byly přidány pro přehlednost; tučný text označuje, co uživatel skutečně vybral):
<html> <body> <!-- StartFragment--> <p>WYSIWYG Editor, which supports</p> <ul> <li>Cut</li> <li>Cop</li> </ul> <!-- EndFragment--> </body> </html>
Všimněte si, že:
- Text před textem WYSIWYG byl odebrán.
- Položka seznamu (
<li>Paste</li>
) byla odebrána, protože nebyla ve výběru uživatele. - Odebrali jsme "y" z kopie.