Crie uma extensão do Pinterest Notes para Chrome

Salo Por Salo 5 min de leitura
Crie uma extensão do Pinterest Notes para Chrome

Este tutorial cria o menor protótipo útil do Chrome Manifest V3: uma área de texto privada montada nas páginas do Pinterest Pin, codificada pelo ID numérico do Pin e salva em chrome.storage.local. É intencionalmente um protótipo, não um clone pronto para produção das notas anteriores do Pinterest.

O DOM do Pinterest pode mudar sem aviso prévio. Mantenha os seletores isolados, evite imitar a marca protegida do Pinterest e teste os tipos de páginas e localidades que você oferece suporte.

1. Crie a extensão Manifest V3

Crie uma pasta com manifesto.json e conteúdo.js. do cromo referência de manifesto é a fonte da verdade para as chaves disponíveis.

{
  "versão_manifesto": 3,
  "name": "Protótipo de contexto de pino",
  "versão": "0.1.0",
  "description": "Salvar uma nota local privada para um Pin do Pinterest.",
  "permissões": ["armazenamento"],
  "content_scripts": [{
    "correspondências": ["https://*.pinterest.com/*"],
    "js": ["content.js"],
    "run_at": "documento_idle"
  }]
}

A correspondência do host é ampla porque o Pinterest usa navegação do lado do cliente. Se o seu recurso oferece suporte a menos rotas ou domínios de países, restrinja e documente esse escopo.

2. Obtenha uma chave estável do URL do Pin

Não digite notas pela posição de um cartão ou título visível. Extraia o ID numérico de um canônico /pino/…/ caminho e retorno nulo em todos os outros lugares.

