Atualizar seu código

Atualizações não relacionadas a outros problemas

Esta é a primeira das três seções que descrevem as alterações necessárias para o código que não faz parte do service worker de extensão. Esta seção é destinada a alterações de código necessárias não relacionadas a outros problemas. As próximas duas seções abordam a substituição do bloqueio de solicitações da Web e a melhoria da segurança.

Substituir tabings.executeScript() por scripting.executeScript()

No Manifesto V3, o executeScript() é movido da API tabs para a API scripting. Isso exige mudanças nas permissões do arquivo de manifesto, além das mudanças reais no código.

Para o método executeScript(), você precisa de:

  • A permissão "scripting";
  • Permissões de host ou a permissão "activeTab".

O método scripting.executeScript() é semelhante a como funcionava com tabs.executeScript(). Há algumas diferenças.

  • Enquanto o método antigo aceita apenas um arquivo, o novo método aceita uma matriz de arquivos.
  • Você também transmite um objeto ScriptInjection em vez de InjectDetails. Há várias diferenças entre os dois. Por exemplo, o tabId agora é transmitido como um membro de ScriptInjection.target em vez de como um argumento de método.

O exemplo mostra como fazer isso.

Manifest V2
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

chrome.tabs.executeScript(
  tab.id,
  {
    file: 'content-script.js'
  }
);

Em um arquivo de script em segundo plano.

Manifesto V3
async function getCurrentTab()
let tab = await getCurrentTab();

chrome.scripting.executeScript({
  target: {tabId: tab.id},
  files: ['content-script.js']
});

No service worker de extensão.

Substitua tabing.insertCSS() e tabs.removeCSS() por scripting.insertCSS() e scripting.removeCSS()

No Manifesto V3, insertCSS() e removeCSS() foram movidos da API tabs para a API scripting. Isso exige mudanças nas permissões do arquivo de manifesto, além das mudanças no código:

  • A permissão "scripting";
  • Permissões de host ou a permissão "activeTab".

As funções na API scripting são semelhantes às funções em tabs. Há algumas diferenças.

  • Ao chamar esses métodos, você transmite um objeto CSSInjection em vez de InjectDetails.
  • O tabId agora é transmitido como um membro de CSSInjection.target em vez de como um argumento de método.

O exemplo mostra como fazer isso para insertCSS(). O procedimento para removeCSS() é o mesmo.

Manifest V2
chrome.tabs.insertCSS(tabId, injectDetails, () => {
  // callback code
});

Em um arquivo de script em segundo plano.

Manifesto V3
const insertPromise = await chrome.scripting.insertCSS({
  files: ["style.css"],
  target: { tabId: tab.id }
});
// Remaining code. 

No service worker de extensão.

Substituir ações do navegador e da página por ações

Ações do navegador e ações de página eram conceitos separados no Manifesto V2. Embora tenham começado com funções distintas, as diferenças entre elas diminuíram com o tempo. No Manifesto V3, esses conceitos estão consolidados na API Action. Isso exige mudanças no manifest.json e no código da extensão diferentes das que você colocaria no script de segundo plano do Manifesto V2.

As ações no Manifesto V3 se assemelham às ações do navegador. No entanto, a API action não fornece hide() e show() como pageAction. Se você ainda precisar de ações de página, poderá emulá-las usando conteúdo declarativo ou chamar enable() ou disable() com um ID de guia.

Substituir "browser_action" e "page_action" com "ação"

No manifest.json, substitua os campos "browser_action" e "page_action" pelo campo "action". Consulte a referência para ver informações sobre o campo "action".

Manifest V2
{
  ...
  "page_action": { ... },
  "browser_action": {
    "default_popup": "popup.html"
   }
  ...
}
Manifesto V3
{
  ...
  "action": {
    "default_popup": "popup.html"
  }

  ...
}

Substituir as APIs browserAction e pageAction pela API de ação

Onde o Manifest V2 usava as APIs browserAction e pageAction, agora você precisa usar a API action.

Manifest V2
chrome.browserAction.onClicked.addListener(tab => { ... });
chrome.pageAction.onClicked.addListener(tab => { ... });
Manifesto V3
chrome.action.onClicked.addListener(tab => { ... });

Substituir callbacks por promessas

No Manifesto V3, muitos métodos da API de extensão retornam promessas. Uma promessa é um proxy ou marcador de posição de um valor retornado por um método assíncrono. Se você nunca usou promessas, leia sobre elas no MDN. Esta página descreve o que você precisa saber para usá-los em uma extensão do Chrome.

Para compatibilidade com versões anteriores, muitos métodos continuam a oferecer suporte a callbacks após a adição do suporte à promessa. Lembre-se de que não é possível usar ambos na mesma chamada de função. Se você passar um callback, a função não retornará uma promessa e, se você quiser que uma promessa seja retornada, não transmita um callback. Alguns recursos da API, como listeners de eventos, continuarão a exigir callbacks. Para verificar se um método oferece suporte a promessas, procure a "promessa". na referência da API.

Para converter um callback em uma promessa, remova o callback e processe a promessa retornada. O exemplo abaixo foi retirado do exemplo de permissões opcionais (link em inglês), especificamente newtab.js. A versão do callback mostra como seria a chamada do exemplo para request() com um callback. Observe que a versão da promessa pode ser reescrita com a função de modo assíncrono e de espera.

Chamada de retorno
chrome.permissions.request(newPerms, (granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});
Promise
const newPerms = { permissions: ['topSites'] };
chrome.permissions.request(newPerms)
.then((granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});

Substituir funções que esperam um contexto em segundo plano do Manifest V2

Outros contextos de extensão só podem interagir com service workers de extensão usando a transmissão de mensagens. Consequentemente, você precisará substituir chamadas que esperam um contexto em segundo plano, especificamente:

  • chrome.runtime.getBackgroundPage()
  • chrome.extension.getBackgroundPage()
  • chrome.extension.getExtensionTabs()

Os scripts de extensão devem usar a transmissão de mensagens para a comunicação entre um service worker e outras partes da sua extensão. Atualmente, isso pode ser feito usando sendMessage() e implementando chrome.runtime.onMessage no seu service worker de extensão. Em longo prazo, substitua essas chamadas por postMessage() e pelo manipulador de eventos de mensagem de um service worker.

Substituir APIs sem suporte

Os métodos e propriedades listados abaixo precisam ser alterados no Manifesto V3.

Método ou propriedade do Manifest V2 Substituir por
chrome.extension.connect() chrome.runtime.connect()
chrome.extension.connectNative() chrome.runtime.connectNative()
chrome.extension.getExtensionTabs() chrome.extension.getViews()
chrome.extension.getURL() chrome.runtime.getURL()
chrome.extension.lastError Quando os métodos retornarem promessas, use promise.catch().
chrome.extension.onConnect chrome.runtime.onConnect
chrome.extension.onConnectExternal chrome.runtime.onConnectExternal
chrome.extension.onMessage chrome.runtime.onMessage
chrome.extension.onRequest chrome.runtime.onMessage
chrome.extension.onRequestExternal chrome.runtime.onMessageExternal
chrome.extension.sendMessage() chrome.runtime.sendMessage()
chrome.extension.sendNativeMessage() chrome.runtime.sendNativeMessage()
chrome.extension.sendRequest() chrome.runtime.sendMessage()
chrome.runtime.onSuspend (scripts de segundo plano) Incompatível com service workers de extensão. Use o evento de documento beforeunload.
chrome.tabs.getAllInWindow() chrome.tabs.query()
chrome.tabs.getSelected() chrome.tabs.query()
chrome.tabs.onActiveChanged chrome.tabs.onActivated
chrome.tabs.onHighlightChanged chrome.tabs.onHighlighted
chrome.tabs.onSelectionChanged chrome.tabs.onActivated
chrome.tabs.sendRequest() chrome.runtime.sendMessage()
chrome.tabs.Tab.selected chrome.tabs.Tab.highlighted