Visão geral da arquitetura

Extensões são pacotes compactados de HTML, CSS, JavaScript, imagens e outros arquivos usados na plataforma da Web que personalizam a experiência de navegação no Google Chrome. As extensões são criadas usando tecnologia da Web e podem utilizar as mesmas APIs que o navegador fornece para a Web aberta.

As extensões têm muitas possibilidades funcionais. Eles podem modificar o conteúdo da Web que os usuários veem e interagem, ou estender e alterar o comportamento do próprio navegador.

Considere as extensões como a porta de entrada para tornar o Chrome o navegador mais personalizado.

Arquivos de extensão

As extensões variam em tipos de arquivos e quantidades de diretórios, mas todos precisam ter um [manifesto][docs-manifest]. Algumas extensões básicas, mas úteis, podem consistir apenas no manifesto e no ícone da barra de ferramentas.

O arquivo de manifesto, intitulado manifest.json, fornece informações ao navegador sobre a extensão, como os arquivos mais importantes e os recursos que a extensão pode usar.

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": {
    "128": "icon_16.png",
    "128": "icon_32.png",
    "128": "icon_48.png",
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["background_script.js"]
  },
  "permissions": ["https://*.google.com/", "activeTab"],
  "browser_action": {
    "default_icon": "icon_16.png",
    "default_popup": "popup.html"
  }
}

As extensões precisam ter um ícone na barra de ferramentas do navegador. Os ícones da barra de ferramentas facilitam o acesso e informam os usuários de quais extensões estão instaladas. A maioria dos usuários interage com uma extensão que usa um pop-up clicando no ícone.

Esta extensão Verificador do Google Mail usa uma ação do navegador:

Uma captura de tela da extensão Verificador do Google Mail

Esta extensão do Mappy usa uma ação da página e um script de conteúdo:

Uma captura de tela da extensão Mappy

Referência a arquivos

Os arquivos de uma extensão podem ser referenciados usando um URL relativo, assim como os arquivos em uma página HTML comum.

<img src="images/my_image.png">

Além disso, cada arquivo também pode ser acessado usando um URL absoluto.

chrome-extension://EXTENSION_ID/PATH_TO_FILE

No URL absoluto, o EXTENSION_ID é um identificador exclusivo que o sistema de extensões gera para cada extensão. Para visualizar os IDs de todas as extensões carregadas, acesse o URL chrome://extensions. O PATH_TO_FILE é o local do arquivo na pasta principal da extensão. Ele corresponde ao URL relativo.

Ao trabalhar em uma extensão descompactada, o ID da extensão pode mudar. Especificamente, o ID de uma extensão descompactada mudará se ela for carregada de um diretório diferente. O ID será alterado novamente quando a extensão for empacotada. Se o código de uma extensão depender de um URL absoluto, ele poderá usar o método chrome.runtime.getURL() para evitar fixar o ID no código durante o desenvolvimento.

Arquitetura

A arquitetura de uma extensão depende da funcionalidade dela, mas muitas extensões robustas incluem vários componentes:

Script em segundo plano

O script em segundo plano é o manipulador de eventos da extensão. Ele contém listeners de eventos do navegador que são importantes para a extensão. Ele permanece inativo até que um evento seja disparado e, em seguida, executa a lógica instruída. Um script em segundo plano efetivo só é carregado quando é necessário e descarregado quando fica inativo.

Elementos da interface

A interface do usuário de uma extensão precisa ser intencional e mínima. A interface precisa personalizar ou melhorar a experiência de navegação sem que ela se distraia. A maioria das extensões tem uma ação do navegador ou uma ação da página, mas pode conter outras formas de IU, como menus de contexto, o uso da omnibox ou a criação de um atalho de teclado.

As páginas da interface da extensão, como um pop-up, podem conter páginas HTML comuns com lógica JavaScript. As extensões também podem chamar tabs.create ou window.open() para exibir outros arquivos HTML presentes na extensão.

Uma extensão que usa uma ação de página e um pop-up pode usar a API de conteúdo declarativo para definir regras no script em segundo plano para quando o pop-up estiver disponível para os usuários. Quando as condições são atendidas, o script em segundo plano se comunica com o pop-up para tornar o ícone clicável para os usuários.

Uma janela do navegador com uma ação da página exibindo um pop-up

Scripts de conteúdo

As extensões que leem ou gravam em páginas da Web utilizam um script de conteúdo. O script de conteúdo contém um JavaScript que é executado nos contextos de uma página que foi carregada no navegador. Os scripts de conteúdo leem e modificam o DOM das páginas da Web que o navegador visita.

Uma janela do navegador com uma ação de página e um script de conteúdo

Os scripts de conteúdo podem se comunicar com a extensão pai ao trocar mensagens e armazenar valores usando a API storage.

Mostra um caminho de comunicação entre o script de conteúdo e a extensão mãe

Página "Opções"

Assim como as extensões permitem que os usuários personalizem o navegador Chrome, a página de opções ativa a personalização da extensão. Elas podem ser usadas para ativar recursos e permitir que os usuários escolham qual funcionalidade é relevante para as necessidades deles.

Como usar as APIs do Chrome

Além de ter acesso às mesmas APIs que as páginas da Web, as extensões também podem usar APIs específicas de extensões, que criam forte integração com o navegador. Extensões e páginas da Web podem acessar o método window.open() padrão para abrir um URL, mas as extensões podem especificar em qual janela esse URL deve ser exibido, usando o método tabs.create da API Chrome.

Métodos assíncronos x síncronos

A maioria dos métodos da API do Chrome é assíncrono: eles retornam imediatamente sem esperar a conclusão da operação. Se uma extensão precisar saber o resultado de uma operação assíncrona, ela poderá transmitir uma função de callback para o método. O callback é executado mais tarde, possivelmente muito mais tarde, após o retorno do método.

Se a extensão for necessária para navegar até um novo URL na guia selecionada pelo usuário, ela vai precisar receber o ID da guia atual e atualizar o endereço dessa guia para o novo URL.

Se o método tabs.query for síncrono, o código pode ficar parecido com este:

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

Essa abordagem falhará porque query() é assíncrono. Ele retorna sem aguardar a conclusão do trabalho e não retorna um valor. Um método é assíncrono quando o parâmetro de callback está disponível na assinatura.

// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)

Para consultar corretamente uma guia e atualizar o URL dela, a extensão precisa usar o parâmetro de callback.

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

No código acima, as linhas são executadas na seguinte ordem: 1, 4, 2. A função de callback especificada para query() é chamada e executa a linha 2, mas somente depois que as informações sobre a guia selecionada estão disponíveis. Isso acontece algum tempo depois que query() retorna. Embora update() seja assíncrono, o código não usa um parâmetro de callback, já que a extensão não faz nada com os resultados da atualização.

// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()

Esse método retorna o URL de forma síncrona como uma string e não realiza outro trabalho assíncrono.

Mais detalhes

Para mais informações, consulte os documentos de referência da API Chrome e assista ao vídeo a seguir.

Comunicação entre páginas

Diferentes componentes em uma extensão geralmente precisam se comunicar entre si. Diferentes páginas HTML podem ser encontradas usando os métodos chrome.extension, como getViews() e getBackgroundPage(). Quando uma página tem uma referência a outras páginas de extensão, a primeira pode invocar funções nas outras páginas e manipular os DOMs delas. Além disso, todos os componentes da extensão podem acessar valores armazenados usando a API storage e se comunicar por meio da transmissão de mensagens.

Salvando dados e modo de navegação anônima

As extensões podem salvar dados usando a API storage, a API Web Storage HTML5 ou fazendo solicitações de servidor que resultam em salvamento de dados. Quando a extensão precisa salvar algo, primeiro considere se esse item é de uma janela anônima. Por padrão, as extensões não são executadas em janelas anônimas.

O modo de navegação anônima promete que a janela não deixará rastros. Ao lidar com dados de janelas anônimas, as extensões precisam respeitar essa promessa. Se uma extensão normalmente salva o histórico de navegação, não salve o histórico de janelas anônimas. No entanto, as extensões podem armazenar preferências de configuração de qualquer janela, anônima ou não.

Para detectar se uma janela está no modo de navegação anônima, verifique a propriedade incognito do objeto tabs.Tab ou windows.Window relevante.

function saveTabData(tab) {
  if (tab.incognito) {
    return;
  } else {
    chrome.storage.local.set({data: tab.url});
  }
}

Vá além

Depois de ler a visão geral e concluir o tutorial de Primeiros passos, os desenvolvedores estarão prontos para começar a criar as próprias extensões. Mergulhe no mundo do Chrome personalizado com os recursos a seguir.