`white-space` CSS-Eigenschaft von Clipboard-Daten wird beim Einfügen in Rich-Text-Editor nicht beachtet

Priorität/Schweregrad:

Mittel

Plattform:

Betriebssystem

  • Windows 11

Browser

  • Google Chrome 139.0.7258.128

Discourse

028c90dd5e7a2799ea5b6e963f71fc0222681943

Beschreibung:

Text, der aus einigen Quellen kopiert wird, kann zusätzlich zu reinem Text (text/plain) auch in formatierter Form (text/html) in die Zwischenablage gelangen.

Wenn Text in den Composer eingefügt wird, wird, falls ein formatiert datentyp in der Zwischenablage vorhanden ist, diese Datenart anstelle des reinen Texttyps verwendet.

Standardmäßig werden Leerzeichen in HTML-Inhalten reduziert. Dieses Verhalten kann über die CSS-Eigenschaft white-space gesteuert werden.

:bug: Beim Einfügen im Composer im Modus „Rich-Text-Editor“ wird die CSS-Eigenschaft white-space der Daten in der Zwischenablage nicht beachtet. Dies führt dazu, dass Leerzeichen im eingefügten Inhalt immer reduziert werden. In Fällen, in denen der Quellinhalt die white-space-Eigenschaft auf den Wert pre gesetzt hatte, ist der eingefügte Inhalt schwer zu lesen und in Fällen, in denen die Leerzeichen des Quellinhalts technische Bedeutung hatten, falsch.

Reproduzierbare Schritte:

  1. Erstellen Sie eine HTML-Datei mit folgendem Inhalt:
    <html>
      <body>
        <span style="white-space: pre">foo
    bar
        </span>
      </body>
    </html>
    
  2. Öffnen Sie die Datei in Ihrem Webbrowser.
    Beachten Sie, dass die Leerzeichen des Seiteninhalts nicht reduziert werden:
    foo
    bar
    
  3. Kopieren Sie den Inhalt der Webseite.
  4. Öffnen Sie den Beitrags-Composer.
  5. Versetzen Sie den Composer in den Modus „Rich-Text-Editor“.
  6. Fügen Sie den kopierten Inhalt ein.

:bug: Anstatt das gleiche Format wie der kopierte Inhalt zu haben, wurden die Leerzeichen des eingefügten Inhalts reduziert:

foo bar

Zusätzlicher Kontext:

Ich sehe, dass ProseMirror white-space: pre unterstützt:


Der Fehler tritt nicht auf, wenn der Composer im Modus „Markdown-Editor“ verwendet wird.


Der Fehler tritt nicht auf, wenn der Inhalt anstelle des normalen Editor-Modus in einen Codeblock eingefügt wird. Zwar wäre es in vielen Fällen am besten, Inhalte, die etwas wie white-space: pre verwenden, in einen Codeblock zu setzen. Es ist jedoch ziemlich üblich, dass Benutzer Formatierungen nachträglich anwenden, indem sie den Inhalt in den Composer einfügen, den Inhalt auswählen und dann die Werkzeugleiste des Composers verwenden, um die Formatierung anzuwenden (im Gegensatz zum alternativen Ansatz, einen Codeblock auszulösen, bevor der Inhalt hinzugefügt wird).


Ich fand dieses Werkzeug nützlich, um die Rohdaten des Inhalts der Zwischenablage zu untersuchen:


Ich kann den Fehler auf try.discourse.org im „Sicherheitsmodus“ reproduzieren.

Verwandt

2 „Gefällt mir“

Haben Sie den Beitragseditor in den Modus „Rich-Text-Editor“ versetzt, bevor Sie den von der Webseite kopierten Inhalt eingefügt haben?

Der Fehler tritt immer noch auf.

Sind Sie sicher, dass Sie die Anweisungen genau wie geschrieben befolgt haben?

Bitte beachten Sie, dass Sie den Inhalt kopieren müssen, der aus diesem HTML gerendert wird, damit der Inhalt der Zwischenablage mit Daten vom Typ text/html gefüllt wird:

<html>
<body>
<!--StartFragment--><span>foo
bar
    </span><!--EndFragment-->
</body>
</html>

Hierbei geht es nicht darum, Ihren Beitrag mit HTML-Markup zu verfassen.

