HTML-Zwischenablageformat
Die Anforderungen für die Übertragung von HTML-Text über die Zwischenablage unterscheiden sich je nach Szenario. Dieser Artikel befasst sich mit dem Ausschneiden und Einfügen von Fragmenten eines HTML-Dokuments. Es kann Anforderungen für die Übertragung ganzer HTML-Dokumente über die Zwischenablage geben; Dieser Artikel basiert jedoch auf der Anforderung, Fragmente des ausgewählten HTML-Texts zu übertragen. Daher wird eine Methode, bei der das gesamte HTML-Dokument in die Zwischenablage kopiert werden musste, als zu schwer angesehen.
Das CF_HTML
Format der Zwischenablage ermöglicht es, ein Fragment von unformatiertem HTML-Text und dessen Kontext (d. h. äußeres HTML) als ASCII in der Zwischenablage zu speichern. Dadurch kann der Kontext des HTML-Fragments, das aus allen vorangehenden umgebenden Tags besteht, von einer Anwendung untersucht werden, sodass die umgebenden Tags des HTML-Fragments mit ihren Attributen notiert werden können. Obwohl es an Anwendungen liegt, zu entscheiden, wie solche Fragmente interpretiert werden sollen, sind hier einige grundlegende Richtlinien enthalten, die auf IE4-/MSHTML-Implementierungen basieren.
Der offizielle Name der Zwischenablage (die von RegisterClipboardFormat
verwendete Zeichenfolge) lautet "HTML Format
".
BESCHREIBUNG
CF_HTML
ist ein Text-Zwischenablageformat, obwohl immer UTF-8-Codierung verwendet wird. Beachten Sie, dass die Verwendung von UTF-8 hier eine Ausnahme von der allgemeinen Regel darstellt, dass die Windows-API UTF-16 für die Darstellung von Textzeichenfolgen verwendet, insbesondere für Menschen lesbare (d. h. lokalisierbare) Zeichenfolgen.
Sie können das allgemeine Layout oder die Syntax der CF_HTML
Zwischenablage im Pseudo-Backus-Naur-Format wie folgt beschreiben:
Hinweis
Diese Grammatik ist nicht normativ**
<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"
Beschreibungsheader und Offsets
Der Beschreibungsheader enthält die Versionsnummer der Zwischenablage und offsets, die angeben, wo der Kontext und das Fragment beginnen und enden. Die Beschreibung ist eine Liste von ASCII-Textschlüsselwörtern, gefolgt von einer Zeichenfolge und getrennt durch einen Doppelpunkt (:).
-
Version
: Versionsnummer der Zwischenablage. Die Startversion istVersion:0.9
. Ab Windows 10 20H2 ist dies jetztVersion:1.0
. -
StartHTML
: Offset (in Bytes) vom Anfang der Zwischenablage bis zum Anfang des Kontexts, oder-1
, wenn kein Kontext vorhanden ist. -
EndHTML
: Offset (in Bytes) vom Anfang der Zwischenablage bis zum Ende des Kontexts oder-1
, wenn kein Kontext vorhanden ist. -
StartFragment
: Offset (in Bytes) vom Anfang der Zwischenablage bis zum Anfang des Fragments. -
EndFragment
: Offset (in Bytes) vom Anfang der Zwischenablage bis zum Ende des Fragments. -
StartSelection
: Optional. Offset (in Bytes) vom Anfang der Zwischenablage bis zum Anfang der Auswahl. -
EndSelection
: Optional. Offset (in Bytes) vom Anfang der Zwischenablage bis zum Ende der Auswahl.
Die StartSelection
Schlüsselwörter und EndSelection
sind optional und müssen weggelassen werden, wenn die Anwendung diese Informationen nicht generieren soll.
Zukünftige Überarbeitungen des CF_HTML
Zwischenablageformats können z. B. den Header erweitern, da der HTML-Code am StartHTML
Offset beginnt und später mehrere StartFragment
Paare EndFragment
hinzugefügt werden können, um die nicht zusammenhängende Auswahl von Fragmenten zu unterstützen.
Offsetsyntax
Zur Vereinfachung der Programme, die die Byteoffsets generieren, können die Offsetwerte optional mit einer beliebigen Anzahl von Nullziffern '0'
aufgefüllt werden. Der Grund dafür ist, dass Programme, die den HTML-Code für die Offsets schnüffeln, für jeden Schlüsselwort (keyword) zehn (10) Nullen in den Ausgabepuffer schreiben könnten (z. B. StartHTML: 0000000000
). Später, wenn der genaue StartHTML
Offset bekannt ist (z. B. 71), kann das Programm die rechtssten Nullen mit "71" im Puffer überschreiben (z. B. ergibt ).StartHTML: 0000000071
Der einzige Zeichensatz, der von der Zwischenablage unterstützt wird, ist Unicode (UTF-8). Da die ersten Zeichen von UTF-8 und ASCII übereinstimmen, ist die Beschreibung immer ASCII, aber die Bytes des Kontexts (beginnend bei StartHTML
) können alle anderen Zeichen verwenden, die in UTF-8 codiert sind.
Die Zeilenenden im Header des Zwischenablageformats (<br>
oben) können durch CRLF (Windows), LF (Unix) oder lone CR (archaisch) dargestellt werden.
Das Fragment, die Auswahl und deren Kontext
Element | Beschreibungsheader | Erfordert gültigen HTML-Code für Start- und Endzeichenpositionen |
---|---|---|
Kontext |
StartHTML und EndHTML |
Ja |
Fragment |
StartFragment und EndFragment |
Ja |
Auswahl |
StartSelection und EndSelection |
Nein |
Kontext
Der Kontext ist ein gültiges, vollständiges HTML-Dokument . Dies bedeutet jedoch nicht, dass das gesamte ursprüngliche HTML-Quelldokument, das die Auswahl des Benutzers enthält, wörtlich übernommen wird; im Gegenteil, es kann ein minimales, aber wohlgeformte HTML-Dokument sein.
Dieser Kontext enthält das Fragment und alle vorangehenden umgebenden Tags (Start- und Endtags; diese vorangehenden umgebenden Tags stellen alle übergeordneten Knoten des Fragments bis zum HTML-Knoten dar. Der obige Beispielartikel enthält ein vollständiges HTML-Element <head>
, das die Verwendung von <base href="">
- und <title>
-Elementen zulässt. Beispielsweise kann dieses Element eingefügt werden, um diese zusätzlichen Informationen zu erhalten. Eine Anwendung, die ein HTML-Fragment in die Zwischenablage kopiert, kann ein <base href="">
Element erstellen, um es in den Kontext einzuschließen, wenn ein solches Element noch nicht vorhanden ist. Auf diese Weise können nicht absolute URIs im HTML-Fragment aufgelöst werden.
Der Kontext ist optional, da ausreichende Informationen in das Fragment für das einfache Einfügen eines HTML-Fragments enthalten sind. Wenn der Kontext nicht gespeichert wird, werden nur das Fragment und der StartHTML=EndHTML=-1
gespeichert.
Fragment
Das Fragment (<fragment-text>
oben) enthält ein gültiges HTML-Fragment.
Ein gültiges HTML-Fragment besteht aus einem einzelnen äußeren HTML-Element. Dieses Element kann nachfolgernde HTML-Elemente enthalten, sofern sie ordnungsgemäß geschachtelt sind. Ein Fragment kann beispielsweise ein einzelnes <div>
Element sein, das drei <p>
Elemente enthält. Ein Fragment, das aus einem <span>
Element besteht, das drei <p>
Elemente enthält, wäre ungültig, da ein <span>
Element (ein Element) keine Elemente auf Blockebene als untergeordnete Elemente enthalten kann.
So stellt das Fragment effektiv den größeren Bereich auf dem Bildschirm dar, den der Benutzer seine Textauswahl vorgenommen hat (z. B. zum Kopieren). Die Auswahl enthält den markierten Text sowie die öffnenden Tags und Attribute eines Elements, das ein Endtag im ausgewählten Text enthält, und Endtags am Ende des Fragments für alle enthaltenen Starttags. Dies sind alle Informationen, die für das einfache Einfügen eines HTML-Fragments erforderlich sind.
Dem Fragment sollten die HTML-Kommentare <!--StartFragment-->
vorangestellt und gefolgt werden, um <!--EndFragment-->
anzugeben, wo das Fragment beginnt und endet. Diese HTML-Kommentare müssen wörtlich verwendet werden, ohne Leerzeichen in jedem Kommentar selbst. Daher werden der Anfang und das Ende des Fragments durch das Vorhandensein dieser Kommentare und durch die StartFragment
Kopfzeilen und EndFragment
angegeben. Von Tools wird erwartet, dass sie diese Informationen erzeugen. Diese Redundanz ist beabsichtigt und wurde eingeführt, um den Anfang des Fragments (aus der Byteanzahl) zu finden und die Position des Fragments direkt in der HTML-Struktur zu markieren.
Auswahl
Die Auswahl ist optional, da ausreichende Informationen für das grundlegende Einfügen in das Fragment enthalten sind. Wenn die Auswahl nicht gespeichert wird, werden sowohl als auch StartSelection
EndSelection
nicht im Header gespeichert.
Falls vorhanden, entspricht die Auswahlgenau dem Textbereich, den der Benutzer (innerhalb des Fragments) ausgewählt hat. Dadurch werden dem Fragment weitere Informationen hinzugefügt, indem der exakt ausgewählte Text ohne die wohlgeformten und ausgeglichenen Start- und Endtags und Endtags angegeben wird.
Denken Sie daran, dass die Auswahl eine Textausführung darstellen kann, die in einem beliebigen Element beginnen und in jedem nachfolgenden - oder vorgängern - Element enden kann. Folglich ist es unmöglich, eine Textauswahl mit HTML darzustellen.
Szenarien
In den folgenden Szenarien wird beschrieben, wie der IE4/MSHTML HTML-Editor HTML-Ausschneiden und Einfügen behandelt. Andere Anwendungen können diesen Szenarien folgen oder nicht. Das hier beschriebene Zwischenablageformat soll flexibilität für die Funktionsweise einer Anwendung ermöglichen. (Diese Szenarien zeigen nur guten HTML-Code an, d. h. keine überlappenden Tags.)
Szenario 1: Einfaches HTML-Fragment
Nehmen Wir den folgenden HTML-Text an:
<body>This is normal. <b>This is bold.</b> <i><b>This is bold italic.</b> This is italic.</i></body>
Dies wird wie folgt angezeigt:
Dies ist normal. Dies ist fett.Dies ist fett kursiv.Dies ist kursiv.
Wenn Ihr Benutzer den oben genannten HTML-Text in eine MSHTML-basierte Anwendung geladen hat (MSHTML, auch Trident genannt, war die Engine von Internet Explorer), verarbeitet MSHTML das Kopieren einer Teilzeichenfolge von HTML wie folgt:
- Der Benutzer wählt einen Text ohne vorangehendes oder nachfolgendes Leerzeichen aus, z. B. "fett, das ist fett kursiv this" aus dem obigen Beispiel.
- Um den Text in die Zwischenablage zu kopieren, klickt der Benutzer auf die Befehlsschaltfläche Kopieren.
MSHTML platziert diesen HTML-Text wie folgt in der Windows-Zwischenablage:
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>
Szenario 2: Fragment einer Tabelle in HTML
Nehmen Sie den folgenden HTML-Text an:
<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>
Dies wird wie folgt angezeigt:
Kopf 1 Element 1 Item 2 Element 3 Punkt 4 Punkt 5 Punkt 6 Punkt 7 Punkt 8 Kopf 2 Punkt 9 Element 10 Element 11 Element 12
Wie MSHTML das Kopieren einer Teilzeichenfolge von HTML aus einer Tabelle behandelt
Wenn der Benutzer die Maus verwendet, um eine Textauswahl vorzunehmen, die die Tabellenzellen Element 6, Element 7, Element 10 und Element 11 abdeckt. Diese Auswahl wird dann in die Zwischenablage kopiert.
Was folgt, ist, was sich in der Zwischenablage befindet (beachten Sie, dass dies die Interpretation von IE4/MSHTML ist). Zur Übersichtlichkeit wurden Zeilenumbrüche hinzugefügt.
<!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>
Die Auswahl, als durch und EndSelection
getrenntStartSelection
, wird fett dargestellt.
Szenario 3: Einfügen eines Fragments einer sortierten Liste <ol>
in Nur-Text
Nehmen Sie den folgenden HTML-Text an:
<BODY><OL TYPE="a"><LI>Item 1<LI>Item 2<LI>Item 3<LI>Item 4<LI>Item 5<LI>Item 6</OL></BODY>
Dies wird wie folgt angezeigt:
- Element 1
- Item 2
- Element 3
- Punkt 4
- Punkt 5
- Punkt 6
Wie MSHTML das Kopieren einer Teilzeichenfolge von HTML-nummerierten Listenelementen verarbeitet
- Der Benutzer nimmt eine Textauswahl vom Anfang von Element 3 über Element 4 bis zum Ende von Element 5 vor. Der Benutzer ruft den Befehl Kopieren auf.
- Der folgende HTML-Code befindet sich in der Zwischenablage (zur Übersichtlichkeit hinzugefügte Zeilenumbrüche) – die genaue Position der
<!--Star/EndFragment -->
Kommentare hängt davon ab, wie der Benutzer die Textauswahllogik seines Browsers verarbeitet hat:
<html>
<body>
<ol>
<!-- StartFragment-->
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<!-- EndFragment-->
</ol>
</body>
</html>
Wenn dieses Fragment nun in ein leeres Dokument eingefügt werden soll, wird der folgende HTML-Code erstellt:
<body>
<ol>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ol>
</body>
Dies wird wie folgt angezeigt:
- Element 3
- Punkt 4
- Punkt 5
Szenario 5: Einfügen einer teilweise ausgewählten Region
Nehmen Sie den folgenden HTML-Text an:
<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>
Dies wird wie folgt angezeigt:
IE4/MSHTML ist ein WYSIWYG-Editor, der Folgendes unterstützt:
- Ausschneiden
- Kopieren
- Einfügen
Dies ist ein großartiges Tool!
Vorgehensweise beim Kopieren einer Teilzeichenfolge von HTML-Listenelementen in MSHTML
Der Benutzer verwendet seine Maus, um eine Textauswahl zu ziehen, z. B. "WYSIWYG-Editor, der unterstützt: Cut Cop". Als wäre es Nur-Text, würde diese Auswahl wie dieses fehlerhafte HTML-Fragment aussehen:
WYSIWYG Editor, which supports:</p>
<ul>
<li>Cut</li>
<li>Cop
Wenn der Benutzer die Befehlsschaltfläche Kopieren drückt, sieht die Zwischenablage wie folgt aus (Zeilenumbrüche wurden zur Übersichtlichkeit hinzugefügt; der fett formatierte Text gibt an, was der Benutzer tatsächlich ausgewählt hat):
<html> <body> <!-- StartFragment--> <p>WYSIWYG Editor, which supports</p> <ul> <li>Cut</li> <li>Cop</li> </ul> <!-- EndFragment--> </body> </html>
Beachten Sie, Folgendes:
- Der Text vor "WYSIWYG" wurde entfernt.
- Das Listenelement (
<li>Paste</li>
) wurde entfernt, da es sich nicht in der Auswahl des Benutzers befand. - Das "y" aus "Kopieren" wurde entfernt.