Propriedade CSS `white-space` de dados da área de transferência não respeitada ao colar em editor de rich text

Prioridade/Severidade:

Média

Plataforma:

Sistema Operacional

  • Windows 11

Navegador

  • Google Chrome 139.0.7258.128

Discourse

028c90dd5e7a2799ea5b6e963f71fc0222681943

Descrição:

O texto copiado de algumas fontes pode ser armazenado na área de transferência em um formato formatado (tipo text/html) além de texto simples (tipo text/plain).

Quando o texto é colado no compositor, se um tipo de dado formatado estiver presente na área de transferência, esses dados serão usados em vez do tipo de texto simples.

Por padrão, o espaço em branco no conteúdo HTML é colapsado. Esse comportamento pode ser controlado através da propriedade CSS white-space.

:bug: Ao colar no compositor quando no modo "editor de rich text", a propriedade CSS white-space dos dados da área de transferência não é respeitada. Isso resulta no colapso do espaço em branco no conteúdo colado. Em casos onde o conteúdo de origem tinha a propriedade white-space definida como o valor pre, isso resulta em um conteúdo colado difícil de ler e incorreto em casos onde o espaço em branco do conteúdo de origem tinha significado técnico.

Passos para reproduzir:

  1. Crie um arquivo HTML com o seguinte conteúdo:
    <html>
      <body>
        <span style="white-space: pre">foo
    bar
        </span>
      </body>
    </html>
    
  2. Abra o arquivo em seu navegador.
    Observe que o espaço em branco do conteúdo da página não é colapsado:
    foo
    bar
    
  3. Copie o conteúdo da página da web.
  4. Abra o compositor de postagens.
  5. Coloque o compositor no modo “editor de rich text”.
  6. Cole o conteúdo copiado.

:bug: Em vez de ter o mesmo formato do conteúdo copiado, o espaço em branco do conteúdo colado foi colapsado:

foo bar

Contexto adicional:

Vejo que o ProseMirror suporta white-space: pre:


O erro não ocorre ao usar o compositor no modo “editor Markdown”.


O erro não ocorre se o conteúdo for colado em um bloco de código em vez do modo de editor normal. É verdade que em muitos casos seria mais apropriado colocar o conteúdo que usa algo como white-space: pre em um bloco de código. No entanto, é bastante comum que os usuários apliquem formatação retroativamente adicionando o conteúdo ao compositor, selecionando o conteúdo e, em seguida, usando a barra de ferramentas do compositor para aplicar a formatação (em oposição à abordagem alternativa de acionar um bloco de código antes de adicionar o conteúdo).


Achei esta uma ferramenta útil para examinar os dados brutos do conteúdo da área de transferência:


Consigo reproduzir o erro em try.discourse.org em "modo de segurança".

Relacionado

2 curtidas

Você colocou o editor de postagens no modo “editor de rich text” antes de colar o conteúdo copiado da página da web?

A falha ainda ocorre.

Você tem certeza de que seguiu as instruções exatamente como escritas?

Por favor, note que você deve copiar o conteúdo que é renderizado a partir desse HTML, de modo que o conteúdo da área de transferência seja preenchido com dados do tipo text/html:

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

Isso não é sobre compor sua postagem usando marcação HTML.

Ah, boa observação. Eu tenho uma tendência a ler o post rápido demais :sweat_smile:

1 curtida

Obrigado por relatar @per1234, estamos analisando isso.

Entendemos o problema geral aqui, queremos tornar o mais fácil possível para as pessoas colarem exemplos de código.

2 curtidas

O que você esperaria de uma área de transferência HTML como essa?

foo
bar

Ou, considerando que é uma tag span, duas linhas de código inline com uma quebra de linha entre elas?

foo
bar

Ou apenas que respeitemos as quebras de linha, mas em um parágrafo normal, com uma quebra de linha entre elas?

foo
bar

Obrigado!

Não tenho muito conhecimento sobre o assunto de HTML, mas esperaria esta renderização:

Pelo que pude apurar, é assim que o navegador Chrome renderiza.


Dito isso, no uso específico em que encontrei o problema, é verdade que a renderização de bloco de código seria a mais apropriada. Obtemos esse tipo de conteúdo da área de transferência clicando no botão “Copiar Saída do Console” em um IDE online chamado “Arduino Cloud Editor”:

Isso copia a saída produzida pelo compilador e outras ferramentas para a área de transferência. Esse tipo de conteúdo não-prosa é melhor formatado como um bloco de código.

Se o seguinte procedimento for usado para compartilhar essa saída copiada em uma postagem de fórum:

  1. Coloque o compositor de postagem no modo “editor de rich text”.
  2. Cole o conteúdo no compositor.
  3. Selecione o conteúdo colado.
  4. Clique no ícone </> na barra de ferramentas do compositor.

A postagem acaba com a seguinte formatação:

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

(note que todo o conteúdo copiado está em uma única linha)

enquanto esperaríamos esta formatação de postagem:

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

No entanto, essa preferência por um bloco de código é específica para o nosso caso de uso particular. Pode ser que em outros casos de uso existam fontes de conteúdo da área de transferência com a propriedade white-space: pre para as quais um bloco de código não seria apropriado. E mesmo para o nosso caso de uso, é razoável colocar a responsabilidade de aplicar manualmente a formatação de bloco de código no usuário.

1 curtida

Não mais, isso foi corrigido recentemente (você pode testar aqui).

Nesse caso, ele ainda usa uma tag span na saída da sua área de transferência text/html, ou ele apenas gera plain/text?

Se eu usar a ferramenta “Clipboard Inspector” para verificar quais dados estão na minha área de transferência depois de clicar no botão “Copy Console Output” no Arduino Cloud Editor, ele mostra que há os seguintes dados do tipo “text/plain”:

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

e os seguintes dados do tipo “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>

Espero que isso responda à sua pergunta. Fico feliz em fornecer informações adicionais, se necessário.

Isso deve ser corrigido por FIX: [rich editor] convert newlines to hard breaks when parsed from HTML by renato · Pull Request #35518 · discourse/discourse · GitHub (ainda não mesclado, ainda aguarda revisão de código).

Minha primeira tentativa foi convertê-lo para um bloco de código, mas acho que seria muito precipitado e causaria alguns falsos positivos. Em vez disso, apenas respeitamos as quebras de linha, convertendo-as em quebras rígidas no contexto em que o HTML foi colado. (Graças à melhoria de Marijn no prosemirror-model: When preserving whitespace, replace newlines with line break replacem… · ProseMirror/prosemirror-model@79e9f2b · GitHub)

Com as melhorias recentes no botão da barra de ferramentas de código, os usuários devem ser capazes de selecionar esta seção colada com as quebras rígidas e convertê-la em um bloco de código, e as novas linhas devem ser mantidas.

2 curtidas

Muito obrigado pela correção @renato, e por dedicar tempo para postar uma atualização aqui!

As correções de bugs recentes trouxeram a funcionalidade do editor de rich text para um ponto em que ele pode servir para tornar nosso fórum mais acessível a usuários menos técnicos que ainda não estão familiarizados com Markdown e não estão motivados a aprendê-lo.


Ainda existem algumas condições sob as quais os resultados não são os esperados, mas estas são coisas que não é razoável mitigar através da base de código do Discourse:

Corrupção devido a sintaxe de marcação incidental

As postagens podem ser corrompidas no caso de haver conteúdo que incidentalmente se assemelha a marcação. Isso se deve à decisão intencional de suportar marcação no editor de rich text.

Para o nosso caso de uso, onde aqueles que desejam usar marcação devem usar o editor Markdown, enquanto o editor de rich text se destina apenas ao uso por aqueles sem interesse em usar marcação, esta é uma decisão muito infeliz. Um dos problemas mais significativos que temos com usuários não técnicos usando o editor Markdown é a corrupção de postagens devido a marcação incidental e eu tinha grandes esperanças de que o editor de rich text forneceria uma solução para isso. No entanto, para o caso de uso onde um fórum fornecerá apenas um editor de rich text, este design faz todo o sentido, pois ainda permite que usuários fluentes em Markdown componham postagens de forma eficiente.

Formatação incorreta devido a marcação inadequada no conteúdo da área de transferência

Temos um caso em que o conteúdo do tipo “text/html” adicionado à área de transferência ao copiar de um aplicativo específico tem marcação HTML inadequada, o que resulta em formatação incorreta quando o conteúdo é colado no editor de rich text fora de um bloco de código.

Este é, claro, um bug no aplicativo e o Discourse está agindo 100% corretamente ao formatar o conteúdo conforme indicado pela marcação.

1 curtida

Muito obrigado @per1234

Você pode detalhar um pouco mais os exemplos onde a corrupção pode ocorrer? Ainda temos alguns casos extremos em torno de nós que não sabemos como renderizar, mas tentamos proibir a alternância para o editor rico em casos como este.

Em relação à área de transferência, certamente queremos melhorar. É um problema difícil, qualquer reprodução exata aqui seria muito útil.

Claro. Fico feliz se a informação puder ser útil. Gostaria de reiterar minha declaração anterior:

No entanto, ficaria feliz em estar errado sobre isso :slightly_smiling_face:.

  1. Copie o seguinte código C++:
    #include <iostream>
    int main() {
      std::cout << __FILE__;
    }
    
  2. Abra o compositor de postagens.
  3. Coloque o compositor no modo “editor de rich text”.
  4. Cole o conteúdo copiado no compositor.

:slightly_frowning_face: O conteúdo está corrompido:

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

(observe que o <iostream> foi suprimido por se assemelhar a uma tag HTML não suportada, e o __FILE__ foi tratado como marcação em negrito)

Isso pode ser visto como erro do usuário, pois poderia ser evitado acionando um bloco de código antes de colar o conteúdo não em prosa. No entanto, poderíamos esperar que o fluxo de trabalho alternativo de aplicar formatação de bloco de código retroativamente ao conteúdo colado seria igualmente válido (como é ao usar o editor Markdown).

Equipamento

  • Qualquer placa Arduino (seja oficial ou de terceiros)

Instruções

  1. Instale o Arduino IDE 2.3.6, que pode ser baixado na página “Software” do site do Arduino:
    https://www.arduino.cc/en/software/#ide-download-section
  2. Inicie o Arduino IDE.
  3. Selecione File > New Sketch nos menus do Arduino IDE.
  4. Substitua o conteúdo do novo sketch pelo seguinte código:
    void setup() {
      Serial.begin(9600);
      while (!Serial) {}  // Aguarda a porta serial ser aberta.
      delay(500);         // Algumas placas requerem um delay após a inicialização da porta serial.
      Serial.println("foo");
      Serial.println("bar");
    }
    void loop() {}
    
  5. Selecione Tools > Serial Monitor nos menus do Arduino IDE para abrir a visualização Serial Monitor, se ela ainda não estiver aberta.
  6. Selecione “9600” no menu da taxa de baud na visualização Serial Monitor.
  7. Faça o upload do sketch para sua placa Arduino.
  8. Selecione a saída serial do campo na visualização Serial Monitor.
  9. Copie o conteúdo selecionado.
  10. Abra o compositor de postagens do Discourse.
  11. Coloque o compositor no modo “editor de rich text”.
  12. Cole o conteúdo copiado no compositor.

:slightly_frowning_face: Cada linha do conteúdo copiado é colocada em um bloco de código separado:

foo

bar


Se você inspecionar o conteúdo da área de transferência, verá que, além do conteúdo esperado do tipo “text/plain”:

foo
bar

Ele também contém o seguinte conteúdo do tipo “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>

Como o Serial Monitor do Arduino IDE 2.x envolve incorretamente cada linha do conteúdo copiado do tipo “text/html” em tags <pre>, a renderização de cada linha do conteúdo colado como um bloco de código separado pelo editor de rich text do Discourse é correta e esperada.

Assim como no outro problema que descrevi acima, a formatação inesperada pode ser evitada acionando proativamente a formatação de bloco de código antes de colar o conteúdo.

2 curtidas