Gut bemerkt. Ich neige dazu, den Beitrag etwas zu schnell zu überfliegen :sweat_smile:

1 „Gefällt mir“

Danke für die Meldung @per1234, wir schauen uns das an.

Wir verstehen das allgemeine Problem hier, wir wollen es den Leuten so einfach wie möglich machen, Codebeispiele einzufügen.

2 „Gefällt mir“

Was würdest du von einer solchen HTML-Zwischenablage erwarten?

foo
bar

Oder, wenn man bedenkt, dass es sich um ein span-Tag handelt, zwei Inline-Codezeilen mit einem harten Umbruch dazwischen?

foo
bar

Oder einfach, dass wir die Zeilenumbrüche respektieren, aber in einem normalen Absatz, mit einem harten Umbruch dazwischen?

foo
bar

Danke!

Ich bin in der Materie HTML nicht sehr bewandert, aber ich würde dies erwarten:

Soweit ich das beurteilen kann, rendert der Chrome-Browser dies so.


Das gesagt, in der spezifischen Verwendung, in der ich das Problem angetroffen habe, wäre die Codeblock-Darstellung tatsächlich am besten geeignet. Wir erhalten diese Art von Zwischenablageinhalt, indem wir auf die Schaltfläche „Konsolenausgabe kopieren“ in einer Online-IDE namens „Arduino Cloud Editor“ klicken:

Dies kopiert die vom Compiler und anderen Tools erzeugte Ausgabe in die Zwischenablage. Diese Art von Nicht-Prosa-Inhalt wird am besten als Codeblock formatiert.

Wenn das folgende Verfahren verwendet wird, um diese kopierte Ausgabe in einem Forenbeitrag zu teilen:

  1. Versetzen Sie den Beitragseditor in den Modus „Rich-Text-Editor“.
  2. Fügen Sie den Inhalt in den Editor ein.
  3. Wählen Sie den eingefügten Inhalt aus.
  4. Klicken Sie auf das Symbol </> in der Symbolleiste des Editors.

Der Beitrag endet mit der folgenden Formatierung:

/run/arduino/sketches/asdf/asdf.ino:1:2: error: #error foo  #error foo   ^~~~~

(beachten Sie, dass der gesamte kopierte Inhalt in einer einzigen Zeile steht)

während wir diese Beitragsformatierung erwarten würden:

/run/arduino/sketches/asdf/asdf.ino:1:2: error: #error foo
 #error foo
  ^~~~~

Diese Präferenz für einen Codeblock ist jedoch spezifisch für unseren besonderen Anwendungsfall. Es mag sein, dass es in anderen Anwendungsfällen Quellen für Zwischenablageinhalte mit der Eigenschaft white-space: pre gibt, für die ein Codeblock nicht geeignet wäre. Und selbst für unseren Anwendungsfall ist es vernünftig, die Verantwortung für die manuelle Anwendung der Codeblockformatierung dem Benutzer zu überlassen.

1 „Gefällt mir“

[quote=“per1234, post:8, topic:379035”]Der Beitrag endet mit der folgenden Formatierung:


[/quote]

Nicht mehr, das wurde kürzlich behoben (Sie können es hier testen).

[quote=“per1234, post:8, topic:379035”]

[/quote]

In diesem Fall wird immer noch ein span-Tag in der text/html-Zwischenablageausgabe verwendet, oder wird nur plain/text ausgegeben?

Wenn ich das Tool "Clipboard Inspector" verwende, um zu überprüfen, welche Daten sich in meiner Zwischenablage befinden, nachdem ich auf die Schaltfläche „Copy Console Output“ im Arduino Cloud Editor geklickt habe, zeigt es die folgenden Daten vom Typ „text/plain“ an:

/run/arduino/sketches/asdf/asdf.ino:1:2: error: #error foo
 #error foo
  ^~~~~

und die folgenden Daten vom Typ „text/html“:

<span style="color: rgb(0, 0, 0); font-family: &quot;Open Sans&quot;, &quot;Lucida Grande&quot;, lucida, verdana, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.16px; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: pre; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">/run/arduino/sketches/asdf/asdf.ino:1:2: error: #error foo
 #error foo
  ^~~~~</span>

Ich hoffe, das beantwortet Ihre Frage. Gerne gebe ich weitere Informationen, falls erforderlich.

Dies sollte durch FIX: [rich editor] convert newlines to hard breaks when parsed from HTML by renato · Pull Request #35518 · discourse/discourse · GitHub behoben werden (noch nicht zusammengeführt, wartet noch auf eine Code-Überprüfung).

Mein erster Versuch war, es in einen Code-Block umzuwandeln, aber ich denke, das wäre zu voreilig und würde einige Fehlalarme verursachen. Stattdessen respektieren wir einfach Zeilenumbrüche und wandeln sie im Kontext, in den die HTML-Datei eingefügt wurde, in harte Umbrüche um. (Dank Marijns Verbesserung von prosemirror-model: When preserving whitespace, replace newlines with line break replacem… · ProseMirror/prosemirror-model@79e9f2b · GitHub)

Mit den jüngsten Verbesserungen am Code-Toolbar-Button sollten Benutzer diesen eingefügten Abschnitt mit den harten Umbrüchen auswählen und in einen Code-Block umwandeln können, wobei die Zeilenumbrüche übernommen werden.

2 „Gefällt mir“

Vielen Dank für die Korrektur, @renato, und dass Sie sich die Zeit genommen haben, hier ein Update zu posten!

Die jüngsten Fehlerbehebungen haben die Funktionalität des Rich-Text-Editors auf einen Stand gebracht, auf dem er unser Forum für weniger technisch versierte Benutzer, die Markdown nicht kennen und nicht motiviert sind, es zu lernen, zugänglicher machen kann.


Es gibt immer noch ein paar Bedingungen, unter denen die Ergebnisse nicht wie erwartet sind, aber dies sind Dinge, die es nicht zumutbar ist, über die Discourse-Codebasis zu mildern:

Beschädigung durch versehentliche Markup-Syntax

Beiträge können beschädigt werden, wenn Inhalte vorhanden sind, die versehentlich Markup ähneln. Dies liegt an der bewussten Entscheidung, Markup im Rich-Text-Editor zu unterstützen.

Für unseren Anwendungsfall, bei dem erwartet wird, dass diejenigen, die Markup verwenden möchten, den Markdown-Editor verwenden, während der Rich-Text-Editor nur für diejenigen gedacht ist, die kein Interesse an der Verwendung von Markup haben, ist dies eine sehr unglückliche Entscheidung. Eines der größten Probleme, die wir mit nicht-technischen Benutzern haben, die den Markdown-Editor verwenden, ist die Beschädigung von Beiträgen aufgrund von versehentlichem Markup, und ich hatte große Hoffnungen, dass der Rich-Text-Editor dafür eine Lösung bieten würde. Für den Anwendungsfall, bei dem ein Forum nur einen Rich-Text-Editor bereitstellt, ist dieses Design jedoch durchaus sinnvoll, da es Benutzern, die mit Markdown vertraut sind, immer noch ermöglicht, Beiträge effizient zu verfassen.

Falsche Formatierung aufgrund von unangemessenem Markup in den Zwischeninhalten

Wir haben einen Fall, in dem der Inhalt vom Typ „text/html“, der in die Zwischenablage eingefügt wird, wenn aus einer bestimmten Anwendung kopiert wird, unangemessenes HTML-Markup enthält, was zu einer falschen Formatierung führt, wenn der Inhalt außerhalb eines Codeblocks in den Rich-Text-Editor eingefügt wird.

Dies ist natürlich ein Fehler in der Anwendung, und Discourse verhält sich zu 100 % korrekt, indem es den Inhalt gemäß dem Markup formatiert.

1 „Gefällt mir“

Vielen Dank @per1234

Können Sie Beispiele für Korruption etwas näher erläutern? Wir haben noch einige Ausnahmefälle bei Knoten, die wir nicht rendern können, aber wir versuchen, das Umschalten zum Rich-Editor in solchen Fällen zu verbieten.

Was die Zwischenablage betrifft, wollen wir uns auf jeden Fall verbessern. Es ist ein schwieriges Problem, und genaue Reproduktionen wären sehr hilfreich.

Sicher. Ich freue mich, wenn die Informationen nützlich sein können. Ich möchte meine vorherige Aussage wiederholen:

Ich würde mich jedoch freuen, wenn ich mich diesbezüglich irren würde :slightly_smiling_face:.

  1. Kopieren Sie den folgenden C+±Code:
    #include <iostream>
    int main() {
      std::cout << __FILE__;
    }
    
  2. Öffnen Sie den Beitragseditor.
  3. Versetzen Sie den Editor in den Modus „Rich-Text-Editor“.
  4. Fügen Sie den kopierten Inhalt in den Editor ein.

:slightly_frowning_face: Der Inhalt ist beschädigt:

#include
int main() {
std::cout << FILE;
}

(Beachten Sie, dass <iostream> unterdrückt wurde, da es wie ein nicht unterstützter HTML-Tag aussah, und __FILE__ als fette Auszeichnung behandelt wurde)

Dies könnte als Benutzerfehler angesehen werden, da es durch Auslösen eines Codeblocks vor dem Einfügen des Nicht-Prosa-Inhalts vermieden werden könnte. Wir könnten jedoch erwarten, dass der alternative Workflow, die Codeblockformatierung nachträglich auf eingefügten Inhalt anzuwenden, ebenso gültig wäre (wie im Markdown-Editor).

Ausrüstung

  • Jede Arduino-Platine (offiziell oder von Drittanbietern)

Anweisungen

  1. Installieren Sie die Arduino IDE 2.3.6, die von der „Software“-Seite der Arduino-Website heruntergeladen werden kann:
    https://www.arduino.cc/en/software/#ide-download-section
  2. Starten Sie die Arduino IDE.
  3. Wählen Sie im Menü der Arduino IDE Datei > Neuer Sketch aus.
  4. Ersetzen Sie den Inhalt des neuen Sketches durch den folgenden Code:
    void setup() {
      Serial.begin(9600);
      while (!Serial) {}  // Warten, bis der serielle Port geöffnet ist.
      delay(500);         // Einige Boards benötigen eine Verzögerung nach der Initialisierung des seriellen Ports.
      Serial.println("foo");
      Serial.println("bar");
    }
    void loop() {}
    
  5. Wählen Sie im Menü der Arduino IDE Werkzeuge > Serieller Monitor, um die Ansicht Serieller Monitor zu öffnen, falls sie noch nicht geöffnet ist.
  6. Wählen Sie im Menü der Ansicht Serieller Monitor9600“ aus der Baudratenauswahl.
  7. Laden Sie den Sketch auf Ihr Arduino-Board hoch.
  8. Wählen Sie die serielle Ausgabe aus dem Feld in der Ansicht Serieller Monitor.
  9. Kopieren Sie den ausgewählten Inhalt.
  10. Öffnen Sie den Discourse-Beitragseditor.
  11. Versetzen Sie den Editor in den Modus „Rich-Text-Editor“.
  12. Fügen Sie den kopierten Inhalt in den Editor ein.

:slightly_frowning_face: Jede Zeile des kopierten Inhalts wird in einem separaten Codeblock platziert:

foo

bar

Wenn Sie den Inhalt der Zwischenablage untersuchen, sehen Sie, dass er zusätzlich zum erwarteten Inhalt vom Typ „text/plain“:

foo
bar

Auch den folgenden Inhalt vom Typ „text/html“ enthält:

<div style="color: rgb(78, 91, 97); font-family: monospace; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: nowrap; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; position: absolute; left: 0px; top: 0px; height: 18px; width: 1862px;"><pre style="margin: 0px;">foo
</pre></div><div style="color: rgb(78, 91, 97); font-family: monospace; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: nowrap; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; position: absolute; left: 0px; top: 18px; height: 18px; width: 1862px;"><pre style="margin: 0px;">bar</pre></div>

Da der serielle Monitor der Arduino IDE 2.x jede Zeile des kopierten Inhalts vom Typ „text/html“ fälschlicherweise in <pre>-Tags einschließt, ist die Darstellung jeder Zeile des eingefügten Inhalts als separater Codeblock durch den Rich-Text-Editor von Discourse korrekt und erwartet.

Wie beim anderen Problem, das ich oben beschrieben habe, kann die unerwartete Formatierung vermieden werden, indem Sie proaktiv die Codeblockformatierung auslösen, bevor Sie den Inhalt einfügen.

2 „Gefällt mir“