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:
parent
688c5a48f3
commit
7632cfde2c
14 changed files with 792 additions and 4 deletions
87
extension/background.js
Normal file
87
extension/background.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import {
|
||||
generateCPF,
|
||||
formatCPF,
|
||||
generateCNPJ,
|
||||
generateCNPJAlpha,
|
||||
formatCNPJ,
|
||||
} from "./generator.js";
|
||||
|
||||
// Firefox expõe `browser`, Chromium expõe `chrome`. As APIs usadas aqui são
|
||||
// compatíveis nos dois, então basta escolher o objeto disponível.
|
||||
const api = typeof browser !== "undefined" ? browser : chrome;
|
||||
|
||||
const MENU_ITEMS = [
|
||||
{ id: "cpf-formatted", parentId: "cpf", title: "Formatado (000.000.000-00)" },
|
||||
{ id: "cpf-raw", parentId: "cpf", title: "Só números" },
|
||||
{
|
||||
id: "cnpj-formatted",
|
||||
parentId: "cnpj",
|
||||
title: "Formatado (00.000.000/0000-00)",
|
||||
},
|
||||
{ id: "cnpj-raw", parentId: "cnpj", title: "Só números" },
|
||||
{ id: "cnpj-alpha-formatted", parentId: "cnpj", title: "Alfanumérico" },
|
||||
{
|
||||
id: "cnpj-alpha-raw",
|
||||
parentId: "cnpj",
|
||||
title: "Alfanumérico, só números",
|
||||
},
|
||||
];
|
||||
|
||||
function buildMenus() {
|
||||
api.contextMenus.removeAll(() => {
|
||||
// contexts: "editable" faz o menu aparecer apenas em input, textarea e
|
||||
// elementos contenteditable — nunca no resto da página.
|
||||
api.contextMenus.create({
|
||||
id: "cpf",
|
||||
title: "Gerar CPF",
|
||||
contexts: ["editable"],
|
||||
});
|
||||
api.contextMenus.create({
|
||||
id: "cnpj",
|
||||
title: "Gerar CNPJ",
|
||||
contexts: ["editable"],
|
||||
});
|
||||
|
||||
for (const item of MENU_ITEMS) {
|
||||
api.contextMenus.create({ ...item, contexts: ["editable"] });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
api.runtime.onInstalled.addListener(buildMenus);
|
||||
api.runtime.onStartup.addListener(buildMenus);
|
||||
|
||||
function valueFor(menuItemId) {
|
||||
switch (menuItemId) {
|
||||
case "cpf-formatted":
|
||||
return formatCPF(generateCPF());
|
||||
case "cpf-raw":
|
||||
return generateCPF();
|
||||
case "cnpj-formatted":
|
||||
return formatCNPJ(generateCNPJ());
|
||||
case "cnpj-raw":
|
||||
return generateCNPJ();
|
||||
case "cnpj-alpha-formatted":
|
||||
return formatCNPJ(generateCNPJAlpha());
|
||||
case "cnpj-alpha-raw":
|
||||
return generateCNPJAlpha();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
api.contextMenus.onClicked.addListener((info, tab) => {
|
||||
const value = valueFor(info.menuItemId);
|
||||
if (value === null || !tab?.id) return;
|
||||
|
||||
api.scripting.executeScript({
|
||||
target: { tabId: tab.id, frameIds: [info.frameId ?? 0] },
|
||||
files: ["insert.js"],
|
||||
});
|
||||
|
||||
api.scripting.executeScript({
|
||||
target: { tabId: tab.id, frameIds: [info.frameId ?? 0] },
|
||||
func: (text) => insertIntoFocused(text),
|
||||
args: [value],
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue