Atualmente no Discourse, se você colar texto simples no compositor, o comportamento típico do navegador via Ctrl+Z desfará essa colagem e removerá o texto colado. No entanto, se você colar texto formatado como este texto em negrito, o desfazer não funciona. Da mesma forma, colar links sobre texto para vinculá-los não pode ser desfeito, nem a marcação inserida por atalhos como Ctrl+B ou ao adicionar formatação pelas opções da barra de ferramentas do compositor. Idealmente, o máximo possível disso seria adicionado à pilha de desfazer para que Ctrl+Z funcione.
Deixe-me dar uma descrição do que acontece comigo com bastante frequência.
Copio um texto de outro site que por acaso é um link, negrito, um cabeçalho, etc. (Às vezes, esse fato é registrado e às vezes não.)
Vou ao Discourse para colar esse texto em minha postagem já parcialmente escrita.
Pressiono Ctrl+V, que insere o texto formatado.
Percebo meu erro e pressiono Ctrl+Z, o que não faz nada.
Removo manualmente o texto formatado que inseri por engano. (Na maioria das vezes, é a versão vinculada que colei por engano, então não é como se eu tivesse que remover apenas um ‘#’ ou algo assim.)
Pressiono Ctrl+Shift+V, o que eu deveria ter feito da primeira vez para colar o texto sem formatação.
Obviamente, isso é em parte erro do usuário, e quando não me engano, são apenas duas etapas (copiar de outro site, colar como texto simples no Discourse). Mas quando eu erro (o que acontece com frequência, já que estou acostumado a apenas pressionar Ctrl+V, já que a maioria dos sites não faz colagem formatada), seria bom se eu pudesse economizar tempo fazendo Ctrl+Z funcionar normalmente.
Certo, o desfazer não funciona por padrão quando você usa JavaScript para modificar uma entrada. Mas pesquisei e descobri que document.execCommand pode inserir texto enquanto anexa à pilha de desfazer.
Por exemplo, se você fizer document.getElementById('myInput').value = 'asd' e depois \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eZ\u003c/kbd\u003e, ele não desfará.
Mas se você fizer document.execCommand('insertText', false, 'asd') enquanto o cursor estiver onde você deseja (o que deve acontecer com base no fluxo de trabalho atual do Discourse), o texto será inserido corretamente e \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eZ\u003c/kbd\u003e removerá o texto adicionado como esperado.
Basicamente, estou me perguntando se document.execCommand (ou algum outro processo, se outra abordagem for considerada melhor) pode ser usado para anexar à pilha de desfazer para que \u003ckbd\u003eCtrl\u003c/kbd\u003e+\u003ckbd\u003eZ\u003c/kbd\u003e funcione nesses casos.
Não — removemos intencionalmente esse suporte do Discourse anos atrás, em favor de deixar o tratamento de desfazer da caixa de texto nativa do navegador funcionar como deveria em todos os sites padrão.
Acho que estou perdendo alguma coisa. O que exatamente significa “deixar o tratamento de desfazer da caixa de texto nativa do navegador funcionar”? Pelo que pude apurar, o desfazer para texto formatado não funciona de forma alguma no Discourse, então você está dizendo que o não funcionamento do desfazer é o comportamento padrão do site?
O motivo da minha confusão é que não consigo pensar em um único site (além de coisas como o Microsoft Word, onde o desfazer funciona) que suporte colagem formatada além do Discourse. Portanto, não tenho nada para comparar o Discourse para ver o que é “padrão”. Se você pudesse me indicar alguns sites para comparação, isso seria muito útil.
Pressione Try it yourself, em seguida, insira texto na caixa de texto, pause e pressione Ctrl+Z para desfazer suas ações. Aqui está uma demonstração. Primeiro, pressionamos o botão Try it yourself, que resulta na exibição de um textarea HTML no navegador.
Meu entendimento é que @seanblue está perguntando se podemos alterar as APIs do navegador que usamos ao manipular a textarea para dar melhores dicas ao navegador, para que ele possa lidar melhor com o desfazer. Portanto, isso se aplicaria apenas a atalhos de teclado, barra de ferramentas, upload e coisas assim.
Não sou contra ajustar coisas aqui, mas me preocupo que algumas dessas APIs exijam muito cuidado, certamente há risco de regressões.
Não sou contra experimentos aqui, talvez se a comunidade desejar enviar alguns PRs para nos mostrar como isso é feito.
Poderíamos definitivamente fazer melhor aqui. Muitos dos nossos botões da barra de ferramentas e o comportamento de colar especial definem diretamente o valor da textarea em JavaScript. Isso quebra totalmente o histórico nativo de desfazer/refazer do navegador.
Em vez disso, sempre que fizermos modificações programáticas na textarea, devemos usar document.execCommand (como @seanblue mencionou). Dessa forma, o navegador interpreta como uma ação do usuário e a insere de forma limpa no histórico de desfazer/refazer.
o comando insertText, que você pode usar para substituir programaticamente o texto no cursor, preservando o buffer de desfazer (histórico de edições) em elementos textarea e input simples.
Mas essa caixa de texto não lida com texto formatado, que não é o que estou falando. Eu sei que os navegadores lidam com desfazer texto digitado e colado normalmente. Meu ponto é que o Discourse não lida com desfazer texto formatado colado. Siga estas etapas para ver do que estou falando.
Isso mesmo. Não estou sugerindo lidar com o desfazer em JavaScript. Estou sugerindo que, ao manipular a área de texto, você informe o navegador para que ele possa desfazer a alteração por conta própria quando o usuário pressionar Ctrl+Z.
Para que valha a pena, 99% da minha frustração seria resolvida se Ctrl+Z funcionasse após colar texto formatado. Seria ideal se cada operação pudesse ser desfeita com Ctrl+Z? Com certeza. Mas a maioria das outras operações pode ser desfeita repetindo a operação original (por exemplo, fazer Ctrl+B pode adicionar e remover a marcação em negrito). Mas com a colagem, ela tem o potencial de incluir uma quantidade significativa de marcação inesperada, incluindo cabeçalhos, links e até tabelas, razão pela qual é tão importante que o desfazer funcione nesse caso.
Se reduzíssemos o escopo para apenas lidar com o desfazer no caso de colagem formatada e ignorássemos outros atalhos, botões da barra de ferramentas, etc., isso reduziria o risco o suficiente para tentar?
Entendi; entre a sua explicação e a do @david, compreendo a distinção. Eu simplesmente nunca usei esses botões no editor na maior parte do tempo. Eu digito as coisas na caixa de texto usando o teclado do meu computador (físico ou na tela), e isso é tratado perfeitamente pelo navegador.
Isso é compreensível. Eu também costumo digitar a marcação em vez de usar os botões da barra de ferramentas para isso, então esse aspecto não é realmente um problema para mim. Eu só mencionei as coisas da barra de ferramentas no OP para apontar que isso não acontece apenas ao colar texto formatado. Ser capaz de desfazer as ações da barra de ferramentas não é super importante porque o usuário está realizando essas ações intencionalmente. Mas ao colar, a formatação é muitas vezes incidental e inesperada, então ser capaz de desfazer isso seria muito conveniente.
Ainda não está agendado, mas sim, parece resolver o problema. Acho que deveríamos mudar nossa implementação tanto para a barra de ferramentas quanto para atalhos como CTRL+B e menções.
É uma mudança bastante complexa, eu diria que levaria cerca de 1 a 3 semanas de trabalho para implementar tudo isso. Há muita área de superfície:
Recortar e colar imagens
Uploads
Negrito / Itálico
Links
@menções
#autocompletar
Eu apoio essa mudança, mas não tenho certeza de quando podemos agendá-la… Acho que não me importo em encaixá-la para nossa próxima versão, alguma objeção @codinghorror?
Eu gosto que você poderá usar CTRL+Z até uma caixa vazia em vez de ser bloqueado na sua primeira menção, link, etc…
Uma coisa boa é que (na minha opinião) pode ser razoavelmente feito incrementalmente, em vez de ter que lançar tudo de uma vez. Obviamente, não sei se será o caso de uma perspectiva técnica, mas de uma perspectiva do usuário, acho que estaria tudo bem. Algumas separações lógicas poderiam ser:
Colar texto que se torna formatado, incluindo coisas como negrito, imagens e links
Autocompletar menções, categorias/tags, emoji
Atalhos de teclado como Ctrl+B para negrito
Ações da barra de ferramentas, como negrito, ocultar detalhes, desfocar spoilers, etc.
Sinto que cada um desses grupos poderia ser feito individualmente sem confundir os usuários, e pessoalmente essa seria a ordem em que eu implementaria.
Estou alocando este trabalho para nosso próximo lançamento, o que significa que o resolveremos nos próximos 6 meses ou mais, não acontecerá da noite para o dia, mas faremos progressos aqui.
Sim, eu te entendo completamente, mas isso vai levar um pouco mais de tempo.
Isso meio que se transformou em uma refatoração completa necessária no composer. Nosso plano de longo prazo é dar suporte a uma camada de abstração diferente para o composer, que agora está SUPERmente acoplada a ser sempre um elemento TEXTAREA.
A primeira medida para destravar é dar suporte a um composer contenteditable que se pareça e aja como nossa área de texto atual.
Não vejo começarmos este projeto por mais 3 meses, pois temos outros 3 projetos muito grandes na frente dele, mas certamente vejo começarmos este projeto este ano.
Sem problemas, estava apenas procurando uma atualização.
Uau, eu nunca tinha ouvido falar de contenteditable até agora. Você se importaria de compartilhar uma breve explicação técnica de por que essa mudança é necessária/desejável? Se não, tudo bem, estou apenas curioso.
É um tanto complicado, mas queremos entrar no mundo de experimentar editores ricos. Isso nos permitiria.
A razão pela qual este trabalho está no caminho crítico é que todos os nossos internos estão fortemente acoplados a uma implementação específica (TEXTAREA). Não temos uma única função para interagir com o compositor, é mais como copiar e colar 20 implementações diferentes.
O que gostaríamos de fazer é ter um pequeno componente “esqueleto” que diga
É assim que você seleciona texto
É assim que você insere texto
E assim por diante… então podemos reimplementar o esqueleto como um contenteditable ou uma implementação amigável de desfazer do TEXTAREA.
No entanto, muito código precisa ser movido para permitir isso.
Isso está longe de ser tão abrangente quanto o trabalho de longo prazo que @sam descreveu. Mas acho que isso ajudará no curto prazo. Isso deve preservar o histórico de desfazer ao colar texto rico, citar e ao usar (a maioria) dos botões/atalhos de teclado do composer.
Já está ativo no Meta - avise se notar algum problema.