FluentUI: Editoren und Code-Darstellung
Zurück: FluentUI (Design-System-Bibliothek)
Fünf verschiedene Editor- und Code-Bausteine, und die Frage, welcher wofür gedacht ist – mit dem Verweis auf die jeweilige Quelle der Wahrheit.
1. Übersicht und Zweck
Status: gemischt – fünf Bausteine [Live] (je eigener Träger,
darunter codeEditor() und htmlSplitEditor()) plus die Editor-/Markup-Umschaltung
(WYSIWYG-Umschaltung, bewusst außerhalb dieser Seite geführt – Träger
wvdsmd), je Abschnitt vermerkt.
Diese Seite ordnet fünf verschiedene Editor-/Code-Darstellungs-Bausteine ein und verlinkt die jeweilige Quelle der Wahrheit – sie ersetzt keine Plugin-Doku. Zielgruppe: jeder Entwickler, der entscheiden muss, welcher Baustein für „Code zeigen“ vs. „Code bearbeiten“ vs. „Wiki-Inhalt bearbeiten“ der richtige ist (Abschnitt 5).
2. Voraussetzungen
- Für
codeEditor()undhtmlSplitEditor(): DokuWiki mit aktiviertem Pluginwkfluentuiundhelper_plugin_wkfluentui_widgetsgeladen. - Für GeSHi: keine – Core-Funktion, immer verfügbar.
- Für den Markdown-Editor: Plugin
wvdsmdaktiviert, Seite trägt den Markdown-Marker (Autodetect).
3. Konzepte
Gemeinsames Muster aller fünf Bausteine: progressive Erweiterung über einer funktionsfähigen Textarea – dieselbe Konvention wie bei den JS-Erweiterungen der Helper-API (kein zweiter Code-Pfad, Markup bleibt das Speicherformat).
| Baustein | Was es ist | Verwendung | Träger / Quelle der Wahrheit | Status |
|---|---|---|---|---|
| GeSHi (Code-Rendering) | Syntax-Highlighting beim Rendern – kein Editor, keine eigene API | <code sql>…</code>/<file> im Wiki-Text und Fenced-Code-Blöcke (```lang) in Markdown-Embeds ({{md>…}} / <markdown>); Sprachkennung = GeSHi-Sprachname | DokuWiki-Core (inc/parser/xhtml.php → vendored GeSHi); Optik über --wk-wiki-code-*-Tokens | umgesetzt (Core) |
| Quellcode-Editor | CodeMirror, progressiv über einer normalen <textarea> – ohne JavaScript bleibt die Textarea voll funktionsfähig | jedes Admin-Modul über codeEditor() (Erstkonsument: SQL-Workbench in wksqliteds) | gemeinsame Kopie unter wkfluentui/cm/ + Widget codeEditor() (Vertrag: Abschnitt 6/7 unten) | umgesetzt |
| Geteilter HTML-Editor | Quelltext und bearbeitbare gerenderte Vorschau nebeneinander; die Quelle bleibt maßgeblich, die Vorschau schreibt neu formatiert zurück | Admin-Flächen, die HTML-Fragmente pflegen (Erstkonsument: Snippet-Verwaltung in wksnippet) | Widget htmlSplitEditor() + scripts/htmlsplit.js, Vorschau in einem Sandbox-iframe (Vertrag: Abschnitt 8/9 unten) | umgesetzt |
| DokuWiki-Standard-Editor | Cores Seiten-Editor: Toolbar (Fett/Link/…) + Textarea + Vorschau, Draft-/Lock-Fluss | jede Wiki-Seite, do=edit | DokuWiki-Core | umgesetzt (Core) |
| Markdown-Editor | vendored EasyMDE ersetzt die Textarea auf Markdown-Seiten; Marker-Zeile unsichtbar, DokuWiki-Save/Draft-Fluss unverändert; No-JS-Fallback = Textarea | Seiten mit Markdown-Marker (Autodetect) | Plugin wvdsmd – Quelle der Wahrheit: Markdown (wvdsmd) | umgesetzt |
4. Erste Schritte
Minimalbeispiel: CodeMirror-Editor über eine bestehende SQL-Textarea aktivieren.
/** @var helper_plugin_wkfluentui_widgets $widgets */
$widgets = plugin_load('helper', 'wkfluentui_widgets');
?>
<textarea id="sql-input" name="sql"></textarea>
<?php echo $widgets->codeEditor('sql-input', 'sql'); ?>
Falsch: codeEditor() auf eine Textarea zeigen lassen, die zum
Zeitpunkt des Aufrufs noch nicht im DOM steht (z. B. Aufruf vor dem
<textarea>-Tag). Das Aktivierungs-Markup verweist per id auf ein
Element, das existieren muss – die Reihenfolge im Beispiel oben (Textarea
zuerst) ist verbindlich.
5. Verwendung: Leitfaden „welcher Baustein wofür“
| Bedarf | Baustein |
|---|---|
| Code im Inhalt zeigen | <code lang> (GeSHi) – nie einen Editor einbetten |
| Code/SQL im Admin-Modul bearbeiten | codeEditor() (ein Aufruf neben der Textarea, kein plugin-lokales Vendoring nötig) |
| HTML-Fragment mit Sichtprüfung bearbeiten | htmlSplitEditor() (umschließt dieselbe Textarea; enthält codeEditor() für die Quellseite) |
| HTML-Feld eines Formulars als formatierten Text schreiben (Beschreibung, Kommentar) | htmlSplitEditor() mit 'variant' => 'field' – siehe Feld-Variante |
| Wiki-Inhalt bearbeiten | Core-Editor; Markdown-Seiten automatisch via wvdsmd |
| Kein Nachbau von Monaco/VS-Code-Editoren | bewusste Grenze wie bei der Layout-Mechanik (layout) |
6. API-Referenz: codeEditor()
| Metadatum | Wert |
|---|---|
| Sprache | PHP |
| Namespace | helper_plugin_wkfluentui_widgets |
| Datei | lib/plugins/wkfluentui/helper/widgets.php |
| Sichtbarkeit | public |
| Stabilität | stabil (Stufe 1) |
public function codeEditor(string $textareaId, string $language, array $opts = []): string
Zusammenfassung: Liefert das <script>-freie
Aktivierungs-Markup (data-wk-code-editor-Attribute) für eine
bestehende, benannte Textarea; scripts/codeeditor.js (progressive
Erweiterung) ersetzt sie beim Laden durch eine CodeMirror-Instanz.
Rückgabewert: string – Aktivierungs-Markup. Leerer String bei
unbekannter $language-Kennung oder leerer $textareaId – die Textarea
bleibt in beiden Fällen unangetastet eine gewöhnliche Textarea, kein Fehler.
7. Parameter, Optionen und Zustände
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
$textareaId | string | Ja | id der bestehenden Ziel-Textarea |
$language | string | Ja | eine von sql|php|css|javascript|markdown|html; jede andere Kennung liefert den leeren String |
$opts['submitId'] | string | Nein | id des Submit-Buttons, den Strg+Enter klickt – der Editor synchronisiert vorher in die Textarea |
Instanz-Zugriff (Client): wkCodeEditor.get(textareaId) – null,
solange/falls CodeMirror nicht geladen hat; zur Klick-Zeit auflösen, nicht
beim Seitenaufbau. Event wk-codeeditor-ready feuert zusätzlich an der
Textarea.
Lazy-Load: Vendor-Assets laden nur auf Seiten mit mindestens einem Aktivierungs-Marker nach – kein site-weiter Payload-Anstieg.
Vendoring (begründete Spez-Korrektur): die gemeinsame CodeMirror-Kopie
(5.65.16 + Modi sql/php/css/javascript/markdown/htmlmixed samt Abhängigkeiten
clike/xml/htmlmixed, MIT-Lizenzdatei) liegt unter wkfluentui/cm/ –
nicht im ursprünglich skizzierten vendor/cm/, weil DokuWikis
Web-Schicht direkten Zugriff auf vendor/-Verzeichnisse verweigert (auf
dieser Instanz empirisch verifiziert, 404).
Fehlerverhalten:
| Bedingung | Verhalten |
|---|---|
unbekannte $language-Kennung | Rückgabe leerer String, Textarea bleibt unangetastet |
leere $textareaId | Rückgabe leerer String |
| Ziel-Textarea existiert nicht im DOM | kein PHP-Fehler (das Widget prüft das DOM nicht); scripts/codeeditor.js findet beim Laden kein Ziel und aktiviert nichts – stille clientseitige Degradation |
8. API-Referenz: htmlSplitEditor()
| Metadatum | Wert |
|---|---|
| Sprache | PHP |
| Namespace | helper_plugin_wkfluentui_widgets |
| Datei | lib/plugins/wkfluentui/helper/widgets.php |
| Träger der Interaktion | lib/plugins/wkfluentui/scripts/htmlsplit.js |
| Sichtbarkeit | public |
| Stabilität | stabil (Stufe 1) |
public function htmlSplitEditor(string $textareaHtml, string $textareaId, array $opts = []): string
Zusammenfassung: Umschließt die fertige, vom Aufrufer erzeugte
Textarea mit einem geteilten Editor: links der Quelltext (CodeMirror,
Sprache html – derselbe Baustein wie in Abschnitt 6), rechts die
gerenderte Vorschau. Die Vorschau ist bearbeitbar; was dort geändert wird,
landet neu formatiert in der Quelle.
Warum der Aufrufer die Textarea behält: Diese Bibliothek hat bewusst kein nacktes Textarea-Widget – Name, Größe, Pflichtfeld-Status und Label eines Formularfelds gehören zum Bildschirm, nicht zum Entwurfssystem. Das Widget bekommt deshalb fertiges, vom Aufrufer escaptes Markup und legt nur die Umgebung darum. Folge: der abgeschickte POST ist mit und ohne diesen Baustein identisch.
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
$textareaHtml | string | Ja | vollständiges <textarea …>-Markup des Aufrufers, von diesem escapt |
$textareaId | string | Ja | deren id; leer ⇒ $textareaHtml wird unverändert zurückgegeben |
$opts['mode'] | string | Nein | Startansicht source|split|preview (Standard split); eine zuvor gespeicherte Benutzeransicht gewinnt |
$opts['editable'] | bool | Nein | false ⇒ Vorschau nur lesbar, Formatiergruppe entfällt vollständig (Standard true) |
$opts['storageKey'] | string | Nein | Namensraum der gespeicherten Ansicht (wk-htmlsplit:<storageKey> in localStorage); leer ⇒ Ansicht wird nicht gemerkt |
$opts['submitId'] | string | Nein | id des Speichern-Knopfs – an codeEditor() weitergegeben, also Strg+Enter |
$opts['lang'] | string | Nein | Inhaltssprache der Vorschau (Standard $conf['lang']) |
$opts['variant'] | string | Nein | field ⇒ Feld-Variante (unten); mode, editable und storageKey werden dann nicht gelesen. Ohne die Option ist die Ausgabe der geteilte Editor, unverändert |
$opts['label'] | string | nur Feld | zugänglicher Name der Eingabefläche – in der formatierten Ansicht ist die Beschriftung der Textarea nicht sichtbar |
$opts['rows'] | int | Nein | nur Feld: Mindesthöhe in Zeilen (Standard 6, mindestens 2) |
Ohne JavaScript: die Werkzeugleiste trägt serverseitig hidden (ihre
Ansichts- und Formatierknöpfe wären sonst tote Bedienelemente), die
Vorschaufläche ist leer und hidden. Übrig bleibt genau die Textarea des
Aufrufers. Alle Knöpfe des Bausteins sind type=„button“, und das
Adressfeld der Verknüpfung trägt kein name – es kann also nichts
mitgeschickt werden.
Vorschau als Sandbox-iframe: sandbox=„allow-same-origin“, ohne
allow-scripts (beide zusammen sind die dokumentierte
Sandbox-Ausnahme und damit keine Absicherung). Das ist notwendig, weil
gepflegte HTML-Fragmente <style> und <script> enthalten
dürfen: inline gerendert würde ein <style> die Admin-Seite ringsum
umstylen. Verifiziert auf dieser Instanz – das <script> eines
Fragments läuft weder im Rahmen noch im Elterndokument, sein
<style> wirkt innerhalb des Rahmens und die Admin-Seite bleibt
messbar unverändert. Die Stylesheets der Wirtsseite werden in das
Vorschaudokument kopiert, damit die Vorschau die echte Kaskade zeigt und
nicht eine handgepflegte Näherung.
Platzhalter-Chips: Plugin-Platzhalter ({{wk:lang>…}},
{{wk:image>…}}) sind kein HTML. In der Vorschau werden sie zu je
einem unteilbaren, nicht bearbeitbaren Chip, der das Token wörtlich
trägt und wörtlich zurückgeschrieben wird – sonst zerlegt ein einzelner
Tastendruck ein Token, oder die Textkodierung macht aus dem < in
{{wk:lang>de:< 24 Stunden}} ein <, womit das Muster des
konsumierenden Plugins nicht mehr passt. Die Chips entstehen aus dem
Quelltext, nicht aus dem geparsten Baum: nur dort existieren die
Rohbytes noch, nur dort ist ein Platzhalter, der selbst Markup enthält
(…Industrie-<br/>erfahrung…), ein zusammenhängendes Token, und nur
dort ist Text- von Attributposition unterscheidbar. Platzhalter in
Attributwerten bleiben unangetastet.
Speicherweg: Die Textarea ist und bleibt das Formularfeld. Eine
Vorschau-Änderung, die beim Klick auf Speichern noch in ihrer
Entprellzeit steckt, wird in der Capture-Phase am document
nachgezogen – vor dem Übertrag von CodeMirror in die Textarea, der am
Formular selbst hängt. Ohne diese Reihenfolge gehen die letzten
Tastendrücke der Vorschau beim Speichern verloren, und zwar stumm.
Erstkonsument: Snippet-Verwaltung (wksnippet,
do=admin&page=wksnippet&edit=<key>).
Feld-Variante
Ein HTML-Feld eines Formulars ist kein HTML-Fragment: sein Markup ist Speicherformat, nicht Gegenstand der Arbeit. Beschreibung, Nachstellschritte und Kommentar eines Arbeitselements sind in Azure DevOps solche Felder und werden dort als formatierter Text bearbeitet. 'variant' => 'field' liefert dafür dieselbe Maschine mit anderem Gesicht.
$ta = $widgets->textArea([ 'name' => 'System.Description', 'id' => 'wk-wi-desc', 'value' => $html, 'rows' => 10, 'ariaLabel' => 'Beschreibung', 'bare' => true, ]); echo $widgets->htmlSplitEditor($ta, 'wk-wi-desc', [ 'variant' => 'field', 'label' => 'Beschreibung', 'rows' => 10, ]);
| Gleich wie der geteilte Editor | Anders |
|---|---|
| Die Textarea bleibt das Formularfeld; ein unberührtes Feld schickt seinen Wert Byte für Byte zurück, auch nach Umschalten auf HTML und zurück | formatierter Text als Vorgabe, der Quelltext ist ein Umschalter (HTML); keine geteilte Ansicht |
| Vorschau im Sandbox-iframe ohne Skripte | Höhe folgt dem Inhalt zwischen rows Zeilen und 60 % des Fensters, die ganze Fläche ist Eingabe |
| ausstehende Eingabe wird beim Absenden übernommen | Schrift aus der Umgebung des Bausteins (im Formular 13/18), nicht die Lesegröße der Seite |
kein Bedienelement trägt ein name | eine Leiste: Fett, Kursiv, Unterstrichen, Code, Aufzählung, Nummerierung, Link, Formatierung entfernen, HTML; Strg+B/I/U, Strg+K |
Link-Adresse erscheint erst auf Befehl (Escape schließt sie) |
|
keine Platzhalter-Chips ({{ ist in einem Feld Text), kein Hinweis zur maßgeblichen Quelle, keine Schreibmeldung |
Pflichtfeld und Platzhalter. Trägt die Textarea required, nimmt das Skript es ab und prüft selbst beim Absenden – leer ist auch, was ein geleertes Feld hinterlässt (<p><br></p>, ): anhalten, aria-invalid, Rahmen in der Fehlerfarbe, Meldung in der Statuszeile, Fokus ins Feld. Grund: in der formatierten Ansicht ist die Textarea verborgen, und ein verborgenes Pflichtfeld verweigert der Browser nur in der Konsole („an invalid form control is not focusable“) – der Knopf täte scheinbar nichts. Ohne Skript bleibt required an der Textarea. Ein placeholder der Textarea erscheint auch in der formatierten Fläche.
Barrierefreiheit. Die Fläche ist role=„textbox“ mit aria-multiline, Name aus label, aria-required/aria-placeholder nach der Textarea; die Befehle tragen aria-keyshortcuts.
Zwei Browser-Eigenheiten, gemessen:
- Inline-Code gibt es nicht als Editorbefehl, und der naheliegende Ersatz scheitert: Chrome macht aus einem per
insertHTMLeingefügten<code>ein<span style="font-family: …">. Das Element wird deshalb über den Range gesetzt; dieser eine Schritt liegt nicht auf dem Rückgängig-Stapel. - Alles markieren, löschen, tippen übernahm die Formatierung des gelöschten Anfangs als Tippstil – nach Code als
<font face="Consolas…">. Eine leer gelöschte Fläche beginnt deshalb mit einem leeren Absatz und frischer Einfügemarke.
Absicherung beim Verbraucher. Die Feld-Variante ist jünger als der Baustein. Ein älterer Bausatz ignoriert die Option und zeichnet den geteilten Editor. Ein Verbraucher nimmt die Antwort deshalb nur, wenn sie data-wk-hs-variant="field" trägt, und zeichnet sonst seine Textarea (so wkdoadowi).
Erstverbraucher: Arbeitselement-Ansicht (wkdoadowi): Beschreibung, Nachstellschritte, Kommentar. Nicht enthalten: Bilder einfügen (ADO lädt sie als Anhang hoch).
9. Rundlauf: was eine Vorschau-Bearbeitung an der Quelle ändert
Eine Bearbeitung in der Vorschau bedeutet, dass der Browser das Markup neu serialisiert. Das ist verlustbehaftet und deshalb hier beziffert statt beschwiegen. Wer nur links im Quelltext arbeitet, löst nichts davon aus.
Gemessen über alle 55 Snippet-Dateien dieser Instanz (Quelle → Vorschau → Bearbeitung → Quelle):
| Ergebnis | Dateien |
|---|---|
| Dokument parst gleich (Elemente, Attribute, Text) | 55 / 55 |
| Platzhalter byteweise identisch (430 Stück) | 55 / 55 |
<script>-/<style>-Inhalte byteweise identisch | 55 / 55 |
| Datei als Ganzes byteweise identisch | 28 / 55 |
| Unterschied ausschließlich in der Einrückung | 23 / 55 |
| Unterschied darüber hinaus | 4 / 55 |
Die vier Abweichungen sind darstellungsneutral: Zeichenreferenzen für
druckbare Zeichen werden zum Zeichen selbst (✓ → Häkchen,
» → Guillemet), und der Schrägstrich eines leeren Elements
entfällt (<br/> → <br>).
Rücknahme: Das Zurückschreiben ist eine CodeMirror-Änderung – ein
einzelnes Strg+Z im Quelltextfeld nimmt die komplette Neuformatierung
zurück. Die Werkzeugleiste sagt das auch dort, wo es passiert.
Einrückung: vier Leerzeichen, und ein Element, dessen Kinder alle inline
sind, bleibt einzeilig, solange die Zeile 110 Zeichen nicht überschreitet.
Inhalte von <script>, <style>, <pre> und
<textarea> werden nie umgebrochen oder neu eingerückt – dort
ändert Einrücken die Bedeutung, nicht das Aussehen.
10. Vollständige Beispiele: Editor ↔ Markup-Umschaltung [Live]
Träger wvdsmd (Vollausbau 2026-07-14) –
Quelle: lib/plugins/wvdsmd/script.js.
Auf Markdown-Seiten trägt die EasyMDE-Toolbar einen Umschalter zwischen
Editor-Ansicht (EasyMDE mit Format-Toolbar und Vorschau) und
Markup-Ansicht (die rohe Textarea inklusive sichtbarer Marker-Zeile –
identisch zum No-JS-Zustand). Der Wechsel ist jederzeit in beide
Richtungen möglich und wirkt sofort, ohne Speichern; die zuletzt gewählte
Ansicht wird pro Benutzer gemerkt (localStorage,
wk-editor-view:<login>); jeder Wechsel wird über eine
aria-live-Region angesagt. Eigenschaften:
- Markup bleibt Speicherformat (Markdown) – beide Ansichten editieren dieselbe zugrunde liegende Textarea, es gibt keine Rückserialisierung und damit konstruktionsbedingt verlustfreie Wechsel (byte-gleicher Quelltext, im Verifikationslauf nachgewiesen).
- No-JS-Fallback bleibt die rohe Textarea; der Umschalter existiert nur in der JS-erweiterten Ansicht.
- DokuWiki-Syntax-Seiten behalten den Core-Editor mit seiner Syntax-Toolbar und dem „Vorschau“-Button – dort gibt es nur eine Bearbeitungsansicht, ein Umschalter wäre bedeutungslos.
Vertiefung – konkrete Toolbar-Befehle: zwei Unterseiten dokumentieren, welche DokuWiki-Syntax/Markdown-Tokens die Editor-Toolbars einfügen (EasyMDE für Markdown, Core-Toolbar für DokuWiki-Syntax), nach dem Kategorienschema der DevExpress-ASPxHtmlEditor-Demo-Suite (https://demos.devexpress.com/ASPxHTMLEditorDemos/Default.aspx), aber auf das tatsächliche Ziel-Format dieser Bibliothek übertragen statt generischer HTML-Tags:
- Formatierung – Zeichen-/Absatzformate als Syntax-Tokens
- Tabellen und Medien – Tabellen-, Medien- und Link-Syntax
11. Einschränkungen und Randfälle
- GeSHi bestimmt die Sprachliste; unbekannte Kennungen rendern als Klartext (kein Fehler). In Markdown-Embeds gilt dasselbe:
wvdsdwmdsParsedownRendererhebt Fenced-Blöcke mit bekannter Sprachkennung über DokuWikis GeSHi-Pfad hervor (p_xhtml_cached_geshi()); Blöcke ohne/mit unbekannter Kennung bleiben Parsedown-Roh-<pre>– degradiert, nie verloren. Engine-Kennungparsedown-1.7.4-geshi1invalidiert Alt-Caches. - CodeMirror/EasyMDE sind vendored (offline, keine CDN-Abhängigkeit) – Updates sind bewusste, versionierte Plugin-Änderungen.
- Editor-Flächen liegen im Content-Panel und folgen dem Panel-Füll-Rezept aus datagrid (Zutaten 1–3 gelten identisch für Editoren).
- Kein Nachbau von Monaco/VS-Code-Editoren (Abschnitt 5).
12. Accessibility und Kompatibilität
- Vollständiger Überblick: Accessibility (konsolidiert, nicht hier dupliziert).
- Ohne JavaScript bleibt jeder Baustein eine gewöhnliche, vollständig zugängliche Textarea.
- CodeMirror/EasyMDE sind vendored – Browserkompatibilität folgt den jeweiligen Vendor-Release-Notes (nicht separat in dieser Bibliothek getestet).
13. Troubleshooting
Symptom: codeEditor() rendert nichts (leerer String), obwohl
Textarea und Sprache korrekt aussehen.
Ursache: $language enthält eine Kennung außerhalb von
sql/php/css/javascript/markdown/html (Groß-/Kleinschreibung
beachten – die Prüfung ist exakt, keine Normalisierung).
Lösung: Kennung gegen die exakte Liste in Abschnitt 7 prüfen.
Symptom: Markdown-Fenced-Code-Block wird nicht hervorgehoben.
Ursache: unbekannte oder fehlende Sprachkennung nach den drei Backticks, oder der Cache trägt noch die alte Engine-Kennung.
Lösung: Sprachkennung gegen GeSHis Liste prüfen; bei Verdacht auf
veralteten Cache: Engine-Kennung parsedown-1.7.4-geshi1 erzwingt
Invalidierung.
Symptom: Beim geteilten HTML-Editor fehlt die Werkzeugleiste, oder die Vorschau bleibt leer, obwohl das Markup im Quelltext steht.
Ursache: Der ausgelieferte Skript-Bund ist veraltet.
lib/exe/js.php bündelt die Dateien aus scripts/ über
/* DOKUWIKI:include */ und stützt seinen Zwischenspeicher nicht auf
deren Änderungszeit – eine Änderung an scripts/htmlsplit.js allein
erneuert den Bund also nicht, und der Browser hält zusätzlich seine eigene
Kopie unter unveränderter tseed-Kennung.
Lösung: script.js des Plugins anfassen (touch) und im Browser
hart neu laden (Strg+Umschalt+R). Gilt für jede Änderung an einer
eingebundenen Skriptdatei, nicht nur für diesen Baustein.
14. Verwandte Themen
- DW-Editor: Formatierung · DW-Editor: Tabellen und Medien – Vertiefung der Formatierungs-Toolbar
- DW-Editor: Adaptivity · DW-Editor: Accessibility – Adaptivity/Accessibility
- Markdown (wvdsmd) – Markdown-Authoring (Marker, EasyMDE, Import/Export)
- SQLite Data Studio: Admin-Oberfläche – SQL-Workbench (CodeMirror-Konsument)
- FluentUI: Desktop-DataGrid – Demo-Übersicht · FluentUI: Admin-Bereich (vertieft) – Panels, in denen Editoren leben
- FluentUI: Öffentliche Helper-API – Konvention „progressive Erweiterung“