Injetar scripts na guia ativa

Simplifique o estilo da página atual clicando no ícone da barra de ferramentas da extensão.

Visão geral

Este tutorial cria uma extensão que simplifica o estilo da extensão do Chrome e das páginas de documentação da Chrome Web Store para facilitar a leitura.

Neste guia, vamos explicar como fazer o seguinte:

  • Use o service worker de extensão como coordenador de eventos.
  • Preserve a privacidade do usuário com a permissão "activeTab".
  • Executar o código quando o usuário clicar no ícone da barra de ferramentas da extensão.
  • Inserir e remover uma folha de estilo usando a API Scripting.
  • Use um atalho de teclado para executar o código.

Antes de começar

Este guia pressupõe que você tenha experiência básica em desenvolvimento da Web. Recomendamos consultar Hello World para ver uma introdução ao fluxo de trabalho de desenvolvimento de extensões.

Criar a extensão

Para começar, crie um novo diretório chamado focus-mode que armazenará os arquivos da extensão. Se preferir, faça o download do código-fonte completo no GitHub (link em inglês).

Etapa 1: adicionar os dados e ícones da extensão

Crie um arquivo chamado manifest.json e inclua o código a seguir.

{
  "manifest_version": 3,
  "name": "Focus Mode",
  "description": "Enable focus mode on Chrome's official Extensions and Chrome Web Store documentation.",
  "version": "1.0",
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  }
}

Para saber mais sobre essas chaves de manifesto, confira o tutorial "Executar scripts em todas as guias", que explica os metadados e ícones da extensão em mais detalhes.

Crie uma pasta images e faça o download dos ícones para dentro dela.

Etapa 2: inicializar a extensão

As extensões podem monitorar eventos do navegador em segundo plano usando o service worker da extensão. Os service workers são ambientes JavaScript especiais que processam eventos e são encerrados quando não são necessários.

Comece registrando o service worker no arquivo manifest.json:

{
  ...
  "background": {
    "service_worker": "background.js"
  },
  ...
}

Crie um arquivo chamado background.js e adicione o seguinte código:

chrome.runtime.onInstalled.addListener(() => {
  chrome.action.setBadgeText({
    text: "OFF",
  });
});

O primeiro evento que nosso service worker detectará é runtime.onInstalled(). Esse método permite que a extensão defina um estado inicial ou conclua algumas tarefas na instalação. As extensões podem usar a API Storage e o IndexedDB para armazenar o estado do aplicativo. No entanto, nesse caso, como estamos lidando apenas com dois estados, usaremos o próprio texto do selo da ação para rastrear se a extensão está "ATIVADA" ou "DESATIVADA".

Etapa 3: ativar a ação da extensão

A ação da extensão controla o ícone da barra de ferramentas da extensão. Portanto, sempre que o usuário clicar no ícone da extensão, ele executará um código (como neste exemplo) ou exibirá um pop-up. Adicione o código abaixo para declarar a ação de extensão no arquivo manifest.json:

{
  ...
  "action": {
    "default_icon": {
      "16": "images/icon-16.png",
      "32": "images/icon-32.png",
      "48": "images/icon-48.png",
      "128": "images/icon-128.png"
    }
  },
  ...
}

Usar a permissão ActiveTab para proteger a privacidade do usuário

A permissão activeTab concede à extensão a capacidade temporária de executar código na guia ativa. Ela também permite o acesso a propriedades confidenciais da guia atual.

Essa permissão é ativada quando o usuário invoca a extensão. Nesse caso, o usuário invoca a extensão clicando na ação dela.

💡 Que outras interações de usuários ativam a permissão ActiveTab na minha própria extensão?

  • Pressionar uma combinação de atalhos de teclado.
  • Seleção de um item do menu de contexto.
  • Aceitar uma sugestão da omnibox.
  • Abrindo um pop-up de extensão.

A permissão "activeTab" permite que os usuários escolham intencionalmente executar a extensão na guia em foco. Dessa forma, ela protege a privacidade do usuário. Outro benefício é que isso não aciona um aviso de permissão.

Para usar a permissão "activeTab", adicione-a à matriz de permissões do manifesto:

{
  ...
  "permissions": ["activeTab"],
  ...
}

Etapa 4: acompanhar o estado da guia atual

