Para modificar qualquer página que combine com um padrão particular (por exemplo, "https://example.org/") a medida que elas são carregadas, use o módulo page-mod
.
Para criar um page-mod, você precisa de duas coisas:
- Um ou mais content scripts(script de conteúdo) para executar cuja tarefa é interagir com o conteúdo web.
- Um ou mais patterns(padrões) para combinar com URLs que você quer modificar.
Um trecho simples de códingo onde o script de conteúdo é fornecido com a opção contentScript
e o padrão de busca da URL é dado pela opção include
como a seguir:
// Importe a API page-mod var pageMod = require("sdk/page-mod"); // Crie um page-mod // Ele executará um script toda vez que uma URL ".org" é carregada // O script substitui o conteúdo da página por uma mensagem pageMod.PageMod({ include: "*.org", contentScript: 'document.body.innerHTML = ' + ' "<h1>Page matches ruleset</h1>";' });
Faça o seguinte:
- Crie um novo diretório navegue para ele.
- Execute
jpm init
oucfx init
Abra o arquivo index.js
e adicione o código acima (lib/main.js se estiver usando
cfx
)- Execute
jpm run
oucfx run
. - Abra no navegador o site ietf.org.
Abaixo é o que você deve ver.
Especificando o Padão a Combinar
O padrão de combinação usa a síntaxe match-pattern
. Você pode passar uma única string como padrão a combinar ou um array.
Mantendo o Conteúdo do Script em um Arquivo Separado
No exemplo acima, nós fornecemos o script de conteúdo como uma string.
A menos que o script seja extremamente simples, é melhor manter o script em um arquivo separado. Isso torna o código mais fácil para manter, depurar, e revisar. Para fazer isso, você precisa:
- Salvar o script no diretório "
data
" do add-on. - Use a opção
contentScriptFile
ao invés decontentScript
e passe para ela a URL do script que pode ser obtida usandoself.data.url("my-script.js")
. A partir do Firefox 34, você pode usar"./my-script.js"
.
Por exemplo, se você salvar o script acima no diretório data do add-on em um arquivo chamado my-script.js
:
// Importe a API page-mod var pageMod = require("sdk/page-mod"); // Importe a API self var self = require("sdk/self"); // Crie um page-mod // Ele executará um script toda vez que uma URL ".org" é carregada // O script substitui o conteúdo da página por uma mensagem pageMod.PageMod({ include: "*.org", contentScriptFile: self.data.url("my-script.js") });
Ou a partir do Firefox 34:
// Importe a API page-mod var pageMod = require("sdk/page-mod"); // Crie um page-mod // Ele executará um script toda vez que uma URL ".org" é carregada // O script substitui o conteúdo da página por uma mensagem pageMod.PageMod({ include: "*.org", contentScriptFile: "./my-script.js" });
Carregando Múltiplos Scripts de Conteúdo
Você pode carregar mais do que um script, e eles podem interagir um com o outro.
Por exmeplo, você poderia reescrever o my-script.js
para usar o jQuery.
$("body").html("<h1>Page matches ruleset</h1>");
Então baixe o jQuery para o diretório data
do add-on, e carregue o script e o jQuery juntos (tenha certeza de carregar o jQuery primeiro).
// Importe a API page-mod var pageMod = require("sdk/page-mod"); // Importe a API self var self = require("sdk/self"); // Crie um page-mod // Ele executará um script toda vez que uma URL ".org" é carregada // O script substitui o conteúdo da página por uma mensagem pageMod.PageMod({ include: "*.org", contentScriptFile: [self.data.url("jquery-1.7.min.js"), self.data.url("my-script.js")] });
Você pode usar ambos contentScript
e contentScriptFile
no mesmo page-mod. Se você fizer isto, o script carregado usando contentScriptFile
são carregados primeiro.
// Importe a API page-mod var pageMod = require("sdk/page-mod"); // Importe a API self var self = require("sdk/self"); // Crie um page-mod // Ele executará um script toda vez que uma URL ".org" é carregada // O script substitui o conteúdo da página por uma mensagem pageMod.PageMod({ include: "*.org", contentScriptFile: self.data.url("jquery-1.7.min.js"), contentScript: '$("body").html("<h1>Page matches ruleset</h1>");' });
Note, porém, que você não pode carregar um script de um site web. O script deve ser carregado do data
.
Comunicando com o Script de Conteúdo
Seu script do add-on e o script de conteúdo não podem acessar diretamente a variável de um ou outro ou chamar função dos outros, mas eles podem enviar mensagens um para o outro.
Para enviar mensagens de um lado para o outro, use o emitente de chamadas port.emit()
e receba respostas usando port.on()
.
- No script de conteúdo,
port
é uma propriedade do objeto globalself
. - No script do add-on, você precisa capturar evento no
onAttach
event passando um objeto worker que contém aport
.
Vamos reescrever o exemplo acima para passar uma mensagem do add-on para o script de conteúdo. A mensagem conterá o novo conteúdo para inserir dentro do documento
O script de conteúdo agora precisa parecer com isto:
// "self" é um objeto global no script de conteúdo // Espera pelas mensagens, e substitui o conteúdo do // documento com a mensagem recebida self.port.on("replacePage", function(message) { document.body.innerHTML = "<h1>" + message + "</h1>"; });
No script do add-on, nós enviaremos ao script de conteúdo uma mensagem dentro do onAttach
.
// Importe a API page-mod var pageMod = require("sdk/page-mod"); // Importe a API self var self = require("sdk/self"); // Crie um page-mod // Ele executará um script toda vez que uma URL ".org" é carregada // O script substitui o conteúdo da página por uma mensagem pageMod.PageMod({ include: "*.org", contentScriptFile: self.data.url("my-script.js"), // Envia ao script de conteúdo uma mensagem dentro de onAttach onAttach: function(worker) { worker.port.emit("replacePage", "Page matches ruleset"); } });
A mensagem replacePage
não é uma mensagem embutida: é uma mensagem definida pelo add-on na chamada do port.emit()
.
Injetando CSS
Note que a característica descrita nesta seção é experimental no momento. Nós devemos provavelmente continuar suportando essa característica, mas os detalhes da API devem mudar.
Em vez de injetar JavaScript na página, você pode injetar CSS definindo a opção do contentStyle
do mod-page.
var pageMod = require("sdk/page-mod").PageMod({ include: "*", contentStyle: "body {" + " border: 5px solid green;" + "}" });
Como com o contentScript
, há uma opção correspondente para contentStyleFile
que leva uma URL de um arquivo CSS situado no diretório "data"; é uma boa prática usar essa opção ao invés de contentStyle
se o CSS é muito complexo.
var pageMod = require("sdk/page-mod").PageMod({ include: "*", contentStyleFile: require("sdk/self").data.url("my-style.css") });
Ou, a partir do Firefox 34, você pode usar a versão mais simples:
var pageMod = require("sdk/page-mod").PageMod({ include: "*", contentStyleFile: "./my-style.css" });
Aprendendo mais
Para aprender mais sobre o page-mod
, veja a referência da API page. Em particular, o construtor PageMod
leva várias opções adicionais para controlar seu comportamento:
-
Por padrão, script de conteúdo não são anexados a qualuqer tab que já esteja aberta quando o page-mod é criado, e são anexados à iframes bem como documentos superiores. Para controlar esse comportamento use a opção
attachTo
. -
Defina valores somente leitura acessíveis ao script de conteúdo usando a opção
contentScriptOptions
. -
Por padrão, o script de conteúdo são anexados depois de todo o (DOM, JS, CSS, imagens) para a página ter sido carregado, no momento o evento window.onload dispara. Para controlar esse comportamento, use a opção
contentScriptWhen
.
Para aprender mais sobre o script de conteúdo,, veja o guia content scripts.