Lançamento do Wordgard 0.1
(marijnhaverbeke.nl)- Wordgard 0.1 é uma nova biblioteca JavaScript de editor de texto rico, criada com base em 9 anos de experiência desde a estabilização do ProseMirror e refletindo o design do CodeMirror 6
- Em vez de transformar o ProseMirror existente em 2.0 ou adicionar camadas ao 1.x, ele foi redesenhado com uma nova API sem o peso da compatibilidade e com um nome separado
- O design central usa um modelo baseado em seções de mudança em vez de steps, combinando tipos independentes de nó e marca com um sistema de extensões facet no estilo do CodeMirror
- Reduz a dependência do comportamento de seleção do navegador ao lidar diretamente com seleção por ponteiro e teclado, mas mantém a implementação do navegador para seleção por toque devido a problemas com o menu de contexto nativo
- Pode ser instalado via npm com
wordgard, e a documentação e o manual de referência já foram publicados, mas deve permanecer na série 0.x por algum tempo enquanto recebe feedback e correções de bugs
Natureza do Wordgard e estado de lançamento
- Wordgard é um projeto que reimagina do zero um sistema de editor de texto rico no estilo do ProseMirror
- Foi fortemente influenciado pelo que foi aprendido nos 9 anos desde a estabilização do ProseMirror e pelo redesenho da versão 6 do CodeMirror
- É uma biblioteca JavaScript que exibe a interface do editor usando o DOM do navegador, e sua licença é MIT
- O código está disponível em um servidor Forgejo
- Pode ser instalado como
wordgardno registro npm, e o modo de uso pode ser consultado no site
Por que criar um novo sistema sem substituir o ProseMirror
- O ProseMirror continua sendo mantido, mas algumas escolhas de design permaneceram como pontos que hoje deveriam ter sido feitos de outra forma
- Se fosse lançado um ProseMirror 2.0 com interface incompatível, poderia ficar ambíguo o que as pessoas querem dizer quando falam “ProseMirror”
- Se novas ideias fossem adicionadas ao ProseMirror 1.x de forma retrocompatível, a estrutura poderia acabar seguindo por compromissos excessivos
- O Wordgard reaproveita muitas ideias do ProseMirror, mas sua interface de programação foi redesenhada do zero sem preocupação com compatibilidade
Representação de mudanças: modelo baseado em seções em vez de steps
- Os steps do ProseMirror dividem uma mudança em várias operações atômicas, e cada step é aplicado ao documento gerado pelo step anterior
- Esse método funciona, mas lidar com o ajuste de posições entre vários steps e rastrear o escopo das mudanças é complexo e pouco prático
- O Wordgard usa um modelo mais simples, baseado na representação de mudanças do CodeMirror e no formato “delta” do ShareJS
- Quando o documento tem comprimento 10 e se insere
Lna posição 4, isso é representado como[keep 4] [replace 0 with "L"] [keep 6] - Ao remover os dois primeiros caracteres, fica
[replace 2 with ""] [keep 8]
- Quando o documento tem comprimento 10 e se insere
- Para lidar com texto rico, ele adiciona seções de mudança, permitindo adicionar ou remover marcas como destaque, estilo de link e texto alternativo de imagem sem quebrar a estrutura
- Se as palavras de 3 a 6 forem colocadas em negrito, isso é representado como
[keep 3] [update 3 +bold] [keep 4]
- Se as palavras de 3 a 6 forem colocadas em negrito, isso é representado como
- O Wordgard usa o mesmo índice por contagem de tokens do ProseMirror, tratando as posições do documento como uma sequência plana de tokens de abertura/fechamento de nó e tokens folha
- Uma transação única sempre contém exatamente uma mudança, o que facilita composição, verificação e inferência
- Há suporte a transformação operacional limitada para mesclar múltiplas mudanças expressas com base no mesmo documento inicial
- Isso permite representar com mais conforto transações com várias mudanças
- Também pode ser usado para edição colaborativa e para implementar histórico de undo com reversão parcial de mudanças
Como manter uma estrutura de documento válida
- Um documento do Wordgard não é apenas uma sequência simples de tokens, mas uma estrutura de árvore balanceada
- Por exemplo, se um token de fechamento de nó for removido, o equilíbrio dos tokens pode se quebrar e gerar uma mudança impossível de aplicar
- O código que cria conjuntos de mudanças precisa verificar e ajustar as mudanças para que o resultado mantenha uma estrutura de documento válida
- Na transformação operacional, a mudança transformada também não pode invalidar o documento
- O modelo de mudanças do Wordgard deriva uma fix-up change para corrigir o resultado combinado durante a transformação
- As entradas são usadas com cuidado para que A-over-B e B-over-A produzam a mesma correção
- Sem essa correção, as duas ordens poderiam produzir o mesmo documento, porém inválido
- Ao compor a mesma correção, ambas as ordens convergem para o mesmo documento válido
- A maioria das mudanças não precisa de correção, mas, quando precisa, o sistema foi projetado para preservar a convergência
Composição de schema e generalização de marks
- No ProseMirror, o schema do documento define diretamente as relações entre nós, então normalmente ele precisa ser configurado manualmente
- Os tipos de nó e mark do ProseMirror existem apenas dentro de um schema específico, sem uma identidade de nó compartilhável entre schemas
- No Wordgard, os tipos de nó e mark são objetos independentes que podem ser incluídos em vários schemas de documento
- Esses objetos funcionam como handles com tipagem e autocomplete, facilitando montar um schema combinando apenas os elementos necessários
- O schema pode sobrescrever relações de elementos existentes
- Definições de nó ou mark especificam conteúdo ou tipos de destino padrão
- Quando se quer usar o mesmo elemento de outra forma, o schema pode alterar essas relações
- Isso permite fornecer nós embutidos padrão mais ricos e facilita anexar diretamente a esses nós integrações de sistema, como extensões de suporte à edição ou botões de menu
- Recursos antes presos a atributos específicos de nós, como alinhamento de texto ou texto alternativo, podem ser adicionados de forma mais modular por meio da generalização de marks
- O próprio tipo de nó não precisa saber quais marks o têm como alvo
Por que flexibilizar as restrições de conteúdo
- A especificação de conteúdo permitido baseada em expressões regulares, um recurso marcante do ProseMirror, não é suportada no Wordgard
- A descrição de conteúdo de nós no Wordgard restringe apenas quais tipos de filhos são aceitos, mas não restringe sua ordem
- Restrições baseadas em expressões regulares dificultam a escrita de código genérico de manipulação de documentos
- Código não escrito para um schema específico quase não consegue assumir quais transformações são válidas
- Cada operação precisa ser comparada com as restrições de conteúdo, e esse processo é sutil e pesado
- Restrições que travam fortemente a forma do documento podem bloquear etapas intermediárias de edição rumo ao resultado pretendido pelo usuário, prejudicando a experiência
- O Wordgard incentiva uma abordagem mais flexível para a forma do documento
- Quando são necessárias condições invariantes além das regras do schema, ele fornece a abstração de correction
- Formas de documento indesejadas podem ser corrigidas por código
- Isso permite correções mais inteligentes e sensíveis ao contexto do que impor expressões de conteúdo
- Também serve para condições que nem poderiam ser expressas nas restrições do ProseMirror, como garantir tabelas retangulares
Sistema de extensões: facets no estilo do CodeMirror 6
- O sistema de extensões do ProseMirror faz com que plugins assumam várias funções, e a ordem no array influencia a prioridade
- Pode acontecer de um plugin precisar de baixa prioridade em um hook e alta prioridade em outro
- O sistema baseado em facets do CodeMirror torna as extensões mais granulares e permite que cada valor de extensão defina sua própria categoria de prioridade
- Um Facet é um ponto de extensão tipado que pode ser definido não só pela biblioteca, mas por qualquer código
- O Wordgard traz essa parte do sistema do CodeMirror quase intacta, incluindo o mecanismo de atualização de estado e reconfiguração
- A configuração não é um array de plugins, mas uma árvore de extensões
- definição de manipuladores de evento
- configuração de propriedades do editor
- adição de novo estado ao editor
- A implementação de funcionalidades costuma ser composta por conjuntos de extensões que atuam em conjunto
- Os elementos primitivos foram projetados para que os pacotes de extensões geralmente se combinem bem apenas sendo adicionados à configuração
Redução da dependência do navegador e tratamento de seleção
- Muitos problemas do ProseMirror estão ligados à dependência do comportamento nativo de seleção do navegador
- A abordagem anterior deixava o navegador lidar com movimentação de cursor em texto bidirecional ou conteúdo com estilos incomuns e depois refletia o resultado no próprio modelo de seleção
- Na prática, os navegadores podem não mover o cursor por certos conteúdos, não desenhá-lo, desenhá-lo na posição errada ou se comportar de forma estranha ao arrastar a seleção com o mouse
- O Wordgard lida diretamente com quase toda a seleção por ponteiro e teclado
- Implementa o tratamento de texto bidirecional
- Cria um modelo de layout de conteúdo
- Desenha o cursor por conta própria
- A seleção por toque é a exceção e usa a implementação nativa
- Reimplementar isso parece quebrar o menu de contexto nativo
- Em celulares e tablets, é difícil substituir o menu de contexto
- A seleção por toque também tende a apresentar menos comportamentos estranhos do que a seleção por teclado
Tratamento de eventos de entrada e remoção da observação de mudanças no DOM
- Nos últimos 9 anos, o suporte dos navegadores a eventos de edição, especialmente ao
beforeinput, ficou mais consistente - Ainda é necessário testar em ambientes reais de uso, mas o Wordgard parece capaz de funcionar sem a observação de mudanças no DOM nem os truques de parse de conteúdo alterado dos quais o ProseMirror dependia
- O Wordgard trata o evento
beforeinputpara tudo, exceto entrada de texto em composição - Essa abordagem evita uma série de problemas que exigiam implementações de contorno complicadas
Estabilidade, plano de versão e licença
- O Wordgard está em um estado um pouco mais avançado do que projetos anteriores no momento em que foram anunciados
- As interfaces centrais já suportam quase tudo o que se desejava, e várias extensões também foram escritas para verificar se o design é prático
- A documentação ainda está um pouco crua, mas o manual de referência está completo e pode ser usado
- Muitos problemas podem não aparecer até que pessoas comecem a usá-lo em trabalho real
- Ainda há recursos que o autor quer adicionar, e a expectativa é que outras pessoas também passem a examiná-lo após o lançamento
- Algumas partes da interface pública podem precisar ser repensadas à luz de mais experiência
- A primeira versão é a 0.1, e ela deve permanecer na série 0.x por algum tempo para coletar feedback, corrigir bugs e aparar arestas
- O período estimado é de pelo menos cerca de 1 ano
- Assim como nos projetos anteriores, a licença é MIT
- Uma licença mais restritiva foi considerada, mas o interesse maior é em uso amplo, por isso foi escolhida uma licença permissiva
Modelos de IA, geração de código e política de pull requests
- Modelos de linguagem não foram usados para criar este software
- Como o código JavaScript estará na web e a documentação precisa ser pública, considera-se que não há uma forma confiável de impedir que código e ideias públicas entrem em grandes modelos de linguagem
- No Wordgard, está sendo feito um experimento de não aceitar pull requests, ao contrário da prática padrão de código aberto
- Revisar grandes mudanças e ajustá-las para que correspondam ao esperado costuma dar mais trabalho do que implementá-las diretamente
- Com a forte redução no custo de geração de código, torna-se menos atraente uma estrutura em que outras pessoas simplesmente enviam código e os mantenedores precisam revisar, manter ou explicar por que recusaram
1 comentários
Comentários no Lobste.rs
Como autor, vou verificar esta thread de vez em quando caso haja perguntas ou feedback
Imagino que dê para gerar HTML com um renderizador de Markdown e editá-lo no Wordgard, mas depois disso como seria possível extrair Markdown do conteúdo do editor?
Elas acabarão migrando para o Wordgard? Se alguém estiver pensando em usar ProseMirror em um projeto novo, quando deveria escolher o Wordgard?
E também há uma arte bacana feita por uma artista real, humana
Gostei
Parabéns ao Marijn pelo projeto e pelo lançamento. Parece ótimo, e também gostei da arte da Kamila Stankiewicz
A página inicial principal do projeto é https://wordgard.net/
Este trecho, especialmente o último parágrafo inteiro, é realmente interessante
Fico imaginando se esse tipo de abordagem pode se tornar mais comum por um tempo, até termos uma relação melhor com a geração de código por IA — ou até optarmos por não ter relação nenhuma com ela
Para constar, o código está sob a licença MIT