função getPinId (url = localização.href) {
  tente {
    const {nome do caminho} = novo URL(url);
    const match = pathname.match(//pin/(d+)/?/);
    partida de retorno? correspondência[1]: nulo;
  } pegar {
    retornar nulo;
  }
}

Teste URLs detalhados válidos, strings de consulta, páginas não-Pin, URLs malformados e quaisquer padrões de localidade que você afirma oferecer suporte. Nunca anexe uma nota silenciosamente quando a identificação for incerta.

3. Armazene um registro versionado

Mantenha o esquema explícito para que futuras migrações sejam possíveis:

função assíncrona readNote(pinId) {
  const key = 'pin-nota:' + pinId;
  resultado const = aguarda chrome.storage.local.get(chave);
  retornar resultado[chave] ?? { versão: 1, pinId, texto: '', atualizadoAt: null };
}

função assíncrona writeNote(pinId, texto) {
  const key = 'pin-nota:' + pinId;
  registro constante = {
    versão: 1,
    PINId,
    texto,
    atualizadoAt: new Date().toISOString()
  };
  aguarde chrome.storage.local.set({ [chave]: registro });
  registro de retorno;
}

O Chrome documenta um limite padrão de 10 MB para armazenamento.local, com um separado armazenamento ilimitado permissão para aumentá-lo. O Chrome também documenta que o armazenamento local da extensão é limpo quando a extensão é removida. Leia o atual Documentação da API de armazenamento e exporte o design antes de solicitar dados importantes.

4. Monte um editor isolado e acessível

Um Shadow DOM reduz colisões acidentais de estilo. O exemplo é anexado ao corpo da página para que não dependa de um nome de classe frágil do Pinterest:

função assíncrona mountEditor(pinId) {
  if (document.querySelector('[data-pin-context-root]')) retorno;

  const host = document.createElement('aside');
  host.dataset.pinContextRoot = '';
  host.setAttribute('aria-label', 'Nota do Pin Privado');
  document.body.append(host);

  const root = host.attachShadow({modo: 'aberto' });
  rótulo const = document.createElement('rótulo');
  label.textContent = 'Nota privada';
  editor const = document.createElement('textarea');
  editor.setAttribute('aria-label', 'Nota privada para este Pin');
  const status = document.createElement('span');
  status.setAttribute('role', 'status');

  const salvo = aguarda readNote(pinId);
  editor.valor = salvo.texto;
  root.append(rótulo, editor, status);
  bindAutosave(editor, status, pinId);
}

Crie texto de interface com textoConteúdo, não confiável HTML interno. Adicione estilos de foco visíveis, contraste suficiente, um rótulo real, acesso ao teclado e texto de status que não roube o foco.

5. Salve sem escrever a cada pressionamento de tecla

function bindAutosave(editor, status, pinId) {
  deixe salvarTimer;
  editor.addEventListener('input', () => {
    status.textContent = 'Não salvo';
    clearTimeout(saveTimer);
    saveTimer = setTimeout(async() => {
      tente {
        aguarde writeNote(pinId, editor.value);
        status.textContent = 'Salvo localmente';
      } pegar (erro) {
        console.error('Falha ao salvar nota de fixação', erro);
        status.textContent = 'Não foi possível salvar';
      }
    }, 400);
  });
}

Para produção, libere também entradas pendentes na transição de página, proteja-se contra duas guias que se sobrepõem, defina um tamanho máximo de nota e detecte erros de cota.

6. Lide com a navegação do lado do cliente do Pinterest

Um manipulador de carregamento de página único perde a navegação entre as visualizações de feed e de detalhes. Use uma função de reconciliação idempotente e observe as alterações sem remontar a cada mutação:

deixe agendado = falso;

função assíncrona reconciliar() {
  agendado = falso;
  const pinId = getPinId();
  const existente = document.querySelector('[data-pin-context-root]');
  se (!pinId) {
    existente?.remove();
    retornar;
  }
  if (existente?.dataset.pinId === pinId) return;
  existente?.remove();
  aguarde mountEditor(pinId);
  const montado = document.querySelector('[data-pin-context-root]');
  if (montado) montado.dataset.pinId = pinId;
}

novo MutationObserver(() => {
  se retorno (programado);
  agendado = verdadeiro;
  requestAnimationFrame(reconciliar);
}).observe(document.documentElement, { childList: true, subtree: true });

conciliar();

Uma versão de produção também deve observar o estado de navegação diretamente, sempre que possível, e desconectar os observadores de que não precisa mais. Crie o perfil do código em feeds longos; um recurso correto que degrada o desempenho da página ainda é uma extensão ruim.

7. Respeite as restrições de segurança do Manifest V3

O Manifest V3 proíbe código executável hospedado remotamente. Agrupe o JavaScript executável com a extensão, mantenha a política de segurança de conteúdo padrão, a menos que você tenha uma alteração justificada, evite a execução dinâmica de código e solicite apenas as permissões exigidas pelo recurso. do cromo Visão geral do manifesto V3 explica o modelo da plataforma.

8. Adicione os recursos que um produto real precisa

9. Teste os caminhos de falha

  1. Carregue a extensão descompactada de cromo://extensões.
  2. Visite um feed, um quadro, uma página de detalhes do Pin e uma rota sem Pin.
  3. Navegue entre dois Pins sem recarregar e confirme o isolamento da nota.
  4. Abra o mesmo Pin em duas guias e teste o comportamento do conflito.
  5. Desative o armazenamento ou simule falha de cota e verifique o aviso.
  6. Exporte, remova um registro de teste e restaure-o.
  7. Teste a navegação do teclado, o zoom, os rótulos do leitor de tela e as condições de página escura/clara.

A lição de engenharia

A área de texto é a parte fácil. Uma extensão confiável do Pinterest depende de identidade estável, gerenciamento resiliente do ciclo de vida, interface de usuário acessível, permissões restritas, armazenamento documentado e um caminho de saída testado. Desenvolva essas qualidades antes de expandir a lista de recursos.

Continue construindo seu sistema Pinterest

Continue com o guia que corresponde à sua próxima etapa:

Salo

Sobre o autor

Salo é um designer de produto e usuário avançado que escreve sobre organização digital, fluxos de trabalho do Pinterest e ferramentas para pensar melhor.

Obtenha a extensão Notestopin do Chrome

Adicione notas privadas a qualquer Pin, marque-os e pesquise seus salvamentos mais tarde.

Adicionar ao Chrome