feat: extensão de navegador para gerar CPF/CNPJ no menu de contexto

Adiciona uma extensão MV3 (Firefox e Chromium/Brave) que insere CPF ou CNPJ
válido direto no campo focado, pelo menu de contexto de qualquer input,
textarea ou contenteditable.

Extensões rodam em sandbox sem acesso a processos, então não há como invocar
os binários cpfgen/cnpjgen; fazer isso exigiria um host de native messaging
registrado no SO. Como os algoritmos são curtos e puros, foram portados para
JS em extension/generator.js, a partir de main.go (CPF) e de
cnpj_generator/cnpj/generate.go (CNPJ), trocando math/rand por
crypto.getRandomValues. test_generator.mjs compara as duas implementações
para que não divirjam.

A inserção usa document.execCommand("insertText"), que emite os eventos
nativos e portanto funciona em campos controlados por React/Vue — atribuir
.value diretamente seria descartado por esses frameworks.

Somente desktop: o Firefox para Android não implementa a API menus.

Testes carregam a extensão de verdade nos dois navegadores e verificam que os
8 itens de menu são criados e que a inserção funciona nos três tipos de campo.
This commit is contained in:
Lucas F. 2026-09-03 17:57:50 -03:00
parent 688c5a48f3
commit 7632cfde2c
14 changed files with 792 additions and 4 deletions

View file

@ -1,6 +1,7 @@
# cpfgen
CLI para gerar CPFs válidos em Go.
CLI para gerar CPFs válidos em Go, mais uma extensão de navegador que gera
CPF e CNPJ pelo menu de contexto de qualquer campo de texto.
## Instalação
@ -20,3 +21,75 @@ make test
./bin/cpfgen # 487.197.991-10
./bin/cpfgen -num # 48719799110
```
## Extensão de navegador
Em `extension/`. Clique com o botão direito em qualquer `input`, `textarea` ou
campo `contenteditable` e escolha **Gerar CPF** ou **Gerar CNPJ** — o valor é
inserido direto no campo, na posição do cursor.
Cada menu oferece formatado e só números; o CNPJ inclui também as duas variantes
alfanuméricas (formato novo).
A extensão **não** chama os binários Go: extensões rodam num sandbox sem acesso
a processos do sistema, e fazer isso exigiria um host de native messaging
registrado no sistema operacional. Como os algoritmos são curtos e puros, eles
foram portados para JS em `extension/generator.js`, a partir de `main.go` (CPF) e
de `cnpj_generator/cnpj/generate.go` (CNPJ). `make ext-test` compara as duas
implementações para garantir que não divirjam.
Não pede permissão de rede nem de acesso a sites, não coleta nada e funciona
offline.
**Somente desktop.** O Firefox para Android não implementa a API `menus` — pela
[documentação da Mozilla](https://extensionworkshop.com/documentation/develop/differences-between-desktop-and-android-extensions/),
*"`menus`, which means you cannot add options to context menus"*. Como a
extensão é inteiramente baseada no menu de contexto, ela não tem como funcionar
lá. Por isso o manifesto não declara `gecko_android`.
### Instalar no Firefox
Temporário (some ao fechar o navegador):
1. Abra `about:debugging#/runtime/this-firefox`
2. **Carregar extensão temporária…**
3. Escolha `extension/manifest.json`
Permanente: o Firefox só instala extensões assinadas. Rode `make ext-build` e
envie `web-ext-artifacts/cpfgen-1.0.0.zip` para
[addons.mozilla.org](https://addons.mozilla.org/developers/) — dá para publicar
como *unlisted* e receber um `.xpi` assinado só seu, sem listar na loja.
Para desenvolver, `make ext-run` abre um Firefox já com a extensão carregada e
recarrega a cada alteração.
### Instalar no Brave
1. Abra `brave://extensions`
2. Ligue o **Modo do desenvolvedor** (canto superior direito)
3. **Carregar sem compactação** e escolha a pasta `extension/`
Isso persiste entre reinicializações. O Brave mostra um aviso sobre extensões em
modo desenvolvedor a cada início — é esperado. O mesmo procedimento vale para
Chrome, Chromium e Edge.
### Testes da extensão
```sh
make ext-test # porte JS vs. binários Go + extensão real no Firefox e no Brave
make ext-lint # validação oficial da Mozilla (web-ext lint)
make ext-build # gera o .zip para publicação
```
`make ext-test` roda três coisas:
- `test_generator.mjs` — gera centenas de amostras pelo JS e pelos binários Go e
revalida todos os dígitos verificadores com uma implementação independente;
- `test_extension.py` — sobe um Firefox headless, instala a extensão de verdade,
confere que os 8 itens de menu foram criados e que a inserção funciona em
`input`, `textarea` e `contenteditable`;
- `test_chromium.py` — carrega a extensão no Brave headless e confere que o
service worker MV3 sobe e registra os mesmos 8 itens.
Precisa de `node`, `python3`, `firefox` e `brave` (os dois navegadores e os
binários Go são pulados com aviso se não estiverem presentes).