La propriété CSS `white-space` des données du presse-papiers n'est pas respectée lors du collage dans l'éditeur de texte enrichi

Priorité/Gravité :

Moyenne

Plateforme :

Système d’exploitation

  • Windows 11

Navigateur

  • Google Chrome 139.0.7258.128

Discourse

028c90dd5e7a2799ea5b6e963f71fc0222681943

Description :

Le texte copié à partir de certaines sources peut être stocké dans le presse-papiers sous une forme formatée (type text/html) en plus du texte brut (type text/plain).

Lorsque du texte est collé dans le compositeur, si un type de données formaté est présent dans le presse-papiers, ces données sont utilisées à la place du type texte brut.

Par défaut, les espaces blancs dans le contenu HTML sont réduits. Ce comportement peut être contrôlé via la propriété CSS white-space.

:bug: Lors du collage dans le compositeur en mode « éditeur de texte enrichi », la propriété CSS white-space des données du presse-papiers n’est pas respectée. Cela entraîne une réduction systématique des espaces blancs dans le contenu collé. Dans les cas où le contenu source avait une propriété white-space définie sur la valeur pre, le contenu collé devient difficile à lire et incorrect dans les cas où les espaces blancs du contenu source avaient une signification technique.

Étapes reproductibles :

  1. Créez un fichier HTML avec le contenu suivant :
    <html>
      <body>
        <span style="white-space: pre">foo
    bar
        </span>
      </body>
    </html>
    
  2. Ouvrez le fichier dans votre navigateur web.
    Notez que les espaces blancs du contenu de la page ne sont pas réduits :
    foo
    bar
    
  3. Copiez le contenu de la page web.
  4. Ouvrez le compositeur de publication.
  5. Mettez le compositeur en mode « éditeur de texte enrichi ».
  6. Collez le contenu copié.

:bug: Au lieu d’avoir le même format que le contenu copié, les espaces blancs du contenu collé ont été réduits :

foo bar

Contexte supplémentaire :

Je constate que ProseMirror prend en charge white-space: pre :


La faute ne se produit pas lors de l’utilisation du compositeur en mode « éditeur Markdown ».


La faute ne se produit pas si le contenu est collé dans un bloc de code au lieu du mode éditeur normal. Il est vrai que dans de nombreux cas, il serait plus approprié de placer le contenu qui utilise quelque chose comme white-space: pre dans un bloc de code. Cependant, il est assez courant que les utilisateurs appliquent un formatage rétroactivement en ajoutant le contenu au compositeur, en sélectionnant le contenu, puis en utilisant la barre d’outils du compositeur pour appliquer le formatage (par opposition à l’approche alternative consistant à déclencher un bloc de code avant d’ajouter le contenu).


J’ai trouvé cet outil utile pour examiner les données brutes du contenu du presse-papiers :


Je suis en mesure de reproduire la faute sur try.discourse.org en « mode sans échec ».

Connexe

2 « J'aime »

Avez-vous mis l’éditeur de publication en mode « éditeur de texte enrichi » avant de coller le contenu copié depuis la page web ?

La faute se produit toujours.

Êtes-vous sûr d’avoir suivi les instructions exactement comme indiqué ?

Veuillez noter que vous devez copier le contenu rendu à partir de ce HTML, de sorte que le contenu du presse-papiers soit rempli avec des données de type text/html :

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

Il ne s’agit pas de composer votre message en utilisant du balisage HTML.

Ah, bonne remarque. J’ai tendance à survoler l’article un peu trop vite :sweat_smile:

1 « J'aime »

Merci de votre signalement @per1234, nous examinons cela.

Nous comprenons le problème général ici, nous voulons rendre aussi facile que possible pour les gens de coller des exemples de code.

2 « J'aime »

À quoi vous attendriez-vous de ce presse-papiers HTML ?

foo
bar

Ou, considérant qu’il s’agit d’une balise span, deux lignes de code en ligne avec un saut de ligne entre les deux ?

foo
bar

Ou simplement que nous respections les sauts de ligne mais dans un paragraphe normal, avec un saut de ligne entre les deux ?

foo
bar

Merci !

Je ne suis pas très calé en HTML, mais je m’attendrais à ce rendu :

D’après ce que j’ai pu constater, c’est ainsi que le navigateur Chrome le rend.


Cela dit, dans l’usage spécifique où j’ai rencontré le problème, il est vrai que le rendu en bloc de code serait le plus approprié. Nous obtenons ce type de contenu du presse-papiers en cliquant sur le bouton “Copier la sortie de la console” dans un IDE en ligne nommé “Arduino Cloud Editor” :

Cela copie dans le presse-papiers la sortie produite par le compilateur et d’autres outils. Ce type de contenu non textuel est mieux formaté en bloc de code.

Si la procédure suivante est utilisée pour partager cette sortie copiée dans un message de forum :

  1. Mettez l’éditeur de messages en mode “éditeur de texte enrichi”.
  2. Collez le contenu dans l’éditeur.
  3. Sélectionnez le contenu collé.
  4. Cliquez sur l’icône </> dans la barre d’outils de l’éditeur.

Le message se retrouve avec le formatage suivant :

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

(notez que tout le contenu copié est sur une seule ligne)

alors que nous nous attendrions à ce formatage de message :

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

Cependant, cette préférence pour un bloc de code est spécifique à notre cas d’utilisation particulier. Il se peut que dans d’autres cas d’utilisation, il existe des sources de contenu du presse-papiers avec une propriété white-space: pre pour lesquelles un bloc de code ne serait pas approprié. Et même pour notre cas d’utilisation, il est raisonnable de laisser la responsabilité d’appliquer manuellement le formatage en bloc de code à l’utilisateur.

1 « J'aime »

[quote=“per1234, post:8, topic:379035”]Le message se termine avec le formatage suivant :


[/quote]

Plus maintenant, cela a été corrigé récemment (vous pouvez le tester ici).

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

[/quote]

Dans ce cas, utilise-t-il toujours une balise span dans sa sortie de presse-papiers text/html, ou ne produit-il que du plain/text ?

Si j’utilise l’outil « Clipboard Inspector » pour vérifier les données dans mon presse-papiers après avoir cliqué sur le bouton « Copier la sortie de la console » dans l’éditeur Arduino Cloud, il affiche les données suivantes de type « text/plain » :

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

et les données suivantes de type « 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>

J’espère que cela répond à votre question. Je suis heureux de fournir des informations supplémentaires si nécessaire.

Cela devrait être corrigé par FIX: [rich editor] convert newlines to hard breaks when parsed from HTML by renato · Pull Request #35518 · discourse/discourse · GitHub (pas encore fusionné, il attend toujours une revue de code).

Ma première tentative a été de le convertir en bloc de code, mais je pense que ce serait trop hâtif et causerait de faux positifs. Au lieu de cela, nous respectons simplement les sauts de ligne en les convertissant en sauts forcés dans le contexte où le HTML a été collé. (Merci aux améliorations de Marijn pour prosemirror-model : When preserving whitespace, replace newlines with line break replacem… · ProseMirror/prosemirror-model@79e9f2b · GitHub)

Avec les récentes améliorations du bouton de la barre d’outils de code, les utilisateurs devraient pouvoir sélectionner cette section collée avec les sauts forcés et la convertir en bloc de code, et les nouvelles lignes devraient être conservées.

2 « J'aime »

Merci beaucoup pour la correction @renato, et d’avoir pris le temps de publier une mise à jour ici !

Les récentes corrections de bugs ont amené la fonctionnalité de l’éditeur de texte enrichi au point où elle peut servir à rendre notre forum plus accessible aux utilisateurs moins techniques qui ne connaissent pas déjà Markdown et ne sont pas motivés à l’apprendre.


Il existe encore quelques conditions dans lesquelles les résultats ne sont pas ceux attendus, mais ce sont des choses qu’il n’est pas raisonnable d’atténuer via la base de code de Discourse :

Corruption due to incidental markup syntax

Les publications peuvent être corrompues dans le cas où il y a du contenu qui ressemble incidemment à du balisage. Ceci est dû à la décision intentionnelle de prendre en charge le balisage dans l’éditeur de texte enrichi.

Pour notre cas d’utilisation où ceux qui souhaitent utiliser le balisage sont censés utiliser l’éditeur Markdown, tandis que l’éditeur de texte enrichi est destiné uniquement à ceux qui n’ont aucun intérêt à utiliser le balisage, c’est une décision très malheureuse. L’un des problèmes les plus importants que nous ayons avec les utilisateurs non techniques utilisant l’éditeur Markdown est la corruption des publications due à un balisage incident et j’avais grand espoir que l’éditeur de texte enrichi fournirait une solution à cela. Cependant, pour le cas d’utilisation où un forum ne fournit qu’un éditeur de texte enrichi, cette conception a parfaitement de sens car elle permet toujours aux utilisateurs maîtrisant Markdown de composer efficacement des publications.