Depois que o usuário clicar na ação da extensão, ela verificará se o URL corresponde a uma página de documentação. Em seguida, ele verifica o estado da guia atual e define o próximo estado. Adicione o seguinte código a background.js:

const extensions = 'https://developer.chrome.com/docs/extensions'
const webstore = 'https://developer.chrome.com/docs/webstore'

chrome.action.onClicked.addListener(async (tab) => {
  if (tab.url.startsWith(extensions) || tab.url.startsWith(webstore)) {
    // Retrieve the action badge to check if the extension is 'ON' or 'OFF'
    const prevState = await chrome.action.getBadgeText({ tabId: tab.id });
    // Next state will always be the opposite
    const nextState = prevState === 'ON' ? 'OFF' : 'ON'

    // Set the action badge to the next state
    await chrome.action.setBadgeText({
      tabId: tab.id,
      text: nextState,
    });
  }
});

Etapa 5: adicionar ou remover a folha de estilo

Agora é hora de alterar o layout da página. Crie um arquivo chamado focus-mode.css e inclua o seguinte código:

body > .scaffold > :is(top-nav, navigation-rail, side-nav, footer),
main > :not(:last-child),
main > :last-child > navigation-tree,
main .toc-container {
  display: none;
}

main > :last-child {
  margin-top: min(10vmax, 10rem);
  margin-bottom: min(10vmax, 10rem);
}

Insira ou remova a folha de estilo usando a API Scripting. Comece declarando a permissão "scripting" no manifesto:

{
  ...
  "permissions": ["activeTab", "scripting"],
  ...
}

Por fim, em background.js, adicione o código abaixo para mudar o layout da página:

  ...
    if (nextState === "ON") {
      // Insert the CSS file when the user turns the extension on
      await chrome.scripting.insertCSS({
        files: ["focus-mode.css"],
        target: { tabId: tab.id },
      });
    } else if (nextState === "OFF") {
      // Remove the CSS file when the user turns the extension off
      await chrome.scripting.removeCSS({
        files: ["focus-mode.css"],
        target: { tabId: tab.id },
      });
    }
  }
});

💡 Posso usar a API Scripting para injetar código em vez de uma folha de estilo?

Sim. Use o scripting.executeScript() para injetar o JavaScript.

Opcional: atribuir um atalho do teclado

Só por diversão, adicione um atalho para ativar ou desativar o "Modo sem distrações". Adicione a chave "commands" ao manifesto.

{
  ...
  "commands": {
    "_execute_action": {
      "suggested_key": {
        "default": "Ctrl+B",
        "mac": "Command+B"
      }
    }
  }
}

A chave "_execute_action" executa o mesmo código que o evento action.onClicked(). Portanto, nenhum outro código é necessário.

Testar se ele funciona

Verifique se a estrutura de arquivos do seu projeto é semelhante a esta:

O conteúdo da pasta do modo de foco: manifest.json, background.js, focus-mode.css e as pastas de imagens.

Carregar sua extensão localmente

Para carregar uma extensão descompactada no modo de desenvolvedor, siga as etapas em Hello World.

Testar a extensão em uma página de documentação

Primeiro, abra qualquer uma destas páginas:

Em seguida, clique na ação da extensão. Se você configurou um atalho de teclado, pressione Ctrl + B ou Cmd + B para testá-lo.

Ele deve sair deste modo:

Extensão do Modo sem distrações DESATIVADA
Extensão "Modo sem distrações" desativada

Para isto:

Extensão do Modo sem distrações ATIVADA
Extensão do Modo sem distrações ativada

🎯 Possíveis melhorias

Com base no que você aprendeu hoje, tente realizar qualquer uma das seguintes ações:

  • Melhorar a folha de estilo CSS.
  • Atribua um atalho de teclado diferente.
  • Mude o layout do seu blog ou site de documentação favorito.

Continue desenvolvendo.

Parabéns por concluir este tutorial 🎉. Continue aprimorando suas habilidades concluindo outros tutoriais nesta série:

Extensão Conteúdo do laboratório
Tempo de leitura Inserir automaticamente um elemento em um conjunto específico de páginas.
Gerenciador de guias Para criar um pop-up que gerencia as guias do navegador.

Continue descobrindo

Esperamos que você tenha gostado de criar essa extensão do Chrome e esteja animado para continuar sua jornada de aprendizado de desenvolvimento de extensões. Recomendamos os seguintes programas de aprendizado: