Notepad Neo

Engenharia

Anotações de quem construiu um editor de texto no navegador

O Notepad Neo é um editor de texto formatado construído sobre uma única div contenteditable, sem framework de editor e sem dependências em tempo de execução. A exportação para Word e PDF foi escrita do zero — um gerador de ZIP, um emissor de OOXML e um escritor de bytes de PDF, tudo no navegador.

Estes são relatos das partes que se revelaram mais difíceis do que o esperado. Cada um descreve algo que realmente quebrou neste app, cita o código que está em produção hoje e diz com clareza onde a abordagem chega ao limite.

O que cada artigo cobre

Quais módulos do editor cada artigo cobre O editor é formado por um elemento de papel contenteditable cercado por cinco subsistemas. O módulo de texto bidirecional e a barra de ferramentas ficam do lado da entrada; o adaptador de armazenamento persiste o estado; e os geradores de DOCX e PDF leem o documento para fora. Cada um dos cinco artigos corresponde a um desses subsistemas. #editor-paper uma div contenteditable bidi.ts direção por bloco, 197 linhas toolbar.ts tamanho de fonte, blocos, alinhamento docx/ — 785 linhas zip.ts · ooxml.ts · index.ts pdf/ — ~1.300 linhas sandbox · measure · writer storage.ts localStorage → IndexedDB LADO DA ENTRADA LADO DA SAÍDA
Não há nenhum modelo de documento entre o DOM e o resto — é isso que torna os dois exportadores simples e as operações de edição difíceis. Todo artigo abaixo decorre dessa única decisão.
  1. · atualizado em · 12 min de leitura

    Por que dir="auto" quebra um editor multilíngue

    Uma nota que começa com a palavra "Hello" mantém todo parágrafo em árabe abaixo dela alinhado à esquerda — para sempre. Por que a regra Unicode do primeiro caractere forte precisa rodar por bloco, quais code points contam como fortes, e as sete coisas que quebraram no caminho.

    • Bidi Unicode
    • contenteditable
    • Propriedades lógicas CSS
    • UAX #9
  2. · atualizado em · 13 min de leitura

    Gerando um PDF no navegador deixando o navegador cuidar do layout

    O PDF não tem motor de layout, então cada glifo precisa de uma coordenada. Medir um clone fora da tela em vez de reimplementar a quebra de linha, sondar linhas de base que o DOM não informa, e a barreira de codificação que manda alguns documentos para a Impressão.

    • PDF
    • Medição de layout
    • Codificação de texto
    • API Range
  3. · atualizado em · 13 min de leitura

    Escrevendo um .docx no navegador sem dependências

    Um .docx é um ZIP de partes XML. Um gerador de ZIP de 114 linhas, a ordem estrita dos filhos no OOXML cujo modo de falha é um arquivo que não abre, e por que cada propriedade de caractere precisa de um gêmeo para escritas complexas.

    • OOXML
    • Formato ZIP
    • Exportação de arquivos
    • ECMA-376
  4. · atualizado em · 11 min de leitura

    Mudando o tamanho da fonte em contenteditable sem HierarchyRequestError

    range.surroundContents() lança exceção em qualquer seleção que cruze a fronteira de um elemento. O truque com o execCommand obsoleto que o substitui, e os cinco bugs seguintes que ele cria.

    • contenteditable
    • execCommand
    • API Selection
    • Cascata CSS
  5. · atualizado em · 11 min de leitura

    O que acontece quando o localStorage acaba

    O salvamento automático dentro de um limite de 5 MiB falha em silêncio, e a pessoa só descobre ao fechar a aba. Por que o fallback dispara na escrita que falhou, e não em uma estimativa de tamanho, e a recuperação automática que ninguém projetou.

    • localStorage
    • IndexedDB
    • Local-first
    • Cotas de armazenamento