Incorrect formatting due to inappropriate markup in clipboard content

Nous avons un cas où le contenu de type « text/html » ajouté au presse-papiers lors de la copie à partir d’une application spécifique contient un balisage HTML inapproprié, ce qui entraîne un formatage incorrect lorsque le contenu est collé dans l’éditeur de texte enrichi en dehors d’un bloc de code.

C’est bien sûr un bug dans l’application et Discourse agit à 100 % correctement en formatant le contenu tel qu’indiqué par le balisage.

1 « J'aime »

Merci beaucoup @per1234

Pouvez-vous donner plus d’exemples de cas où la corruption peut se produire ? Nous avons encore quelques cas limites concernant des nœuds que nous ne savons pas comment afficher, mais nous essayons d’interdire le passage à l’éditeur enrichi dans de tels cas.

Concernant le presse-papiers, nous voulons certainement nous améliorer. C’est un problème difficile, toute reproduction exacte ici serait très utile.

Bien sûr. Je suis heureux si l’information peut être utile. Je voudrais réitérer ma déclaration précédente :

Cependant, je serais heureux de me tromper à ce sujet :slightly_smiling_face:.

  1. Copiez le code C++ suivant :
    #include <iostream>
    int main() {
      std::cout << __FILE__;
    }
    
  2. Ouvrez le compositeur de publication.
  3. Mettez le compositeur en mode « éditeur de texte enrichi ».
  4. Collez le contenu copié dans le compositeur.

:slightly_frowning_face: Le contenu est corrompu :

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

(notez que <iostream> a été supprimé car il ressemblait à une balise HTML non prise en charge, et __FILE__ a été traité comme du balisage gras)

Cela pourrait être considéré comme une erreur de l’utilisateur, car cela pourrait être évité en déclenchant un bloc de code avant de coller le contenu non-prose. Cependant, nous pourrions nous attendre à ce que le flux de travail alternatif consistant à appliquer un formatage de bloc de code rétroactivement au contenu collé soit tout aussi valable (comme c’est le cas lorsque l’on utilise l’éditeur Markdown).

Équipement

  • N’importe quelle carte Arduino (officielle ou tierce)

Instructions

  1. Installez l’IDE Arduino 2.3.6, téléchargeable depuis la page « Logiciels » du site web Arduino :
    https://www.arduino.cc/en/software/#ide-download-section
  2. Démarrez l’IDE Arduino.
  3. Sélectionnez Fichier > Nouvelle esquisse dans les menus de l’IDE Arduino.
  4. Remplacez le contenu de la nouvelle esquisse par le code suivant :
    void setup() {
      Serial.begin(9600);
      while (!Serial) {}  // Attendre que le port série soit ouvert.
      delay(500);         // Certaines cartes nécessitent un délai après l'initialisation du port série.
      Serial.println("foo");
      Serial.println("bar");
    }
    void loop() {}
    
  5. Sélectionnez Outils > Moniteur série dans les menus de l’IDE Arduino pour ouvrir la vue Moniteur série, si elle n’est pas déjà ouverte.
  6. Sélectionnez « 9600 » dans le menu du débit en bauds dans la vue Moniteur série.
  7. Téléversez l’esquisse sur votre carte Arduino.
  8. Sélectionnez la sortie série dans le champ de la vue Moniteur série.
  9. Copiez le contenu sélectionné.
  10. Ouvrez le compositeur de publication Discourse.
  11. Mettez le compositeur en mode « éditeur de texte enrichi ».
  12. Collez le contenu copié dans le compositeur.

:slightly_frowning_face: Chaque ligne du contenu copié est placée dans un bloc de code distinct :

foo

bar


Si vous inspectez le contenu du presse-papiers, vous verrez qu’en plus du contenu attendu de type « text/plain » :

foo
bar

Il contient également le contenu suivant de type « text/html » :

<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>

Étant donné que le Moniteur série de l’IDE Arduino 2.x encapsule incorrectement chaque ligne du contenu copié de type « text/html » dans des balises <pre>, le rendu de chaque ligne du contenu collé comme un bloc de code distinct par l’éditeur de texte enrichi de Discourse est correct et attendu.

Comme pour l’autre problème que j’ai décrit ci-dessus, le formatage inattendu peut être évité en déclenchant de manière proactive le formatage du bloc de code avant de coller le contenu.

2 « J'aime »